Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@azure/core-lro

Package Overview
Dependencies
Maintainers
3
Versions
384
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@azure/core-lro - npm Package Compare versions

Comparing version 1.0.1-dev.20200124.1 to 1.0.1-dev.20200128.1

3

CHANGELOG.md

@@ -5,2 +5,5 @@ # Release History

- `getOperationState()` now returns `TState`.
- `TState` of `PollerLike` can be a subset of `TState` of `Poller`,
## 1.0.0 (2019-10-29)

@@ -7,0 +10,0 @@

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { __awaiter, __extends, __generator } from "tslib";
/**
* When a poller is manually stopped through the `stopPolling` method,
* the poller will be rejected with an instance of the PollerStoppedError.
*/
var PollerStoppedError = /** @class */ (function (_super) {

@@ -15,2 +19,6 @@ __extends(PollerStoppedError, _super);

export { PollerStoppedError };
/**
* When a poller is cancelled through the `cancelOperation` method,
* the poller will be rejected with an instance of the PollerCancelledError.
*/
var PollerCancelledError = /** @class */ (function (_super) {

@@ -30,4 +38,126 @@ __extends(PollerCancelledError, _super);

* 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();
* ```
*
*/
var Poller = /** @class */ (function () {
/**
* 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>.
*/
function Poller(operation) {

@@ -48,2 +178,4 @@ var _this = this;

/**
* @internal
* @ignore
* Starts a loop that will break only if the poller is done

@@ -76,4 +208,10 @@ * or if the poller is stopped.

/**
* @internal
* @ignore
* 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.
*/

@@ -117,3 +255,10 @@ Poller.prototype.pollOnce = function (options) {

/**
* @internal
* @ignore
* 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.
*/

@@ -127,2 +272,4 @@ Poller.prototype.fireProgress = function (state) {

/**
* @internal
* @ignore
* Invokes the underlying operation's cancel method, and rejects the

@@ -151,4 +298,8 @@ * pollUntilDone promise.

/**
* Reaches out to the underlying service.
* It should call the operation's update method.
* 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.
*/

@@ -181,3 +332,6 @@ Poller.prototype.poll = function (options) {

/**
* Reports updates.
* 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.
*/

@@ -216,3 +370,9 @@ Poller.prototype.onProgress = function (callback) {

/**
* Tries to cancel the underlying operation.
* 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.
*/

@@ -234,4 +394,47 @@ Poller.prototype.cancelOperation = function (options) {

* Returns the state of the operation.
* TState can be a different type than the underlying operation's TState.
* This method can be overridden with a custom implementation that returns specific properties out of this.operation.state.
*
* 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.
*/

@@ -252,3 +455,4 @@ Poller.prototype.getOperationState = function () {

/**
* Returns a serialized version of the poller.
* Returns a serialized version of the poller's operation
* by invoking the operation's toString method.
*/

@@ -255,0 +459,0 @@ Poller.prototype.toString = function () {

@@ -14,2 +14,9 @@ // Copyright (c) Microsoft Corporation.

abortSignal = options.abortSignal || (requestOptions && requestOptions.abortSignal);
if (!client) {
// The client property is assigned to the operation state during the instantiation of the `TestPoller`.
// So the client should always exist.
// Though `PublicTestOperationState` doesn't have the client property,
// so we have to make it optional in `TestOperationState`.
throw new Error("The client property should exist");
}
doFinalResponse = previousResponse && previousResponse.parsedBody.doFinalResponse;

@@ -16,0 +23,0 @@ if (!!initialResponse) return [3 /*break*/, 2];

@@ -49,6 +49,19 @@ // Copyright (c) Microsoft Corporation.

/**
* Can be used to get a publicly safe version of the poller state.
* The getOperationState() from TestPoller returns an object
* with the subset of properties from TestOperationState that are
* safe to be shared with the public.
*/
TestPoller.prototype.getOperationState = function () {
return this.operation.state;
var state = 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 PublicTestOperationState.
// The other properties from TestOperationState will be hidden from the user.
previousResponse: state.previousResponse
};
};

@@ -55,0 +68,0 @@ return TestPoller;

@@ -6,3 +6,3 @@ /*!

*
* Azure Core LRO SDK for JavaScript - 1.0.1-dev.20200124.1
* Azure Core LRO SDK for JavaScript - 1.0.1-dev.20200128.1
*/

@@ -16,2 +16,6 @@ 'use strict';

// Copyright (c) Microsoft Corporation.
/**
* When a poller is manually stopped through the `stopPolling` method,
* the poller will be rejected with an instance of the PollerStoppedError.
*/
var PollerStoppedError = /** @class */ (function (_super) {

@@ -27,2 +31,6 @@ tslib.__extends(PollerStoppedError, _super);

}(Error));
/**
* When a poller is cancelled through the `cancelOperation` method,
* the poller will be rejected with an instance of the PollerCancelledError.
*/
var PollerCancelledError = /** @class */ (function (_super) {

@@ -41,4 +49,126 @@ tslib.__extends(PollerCancelledError, _super);

* 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();
* ```
*
*/
var Poller = /** @class */ (function () {
/**
* 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>.
*/
function Poller(operation) {

@@ -59,2 +189,4 @@ var _this = this;

/**
* @internal
* @ignore
* Starts a loop that will break only if the poller is done

@@ -87,4 +219,10 @@ * or if the poller is stopped.

/**
* @internal
* @ignore
* 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.
*/

@@ -128,3 +266,10 @@ Poller.prototype.pollOnce = function (options) {

/**
* @internal
* @ignore
* 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.
*/

@@ -138,2 +283,4 @@ Poller.prototype.fireProgress = function (state) {

/**
* @internal
* @ignore
* Invokes the underlying operation's cancel method, and rejects the

@@ -162,4 +309,8 @@ * pollUntilDone promise.

/**
* Reaches out to the underlying service.
* It should call the operation's update method.
* 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.
*/

@@ -192,3 +343,6 @@ Poller.prototype.poll = function (options) {

/**
* Reports updates.
* 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.
*/

@@ -227,3 +381,9 @@ Poller.prototype.onProgress = function (callback) {

/**
* Tries to cancel the underlying operation.
* 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.
*/

@@ -245,4 +405,47 @@ Poller.prototype.cancelOperation = function (options) {

* Returns the state of the operation.
* TState can be a different type than the underlying operation's TState.
* This method can be overridden with a custom implementation that returns specific properties out of this.operation.state.
*
* 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.
*/

@@ -263,3 +466,4 @@ Poller.prototype.getOperationState = function () {

/**
* Returns a serialized version of the poller.
* Returns a serialized version of the poller's operation
* by invoking the operation's toString method.
*/

@@ -266,0 +470,0 @@ Poller.prototype.toString = function () {

2

package.json

@@ -9,3 +9,3 @@ {

"sdk-type": "client",
"version": "1.0.1-dev.20200124.1",
"version": "1.0.1-dev.20200128.1",
"description": "LRO Polling strtegy for the Azure SDK in TypeScript",

@@ -12,0 +12,0 @@ "tags": [

@@ -5,5 +5,5 @@ # Azure Core LRO client library for JavaScript

allow the azure-sdk-for-js public libraries to implement fully featured pollers
to manage long running operations with the Azure services.
to manage Long Running Operations (LROs) with the Azure services.
core-lro is made following our guidelines, here: https://azure.github.io/azure-sdk/typescript_design.html#ts-lro
@azure/core-lro is made following our guidelines here: https://azure.github.io/azure-sdk/typescript_design.html#ts-lro

@@ -16,16 +16,4 @@ [Source code](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/core/core-lro)

Since this package is intended to be consumed by developers of the azure-sdk-for-js repository,
you'll need to manually add the following entry to your package.json's dependencies:
To install this package locally, use `npm install --save @azure/core-lro`.
```json
{
// ...
"dependencies": {
// ...
"@azure/core-lro": "1.0.0-preview.1",
// ...
}
}
```
### Configure TypeScript

@@ -39,7 +27,6 @@

You also need to enable `compilerOptions.allowSyntheticDefaultImports` in your
tsconfig.json. Note that if you have enabled `compilerOptions.esModuleInterop`,
`allowSyntheticDefaultImports` is enabled by default. See [TypeScript's
compiler options
handbook](https://www.typescriptlang.org/docs/handbook/compiler-options.html)
They will also need to enable `compilerOptions.allowSyntheticDefaultImports` in their
`tsconfig.json`. Note that if you have enabled `compilerOptions.esModuleInterop`,
`allowSyntheticDefaultImports` is enabled by default.
See [TypeScript's compiler options handbook](https://www.typescriptlang.org/docs/handbook/compiler-options.html)
for more information.

@@ -49,17 +36,17 @@

@azure/core-lro makes a distinction between the Long Running Operation and its Poller.
- Whenever we talk about an **operation**, we mean the static representation of a Long Running Operation.
Any operation will have a definition of a state, which has a defined set of
properties plus any property the implementations would like to add. Any
operation will have three basic functionalities:
1. An update() method that will generate a new operation that might or might
not include changes to its state.
2. A cancel() method, which will tell the service that the operation is no longer needed.
3. A toString() method, that will output a serialized version of the operation.
- A **Poller** is an object who's main function is to interact with an operation until one of three things happen:
1. The poller is stopped.
2. The operation finishes, either by succeeding or failing.
3. The operation is cancelled.
Any operation will have a definition of a **state**, which has an opinionated default set of properties.
The definition of the operation will also have functions that will define how to request new information
about the pending operetion, how to request its cancelation, and how to serialize it.
- A **Poller** is an object who's main function is to interact with an operation until the poller is manually stopped,
the operation finishes (either by succeeding or failing) or if a manual request to cancel the operation has succeeded.
Some characteristics of the pollers are:
- Pollers show the status of the polling behavior.
- Pollers support manual as well as automatic polling.
- Pollers are serializable and can resume from a serialized operation.
- Pollers also specify how much of the operation's state is going to be available to the public.
- A **PollerLike** is the public interface of a Poller, which allows for different implementations to be used.
Now we'll examine how to set up an implementation of an operation and a poller.
## Examples

@@ -74,3 +61,6 @@

First, you'll need to import the definitions of a poll operation and its state, as follows:
To work with a Long Running Operation, we need to define how to update, cancel
and serialize the information related to the remote pending task.
To implement this class for your library or application,
you'll need to import the definitions of a poll operation and its state.

@@ -81,7 +71,24 @@ ```typescript

A **PollOperation** requires implementing its state. We recommend extending the PollOperationState we provide.
An example can be:
A `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.
Besides updating and cancelling, it also defines how to serialize its information,
so that polling can be resumed at any time from a previously serialized operation
(more at [Serializing an operation](#serializing-an-operation)).
`PollOperationState` provides a basic state for the poll operation.
It contains the minimal set of properties needed
to keep track of a long running operation, and it's intended to be extended
with any custom property that your program might need.
The state can be updated any time, but it should be updated at least in three opportunities:
when the operation starts, when it's finished, and when it's cancelled.
To be able to create your custom operations, you'll need to extend the
`PollOperation` class with both your operation's state and the final result
value. For this example, we'll think on the final result value to be `MyResult`,
which can be any type.
```typescript
export interface MyOperationState extends PollOperationState<string> {
import { PollOperationState, PollOperation } from "@azure/core-lro";
export interface MyOperationState extends PollOperationState<MyResult> {
serviceClient: any; // You define all of these properties

@@ -93,14 +100,7 @@ myCustomString: string;

}
```
Now, to be able to create your custom operations, you'll need to extend the
PollOperation class with both your operation's state and the final result
value. For this example, we'll think on the final result value to be a string,
but it can be any type.
```typescript
export interface MyPollOperation extends PollOperation<MyOperationState, string> {}
export interface MyPollOperation extends PollOperation<MyOperationState, MyResult> {}
```
Now you can make a utility function to create new instances of your operation, as follows:
We recommend making a utility function to create new instances of your operation. Just like the following:

@@ -112,3 +112,3 @@ ```typescript

return {
// We recommend you to create copies of the given state,
// We recommend creating copies of the given state,
// just to make sure that no references are left or manipulated by mistake.

@@ -125,7 +125,16 @@ state: {

Keep in mind that you'll need to have implemented these three functions: `update`, `cancel` and `toString`
on order to successfully create an operation. Ideas of how you might do so follow:
To properly define an operation, you will need to have implemented these three functions: `update`, `cancel` and `toString`.
A guide on how to write them follows.
#### Your operation's update method
The `update` method 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](https://github.com/Azure/azure-sdk-for-js/tree/e49e136ad5109e15da2581e3eea16a5675a68d20/sdk/core/abort-controller)'s `AbortSignalLike`.
A more advanced use allows passing in a `fireProgress` function, which, if called, is responsible for triggering the
poller's `onProgress` callbacks.
Here is an example of how to write an update method for your operation:
```typescript

@@ -144,3 +153,3 @@ async function update(

// You might also update the operation's state
// You might update the operation's state at any point
if (isDone) {

@@ -162,8 +171,15 @@ this.state.completed = true;

The operation's `cancel` method should attempt to cancel the pending operation, if it's allowed by the remote service.
Otherwise, it should throw.
It only optionally receives an object with an `abortSignal` property, from [@azure/abort-controller](https://github.com/Azure/azure-sdk-for-js/tree/e49e136ad5109e15da2581e3eea16a5675a68d20/sdk/core/abort-controller)'s `AbortSignalLike`.
It returns a promise that should be resolved with an updated version of the poller's operation.
```typescript
async function cancel(
this: MyOperation,
options: { abortSignal?: AbortSignal } = {}
options: { abortSignal?: AbortSignalLike } = {}
): Promise<MyOperation> {
// Reach out to your service to trigger the cancellation of the operation
// ... Reach out to your service to trigger the cancellation of the operation ...

@@ -179,4 +195,10 @@ return makeOperation(

#### Your operation's toString method
#### Serializing an operation
The operation's method `toString` returns a string with a serialized representation of the operation.
It's useful when a poller wants to be resumed from a previously serialized state.
The deserialization of the operation has to be implemented within the constructor of a class that extends
the Poller class. You can read more at [Resuming from a previous poller](#resuming-from-a-previous-poller).
```typescript

@@ -195,4 +217,15 @@ function toString(this: MyOperation): string {

To implement a poller, you must pull in the definitions of your operation and extend core-lro's poller, as follows:
@azure/core-lro's `Poller` is 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 finishes, by calling `pollUntilDone()`, which returns a promise.
Pollers can also request the cancellation of the ongoing process (internally using `PollOperation`'s `cancel()` method).
The Poller needs two types to be defined, a type representing the state of the poller, which
must include a basic set of properties from `PollOperationState<TResult>` (as mentioned in [Implementing an operation](#implementing-an-operation)), and a return type defined by `TResult`, which can be anything.
To implement a poller, you must pull in the definitions of your operation and extend @azure/core-lro's `Poller` class, as follows:
```typescript

@@ -202,4 +235,4 @@ import { Poller } from "@azure/core-lro";

// See that "string" here is the type of the result
export class MyPoller extends Poller<MyOperationState, string> {
// See that "MyResult" here is the type of the result
export class MyPoller extends Poller<MyOperationState, MyResult> {
constructor(

@@ -233,16 +266,95 @@ baseOperation?: MyOperation,

### Using your poller
Once defined, you'll be able to use your poller as shown below:
Here's one simple example of your poller in action. More examples can be found in the test folder near this README.
```typescript
```ts
const poller = new MyPoller();
// Waiting until the operation completes
// 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();
const state = poller.getOperationState();
```
console.log(state.completed);
The Poller class implements the `PollerLike` interface, which allows poller implementations that avoid having
to export the Poller's class directly, and instead only export the already instantiated poller with the `PollerLike` type.
An example of the definition of a client that returns an instantiated poller can be seen below:
```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;
}
}
// No knowledge of the class MyPoller:
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.
Here's an example usage of your client's poller:
```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();
```
#### Resuming from a previous poller
Pollers by default have a method called `toString` that invokes the operation's `toString` method.
It can be used to store the state of a poller indefinitely, to then resume by creating another poller at any time in the future.
If an operation's `toString` method is defined as follows:
```ts
function toString(this: TestOperation): string {
return JSON.stringify({
state: this.state
});
}
```
A custom implementation of a poller can deserialize it by receiving this string and converting it back to JSON, like in the following 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);
}
}
```
## Troubleshooting

@@ -258,3 +370,3 @@

Please take a look at the [samples](https://github.com/Azure/azure-sdk-for-js/tree/bb0306eb3d962e31be6a421df62e946d1f46590e/sdk/core/core-lro/samples) directory for detailed examples on how to use this library.
Please take a look at the [samples](https://github.com/Azure/azure-sdk-for-js/tree/e49e136ad5109e15da2581e3eea16a5675a68d20/sdk/core/core-lro/samples) directory for detailed examples on how to use this library.

@@ -261,0 +373,0 @@ ## Contributing

@@ -7,6 +7,21 @@ // Copyright (c) Microsoft Corporation.

/**
* 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 type CancelOnProgress = () => void;
/**
* 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 type PollProgressCallback<TState> = (state: TState) => void;
/**
* 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 {

@@ -20,2 +35,6 @@ constructor(message: string) {

/**
* When a poller is cancelled through the `cancelOperation` method,
* the poller will be rejected with an instance of the PollerCancelledError.
*/
export class PollerCancelledError extends Error {

@@ -30,10 +49,10 @@ constructor(message: string) {

/**
* Abstract representation of a poller, intended to expose just the minimal that the user needs to work with.
* Abstract representation of a poller, intended to expose just the minimal API that the user needs to work with.
*/
export interface PollerLike<TState extends PollOperationState<TResult>, TResult> {
/**
* Defines under what conditions to reach out to the underlying service.
* It should call the operation's update method.
* 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?: AbortSignal }): Promise<void>;
poll(options?: { abortSignal?: AbortSignalLike }): Promise<void>;
/**

@@ -44,3 +63,6 @@ * Returns a promise that will resolve once the underlying operation is completed.

/**
* Reports updates.
* 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.
*/

@@ -53,3 +75,3 @@ onProgress(callback: (state: TState) => void): CancelOnProgress;

/**
* Stops the poller from continuing to poll.
* Stops the poller. After this, no manual or automated requests can be sent.
*/

@@ -64,8 +86,8 @@ stopPolling(): void;

*/
cancelOperation(options?: { abortSignal?: AbortSignal }): Promise<void>;
cancelOperation(options?: { abortSignal?: AbortSignalLike }): Promise<void>;
/**
* Returns the state of the operation.
* TState can be a different type than the underlying operation's TState.
* The TState defined in PollerLike can be a subset of the TState defined in
* the Poller implementation.
*/
getOperationState(): TState;

@@ -80,3 +102,4 @@ /**

/**
* Returns a serialized version of the poller.
* Returns a serialized version of the poller's operation
* by invoking the operation's toString method.
*/

@@ -89,2 +112,59 @@ toString(): string;

* 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();
* ```
*
*/

@@ -100,4 +180,74 @@ export abstract class Poller<TState extends PollOperationState<TResult>, TResult>

private pollProgressCallbacks: PollProgressCallback<TState>[] = [];
/**
* 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>) {

@@ -121,3 +271,21 @@ this.operation = operation;

/**
* Determines how much to wait between pollings.
* Defines how much to wait between each poll request.
* This has to be implemented by your custom poller.
*
* @azure/core-http 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-http";
*
* export class MyPoller extends Poller<MyOperationState, string> {
* // The other necessary definitions.
*
* async delay(): Promise<void> {
* const milliseconds = 1000;
* return delay(milliseconds);
* }
* }
* ```
*
*/

@@ -127,2 +295,4 @@ protected abstract async delay(): Promise<void>;

/**
* @internal
* @ignore
* Starts a loop that will break only if the poller is done

@@ -142,4 +312,10 @@ * or if the poller is stopped.

/**
* @internal
* @ignore
* 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.
*/

@@ -168,3 +344,10 @@ private async pollOnce(options: { abortSignal?: AbortSignalLike } = {}): Promise<void> {

/**
* @internal
* @ignore
* 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.
*/

@@ -178,6 +361,8 @@ private fireProgress(state: TState): void {

/**
* @internal
* @ignore
* Invokes the underlying operation's cancel method, and rejects the
* pollUntilDone promise.
*/
private async cancelOnce(options: { abortSignal?: AbortSignal } = {}): Promise<void> {
private async cancelOnce(options: { abortSignal?: AbortSignalLike } = {}): Promise<void> {
this.operation = await this.operation.cancel(options);

@@ -190,6 +375,10 @@ if (this.reject) {

/**
* Reaches out to the underlying service.
* It should call the operation's update method.
* 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.
*/
public poll(options: { abortSignal?: AbortSignal } = {}): Promise<void> {
public poll(options: { abortSignal?: AbortSignalLike } = {}): Promise<void> {
if (!this.pollOncePromise) {

@@ -216,3 +405,6 @@ this.pollOncePromise = this.pollOnce(options);

/**
* Reports updates.
* 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.
*/

@@ -249,3 +441,2 @@ public onProgress(callback: (state: TState) => void): CancelOnProgress {

*/
public isStopped(): boolean {

@@ -256,5 +447,11 @@ return this.stopped;

/**
* Tries to cancel the underlying operation.
* 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.
*/
public cancelOperation(options: { abortSignal?: AbortSignal } = {}): Promise<void> {
public cancelOperation(options: { abortSignal?: AbortSignalLike } = {}): Promise<void> {
if (!this.stopped) {

@@ -273,4 +470,47 @@ this.stopped = true;

* Returns the state of the operation.
* TState can be a different type than the underlying operation's TState.
* This method can be overridden with a custom implementation that returns specific properties out of this.operation.state.
*
* 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.
*/

@@ -293,3 +533,4 @@ public getOperationState(): TState {

/**
* Returns a serialized version of the poller.
* Returns a serialized version of the poller's operation
* by invoking the operation's toString method.
*/

@@ -296,0 +537,0 @@ public toString(): string {

@@ -6,12 +6,59 @@ // Copyright (c) Microsoft Corporation.

/**
* 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 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;
}
/**
* 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 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?: {

@@ -21,4 +68,19 @@ abortSignal?: AbortSignalLike;

}): Promise<PollOperation<TState, TResult>>;
cancel(options?: { abortSignal?: AbortSignal }): 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.
*/
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;
}
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;

@@ -8,2 +14,59 @@

* 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();
* ```
*
*/

@@ -18,33 +81,109 @@ export declare abstract class Poller<TState extends PollOperationState<TResult>, TResult> implements PollerLike<TState, TResult> {

private pollProgressCallbacks;
protected operation: PollOperation<TState, TResult>;
constructor(operation: PollOperation<TState, TResult>);
/**
* Determines how much to wait between pollings.
* 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 abstract delay(): Promise<void>;
protected operation: PollOperation<TState, TResult>;
/**
* Starts a loop that will break only if the poller is done
* or if the poller is stopped.
* 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>.
*/
private startPolling;
constructor(operation: PollOperation<TState, TResult>);
/**
* pollOnce does one polling, by calling to the update method of the underlying
* poll operation to make any relevant change effective.
* Defines how much to wait between each poll request.
* This has to be implemented by your custom poller.
*
* @azure/core-http 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-http";
*
* export class MyPoller extends Poller<MyOperationState, string> {
* // The other necessary definitions.
*
* async delay(): Promise<void> {
* const milliseconds = 1000;
* return delay(milliseconds);
* }
* }
* ```
*
*/
private pollOnce;
protected abstract delay(): Promise<void>;
/* Excluded from this release type: startPolling */
/* Excluded from this release type: pollOnce */
/* Excluded from this release type: fireProgress */
/* Excluded from this release type: cancelOnce */
/**
* fireProgress calls the functions passed in via onProgress the method of the poller.
* 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.
*/
private fireProgress;
/**
* Invokes the underlying operation's cancel method, and rejects the
* pollUntilDone promise.
*/
private cancelOnce;
/**
* Reaches out to the underlying service.
* It should call the operation's update method.
*/
poll(options?: {
abortSignal?: AbortSignal;
abortSignal?: AbortSignalLike;
}): Promise<void>;

@@ -56,3 +195,6 @@ /**

/**
* Reports updates.
* 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.
*/

@@ -73,11 +215,60 @@ onProgress(callback: (state: TState) => void): CancelOnProgress;

/**
* Tries to cancel the underlying operation.
* 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?: AbortSignal;
abortSignal?: AbortSignalLike;
}): Promise<void>;
/**
* Returns the state of the operation.
* TState can be a different type than the underlying operation's TState.
* This method can be overridden with a custom implementation that returns specific properties out of this.operation.state.
*
* 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.
*/

@@ -93,3 +284,4 @@ getOperationState(): TState;

/**
* Returns a serialized version of the poller.
* Returns a serialized version of the poller's operation
* by invoking the operation's toString method.
*/

@@ -99,2 +291,6 @@ toString(): string;

/**
* When a poller is cancelled through the `cancelOperation` method,
* the poller will be rejected with an instance of the PollerCancelledError.
*/
export declare class PollerCancelledError extends Error {

@@ -105,11 +301,11 @@ constructor(message: string);

/**
* Abstract representation of a poller, intended to expose just the minimal that the user needs to work with.
* 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> {
/**
* Defines under what conditions to reach out to the underlying service.
* It should call the operation's update method.
* 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?: AbortSignal;
abortSignal?: AbortSignalLike;
}): Promise<void>;

@@ -121,3 +317,6 @@ /**

/**
* Reports updates.
* 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.
*/

@@ -130,3 +329,3 @@ onProgress(callback: (state: TState) => void): CancelOnProgress;

/**
* Stops the poller from continuing to poll.
* Stops the poller. After this, no manual or automated requests can be sent.
*/

@@ -142,7 +341,8 @@ stopPolling(): void;

cancelOperation(options?: {
abortSignal?: AbortSignal;
abortSignal?: AbortSignalLike;
}): Promise<void>;
/**
* Returns the state of the operation.
* TState can be a different type than the underlying operation's TState.
* The TState defined in PollerLike can be a subset of the TState defined in
* the Poller implementation.
*/

@@ -158,3 +358,4 @@ getOperationState(): TState;

/**
* Returns a serialized version of the poller.
* Returns a serialized version of the poller's operation
* by invoking the operation's toString method.
*/

@@ -164,2 +365,6 @@ 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 {

@@ -169,4 +374,24 @@ 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?: {

@@ -176,18 +401,62 @@ abortSignal?: AbortSignalLike;

}): 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.
*/
cancel(options?: {
abortSignal?: AbortSignal;
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;
export { }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc