initial commit of actions

This commit is contained in:
Dominik Polakovics Polakovics 2026-01-31 18:56:04 +01:00
commit 949ece5785
44660 changed files with 12034344 additions and 0 deletions

View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,94 @@
# Azure Core LRO client library for JavaScript
This is the default implementation of long running operations in Azure SDK JavaScript client libraries which work in both the browser and NodeJS. This library is primarily intended to be used in code generated by [AutoRest](https://github.com/Azure/Autorest) and [`autorest.typescript`](https://github.com/Azure/autorest.typescript).
`@azure/core-lro` follows [The Azure SDK Design Guidelines for Long Running Operations](https://azure.github.io/azure-sdk/typescript_design.html#ts-lro)
Key links:
- [Source code](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/core-lro)
- [Package (npm)](https://www.npmjs.com/package/@azure/core-lro)
- [API Reference Documentation](https://docs.microsoft.com/javascript/api/@azure/core-lro)
- [Samples](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-lro/samples)
## Getting started
### Currently supported environments
- [LTS versions of Node.js](https://github.com/nodejs/release#release-schedule)
- Latest versions of Safari, Chrome, Edge, and Firefox.
### Installation
This package is primarily used in generated code and not meant to be consumed directly by end users.
## Key concepts
### `SimplePollerLike`
A poller is an object that can poll the long running operation on the server for its state until it reaches a terminal state. It provides the following methods:
- `getOperationState`: returns the state of the operation, typed as a type that extends `OperationState`
- `getResult`: returns the result of the operation when it completes and `undefined` otherwise
- `isDone`: returns whether the operation is in a terminal state
- `isStopped`: returns whether the polling stopped
- `onProgress`: registers callback functions to be called every time a polling response is received
- `poll`: sends a single polling request
- `pollUntilDone`: returns a promise that will resolve with the result of the operation
- `stopPolling`: stops polling;
- `toString`: serializes the state of the poller
### `OperationState`
A type for the operation state. It contains a `status` field with the following possible values: `notStarted`, `running`, `succeeded`, `failed`, and `canceled`. It can be accessed as follows:
```typescript
switch(poller.getOperationState().status) {
case "succeeded": // return poller.getResult();
case "failed": // throw poller.getOperationState().error;
case "canceled": // throw new Error("Operation was canceled");
case "running": // ...
case "notStarted": // ...
}
```
### `createHttpPoller`
A function that returns an object of type `SimplePollerLike`. This poller behaves as follows in the presence of errors:
- calls to `poll` and `pollUntilDone` will throw an error in case the operation has failed or canceled unless the `resolveOnUnsuccessful` option was set to true.
- `poller.getOperationState().status` will be set to true when either the operation fails or it returns an error response.
## Examples
Examples can be found in the `samples` folder.
## Troubleshooting
### Logging
Logs can be added at the discretion of the library implementing the Long Running Operation poller.
Packages inside of [azure-sdk-for-js](https://github.com/Azure/azure-sdk-for-js) use
[@azure/logger](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/logger).
## Next steps
Please take a look at the [samples](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-lro/samples) directory for detailed examples on how to use this library.
## Contributing
If you'd like to contribute to this library, please read the [contributing guide](https://github.com/Azure/azure-sdk-for-js/blob/main/CONTRIBUTING.md) to learn more about how to build and test the code.
### Testing
To run our tests, first install the dependencies (with `npm install` or `rush install`),
then run the unit tests with: `npm run unit-test`.
### Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fcore%2Fcore-lro%2FREADME.png)

View file

@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=models.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../src/http/models.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AbortSignalLike } from \"@azure/abort-controller\";\nimport { LroError } from \"../poller/models\";\n\n// TODO: rename to ResourceLocationConfig\n/**\n * The potential location of the result of the LRO if specified by the LRO extension in the swagger.\n */\nexport type LroResourceLocationConfig = \"azure-async-operation\" | \"location\" | \"original-uri\";\n\n/**\n * The type of a LRO response body. This is just a convenience type for checking the status of the operation.\n */\n\nexport interface ResponseBody extends Record<string, unknown> {\n /** The status of the operation. */\n status?: unknown;\n /** The state of the provisioning process */\n provisioningState?: unknown;\n /** The properties of the provisioning process */\n properties?: { provisioningState?: unknown } & Record<string, unknown>;\n /** The error if the operation failed */\n error?: Partial<LroError>;\n /** The location of the created resource */\n resourceLocation?: string;\n}\n\n/**\n * Simple type of the raw response.\n */\nexport interface RawResponse {\n /** The HTTP status code */\n statusCode: number;\n /** A HttpHeaders collection in the response represented as a simple JSON object where all header names have been normalized to be lower-case. */\n headers: {\n [headerName: string]: string;\n };\n /** The parsed response body */\n body?: unknown;\n}\n\n// TODO: rename to OperationResponse\n/**\n * The type of the response of a LRO.\n */\nexport interface LroResponse<T = unknown> {\n /** The flattened response */\n flatResponse: T;\n /** The raw response */\n rawResponse: RawResponse;\n}\n\n/**\n * Description of a long running operation.\n */\nexport interface LongRunningOperation<T = unknown> {\n /**\n * The request path. This should be set if the operation is a PUT and needs\n * to poll from the same request path.\n */\n requestPath?: string;\n /**\n * The HTTP request method. This should be set if the operation is a PUT or a\n * DELETE.\n */\n requestMethod?: string;\n /**\n * A function that can be used to send initial request to the service.\n */\n sendInitialRequest: () => Promise<LroResponse<unknown>>;\n /**\n * A function that can be used to poll for the current status of a long running operation.\n */\n sendPollRequest: (\n path: string,\n options?: { abortSignal?: AbortSignalLike },\n ) => Promise<LroResponse<T>>;\n}\n\nexport type HttpOperationMode = \"OperationLocation\" | \"ResourceLocation\" | \"Body\";\n\n/**\n * Options for `createPoller`.\n */\nexport interface CreateHttpPollerOptions<TResult, TState> {\n /**\n * Defines how much time the poller is going to wait before making a new request to the service.\n */\n intervalInMs?: number;\n /**\n * A serialized poller which can be used to resume an existing paused Long-Running-Operation.\n */\n restoreFrom?: string;\n /**\n * The potential location of the result of the LRO if specified by the LRO extension in the swagger.\n */\n resourceLocationConfig?: LroResourceLocationConfig;\n /**\n * A function to process the result of the LRO.\n */\n processResult?: (result: unknown, state: TState) => TResult;\n /**\n * A function to process the state of the LRO.\n */\n updateState?: (state: TState, response: LroResponse) => void;\n /**\n * A function to be called each time the operation location is updated by the\n * service.\n */\n withOperationLocation?: (operationLocation: string) => void;\n /**\n * Control whether to throw an exception if the operation failed or was canceled.\n */\n resolveOnUnsuccessful?: boolean;\n}\n"]}

View file

@ -0,0 +1,282 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { initOperation, pollOperation } from "../poller/operation";
import { logger } from "../logger";
function getOperationLocationPollingUrl(inputs) {
const { azureAsyncOperation, operationLocation } = inputs;
return operationLocation !== null && operationLocation !== void 0 ? operationLocation : azureAsyncOperation;
}
function getLocationHeader(rawResponse) {
return rawResponse.headers["location"];
}
function getOperationLocationHeader(rawResponse) {
return rawResponse.headers["operation-location"];
}
function getAzureAsyncOperationHeader(rawResponse) {
return rawResponse.headers["azure-asyncoperation"];
}
function findResourceLocation(inputs) {
var _a;
const { location, requestMethod, requestPath, resourceLocationConfig } = inputs;
switch (requestMethod) {
case "PUT": {
return requestPath;
}
case "DELETE": {
return undefined;
}
case "PATCH": {
return (_a = getDefault()) !== null && _a !== void 0 ? _a : requestPath;
}
default: {
return getDefault();
}
}
function getDefault() {
switch (resourceLocationConfig) {
case "azure-async-operation": {
return undefined;
}
case "original-uri": {
return requestPath;
}
case "location":
default: {
return location;
}
}
}
}
export function inferLroMode(inputs) {
const { rawResponse, requestMethod, requestPath, resourceLocationConfig } = inputs;
const operationLocation = getOperationLocationHeader(rawResponse);
const azureAsyncOperation = getAzureAsyncOperationHeader(rawResponse);
const pollingUrl = getOperationLocationPollingUrl({ operationLocation, azureAsyncOperation });
const location = getLocationHeader(rawResponse);
const normalizedRequestMethod = requestMethod === null || requestMethod === void 0 ? void 0 : requestMethod.toLocaleUpperCase();
if (pollingUrl !== undefined) {
return {
mode: "OperationLocation",
operationLocation: pollingUrl,
resourceLocation: findResourceLocation({
requestMethod: normalizedRequestMethod,
location,
requestPath,
resourceLocationConfig,
}),
};
}
else if (location !== undefined) {
return {
mode: "ResourceLocation",
operationLocation: location,
};
}
else if (normalizedRequestMethod === "PUT" && requestPath) {
return {
mode: "Body",
operationLocation: requestPath,
};
}
else {
return undefined;
}
}
function transformStatus(inputs) {
const { status, statusCode } = inputs;
if (typeof status !== "string" && status !== undefined) {
throw new Error(`Polling was unsuccessful. Expected status to have a string value or no value but it has instead: ${status}. This doesn't necessarily indicate the operation has failed. Check your Azure subscription or resource status for more information.`);
}
switch (status === null || status === void 0 ? void 0 : status.toLocaleLowerCase()) {
case undefined:
return toOperationStatus(statusCode);
case "succeeded":
return "succeeded";
case "failed":
return "failed";
case "running":
case "accepted":
case "started":
case "canceling":
case "cancelling":
return "running";
case "canceled":
case "cancelled":
return "canceled";
default: {
logger.verbose(`LRO: unrecognized operation status: ${status}`);
return status;
}
}
}
function getStatus(rawResponse) {
var _a;
const { status } = (_a = rawResponse.body) !== null && _a !== void 0 ? _a : {};
return transformStatus({ status, statusCode: rawResponse.statusCode });
}
function getProvisioningState(rawResponse) {
var _a, _b;
const { properties, provisioningState } = (_a = rawResponse.body) !== null && _a !== void 0 ? _a : {};
const status = (_b = properties === null || properties === void 0 ? void 0 : properties.provisioningState) !== null && _b !== void 0 ? _b : provisioningState;
return transformStatus({ status, statusCode: rawResponse.statusCode });
}
function toOperationStatus(statusCode) {
if (statusCode === 202) {
return "running";
}
else if (statusCode < 300) {
return "succeeded";
}
else {
return "failed";
}
}
export function parseRetryAfter({ rawResponse }) {
const retryAfter = rawResponse.headers["retry-after"];
if (retryAfter !== undefined) {
// Retry-After header value is either in HTTP date format, or in seconds
const retryAfterInSeconds = parseInt(retryAfter);
return isNaN(retryAfterInSeconds)
? calculatePollingIntervalFromDate(new Date(retryAfter))
: retryAfterInSeconds * 1000;
}
return undefined;
}
export function getErrorFromResponse(response) {
const error = accessBodyProperty(response, "error");
if (!error) {
logger.warning(`The long-running operation failed but there is no error property in the response's body`);
return;
}
if (!error.code || !error.message) {
logger.warning(`The long-running operation failed but the error property in the response's body doesn't contain code or message`);
return;
}
return error;
}
function calculatePollingIntervalFromDate(retryAfterDate) {
const timeNow = Math.floor(new Date().getTime());
const retryAfterTime = retryAfterDate.getTime();
if (timeNow < retryAfterTime) {
return retryAfterTime - timeNow;
}
return undefined;
}
export function getStatusFromInitialResponse(inputs) {
const { response, state, operationLocation } = inputs;
function helper() {
var _a;
const mode = (_a = state.config.metadata) === null || _a === void 0 ? void 0 : _a["mode"];
switch (mode) {
case undefined:
return toOperationStatus(response.rawResponse.statusCode);
case "Body":
return getOperationStatus(response, state);
default:
return "running";
}
}
const status = helper();
return status === "running" && operationLocation === undefined ? "succeeded" : status;
}
/**
* Initiates the long-running operation.
*/
export async function initHttpOperation(inputs) {
const { stateProxy, resourceLocationConfig, processResult, lro, setErrorAsResult } = inputs;
return initOperation({
init: async () => {
const response = await lro.sendInitialRequest();
const config = inferLroMode({
rawResponse: response.rawResponse,
requestPath: lro.requestPath,
requestMethod: lro.requestMethod,
resourceLocationConfig,
});
return Object.assign({ response, operationLocation: config === null || config === void 0 ? void 0 : config.operationLocation, resourceLocation: config === null || config === void 0 ? void 0 : config.resourceLocation }, ((config === null || config === void 0 ? void 0 : config.mode) ? { metadata: { mode: config.mode } } : {}));
},
stateProxy,
processResult: processResult
? ({ flatResponse }, state) => processResult(flatResponse, state)
: ({ flatResponse }) => flatResponse,
getOperationStatus: getStatusFromInitialResponse,
setErrorAsResult,
});
}
export function getOperationLocation({ rawResponse }, state) {
var _a;
const mode = (_a = state.config.metadata) === null || _a === void 0 ? void 0 : _a["mode"];
switch (mode) {
case "OperationLocation": {
return getOperationLocationPollingUrl({
operationLocation: getOperationLocationHeader(rawResponse),
azureAsyncOperation: getAzureAsyncOperationHeader(rawResponse),
});
}
case "ResourceLocation": {
return getLocationHeader(rawResponse);
}
case "Body":
default: {
return undefined;
}
}
}
export function getOperationStatus({ rawResponse }, state) {
var _a;
const mode = (_a = state.config.metadata) === null || _a === void 0 ? void 0 : _a["mode"];
switch (mode) {
case "OperationLocation": {
return getStatus(rawResponse);
}
case "ResourceLocation": {
return toOperationStatus(rawResponse.statusCode);
}
case "Body": {
return getProvisioningState(rawResponse);
}
default:
throw new Error(`Internal error: Unexpected operation mode: ${mode}`);
}
}
function accessBodyProperty({ flatResponse, rawResponse }, prop) {
var _a, _b;
return (_a = flatResponse === null || flatResponse === void 0 ? void 0 : flatResponse[prop]) !== null && _a !== void 0 ? _a : (_b = rawResponse.body) === null || _b === void 0 ? void 0 : _b[prop];
}
export function getResourceLocation(res, state) {
const loc = accessBodyProperty(res, "resourceLocation");
if (loc && typeof loc === "string") {
state.config.resourceLocation = loc;
}
return state.config.resourceLocation;
}
export function isOperationError(e) {
return e.name === "RestError";
}
/** Polls the long-running operation. */
export async function pollHttpOperation(inputs) {
const { lro, stateProxy, options, processResult, updateState, setDelay, state, setErrorAsResult, } = inputs;
return pollOperation({
state,
stateProxy,
setDelay,
processResult: processResult
? ({ flatResponse }, inputState) => processResult(flatResponse, inputState)
: ({ flatResponse }) => flatResponse,
getError: getErrorFromResponse,
updateState,
getPollingInterval: parseRetryAfter,
getOperationLocation,
getOperationStatus,
isOperationError,
getResourceLocation,
options,
/**
* The expansion here is intentional because `lro` could be an object that
* references an inner this, so we need to preserve a reference to it.
*/
poll: async (location, inputOptions) => lro.sendPollRequest(location, inputOptions),
setErrorAsResult,
});
}
//# sourceMappingURL=operation.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { getErrorFromResponse, getOperationLocation, getOperationStatus, getResourceLocation, getStatusFromInitialResponse, inferLroMode, isOperationError, parseRetryAfter, } from "./operation";
import { buildCreatePoller } from "../poller/poller";
/**
* Creates a poller that can be used to poll a long-running operation.
* @param lro - Description of the long-running operation
* @param options - options to configure the poller
* @returns an initialized poller
*/
export async function createHttpPoller(lro, options) {
const { resourceLocationConfig, intervalInMs, processResult, restoreFrom, updateState, withOperationLocation, resolveOnUnsuccessful = false, } = options || {};
return buildCreatePoller({
getStatusFromInitialResponse,
getStatusFromPollResponse: getOperationStatus,
isOperationError,
getOperationLocation,
getResourceLocation,
getPollingInterval: parseRetryAfter,
getError: getErrorFromResponse,
resolveOnUnsuccessful,
})({
init: async () => {
const response = await lro.sendInitialRequest();
const config = inferLroMode({
rawResponse: response.rawResponse,
requestPath: lro.requestPath,
requestMethod: lro.requestMethod,
resourceLocationConfig,
});
return Object.assign({ response, operationLocation: config === null || config === void 0 ? void 0 : config.operationLocation, resourceLocation: config === null || config === void 0 ? void 0 : config.resourceLocation }, ((config === null || config === void 0 ? void 0 : config.mode) ? { metadata: { mode: config.mode } } : {}));
},
poll: lro.sendPollRequest,
}, {
intervalInMs,
withOperationLocation,
restoreFrom,
updateState,
processResult: processResult
? ({ flatResponse }, state) => processResult(flatResponse, state)
: ({ flatResponse }) => flatResponse,
});
}
//# sourceMappingURL=poller.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"poller.js","sourceRoot":"","sources":["../../../src/http/poller.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,4BAA4B,EAC5B,YAAY,EACZ,gBAAgB,EAChB,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAyB,EACzB,OAAkD;IAElD,MAAM,EACJ,sBAAsB,EACtB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,qBAAqB,EACrB,qBAAqB,GAAG,KAAK,GAC9B,GAAG,OAAO,IAAI,EAAE,CAAC;IAClB,OAAO,iBAAiB,CAA+B;QACrD,4BAA4B;QAC5B,yBAAyB,EAAE,kBAAkB;QAC7C,gBAAgB;QAChB,oBAAoB;QACpB,mBAAmB;QACnB,kBAAkB,EAAE,eAAe;QACnC,QAAQ,EAAE,oBAAoB;QAC9B,qBAAqB;KACtB,CAAC,CACA;QACE,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,kBAAkB,EAAE,CAAC;YAChD,MAAM,MAAM,GAAG,YAAY,CAAC;gBAC1B,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,aAAa,EAAE,GAAG,CAAC,aAAa;gBAChC,sBAAsB;aACvB,CAAC,CAAC;YACH,uBACE,QAAQ,EACR,iBAAiB,EAAE,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,iBAAiB,EAC5C,gBAAgB,EAAE,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,gBAAgB,IACvC,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,EAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAC5D;QACJ,CAAC;QACD,IAAI,EAAE,GAAG,CAAC,eAAe;KAC1B,EACD;QACE,YAAY;QACZ,qBAAqB;QACrB,WAAW;QACX,WAAW;QACX,aAAa,EAAE,aAAa;YAC1B,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,KAAK,CAAC;YACjE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,YAAuB;KAClD,CACF,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { LongRunningOperation, LroResponse } from \"./models\";\nimport { OperationState, SimplePollerLike } from \"../poller/models\";\nimport {\n getErrorFromResponse,\n getOperationLocation,\n getOperationStatus,\n getResourceLocation,\n getStatusFromInitialResponse,\n inferLroMode,\n isOperationError,\n parseRetryAfter,\n} from \"./operation\";\nimport { CreateHttpPollerOptions } from \"./models\";\nimport { buildCreatePoller } from \"../poller/poller\";\n\n/**\n * Creates a poller that can be used to poll a long-running operation.\n * @param lro - Description of the long-running operation\n * @param options - options to configure the poller\n * @returns an initialized poller\n */\nexport async function createHttpPoller<TResult, TState extends OperationState<TResult>>(\n lro: LongRunningOperation,\n options?: CreateHttpPollerOptions<TResult, TState>,\n): Promise<SimplePollerLike<TState, TResult>> {\n const {\n resourceLocationConfig,\n intervalInMs,\n processResult,\n restoreFrom,\n updateState,\n withOperationLocation,\n resolveOnUnsuccessful = false,\n } = options || {};\n return buildCreatePoller<LroResponse, TResult, TState>({\n getStatusFromInitialResponse,\n getStatusFromPollResponse: getOperationStatus,\n isOperationError,\n getOperationLocation,\n getResourceLocation,\n getPollingInterval: parseRetryAfter,\n getError: getErrorFromResponse,\n resolveOnUnsuccessful,\n })(\n {\n init: async () => {\n const response = await lro.sendInitialRequest();\n const config = inferLroMode({\n rawResponse: response.rawResponse,\n requestPath: lro.requestPath,\n requestMethod: lro.requestMethod,\n resourceLocationConfig,\n });\n return {\n response,\n operationLocation: config?.operationLocation,\n resourceLocation: config?.resourceLocation,\n ...(config?.mode ? { metadata: { mode: config.mode } } : {}),\n };\n },\n poll: lro.sendPollRequest,\n },\n {\n intervalInMs,\n withOperationLocation,\n restoreFrom,\n updateState,\n processResult: processResult\n ? ({ flatResponse }, state) => processResult(flatResponse, state)\n : ({ flatResponse }) => flatResponse as TResult,\n },\n );\n}\n"]}

View file

@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export { createHttpPoller } from "./http/poller";
/**
* This can be uncommented to expose the protocol-agnostic poller
*/
// export {
// BuildCreatePollerOptions,
// Operation,
// CreatePollerOptions,
// OperationConfig,
// RestorableOperationState,
// } from "./poller/models";
// export { buildCreatePoller } from "./poller/poller";
/** legacy */
export * from "./legacy/lroEngine";
export * from "./legacy/poller";
export * from "./legacy/pollOperation";
//# sourceMappingURL=index.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAejD;;GAEG;AACH,WAAW;AACX,8BAA8B;AAC9B,eAAe;AACf,yBAAyB;AACzB,qBAAqB;AACrB,8BAA8B;AAC9B,4BAA4B;AAC5B,uDAAuD;AAEvD,aAAa;AACb,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nexport { createHttpPoller } from \"./http/poller\";\nexport {\n CancelOnProgress,\n OperationState,\n OperationStatus,\n SimplePollerLike,\n} from \"./poller/models\";\nexport { CreateHttpPollerOptions } from \"./http/models\";\nexport {\n LroResourceLocationConfig,\n LongRunningOperation,\n LroResponse,\n RawResponse,\n} from \"./http/models\";\n\n/**\n * This can be uncommented to expose the protocol-agnostic poller\n */\n// export {\n// BuildCreatePollerOptions,\n// Operation,\n// CreatePollerOptions,\n// OperationConfig,\n// RestorableOperationState,\n// } from \"./poller/models\";\n// export { buildCreatePoller } from \"./poller/poller\";\n\n/** legacy */\nexport * from \"./legacy/lroEngine\";\nexport * from \"./legacy/poller\";\nexport * from \"./legacy/pollOperation\";\nexport { PollerLike } from \"./legacy/models\";\n"]}

View file

@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export { LroEngine } from "./lroEngine";
//# sourceMappingURL=index.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/legacy/lroEngine/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nexport { LroEngine } from \"./lroEngine\";\nexport { LroEngineOptions } from \"./models\";\n"]}

View file

@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { GenericPollOperation } from "./operation";
import { POLL_INTERVAL_IN_MS } from "../../poller/constants";
import { Poller } from "../poller";
import { deserializeState } from "../../poller/operation";
/**
* The LRO Engine, a class that performs polling.
*/
export class LroEngine extends Poller {
constructor(lro, options) {
const { intervalInMs = POLL_INTERVAL_IN_MS, resumeFrom, resolveOnUnsuccessful = false, isDone, lroResourceLocationConfig, processResult, updateState, } = options || {};
const state = resumeFrom
? deserializeState(resumeFrom)
: {};
const operation = new GenericPollOperation(state, lro, !resolveOnUnsuccessful, lroResourceLocationConfig, processResult, updateState, isDone);
super(operation);
this.resolveOnUnsuccessful = resolveOnUnsuccessful;
this.config = { intervalInMs: intervalInMs };
operation.setPollerConfig(this.config);
}
/**
* The method used by the poller to wait before attempting to update its operation.
*/
delay() {
return new Promise((resolve) => setTimeout(() => resolve(), this.config.intervalInMs));
}
}
//# sourceMappingURL=lroEngine.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"lroEngine.js","sourceRoot":"","sources":["../../../../src/legacy/lroEngine/lroEngine.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;GAEG;AACH,MAAM,OAAO,SAA+D,SAAQ,MAGnF;IAGC,YAAY,GAAkC,EAAE,OAA2C;QACzF,MAAM,EACJ,YAAY,GAAG,mBAAmB,EAClC,UAAU,EACV,qBAAqB,GAAG,KAAK,EAC7B,MAAM,EACN,yBAAyB,EACzB,aAAa,EACb,WAAW,GACZ,GAAG,OAAO,IAAI,EAAE,CAAC;QAClB,MAAM,KAAK,GAAqC,UAAU;YACxD,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC;YAC9B,CAAC,CAAE,EAAuC,CAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,oBAAoB,CACxC,KAAK,EACL,GAAG,EACH,CAAC,qBAAqB,EACtB,yBAAyB,EACzB,aAAa,EACb,WAAW,EACX,MAAM,CACP,CAAC;QACF,KAAK,CAAC,SAAS,CAAC,CAAC;QACjB,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;QAEnD,IAAI,CAAC,MAAM,GAAG,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;QAC7C,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,KAAK;QACH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;IACzF,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { LroEngineOptions, PollerConfig } from \"./models\";\nimport { GenericPollOperation } from \"./operation\";\nimport { LongRunningOperation } from \"../../http/models\";\nimport { POLL_INTERVAL_IN_MS } from \"../../poller/constants\";\nimport { PollOperationState } from \"../pollOperation\";\nimport { Poller } from \"../poller\";\nimport { RestorableOperationState } from \"../../poller/models\";\nimport { deserializeState } from \"../../poller/operation\";\n\n/**\n * The LRO Engine, a class that performs polling.\n */\nexport class LroEngine<TResult, TState extends PollOperationState<TResult>> extends Poller<\n TState,\n TResult\n> {\n private config: PollerConfig;\n\n constructor(lro: LongRunningOperation<TResult>, options?: LroEngineOptions<TResult, TState>) {\n const {\n intervalInMs = POLL_INTERVAL_IN_MS,\n resumeFrom,\n resolveOnUnsuccessful = false,\n isDone,\n lroResourceLocationConfig,\n processResult,\n updateState,\n } = options || {};\n const state: RestorableOperationState<TState> = resumeFrom\n ? deserializeState(resumeFrom)\n : ({} as RestorableOperationState<TState>);\n const operation = new GenericPollOperation(\n state,\n lro,\n !resolveOnUnsuccessful,\n lroResourceLocationConfig,\n processResult,\n updateState,\n isDone,\n );\n super(operation);\n this.resolveOnUnsuccessful = resolveOnUnsuccessful;\n\n this.config = { intervalInMs: intervalInMs };\n operation.setPollerConfig(this.config);\n }\n\n /**\n * The method used by the poller to wait before attempting to update its operation.\n */\n delay(): Promise<void> {\n return new Promise((resolve) => setTimeout(() => resolve(), this.config.intervalInMs));\n }\n}\n"]}

View file

@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=models.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../../src/legacy/lroEngine/models.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { LroResourceLocationConfig, RawResponse } from \"../../http/models\";\n\n/**\n * Options for the LRO poller.\n */\nexport interface LroEngineOptions<TResult, TState> {\n /**\n * Defines how much time the poller is going to wait before making a new request to the service.\n */\n intervalInMs?: number;\n /**\n * A serialized poller which can be used to resume an existing paused Long-Running-Operation.\n */\n resumeFrom?: string;\n /**\n * The potential location of the result of the LRO if specified by the LRO extension in the swagger.\n */\n lroResourceLocationConfig?: LroResourceLocationConfig;\n /**\n * A function to process the result of the LRO.\n */\n processResult?: (result: unknown, state: TState) => TResult;\n /**\n * A function to process the state of the LRO.\n */\n updateState?: (state: TState, lastResponse: RawResponse) => void;\n /**\n * A predicate to determine whether the LRO finished processing.\n */\n isDone?: (lastResponse: unknown, state: TState) => boolean;\n /**\n * Control whether to throw an exception if the operation failed or was canceled.\n */\n resolveOnUnsuccessful?: boolean;\n}\n\nexport interface PollerConfig {\n intervalInMs: number;\n}\n"]}

View file

@ -0,0 +1,84 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { initHttpOperation, pollHttpOperation } from "../../http/operation";
import { logger } from "../../logger";
const createStateProxy = () => ({
initState: (config) => ({ config, isStarted: true }),
setCanceled: (state) => (state.isCancelled = true),
setError: (state, error) => (state.error = error),
setResult: (state, result) => (state.result = result),
setRunning: (state) => (state.isStarted = true),
setSucceeded: (state) => (state.isCompleted = true),
setFailed: () => {
/** empty body */
},
getError: (state) => state.error,
getResult: (state) => state.result,
isCanceled: (state) => !!state.isCancelled,
isFailed: (state) => !!state.error,
isRunning: (state) => !!state.isStarted,
isSucceeded: (state) => Boolean(state.isCompleted && !state.isCancelled && !state.error),
});
export class GenericPollOperation {
constructor(state, lro, setErrorAsResult, lroResourceLocationConfig, processResult, updateState, isDone) {
this.state = state;
this.lro = lro;
this.setErrorAsResult = setErrorAsResult;
this.lroResourceLocationConfig = lroResourceLocationConfig;
this.processResult = processResult;
this.updateState = updateState;
this.isDone = isDone;
}
setPollerConfig(pollerConfig) {
this.pollerConfig = pollerConfig;
}
async update(options) {
var _a;
const stateProxy = createStateProxy();
if (!this.state.isStarted) {
this.state = Object.assign(Object.assign({}, this.state), (await initHttpOperation({
lro: this.lro,
stateProxy,
resourceLocationConfig: this.lroResourceLocationConfig,
processResult: this.processResult,
setErrorAsResult: this.setErrorAsResult,
})));
}
const updateState = this.updateState;
const isDone = this.isDone;
if (!this.state.isCompleted && this.state.error === undefined) {
await pollHttpOperation({
lro: this.lro,
state: this.state,
stateProxy,
processResult: this.processResult,
updateState: updateState
? (state, { rawResponse }) => updateState(state, rawResponse)
: undefined,
isDone: isDone
? ({ flatResponse }, state) => isDone(flatResponse, state)
: undefined,
options,
setDelay: (intervalInMs) => {
this.pollerConfig.intervalInMs = intervalInMs;
},
setErrorAsResult: this.setErrorAsResult,
});
}
(_a = options === null || options === void 0 ? void 0 : options.fireProgress) === null || _a === void 0 ? void 0 : _a.call(options, this.state);
return this;
}
async cancel() {
logger.error("`cancelOperation` is deprecated because it wasn't implemented");
return this;
}
/**
* Serializes the Poller operation.
*/
toString() {
return JSON.stringify({
state: this.state,
});
}
}
//# sourceMappingURL=operation.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=models.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../src/legacy/models.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AbortSignalLike } from \"@azure/abort-controller\";\nimport { CancelOnProgress } from \"../poller/models\";\nimport { PollOperationState } from \"./pollOperation\";\n\n/**\n * Abstract representation of a poller, intended to expose just the minimal API that the user needs to work with.\n */\n// eslint-disable-next-line no-use-before-define\nexport interface PollerLike<TState extends PollOperationState<TResult>, TResult> {\n /**\n * Returns a promise that will resolve once a single polling request finishes.\n * It does this by calling the update method of the Poller's operation.\n */\n poll(options?: { abortSignal?: AbortSignalLike }): Promise<void>;\n /**\n * Returns a promise that will resolve once the underlying operation is completed.\n */\n pollUntilDone(pollOptions?: { abortSignal?: AbortSignalLike }): Promise<TResult>;\n /**\n * Invokes the provided callback after each polling is completed,\n * sending the current state of the poller's operation.\n *\n * It returns a method that can be used to stop receiving updates on the given callback function.\n */\n onProgress(callback: (state: TState) => void): CancelOnProgress;\n /**\n * Returns true if the poller has finished polling.\n */\n isDone(): boolean;\n /**\n * Stops the poller. After this, no manual or automated requests can be sent.\n */\n stopPolling(): void;\n /**\n * Returns true if the poller is stopped.\n */\n isStopped(): boolean;\n /**\n * Attempts to cancel the underlying operation.\n * @deprecated `cancelOperation` has been deprecated because it was not implemented.\n */\n cancelOperation(options?: { abortSignal?: AbortSignalLike }): Promise<void>;\n /**\n * Returns the state of the operation.\n * The TState defined in PollerLike can be a subset of the TState defined in\n * the Poller implementation.\n */\n getOperationState(): TState;\n /**\n * Returns the result value of the operation,\n * regardless of the state of the poller.\n * It can return undefined or an incomplete form of the final TResult value\n * depending on the implementation.\n */\n getResult(): TResult | undefined;\n /**\n * Returns a serialized version of the poller's operation\n * by invoking the operation's toString method.\n */\n toString(): string;\n}\n"]}

View file

@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=pollOperation.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"pollOperation.js","sourceRoot":"","sources":["../../../src/legacy/pollOperation.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AbortSignalLike } from \"@azure/abort-controller\";\n\n/**\n * PollOperationState contains an opinionated list of the smallest set of properties needed\n * to define any long running operation poller.\n *\n * While the Poller class works as the local control mechanism to start triggering, wait for,\n * and potentially cancel a long running operation, the PollOperationState documents the status\n * of the remote long running operation.\n *\n * It should be updated at least when the operation starts, when it's finished, and when it's cancelled.\n * Though, implementations can have any other number of properties that can be updated by other reasons.\n */\nexport interface PollOperationState<TResult> {\n /**\n * True if the operation has started.\n */\n isStarted?: boolean;\n /**\n * True if the operation has been completed.\n */\n isCompleted?: boolean;\n /**\n * True if the operation has been cancelled.\n */\n isCancelled?: boolean;\n /**\n * Will exist if the operation encountered any error.\n */\n error?: Error;\n /**\n * Will exist if the operation concluded in a result of an expected type.\n */\n result?: TResult;\n}\n\n/**\n * PollOperation is an interface that defines how to update the local reference of the state of the remote\n * long running operation, just as well as how to request the cancellation of the same operation.\n *\n * It also has a method to serialize the operation so that it can be stored and resumed at any time.\n */\nexport interface PollOperation<TState, TResult> {\n /**\n * The state of the operation.\n * It will be used to store the basic properties of PollOperationState<TResult>,\n * plus any custom property that the implementation may require.\n */\n state: TState;\n\n /**\n * Defines how to request the remote service for updates on the status of the long running operation.\n *\n * It optionally receives an object with an abortSignal property, from \\@azure/abort-controller's AbortSignalLike.\n * Also optionally receives a \"fireProgress\" function, which, if called, is responsible for triggering the\n * poller's onProgress callbacks.\n *\n * @param options - Optional properties passed to the operation's update method.\n */\n update(options?: {\n abortSignal?: AbortSignalLike;\n fireProgress?: (state: TState) => void;\n }): Promise<PollOperation<TState, TResult>>;\n\n /**\n * Attempts to cancel the underlying operation.\n *\n * It only optionally receives an object with an abortSignal property, from \\@azure/abort-controller's AbortSignalLike.\n *\n * It returns a promise that should be resolved with an updated version of the poller's operation.\n *\n * @param options - Optional properties passed to the operation's update method.\n *\n * @deprecated `cancel` has been deprecated because it was not implemented.\n */\n cancel(options?: { abortSignal?: AbortSignalLike }): Promise<PollOperation<TState, TResult>>;\n\n /**\n * Serializes the operation.\n * Useful when wanting to create a poller that monitors an existing operation.\n */\n toString(): string;\n}\n"]}

