Socket
Socket
Sign inDemoInstall

p-cancelable

Package Overview
Dependencies
0
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.0.0 to 4.0.0

99

index.d.ts

@@ -19,55 +19,9 @@ /**

export interface OnCancelFunction {
(cancelHandler: () => void): void;
shouldReject: boolean;
(cancelHandler: () => void): void;
}
// eslint-disable-next-line @typescript-eslint/naming-convention
export default class PCancelable<ValueType> extends Promise<ValueType> {
/**
Whether the promise is canceled.
*/
readonly isCanceled: boolean;
/**
Cancel the promise and optionally provide a reason.
The cancellation is synchronous. Calling it after the promise has settled or multiple times does nothing.
@param reason - The cancellation reason to reject the promise with.
*/
cancel: (reason?: string) => void;
/**
Create a promise that can be canceled.
Can be constructed in the same was as a [`Promise` constructor](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise), but with an appended `onCancel` parameter in `executor`. `PCancelable` is a subclass of `Promise`.
Cancelling will reject the promise with `CancelError`. To avoid that, set `onCancel.shouldReject` to `false`.
@example
```
import PCancelable from 'p-cancelable';
const cancelablePromise = new PCancelable((resolve, reject, onCancel) => {
const job = new Job();
onCancel.shouldReject = false;
onCancel(() => {
job.stop();
});
job.on('finish', resolve);
});
cancelablePromise.cancel(); // Doesn't throw an error
```
*/
constructor(
executor: (
resolve: (value?: ValueType | PromiseLike<ValueType>) => void,
reject: (reason?: unknown) => void,
onCancel: OnCancelFunction
) => void
);
/**
Convenience method to make your promise-returning or async function cancelable.

@@ -149,3 +103,3 @@

Agument5Type,
ReturnType
ReturnType,
>(

@@ -170,2 +124,49 @@ userFn: (

): (...arguments: unknown[]) => PCancelable<ReturnType>;
/**
Whether the promise is canceled.
*/
readonly isCanceled: boolean;
/**
Cancel the promise and optionally provide a reason.
The cancellation is synchronous. Calling it after the promise has settled or multiple times does nothing.
@param reason - The cancellation reason to reject the promise with.
*/
cancel: (reason?: string) => void;
/**
Create a promise that can be canceled.
Can be constructed in the same was as a [`Promise` constructor](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise), but with an appended `onCancel` parameter in `executor`. `PCancelable` is a subclass of `Promise`.
Cancelling will reject the promise with `CancelError`. To avoid that, set `onCancel.shouldReject` to `false`.
@example
```
import PCancelable from 'p-cancelable';
const cancelablePromise = new PCancelable((resolve, reject, onCancel) => {
const job = new Job();
onCancel.shouldReject = false;
onCancel(() => {
job.stop();
});
job.on('finish', resolve);
});
cancelablePromise.cancel(); // Doesn't throw an error
```
*/
constructor(
executor: (
resolve: (value?: ValueType | PromiseLike<ValueType>) => void,
reject: (reason?: unknown) => void,
onCancel: OnCancelFunction
) => void
);
}

