UNPKG

overmind

Version:
245 lines • 11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createMutationOperator = exports.createOperator = exports.createNextPath = exports.createContext = exports.operatorStopped = exports.operatorStarted = exports.action = void 0; const internalTypes_1 = require("./internalTypes"); const utils_1 = require("./utils"); function action(operation) { return createMutationOperator('action', (0, utils_1.getFunctionName)(operation), (err, context, value, next) => { if (err) next(err, value); else { const result = operation(context, value); if ((0, utils_1.isPromise)(result)) { next(null, result.then((resolvedValue) => resolvedValue)); } else { next(null, result); } } }); } exports.action = action; function operatorStarted(type, arg, context) { if (process.env.NODE_ENV === 'production') { return; } const name = typeof arg === 'function' ? arg.displayName || arg.name : String(arg); context.execution.isRunning = true; context.execution.emit(internalTypes_1.EventType.OPERATOR_START, Object.assign(Object.assign({}, context.execution), { name, type })); } exports.operatorStarted = operatorStarted; function operatorStopped(context, value, details = {}) { if (process.env.NODE_ENV === 'production') { if (value instanceof Promise) { context.execution.emit(internalTypes_1.EventType.OPERATOR_ASYNC, Object.assign(Object.assign({}, context.execution), { isAsync: true })); } return; } const evaluatedDetails = { error: details.error ? details.error.message : undefined, isIntercepted: Boolean(details.isIntercepted), isSkipped: Boolean(details.isSkipped), }; if (value instanceof Promise) { value .then((promiseValue) => { context.execution.isRunning = false; context.execution.emit(internalTypes_1.EventType.OPERATOR_END, Object.assign(Object.assign(Object.assign({}, context.execution), { result: promiseValue, isAsync: true }), evaluatedDetails)); }) .catch(() => { // Make sure an error does not cause uncaught }); } else { context.execution.isRunning = false; context.execution.emit(internalTypes_1.EventType.OPERATOR_END, Object.assign(Object.assign(Object.assign({}, context.execution), { result: value, isAsync: false }), evaluatedDetails)); } } exports.operatorStopped = operatorStopped; function createContext(context, value, path) { if (process.env.NODE_ENV === 'production') { return Object.assign(Object.assign({}, context), { value }); } const newExecution = Object.assign(Object.assign({}, context.execution), { operatorId: context.execution.getNextOperatorId(), path: path || context.execution.path }); const mutationTrees = []; return Object.assign(Object.assign({}, context), { actions: (0, utils_1.createActionsProxy)(context.actions[utils_1.ORIGINAL_ACTIONS] || context.actions, (action) => { return (value) => action(value, newExecution.isRunning ? newExecution : null); }), value, execution: newExecution, effects: context.execution.trackEffects(newExecution), flush: context.parentExecution ? context.parentExecution.flush : (isAsync) => { return this.proxyStateTree.flush(mutationTrees, isAsync); }, getMutationTree: context.parentExecution ? context.parentExecution.getMutationTree : () => { const mutationTree = this.proxyStateTree.getMutationTree(); mutationTrees.push(mutationTree); if (this.mode.mode === utils_1.MODE_TEST) { mutationTree.onMutation((mutation) => { this.addExecutionMutation(mutation); }); } return mutationTree; } }); } exports.createContext = createContext; function createNextPath(next) { if (process.env.NODE_ENV === 'production') { return next; } return (err, context) => { const newContext = Object.assign(Object.assign({}, context), { execution: Object.assign(Object.assign({}, context.execution), { path: context.execution.path.slice(0, context.execution.path.length - 1) }) }); if (err) next(err, newContext); else next(null, newContext); }; } exports.createNextPath = createNextPath; function createOperator(type, name, cb) { const operator = (err, context, next, final) => { operatorStarted(type, name, context); let nextIsCalled = false; try { cb(err, { state: context.state, effects: context.effects, actions: context.actions, execution: context.execution, addFlushListener: context.addFlushListener, addMutationListener: context.addMutationListener, reaction: context.reaction, }, context.value, (err, value, options = {}) => { function run(err, value) { if (options.path) { const newContext = createContext(context, value, context.execution.path && context.execution.path.concat(options.path.name)); const nextWithPath = createNextPath(next); const operatorToRun = options.path.operator[utils_1.IS_OPERATOR] ? options.path.operator : action(options.path.operator); operatorToRun(err, newContext, (...args) => { operatorStopped(context, args[1].value); nextWithPath(...args); }); } else { operatorStopped(context, err || value, { isSkipped: err ? true : options.isSkipped, }); next(err, createContext(context, value)); } } if (value && value instanceof Promise) { value .then((promiseValue) => run(err, promiseValue)) .catch((promiseError) => run(promiseError, promiseError)); } else { nextIsCalled = true; run(err, value); } }, (err, value) => { nextIsCalled = true; operatorStopped(context, err || value, { isSkipped: Boolean(err), isIntercepted: !err, }); final(err, createContext(context, value)); }); } catch (error) { nextIsCalled = true; operatorStopped(context, context.value, { error, }); next(error, createContext(context, context.value)); } if (!nextIsCalled) { context.execution.emit(internalTypes_1.EventType.OPERATOR_ASYNC, Object.assign(Object.assign({}, context.execution), { isAsync: true })); } }; operator[utils_1.IS_OPERATOR] = true; return operator; } exports.createOperator = createOperator; function createMutationOperator(type, name, cb) { const operator = (err, context, next, final) => { operatorStarted(type, name, context); const mutationTree = context.execution.getMutationTree(); if (!(process.env.NODE_ENV === 'production')) { mutationTree.onMutation((mutation) => { context.execution.emit(internalTypes_1.EventType.MUTATIONS, Object.assign(Object.assign({}, context.execution), { mutations: [mutation] })); }); } let nextIsCalled = false; try { cb(err, { state: mutationTree.state, effects: context.effects, actions: context.actions, execution: context.execution, addFlushListener: context.addFlushListener, addMutationListener: context.addMutationListener, reaction: context.reaction, }, process.env.NODE_ENV === 'production' ? context.value : context.execution.scopeValue(context.value, mutationTree), (err, value, options = {}) => { function run(err, value) { operatorStopped(context, err || value, { isSkipped: err ? true : options.isSkipped, }); mutationTree.dispose(); next(err, createContext(context, value)); } if (value && value instanceof Promise) { value .then((promiseValue) => run(err, promiseValue)) .catch((promiseError) => run(promiseError, promiseError)); } else { nextIsCalled = true; run(err, value); } }, (err, value) => { nextIsCalled = true; operatorStopped(context, err || value, { isSkipped: Boolean(err), isIntercepted: !err, }); final(err, createContext(context, value)); }); if (!(process.env.NODE_ENV === 'production')) { let pendingFlush; mutationTree.onMutation(() => { if (pendingFlush) { clearTimeout(pendingFlush); } pendingFlush = setTimeout(() => { const flushData = context.execution.flush(true); if (flushData.mutations.length) { context.execution.send({ type: 'flush', data: Object.assign(Object.assign(Object.assign({}, context.execution), flushData), { mutations: flushData.mutations }), }); } }); }); } } catch (error) { nextIsCalled = true; operatorStopped(context, context.value, { error, }); next(error, createContext(context, context.value)); } if (!nextIsCalled) { context.execution.emit(internalTypes_1.EventType.OPERATOR_ASYNC, Object.assign(Object.assign({}, context.execution), { isAsync: true })); } }; operator[utils_1.IS_OPERATOR] = true; return operator; } exports.createMutationOperator = createMutationOperator; //# sourceMappingURL=operator.js.map