UNPKG

@nevware21/ts-async

Version:

support for asynchronous development with a Promise based task Scheduler, several different Promise implementations (synchronous, idle, asynchronous and native runtime wrappers), await helpers, and aliases all built and tested using TypeScript.

1,138 lines (1,116 loc) 46.4 kB
/*! * NevWare21 Solutions LLC - ts-async, 0.5.4 * https://github.com/nevware21/ts-async * Copyright (c) NevWare21 Solutions LLC and contributors. All rights reserved. * Licensed under the MIT license. */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@nevware21/ts-utils')) : typeof define === 'function' && define.amd ? define(['exports', '@nevware21/ts-utils'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.nevware21 = global.nevware21 || {}, global.nevware21["ts-async"] = {}), global.nevware21["ts-utils"])); })(this, (function (exports, tsUtils) { 'use strict'; var STR_PROMISE = "Promise"; var DONE = "done"; var VALUE = "value"; var RETURN = "return"; var REJECTED = "rejected"; function doAwaitResponse(value, cb) { return doAwait(value, function (value) { return cb ? cb({ status: "fulfilled", rejected: false, value: value }) : value; }, function (reason) { return cb ? cb({ status: REJECTED, rejected: true, reason: reason }) : reason; }); } function doAwait(value, resolveFn, rejectFn, finallyFn) { var result = value; try { if (tsUtils.isPromiseLike(value)) { if (resolveFn || rejectFn) { result = value.then(resolveFn, rejectFn); } } else { try { if (resolveFn) { result = resolveFn(value); } } catch (err) { if (rejectFn) { result = rejectFn(err); } else { throw err; } } } } finally { if (finallyFn) { doFinally(result, finallyFn); } } return result; } function doFinally(value, finallyFn) { var result = value; if (finallyFn) { if (tsUtils.isPromiseLike(value)) { if (value.finally) { result = value.finally(finallyFn); } else { result = value.then(function (value) { finallyFn(); return value; }, function (reason) { finallyFn(); throw reason; }); } } else { finallyFn(); } } return result; } /*#__NO_SIDE_EFFECTS__*/ function _pureAssign(func1, func2) { return func1 || func2; } var _debugState; var _debugResult; var _debugHandled; var _promiseDebugEnabled = false; function _addDebugState$1(thePromise, stateFn, resultFn, handledFn) { _debugState = _debugState || { toString: function () { return "[[PromiseState]]"; } }; _debugResult = _debugResult || { toString: function () { return "[[PromiseResult]]"; } }; _debugHandled = _debugHandled || { toString: function () { return "[[PromiseIsHandled]]"; } }; var props = {}; props[_debugState] = { get: stateFn }; props[_debugResult] = { get: resultFn }; props[_debugHandled] = { get: handledFn }; tsUtils.objDefineProperties(thePromise, props); } function setPromiseDebugState(enabled, logger) { _promiseDebugEnabled = enabled; } var STRING_STATES = [ "pending", "resolving", "resolved", REJECTED ]; var DISPATCH_EVENT = "dispatchEvent"; var _hasInitEvent; function _hasInitEventFn(doc) { var evt; if (doc && doc.createEvent) { evt = doc.createEvent("Event"); } return (!!evt && evt.initEvent); } function emitEvent(target, evtName, populateEvent, useNewEvent) { var doc = tsUtils.getDocument(); !_hasInitEvent && (_hasInitEvent = tsUtils.createCachedValue(!!tsUtils.safe(_hasInitEventFn, [doc]).v)); var theEvt = _hasInitEvent.v ? doc.createEvent("Event") : (useNewEvent ? new Event(evtName) : {}); populateEvent && populateEvent(theEvt); if (_hasInitEvent.v) { theEvt.initEvent(evtName, false, true); } if (theEvt && target[DISPATCH_EVENT]) { target[DISPATCH_EVENT](theEvt); } else { var handler = target["on" + evtName]; if (handler) { handler(theEvt); } else { var theConsole = tsUtils.getInst("console"); theConsole && (theConsole["error"] || theConsole["log"])(evtName, tsUtils.dumpObj(theEvt)); } } } var NODE_UNHANDLED_REJECTION = "unhandledRejection"; var UNHANDLED_REJECTION = NODE_UNHANDLED_REJECTION.toLowerCase(); var _currentPromiseId = []; var _uniquePromiseId = 0; var _unhandledRejectionTimeout = 10; var _aggregationError; var _hasPromiseRejectionEvent; function dumpFnObj(value) { if (tsUtils.isFunction(value)) { return value.toString(); } return tsUtils.dumpObj(value); } /*#__NO_SIDE_EFFECTS__*/ function _createAggregationError(values) { !_aggregationError && (_aggregationError = tsUtils.createCachedValue(tsUtils.safe(tsUtils.getInst, ["AggregationError"]).v || tsUtils.createCustomError("AggregationError", function (self, args) { self.errors = args[0]; }))); return new _aggregationError.v(values); } function _createPromise(newPromise, processor, executor) { var additionalArgs = tsUtils.arrSlice(arguments, 3); var _state = 0 ; var _hasResolved = false; var _settledValue; var _queue = []; var _id = _uniquePromiseId++; var _parentId = _currentPromiseId.length > 0 ? _currentPromiseId[_currentPromiseId.length - 1] : undefined; var _handled = false; var _unHandledRejectionHandler = null; var _thePromise; function _then(onResolved, onRejected) { try { _currentPromiseId.push(_id); _handled = true; _unHandledRejectionHandler && _unHandledRejectionHandler.cancel(); _unHandledRejectionHandler = null; var thenPromise = newPromise(function (resolve, reject) { _queue.push(function () { try { var handler = _state === 2 ? onResolved : onRejected; var value = tsUtils.isUndefined(handler) ? _settledValue : (tsUtils.isFunction(handler) ? handler(_settledValue) : handler); if (tsUtils.isPromiseLike(value)) { value.then(resolve, reject); } else if (handler) { resolve(value); } else if (_state === 3 ) { reject(value); } else { resolve(value); } } catch (e) { reject(e); } }); if (_hasResolved) { _processQueue(); } }, additionalArgs); return thenPromise; } finally { _currentPromiseId.pop(); } } function _catch(onRejected) { return _then(undefined, onRejected); } function _finally(onFinally) { var thenFinally = onFinally; var catchFinally = onFinally; if (tsUtils.isFunction(onFinally)) { thenFinally = function (value) { onFinally && onFinally(); return value; }; catchFinally = function (reason) { onFinally && onFinally(); throw reason; }; } return _then(thenFinally, catchFinally); } function _strState() { return STRING_STATES[_state]; } function _processQueue() { if (_queue.length > 0) { var pending = _queue.slice(); _queue = []; _handled = true; _unHandledRejectionHandler && _unHandledRejectionHandler.cancel(); _unHandledRejectionHandler = null; processor(pending); } } function _createSettleIfFn(newState, allowState) { return function (theValue) { if (_state === allowState) { if (newState === 2 && tsUtils.isPromiseLike(theValue)) { _state = 1 ; theValue.then(_createSettleIfFn(2 , 1 ), _createSettleIfFn(3 , 1 )); return; } _state = newState; _hasResolved = true; _settledValue = theValue; _processQueue(); if (!_handled && newState === 3 && !_unHandledRejectionHandler) { _unHandledRejectionHandler = tsUtils.scheduleTimeout(_notifyUnhandledRejection, _unhandledRejectionTimeout); } } }; } function _notifyUnhandledRejection() { if (!_handled) { _handled = true; if (tsUtils.isNode()) { process.emit(NODE_UNHANDLED_REJECTION, _settledValue, _thePromise); } else { var gbl = tsUtils.getWindow() || tsUtils.getGlobal(); !_hasPromiseRejectionEvent && (_hasPromiseRejectionEvent = tsUtils.createCachedValue(tsUtils.safe((tsUtils.getInst), [STR_PROMISE + "RejectionEvent"]).v)); emitEvent(gbl, UNHANDLED_REJECTION, function (theEvt) { tsUtils.objDefine(theEvt, "promise", { g: function () { return _thePromise; } }); theEvt.reason = _settledValue; return theEvt; }, !!_hasPromiseRejectionEvent.v); } } } _thePromise = { then: _then, "catch": _catch, finally: _finally }; tsUtils.objDefineProp(_thePromise, "state", { get: _strState }); if (_promiseDebugEnabled) { _addDebugState$1(_thePromise, _strState, function () { return tsUtils.objToString(_settledValue); }, function () { return _handled; }); } if (tsUtils.hasSymbol()) { _thePromise[tsUtils.getKnownSymbol(11 )] = "IPromise"; } function _toString() { return "IPromise" + (_promiseDebugEnabled ? "[" + _id + (!tsUtils.isUndefined(_parentId) ? (":" + _parentId) : "") + "]" : "") + " " + _strState() + (_hasResolved ? (" - " + dumpFnObj(_settledValue)) : "") + (""); } _thePromise.toString = _toString; (function _initialize() { if (!tsUtils.isFunction(executor)) { tsUtils.throwTypeError(STR_PROMISE + ": executor is not a function - " + dumpFnObj(executor)); } var _rejectFn = _createSettleIfFn(3 , 0 ); try { executor.call(_thePromise, _createSettleIfFn(2 , 0 ), _rejectFn); } catch (e) { _rejectFn(e); } })(); return _thePromise; } /*#__NO_SIDE_EFFECTS__*/ function _createAllPromise(newPromise) { return function (input) { var additionalArgs = tsUtils.arrSlice(arguments, 1); return newPromise(function (resolve, reject) { try { var values_1 = []; var pending_1 = 1; tsUtils.iterForOf(input, function (item, idx) { if (item) { pending_1++; doAwait(item, function (value) { values_1[idx] = value; if (--pending_1 === 0) { resolve(values_1); } }, reject); } }); pending_1--; if (pending_1 === 0) { resolve(values_1); } } catch (e) { reject(e); } }, additionalArgs); }; } /*#__NO_SIDE_EFFECTS__*/ function _createResolvedPromise(newPromise) { return function (value) { var additionalArgs = tsUtils.arrSlice(arguments, 1); if (tsUtils.isPromiseLike(value)) { return value; } return newPromise(function (resolve) { resolve(value); }, additionalArgs); }; } /*#__NO_SIDE_EFFECTS__*/ function _createRejectedPromise(newPromise) { return function (reason) { var additionalArgs = tsUtils.arrSlice(arguments, 1); return newPromise(function (_resolve, reject) { reject(reason); }, additionalArgs); }; } /*#__NO_SIDE_EFFECTS__*/ function _createAllSettledPromise(newPromise) { return tsUtils.createCachedValue(function (input) { var additionalArgs = tsUtils.arrSlice(arguments, 1); return newPromise(function (resolve, reject) { var values = []; var pending = 1; function processItem(item, idx) { pending++; doAwaitResponse(item, function (value) { if (value.rejected) { values[idx] = { status: REJECTED, reason: value.reason }; } else { values[idx] = { status: "fulfilled", value: value.value }; } if (--pending === 0) { resolve(values); } }); } try { if (tsUtils.isArray(input)) { tsUtils.arrForEach(input, processItem); } else if (tsUtils.isIterable(input)) { tsUtils.iterForOf(input, processItem); } else { tsUtils.throwTypeError("Input is not an iterable"); } pending--; if (pending === 0) { resolve(values); } } catch (e) { reject(e); } }, additionalArgs); }); } /*#__NO_SIDE_EFFECTS__*/ function _createRacePromise(newPromise) { return tsUtils.createCachedValue(function (input) { var additionalArgs = tsUtils.arrSlice(arguments, 1); return newPromise(function (resolve, reject) { var isDone = false; function processItem(item) { doAwaitResponse(item, function (value) { if (!isDone) { isDone = true; if (value.rejected) { reject(value.reason); } else { resolve(value.value); } } }); } try { if (tsUtils.isArray(input)) { tsUtils.arrForEach(input, processItem); } else if (tsUtils.isIterable(input)) { tsUtils.iterForOf(input, processItem); } else { tsUtils.throwTypeError("Input is not an iterable"); } } catch (e) { reject(e); } }, additionalArgs); }); } /*#__NO_SIDE_EFFECTS__*/ function _createAnyPromise(newPromise) { return tsUtils.createCachedValue(function (input) { var additionalArgs = tsUtils.arrSlice(arguments, 1); return newPromise(function (resolve, reject) { var theErros = []; var pending = 1; var isDone = false; function processItem(item, idx) { pending++; doAwaitResponse(item, function (value) { if (!value.rejected) { isDone = true; resolve(value.value); return; } else { theErros[idx] = value.reason; } if (--pending === 0 && !isDone) { reject(_createAggregationError(theErros)); } }); } try { if (tsUtils.isArray(input)) { tsUtils.arrForEach(input, processItem); } else if (tsUtils.isIterable(input)) { tsUtils.iterForOf(input, processItem); } else { tsUtils.throwTypeError("Input is not an iterable"); } pending--; if (pending === 0 && !isDone) { reject(_createAggregationError(theErros)); } } catch (e) { reject(e); } }, additionalArgs); }); } function syncItemProcessor(pending) { tsUtils.arrForEach(pending, function (fn) { try { fn(); } catch (e) { } }); } function timeoutItemProcessor(timeout) { var callbackTimeout = tsUtils.isNumber(timeout) ? timeout : 0; return function (pending) { tsUtils.scheduleTimeout(function () { syncItemProcessor(pending); }, callbackTimeout); }; } function idleItemProcessor(timeout) { var options; if (timeout >= 0) { options = { timeout: +timeout }; } return function (pending) { tsUtils.scheduleIdleCallback(function (deadline) { syncItemProcessor(pending); }, options); }; } var _allAsyncSettledCreator; var _raceAsyncCreator; var _anyAsyncCreator; function createAsyncPromise(executor, timeout) { return _createPromise(createAsyncPromise, timeoutItemProcessor(timeout), executor, timeout); } var createAsyncAllPromise = /*#__PURE__*/ _createAllPromise(createAsyncPromise); var createAsyncResolvedPromise = /*#__PURE__*/ _createResolvedPromise(createAsyncPromise); var createAsyncRejectedPromise = /*#__PURE__*/ _createRejectedPromise(createAsyncPromise); function createAsyncAllSettledPromise(input, timeout) { !_allAsyncSettledCreator && (_allAsyncSettledCreator = _createAllSettledPromise(createAsyncPromise)); return _allAsyncSettledCreator.v(input, timeout); } function createAsyncRacePromise(values, timeout) { !_raceAsyncCreator && (_raceAsyncCreator = _createRacePromise(createAsyncPromise)); return _raceAsyncCreator.v(values, timeout); } function createAsyncAnyPromise(values, timeout) { !_anyAsyncCreator && (_anyAsyncCreator = _createAnyPromise(createAsyncPromise)); return _anyAsyncCreator.v(values, timeout); } var _promiseCls; var _allCreator; var _allNativeSettledCreator; var _raceNativeCreator; var _anyNativeCreator; /*#__NO_SIDE_EFFECTS__*/ function _createNativePromiseHelper(name, func) { !_promiseCls && (_promiseCls = tsUtils.createCachedValue((tsUtils.safe(tsUtils.getInst, [STR_PROMISE]).v) || null)); if (_promiseCls.v && _promiseCls.v[name]) { return tsUtils.createCachedValue(function (input, timeout) { return createNativePromise(function (resolve, reject) { _promiseCls.v[name](input).then(resolve, reject); }); }); } return func(); } function createNativePromise(executor, timeout) { !_promiseCls && (_promiseCls = tsUtils.createCachedValue((tsUtils.safe(tsUtils.getInst, [STR_PROMISE]).v) || null)); var PrmCls = _promiseCls.v; if (!PrmCls) { return createAsyncPromise(executor); } if (!tsUtils.isFunction(executor)) { tsUtils.throwTypeError(STR_PROMISE + ": executor is not a function - " + tsUtils.dumpObj(executor)); } var _state = 0 ; function _strState() { return STRING_STATES[_state]; } var thePromise = new PrmCls(function (resolve, reject) { function _resolve(value) { _state = 2 ; resolve(value); } function _reject(reason) { _state = 3 ; reject(reason); } executor(_resolve, _reject); }); tsUtils.objDefineProp(thePromise, "state", { get: _strState }); return thePromise; } function createNativeAllPromise(input, timeout) { !_allCreator && (_allCreator = _createNativePromiseHelper("all", function () { return tsUtils.createCachedValue(_createAllPromise(createNativePromise)); })); return _allCreator.v(input, timeout); } var createNativeResolvedPromise = /*#__PURE__*/ _createResolvedPromise(createNativePromise); var createNativeRejectedPromise = /*#__PURE__*/ _createRejectedPromise(createNativePromise); function createNativeAllSettledPromise(input, timeout) { !_allNativeSettledCreator && (_allNativeSettledCreator = _createNativePromiseHelper("allSettled", function () { return _createAllSettledPromise(createNativePromise); })); return _allNativeSettledCreator.v(input, timeout); } function createNativeRacePromise(values, timeout) { !_raceNativeCreator && (_raceNativeCreator = _createNativePromiseHelper("race", function () { return _createRacePromise(createNativePromise); })); return _raceNativeCreator.v(values, timeout); } function createNativeAnyPromise(values, timeout) { !_anyNativeCreator && (_anyNativeCreator = _createNativePromiseHelper("any", function () { return _createAnyPromise(createNativePromise); })); return _anyNativeCreator.v(values, timeout); } var _allSyncSettledCreator; var _raceSyncCreator; var _anySyncCreator; function createSyncPromise(executor) { return _createPromise(createSyncPromise, syncItemProcessor, executor); } var createSyncAllPromise = /*#__PURE__*/ _createAllPromise(createSyncPromise); var createSyncResolvedPromise = /*#__PURE__*/ _createResolvedPromise(createSyncPromise); var createSyncRejectedPromise = /*#__PURE__*/ _createRejectedPromise(createSyncPromise); function createSyncAllSettledPromise(input, timeout) { !_allSyncSettledCreator && (_allSyncSettledCreator = _createAllSettledPromise(createSyncPromise)); return _allSyncSettledCreator.v(input, timeout); } function createSyncRacePromise(values, timeout) { !_raceSyncCreator && (_raceSyncCreator = _createRacePromise(createSyncPromise)); return _raceSyncCreator.v(values, timeout); } function createSyncAnyPromise(values, timeout) { !_anySyncCreator && (_anySyncCreator = _createAnyPromise(createSyncPromise)); return _anySyncCreator.v(values, timeout); } var _defaultIdleTimeout; var _allIdleSettledCreator; var _raceIdleCreator; var _anyIdleCreator; function setDefaultIdlePromiseTimeout(idleDeadline) { _defaultIdleTimeout = idleDeadline; } var setDefaultIdleTimeout = ( /*#__PURE__*/_pureAssign(setDefaultIdlePromiseTimeout)); function createIdlePromise(executor, timeout) { var theTimeout = tsUtils.isUndefined(timeout) ? _defaultIdleTimeout : timeout; return _createPromise(createIdlePromise, idleItemProcessor(theTimeout), executor, theTimeout); } var createIdleAllPromise = /*#__PURE__*/ _createAllPromise(createIdlePromise); var createIdleResolvedPromise = /*#__PURE__*/ _createResolvedPromise(createIdlePromise); var createIdleRejectedPromise = /*#__PURE__*/ _createRejectedPromise(createIdlePromise); function createIdleAllSettledPromise(input, timeout) { !_allIdleSettledCreator && (_allIdleSettledCreator = _createAllSettledPromise(createIdlePromise)); return _allIdleSettledCreator.v(input, timeout); } function createIdleRacePromise(values, timeout) { !_raceIdleCreator && (_raceIdleCreator = _createRacePromise(createIdlePromise)); return _raceIdleCreator.v(values, timeout); } function createIdleAnyPromise(values, timeout) { !_anyIdleCreator && (_anyIdleCreator = _createAnyPromise(createIdlePromise)); return _anyIdleCreator.v(values, timeout); } var _promiseCreator; var _allSettledCreator; var _raceCreator; var _anyCreator; function setCreatePromiseImpl(creator) { _promiseCreator = creator ? tsUtils.createCachedValue(creator) : null; } function createPromise(executor, timeout) { !_promiseCreator && (_promiseCreator = tsUtils.createCachedValue(createNativePromise)); return _promiseCreator.v.call(this, executor, timeout); } var createAllPromise = /*#__PURE__*/ _createAllPromise(createPromise); var createResolvedPromise = /*#__PURE__*/ _createResolvedPromise(createPromise); var createRejectedPromise = /*#__PURE__*/ _createRejectedPromise(createPromise); function createAllSettledPromise(input, timeout) { !_allSettledCreator && (_allSettledCreator = _createAllSettledPromise(createPromise)); return _allSettledCreator.v(input, timeout); } function createRacePromise(values, timeout) { !_raceCreator && (_raceCreator = _createRacePromise(createPromise)); return _raceCreator.v(values, timeout); } function createAnyPromise(values, timeout) { !_anyCreator && (_anyCreator = _createAnyPromise(createPromise)); return _anyCreator.v(values, timeout); } function createTimeoutPromise(timeout, resolveReject, message) { return createPromise(function (resolve, reject) { tsUtils.scheduleTimeout(function () { (resolveReject ? resolve : reject)(!tsUtils.isUndefined(message) ? message : "Timeout of " + timeout + "ms exceeded"); }, timeout); }); } function _doneChk(isDone, state, value, thisArg) { var result = isDone; state.res = value; if (!result) { if (state.isDone && tsUtils.isFunction(state.isDone)) { return doAwait(state.isDone.call(thisArg, state), function (done) { state.iter++; return !!done; }); } else { result = !!state.isDone; } } state.iter++; return result; } function doWhileAsync(callbackFn, isDoneFn, thisArg) { var promise; var resolve; var reject = function (reason) { isDone = true; throw reason; }; var isDone = false; var state = { st: tsUtils.utcNow(), iter: 0, isDone: isDoneFn || false }; if (callbackFn) { var _createPromise_1 = function () { return createPromise(function (res, rej) { resolve = res; reject = rej; }); }; var _handleAsyncDone_1 = function (done) { isDone = !!done; if (!isDone) { _processNext_1(); } else { resolve(state.res); } }; var _processNext_1 = function () { while (!isDone) { try { var cbResult = callbackFn.call(thisArg, state); if (tsUtils.isPromiseLike(cbResult)) { promise = promise || _createPromise_1(); doAwait(cbResult, function (res) { try { doAwait(_doneChk(isDone, state, res, thisArg), _handleAsyncDone_1, reject); } catch (e) { reject(e); } }, reject); return promise; } else { var dnRes = _doneChk(isDone, state, cbResult, thisArg); if (tsUtils.isPromiseLike(dnRes)) { promise = promise || _createPromise_1(); doAwait(dnRes, _handleAsyncDone_1, reject); return promise; } else { isDone = !!dnRes; } } } catch (e) { reject(e); return promise; } } if (isDone && resolve) { resolve(state.res); } return promise || state.res; }; return _processNext_1(); } } function arrForEachAsync(theArray, callbackFn, thisArg) { if (theArray) { var len_1 = tsUtils.getLength(theArray); if (len_1) { var isDone = function (state) { if (state.iter >= len_1 || state.res === -1) { return true; } }; return doWhileAsync(function (state) { var idx = state.iter; if (idx in theArray) { return callbackFn.call(thisArg || theArray, theArray[idx], idx, theArray); } }, isDone); } } } var _iterSymbol; var _iterAsyncSymbol; function iterForOfAsync(iter, callbackFn, thisArg) { var err; var iterResult; var theIter = iter; function onFailed(failed) { err = { e: failed }; if (theIter.throw) { iterResult = null; theIter.throw(err); } throw failed; } function onFinally() { try { if (iterResult && !iterResult[DONE]) { theIter[RETURN] && theIter[RETURN](iterResult); } } finally { if (err) { throw err.e; } } } if (iter) { if (!tsUtils.isIterator(iter)) { !_iterAsyncSymbol && (_iterAsyncSymbol = tsUtils.createCachedValue(tsUtils.getKnownSymbol(0 ))); theIter = iter[_iterAsyncSymbol.v] ? iter[_iterAsyncSymbol.v]() : null; if (!theIter) { !_iterSymbol && (_iterSymbol = tsUtils.createCachedValue(tsUtils.getKnownSymbol(3 ))); theIter = iter[_iterSymbol.v] ? iter[_iterSymbol.v]() : null; } } if (theIter && tsUtils.isIterator(theIter)) { var result = void 0; try { result = doWhileAsync(function (state) { return doAwait(theIter.next(), function (res) { iterResult = res; if (!res[DONE]) { return tsUtils.fnCall(callbackFn, thisArg || theIter, iterResult[VALUE], state.iter, theIter); } }, function (reason) { state.isDone = true; onFailed(reason); }); }, function (state) { if (!iterResult || iterResult[DONE] || state.res === -1) { onFinally(); return true; } }, thisArg || theIter); if (tsUtils.isPromiseLike(result)) { result = doFinally(result.catch(onFailed), onFinally); } return result; } catch (failed) { onFailed(failed); } finally { if (result && !tsUtils.isPromiseLike(result)) { onFinally(); } } } } } var REJECT = "reject"; var REJECTED_ERROR = "Rejected"; var _schedulerId = 0; var _debugName; var _debugIntState; var _customErrors = {}; function _rejectDone() { } function _createError(type, evt, message) { !_customErrors[type] && (_customErrors[type] = tsUtils.createCustomError(type)); var now = tsUtils.utcNow(); return new (_customErrors[type])("Task [".concat(evt.id, "] ").concat(message || "", "- ").concat((evt.st ? "Running" : "Waiting"), ": ").concat(_calcTime(now, evt.st || evt.cr))); } function _calcTime(now, start) { return ((now - start) || "0") + " ms"; } function _abortStaleTasks(taskQueue, staleTimeoutPeriod) { var now = tsUtils.utcNow(); var expired = now - staleTimeoutPeriod; tsUtils.arrForEach(taskQueue, function (evt) { if (evt && !evt.rj && (evt.st && evt.st < expired) || (!evt.st && evt.cr && evt.cr < expired)) { evt && evt[REJECT](evt.rj || _createError("Aborted", evt, "Stale ")); } }); } function _removeTask(queue, taskDetail) { var idx = tsUtils.arrIndexOf(queue, taskDetail); if (idx !== -1) { queue.splice(idx, 1); } } function _addDebugState(theScheduler, nameFn, stateFn) { _debugName = _debugName || { toString: function () { return "[[SchedulerName]]"; } }; _debugIntState = _debugIntState || { toString: function () { return "[[SchedulerState]]"; } }; tsUtils.objDefineProp(theScheduler, _debugName, { get: nameFn }); tsUtils.objDefineProp(theScheduler, _debugIntState, { get: stateFn }); } function createTaskScheduler(newPromise, name) { var _theTask; var _running = []; var _waiting = []; var _staleTimeoutPeriod = 600000; var _staleTimeoutCheckPeriod = _staleTimeoutPeriod / 10; var _taskCount = 0; var _schedulerName = (name ? (name + ".") : "") + _schedulerId++; var _blockedTimer; newPromise = newPromise || createPromise; var _startBlockedTimer = function () { var hasTasks = (tsUtils.getLength(_running) + tsUtils.getLength(_waiting)) > 0; if (_staleTimeoutPeriod > 0) { if (!_blockedTimer) { _blockedTimer = tsUtils.scheduleTimeout(function () { _abortStaleTasks(_running, _staleTimeoutPeriod); _abortStaleTasks(_waiting, _staleTimeoutPeriod); _blockedTimer && (_blockedTimer.enabled = ((tsUtils.getLength(_running) + tsUtils.getLength(_waiting)) > 0)); }, _staleTimeoutCheckPeriod); _blockedTimer.unref(); } _blockedTimer && (_blockedTimer.enabled = hasTasks); } }; var _queueTask = function (startAction, taskName, timeout) { var _a; var taskId = _schedulerName + "." + _taskCount++; if (taskName) { taskId += "-(" + taskName + ")"; } var newTask = (_a = { id: taskId, cr: tsUtils.utcNow(), to: timeout }, _a[REJECT] = function (reason) { newTask.rj = reason || _createError(REJECTED_ERROR, newTask); newTask[REJECT] = _rejectDone; }, _a); if (!_theTask) { newTask.p = newPromise(_runTask(newTask, startAction)); } else { newTask.p = _waitForPreviousTask(newTask, _theTask, startAction); } _theTask = newTask; return newTask.p; }; var _runTask = function (taskDetail, startAction) { taskDetail.st = tsUtils.utcNow(); _running.push(taskDetail); _startBlockedTimer(); return function (onTaskResolve, onTaskReject) { var _promiseReject = function (reason) { taskDetail.rj = taskDetail.rj || reason || _createError(REJECTED_ERROR, taskDetail); taskDetail[REJECT] = _rejectDone; _doCleanup(taskDetail); onTaskResolve = null; onTaskReject && onTaskReject(reason); onTaskReject = null; }; var taskId = taskDetail.id; if (taskDetail.rj) { _promiseReject(taskDetail.rj); } else { taskDetail[REJECT] = _promiseReject; try { var startResult = startAction(taskId); if (taskDetail.to && tsUtils.isPromiseLike(startResult)) { taskDetail.t = tsUtils.scheduleTimeout(function () { _promiseReject(_createError("Timeout", taskDetail)); }, taskDetail.to); } doAwait(startResult, function (theResult) { _doCleanup(taskDetail); try { onTaskResolve && onTaskResolve(theResult); } catch (e) { onTaskReject && onTaskReject(e); } onTaskReject = null; onTaskResolve = null; }, _promiseReject); } catch (e) { _promiseReject(e); } } }; }; var _waitForPreviousTask = function (taskDetail, prevTask, startAction) { _waiting.push(taskDetail); _startBlockedTimer(); return newPromise(function (onWaitResolve, onWaitReject) { doAwaitResponse(prevTask.p, function () { _removeTask(_waiting, taskDetail); _runTask(taskDetail, startAction)(onWaitResolve, onWaitReject); }); }); }; var _doCleanup = function (taskDetail) { _removeTask(_running, taskDetail); taskDetail.t && taskDetail.t.cancel(); taskDetail.t = null; if (_theTask && _theTask === taskDetail) { _theTask = null; if (tsUtils.getLength(_running) + tsUtils.getLength(_waiting) === 0) { _blockedTimer && _blockedTimer.cancel(); _blockedTimer = null; } } }; var theScheduler = { idle: true, queue: _queueTask, setStaleTimeout: function (staleTimeout, staleCheckPeriod) { _blockedTimer && _blockedTimer.cancel(); _blockedTimer = null; _staleTimeoutPeriod = staleTimeout; _staleTimeoutCheckPeriod = staleCheckPeriod || staleTimeout / 10; _startBlockedTimer(); } }; tsUtils.objDefine(theScheduler, "idle", { g: function () { return tsUtils.getLength(_running) + tsUtils.getLength(_waiting) === 0; } }); _addDebugState(theScheduler, function () { return _schedulerName; }, function () { return { l: _theTask, r: _running, w: _waiting }; }); return theScheduler; } var toStringTagSymbol = tsUtils.getKnownSymbol(11 ); var PolyPromise = /*#__PURE__*/ (function () { function PolyPromiseImpl(executor) { this._$ = createAsyncPromise(executor); if (toStringTagSymbol) { this[toStringTagSymbol] = "Promise"; } tsUtils.objDefineProp(this, "state", { get: function () { return this._$.state; } }); } PolyPromiseImpl.all = createAsyncAllPromise; PolyPromiseImpl.race = createAsyncRacePromise; PolyPromiseImpl.any = createAsyncAnyPromise; PolyPromiseImpl.reject = createAsyncRejectedPromise; PolyPromiseImpl.resolve = createAsyncResolvedPromise; PolyPromiseImpl.allSettled = createAsyncAllSettledPromise; var theProto = PolyPromiseImpl.prototype; theProto.then = function (onResolved, onRejected) { return this._$.then(onResolved, onRejected); }; theProto.catch = function (onRejected) { return this._$.catch(onRejected); }; theProto.finally = function (onfinally) { return this._$.finally(onfinally); }; return PolyPromiseImpl; }()); exports.PolyPromise = PolyPromise; exports.arrForEachAsync = arrForEachAsync; exports.createAllPromise = createAllPromise; exports.createAllSettledPromise = createAllSettledPromise; exports.createAnyPromise = createAnyPromise; exports.createAsyncAllPromise = createAsyncAllPromise; exports.createAsyncAllSettledPromise = createAsyncAllSettledPromise; exports.createAsyncAnyPromise = createAsyncAnyPromise; exports.createAsyncPromise = createAsyncPromise; exports.createAsyncRacePromise = createAsyncRacePromise; exports.createAsyncRejectedPromise = createAsyncRejectedPromise; exports.createAsyncResolvedPromise = createAsyncResolvedPromise; exports.createIdleAllPromise = createIdleAllPromise; exports.createIdleAllSettledPromise = createIdleAllSettledPromise; exports.createIdleAnyPromise = createIdleAnyPromise; exports.createIdlePromise = createIdlePromise; exports.createIdleRacePromise = createIdleRacePromise; exports.createIdleRejectedPromise = createIdleRejectedPromise; exports.createIdleResolvedPromise = createIdleResolvedPromise; exports.createNativeAllPromise = createNativeAllPromise; exports.createNativeAllSettledPromise = createNativeAllSettledPromise; exports.createNativeAnyPromise = createNativeAnyPromise; exports.createNativePromise = createNativePromise; exports.createNativeRacePromise = createNativeRacePromise; exports.createNativeRejectedPromise = createNativeRejectedPromise; exports.createNativeResolvedPromise = createNativeResolvedPromise; exports.createPromise = createPromise; exports.createRacePromise = createRacePromise; exports.createRejectedPromise = createRejectedPromise; exports.createResolvedPromise = createResolvedPromise; exports.createSyncAllPromise = createSyncAllPromise; exports.createSyncAllSettledPromise = createSyncAllSettledPromise; exports.createSyncAnyPromise = createSyncAnyPromise; exports.createSyncPromise = createSyncPromise; exports.createSyncRacePromise = createSyncRacePromise; exports.createSyncRejectedPromise = createSyncRejectedPromise; exports.createSyncResolvedPromise = createSyncResolvedPromise; exports.createTaskScheduler = createTaskScheduler; exports.createTimeoutPromise = createTimeoutPromise; exports.doAwait = doAwait; exports.doAwaitResponse = doAwaitResponse; exports.doFinally = doFinally; exports.doWhileAsync = doWhileAsync; exports.iterForOfAsync = iterForOfAsync; exports.setCreatePromiseImpl = setCreatePromiseImpl; exports.setDefaultIdlePromiseTimeout = setDefaultIdlePromiseTimeout; exports.setDefaultIdleTimeout = setDefaultIdleTimeout; exports.setPromiseDebugState = setPromiseDebugState; })); //# sourceMappingURL=ts-async.js.map