@@ -12,28 +12,31 @@ export class CancelError extends Error {

// TODO: Use private class fields when ESLint 8 is out.
const promiseState = Object.freeze({
pending: Symbol('pending'),
canceled: Symbol('canceled'),
resolved: Symbol('resolved'),
rejected: Symbol('rejected'),
});
export default class PCancelable {
static fn(userFunction) {
return (...arguments_) => {
return new PCancelable((resolve, reject, onCancel) => {
arguments_.push(onCancel);
// eslint-disable-next-line promise/prefer-await-to-then
userFunction(...arguments_).then(resolve, reject);
});
};
return (...arguments_) => new PCancelable((resolve, reject, onCancel) => {
arguments_.push(onCancel);
userFunction(...arguments_).then(resolve, reject);
});
}
#cancelHandlers = [];
#rejectOnCancel = true;
#state = promiseState.pending;
#promise;
#reject;
constructor(executor) {
this._cancelHandlers = [];
this._isPending = true;
this._isCanceled = false;
this._rejectOnCancel = true;
this.#promise = new Promise((resolve, reject) => {
this.#reject = reject;
this._promise = new Promise((resolve, reject) => {
this._reject = reject;
const onResolve = value => {
if (!this._isCanceled || !onCancel.shouldReject) {
this._isPending = false;
if (this.#state !== promiseState.canceled || !onCancel.shouldReject) {
resolve(value);
this.#state = promiseState.resolved;
}

@@ -43,12 +46,14 @@ };

const onReject = error => {
this._isPending = false;
reject(error);
if (this.#state !== promiseState.canceled || !onCancel.shouldReject) {
reject(error);
this.#state = promiseState.rejected;
}
};
const onCancel = handler => {
if (!this._isPending) {
throw new Error('The `onCancel` handler was attached after the promise settled.');
if (this.#state !== promiseState.pending) {
throw new Error(`The \`onCancel\` handler was attached after the promise ${this.#state.description}.`);
}
this._cancelHandlers.push(handler);
this.#cancelHandlers.push(handler);
};

@@ -58,7 +63,7 @@

shouldReject: {
get: () => this._rejectOnCancel,
get: () => this.#rejectOnCancel,
set: boolean => {
this._rejectOnCancel = boolean;
}
}
this.#rejectOnCancel = boolean;
},
},
});

@@ -70,31 +75,29 @@

// eslint-disable-next-line unicorn/no-thenable
then(onFulfilled, onRejected) {
// eslint-disable-next-line promise/prefer-await-to-then
return this._promise.then(onFulfilled, onRejected);
return this.#promise.then(onFulfilled, onRejected);
}
catch(onRejected) {
// eslint-disable-next-line promise/prefer-await-to-then
return this._promise.catch(onRejected);
return this.#promise.catch(onRejected);
}
finally(onFinally) {
// eslint-disable-next-line promise/prefer-await-to-then
return this._promise.finally(onFinally);
return this.#promise.finally(onFinally);
}
cancel(reason) {
if (!this._isPending || this._isCanceled) {
if (this.#state !== promiseState.pending) {
return;
}
this._isCanceled = true;
this.#state = promiseState.canceled;
if (this._cancelHandlers.length > 0) {
if (this.#cancelHandlers.length > 0) {
try {
for (const handler of this._cancelHandlers) {
for (const handler of this.#cancelHandlers) {
handler();
}
} catch (error) {
this._reject(error);
this.#reject(error);
return;

@@ -104,4 +107,4 @@ }

if (this._rejectOnCancel) {
this._reject(new CancelError(reason));
if (this.#rejectOnCancel) {
this.#reject(new CancelError(reason));
}

@@ -111,3 +114,3 @@ }

get isCanceled() {
return this._isCanceled;
return this.#state === promiseState.canceled;
}

@@ -114,0 +117,0 @@ }

{
"name": "p-cancelable",
"version": "3.0.0",
"version": "4.0.0",
"description": "Create a promise that can be canceled",

@@ -15,3 +15,3 @@ "license": "MIT",

"engines": {
"node": ">=12.20"
"node": ">=14.16"
},

@@ -46,7 +46,7 @@ "scripts": {

"devDependencies": {
"ava": "^3.15.0",
"ava": "^4.2.0",
"delay": "^5.0.0",
"tsd": "^0.16.0",
"xo": "^0.40.1"
"tsd": "^0.20.0",
"xo": "^0.48.0"
}
}

@@ -7,9 +7,9 @@ # p-cancelable

*If you target [Node.js 15](https://medium.com/@nodejs/node-js-v15-0-0-is-here-deb00750f278) or later, this package is [less useful](https://github.com/sindresorhus/p-cancelable/issues/27) and you should probably use [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) instead.*
*If you target [Node.js 16](https://medium.com/@nodejs/node-js-v15-0-0-is-here-deb00750f278) or later, this package is [less useful](https://github.com/sindresorhus/p-cancelable/issues/27) and you should probably use [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) instead.*
## Install
```sh
npm install p-cancelable
```
$ npm install p-cancelable
```

@@ -16,0 +16,0 @@ ## Usage

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc