@omnia/fx
Version:
Provide Omnia Fx typings and tooling for clientside Omnia development.
159 lines (158 loc) • 5.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResponsePromise = exports.Future = void 0;
class Future extends Promise {
constructor(executor) {
let resolveLocal;
let rejectLocal;
const onAborted = (cb) => {
setTimeout(() => {
this.onAborted = cb;
});
};
const exec = (resolve, reject) => {
// assign to local to prevent error assignbefore call super;
resolveLocal = resolve;
rejectLocal = reject;
};
super(exec);
this.resolving = false;
this._resolved = false;
this._rejected = false;
this.resolve = (value) => {
this.resolving = false;
this._resolved = true;
resolveLocal(value);
};
this.reject = (reason) => {
this.resolving = false;
this._rejected = true;
rejectLocal(reason);
};
if (executor) {
executor(this.resolve, this.reject, onAborted);
}
}
/**
* Handles success / rejection from Promise and returns the result as an object.
* If the promise is rejected, the error will be in the error property.
* No need to try/catch the promise when using this method.
*
* @return {*} {Future<{ success?: T, error?: Error; }>}
* @memberof Future
*/
//tryCatch(): Future<{ success?: T, error?: Error; }> {
tryCatch() {
return new Future(async (resolve) => {
try {
const data = await this;
resolve([data, undefined]);
}
catch (err) {
resolve([undefined, err]);
}
});
}
unwrapAxiosApiResponse() {
return new Future((resolve, reject, abort) => {
this.abortIf(abort);
return this.then(response => {
const apiResponse = response;
if (apiResponse?.data.success) {
resolve(apiResponse.data.data);
}
else {
reject(apiResponse.data.errorMessage);
}
}).catch(() => {
reject();
});
});
}
unwrap(executor) {
return new Future((resolve, reject, abort) => {
this.abortIf(abort);
return this.then(q => executor(q, resolve, reject));
});
}
/**
* Expose abort for other future to use.
* chain method for future
* @param onAbort
*/
abortIf(onAbort) {
//to avoid "Illegal invocation" from lost context of this
const abort = (reason) => { this.abort(reason); };
onAbort(abort);
return this;
}
// then<TResult1 = T, TResult2 = never>(onfulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>): Promise<TResult1 | TResult2> {
// this.then();
// }
/**
* Aborts the request
*
* @param {*} [reason]
* @memberof Future
*/
abort(reason) {
if (this.onAborted) {
this.onAborted(reason);
}
else {
throw "Failed calling abort() => The future has no onAborted callback or you tried to call abort immediately after the future was created.";
}
}
/**
* Creates a Promise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any Promise is rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
static all(values) {
// have issue with Promise.all not working when promises is mixin Future and promise
// so implement Future.all to make a wrapper promise to Future to resolve that issue.
const promises = values.map(p => p instanceof Future ? new Promise((resolve, reject) => p.then(resolve, reject)) : p);
return Promise.all(promises);
}
get resolved() {
return this._resolved;
}
get rejected() {
return this._rejected;
}
static get [Symbol.species]() {
return Promise;
}
get [Symbol.toStringTag]() {
// return Object value to make vue can build get/set reactive.
return "Object";
}
static new() {
return new Future(() => { });
}
}
exports.Future = Future;
class ResponsePromise extends Promise {
constructor(executor) {
const onCancel = (cb) => {
//using nextTick because we cant use "this" before super()
setTimeout(() => {
this.cancelCb = cb;
});
};
const oExecutor = (resolve, reject) => {
executor(resolve, reject, onCancel);
};
super(oExecutor);
}
cancel() {
if (this.cancelCb) {
this.cancelCb();
}
else {
console.warn("onCancel not provided");
}
}
}
exports.ResponsePromise = ResponsePromise;