npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

cancellation-context

v0.2.11

Published

Promise-cancellation made easy. Cancel one or more promises in a given context.

Downloads

24

Readme

cancellation-context

Promise-cancellation made easy. Cancel one or more promises in a given context.

Install

npm i cancellation-context

Usage

Create a new context by calling the exported factory function.

const CancellationContext = require('cancellation-context');
const context = CancellationContext();

Once you have a context, you can create new "cancellable-promise" instances within that context by calling context.Cancellable with promise-thunk factory.

Note: Promises are eager by design and don't naturally lend themselve to cancellation. As such, arbitrary promises are not cancellable and the onus is the author to write cancellable promise implementations. No library, including this one, will be able to solve for that unless there are some fundamental changes to the JavaScript spec.

The cancellation-context library attempts to make the authoring of cancellable-promises as easy as possible by designing around the idea of promise-thunks.

The recommended pattern is as follows:

CancellableFactory = ({{ ...args }}) => onCancel => {{ promise }};

For example...

const context = require('cancellation-context')();

const MyCancellableFactory = msg => onCancel => new Promise((resolve, reject) => {
    const t = setTimeout(() => resolve(msg), 1000);
    onCancel(reason => {
        clearTimeout(t);
        resolve(reason);
    });
});

(async () => {
    const myCancellable = context.Cancellable(MyCancellableFactory('success!'));
    setTimeout(() => myCancellable.cancel('cancelled!'), 500);
    console.log(await myCancellable); // => 'cancelled!'
})();

By leveraging a thunk pattern, you can maintain composability while supporting the need for an onCancel hook.

API

cancellation-context

module.exports ⇒ CancellationContext

Factory function for creating CancellationContext instances.

Kind: Exported member

module.exports~CancellationContext

Kind: inner class of module.exports
See: CancellationContextFactory

new CancellationContext()

CancellationContext is a private class. Use exported CancellationContextFactory function for instantiation.

module.exports~CancellationError

Kind: inner class of module.exports
Implements: Error

new CancellationError()

An error class used for indicating cancellation events.

module.exports~TimeoutError

Kind: inner class of module.exports
Implements: Error

new TimeoutError()

An error class used for indicating timeout events.

module.exports~Cancellable(PromiseThunkFactory) ⇒ CancellablePromise

Given a PromiseThunkFactory which accepts on onCancel hook, returns a CancellablePromise.

Kind: inner method of module.exports
Returns: CancellablePromise - A CancellablePromise is a promise with an additional cancel method attached.

| Param | Type | | --- | --- | | PromiseThunkFactory | function |

module.exports~Perishable(PromiseThunkFactory) ⇒ PerishablePromise

Given a PromiseThunkFactory which accepts on onCancel hook, returns a PerishablePromise.

Kind: inner method of module.exports
Returns: PerishablePromise - A PerishablePromise is a CancellablePromise which will be automatically cancelled after a specified amount of time.

| Param | Type | | --- | --- | | PromiseThunkFactory | function |

module.exports~cancel(promise, reason) ⇒ void

Given promise and reason calls canceller on promise with reason.

Kind: inner method of module.exports

| Param | Type | Description | | --- | --- | --- | | promise | Promise | CancellablePromise to be cancelled | | reason | 'string' | 'Error' | reason for cancellation |

module.exports~cancelAll(reason) ⇒ void

Calls cancel method with reason on every CancellablePromise associated with the context instance.

Kind: inner method of module.exports

| Param | Type | Description | | --- | --- | --- | | reason | 'string' | 'Error' | reason for cancellation |

module.exports~delay(ms) ⇒ function

A cancellable delay implementation which resolves after given number of milliseconds.

Kind: inner method of module.exports
Returns: function - Returns function which accepts onCancel hook.

| Param | Type | Description | | --- | --- | --- | | ms | number | Number of milliseconds to wait |

Example

const cancellableDelay = context.Cancellable(context.delay(1500));
setTimeout(() => cancellableDelay.cancel(), 1000);
await cancellableDelay;

