@formily/reactive
Version:
> Web Reactive Library Like Mobx
131 lines • 4.07 kB
JavaScript
import { ObModelSymbol, ReactionStack } from '../environment';
import { createAnnotation } from '../internals';
import { buildDataTree } from '../tree';
import { isFn } from '../checkers';
import { bindTargetKeyWithCurrentReaction, runReactionsFromTargetKey, bindComputedReactions, hasRunningReaction, isUntracking, batchStart, batchEnd, releaseBindingReactions, } from '../reaction';
var getDescriptor = Object.getOwnPropertyDescriptor;
var getProto = Object.getPrototypeOf;
var ClassDescriptorSymbol = Symbol('ClassDescriptorSymbol');
function getPropertyDescriptor(obj, key) {
if (!obj)
return;
return getDescriptor(obj, key) || getPropertyDescriptor(getProto(obj), key);
}
function getPropertyDescriptorCache(obj, key) {
var constructor = obj.constructor;
if (constructor === Object || constructor === Array)
return getPropertyDescriptor(obj, key);
var cache = constructor[ClassDescriptorSymbol] || {};
var descriptor = cache[key];
if (descriptor)
return descriptor;
var newDesc = getPropertyDescriptor(obj, key);
constructor[ClassDescriptorSymbol] = cache;
cache[key] = newDesc;
return newDesc;
}
function getPrototypeDescriptor(target, key, value) {
if (!target) {
if (value) {
if (isFn(value)) {
return { get: value };
}
else {
return value;
}
}
return {};
}
var descriptor = getPropertyDescriptorCache(target, key);
if (descriptor) {
return descriptor;
}
return {};
}
export var computed = createAnnotation(function (_a) {
var target = _a.target, key = _a.key, value = _a.value;
var store = {};
var proxy = {};
var context = target ? target : store;
var property = target ? key : 'value';
var descriptor = getPrototypeDescriptor(target, property, value);
function compute() {
var _a;
store.value = (_a = descriptor.get) === null || _a === void 0 ? void 0 : _a.call(context);
}
function reaction() {
if (ReactionStack.indexOf(reaction) === -1) {
releaseBindingReactions(reaction);
try {
ReactionStack.push(reaction);
compute();
}
finally {
ReactionStack.pop();
}
}
}
reaction._name = 'ComputedReaction';
reaction._scheduler = function () {
reaction._dirty = true;
runReactionsFromTargetKey({
target: context,
key: property,
value: store.value,
type: 'set',
});
};
reaction._isComputed = true;
reaction._dirty = true;
reaction._context = context;
reaction._property = property;
function get() {
if (hasRunningReaction()) {
bindComputedReactions(reaction);
}
if (!isUntracking()) {
//如果允许untracked过程中收集依赖,那么永远不会存在绑定,因为_dirty已经设置为false
if (reaction._dirty) {
reaction();
reaction._dirty = false;
}
}
else {
compute();
}
bindTargetKeyWithCurrentReaction({
target: context,
key: property,
type: 'get',
});
return store.value;
}
function set(value) {
var _a;
try {
batchStart();
(_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call(context, value);
}
finally {
batchEnd();
}
}
if (target) {
Object.defineProperty(target, key, {
get: get,
set: set,
enumerable: true,
});
return target;
}
else {
Object.defineProperty(proxy, 'value', {
set: set,
get: get,
});
buildDataTree(target, key, store);
proxy[ObModelSymbol] = store;
}
return proxy;
});
//# sourceMappingURL=computed.js.map