UNPKG

@formily/reactive

Version:

> Web Reactive Library Like Mobx

131 lines 4.07 kB
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