@turbox3d/reactivity
Version:
Large-scale reactive state management library
80 lines • 2.56 kB
JavaScript
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import { generateUUID } from '@turbox3d/shared';
import { depCollector } from './collector';
import { store } from './store';
import { TURBOX_PREFIX } from '../const/symbol';
import { EEventName, emitter } from '../utils/event';
export var Reaction = /*#__PURE__*/function () {
function Reaction(name, runner, computed, lazy, deps, immediately) {
_classCallCheck(this, Reaction);
this.name = name;
this.runner = runner;
this.computed = computed;
this.lazy = lazy;
this.deps = deps;
this.immediately = immediately;
}
return _createClass(Reaction, [{
key: "dispose",
value: function dispose() {
if (this.unsubscribeHandler !== void 0) {
this.unsubscribeHandler();
}
depCollector.clear(this);
}
}]);
}();
export function createReaction(func, options) {
var name = options && options.name || func.name || "".concat(TURBOX_PREFIX, "REACTIVE_").concat(generateUUID());
var lazy = options && options.lazy !== void 0 ? options.lazy : false;
var deps = options && options.deps || [];
var immediately = options && options.immediately !== void 0 ? options.immediately : true;
var firstRun = true;
var reaction = new Reaction(name, function () {
var isInner = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
try {
depCollector.start(reaction);
if (reaction.deps.length > 0) {
var values = [];
reaction.deps.forEach(function (dep) {
var value = dep();
values.push(value);
});
depCollector.end();
!firstRun && func.call.apply(func, [null].concat(values));
} else {
func.call(null);
depCollector.end();
}
if (firstRun) {
firstRun = false;
}
} catch (error) {
depCollector.end();
if (firstRun) {
firstRun = false;
}
if (!isInner) {
throw error;
}
}
}, !!(options && options.computed), lazy, deps, immediately);
var subscribe = function subscribe() {
reaction.unsubscribeHandler = store.subscribe(function (isInner) {
reaction.runner(isInner);
}, reaction);
reaction.runner();
};
if (!store) {
emitter.on(EEventName.storeOnActive, function () {
subscribe();
});
} else {
subscribe();
}
return reaction;
}
export function reactive(func, options) {
return createReaction(func, options);
}