UNPKG

overmind

Version:
265 lines • 9.28 kB
import { action, createContext, createMutationOperator, createNextPath, createOperator, operatorStarted, operatorStopped, } from './operator'; import * as utils from './utils'; export function pipe(...operators) { const instance = (err, context, next, final = next) => { if (err) next(err, context); else { let operatorIndex = 0; const run = (operatorErr, operatorContext) => { const operator = operators[operatorIndex++]; const operatorToRun = operator ? operator[utils.IS_OPERATOR] ? operator : action(operator) : next; try { operatorToRun(operatorErr, operatorContext, run, final); } catch (operatorError) { operatorToRun(operatorErr, operatorContext, run, final); } }; run(null, context); } }; instance[utils.IS_OPERATOR] = true; return instance; } export function branch(...operators) { const instance = (err, context, next, final = next) => { if (err) next(err, context); else { let operatorIndex = 0; const run = (operatorErr, operatorContext) => { const operator = operators[operatorIndex++]; const operatorToRun = operator ? operator[utils.IS_OPERATOR] ? operator : action(operator) : (err, finalContext, finalNext, finalFinal) => { next(err, { ...finalContext, value: context.value, }, finalNext, finalFinal); }; try { operatorToRun(operatorErr, operatorContext, run, final); } catch (operatorError) { operatorToRun(operatorErr, operatorContext, run, final); } }; run(null, context); } }; instance[utils.IS_OPERATOR] = true; return instance; } export function parallel(...operators) { const instance = (err, context, next) => { if (err) next(err, context); else { let evaluatingCount = operators.length; let lastContext; let hasErrored = false; const results = []; const evaluate = (index, err, newContext) => { if (hasErrored) { return; } if (err) { hasErrored = true; return next(err, lastContext); } results[index] = newContext.value; evaluatingCount--; if (!evaluatingCount) { operatorStopped(context, results); next(null, createContext(lastContext, results, lastContext.execution.path && lastContext.execution.path.slice(0, lastContext.execution.path.length - 1))); } }; operatorStarted('parallel', '', context); operators.forEach((operator, index) => { lastContext = createContext(lastContext || context, context.value, context.execution.path && context.execution.path.concat(String(index))); const nextWithPath = createNextPath(evaluate.bind(undefined, index)); const operatorToRun = operator[utils.IS_OPERATOR] ? operator : action(operator); // @ts-ignore operatorToRun(null, lastContext, nextWithPath); }); } }; instance[utils.IS_OPERATOR] = true; return instance; } export function noop() { return createOperator('noop', '', (err, context, value, next) => { if (err) next(err, value); else next(null, value); }); } export function filter(operation) { return createOperator('filter', utils.getFunctionName(operation), (err, context, value, next, final) => { if (err) next(err, value); else if (operation(context, value)) next(null, value); else final(null, value); }); } export function catchError(operation) { return createMutationOperator('catchError', utils.getFunctionName(operation), (err, context, value, next) => { if (err) next(null, operation(context, err)); else next(null, value, { isSkipped: true, }); }); } export function tryCatch(paths) { const instance = (err, context, next) => { if (err) next(err, context); else { const evaluateCatch = (err, catchContext) => { operatorStopped(context, context.value); next(err, createContext(catchContext, context.value)); }; const evaluateTry = (err, tryContext) => { if (err) { const newContext = createContext(tryContext, err, context.execution.path && context.execution.path.concat('catch')); const nextWithPath = createNextPath(evaluateCatch); const operatorToRun = paths.try[utils.IS_OPERATOR] ? paths.catch : action(paths.catch); // @ts-ignore operatorToRun(null, newContext, nextWithPath); } else { operatorStopped(context, context.value); next(null, createContext(tryContext, context.value)); } }; operatorStarted('tryCatch', '', context); const newContext = createContext(context, context.value, context.execution.path && context.execution.path.concat('try')); const nextWithPath = createNextPath(evaluateTry); const operatorToRun = paths.try[utils.IS_OPERATOR] ? paths.try : action(paths.try); // @ts-ignore operatorToRun(null, newContext, nextWithPath); } }; instance[utils.IS_OPERATOR] = true; return instance; } export function fork(key, paths) { return createOperator('fork', String(key), (err, context, value, next) => { if (err) next(err, value); else { next(null, value, { path: { name: String(key), operator: paths[value[key]], }, }); } }); } export function when(operation, paths) { return createOperator('when', utils.getFunctionName(operation), (err, context, value, next) => { if (err) next(err, value); else if (operation(context, value)) next(null, value, { path: { name: 'true', operator: paths.true, }, }); else next(null, value, { path: { name: 'false', operator: paths.false, }, }); }); } export function wait(ms) { return createOperator('wait', String(ms), (err, context, value, next) => { if (err) next(err, value); else setTimeout(() => next(null, value), ms); }); } export function debounce(ms) { let timeout; let previousFinal; return createOperator('debounce', String(ms), (err, context, value, next, final) => { if (err) next(err, value); else { if (timeout) { clearTimeout(timeout); previousFinal(null, value); } previousFinal = final; timeout = setTimeout(() => { timeout = null; next(null, value); }, ms); } }); } export function throttle(ms) { let timeout; let previousFinal; let currentNext; return createOperator('throttle', String(ms), (err, context, value, next, final) => { if (err) next(err, value); else { if (timeout) { previousFinal(null, value); currentNext = next; } else { timeout = setTimeout(() => { timeout = null; currentNext(null, value); }, ms); } previousFinal = final; currentNext = next; } }); } export function waitUntil(operation) { return createOperator('waitUntil', operation.name, (err, context, value, next) => { if (err) next(err, value); else { const tree = context.execution.getTrackStateTree(); const test = () => { if (operation(tree.state)) { tree.dispose(); next(null, value); } }; tree.trackScope(test, test); } }); } //# sourceMappingURL=operators.js.map