@tacky/store
Version:
State management framework based on react
141 lines (116 loc) • 3.78 kB
JavaScript
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
};
}