UNPKG

@tacky/store

Version:

State management framework based on react

116 lines (96 loc) 3.8 kB
import _regeneratorRuntime from "@babel/runtime/regenerator"; import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator"; import { ctx } from '../const/config'; import { store } from '../core/store'; import { CURRENT_MATERIAL_TYPE } from '../const/symbol'; import { bind, convert2UniqueString, includes } from '../utils/common'; import { EMaterialType } from '../interfaces'; import { invariant } from '../utils/error'; import { quacksLikeADecorator } from '../utils/decorator'; import { materialCallStack } from '../core/domain'; import { historyCollector } from '../core/collector'; /** * @todo: enhance effect feature, such as takeLead, takeLast */ function createEffect(target, name, original) { var stringMethodName = convert2UniqueString(name); return /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() { var _len, payload, _key, length, _args = arguments; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: this[CURRENT_MATERIAL_TYPE] = EMaterialType.EFFECT; materialCallStack.push(this[CURRENT_MATERIAL_TYPE]); for (_len = _args.length, payload = new Array(_len), _key = 0; _key < _len; _key++) { payload[_key] = _args[_key]; } _context.next = 5; return store.dispatch({ name: stringMethodName, payload: payload, type: EMaterialType.EFFECT, domain: this, original: bind(original, this) }); case 5: materialCallStack.pop(); length = materialCallStack.length; this[CURRENT_MATERIAL_TYPE] = materialCallStack[length - 1] || EMaterialType.DEFAULT; if (ctx.timeTravel.isActive && !includes(materialCallStack, EMaterialType.EFFECT)) { historyCollector.save(); historyCollector.endBatch(); } case 9: case "end": return _context.stop(); } } }, _callee, this); })); } /** * decorator @effect, handle some async process and effect. */ export function effect() { var decorator = function decorator(target, name, descriptor) { invariant(ctx.middleware.effect, 'If you want to use @effect decorator, please turn on the built-in effect middleware. By \"config(...)\".'); // typescript only: @effect method = async () => {} if (descriptor === void 0) { var effectFunc; Object.defineProperty(target, name, { enumerable: true, configurable: true, get: function get() { return effectFunc; }, set: function set(original) { effectFunc = createEffect(target, name, original); } }); return; } // babel/typescript: @effect method() {} if (descriptor.value !== void 0) { var original = descriptor.value; descriptor.value = createEffect(target, name, original); return descriptor; } // babel only: @effect method = () => {} var initializer = descriptor.initializer; descriptor.initializer = function () { invariant(!!initializer, 'The initializer of the descriptor doesn\'t exist, please compile it by using babel and correspond decorator plugin.'); return createEffect(target, name, initializer && initializer.call(this)); }; return descriptor; }; for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } if (quacksLikeADecorator(args)) { // @effect return decorator.apply(null, args); } // @effect(args) return decorator; }