@nesvet/n
Version:
Various utilities
64 lines • 2.35 kB
JavaScript
/* eslint-disable @typescript-eslint/no-explicit-any */
const nativesMap = new WeakMap();
export class StatefulPromise extends Promise {
constructor(executor, options) {
let nativeResolve;
let nativeReject;
super((resolve, reject) => {
nativeResolve = resolve;
nativeReject = reject;
});
nativesMap.set(this, { resolve: nativeResolve, reject: nativeReject });
if (options?.signal)
if (options.signal.aborted)
this.reject(new DOMException("Aborted", "AbortError"));
else {
const abortListener = () => this.reject(new DOMException("Aborted", "AbortError"));
options.signal.addEventListener("abort", abortListener);
this.finally(() => options.signal?.removeEventListener("abort", abortListener));
}
if (typeof options?.timeout === "number" && Number.isFinite(options.timeout)) {
const timeout = setTimeout(() => this.reject(new DOMException("Timeout exceeded", "TimeoutError")), options.timeout);
this.finally(() => clearTimeout(timeout));
}
executor?.(this.resolve, this.reject);
}
isPending = true;
isFulfilled = false;
isRejected = false;
state = "pending";
result;
resolve = (value) => {
if (this.isPending) {
this.isPending = false;
this.isFulfilled = true;
this.state = "fulfilled";
this.result = value;
const native = nativesMap.get(this);
if (native) {
native.resolve.call(this, value);
nativesMap.delete(this);
}
}
};
reject = (reason) => {
if (this.isPending) {
this.isPending = false;
this.isRejected = true;
this.state = "rejected";
this.result = reason;
const native = nativesMap.get(this);
if (native) {
native.reject.call(this, reason);
nativesMap.delete(this);
}
}
};
static resolved(value) {
return new StatefulPromise(resolve => resolve(value));
}
static rejected(reason) {
return new StatefulPromise((_, reject) => reject(reason));
}
}
//# sourceMappingURL=StatefulPromise.js.map