View file

@ -0,0 +1,397 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
* When a poller is manually stopped through the `stopPolling` method,
* the poller will be rejected with an instance of the PollerStoppedError.
*/
export class PollerStoppedError extends Error {
constructor(message) {
super(message);
this.name = "PollerStoppedError";
Object.setPrototypeOf(this, PollerStoppedError.prototype);
}
}
/**
* When the operation is cancelled, the poller will be rejected with an instance
* of the PollerCancelledError.
*/
export class PollerCancelledError extends Error {
constructor(message) {
super(message);
this.name = "PollerCancelledError";
Object.setPrototypeOf(this, PollerCancelledError.prototype);
}
}
/**
* A class that represents the definition of a program that polls through consecutive requests
* until it reaches a state of completion.
*
* A poller can be executed manually, by polling request by request by calling to the `poll()` method repeatedly, until its operation is completed.
* It also provides a way to wait until the operation completes, by calling `pollUntilDone()` and waiting until the operation finishes.
* Pollers can also request the cancellation of the ongoing process to whom is providing the underlying long running operation.
*
* ```ts
* const poller = new MyPoller();
*
* // Polling just once:
* await poller.poll();
*
* // We can try to cancel the request here, by calling:
* //
* // await poller.cancelOperation();
* //
*
* // Getting the final result:
* const result = await poller.pollUntilDone();
* ```
*
* The Poller is defined by two types, a type representing the state of the poller, which
* must include a basic set of properties from `PollOperationState<TResult>`,
* and a return type defined by `TResult`, which can be anything.
*
* The Poller class implements the `PollerLike` interface, which allows poller implementations to avoid having
* to export the Poller's class directly, and instead only export the already instantiated poller with the PollerLike type.
*
* ```ts
* class Client {
* public async makePoller: PollerLike<MyOperationState, MyResult> {
* const poller = new MyPoller({});
* // It might be preferred to return the poller after the first request is made,
* // so that some information can be obtained right away.
* await poller.poll();
* return poller;
* }
* }
*
* const poller: PollerLike<MyOperationState, MyResult> = myClient.makePoller();
* ```
*
* A poller can be created through its constructor, then it can be polled until it's completed.
* At any point in time, the state of the poller can be obtained without delay through the getOperationState method.
* At any point in time, the intermediate forms of the result type can be requested without delay.
* Once the underlying operation is marked as completed, the poller will stop and the final value will be returned.
*
* ```ts
* const poller = myClient.makePoller();
* const state: MyOperationState = poller.getOperationState();
*
* // The intermediate result can be obtained at any time.
* const result: MyResult | undefined = poller.getResult();
*
* // The final result can only be obtained after the poller finishes.
* const result: MyResult = await poller.pollUntilDone();
* ```
*
*/
// eslint-disable-next-line no-use-before-define
export class Poller {
/**
* A poller needs to be initialized by passing in at least the basic properties of the `PollOperation<TState, TResult>`.
*
* When writing an implementation of a Poller, this implementation needs to deal with the initialization
* of any custom state beyond the basic definition of the poller. The basic poller assumes that the poller's
* operation has already been defined, at least its basic properties. The code below shows how to approach
* the definition of the constructor of a new custom poller.
*
* ```ts
* export class MyPoller extends Poller<MyOperationState, string> {
* constructor({
* // Anything you might need outside of the basics
* }) {
* let state: MyOperationState = {
* privateProperty: private,
* publicProperty: public,
* };
*
* const operation = {
* state,
* update,
* cancel,
* toString
* }
*
* // Sending the operation to the parent's constructor.
* super(operation);
*
* // You can assign more local properties here.
* }
* }
* ```
*
* Inside of this constructor, a new promise is created. This will be used to
* tell the user when the poller finishes (see `pollUntilDone()`). The promise's
* resolve and reject methods are also used internally to control when to resolve
* or reject anyone waiting for the poller to finish.
*
* The constructor of a custom implementation of a poller is where any serialized version of
* a previous poller's operation should be deserialized into the operation sent to the
* base constructor. For example:
*
* ```ts
* export class MyPoller extends Poller<MyOperationState, string> {
* constructor(
* baseOperation: string | undefined
* ) {
* let state: MyOperationState = {};
* if (baseOperation) {
* state = {
* ...JSON.parse(baseOperation).state,
* ...state
* };
* }
* const operation = {
* state,
* // ...
* }
* super(operation);
* }
* }
* ```
*
* @param operation - Must contain the basic properties of `PollOperation<State, TResult>`.
*/
constructor(operation) {
/** controls whether to throw an error if the operation failed or was canceled. */
this.resolveOnUnsuccessful = false;
this.stopped = true;
this.pollProgressCallbacks = [];
this.operation = operation;
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
// This prevents the UnhandledPromiseRejectionWarning in node.js from being thrown.
// The above warning would get thrown if `poller.poll` is called, it returns an error,
// and pullUntilDone did not have a .catch or await try/catch on it's return value.
this.promise.catch(() => {
/* intentionally blank */
});
}
/**
* Starts a loop that will break only if the poller is done
* or if the poller is stopped.
*/
async startPolling(pollOptions = {}) {
if (this.stopped) {
this.stopped = false;
}
while (!this.isStopped() && !this.isDone()) {
await this.poll(pollOptions);
await this.delay();
}
}
/**
* pollOnce does one polling, by calling to the update method of the underlying
* poll operation to make any relevant change effective.
*
* It only optionally receives an object with an abortSignal property, from \@azure/abort-controller's AbortSignalLike.
*
* @param options - Optional properties passed to the operation's update method.
*/
async pollOnce(options = {}) {
if (!this.isDone()) {
this.operation = await this.operation.update({
abortSignal: options.abortSignal,
fireProgress: this.fireProgress.bind(this),
});
}
this.processUpdatedState();
}
/**
* fireProgress calls the functions passed in via onProgress the method of the poller.
*
* It loops over all of the callbacks received from onProgress, and executes them, sending them
* the current operation state.
*
* @param state - The current operation state.
*/
fireProgress(state) {
for (const callback of this.pollProgressCallbacks) {
callback(state);
}
}
/**
* Invokes the underlying operation's cancel method.
*/
async cancelOnce(options = {}) {
this.operation = await this.operation.cancel(options);
}
/**
* Returns a promise that will resolve once a single polling request finishes.
* It does this by calling the update method of the Poller's operation.
*
* It only optionally receives an object with an abortSignal property, from \@azure/abort-controller's AbortSignalLike.
*
* @param options - Optional properties passed to the operation's update method.
*/
poll(options = {}) {
if (!this.pollOncePromise) {
this.pollOncePromise = this.pollOnce(options);
const clearPollOncePromise = () => {
this.pollOncePromise = undefined;
};
this.pollOncePromise.then(clearPollOncePromise, clearPollOncePromise).catch(this.reject);
}
return this.pollOncePromise;
}
processUpdatedState() {
if (this.operation.state.error) {
this.stopped = true;
if (!this.resolveOnUnsuccessful) {
this.reject(this.operation.state.error);
throw this.operation.state.error;
}
}
if (this.operation.state.isCancelled) {
this.stopped = true;
if (!this.resolveOnUnsuccessful) {
const error = new PollerCancelledError("Operation was canceled");
this.reject(error);
throw error;
}
}
if (this.isDone() && this.resolve) {
// If the poller has finished polling, this means we now have a result.
// However, it can be the case that TResult is instantiated to void, so
// we are not expecting a result anyway. To assert that we might not
// have a result eventually after finishing polling, we cast the result
// to TResult.
this.resolve(this.getResult());
}
}
/**
* Returns a promise that will resolve once the underlying operation is completed.
*/
async pollUntilDone(pollOptions = {}) {
if (this.stopped) {
this.startPolling(pollOptions).catch(this.reject);
}
// This is needed because the state could have been updated by
// `cancelOperation`, e.g. the operation is canceled or an error occurred.
this.processUpdatedState();
return this.promise;
}
/**
* Invokes the provided callback after each polling is completed,
* sending the current state of the poller's operation.
*
* It returns a method that can be used to stop receiving updates on the given callback function.
*/
onProgress(callback) {
this.pollProgressCallbacks.push(callback);
return () => {
this.pollProgressCallbacks = this.pollProgressCallbacks.filter((c) => c !== callback);
};
}
/**
* Returns true if the poller has finished polling.
*/
isDone() {
const state = this.operation.state;
return Boolean(state.isCompleted || state.isCancelled || state.error);
}
/**
* Stops the poller from continuing to poll.
*/
stopPolling() {
if (!this.stopped) {
this.stopped = true;
if (this.reject) {
this.reject(new PollerStoppedError("This poller is already stopped"));
}
}
}
/**
* Returns true if the poller is stopped.
*/
isStopped() {
return this.stopped;
}
/**
* Attempts to cancel the underlying operation.
*
* It only optionally receives an object with an abortSignal property, from \@azure/abort-controller's AbortSignalLike.
*
* If it's called again before it finishes, it will throw an error.
*
* @param options - Optional properties passed to the operation's update method.
*/
cancelOperation(options = {}) {
if (!this.cancelPromise) {
this.cancelPromise = this.cancelOnce(options);
}
else if (options.abortSignal) {
throw new Error("A cancel request is currently pending");
}
return this.cancelPromise;
}
/**
* Returns the state of the operation.
*
* Even though TState will be the same type inside any of the methods of any extension of the Poller class,
* implementations of the pollers can customize what's shared with the public by writing their own
* version of the `getOperationState` method, and by defining two types, one representing the internal state of the poller
* and a public type representing a safe to share subset of the properties of the internal state.
* Their definition of getOperationState can then return their public type.
*
* Example:
*
* ```ts
* // Let's say we have our poller's operation state defined as:
* interface MyOperationState extends PollOperationState<ResultType> {
* privateProperty?: string;
* publicProperty?: string;
* }
*
* // To allow us to have a true separation of public and private state, we have to define another interface:
* interface PublicState extends PollOperationState<ResultType> {
* publicProperty?: string;
* }
*
* // Then, we define our Poller as follows:
* export class MyPoller extends Poller<MyOperationState, ResultType> {
* // ... More content is needed here ...
*
* public getOperationState(): PublicState {
* const state: PublicState = this.operation.state;
* return {
* // Properties from PollOperationState<TResult>
* isStarted: state.isStarted,
* isCompleted: state.isCompleted,
* isCancelled: state.isCancelled,
* error: state.error,
* result: state.result,
*
* // The only other property needed by PublicState.
* publicProperty: state.publicProperty
* }
* }
* }
* ```
*
* You can see this in the tests of this repository, go to the file:
* `../test/utils/testPoller.ts`
* and look for the getOperationState implementation.
*/
getOperationState() {
return this.operation.state;
}
/**
* Returns the result value of the operation,
* regardless of the state of the poller.
* It can return undefined or an incomplete form of the final TResult value
* depending on the implementation.
*/
getResult() {
const state = this.operation.state;
return state.result;
}
/**
* Returns a serialized version of the poller's operation
* by invoking the operation's toString method.
*/
toString() {
return this.operation.toString();
}
}
//# sourceMappingURL=poller.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,9 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { createClientLogger } from "@azure/logger";
/**
* The `@azure/logger` configuration for this package.
* @internal
*/
export const logger = createClientLogger("core-lro");
//# sourceMappingURL=logger.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { createClientLogger } from \"@azure/logger\";\n\n/**\n * The `@azure/logger` configuration for this package.\n * @internal\n */\nexport const logger = createClientLogger(\"core-lro\");\n"]}

