import { computed, observable } from 'mobx'; import { lazyObservable } from 'mobx-utils'; import { decorator_compatibility } from './utils'; const getPrivateStore = (obj: any, key: symbol) => { let store = obj[key]; if (!store) store = obj[key] = {}; return store; } const LAZY_PROPS = Symbol('lazyObservable collection'); /** * A decorator form of mobx-utils' lazyObservable. * May decorate a property, using it's value as the initialValue * @param callback */ export const LazyObservable = (callback: (this: S, sink: (newValue: T) => void, self: S) => void) => decorator_compatibility({ legacy(target, propertyKey, descriptor) { const makeLazyObservable = (self, defaultValue?) => lazyObservable((sink) => callback.call(self, sink, self), defaultValue); return computed(target, propertyKey as any, { set(value: T) { const state = getPrivateStore(this, LAZY_PROPS); if (typeof value == 'object') value = observable(value); state[propertyKey] = makeLazyObservable(this, value) }, ...(descriptor || {}), get() { const state = getPrivateStore(this, LAZY_PROPS); const lazy = state[propertyKey] = state[propertyKey] || makeLazyObservable(this); return lazy.current(); }, }) }, // stage3(value, context) { // // TODO // }, });