@ceramicnetwork/common
Version:
Ceramic common types and utilities
62 lines • 1.95 kB
JavaScript
import { timer, fromEvent, merge } from 'rxjs';
import { first } from 'rxjs/operators';
export function mergeAbortSignals(signals) {
const controller = new AbortController();
if (signals.length === 0) {
throw Error('Need abort signals to create a merged abort signal');
}
if (signals.some((signal) => signal.aborted)) {
controller.abort();
return controller.signal;
}
merge(...signals.map((signal) => fromEvent(signal, 'abort')))
.pipe(first())
.subscribe(() => {
controller.abort();
});
return controller.signal;
}
export class TimedAbortSignal {
constructor(timeout) {
const controller = new AbortController();
this.signal = controller.signal;
if (timeout <= 0) {
controller.abort();
return;
}
this._subscription = timer(timeout).subscribe(() => {
controller.abort();
});
}
clear() {
this._subscription?.unsubscribe();
}
}
export async function abortable(original, fn) {
const controller = new AbortController();
const onAbort = () => {
controller.abort();
};
original.addEventListener('abort', onAbort);
if (original.aborted)
controller.abort();
return fn(controller.signal).finally(() => {
original.removeEventListener('abort', onAbort);
});
}
export async function delayOrAbort(ms, signal) {
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => resolve(), ms);
if (signal) {
const handleAbort = () => {
clearTimeout(timeout);
signal.removeEventListener('abort', handleAbort);
reject(signal.reason);
};
if (signal.aborted)
handleAbort();
signal.addEventListener('abort', handleAbort);
}
});
}
//# sourceMappingURL=abort-signal-utils.js.map