module.exports~timeout(ms) ⇒ function

A cancellable timeout implementation which resolves after given number of milliseconds.

Kind: inner method of module.exports
Returns: function - Returns function which accepts onCancel hook.

| Param | Type | Description | | --- | --- | --- | | ms | number | Number of milliseconds to wait |

Example

const cancellableTimeout = context.Cancellable(context.delay(1500));
setTimeout(() => cancellableTimeout.cancel(), 1000);
await cancellableTimeout;

module.exports~CancellableDelay(ms) ⇒ function

A CancellableFactory which resolves after given number of milliseconds.

Kind: inner method of module.exports
Returns: function - Returns function which accepts onCancel hook.

| Param | Type | Description | | --- | --- | --- | | ms | number | Number of milliseconds to wait |

Example

const cancellableDelay = context.CancellableDelay(1500));
setTimeout(() => cancellableDelay.cancel(), 1000);
await cancellableDelay;

module.exports~CancellableTimeout(ms) ⇒ function

A CancellableFactory which rejects after given number of milliseconds.

Kind: inner method of module.exports
Returns: function - Returns function which accepts onCancel hook.

| Param | Type | Description | | --- | --- | --- | | ms | number | Number of milliseconds to wait |

Example

const cancellableTimeout = context.CancellableTimeout(1500));
setTimeout(() => cancellableTimeout.cancel(), 1000);
await cancellableTimeout;

module.exports~PerishableTimeout(ms, ttl) ⇒ function

A PerishableFactory which rejects after given number of milliseconds.

Kind: inner method of module.exports
Returns: function - Returns function which accepts onCancel hook.

| Param | Type | Description | | --- | --- | --- | | ms | number | Number of milliseconds to wait | | ttl | number | Number of milliseconds until cancelled |

Example

const cancellableTimeout = context.PerishableTimeout(1500, 1000);
await cancellableTimeout;

module.exports~PerishableDelay(ms, ttl) ⇒ function

A PerishableFactory which resolves after given number of milliseconds.

Kind: inner method of module.exports
Returns: function - Returns function which accepts onCancel hook.

| Param | Type | Description | | --- | --- | --- | | ms | number | Number of milliseconds to wait | | ttl | number | Number of milliseconds until cancelled |

Example

const cancellableDelay = context.PerishableDelay(1500, 1000);
await cancellableDelay;

Examples

Cancellable Delay

const context = require('cancellation-context')();

(async () => {

    try {
        const ttl = 1000; // try increasing to 10000
        console.log(await context.PerishableTimeout(1500, ttl).then(() => 'success'));
    } catch (e) {
        console.error('Boom!', e);
    }

})();

Manual Cancellation

const context = require('cancellation-context')();

const sleep = ms => onCancel => {
    return new Promise((resolve, reject) => {
        const t = setTimeout(() => resolve('success'), ms);
        onCancel(error => {
            clearTimeout(t);
            reject(error);
        });
    });
};

(async () => {

    try {
        const promise = context.Cancellable(sleep(1500));
        const handle = setTimeout(() => context.cancel(promise), 1000); // try increasing to 10000
        console.log('Success!', await promise);
        clearTimeout(handle);
    } catch (e) {
        console.error('Boom!', e);
    }

})();

Async Iterables

const context = require('cancellation-context')();

(async () => {

    async function* loop() {
        while (true) {
            const promises = [
                context.CancellableTimeout(500).then(() => (console.log('done'), 'success')),
                context.CancellableTimeout(1000).then(() => (console.log('done'), 'success')),
                context.CancellableTimeout(1500).then(() => (console.log('done'), 'success'))
            ];
            yield await Promise.all(promises);
        }
    }

    setTimeout(() => context.cancelAll(), 4000);

    try {
        for await (const result of loop()) {
            console.log(result);
        }
    } catch (e) {
        context.cancelAll();
        console.error('Boom!', e);
    }

})();