@turbox3d/reactivity
Version:
Large-scale reactive state management library
313 lines (312 loc) • 11.2 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.triggerCollector = exports.depCollector = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _shared = require("@turbox3d/shared");
var _config = require("../const/config");
var _timeTravel = require("./time-travel");
var _store = require("./store");
var _enums = require("../const/enums");
var _action = require("./action");
var _domain = require("./domain");
var _common = require("../utils/common");
var _event = require("../utils/event");
var _materialCallStack = require("../utils/materialCallStack");
var isInBlackList = function isInBlackList(propKey) {
var blackList = {
constructor: true,
$$turboxProperties: true,
context: true,
currentTarget: true,
originalArrayLength: true,
reactorConfigMap: true,
computedProperties: true,
propertyGet: true,
propertySet: true,
proxyDeleteProperty: true,
proxyOwnKeys: true,
proxySet: true,
proxyGet: true,
proxyReactive: true,
$update: true,
illegalAssignmentCheck: true,
dispatch: true
};
return !!blackList[propKey];
};
/**
* collect relation map of the dep key and the reaction ids
*/
var DepCollector = /*#__PURE__*/function () {
function DepCollector() {
(0, _classCallCheck2["default"])(this, DepCollector);
this.dependencyGraph = new Map();
this.reactionIdDeps = new Map();
this.reactionIdStack = [];
}
return (0, _createClass2["default"])(DepCollector, [{
key: "start",
value: function start(id) {
this.reactionIdStack.push(id);
}
}, {
key: "collect",
value: function collect(target, propertyKey) {
if (isInBlackList(propertyKey)) {
return;
}
var stackLength = this.reactionIdStack.length;
if (stackLength === 0) {
return;
}
var currentReactionId = this.reactionIdStack[stackLength - 1];
var depNodeAssembly = this.dependencyGraph.get(target);
if (depNodeAssembly !== void 0) {
var depNode = depNodeAssembly.get(propertyKey);
if (depNode !== void 0) {
depNode.add(currentReactionId);
} else {
depNodeAssembly.set(propertyKey, new Set([currentReactionId]));
}
} else {
var map = new Map([[propertyKey, new Set([currentReactionId])]]);
this.dependencyGraph.set(target, map);
}
var reactionDeps = this.reactionIdDeps.get(currentReactionId);
if (reactionDeps !== void 0) {
var depNodeStatusAssembly = reactionDeps.get(target);
if (depNodeStatusAssembly !== void 0) {
depNodeStatusAssembly.set(propertyKey, _enums.EDepState.LATEST);
} else {
reactionDeps.set(target, new Map([[propertyKey, _enums.EDepState.LATEST]]));
}
} else {
this.reactionIdDeps.set(currentReactionId, new Map([[target, new Map([[propertyKey, _enums.EDepState.LATEST]])]]));
}
}
}, {
key: "end",
value: function end() {
var _this = this;
var currentReactionId = this.reactionIdStack.pop();
if (!currentReactionId) {
return;
}
var map = this.reactionIdDeps.get(currentReactionId);
if (!map) {
return;
}
map.forEach(function (depNode, target) {
depNode.forEach(function (value, key) {
// remove stale deps
if (value === _enums.EDepState.OBSERVED) {
var depNodeAssembly = _this.dependencyGraph.get(target);
if (depNodeAssembly) {
var idSet = depNodeAssembly.get(key);
idSet && idSet["delete"](currentReactionId);
depNode.set(key, _enums.EDepState.NOT_OBSERVED);
}
}
// reset dep status
if (value === _enums.EDepState.LATEST) {
depNode.set(key, _enums.EDepState.OBSERVED);
}
});
});
}
}, {
key: "clear",
value: function clear(id) {
var _this2 = this;
var map = this.reactionIdDeps.get(id);
if (!map) {
return;
}
map.forEach(function (depNode, target) {
depNode.forEach(function (value, key) {
var depNodeAssembly = _this2.dependencyGraph.get(target);
if (depNodeAssembly) {
var idSet = depNodeAssembly.get(key);
idSet && idSet["delete"](id);
}
});
});
this.reactionIdDeps["delete"](id);
}
}, {
key: "isObserved",
value: function isObserved(targetKey, propKey) {
var map = this.dependencyGraph.get(targetKey);
return map !== void 0 && map.has(propKey) && (map.get(propKey) || new Set()).size > 0;
}
}]);
}();
var depCollector = exports.depCollector = new DepCollector();
var TriggerCollector = /*#__PURE__*/function () {
function TriggerCollector() {
(0, _classCallCheck2["default"])(this, TriggerCollector);
this.waitTriggerIds = new Set();
}
return (0, _createClass2["default"])(TriggerCollector, [{
key: "trigger",
value: function trigger(target, key, payload) {
var isNeedRecord = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
var devToolInfo = arguments.length > 4 ? arguments[4] : undefined;
var _a, _b;
var type = payload.type,
beforeUpdate = payload.beforeUpdate,
didUpdate = payload.didUpdate;
if (_config.ctx.devTool && devToolInfo) {
try {
var stringify = (_a = window && window.__TURBOX_DEVTOOL_GOLBAL_STRINGIFY__) !== null && _a !== void 0 ? _a : JSON.stringify;
var event = {
time: Date.now(),
stackId: (_b = _materialCallStack.materialCallStack.currentStack) === null || _b === void 0 ? void 0 : _b.stackId,
domain: devToolInfo.domain,
keyPath: devToolInfo.keyPath,
newValue: stringify(didUpdate),
oldValue: stringify(beforeUpdate),
type: type
};
_event.emitter.emit(_event.EEventName.setProperty, event);
console.log(event);
} catch (e) {
(0, _shared.fail)(e);
}
}
var enhanceKey = type === _enums.ECollectType.ADD ? _enums.ESpecialReservedKey.ITERATE : key;
this.collectComponentId(target, enhanceKey);
if (!_config.ctx.timeTravel.isActive || !_timeTravel.TimeTravel.currentTimeTravel || !isNeedRecord || _timeTravel.TimeTravel.processing || enhanceKey === _enums.ESpecialReservedKey.ITERATE || enhanceKey === _enums.ESpecialReservedKey.COMPUTED) {
return;
}
if (_action.Action.context) {
this.recordDiff(target, enhanceKey, payload, _action.Action.context.historyNode.history);
return;
}
this.recordDiff(target, enhanceKey, payload, _timeTravel.TimeTravel.currentTimeTravel.currentHistory);
}
}, {
key: "endBatch",
value: function endBatch() {
var isClearHistory = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
var action = arguments.length > 1 ? arguments[1] : undefined;
if (!action) {
this.waitTriggerIds.clear();
}
if (!_config.ctx.timeTravel.isActive || !_timeTravel.TimeTravel.currentTimeTravel || !isClearHistory) {
return;
}
if (action) {
action.historyNode.actionChain.length = 0;
action.historyNode.history.clear();
(0, _shared.nextTick)(function () {
var ctt = _timeTravel.TimeTravel.currentTimeTravel;
ctt && ctt.onChange(ctt.undoable, ctt.redoable, 'clear', action);
});
return;
}
_store.actionTypeChain.length = 0;
_timeTravel.TimeTravel.currentTimeTravel.currentHistory.clear();
}
}, {
key: "save",
value: function save(action) {
if (!_config.ctx.timeTravel.isActive || !_timeTravel.TimeTravel.currentTimeTravel || _action.Action.context) {
return;
}
var ctt = _timeTravel.TimeTravel.currentTimeTravel;
if (action) {
this.saveHistory(ctt, action.historyNode.actionChain, action.historyNode.history, action);
return;
}
this.saveHistory(ctt, _store.actionTypeChain, ctt.currentHistory);
}
}, {
key: "collectComponentId",
value: function collectComponentId(target, enhanceKey) {
var _this3 = this;
var depNodeAssembly = depCollector.dependencyGraph.get(target);
if (depNodeAssembly !== void 0) {
var idSet = depNodeAssembly.get(enhanceKey);
if (idSet !== void 0 && idSet.size > 0) {
idSet.forEach(function (id) {
return _this3.waitTriggerIds.add(id);
});
}
}
}
}, {
key: "recordDiff",
value: function recordDiff(target, enhanceKey, payload, history) {
var type = payload.type,
beforeUpdate = payload.beforeUpdate,
didUpdate = payload.didUpdate;
var proxyTarget;
if ((0, _common.isDomain)(target)) {
proxyTarget = target;
} else {
proxyTarget = _domain.rawCache.get(target);
}
if (!proxyTarget) {
return;
}
var keyToDiffChangeMap = history.get(proxyTarget);
if (keyToDiffChangeMap !== void 0) {
var diffInfo = keyToDiffChangeMap.get(enhanceKey);
if (diffInfo !== void 0) {
diffInfo.didUpdate = didUpdate;
} else {
keyToDiffChangeMap.set(enhanceKey, {
type: type,
beforeUpdate: beforeUpdate,
didUpdate: didUpdate
});
}
} else {
history.set(proxyTarget, new Map([[enhanceKey, {
type: type,
beforeUpdate: beforeUpdate,
didUpdate: didUpdate
}]]));
}
}
}, {
key: "saveHistory",
value: function saveHistory(ctt, actionChain, history, action) {
if (!history) {
return;
}
if (history.size === 0) {
return;
}
var clonedChain = _config.ctx.timeTravel.keepActionChain ? actionChain.slice() : [];
var clonedHistory = new Map(history);
if (ctt.cursor === ctt.transactionHistories.length - 1) {
ctt.transactionHistories.push({
actionChain: clonedChain,
history: clonedHistory
});
ctt.cursor += 1;
} else if (ctt.cursor < ctt.transactionHistories.length - 1) {
ctt.transactionHistories = ctt.transactionHistories.slice(0, ctt.cursor + 1);
ctt.transactionHistories.push({
actionChain: clonedChain,
history: clonedHistory
});
ctt.cursor += 1;
}
if (ctt.transactionHistories.length > _config.ctx.timeTravel.maxStepNumber) {
ctt.transactionHistories.shift();
ctt.cursor -= 1;
}
(0, _shared.nextTick)(function () {
ctt.onChange(ctt.undoable, ctt.redoable, 'save', action);
});
}
}]);
}();
var triggerCollector = exports.triggerCollector = new TriggerCollector();