View file

@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
* The default time interval to wait before sending the next polling request.
*/
export const POLL_INTERVAL_IN_MS = 2000;
/**
* The closed set of terminal states.
*/
export const terminalStates = ["succeeded", "canceled", "failed"];
//# sourceMappingURL=constants.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/poller/constants.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AACxC;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * The default time interval to wait before sending the next polling request.\n */\nexport const POLL_INTERVAL_IN_MS = 2000;\n/**\n * The closed set of terminal states.\n */\nexport const terminalStates = [\"succeeded\", \"canceled\", \"failed\"];\n"]}

View file

@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=models.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,166 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { logger } from "../logger";
import { terminalStates } from "./constants";
/**
* Deserializes the state
*/
export function deserializeState(serializedState) {
try {
return JSON.parse(serializedState).state;
}
catch (e) {
throw new Error(`Unable to deserialize input state: ${serializedState}`);
}
}
function setStateError(inputs) {
const { state, stateProxy, isOperationError } = inputs;
return (error) => {
if (isOperationError(error)) {
stateProxy.setError(state, error);
stateProxy.setFailed(state);
}
throw error;
};
}
function appendReadableErrorMessage(currentMessage, innerMessage) {
let message = currentMessage;
if (message.slice(-1) !== ".") {
message = message + ".";
}
return message + " " + innerMessage;
}
function simplifyError(err) {
let message = err.message;
let code = err.code;
let curErr = err;
while (curErr.innererror) {
curErr = curErr.innererror;
code = curErr.code;
message = appendReadableErrorMessage(message, curErr.message);
}
return {
code,
message,
};
}
function processOperationStatus(result) {
const { state, stateProxy, status, isDone, processResult, getError, response, setErrorAsResult } = result;
switch (status) {
case "succeeded": {
stateProxy.setSucceeded(state);
break;
}
case "failed": {
const err = getError === null || getError === void 0 ? void 0 : getError(response);
let postfix = "";
if (err) {
const { code, message } = simplifyError(err);
postfix = `. ${code}. ${message}`;
}
const errStr = `The long-running operation has failed${postfix}`;
stateProxy.setError(state, new Error(errStr));
stateProxy.setFailed(state);
logger.warning(errStr);
break;
}
case "canceled": {
stateProxy.setCanceled(state);
break;
}
}
if ((isDone === null || isDone === void 0 ? void 0 : isDone(response, state)) ||
(isDone === undefined &&
["succeeded", "canceled"].concat(setErrorAsResult ? [] : ["failed"]).includes(status))) {
stateProxy.setResult(state, buildResult({
response,
state,
processResult,
}));
}
}
function buildResult(inputs) {
const { processResult, response, state } = inputs;
return processResult ? processResult(response, state) : response;
}
/**
* Initiates the long-running operation.
*/
export async function initOperation(inputs) {
const { init, stateProxy, processResult, getOperationStatus, withOperationLocation, setErrorAsResult, } = inputs;
const { operationLocation, resourceLocation, metadata, response } = await init();
if (operationLocation)
withOperationLocation === null || withOperationLocation === void 0 ? void 0 : withOperationLocation(operationLocation, false);
const config = {
metadata,
operationLocation,
resourceLocation,
};
logger.verbose(`LRO: Operation description:`, config);
const state = stateProxy.initState(config);
const status = getOperationStatus({ response, state, operationLocation });
processOperationStatus({ state, status, stateProxy, response, setErrorAsResult, processResult });
return state;
}
async function pollOperationHelper(inputs) {
const { poll, state, stateProxy, operationLocation, getOperationStatus, getResourceLocation, isOperationError, options, } = inputs;
const response = await poll(operationLocation, options).catch(setStateError({
state,
stateProxy,
isOperationError,
}));
const status = getOperationStatus(response, state);
logger.verbose(`LRO: Status:\n\tPolling from: ${state.config.operationLocation}\n\tOperation status: ${status}\n\tPolling status: ${terminalStates.includes(status) ? "Stopped" : "Running"}`);
if (status === "succeeded") {
const resourceLocation = getResourceLocation(response, state);
if (resourceLocation !== undefined) {
return {
response: await poll(resourceLocation).catch(setStateError({ state, stateProxy, isOperationError })),
status,
};
}
}
return { response, status };
}
/** Polls the long-running operation. */
export async function pollOperation(inputs) {
const { poll, state, stateProxy, options, getOperationStatus, getResourceLocation, getOperationLocation, isOperationError, withOperationLocation, getPollingInterval, processResult, getError, updateState, setDelay, isDone, setErrorAsResult, } = inputs;
const { operationLocation } = state.config;
if (operationLocation !== undefined) {
const { response, status } = await pollOperationHelper({
poll,
getOperationStatus,
state,
stateProxy,
operationLocation,
getResourceLocation,
isOperationError,
options,
});
processOperationStatus({
status,
response,
state,
stateProxy,
isDone,
processResult,
getError,
setErrorAsResult,
});
if (!terminalStates.includes(status)) {
const intervalInMs = getPollingInterval === null || getPollingInterval === void 0 ? void 0 : getPollingInterval(response);
if (intervalInMs)
setDelay(intervalInMs);
const location = getOperationLocation === null || getOperationLocation === void 0 ? void 0 : getOperationLocation(response, state);
if (location !== undefined) {
const isUpdated = operationLocation !== location;
state.config.operationLocation = location;
withOperationLocation === null || withOperationLocation === void 0 ? void 0 : withOperationLocation(location, isUpdated);
}
else
withOperationLocation === null || withOperationLocation === void 0 ? void 0 : withOperationLocation(operationLocation, false);
}
updateState === null || updateState === void 0 ? void 0 : updateState(state, response);
}
}
//# sourceMappingURL=operation.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,170 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { deserializeState, initOperation, pollOperation } from "./operation";
import { POLL_INTERVAL_IN_MS } from "./constants";
import { delay } from "@azure/core-util";
const createStateProxy = () => ({
/**
* The state at this point is created to be of type OperationState<TResult>.
* It will be updated later to be of type TState when the
* customer-provided callback, `updateState`, is called during polling.
*/
initState: (config) => ({ status: "running", config }),
setCanceled: (state) => (state.status = "canceled"),
setError: (state, error) => (state.error = error),
setResult: (state, result) => (state.result = result),
setRunning: (state) => (state.status = "running"),
setSucceeded: (state) => (state.status = "succeeded"),
setFailed: (state) => (state.status = "failed"),
getError: (state) => state.error,
getResult: (state) => state.result,
isCanceled: (state) => state.status === "canceled",
isFailed: (state) => state.status === "failed",
isRunning: (state) => state.status === "running",
isSucceeded: (state) => state.status === "succeeded",
});
/**
* Returns a poller factory.
*/
export function buildCreatePoller(inputs) {
const { getOperationLocation, getStatusFromInitialResponse, getStatusFromPollResponse, isOperationError, getResourceLocation, getPollingInterval, getError, resolveOnUnsuccessful, } = inputs;
return async ({ init, poll }, options) => {
const { processResult, updateState, withOperationLocation: withOperationLocationCallback, intervalInMs = POLL_INTERVAL_IN_MS, restoreFrom, } = options || {};
const stateProxy = createStateProxy();
const withOperationLocation = withOperationLocationCallback
? (() => {
let called = false;
return (operationLocation, isUpdated) => {
if (isUpdated)
withOperationLocationCallback(operationLocation);
else if (!called)
withOperationLocationCallback(operationLocation);
called = true;
};
})()
: undefined;
const state = restoreFrom
? deserializeState(restoreFrom)
: await initOperation({
init,
stateProxy,
processResult,
getOperationStatus: getStatusFromInitialResponse,
withOperationLocation,
setErrorAsResult: !resolveOnUnsuccessful,
});
let resultPromise;
const abortController = new AbortController();
const handlers = new Map();
const handleProgressEvents = async () => handlers.forEach((h) => h(state));
const cancelErrMsg = "Operation was canceled";
let currentPollIntervalInMs = intervalInMs;
const poller = {
getOperationState: () => state,
getResult: () => state.result,
isDone: () => ["succeeded", "failed", "canceled"].includes(state.status),
isStopped: () => resultPromise === undefined,
stopPolling: () => {
abortController.abort();
},
toString: () => JSON.stringify({
state,
}),
onProgress: (callback) => {
const s = Symbol();
handlers.set(s, callback);
return () => handlers.delete(s);
},
pollUntilDone: (pollOptions) => (resultPromise !== null && resultPromise !== void 0 ? resultPromise : (resultPromise = (async () => {
const { abortSignal: inputAbortSignal } = pollOptions || {};
// In the future we can use AbortSignal.any() instead
function abortListener() {
abortController.abort();
}
const abortSignal = abortController.signal;
if (inputAbortSignal === null || inputAbortSignal === void 0 ? void 0 : inputAbortSignal.aborted) {
abortController.abort();
}
else if (!abortSignal.aborted) {
inputAbortSignal === null || inputAbortSignal === void 0 ? void 0 : inputAbortSignal.addEventListener("abort", abortListener, { once: true });
}
try {
if (!poller.isDone()) {
await poller.poll({ abortSignal });
while (!poller.isDone()) {
await delay(currentPollIntervalInMs, { abortSignal });
await poller.poll({ abortSignal });
}
}
}
finally {
inputAbortSignal === null || inputAbortSignal === void 0 ? void 0 : inputAbortSignal.removeEventListener("abort", abortListener);
}
if (resolveOnUnsuccessful) {
return poller.getResult();
}
else {
switch (state.status) {
case "succeeded":
return poller.getResult();
case "canceled":
throw new Error(cancelErrMsg);
case "failed":
throw state.error;
case "notStarted":
case "running":
throw new Error(`Polling completed without succeeding or failing`);
}
}
})().finally(() => {
resultPromise = undefined;
}))),
async poll(pollOptions) {
if (resolveOnUnsuccessful) {
if (poller.isDone())
return;
}
else {
switch (state.status) {
case "succeeded":
return;
case "canceled":
throw new Error(cancelErrMsg);
case "failed":
throw state.error;
}
}
await pollOperation({
poll,
state,
stateProxy,
getOperationLocation,
isOperationError,
withOperationLocation,
getPollingInterval,
getOperationStatus: getStatusFromPollResponse,
getResourceLocation,
processResult,
getError,
updateState,
options: pollOptions,
setDelay: (pollIntervalInMs) => {
currentPollIntervalInMs = pollIntervalInMs;
},
setErrorAsResult: !resolveOnUnsuccessful,
});
await handleProgressEvents();
if (!resolveOnUnsuccessful) {
switch (state.status) {
case "canceled":
throw new Error(cancelErrMsg);
case "failed":
throw state.error;
}
}
},
};
return poller;
};
}
//# sourceMappingURL=poller.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,110 @@
# Azure Abort Controller client library for JavaScript
The `@azure/abort-controller` package provides `AbortController` and `AbortSignal` classes. These classes are compatible
with the [AbortController](https://developer.mozilla.org/docs/Web/API/AbortController) built into modern browsers
and the `AbortSignal` used by [fetch](https://developer.mozilla.org/docs/Web/API/Fetch_API).
Use the `AbortController` class to create an instance of the `AbortSignal` class that can be used to cancel an operation
in an Azure SDK that accept a parameter of type `AbortSignalLike`.
Key links:
- [Source code](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/abort-controller)
- [Package (npm)](https://www.npmjs.com/package/@azure/abort-controller)
- [API Reference Documentation](https://docs.microsoft.com/javascript/api/overview/azure/abort-controller-readme)
## Getting started
### Installation
Install this library using npm as follows
```
npm install @azure/abort-controller
```
## Key Concepts
Use the `AbortController` to create an `AbortSignal` which can then be passed to Azure SDK operations to cancel
pending work. The `AbortSignal` can be accessed via the `signal` property on an instantiated `AbortController`.
An `AbortSignal` can also be returned directly from a static method, e.g. `AbortController.timeout(100)`.
that is cancelled after 100 milliseconds.
Calling `abort()` on the instantiated `AbortController` invokes the registered `abort`
event listeners on the associated `AbortSignal`.
Any subsequent calls to `abort()` on the same controller will have no effect.
The `AbortSignal.none` static property returns an `AbortSignal` that can not be aborted.
Multiple instances of an `AbortSignal` can be linked so that calling `abort()` on the parent signal,
aborts all linked signals.
This linkage is one-way, meaning that a parent signal can affect a linked signal, but not the other way around.
To link `AbortSignals` together, pass in the parent signals to the `AbortController` constructor.
## Examples
The below examples assume that `doAsyncWork` is a function that takes a bag of properties, one of which is
of the abort signal.
### Example 1 - basic usage
```js
import { AbortController } from "@azure/abort-controller";
const controller = new AbortController();
doAsyncWork({ abortSignal: controller.signal });
// at some point later
controller.abort();
```
### Example 2 - Aborting with timeout
```js
import { AbortController } from "@azure/abort-controller";
const signal = AbortController.timeout(1000);
doAsyncWork({ abortSignal: signal });
```
### Example 3 - Aborting sub-tasks
```js
import { AbortController } from "@azure/abort-controller";
const allTasksController = new AbortController();
const subTask1 = new AbortController(allTasksController.signal);
const subtask2 = new AbortController(allTasksController.signal);
allTasksController.abort(); // aborts allTasksSignal, subTask1, subTask2
subTask1.abort(); // aborts only subTask1
```
### Example 4 - Aborting with parent signal or timeout
```js
import { AbortController } from "@azure/abort-controller";
const allTasksController = new AbortController();
// create a subtask controller that can be aborted manually,
// or when either the parent task aborts or the timeout is reached.
const subTask = new AbortController(allTasksController.signal, AbortController.timeout(100));
allTasksController.abort(); // aborts allTasksSignal, subTask
subTask.abort(); // aborts only subTask
```
## Next steps
You can build and run the tests locally by executing `rushx test`. Explore the `test` folder to see advanced usage and behavior of the public classes.
## Troubleshooting
If you run into issues while using this library, please feel free to [file an issue](https://github.com/Azure/azure-sdk-for-js/issues/new).
## Contributing
If you'd like to contribute to this library, please read the [contributing guide](https://github.com/Azure/azure-sdk-for-js/blob/main/CONTRIBUTING.md) to learn more about how to build and test the code.
![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fcore%2Fabort-controller%2FREADME.png)

View file

@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
* This error is thrown when an asynchronous operation has been aborted.
* Check for this error by testing the `name` that the name property of the
* error matches `"AbortError"`.
*
* @example
* ```ts
* const controller = new AbortController();
* controller.abort();
* try {
* doAsyncWork(controller.signal)
* } catch (e) {
* if (e.name === 'AbortError') {
* // handle abort error here.
* }
* }
* ```
*/
export class AbortError extends Error {
constructor(message) {
super(message);
this.name = "AbortError";
}
}
//# sourceMappingURL=AbortError.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"AbortError.js","sourceRoot":"","sources":["../../src/AbortError.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAgB;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * This error is thrown when an asynchronous operation has been aborted.\n * Check for this error by testing the `name` that the name property of the\n * error matches `\"AbortError\"`.\n *\n * @example\n * ```ts\n * const controller = new AbortController();\n * controller.abort();\n * try {\n * doAsyncWork(controller.signal)\n * } catch (e) {\n * if (e.name === 'AbortError') {\n * // handle abort error here.\n * }\n * }\n * ```\n */\nexport class AbortError extends Error {\n constructor(message?: string) {\n super(message);\n this.name = \"AbortError\";\n }\n}\n"]}

View file

@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=AbortSignalLike.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"AbortSignalLike.js","sourceRoot":"","sources":["../../src/AbortSignalLike.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * Allows the request to be aborted upon firing of the \"abort\" event.\n * Compatible with the browser built-in AbortSignal and common polyfills.\n */\nexport interface AbortSignalLike {\n /**\n * Indicates if the signal has already been aborted.\n */\n readonly aborted: boolean;\n /**\n * Add new \"abort\" event listener, only support \"abort\" event.\n */\n addEventListener(\n type: \"abort\",\n listener: (this: AbortSignalLike, ev: any) => any,\n options?: any,\n ): void;\n /**\n * Remove \"abort\" event listener, only support \"abort\" event.\n */\n removeEventListener(\n type: \"abort\",\n listener: (this: AbortSignalLike, ev: any) => any,\n options?: any,\n ): void;\n}\n"]}

View file

@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export { AbortError } from "./AbortError";
//# sourceMappingURL=index.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nexport { AbortError } from \"./AbortError\";\nexport { AbortSignalLike } from \"./AbortSignalLike\";\n"]}

View file

@ -0,0 +1,33 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
* This error is thrown when an asynchronous operation has been aborted.
* Check for this error by testing the `name` that the name property of the
* error matches `"AbortError"`.
*
* @example
* ```ts
* const controller = new AbortController();
* controller.abort();
* try {
* doAsyncWork(controller.signal)
* } catch (e) {
* if (e.name === 'AbortError') {
* // handle abort error here.
* }
* }
* ```
*/
class AbortError extends Error {
constructor(message) {
super(message);
this.name = "AbortError";
}
}
exports.AbortError = AbortError;
//# sourceMappingURL=index.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"index.js","sources":["../src/AbortError.ts"],"sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * This error is thrown when an asynchronous operation has been aborted.\n * Check for this error by testing the `name` that the name property of the\n * error matches `\"AbortError\"`.\n *\n * @example\n * ```ts\n * const controller = new AbortController();\n * controller.abort();\n * try {\n * doAsyncWork(controller.signal)\n * } catch (e) {\n * if (e.name === 'AbortError') {\n * // handle abort error here.\n * }\n * }\n * ```\n */\nexport class AbortError extends Error {\n constructor(message?: string) {\n super(message);\n this.name = \"AbortError\";\n }\n}\n"],"names":[],"mappings":";;;;AAAA;AACA;AAEA;;;;;;;;;;;;;;;;;AAiBG;AACG,MAAO,UAAW,SAAQ,KAAK,CAAA;AACnC,IAAA,WAAA,CAAY,OAAgB,EAAA;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;AACf,QAAA,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;KAC1B;AACF;;;;"}

View file

@ -0,0 +1,92 @@
{
"name": "@azure/abort-controller",
"sdk-type": "client",
"version": "2.0.0",
"description": "Microsoft Azure SDK for JavaScript - Aborter",
"main": "./dist/index.js",
"module": "dist-esm/src/index.js",
"scripts": {
"build:samples": "echo Obsolete",
"build:test": "tsc -p . && dev-tool run bundle",
"build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local",
"check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"",
"clean": "rimraf dist dist-* temp types *.tgz *.log",
"execute:samples": "echo skipped",
"extract-api": "tsc -p . && api-extractor run --local",
"format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"",
"integration-test:browser": "echo skipped",
"integration-test:node": "echo skipped",
"integration-test": "npm run integration-test:node && npm run integration-test:browser",
"lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]",
"lint": "eslint package.json api-extractor.json src test --ext .ts",
"pack": "npm pack 2>&1",
"test:browser": "npm run clean && npm run build:test && npm run unit-test:browser && npm run integration-test:browser",
"test:node": "npm run clean && tsc -p . && npm run unit-test:node && npm run integration-test:node",
"test": "npm run clean && tsc -p . && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test",
"unit-test:browser": "karma start --single-run",
"unit-test:node": "dev-tool run test:node-ts-input --no-test-proxy=true",
"unit-test": "npm run unit-test:node && npm run unit-test:browser"
},
"types": "./types/src/index.d.ts",
"files": [
"dist/",
"dist-esm/src/",
"shims-public.d.ts",
"types/src",
"README.md",
"LICENSE"
],
"engines": {
"node": ">=18.0.0"
},
"repository": "github:Azure/azure-sdk-for-js",
"keywords": [
"azure",
"aborter",
"abortsignal",
"cancellation",
"node.js",
"typescript",
"javascript",
"browser",
"cloud"
],
"author": "Microsoft Corporation",
"license": "MIT",
"bugs": {
"url": "https://github.com/Azure/azure-sdk-for-js/issues"
},
"homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/abort-controller/README.md",
"sideEffects": false,
"dependencies": {
"tslib": "^2.2.0"
},
"devDependencies": {
"@azure/dev-tool": "^1.0.0",
"@azure/eslint-plugin-azure-sdk": "^3.0.0",
"@microsoft/api-extractor": "^7.31.1",
"@types/chai": "^4.1.6",
"@types/mocha": "^10.0.0",
"@types/node": "^18.0.0",
"chai": "^4.2.0",
"cross-env": "^7.0.2",
"eslint": "^8.0.0",
"karma": "^6.2.0",
"karma-chrome-launcher": "^3.0.0",
"karma-coverage": "^2.0.0",
"karma-env-preprocessor": "^0.1.1",
"karma-firefox-launcher": "^1.1.0",
"karma-junit-reporter": "^2.0.1",
"karma-mocha": "^2.0.1",
"karma-mocha-reporter": "^2.2.5",
"karma-sourcemap-loader": "^0.3.8",
"mocha": "^10.0.0",
"c8": "^8.0.0",
"rimraf": "^3.0.0",
"ts-node": "^10.0.0",
"typescript": "~5.2.0"
},
"//metadata": {
"migrationDate": "2023-03-08T18:36:03.000Z"
}
}

View file

@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// forward declaration of Event in case DOM libs are not present.
interface Event {}

View file

@ -0,0 +1,22 @@
/**
* This error is thrown when an asynchronous operation has been aborted.
* Check for this error by testing the `name` that the name property of the
* error matches `"AbortError"`.
*
* @example
* ```ts
* const controller = new AbortController();
* controller.abort();
* try {
* doAsyncWork(controller.signal)
* } catch (e) {
* if (e.name === 'AbortError') {
* // handle abort error here.
* }
* }
* ```
*/
export declare class AbortError extends Error {
constructor(message?: string);
}
//# sourceMappingURL=AbortError.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"AbortError.d.ts","sourceRoot":"","sources":["../../src/AbortError.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,UAAW,SAAQ,KAAK;gBACvB,OAAO,CAAC,EAAE,MAAM;CAI7B"}

View file

@ -0,0 +1,19 @@
/**
* Allows the request to be aborted upon firing of the "abort" event.
* Compatible with the browser built-in AbortSignal and common polyfills.
*/
export interface AbortSignalLike {
/**
* Indicates if the signal has already been aborted.
*/
readonly aborted: boolean;
/**
* Add new "abort" event listener, only support "abort" event.
*/
addEventListener(type: "abort", listener: (this: AbortSignalLike, ev: any) => any, options?: any): void;
/**
* Remove "abort" event listener, only support "abort" event.
*/
removeEventListener(type: "abort", listener: (this: AbortSignalLike, ev: any) => any, options?: any): void;
}
//# sourceMappingURL=AbortSignalLike.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"AbortSignalLike.d.ts","sourceRoot":"","sources":["../../src/AbortSignalLike.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,gBAAgB,CACd,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,GAAG,KAAK,GAAG,EACjD,OAAO,CAAC,EAAE,GAAG,GACZ,IAAI,CAAC;IACR;;OAEG;IACH,mBAAmB,CACjB,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,GAAG,KAAK,GAAG,EACjD,OAAO,CAAC,EAAE,GAAG,GACZ,IAAI,CAAC;CACT"}

View file

@ -0,0 +1,3 @@
export { AbortError } from "./AbortError";
export { AbortSignalLike } from "./AbortSignalLike";
//# sourceMappingURL=index.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}

View file

@ -0,0 +1,11 @@
// This file is read by tools that parse documentation comments conforming to the TSDoc standard.
// It should be published with your NPM package. It should not be tracked by Git.
{
"tsdocVersion": "0.12",
"toolPackages": [
{
"packageName": "@microsoft/api-extractor",
"packageVersion": "7.39.0"
}
]
}

View file

@ -0,0 +1,126 @@
{
"name": "@azure/core-lro",
"author": "Microsoft Corporation",
"sdk-type": "client",
"version": "2.6.0",
"description": "Isomorphic client library for supporting long-running operations in node.js and browser.",
"tags": [
"isomorphic",
"browser",
"javascript",
"node",
"microsoft",
"lro",
"polling"
],
"keywords": [
"isomorphic",
"browser",
"javascript",
"node",
"microsoft",
"lro",
"polling",
"azure",
"cloud"
],
"main": "./dist/index.js",
"module": "dist-esm/src/index.js",
"types": "./types/core-lro.d.ts",
"files": [
"types/core-lro.d.ts",
"dist-esm/src",
"dist/",
"README.md",
"LICENSE"
],
"engines": {
"node": ">=18.0.0"
},
"browser": {
"os": false,
"process": false
},
"react-native": {
"./dist/index.js": "./dist-esm/src/index.js"
},
"license": "MIT",
"homepage": "https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-lro/README.md",
"repository": "github:Azure/azure-sdk-for-js",
"bugs": {
"url": "https://github.com/Azure/azure-sdk-for-js/issues"
},
"nyc": {
"extension": [
".ts"
],
"exclude": [
"coverage/**/*",
"**/*.d.ts",
"**/*.js"
],
"reporter": [
"text",
"html",
"cobertura"
],
"all": true
},
"scripts": {
"build:samples": "echo Obsolete",
"build:test": "tsc -p . && dev-tool run bundle",
"build": "npm run clean && tsc -p . && dev-tool run bundle && api-extractor run --local",
"check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"",
"clean": "rimraf dist dist-* types *.log browser statistics.html coverage src/**/*.js test/**/*.js",
"execute:samples": "echo skipped",
"extract-api": "tsc -p . && api-extractor run --local",
"format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"",
"integration-test:browser": "echo skipped",
"integration-test:node": "echo skipped",
"integration-test": "npm run integration-test:node && npm run integration-test:browser",
"lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]",
"lint": "eslint package.json api-extractor.json src test --ext .ts",
"pack": "npm pack 2>&1",
"test:browser": "npm run build:test && npm run unit-test:browser && npm run integration-test:browser",
"test:node": "npm run build:test && npm run unit-test:node && npm run integration-test:node",
"test": "npm run build:test && npm run unit-test",
"unit-test": "npm run unit-test:node && npm run unit-test:browser",
"unit-test:browser": "karma start --single-run",
"unit-test:node": "dev-tool run test:node-ts-input --no-test-proxy=true"
},
"sideEffects": false,
"dependencies": {
"@azure/abort-controller": "^2.0.0",
"@azure/core-util": "^1.2.0",
"@azure/logger": "^1.0.0",
"tslib": "^2.2.0"
},
"devDependencies": {
"@azure/core-rest-pipeline": "^1.1.0",
"@azure/eslint-plugin-azure-sdk": "^3.0.0",
"@azure/dev-tool": "^1.0.0",
"@azure/test-utils": "^1.0.0",
"@microsoft/api-extractor": "^7.31.1",
"@types/mocha": "^10.0.0",
"@types/node": "^18.0.0",
"cross-env": "^7.0.2",
"eslint": "^8.0.0",
"karma": "^6.2.0",
"karma-chrome-launcher": "^3.0.0",
"karma-coverage": "^2.0.0",
"karma-env-preprocessor": "^0.1.1",
"karma-firefox-launcher": "^1.1.0",
"karma-junit-reporter": "^2.0.1",
"karma-mocha": "^2.0.1",
"karma-mocha-reporter": "^2.2.5",
"karma-sourcemap-loader": "^0.3.8",
"mocha": "^10.0.0",
"c8": "^8.0.0",
"rimraf": "^3.0.0",
"ts-node": "^10.0.0",
"typescript": "~5.3.3"
},
"//metadata": {
"migrationDate": "2023-03-08T18:36:03.000Z"
}
}

View file

@ -0,0 +1,704 @@
import { AbortSignalLike } from '@azure/abort-controller';
/**
* CancelOnProgress is used as the return value of a Poller's onProgress method.
* When a user invokes onProgress, they're required to pass in a function that will be
* called as a callback with the new data received each time the poll operation is updated.
* onProgress returns a function that will prevent any further update to reach the original callback.
*/
export declare type CancelOnProgress = () => void;
/**
* Creates a poller that can be used to poll a long-running operation.
* @param lro - Description of the long-running operation
* @param options - options to configure the poller
* @returns an initialized poller
*/
export declare function createHttpPoller<TResult, TState extends OperationState<TResult>>(lro: LongRunningOperation, options?: CreateHttpPollerOptions<TResult, TState>): Promise<SimplePollerLike<TState, TResult>>;
/**
* Options for `createPoller`.
*/
export declare interface CreateHttpPollerOptions<TResult, TState> {
/**
* Defines how much time the poller is going to wait before making a new request to the service.
*/
intervalInMs?: number;
/**
* A serialized poller which can be used to resume an existing paused Long-Running-Operation.
*/
restoreFrom?: string;
/**
* The potential location of the result of the LRO if specified by the LRO extension in the swagger.
*/
resourceLocationConfig?: LroResourceLocationConfig;
/**
* A function to process the result of the LRO.
*/
processResult?: (result: unknown, state: TState) => TResult;
/**
* A function to process the state of the LRO.
*/
updateState?: (state: TState, response: LroResponse) => void;
/**
* A function to be called each time the operation location is updated by the
* service.
*/
withOperationLocation?: (operationLocation: string) => void;
/**
* Control whether to throw an exception if the operation failed or was canceled.
*/
resolveOnUnsuccessful?: boolean;
}
/**
* Description of a long running operation.
*/
export declare interface LongRunningOperation<T = unknown> {
/**
* The request path. This should be set if the operation is a PUT and needs
* to poll from the same request path.
*/
requestPath?: string;
/**
* The HTTP request method. This should be set if the operation is a PUT or a
* DELETE.
*/
requestMethod?: string;
/**
* A function that can be used to send initial request to the service.
*/
sendInitialRequest: () => Promise<LroResponse<unknown>>;
/**
* A function that can be used to poll for the current status of a long running operation.
*/
sendPollRequest: (path: string, options?: {
abortSignal?: AbortSignalLike;
}) => Promise<LroResponse<T>>;
}
/**
* The LRO Engine, a class that performs polling.
*/
export declare class LroEngine<TResult, TState extends PollOperationState<TResult>> extends Poller<TState, TResult> {
private config;
constructor(lro: LongRunningOperation<TResult>, options?: LroEngineOptions<TResult, TState>);
/**
* The method used by the poller to wait before attempting to update its operation.
*/
delay(): Promise<void>;
}
/**
* Options for the LRO poller.
*/
export declare interface LroEngineOptions<TResult, TState> {
/**
* Defines how much time the poller is going to wait before making a new request to the service.
*/
intervalInMs?: number;
/**
* A serialized poller which can be used to resume an existing paused Long-Running-Operation.
*/
resumeFrom?: string;
/**
* The potential location of the result of the LRO if specified by the LRO extension in the swagger.
*/
lroResourceLocationConfig?: LroResourceLocationConfig;
/**
* A function to process the result of the LRO.
*/
processResult?: (result: unknown, state: TState) => TResult;
/**
* A function to process the state of the LRO.
*/
updateState?: (state: TState, lastResponse: RawResponse) => void;
/**
* A predicate to determine whether the LRO finished processing.
*/
isDone?: (lastResponse: unknown, state: TState) => boolean;
/**
* Control whether to throw an exception if the operation failed or was canceled.
*/
resolveOnUnsuccessful?: boolean;
}
/**
* The potential location of the result of the LRO if specified by the LRO extension in the swagger.
*/
export declare type LroResourceLocationConfig = "azure-async-operation" | "location" | "original-uri";
/**
* The type of the response of a LRO.
*/
export declare interface LroResponse<T = unknown> {
/** The flattened response */
flatResponse: T;
/** The raw response */
rawResponse: RawResponse;
}
/**
* While the poller works as the local control mechanism to start triggering and
* wait for a long-running operation, OperationState documents the status of
* the remote long-running operation. It gets updated after each poll.
*/
export declare interface OperationState<TResult> {
/**
* The current status of the operation.
*/
status: OperationStatus;
/**
* Will exist if the operation encountered any error.
*/
error?: Error;
/**
* Will exist if the operation produced a result of the expected type.
*/
result?: TResult;
}
/**
* The set of possible states an operation can be in at any given time.
*/
export declare type OperationStatus = "notStarted" | "running" | "succeeded" | "canceled" | "failed";
/**
* A class that represents the definition of a program that polls through consecutive requests
* until it reaches a state of completion.
*
* A poller can be executed manually, by polling request by request by calling to the `poll()` method repeatedly, until its operation is completed.
* It also provides a way to wait until the operation completes, by calling `pollUntilDone()` and waiting until the operation finishes.
* Pollers can also request the cancellation of the ongoing process to whom is providing the underlying long running operation.
*
* ```ts
* const poller = new MyPoller();
*
* // Polling just once:
* await poller.poll();
*
* // We can try to cancel the request here, by calling:
* //
* // await poller.cancelOperation();
* //
*
* // Getting the final result:
* const result = await poller.pollUntilDone();
* ```
*
* The Poller is defined by two types, a type representing the state of the poller, which
* must include a basic set of properties from `PollOperationState<TResult>`,
* and a return type defined by `TResult`, which can be anything.
*
* The Poller class implements the `PollerLike` interface, which allows poller implementations to avoid having
* to export the Poller's class directly, and instead only export the already instantiated poller with the PollerLike type.
*
* ```ts
* class Client {
* public async makePoller: PollerLike<MyOperationState, MyResult> {
* const poller = new MyPoller({});
* // It might be preferred to return the poller after the first request is made,
* // so that some information can be obtained right away.
* await poller.poll();
* return poller;
* }
* }
*
* const poller: PollerLike<MyOperationState, MyResult> = myClient.makePoller();
* ```
*
* A poller can be created through its constructor, then it can be polled until it's completed.
* At any point in time, the state of the poller can be obtained without delay through the getOperationState method.
* At any point in time, the intermediate forms of the result type can be requested without delay.
* Once the underlying operation is marked as completed, the poller will stop and the final value will be returned.
*
* ```ts
* const poller = myClient.makePoller();
* const state: MyOperationState = poller.getOperationState();
*
* // The intermediate result can be obtained at any time.
* const result: MyResult | undefined = poller.getResult();
*
* // The final result can only be obtained after the poller finishes.
* const result: MyResult = await poller.pollUntilDone();
* ```
*
*/
export declare abstract class Poller<TState extends PollOperationState<TResult>, TResult> implements PollerLike<TState, TResult> {
/** controls whether to throw an error if the operation failed or was canceled. */
protected resolveOnUnsuccessful: boolean;
private stopped;
private resolve?;
private reject?;
private pollOncePromise?;
private cancelPromise?;
private promise;
private pollProgressCallbacks;
/**
* The poller's operation is available in full to any of the methods of the Poller class
* and any class extending the Poller class.
*/
protected operation: PollOperation<TState, TResult>;
/**
* A poller needs to be initialized by passing in at least the basic properties of the `PollOperation<TState, TResult>`.
*
* When writing an implementation of a Poller, this implementation needs to deal with the initialization
* of any custom state beyond the basic definition of the poller. The basic poller assumes that the poller's
* operation has already been defined, at least its basic properties. The code below shows how to approach
* the definition of the constructor of a new custom poller.
*
* ```ts
* export class MyPoller extends Poller<MyOperationState, string> {
* constructor({
* // Anything you might need outside of the basics
* }) {
* let state: MyOperationState = {
* privateProperty: private,
* publicProperty: public,
* };
*
* const operation = {
* state,
* update,
* cancel,
* toString
* }
*
* // Sending the operation to the parent's constructor.
* super(operation);
*
* // You can assign more local properties here.
* }
* }
* ```
*
* Inside of this constructor, a new promise is created. This will be used to
* tell the user when the poller finishes (see `pollUntilDone()`). The promise's
* resolve and reject methods are also used internally to control when to resolve
* or reject anyone waiting for the poller to finish.
*
* The constructor of a custom implementation of a poller is where any serialized version of
* a previous poller's operation should be deserialized into the operation sent to the
* base constructor. For example:
*
* ```ts
* export class MyPoller extends Poller<MyOperationState, string> {
* constructor(
* baseOperation: string | undefined
* ) {
* let state: MyOperationState = {};
* if (baseOperation) {
* state = {
* ...JSON.parse(baseOperation).state,
* ...state
* };
* }
* const operation = {
* state,
* // ...
* }
* super(operation);
* }
* }
* ```
*
* @param operation - Must contain the basic properties of `PollOperation<State, TResult>`.
*/
constructor(operation: PollOperation<TState, TResult>);
/**
* Defines how much to wait between each poll request.
* This has to be implemented by your custom poller.
*
* \@azure/core-util has a simple implementation of a delay function that waits as many milliseconds as specified.
* This can be used as follows:
*
* ```ts
* import { delay } from "@azure/core-util";
*
* export class MyPoller extends Poller<MyOperationState, string> {
* // The other necessary definitions.
*
* async delay(): Promise<void> {
* const milliseconds = 1000;
* return delay(milliseconds);
* }
* }
* ```
*
*/
protected abstract delay(): Promise<void>;
/**
* Starts a loop that will break only if the poller is done
* or if the poller is stopped.
*/
private startPolling;
/**
* pollOnce does one polling, by calling to the update method of the underlying
* poll operation to make any relevant change effective.
*
* It only optionally receives an object with an abortSignal property, from \@azure/abort-controller's AbortSignalLike.
*
* @param options - Optional properties passed to the operation's update method.
*/
private pollOnce;
/**
* fireProgress calls the functions passed in via onProgress the method of the poller.
*
* It loops over all of the callbacks received from onProgress, and executes them, sending them
* the current operation state.
*
* @param state - The current operation state.
*/
private fireProgress;
/**
* Invokes the underlying operation's cancel method.
*/
private cancelOnce;
/**
* Returns a promise that will resolve once a single polling request finishes.
* It does this by calling the update method of the Poller's operation.
*
* It only optionally receives an object with an abortSignal property, from \@azure/abort-controller's AbortSignalLike.
*
* @param options - Optional properties passed to the operation's update method.
*/
poll(options?: {
abortSignal?: AbortSignalLike;
}): Promise<void>;
private processUpdatedState;
/**
* Returns a promise that will resolve once the underlying operation is completed.
*/
pollUntilDone(pollOptions?: {
abortSignal?: AbortSignalLike;
}): Promise<TResult>;
/**
* Invokes the provided callback after each polling is completed,
* sending the current state of the poller's operation.
*
* It returns a method that can be used to stop receiving updates on the given callback function.
*/
onProgress(callback: (state: TState) => void): CancelOnProgress;
/**
* Returns true if the poller has finished polling.
*/
isDone(): boolean;
/**
* Stops the poller from continuing to poll.
*/
stopPolling(): void;
/**
* Returns true if the poller is stopped.
*/
isStopped(): boolean;
/**
* Attempts to cancel the underlying operation.
*
* It only optionally receives an object with an abortSignal property, from \@azure/abort-controller's AbortSignalLike.
*
* If it's called again before it finishes, it will throw an error.
*
* @param options - Optional properties passed to the operation's update method.
*/
cancelOperation(options?: {
abortSignal?: AbortSignalLike;
}): Promise<void>;
/**
* Returns the state of the operation.
*
* Even though TState will be the same type inside any of the methods of any extension of the Poller class,
* implementations of the pollers can customize what's shared with the public by writing their own
* version of the `getOperationState` method, and by defining two types, one representing the internal state of the poller
* and a public type representing a safe to share subset of the properties of the internal state.
* Their definition of getOperationState can then return their public type.
*
* Example:
*
* ```ts
* // Let's say we have our poller's operation state defined as:
* interface MyOperationState extends PollOperationState<ResultType> {
* privateProperty?: string;
* publicProperty?: string;
* }
*
* // To allow us to have a true separation of public and private state, we have to define another interface:
* interface PublicState extends PollOperationState<ResultType> {
* publicProperty?: string;
* }
*
* // Then, we define our Poller as follows:
* export class MyPoller extends Poller<MyOperationState, ResultType> {
* // ... More content is needed here ...
*
* public getOperationState(): PublicState {
* const state: PublicState = this.operation.state;
* return {
* // Properties from PollOperationState<TResult>
* isStarted: state.isStarted,
* isCompleted: state.isCompleted,
* isCancelled: state.isCancelled,
* error: state.error,
* result: state.result,
*
* // The only other property needed by PublicState.
* publicProperty: state.publicProperty
* }
* }
* }
* ```
*
* You can see this in the tests of this repository, go to the file:
* `../test/utils/testPoller.ts`
* and look for the getOperationState implementation.
*/
getOperationState(): TState;
/**
* Returns the result value of the operation,
* regardless of the state of the poller.
* It can return undefined or an incomplete form of the final TResult value
* depending on the implementation.
*/
getResult(): TResult | undefined;
/**
* Returns a serialized version of the poller's operation
* by invoking the operation's toString method.
*/
toString(): string;
}
/**
* When the operation is cancelled, the poller will be rejected with an instance
* of the PollerCancelledError.
*/
export declare class PollerCancelledError extends Error {
constructor(message: string);
}
/**
* Abstract representation of a poller, intended to expose just the minimal API that the user needs to work with.
*/
export declare interface PollerLike<TState extends PollOperationState<TResult>, TResult> {
/**
* Returns a promise that will resolve once a single polling request finishes.
* It does this by calling the update method of the Poller's operation.
*/
poll(options?: {
abortSignal?: AbortSignalLike;
}): Promise<void>;
/**
* Returns a promise that will resolve once the underlying operation is completed.
*/
pollUntilDone(pollOptions?: {
abortSignal?: AbortSignalLike;
}): Promise<TResult>;
/**
* Invokes the provided callback after each polling is completed,
* sending the current state of the poller's operation.
*
* It returns a method that can be used to stop receiving updates on the given callback function.
*/
onProgress(callback: (state: TState) => void): CancelOnProgress;
/**
* Returns true if the poller has finished polling.
*/
isDone(): boolean;
/**
* Stops the poller. After this, no manual or automated requests can be sent.
*/
stopPolling(): void;
/**
* Returns true if the poller is stopped.
*/
isStopped(): boolean;
/**
* Attempts to cancel the underlying operation.
* @deprecated `cancelOperation` has been deprecated because it was not implemented.
*/
cancelOperation(options?: {
abortSignal?: AbortSignalLike;
}): Promise<void>;
/**
* Returns the state of the operation.
* The TState defined in PollerLike can be a subset of the TState defined in
* the Poller implementation.
*/
getOperationState(): TState;
/**
* Returns the result value of the operation,
* regardless of the state of the poller.
* It can return undefined or an incomplete form of the final TResult value
* depending on the implementation.
*/
getResult(): TResult | undefined;
/**
* Returns a serialized version of the poller's operation
* by invoking the operation's toString method.
*/
toString(): string;
}
/**
* When a poller is manually stopped through the `stopPolling` method,
* the poller will be rejected with an instance of the PollerStoppedError.
*/
export declare class PollerStoppedError extends Error {
constructor(message: string);
}
/**
* PollOperation is an interface that defines how to update the local reference of the state of the remote
* long running operation, just as well as how to request the cancellation of the same operation.
*
* It also has a method to serialize the operation so that it can be stored and resumed at any time.
*/
export declare interface PollOperation<TState, TResult> {
/**
* The state of the operation.
* It will be used to store the basic properties of PollOperationState<TResult>,
* plus any custom property that the implementation may require.
*/
state: TState;
/**
* Defines how to request the remote service for updates on the status of the long running operation.
*
* It optionally receives an object with an abortSignal property, from \@azure/abort-controller's AbortSignalLike.
* Also optionally receives a "fireProgress" function, which, if called, is responsible for triggering the
* poller's onProgress callbacks.
*
* @param options - Optional properties passed to the operation's update method.
*/
update(options?: {
abortSignal?: AbortSignalLike;
fireProgress?: (state: TState) => void;
}): Promise<PollOperation<TState, TResult>>;
/**
* Attempts to cancel the underlying operation.
*
* It only optionally receives an object with an abortSignal property, from \@azure/abort-controller's AbortSignalLike.
*
* It returns a promise that should be resolved with an updated version of the poller's operation.
*
* @param options - Optional properties passed to the operation's update method.
*
* @deprecated `cancel` has been deprecated because it was not implemented.
*/
cancel(options?: {
abortSignal?: AbortSignalLike;
}): Promise<PollOperation<TState, TResult>>;
/**
* Serializes the operation.
* Useful when wanting to create a poller that monitors an existing operation.
*/
toString(): string;
}
/**
* PollOperationState contains an opinionated list of the smallest set of properties needed
* to define any long running operation poller.
*
* While the Poller class works as the local control mechanism to start triggering, wait for,
* and potentially cancel a long running operation, the PollOperationState documents the status
* of the remote long running operation.
*
* It should be updated at least when the operation starts, when it's finished, and when it's cancelled.
* Though, implementations can have any other number of properties that can be updated by other reasons.
*/
export declare interface PollOperationState<TResult> {
/**
* True if the operation has started.
*/
isStarted?: boolean;
/**
* True if the operation has been completed.
*/
isCompleted?: boolean;
/**
* True if the operation has been cancelled.
*/
isCancelled?: boolean;
/**
* Will exist if the operation encountered any error.
*/
error?: Error;
/**
* Will exist if the operation concluded in a result of an expected type.
*/
result?: TResult;
}
/**
* PollProgressCallback<TState> is the type of the callback functions sent to onProgress.
* These functions will receive a TState that is defined by your implementation of
* the Poller class.
*/
export declare type PollProgressCallback<TState> = (state: TState) => void;
/**
* Simple type of the raw response.
*/
export declare interface RawResponse {
/** The HTTP status code */
statusCode: number;
/** A HttpHeaders collection in the response represented as a simple JSON object where all header names have been normalized to be lower-case. */
headers: {
[headerName: string]: string;
};
/** The parsed response body */
body?: unknown;
}
/**
* A simple poller interface.
*/
export declare interface SimplePollerLike<TState extends OperationState<TResult>, TResult> {
/**
* Returns a promise that will resolve once a single polling request finishes.
* It does this by calling the update method of the Poller's operation.
*/
poll(options?: {
abortSignal?: AbortSignalLike;
}): Promise<void>;
/**
* Returns a promise that will resolve once the underlying operation is completed.
*/
pollUntilDone(pollOptions?: {
abortSignal?: AbortSignalLike;
}): Promise<TResult>;
/**
* Invokes the provided callback after each polling is completed,
* sending the current state of the poller's operation.
*
* It returns a method that can be used to stop receiving updates on the given callback function.
*/
onProgress(callback: (state: TState) => void): CancelOnProgress;
/**
* Returns true if the poller has finished polling.
*/
isDone(): boolean;
/**
* Stops the poller. After this, no manual or automated requests can be sent.
*/
stopPolling(): void;
/**
* Returns true if the poller is stopped.
*/
isStopped(): boolean;
/**
* Returns the state of the operation.
*/
getOperationState(): TState;
/**
* Returns the result value of the operation,
* regardless of the state of the poller.
* It can return undefined or an incomplete form of the final TResult value
* depending on the implementation.
*/
getResult(): TResult | undefined;
/**
* Returns a serialized version of the poller's operation
* by invoking the operation's toString method.
*/
toString(): string;
}
export { }