UNPKG

@baqhub/sdk

Version:

The official JavaScript SDK for the BAQ federated app platform.

90 lines (89 loc) 2.52 kB
import { CustomError } from "./customError.js"; export class AbortedError extends CustomError { constructor() { super("Process aborted."); } } function throwIfAborted(signal) { if (!signal?.aborted) { return; } throw new AbortedError(); } function delay(delayMilliseconds, abort) { return new Promise((resolve, reject) => { if (abort?.aborted) { return reject(new AbortedError()); } const onAbortRequested = () => { abort?.removeEventListener("abort", onAbortRequested); clearTimeout(timeoutId); reject(new AbortedError()); }; abort?.addEventListener("abort", onAbortRequested); const timeoutId = setTimeout(() => { resolve(); abort?.removeEventListener("abort", onAbortRequested); }, delayMilliseconds); }); } function wait(signal) { return new Promise(resolve => { const onAbort = () => { signal.removeEventListener("abort", onAbort); resolve(); }; signal.addEventListener("abort", onAbort); }); } function sharePromise(promiseCreator) { let promise; let waitersCount = 0; const controller = new AbortController(); const getPromise = () => { if (promise) { return promise; } promise = promiseCreator(controller.signal); return promise; }; return (signal) => { return new Promise((resolve, reject) => { let aborted = false; const cleanup = () => { signal?.removeEventListener("abort", onAbort); waitersCount--; }; const onAbort = () => { aborted = true; cleanup(); if (waitersCount === 0) { controller.abort(); } reject(new AbortedError()); }; waitersCount++; throwIfAborted(signal); signal?.addEventListener("abort", onAbort); getPromise().then(result => { if (aborted) { return; } cleanup(); resolve(result); }, error => { if (aborted) { return; } cleanup(); reject(error); }); }); }; } export const Async = { throwIfAborted, delay, wait, sharePromise, };