UNPKG

async-wrappers

Version:

A set of wrapper functions to perform debouncing, throttling, retrying etc.

122 lines (100 loc) 2.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _pending = _interopRequireDefault(require("./pending")); var _callReducers = require("./callReducers"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * @internal */ /** * @internal */ const wrap = (fn, before, after) => { let wrapped = fn; if (before && after) { wrapped = (...args) => { before(); const result = fn(...args); after(); return result; }; } else if (before) { wrapped = (...args) => { before(); const result = fn(...args); return result; }; } else if (after) { wrapped = (...args) => { const result = fn(...args); after(); return result; }; } return wrapped; }; /** * @internal */ const getRunner = (fn, args, result) => () => { try { result.complete(fn(...args)); } catch (e) { result.error(e); } }; /** * @internal */ // eslint-disable-next-line @typescript-eslint/no-empty-function const empty = () => {}; /** * @internal * * Utility function that wraps a function and will use a reducer to combine the arguments * of multiple calls to that function. As the function is not executed until it is invoked * a promise for the result is returned to the callers. * * @param fn The function to wrap. * @param {?argumentsReducer} callReducer Used to determine the arguments when `fn` is invoked. * This will be called every time the wrapped function is called. * If not supplied the default implementation of only using the latest arguments will be used. * @param onBeforeReduce If supplied this function will be called before the reducer is called. * @param onAfterReduce If supplied this function will be called if the wrapped function is cancelled. * @returns */ const callReduce = (fn, callReducer, onBeforeReduce, onAfterReduce) => { const reducer = typeof callReducer === 'function' ? callReducer : _callReducers.latestArguments; let result = null; let args = []; const reject = reason => { if (result !== null) { result.error(reason ? reason : new Error('reset')); result = null; args = []; } }; // capture the invocation state const prepare = () => { if (result === null) { // sanity check no result pending return empty; } const run = getRunner(fn, args, result); result = null; args = []; return run; }; const call = wrap((...callArgs) => { args = reducer(args, callArgs); if (result === null) { result = (0, _pending.default)(); } return result.promise; }, onBeforeReduce, onAfterReduce); return [call, prepare, reject]; }; var _default = callReduce; exports.default = _default;