ts-async-decorators

TypeScript Async Method Decorators

Usage no npm install needed!

<script type="module">
  import tsAsyncDecorators from 'https://cdn.skypack.dev/ts-async-decorators';
</script>

README

TypeScript Async Method Decorators 🧰

NPM Downloads Tests Code Coverage License: MIT

This package provides a collection of asynchronous method decorators with an elegant declarative API.

What's Inside?

  • after - post action.
  • before - pre action.
  • cancelable - canceling execution.
  • debounce - delaying execution by timeout since the last call.
  • retry - retrying on fail.
  • semaphore - limiting the number of simultaneous calls.
  • throttle - limiting the number of calls per time range.
  • timeout - limiting the execution time.

Get Started

npm install --save ts-async-decorators

API

after

Calls an action after a decorated method.

after({ action, wait = false }): Decorator
  • action: (instance) => unknown - The action to call after the decorated method.
  • wait: boolean - The flag to wait with promise resolution until the action completes.

Example

import { after } from 'ts-async-decorators';

class SomeClass {
  @after({ action() { console.log('called fetch!'); } })
  fetch() {
    // ...
  }
}

before

Calls an action before a decorated method.

before({ action, wait = false }): Decorator
  • action: (instance) => unknown - The action to call before the decorated method.
  • wait: boolean - The flag to wait with the decorated method call until the action completes.

Example

import { before } from 'ts-async-decorators';

class SomeClass {
  @before({ action() { console.log('calling fetch!'); } })
  fetch() {
    // ...
  }
}

cancelable

Wraps a call inside a cancelable promise.

cancelable({ onCancel = undefined }): Decorator
  • onCancel: (instance) => void - The action to call on canceling the returned promise.

There is also an option to set the cancelation callback from within the decorated method.

onCancel(callback): void
  • callback: (instance) => void - The callback that will be called on promise cancelation.

Example using parameters

import { cancelable } from 'ts-async-decorators';

class SomeClass {
  @cancelable({ onCancel() { this.stop(); } })
  start() {
    // ...
  }

  stop() {
    // ...
  }
}

Example using onCancel

import { cancelable, onCancel } from 'ts-async-decorators';

class SomeClass {
  @cancelable()
  fetch() {
    const controller = new AbortController();
    const { signal } = controller;
    onCancel(() => controller.abort());

    return fetch('http://example.com', { signal });
  }
}

debounce

Delays execution by timeout since the last call.

debounce({ immediate = false, timeout }): Decorator
  • immediate: boolean - The flag to call the decorated method on the leading edge.
  • timeout: number | ((instance) => number) - The decorated method will be called only once after timeout milliseconds since the last call.

Example

import { debounce } from 'ts-async-decorators';

class SomeClass {
  @debounce({ timeout: 2000 })
  handleChange() {
    // ...
  }
}

retry

Retries failed method calls.

retry({ retries }): Decorator
  • retries: number | ((instance) => number) - The retries number.

Example

import { retry } from 'ts-async-decorators';

class SomeClass {
  @retry({ retries: 3 })
  fetch() {
    // ...
  }
}

semaphore

Limits the number of simultaneous calls.

semaphore({ limit }): Decorator
  • limit: number - The max number of simultaneous calls.

Example

import { semaphore } from 'ts-async-decorators';

const mutex = () => semaphore({ limit: 1 });

class SomeClass {
  @mutex()
  connect() {
    // ...
  }

  @semaphore({ limit: 2 })
  read() {
    // ...
  }
}

throttle

Limits the number of calls per time range.

throttle({ immediate = false, timeout }): Decorator
  • immediate: boolean - The flag to call the decorated method on the leading edge.
  • timeout: number | ((instance) => number) - The decorated method will be called only once within timeout milliseconds.

Example

import { throttle } from 'ts-async-decorators';

class SomeClass {
  @throttle({ timeout: 1000 })
  handleResize() {
    // ...
  }
}

timeout

Limits method execution time.

timeout({ timeout, reason = 'Operation timeout.' }): Decorator
  • timeout: number | ((instance) => number) - The execution timeout in milliseconds.
  • reason: string - The timeout reason.

Example

import { cancelable, timeout, onCancel } from 'ts-async-decorators';

class SomeClass {
  @timeout({ timeout: 10000, reason = 'Fetch timeout.' })
  @cancelable()
  fetch() {
    const controller = new AbortController();
    const { signal } = controller;
    onCancel(() => controller.abort());

    return fetch('http://example.com', { signal });
  }
}

Examples