UNPKG

@tacky/store

Version:

State management framework based on react

141 lines (116 loc) 3.78 kB
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; import { EMaterialType } from '../interfaces'; import { invariant } from '../utils/error'; import { historyCollector } from './collector'; import { nextTick, deduplicate, includes } from '../utils/common'; import * as ReactDOM from 'react-dom'; import { ctx } from '../const/config'; import { materialCallStack } from './domain'; export var store; export function createStore(enhancer) { if (enhancer !== void 0) { store = enhancer(createStore); return store; } var componentUUIDToListeners = new WeakMap(); var isUpdating = false; function subscribe(listener, uuid) { var isSubscribed = true; var listeners = componentUUIDToListeners.get(uuid); if (listeners === void 0) { componentUUIDToListeners.set(uuid, [listener]); } else { if (!includes(listeners, listener)) { componentUUIDToListeners.set(uuid, listeners.concat(listener)); } } return function unsubscribe() { if (!isSubscribed) { return; } isSubscribed = false; if (componentUUIDToListeners.has(uuid)) { componentUUIDToListeners["delete"](uuid); } }; } var isInBatch = false; var dirtyJob; var needCreateRestSyncJobTrigger = true; function dispatch(action) { var name = action.name, payload = action.payload, type = action.type, domain = action.domain, original = action.original, isAtom = action.isAtom, _action$isInner = action.isInner, isInner = _action$isInner === void 0 ? false : _action$isInner; invariant(!isUpdating, 'Cannot trigger other mutation while the current mutation is executing.'); var callback = function callback() { if (historyCollector.waitTriggerComponentIds.length > 0) { var ids = deduplicate(historyCollector.waitTriggerComponentIds); var pendingListeners = []; for (var index = 0; index < ids.length; index++) { var cid = ids[index]; var listeners = componentUUIDToListeners.get(cid) || []; pendingListeners.push.apply(pendingListeners, _toConsumableArray(listeners)); } ReactDOM.unstable_batchedUpdates(function () { for (var _index = 0; _index < pendingListeners.length; _index++) { var listener = pendingListeners[_index]; listener(); } }); } isInBatch = false; dirtyJob = void 0; if (ctx.timeTravel.isActive && includes(materialCallStack, EMaterialType.EFFECT)) { historyCollector.endBatch(false); return; } if (ctx.timeTravel.isActive && !isInner) { historyCollector.save(); } historyCollector.endBatch(); }; if (!isInBatch && dirtyJob === void 0) { dirtyJob = callback; } if (isAtom) { if (historyCollector.waitTriggerComponentIds.length > 0) { // flush previous job dirtyJob && dirtyJob(); } } try { isUpdating = true; if (!isInner && type !== EMaterialType.MUTATION && type !== EMaterialType.UPDATE) { return; } var currentMutation = original; currentMutation.apply(void 0, _toConsumableArray(payload)); } finally { isUpdating = false; } if (!isInBatch) { isInBatch = true; if (isAtom) { // immediately execute callback(); } if (needCreateRestSyncJobTrigger) { nextTick(function () { dirtyJob && dirtyJob(); needCreateRestSyncJobTrigger = true; }); needCreateRestSyncJobTrigger = false; } } return action; } return { dispatch: dispatch, subscribe: subscribe }; }