@dvcol/common-utils
Version:
Typescript library for common utility functions and constants
176 lines (168 loc) • 7.28 kB
JavaScript
;Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2;
var _chunkMXKBAB24cjs = require('./chunk-MXKBAB24.cjs');
// lib/http/utils/fetch.utils.ts
var CancellablePromise = (_class = class _CancellablePromise extends Promise {constructor(...args2) { super(...args2); _class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this); }
__init() {this._controller = new AbortController()}
__init2() {this._debug = false}
__init3() {this.id = `cancellable-promise-${_chunkMXKBAB24cjs.getUUID.call(void 0, )}`}
/**
* Gets the AbortSignal associated with the AbortController, allowing external code to listen for cancellation events.
*
* @type {AbortSignal}
* @memberof CancellableFetch
*/
get signal() {
return this._controller.signal;
}
/**
* Sets the AbortSignal associated with the AbortController, allowing external code to listen for cancellation events.
* @param signal - The AbortSignal to associate with the AbortController.
*
* @memberof CancellableFetch
*/
set signal(signal) {
this._controller.signal.onabort = signal.onabort;
}
/**
* Cancels the currently active fetch request by aborting the associated AbortController.
*
* @param {unknown} [reason] - An optional reason for aborting the fetch request.
* @memberof CancellableFetch
*/
cancel(reason) {
if (this.signal.aborted) return;
if (this._debug) console.error("Promise was cancelled.", { id: this.id });
this._controller.abort(reason);
}
then(...params) {
const promise = super.then(...params);
promise.cancel = this.cancel.bind(this);
promise.signal = this.signal;
return promise;
}
catch(onRejected) {
const promise = super.catch(onRejected);
promise.cancel = this.cancel.bind(this);
promise.signal = this.signal;
return promise;
}
finally(onFinally) {
const promise = super.finally(onFinally);
promise.cancel = this.cancel.bind(this);
promise.signal = this.signal;
return promise;
}
static isCancellable(promise) {
return promise instanceof _CancellablePromise || "cancel" in promise && "signal" in promise;
}
// eslint-disable-next-line no-dupe-class-members -- To allow method overloading
static resolve(value) {
return _CancellablePromise.from(Promise.resolve(value));
}
static from(promise) {
if (_CancellablePromise.isCancellable(promise)) return promise;
let _reject;
const cancellablePromise = new _CancellablePromise((resolve, reject) => {
_reject = reject;
promise.then(resolve).catch(reject);
});
const onAbort = () => _reject(new DOMException("The operation was aborted.", "AbortError"));
cancellablePromise.signal.addEventListener("abort", onAbort);
return cancellablePromise;
}
}, _class);
var CancellableFetch = (_class2 = class _CancellableFetch {
__init4() {this._controller = new AbortController()}
__init5() {this.id = `cancellable-promise-${_chunkMXKBAB24cjs.getUUID.call(void 0, )}`}
/**
* Gets the AbortSignal associated with the AbortController, allowing external code to listen for cancellation events.
*
* @readonly
* @type {AbortSignal}
* @memberof CancellableFetch
*/
get signal() {
return this._controller.signal;
}
/**
* Creates an instance of CancellableFetch.
*
* @param {boolean} [debug=false] - Indicates whether debug information should be logged when a fetch request is cancelled.
* @memberof CancellableFetch
*/
constructor(debug = false) {;_class2.prototype.__init4.call(this);_class2.prototype.__init5.call(this);
this._debug = debug;
}
/**
* Performs a fetch request with optional cancellation support.
*
* @param {RequestInfo | URL} input - The resource URL or a Request object.
* @param {Omit<RequestInit, 'signal'>} [init] - Optional RequestInit options, excluding the 'signal' property.
* @returns {Promise<Response>} A Promise that resolves to the Response to that request.
* @memberof CancellableFetch
* @throws {Error} If an error occurs during the fetch operation, other than an 'AbortError'.
*/
async fetch(input, init) {
try {
return await fetch(input, { ...init, signal: this._controller.signal });
} catch (error) {
if (error instanceof Error && _optionalChain([error, 'optionalAccess', _ => _.name]) === "AbortError") {
if (this._debug) console.debug("Fetch request was cancelled.", { input, init, error });
return Promise.reject(error);
}
throw error;
}
}
/**
* Performs a fetch request using a new instance of CancellableFetch.
*
* @static
* @template T - The type of the promise result.
* @param {RequestInfo | URL} input - The resource URL or a Request object.
* @param {Omit<RequestInit, 'signal'>} [init] - Optional RequestInit options, excluding the 'signal' property.
* @returns {CancellablePromise<T>} A cancellable promise that resolves to the Response to the fetch request.
* @memberof CancellableFetch
*/
static fetch(input, init) {
const cancellableFetch = new _CancellableFetch();
const promise = cancellableFetch.fetch(input, init);
const attributes = ["id", "signal"];
const bindAttributes = (_promise) => {
attributes.forEach((prop) => {
if (prop in _promise) return;
Object.defineProperty(_promise, prop, { get: () => cancellableFetch[prop] });
});
};
const methods = ["then", "catch", "finally"];
const bindMethods = (_promise) => {
methods.forEach((method) => {
const _method = _promise[method];
_promise[method] = (...params) => {
const methodPromise = _method.bind(_promise)(...params);
if (CancellablePromise.isCancellable(methodPromise)) return methodPromise;
bindAttributes(methodPromise);
bindMethods(methodPromise);
methodPromise.cancel = (...args) => cancellableFetch.cancel(...args);
return methodPromise;
};
});
};
bindAttributes(promise);
bindMethods(promise);
promise.cancel = (...args) => cancellableFetch.cancel(...args);
return promise;
}
/**
* Cancels the currently active fetch request by aborting the associated AbortController.
*
* @param {unknown} [reason] - An optional reason for aborting the fetch request.
*
* @memberof CancellableFetch
*/
cancel(reason) {
if (this.signal.aborted) return;
if (this._debug) console.debug("Fetch request was cancelled.", { id: this.id, reason });
this._controller.abort(reason);
}
}, _class2);
exports.CancellablePromise = CancellablePromise; exports.CancellableFetch = CancellableFetch;