@flowgram.ai/reactive 0.2.16 → 0.2.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/tracker.ts","../../src/core/reactive-base-state.ts","../../src/utils/create-proxy.ts","../../src/core/reactive-state.ts","../../src/hooks/use-reactive-state.ts","../../src/hooks/use-observe.ts","../../src/hooks/use-readonly-reactive-state.ts","../../src/react/observe.tsx","../../src/index.ts"],"sourcesContent":["/**\n * Fork from: https://github.com/meteor/meteor/blob/devel/packages/tracker/tracker.js\n */\ntype ICallback<ARG = void, RET = void> = (arg: ARG) => RET;\n\n/**\n * Tracker 是一套 响应式依赖追踪 库,来源于 Meteor.Tracker\n * https://docs.meteor.com/api/Tracker.html#tracker-autorun-and-async-callbacks\n * https://github.com/meteor/meteor/blob/devel/packages/tracker/tracker.js\n *\n * 相关论文:https://dl.acm.org/doi/fullHtml/10.1145/3184558.3185978\n */\nexport namespace Tracker {\n const _pendingComputations: Computation[] = [];\n const _afterFlushCallbacks: ICallback[] = [];\n // `true` if a Tracker.flush is scheduled, or if we are in Tracker.flush now\n let _willFlush = false;\n // `true` if we are in Tracker.flush now\n let _inFlush = false;\n // `true` if we are computing a computation now, either first time\n // or recompute. This matches Tracker.active unless we are inside\n // Tracker.nonreactive, which nullfies currentComputation even though\n // an enclosing computation may still be running.\n let _inCompute = false;\n let _currentComputation: Computation | undefined = undefined;\n // `true` if the `_throwFirstError` option was passed in to the call\n // to Tracker.flush that we are in. When set, throw rather than log the\n // first error encountered while flushing. Before throwing the error,\n // finish flushing (from a finally block), logging any subsequent\n // errors.\n let _throwFirstError = false;\n\n export interface FlushOptions {\n finishSynchronously?: boolean;\n throwFirstError?: boolean;\n }\n\n function _throwOrLog(msg: string, e: any) {\n if (_throwFirstError) {\n throw e;\n } else {\n console.error(`[Tracker error] ${msg}`, e);\n }\n }\n\n // Run all pending computations and afterFlush callbacks. If we were not called\n // directly via Tracker.flush, this may return before they're all done to allow\n // the event loop to run a little before continuing.\n function _runFlush(options?: FlushOptions) {\n // Nested flush could plausibly happen if, say, a flush causes\n // DOM mutation, which causes a \"blur\" event, which runs an\n // app event handler that calls Tracker.flush. At the moment\n // Spark blocks event handlers during DOM mutation anyway,\n // because the LiveRange tree isn't valid. And we don't have\n // any useful notion of a nested flush.\n if (inFlush()) throw new Error(\"Can't call Tracker.flush while flushing\");\n\n if (_inCompute) throw new Error(\"Can't flush inside Tracker.autorun\");\n\n options = options || {};\n\n _inFlush = true;\n _willFlush = true;\n _throwFirstError = !!options.throwFirstError;\n\n var recomputedCount = 0;\n var finishedTry = false;\n try {\n while (_pendingComputations.length || _afterFlushCallbacks.length) {\n // recompute all pending computations\n while (_pendingComputations.length) {\n var comp = _pendingComputations.shift()!;\n comp._recompute();\n if (comp._needsRecompute()) {\n _pendingComputations.unshift(comp);\n }\n\n if (!options.finishSynchronously && ++recomputedCount > 100) {\n finishedTry = true;\n return;\n }\n }\n\n if (_afterFlushCallbacks.length) {\n // call one afterFlush callback, which may\n // invalidate more computations\n var func = _afterFlushCallbacks.shift()!;\n try {\n func();\n } catch (e: any) {\n _throwOrLog('afterFlush', e);\n }\n }\n }\n finishedTry = true;\n } finally {\n if (!finishedTry) {\n // we're erroring due to throwFirstError being true.\n _inFlush = false; // needed before calling `Tracker.flush()` again\n // finish flushing\n _runFlush({\n finishSynchronously: options.finishSynchronously,\n throwFirstError: false,\n });\n }\n _willFlush = false;\n _inFlush = false;\n if (_pendingComputations.length || _afterFlushCallbacks.length) {\n // We're yielding because we ran a bunch of computations and we aren't\n // required to finish synchronously, so we'd like to give the event loop a\n // chance. We should flush again soon.\n if (options.finishSynchronously) {\n throw new Error('still have more to do?'); // shouldn't happen\n }\n setTimeout(_requireFlush, 10);\n }\n }\n }\n\n function _requireFlush() {\n if (!_willFlush) {\n setTimeout(_runFlush, 0);\n _willFlush = true;\n }\n }\n\n /******************************** Tracker Base API ******************************************/\n\n /**\n * 函数在响应式模块中执行\n * @param computation\n * @param f\n */\n export function withComputation<T = any>(\n computation: Computation,\n f: ICallback<Computation, T>,\n ): T {\n let previousComputation = _currentComputation;\n _currentComputation = computation;\n try {\n return f.call(null, computation);\n } finally {\n _currentComputation = previousComputation;\n }\n }\n\n /**\n * 函数在非响应式模块中执行\n */\n export function withoutComputation<T = any>(f: ICallback<undefined, T>): T {\n let previousComputation = _currentComputation;\n _currentComputation = undefined;\n try {\n return f(undefined);\n } finally {\n _currentComputation = previousComputation;\n }\n }\n\n export function isActive(): boolean {\n return !!_currentComputation;\n }\n\n export function getCurrentComputation(): Computation | undefined {\n return _currentComputation;\n }\n\n /**\n * Run a function now and rerun it later whenever its dependencies\n * change. Returns a Computation object that can be used to stop or observe the\n * rerunning.\n */\n export function autorun<T = any>(\n f: IComputationCallback<T>,\n options?: { onError: ICallback<Error> },\n ): Computation<T> {\n var c = new Computation<T>(f, _currentComputation, options?.onError);\n\n if (isActive())\n Tracker.onInvalidate(function () {\n c.stop();\n });\n\n return c;\n }\n\n export function onInvalidate(f: ICallback<Computation | undefined>) {\n if (!_currentComputation) {\n throw new Error('Tracker.onInvalidate requires a currentComputation');\n }\n _currentComputation.onInvalidate(f);\n }\n\n /**\n * True if we are computing a computation now, either first time or recompute. This matches Tracker.active unless we are inside Tracker.nonreactive, which nullfies currentComputation even though an enclosing computation may still be running.\n */\n export function inFlush(): boolean {\n return _inFlush;\n }\n\n /**\n * Process all reactive updates immediately and ensure that all invalidated computations are rerun.\n */\n export function flush(options?: Omit<FlushOptions, 'finishSynchronously'>) {\n _runFlush({\n finishSynchronously: true,\n throwFirstError: options && options.throwFirstError,\n });\n }\n\n /**\n * Schedules a function to be called during the next flush, or later in the current flush if one is in progress, after all invalidated computations have been rerun. The function will be run once and not on subsequent flushes unless `afterFlush` is called again.\n */\n export function afterFlush(f: ICallback) {\n _afterFlushCallbacks.push(f);\n _requireFlush();\n }\n\n /********************************************************************************************/\n\n export type IComputationCallback<V = any> = ICallback<Computation, V>;\n\n /**\n * A Computation object represents code that is repeatedly rerun\n * in response to\n * reactive data changes. Computations don't have return values; they just\n * perform actions, such as rerendering a template on the screen. Computations\n * are created using Tracker.autorun. Use stop to prevent further rerunning of a\n * computation.\n */\n export class Computation<V = any> {\n private _onInvalidateCallbacks: IComputationCallback[] = [];\n\n private _onStopCallbacks: IComputationCallback[] = [];\n\n private _recomputing = false;\n\n private _result: V;\n\n /**\n * 是否停止\n */\n public stopped = false;\n\n /**\n * 未开始执行则返回 false\n */\n public invalidated = false;\n\n /**\n * 是否第一次执行\n */\n public firstRun = true;\n\n constructor(\n private _fn: IComputationCallback<V>,\n public readonly parent?: Computation,\n private readonly _onError?: ICallback<Error>,\n ) {\n let hasError = true;\n try {\n this._compute();\n hasError = false;\n } finally {\n this.firstRun = false;\n if (hasError) {\n this.stop();\n }\n }\n }\n\n onInvalidate(f: IComputationCallback): void {\n if (this.invalidated) {\n withoutComputation(f.bind(null, this));\n } else {\n this._onInvalidateCallbacks.push(f);\n }\n }\n\n /**\n * @summary Invalidates this computation so that it will be rerun.\n */\n invalidate() {\n if (!this.invalidated) {\n // if we're currently in _recompute(), don't enqueue\n // ourselves, since we'll rerun immediately anyway.\n if (!this._recomputing && !this.stopped) {\n _requireFlush();\n _pendingComputations.push(this);\n }\n\n this.invalidated = true;\n\n // callbacks can't add callbacks, because\n // this.invalidated === true.\n for (var i = 0, f: IComputationCallback; (f = this._onInvalidateCallbacks[i]); i++) {\n withoutComputation(f.bind(null, this));\n }\n this._onInvalidateCallbacks = [];\n }\n }\n\n /**\n * @summary Prevents this computation from rerunning.\n * @locus Client\n */\n stop() {\n if (!this.stopped) {\n this.stopped = true;\n this.invalidate();\n for (let i = 0, f: IComputationCallback; (f = this._onStopCallbacks[i]); i++) {\n withoutComputation(f.bind(null, this));\n }\n this._onStopCallbacks = [];\n }\n }\n\n onStop(f: IComputationCallback): void {\n if (this.stopped) {\n withoutComputation(f.bind(null, this));\n } else {\n this._onStopCallbacks.push(f);\n }\n }\n\n private _compute(): void {\n this.invalidated = false;\n\n var previousInCompute = _inCompute;\n _inCompute = true;\n try {\n this._result = Tracker.withComputation<V>(this, this._fn);\n } finally {\n _inCompute = previousInCompute;\n }\n }\n\n _needsRecompute() {\n return this.invalidated && !this.stopped;\n }\n\n _recompute() {\n this._recomputing = true;\n try {\n if (this._needsRecompute()) {\n try {\n this._compute();\n } catch (e: any) {\n if (this._onError) {\n this._onError(e);\n } else {\n _throwOrLog('recompute', e);\n }\n }\n }\n } finally {\n this._recomputing = false;\n }\n }\n\n /**\n * @summary Process the reactive updates for this computation immediately\n * and ensure that the computation is rerun. The computation is rerun only\n * if it is invalidated.\n */\n flush() {\n if (this._recomputing) return;\n\n this._recompute();\n }\n\n /**\n * @summary Causes the function inside this computation to run and\n * synchronously process all reactive updtes.\n * @locus Client\n */\n run() {\n this.invalidate();\n this.flush();\n }\n\n get result(): V {\n return this._result;\n }\n }\n\n /**\n * A Dependency represents an atomic unit of reactive data that a\n * computation might depend on. Reactive data sources such as Session or\n * Minimongo internally create different Dependency objects for different\n * pieces of data, each of which may be depended on by multiple computations.\n * When the data changes, the computations are invalidated.\n */\n export class Dependency {\n private _dependents: Set<Computation> = new Set<Computation>();\n\n /**\n * Declares that the current computation (or `fromComputation` if given) depends on `dependency`. The computation will be invalidated the next time `dependency` changes.\n * If there is no current computation and `depend()` is called with no arguments, it does nothing and returns false.\n * Returns true if the computation is a new dependent of `dependency` rather than an existing one.\n */\n depend(computation?: Computation): boolean {\n if (!computation) {\n if (!isActive()) {\n return false;\n }\n computation = _currentComputation;\n }\n if (!this._dependents.has(computation!)) {\n this._dependents.add(computation!);\n computation!.onInvalidate(() => {\n this._dependents.delete(computation!);\n });\n return true;\n }\n return false;\n }\n\n /**\n * Invalidate all dependent computations immediately and remove them as dependents.\n */\n changed() {\n for (const dep of this._dependents) {\n dep.invalidate();\n }\n }\n\n /**\n * True if this Dependency has one or more dependent Computations, which would be invalidated if this Dependency were to change.\n */\n hasDependents() {\n return this._dependents.size !== 0;\n }\n }\n}\n","import { Tracker } from './tracker';\n\ntype IStateEqual = (a: any, b: any) => boolean;\n\nexport class ReactiveBaseState<V> {\n protected _dep = new Tracker.Dependency();\n\n protected _value: V;\n\n protected _isEqual: IStateEqual = (a: any, b: any) => a == b;\n\n protected _addDepend(dep: Tracker.Dependency): void {\n if (Tracker.isActive()) {\n dep.depend();\n }\n }\n\n constructor(initialValue: V, opts?: { isEqual?: IStateEqual }) {\n this._value = initialValue;\n if (opts?.isEqual) {\n this._isEqual = opts.isEqual;\n }\n }\n\n hasDependents(): boolean {\n return this._dep.hasDependents();\n }\n\n get value(): V {\n this._addDepend(this._dep);\n return this._value;\n }\n\n set value(newValue: V) {\n if (!this._isEqual(this._value, newValue)) {\n this._value = newValue;\n this._dep.changed();\n }\n }\n}\n","interface ProxyOptions<V> {\n get?: (target: V, key: string) => any;\n set?: (target: V, key: string, newValue: any) => boolean;\n}\n\nexport function createProxy<V extends Record<string, any>>(target: V, opts: ProxyOptions<V>): V {\n let useProxy = 'Proxy' in window;\n if (process.env.NODE_ENV === 'test') {\n if ((global as any).__ignoreProxy) {\n useProxy = false;\n }\n }\n if (useProxy) {\n return new Proxy<V>(target, opts);\n }\n const result: V = {} as V;\n for (const key in target) {\n Object.defineProperty(result, key, {\n enumerable: true,\n get: opts.get ? () => opts.get!(target, key) : undefined,\n set: opts.set ? (newValue: any) => opts.set!(target, key, newValue) : undefined,\n });\n }\n return result;\n}\n","import { Tracker } from './tracker';\n\nimport Dependency = Tracker.Dependency;\n\nimport { ReactiveBaseState } from './reactive-base-state';\nimport { createProxy } from '../utils/create-proxy';\n\nexport class ReactiveState<V extends Record<string, any>> extends ReactiveBaseState<V> {\n private _keyDeps: Map<string, Dependency> = new Map();\n\n set(key: keyof V & string, value: any): boolean {\n this._ensureKey(key);\n const oldValue = this._value[key];\n if (!this._isEqual(oldValue, value)) {\n this._value[key] = value;\n this._keyDeps.get(key)!.changed();\n return true;\n }\n return false;\n }\n\n get(key: keyof V & string) {\n this._ensureKey(key);\n this._addDepend(this._keyDeps.get(key)!);\n return this._value[key];\n }\n\n protected _ensureKey(key: keyof V & string) {\n if (!this._keyDeps.has(key)) {\n this._keyDeps.set(key, new Dependency());\n }\n }\n\n hasDependents(): boolean {\n if (this._dep.hasDependents()) return true;\n for (const dep of this._keyDeps.values()) {\n if (dep.hasDependents()) return true;\n }\n return false;\n }\n\n keys(): string[] {\n return Object.keys(this._value);\n }\n\n set value(newValue: V) {\n if (!this._isEqual(this._value, newValue)) {\n this._value = newValue;\n this._keyDeps.clear();\n this._dep.changed();\n }\n }\n\n private _proxyValue: V;\n\n get value(): V {\n this._addDepend(this._dep);\n if (!this._proxyValue) {\n this._proxyValue = createProxy<V>(this._value, {\n get: (target, key: string) => this.get(key),\n set: (target, key: string, newValue) => {\n this.set(key, newValue);\n return true;\n },\n });\n }\n return this._proxyValue;\n }\n\n private _proxyReadonlyValue: V;\n\n get readonlyValue(): Readonly<V> {\n this._addDepend(this._dep);\n if (!this._proxyReadonlyValue) {\n this._proxyReadonlyValue = createProxy(this._value, {\n get: (target, key: string) => this.get(key),\n set: (newValue, key: string) => {\n throw new Error(`[ReactiveState] Cannnot set readonly field \"${key}\"`);\n },\n });\n }\n return this._proxyReadonlyValue;\n }\n}\n","import { useMemo } from 'react';\n\nimport { ReactiveState } from '../core/reactive-state';\nimport { useObserve } from './use-observe';\n\nexport function useReactiveState<T extends Record<string, any>>(v: ReactiveState<T> | T): T {\n const state = useMemo<ReactiveState<T>>(\n () => (v instanceof ReactiveState ? v : new ReactiveState(v)),\n [],\n );\n return useObserve<T>(state.value);\n}\n","import { useCallback, useEffect, useMemo } from 'react';\n\nimport { useRefresh } from '@flowgram.ai/utils';\n\nimport { createProxy } from '../utils/create-proxy';\nimport { Tracker } from '../core/tracker';\n\nimport Computation = Tracker.Computation;\n\nexport function useObserve<T extends Record<string, any>>(value: T | undefined): T {\n const refresh = useRefresh();\n const computationMap = useMemo<Map<string, Computation>>(() => new Map(), []);\n const clear = useCallback(() => {\n computationMap.forEach((comp) => comp.stop());\n computationMap.clear();\n }, []);\n useEffect(() => clear, []);\n // 重新渲染需要清空依赖\n clear();\n return useMemo(() => {\n if (value === undefined) return {} as T;\n return createProxy(value, {\n get(target, key: string) {\n let computation = computationMap.get(key);\n if (!computation) {\n computation = new Tracker.Computation((c) => {\n if (!c.firstRun) {\n refresh();\n return;\n }\n return value[key];\n });\n computationMap.set(key, computation);\n }\n return value[key];\n },\n });\n }, [value]);\n}\n","import { ReactiveState } from '../core/reactive-state';\nimport { useObserve } from './use-observe';\n\nexport function useReadonlyReactiveState<T extends Record<string, any>>(\n state: ReactiveState<T>,\n): Readonly<T> {\n return useObserve<T>(state.readonlyValue);\n}\n","import React, { useRef, useEffect } from 'react';\n\nimport { useRefresh } from '@flowgram.ai/utils';\n\nimport { Tracker } from '../core/tracker';\n\nimport Computation = Tracker.Computation;\n\nexport function observe<T = any>(fc: React.FC<T>): React.FC<T> {\n return function ReactiveObserver(props: T) {\n const childrenRef = useRef<React.ReactElement<any, any> | null>();\n const computationRef = useRef<Computation | undefined>();\n const refresh = useRefresh();\n computationRef.current?.stop();\n computationRef.current = new Tracker.Computation(c => {\n if (c.firstRun) {\n childrenRef.current = fc(props);\n } else {\n refresh();\n }\n });\n useEffect(\n () => () => {\n computationRef.current?.stop();\n },\n [],\n );\n return childrenRef.current!;\n };\n}\n","import { Tracker } from './core/tracker';\n\nexport { Tracker } from './core/tracker';\nexport { ReactiveState } from './core/reactive-state';\nexport { ReactiveBaseState } from './core/reactive-base-state';\nexport { useReactiveState } from './hooks/use-reactive-state';\nexport { useReadonlyReactiveState } from './hooks/use-readonly-reactive-state';\nexport { useObserve } from './hooks/use-observe';\nexport { observe } from './react/observe';\nexport const { Dependency, Computation } = Tracker;\n"],"mappings":"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","names":["Tracker","Computation","Dependency","useMemo","useMemo","useEffect","useRefresh","useRefresh","useEffect","Dependency"]}
1
+ {"version":3,"sources":["../../src/core/tracker.ts","../../src/core/reactive-base-state.ts","../../src/utils/create-proxy.ts","../../src/core/reactive-state.ts","../../src/hooks/use-reactive-state.ts","../../src/hooks/use-observe.ts","../../src/hooks/use-readonly-reactive-state.ts","../../src/react/observe.tsx","../../src/index.ts"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\n/**\n * Fork from: https://github.com/meteor/meteor/blob/devel/packages/tracker/tracker.js\n */\ntype ICallback<ARG = void, RET = void> = (arg: ARG) => RET;\n\n/**\n * Tracker 是一套 响应式依赖追踪 库,来源于 Meteor.Tracker\n * https://docs.meteor.com/api/Tracker.html#tracker-autorun-and-async-callbacks\n * https://github.com/meteor/meteor/blob/devel/packages/tracker/tracker.js\n *\n * 相关论文:https://dl.acm.org/doi/fullHtml/10.1145/3184558.3185978\n */\nexport namespace Tracker {\n const _pendingComputations: Computation[] = [];\n const _afterFlushCallbacks: ICallback[] = [];\n // `true` if a Tracker.flush is scheduled, or if we are in Tracker.flush now\n let _willFlush = false;\n // `true` if we are in Tracker.flush now\n let _inFlush = false;\n // `true` if we are computing a computation now, either first time\n // or recompute. This matches Tracker.active unless we are inside\n // Tracker.nonreactive, which nullfies currentComputation even though\n // an enclosing computation may still be running.\n let _inCompute = false;\n let _currentComputation: Computation | undefined = undefined;\n // `true` if the `_throwFirstError` option was passed in to the call\n // to Tracker.flush that we are in. When set, throw rather than log the\n // first error encountered while flushing. Before throwing the error,\n // finish flushing (from a finally block), logging any subsequent\n // errors.\n let _throwFirstError = false;\n\n export interface FlushOptions {\n finishSynchronously?: boolean;\n throwFirstError?: boolean;\n }\n\n function _throwOrLog(msg: string, e: any) {\n if (_throwFirstError) {\n throw e;\n } else {\n console.error(`[Tracker error] ${msg}`, e);\n }\n }\n\n // Run all pending computations and afterFlush callbacks. If we were not called\n // directly via Tracker.flush, this may return before they're all done to allow\n // the event loop to run a little before continuing.\n function _runFlush(options?: FlushOptions) {\n // Nested flush could plausibly happen if, say, a flush causes\n // DOM mutation, which causes a \"blur\" event, which runs an\n // app event handler that calls Tracker.flush. At the moment\n // Spark blocks event handlers during DOM mutation anyway,\n // because the LiveRange tree isn't valid. And we don't have\n // any useful notion of a nested flush.\n if (inFlush()) throw new Error(\"Can't call Tracker.flush while flushing\");\n\n if (_inCompute) throw new Error(\"Can't flush inside Tracker.autorun\");\n\n options = options || {};\n\n _inFlush = true;\n _willFlush = true;\n _throwFirstError = !!options.throwFirstError;\n\n var recomputedCount = 0;\n var finishedTry = false;\n try {\n while (_pendingComputations.length || _afterFlushCallbacks.length) {\n // recompute all pending computations\n while (_pendingComputations.length) {\n var comp = _pendingComputations.shift()!;\n comp._recompute();\n if (comp._needsRecompute()) {\n _pendingComputations.unshift(comp);\n }\n\n if (!options.finishSynchronously && ++recomputedCount > 100) {\n finishedTry = true;\n return;\n }\n }\n\n if (_afterFlushCallbacks.length) {\n // call one afterFlush callback, which may\n // invalidate more computations\n var func = _afterFlushCallbacks.shift()!;\n try {\n func();\n } catch (e: any) {\n _throwOrLog('afterFlush', e);\n }\n }\n }\n finishedTry = true;\n } finally {\n if (!finishedTry) {\n // we're erroring due to throwFirstError being true.\n _inFlush = false; // needed before calling `Tracker.flush()` again\n // finish flushing\n _runFlush({\n finishSynchronously: options.finishSynchronously,\n throwFirstError: false,\n });\n }\n _willFlush = false;\n _inFlush = false;\n if (_pendingComputations.length || _afterFlushCallbacks.length) {\n // We're yielding because we ran a bunch of computations and we aren't\n // required to finish synchronously, so we'd like to give the event loop a\n // chance. We should flush again soon.\n if (options.finishSynchronously) {\n throw new Error('still have more to do?'); // shouldn't happen\n }\n setTimeout(_requireFlush, 10);\n }\n }\n }\n\n function _requireFlush() {\n if (!_willFlush) {\n setTimeout(_runFlush, 0);\n _willFlush = true;\n }\n }\n\n /******************************** Tracker Base API ******************************************/\n\n /**\n * 函数在响应式模块中执行\n * @param computation\n * @param f\n */\n export function withComputation<T = any>(\n computation: Computation,\n f: ICallback<Computation, T>,\n ): T {\n let previousComputation = _currentComputation;\n _currentComputation = computation;\n try {\n return f.call(null, computation);\n } finally {\n _currentComputation = previousComputation;\n }\n }\n\n /**\n * 函数在非响应式模块中执行\n */\n export function withoutComputation<T = any>(f: ICallback<undefined, T>): T {\n let previousComputation = _currentComputation;\n _currentComputation = undefined;\n try {\n return f(undefined);\n } finally {\n _currentComputation = previousComputation;\n }\n }\n\n export function isActive(): boolean {\n return !!_currentComputation;\n }\n\n export function getCurrentComputation(): Computation | undefined {\n return _currentComputation;\n }\n\n /**\n * Run a function now and rerun it later whenever its dependencies\n * change. Returns a Computation object that can be used to stop or observe the\n * rerunning.\n */\n export function autorun<T = any>(\n f: IComputationCallback<T>,\n options?: { onError: ICallback<Error> },\n ): Computation<T> {\n var c = new Computation<T>(f, _currentComputation, options?.onError);\n\n if (isActive())\n Tracker.onInvalidate(function () {\n c.stop();\n });\n\n return c;\n }\n\n export function onInvalidate(f: ICallback<Computation | undefined>) {\n if (!_currentComputation) {\n throw new Error('Tracker.onInvalidate requires a currentComputation');\n }\n _currentComputation.onInvalidate(f);\n }\n\n /**\n * True if we are computing a computation now, either first time or recompute. This matches Tracker.active unless we are inside Tracker.nonreactive, which nullfies currentComputation even though an enclosing computation may still be running.\n */\n export function inFlush(): boolean {\n return _inFlush;\n }\n\n /**\n * Process all reactive updates immediately and ensure that all invalidated computations are rerun.\n */\n export function flush(options?: Omit<FlushOptions, 'finishSynchronously'>) {\n _runFlush({\n finishSynchronously: true,\n throwFirstError: options && options.throwFirstError,\n });\n }\n\n /**\n * Schedules a function to be called during the next flush, or later in the current flush if one is in progress, after all invalidated computations have been rerun. The function will be run once and not on subsequent flushes unless `afterFlush` is called again.\n */\n export function afterFlush(f: ICallback) {\n _afterFlushCallbacks.push(f);\n _requireFlush();\n }\n\n /********************************************************************************************/\n\n export type IComputationCallback<V = any> = ICallback<Computation, V>;\n\n /**\n * A Computation object represents code that is repeatedly rerun\n * in response to\n * reactive data changes. Computations don't have return values; they just\n * perform actions, such as rerendering a template on the screen. Computations\n * are created using Tracker.autorun. Use stop to prevent further rerunning of a\n * computation.\n */\n export class Computation<V = any> {\n private _onInvalidateCallbacks: IComputationCallback[] = [];\n\n private _onStopCallbacks: IComputationCallback[] = [];\n\n private _recomputing = false;\n\n private _result: V;\n\n /**\n * 是否停止\n */\n public stopped = false;\n\n /**\n * 未开始执行则返回 false\n */\n public invalidated = false;\n\n /**\n * 是否第一次执行\n */\n public firstRun = true;\n\n constructor(\n private _fn: IComputationCallback<V>,\n public readonly parent?: Computation,\n private readonly _onError?: ICallback<Error>,\n ) {\n let hasError = true;\n try {\n this._compute();\n hasError = false;\n } finally {\n this.firstRun = false;\n if (hasError) {\n this.stop();\n }\n }\n }\n\n onInvalidate(f: IComputationCallback): void {\n if (this.invalidated) {\n withoutComputation(f.bind(null, this));\n } else {\n this._onInvalidateCallbacks.push(f);\n }\n }\n\n /**\n * @summary Invalidates this computation so that it will be rerun.\n */\n invalidate() {\n if (!this.invalidated) {\n // if we're currently in _recompute(), don't enqueue\n // ourselves, since we'll rerun immediately anyway.\n if (!this._recomputing && !this.stopped) {\n _requireFlush();\n _pendingComputations.push(this);\n }\n\n this.invalidated = true;\n\n // callbacks can't add callbacks, because\n // this.invalidated === true.\n for (var i = 0, f: IComputationCallback; (f = this._onInvalidateCallbacks[i]); i++) {\n withoutComputation(f.bind(null, this));\n }\n this._onInvalidateCallbacks = [];\n }\n }\n\n /**\n * @summary Prevents this computation from rerunning.\n * @locus Client\n */\n stop() {\n if (!this.stopped) {\n this.stopped = true;\n this.invalidate();\n for (let i = 0, f: IComputationCallback; (f = this._onStopCallbacks[i]); i++) {\n withoutComputation(f.bind(null, this));\n }\n this._onStopCallbacks = [];\n }\n }\n\n onStop(f: IComputationCallback): void {\n if (this.stopped) {\n withoutComputation(f.bind(null, this));\n } else {\n this._onStopCallbacks.push(f);\n }\n }\n\n private _compute(): void {\n this.invalidated = false;\n\n var previousInCompute = _inCompute;\n _inCompute = true;\n try {\n this._result = Tracker.withComputation<V>(this, this._fn);\n } finally {\n _inCompute = previousInCompute;\n }\n }\n\n _needsRecompute() {\n return this.invalidated && !this.stopped;\n }\n\n _recompute() {\n this._recomputing = true;\n try {\n if (this._needsRecompute()) {\n try {\n this._compute();\n } catch (e: any) {\n if (this._onError) {\n this._onError(e);\n } else {\n _throwOrLog('recompute', e);\n }\n }\n }\n } finally {\n this._recomputing = false;\n }\n }\n\n /**\n * @summary Process the reactive updates for this computation immediately\n * and ensure that the computation is rerun. The computation is rerun only\n * if it is invalidated.\n */\n flush() {\n if (this._recomputing) return;\n\n this._recompute();\n }\n\n /**\n * @summary Causes the function inside this computation to run and\n * synchronously process all reactive updtes.\n * @locus Client\n */\n run() {\n this.invalidate();\n this.flush();\n }\n\n get result(): V {\n return this._result;\n }\n }\n\n /**\n * A Dependency represents an atomic unit of reactive data that a\n * computation might depend on. Reactive data sources such as Session or\n * Minimongo internally create different Dependency objects for different\n * pieces of data, each of which may be depended on by multiple computations.\n * When the data changes, the computations are invalidated.\n */\n export class Dependency {\n private _dependents: Set<Computation> = new Set<Computation>();\n\n /**\n * Declares that the current computation (or `fromComputation` if given) depends on `dependency`. The computation will be invalidated the next time `dependency` changes.\n * If there is no current computation and `depend()` is called with no arguments, it does nothing and returns false.\n * Returns true if the computation is a new dependent of `dependency` rather than an existing one.\n */\n depend(computation?: Computation): boolean {\n if (!computation) {\n if (!isActive()) {\n return false;\n }\n computation = _currentComputation;\n }\n if (!this._dependents.has(computation!)) {\n this._dependents.add(computation!);\n computation!.onInvalidate(() => {\n this._dependents.delete(computation!);\n });\n return true;\n }\n return false;\n }\n\n /**\n * Invalidate all dependent computations immediately and remove them as dependents.\n */\n changed() {\n for (const dep of this._dependents) {\n dep.invalidate();\n }\n }\n\n /**\n * True if this Dependency has one or more dependent Computations, which would be invalidated if this Dependency were to change.\n */\n hasDependents() {\n return this._dependents.size !== 0;\n }\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Tracker } from './tracker';\n\ntype IStateEqual = (a: any, b: any) => boolean;\n\nexport class ReactiveBaseState<V> {\n protected _dep = new Tracker.Dependency();\n\n protected _value: V;\n\n protected _isEqual: IStateEqual = (a: any, b: any) => a == b;\n\n protected _addDepend(dep: Tracker.Dependency): void {\n if (Tracker.isActive()) {\n dep.depend();\n }\n }\n\n constructor(initialValue: V, opts?: { isEqual?: IStateEqual }) {\n this._value = initialValue;\n if (opts?.isEqual) {\n this._isEqual = opts.isEqual;\n }\n }\n\n hasDependents(): boolean {\n return this._dep.hasDependents();\n }\n\n get value(): V {\n this._addDepend(this._dep);\n return this._value;\n }\n\n set value(newValue: V) {\n if (!this._isEqual(this._value, newValue)) {\n this._value = newValue;\n this._dep.changed();\n }\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\ninterface ProxyOptions<V> {\n get?: (target: V, key: string) => any;\n set?: (target: V, key: string, newValue: any) => boolean;\n}\n\nexport function createProxy<V extends Record<string, any>>(target: V, opts: ProxyOptions<V>): V {\n let useProxy = 'Proxy' in window;\n if (process.env.NODE_ENV === 'test') {\n if ((global as any).__ignoreProxy) {\n useProxy = false;\n }\n }\n if (useProxy) {\n return new Proxy<V>(target, opts);\n }\n const result: V = {} as V;\n for (const key in target) {\n Object.defineProperty(result, key, {\n enumerable: true,\n get: opts.get ? () => opts.get!(target, key) : undefined,\n set: opts.set ? (newValue: any) => opts.set!(target, key, newValue) : undefined,\n });\n }\n return result;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Tracker } from './tracker';\n\nimport Dependency = Tracker.Dependency;\n\nimport { ReactiveBaseState } from './reactive-base-state';\nimport { createProxy } from '../utils/create-proxy';\n\nexport class ReactiveState<V extends Record<string, any>> extends ReactiveBaseState<V> {\n private _keyDeps: Map<string, Dependency> = new Map();\n\n set(key: keyof V & string, value: any): boolean {\n this._ensureKey(key);\n const oldValue = this._value[key];\n if (!this._isEqual(oldValue, value)) {\n this._value[key] = value;\n this._keyDeps.get(key)!.changed();\n return true;\n }\n return false;\n }\n\n get(key: keyof V & string) {\n this._ensureKey(key);\n this._addDepend(this._keyDeps.get(key)!);\n return this._value[key];\n }\n\n protected _ensureKey(key: keyof V & string) {\n if (!this._keyDeps.has(key)) {\n this._keyDeps.set(key, new Dependency());\n }\n }\n\n hasDependents(): boolean {\n if (this._dep.hasDependents()) return true;\n for (const dep of this._keyDeps.values()) {\n if (dep.hasDependents()) return true;\n }\n return false;\n }\n\n keys(): string[] {\n return Object.keys(this._value);\n }\n\n set value(newValue: V) {\n if (!this._isEqual(this._value, newValue)) {\n this._value = newValue;\n this._keyDeps.clear();\n this._dep.changed();\n }\n }\n\n private _proxyValue: V;\n\n get value(): V {\n this._addDepend(this._dep);\n if (!this._proxyValue) {\n this._proxyValue = createProxy<V>(this._value, {\n get: (target, key: string) => this.get(key),\n set: (target, key: string, newValue) => {\n this.set(key, newValue);\n return true;\n },\n });\n }\n return this._proxyValue;\n }\n\n private _proxyReadonlyValue: V;\n\n get readonlyValue(): Readonly<V> {\n this._addDepend(this._dep);\n if (!this._proxyReadonlyValue) {\n this._proxyReadonlyValue = createProxy(this._value, {\n get: (target, key: string) => this.get(key),\n set: (newValue, key: string) => {\n throw new Error(`[ReactiveState] Cannnot set readonly field \"${key}\"`);\n },\n });\n }\n return this._proxyReadonlyValue;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useMemo } from 'react';\n\nimport { ReactiveState } from '../core/reactive-state';\nimport { useObserve } from './use-observe';\n\nexport function useReactiveState<T extends Record<string, any>>(v: ReactiveState<T> | T): T {\n const state = useMemo<ReactiveState<T>>(\n () => (v instanceof ReactiveState ? v : new ReactiveState(v)),\n [],\n );\n return useObserve<T>(state.value);\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useCallback, useEffect, useMemo } from 'react';\n\nimport { useRefresh } from '@flowgram.ai/utils';\n\nimport { createProxy } from '../utils/create-proxy';\nimport { Tracker } from '../core/tracker';\n\nimport Computation = Tracker.Computation;\n\nexport function useObserve<T extends Record<string, any>>(value: T | undefined): T {\n const refresh = useRefresh();\n const computationMap = useMemo<Map<string, Computation>>(() => new Map(), []);\n const clear = useCallback(() => {\n computationMap.forEach((comp) => comp.stop());\n computationMap.clear();\n }, []);\n useEffect(() => clear, []);\n // 重新渲染需要清空依赖\n clear();\n return useMemo(() => {\n if (value === undefined) return {} as T;\n return createProxy(value, {\n get(target, key: string) {\n let computation = computationMap.get(key);\n if (!computation) {\n computation = new Tracker.Computation((c) => {\n if (!c.firstRun) {\n refresh();\n return;\n }\n return value[key];\n });\n computationMap.set(key, computation);\n }\n return value[key];\n },\n });\n }, [value]);\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { ReactiveState } from '../core/reactive-state';\nimport { useObserve } from './use-observe';\n\nexport function useReadonlyReactiveState<T extends Record<string, any>>(\n state: ReactiveState<T>,\n): Readonly<T> {\n return useObserve<T>(state.readonlyValue);\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React, { useRef, useEffect } from 'react';\n\nimport { useRefresh } from '@flowgram.ai/utils';\n\nimport { Tracker } from '../core/tracker';\n\nimport Computation = Tracker.Computation;\n\nexport function observe<T = any>(fc: React.FC<T>): React.FC<T> {\n return function ReactiveObserver(props: T) {\n const childrenRef = useRef<React.ReactElement<any, any> | null>();\n const computationRef = useRef<Computation | undefined>();\n const refresh = useRefresh();\n computationRef.current?.stop();\n computationRef.current = new Tracker.Computation(c => {\n if (c.firstRun) {\n childrenRef.current = fc(props);\n } else {\n refresh();\n }\n });\n useEffect(\n () => () => {\n computationRef.current?.stop();\n },\n [],\n );\n return childrenRef.current!;\n };\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Tracker } from './core/tracker';\n\nexport { Tracker } from './core/tracker';\nexport { ReactiveState } from './core/reactive-state';\nexport { ReactiveBaseState } from './core/reactive-base-state';\nexport { useReactiveState } from './hooks/use-reactive-state';\nexport { useReadonlyReactiveState } from './hooks/use-readonly-reactive-state';\nexport { useObserve } from './hooks/use-observe';\nexport { observe } from './react/observe';\nexport const { Dependency, Computation } = Tracker;\n"],"mappings":"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","names":["Tracker","Computation","Dependency","useMemo","useMemo","useEffect","useRefresh","useRefresh","useEffect","Dependency"]}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,9 @@
1
1
  import React from 'react';
2
2
 
3
+ /**
4
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
5
+ * SPDX-License-Identifier: MIT
6
+ */
3
7
  /**
4
8
  * Fork from: https://github.com/meteor/meteor/blob/devel/packages/tracker/tracker.js
5
9
  */
@@ -135,6 +139,11 @@ declare namespace Tracker {
135
139
  }
136
140
  }
137
141
 
142
+ /**
143
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
144
+ * SPDX-License-Identifier: MIT
145
+ */
146
+
138
147
  type IStateEqual = (a: any, b: any) => boolean;
139
148
  declare class ReactiveBaseState<V> {
140
149
  protected _dep: Tracker.Dependency;
@@ -149,6 +158,11 @@ declare class ReactiveBaseState<V> {
149
158
  set value(newValue: V);
150
159
  }
151
160
 
161
+ /**
162
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
163
+ * SPDX-License-Identifier: MIT
164
+ */
165
+
152
166
  declare class ReactiveState<V extends Record<string, any>> extends ReactiveBaseState<V> {
153
167
  private _keyDeps;
154
168
  set(key: keyof V & string, value: any): boolean;
@@ -163,14 +177,38 @@ declare class ReactiveState<V extends Record<string, any>> extends ReactiveBaseS
163
177
  get readonlyValue(): Readonly<V>;
164
178
  }
165
179
 
180
+ /**
181
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
182
+ * SPDX-License-Identifier: MIT
183
+ */
184
+
166
185
  declare function useReactiveState<T extends Record<string, any>>(v: ReactiveState<T> | T): T;
167
186
 
187
+ /**
188
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
189
+ * SPDX-License-Identifier: MIT
190
+ */
191
+
168
192
  declare function useReadonlyReactiveState<T extends Record<string, any>>(state: ReactiveState<T>): Readonly<T>;
169
193
 
194
+ /**
195
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
196
+ * SPDX-License-Identifier: MIT
197
+ */
170
198
  declare function useObserve<T extends Record<string, any>>(value: T | undefined): T;
171
199
 
200
+ /**
201
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
202
+ * SPDX-License-Identifier: MIT
203
+ */
204
+
172
205
  declare function observe<T = any>(fc: React.FC<T>): React.FC<T>;
173
206
 
207
+ /**
208
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
209
+ * SPDX-License-Identifier: MIT
210
+ */
211
+
174
212
  declare const Dependency: typeof Tracker.Dependency;
175
213
  declare const Computation: typeof Tracker.Computation;
176
214
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import React from 'react';
2
2
 
3
+ /**
4
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
5
+ * SPDX-License-Identifier: MIT
6
+ */
3
7
  /**
4
8
  * Fork from: https://github.com/meteor/meteor/blob/devel/packages/tracker/tracker.js
5
9
  */
@@ -135,6 +139,11 @@ declare namespace Tracker {
135
139
  }
136
140
  }
137
141
 
142
+ /**
143
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
144
+ * SPDX-License-Identifier: MIT
145
+ */
146
+
138
147
  type IStateEqual = (a: any, b: any) => boolean;
139
148
  declare class ReactiveBaseState<V> {
140
149
  protected _dep: Tracker.Dependency;
@@ -149,6 +158,11 @@ declare class ReactiveBaseState<V> {
149
158
  set value(newValue: V);
150
159
  }
151
160
 
161
+ /**
162
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
163
+ * SPDX-License-Identifier: MIT
164
+ */
165
+
152
166
  declare class ReactiveState<V extends Record<string, any>> extends ReactiveBaseState<V> {
153
167
  private _keyDeps;
154
168
  set(key: keyof V & string, value: any): boolean;
@@ -163,14 +177,38 @@ declare class ReactiveState<V extends Record<string, any>> extends ReactiveBaseS
163
177
  get readonlyValue(): Readonly<V>;
164
178
  }
165
179
 
180
+ /**
181
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
182
+ * SPDX-License-Identifier: MIT
183
+ */
184
+
166
185
  declare function useReactiveState<T extends Record<string, any>>(v: ReactiveState<T> | T): T;
167
186
 
187
+ /**
188
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
189
+ * SPDX-License-Identifier: MIT
190
+ */
191
+
168
192
  declare function useReadonlyReactiveState<T extends Record<string, any>>(state: ReactiveState<T>): Readonly<T>;
169
193
 
194
+ /**
195
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
196
+ * SPDX-License-Identifier: MIT
197
+ */
170
198
  declare function useObserve<T extends Record<string, any>>(value: T | undefined): T;
171
199
 
200
+ /**
201
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
202
+ * SPDX-License-Identifier: MIT
203
+ */
204
+
172
205
  declare function observe<T = any>(fc: React.FC<T>): React.FC<T>;
173
206
 
207
+ /**
208
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
209
+ * SPDX-License-Identifier: MIT
210
+ */
211
+
174
212
  declare const Dependency: typeof Tracker.Dependency;
175
213
  declare const Computation: typeof Tracker.Computation;
176
214
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/tracker.ts","../src/core/reactive-base-state.ts","../src/utils/create-proxy.ts","../src/core/reactive-state.ts","../src/hooks/use-reactive-state.ts","../src/hooks/use-observe.ts","../src/hooks/use-readonly-reactive-state.ts","../src/react/observe.tsx"],"sourcesContent":["import { Tracker } from './core/tracker';\n\nexport { Tracker } from './core/tracker';\nexport { ReactiveState } from './core/reactive-state';\nexport { ReactiveBaseState } from './core/reactive-base-state';\nexport { useReactiveState } from './hooks/use-reactive-state';\nexport { useReadonlyReactiveState } from './hooks/use-readonly-reactive-state';\nexport { useObserve } from './hooks/use-observe';\nexport { observe } from './react/observe';\nexport const { Dependency, Computation } = Tracker;\n","/**\n * Fork from: https://github.com/meteor/meteor/blob/devel/packages/tracker/tracker.js\n */\ntype ICallback<ARG = void, RET = void> = (arg: ARG) => RET;\n\n/**\n * Tracker 是一套 响应式依赖追踪 库,来源于 Meteor.Tracker\n * https://docs.meteor.com/api/Tracker.html#tracker-autorun-and-async-callbacks\n * https://github.com/meteor/meteor/blob/devel/packages/tracker/tracker.js\n *\n * 相关论文:https://dl.acm.org/doi/fullHtml/10.1145/3184558.3185978\n */\nexport namespace Tracker {\n const _pendingComputations: Computation[] = [];\n const _afterFlushCallbacks: ICallback[] = [];\n // `true` if a Tracker.flush is scheduled, or if we are in Tracker.flush now\n let _willFlush = false;\n // `true` if we are in Tracker.flush now\n let _inFlush = false;\n // `true` if we are computing a computation now, either first time\n // or recompute. This matches Tracker.active unless we are inside\n // Tracker.nonreactive, which nullfies currentComputation even though\n // an enclosing computation may still be running.\n let _inCompute = false;\n let _currentComputation: Computation | undefined = undefined;\n // `true` if the `_throwFirstError` option was passed in to the call\n // to Tracker.flush that we are in. When set, throw rather than log the\n // first error encountered while flushing. Before throwing the error,\n // finish flushing (from a finally block), logging any subsequent\n // errors.\n let _throwFirstError = false;\n\n export interface FlushOptions {\n finishSynchronously?: boolean;\n throwFirstError?: boolean;\n }\n\n function _throwOrLog(msg: string, e: any) {\n if (_throwFirstError) {\n throw e;\n } else {\n console.error(`[Tracker error] ${msg}`, e);\n }\n }\n\n // Run all pending computations and afterFlush callbacks. If we were not called\n // directly via Tracker.flush, this may return before they're all done to allow\n // the event loop to run a little before continuing.\n function _runFlush(options?: FlushOptions) {\n // Nested flush could plausibly happen if, say, a flush causes\n // DOM mutation, which causes a \"blur\" event, which runs an\n // app event handler that calls Tracker.flush. At the moment\n // Spark blocks event handlers during DOM mutation anyway,\n // because the LiveRange tree isn't valid. And we don't have\n // any useful notion of a nested flush.\n if (inFlush()) throw new Error(\"Can't call Tracker.flush while flushing\");\n\n if (_inCompute) throw new Error(\"Can't flush inside Tracker.autorun\");\n\n options = options || {};\n\n _inFlush = true;\n _willFlush = true;\n _throwFirstError = !!options.throwFirstError;\n\n var recomputedCount = 0;\n var finishedTry = false;\n try {\n while (_pendingComputations.length || _afterFlushCallbacks.length) {\n // recompute all pending computations\n while (_pendingComputations.length) {\n var comp = _pendingComputations.shift()!;\n comp._recompute();\n if (comp._needsRecompute()) {\n _pendingComputations.unshift(comp);\n }\n\n if (!options.finishSynchronously && ++recomputedCount > 100) {\n finishedTry = true;\n return;\n }\n }\n\n if (_afterFlushCallbacks.length) {\n // call one afterFlush callback, which may\n // invalidate more computations\n var func = _afterFlushCallbacks.shift()!;\n try {\n func();\n } catch (e: any) {\n _throwOrLog('afterFlush', e);\n }\n }\n }\n finishedTry = true;\n } finally {\n if (!finishedTry) {\n // we're erroring due to throwFirstError being true.\n _inFlush = false; // needed before calling `Tracker.flush()` again\n // finish flushing\n _runFlush({\n finishSynchronously: options.finishSynchronously,\n throwFirstError: false,\n });\n }\n _willFlush = false;\n _inFlush = false;\n if (_pendingComputations.length || _afterFlushCallbacks.length) {\n // We're yielding because we ran a bunch of computations and we aren't\n // required to finish synchronously, so we'd like to give the event loop a\n // chance. We should flush again soon.\n if (options.finishSynchronously) {\n throw new Error('still have more to do?'); // shouldn't happen\n }\n setTimeout(_requireFlush, 10);\n }\n }\n }\n\n function _requireFlush() {\n if (!_willFlush) {\n setTimeout(_runFlush, 0);\n _willFlush = true;\n }\n }\n\n /******************************** Tracker Base API ******************************************/\n\n /**\n * 函数在响应式模块中执行\n * @param computation\n * @param f\n */\n export function withComputation<T = any>(\n computation: Computation,\n f: ICallback<Computation, T>,\n ): T {\n let previousComputation = _currentComputation;\n _currentComputation = computation;\n try {\n return f.call(null, computation);\n } finally {\n _currentComputation = previousComputation;\n }\n }\n\n /**\n * 函数在非响应式模块中执行\n */\n export function withoutComputation<T = any>(f: ICallback<undefined, T>): T {\n let previousComputation = _currentComputation;\n _currentComputation = undefined;\n try {\n return f(undefined);\n } finally {\n _currentComputation = previousComputation;\n }\n }\n\n export function isActive(): boolean {\n return !!_currentComputation;\n }\n\n export function getCurrentComputation(): Computation | undefined {\n return _currentComputation;\n }\n\n /**\n * Run a function now and rerun it later whenever its dependencies\n * change. Returns a Computation object that can be used to stop or observe the\n * rerunning.\n */\n export function autorun<T = any>(\n f: IComputationCallback<T>,\n options?: { onError: ICallback<Error> },\n ): Computation<T> {\n var c = new Computation<T>(f, _currentComputation, options?.onError);\n\n if (isActive())\n Tracker.onInvalidate(function () {\n c.stop();\n });\n\n return c;\n }\n\n export function onInvalidate(f: ICallback<Computation | undefined>) {\n if (!_currentComputation) {\n throw new Error('Tracker.onInvalidate requires a currentComputation');\n }\n _currentComputation.onInvalidate(f);\n }\n\n /**\n * True if we are computing a computation now, either first time or recompute. This matches Tracker.active unless we are inside Tracker.nonreactive, which nullfies currentComputation even though an enclosing computation may still be running.\n */\n export function inFlush(): boolean {\n return _inFlush;\n }\n\n /**\n * Process all reactive updates immediately and ensure that all invalidated computations are rerun.\n */\n export function flush(options?: Omit<FlushOptions, 'finishSynchronously'>) {\n _runFlush({\n finishSynchronously: true,\n throwFirstError: options && options.throwFirstError,\n });\n }\n\n /**\n * Schedules a function to be called during the next flush, or later in the current flush if one is in progress, after all invalidated computations have been rerun. The function will be run once and not on subsequent flushes unless `afterFlush` is called again.\n */\n export function afterFlush(f: ICallback) {\n _afterFlushCallbacks.push(f);\n _requireFlush();\n }\n\n /********************************************************************************************/\n\n export type IComputationCallback<V = any> = ICallback<Computation, V>;\n\n /**\n * A Computation object represents code that is repeatedly rerun\n * in response to\n * reactive data changes. Computations don't have return values; they just\n * perform actions, such as rerendering a template on the screen. Computations\n * are created using Tracker.autorun. Use stop to prevent further rerunning of a\n * computation.\n */\n export class Computation<V = any> {\n private _onInvalidateCallbacks: IComputationCallback[] = [];\n\n private _onStopCallbacks: IComputationCallback[] = [];\n\n private _recomputing = false;\n\n private _result: V;\n\n /**\n * 是否停止\n */\n public stopped = false;\n\n /**\n * 未开始执行则返回 false\n */\n public invalidated = false;\n\n /**\n * 是否第一次执行\n */\n public firstRun = true;\n\n constructor(\n private _fn: IComputationCallback<V>,\n public readonly parent?: Computation,\n private readonly _onError?: ICallback<Error>,\n ) {\n let hasError = true;\n try {\n this._compute();\n hasError = false;\n } finally {\n this.firstRun = false;\n if (hasError) {\n this.stop();\n }\n }\n }\n\n onInvalidate(f: IComputationCallback): void {\n if (this.invalidated) {\n withoutComputation(f.bind(null, this));\n } else {\n this._onInvalidateCallbacks.push(f);\n }\n }\n\n /**\n * @summary Invalidates this computation so that it will be rerun.\n */\n invalidate() {\n if (!this.invalidated) {\n // if we're currently in _recompute(), don't enqueue\n // ourselves, since we'll rerun immediately anyway.\n if (!this._recomputing && !this.stopped) {\n _requireFlush();\n _pendingComputations.push(this);\n }\n\n this.invalidated = true;\n\n // callbacks can't add callbacks, because\n // this.invalidated === true.\n for (var i = 0, f: IComputationCallback; (f = this._onInvalidateCallbacks[i]); i++) {\n withoutComputation(f.bind(null, this));\n }\n this._onInvalidateCallbacks = [];\n }\n }\n\n /**\n * @summary Prevents this computation from rerunning.\n * @locus Client\n */\n stop() {\n if (!this.stopped) {\n this.stopped = true;\n this.invalidate();\n for (let i = 0, f: IComputationCallback; (f = this._onStopCallbacks[i]); i++) {\n withoutComputation(f.bind(null, this));\n }\n this._onStopCallbacks = [];\n }\n }\n\n onStop(f: IComputationCallback): void {\n if (this.stopped) {\n withoutComputation(f.bind(null, this));\n } else {\n this._onStopCallbacks.push(f);\n }\n }\n\n private _compute(): void {\n this.invalidated = false;\n\n var previousInCompute = _inCompute;\n _inCompute = true;\n try {\n this._result = Tracker.withComputation<V>(this, this._fn);\n } finally {\n _inCompute = previousInCompute;\n }\n }\n\n _needsRecompute() {\n return this.invalidated && !this.stopped;\n }\n\n _recompute() {\n this._recomputing = true;\n try {\n if (this._needsRecompute()) {\n try {\n this._compute();\n } catch (e: any) {\n if (this._onError) {\n this._onError(e);\n } else {\n _throwOrLog('recompute', e);\n }\n }\n }\n } finally {\n this._recomputing = false;\n }\n }\n\n /**\n * @summary Process the reactive updates for this computation immediately\n * and ensure that the computation is rerun. The computation is rerun only\n * if it is invalidated.\n */\n flush() {\n if (this._recomputing) return;\n\n this._recompute();\n }\n\n /**\n * @summary Causes the function inside this computation to run and\n * synchronously process all reactive updtes.\n * @locus Client\n */\n run() {\n this.invalidate();\n this.flush();\n }\n\n get result(): V {\n return this._result;\n }\n }\n\n /**\n * A Dependency represents an atomic unit of reactive data that a\n * computation might depend on. Reactive data sources such as Session or\n * Minimongo internally create different Dependency objects for different\n * pieces of data, each of which may be depended on by multiple computations.\n * When the data changes, the computations are invalidated.\n */\n export class Dependency {\n private _dependents: Set<Computation> = new Set<Computation>();\n\n /**\n * Declares that the current computation (or `fromComputation` if given) depends on `dependency`. The computation will be invalidated the next time `dependency` changes.\n * If there is no current computation and `depend()` is called with no arguments, it does nothing and returns false.\n * Returns true if the computation is a new dependent of `dependency` rather than an existing one.\n */\n depend(computation?: Computation): boolean {\n if (!computation) {\n if (!isActive()) {\n return false;\n }\n computation = _currentComputation;\n }\n if (!this._dependents.has(computation!)) {\n this._dependents.add(computation!);\n computation!.onInvalidate(() => {\n this._dependents.delete(computation!);\n });\n return true;\n }\n return false;\n }\n\n /**\n * Invalidate all dependent computations immediately and remove them as dependents.\n */\n changed() {\n for (const dep of this._dependents) {\n dep.invalidate();\n }\n }\n\n /**\n * True if this Dependency has one or more dependent Computations, which would be invalidated if this Dependency were to change.\n */\n hasDependents() {\n return this._dependents.size !== 0;\n }\n }\n}\n","import { Tracker } from './tracker';\n\ntype IStateEqual = (a: any, b: any) => boolean;\n\nexport class ReactiveBaseState<V> {\n protected _dep = new Tracker.Dependency();\n\n protected _value: V;\n\n protected _isEqual: IStateEqual = (a: any, b: any) => a == b;\n\n protected _addDepend(dep: Tracker.Dependency): void {\n if (Tracker.isActive()) {\n dep.depend();\n }\n }\n\n constructor(initialValue: V, opts?: { isEqual?: IStateEqual }) {\n this._value = initialValue;\n if (opts?.isEqual) {\n this._isEqual = opts.isEqual;\n }\n }\n\n hasDependents(): boolean {\n return this._dep.hasDependents();\n }\n\n get value(): V {\n this._addDepend(this._dep);\n return this._value;\n }\n\n set value(newValue: V) {\n if (!this._isEqual(this._value, newValue)) {\n this._value = newValue;\n this._dep.changed();\n }\n }\n}\n","interface ProxyOptions<V> {\n get?: (target: V, key: string) => any;\n set?: (target: V, key: string, newValue: any) => boolean;\n}\n\nexport function createProxy<V extends Record<string, any>>(target: V, opts: ProxyOptions<V>): V {\n let useProxy = 'Proxy' in window;\n if (process.env.NODE_ENV === 'test') {\n if ((global as any).__ignoreProxy) {\n useProxy = false;\n }\n }\n if (useProxy) {\n return new Proxy<V>(target, opts);\n }\n const result: V = {} as V;\n for (const key in target) {\n Object.defineProperty(result, key, {\n enumerable: true,\n get: opts.get ? () => opts.get!(target, key) : undefined,\n set: opts.set ? (newValue: any) => opts.set!(target, key, newValue) : undefined,\n });\n }\n return result;\n}\n","import { Tracker } from './tracker';\n\nimport Dependency = Tracker.Dependency;\n\nimport { ReactiveBaseState } from './reactive-base-state';\nimport { createProxy } from '../utils/create-proxy';\n\nexport class ReactiveState<V extends Record<string, any>> extends ReactiveBaseState<V> {\n private _keyDeps: Map<string, Dependency> = new Map();\n\n set(key: keyof V & string, value: any): boolean {\n this._ensureKey(key);\n const oldValue = this._value[key];\n if (!this._isEqual(oldValue, value)) {\n this._value[key] = value;\n this._keyDeps.get(key)!.changed();\n return true;\n }\n return false;\n }\n\n get(key: keyof V & string) {\n this._ensureKey(key);\n this._addDepend(this._keyDeps.get(key)!);\n return this._value[key];\n }\n\n protected _ensureKey(key: keyof V & string) {\n if (!this._keyDeps.has(key)) {\n this._keyDeps.set(key, new Dependency());\n }\n }\n\n hasDependents(): boolean {\n if (this._dep.hasDependents()) return true;\n for (const dep of this._keyDeps.values()) {\n if (dep.hasDependents()) return true;\n }\n return false;\n }\n\n keys(): string[] {\n return Object.keys(this._value);\n }\n\n set value(newValue: V) {\n if (!this._isEqual(this._value, newValue)) {\n this._value = newValue;\n this._keyDeps.clear();\n this._dep.changed();\n }\n }\n\n private _proxyValue: V;\n\n get value(): V {\n this._addDepend(this._dep);\n if (!this._proxyValue) {\n this._proxyValue = createProxy<V>(this._value, {\n get: (target, key: string) => this.get(key),\n set: (target, key: string, newValue) => {\n this.set(key, newValue);\n return true;\n },\n });\n }\n return this._proxyValue;\n }\n\n private _proxyReadonlyValue: V;\n\n get readonlyValue(): Readonly<V> {\n this._addDepend(this._dep);\n if (!this._proxyReadonlyValue) {\n this._proxyReadonlyValue = createProxy(this._value, {\n get: (target, key: string) => this.get(key),\n set: (newValue, key: string) => {\n throw new Error(`[ReactiveState] Cannnot set readonly field \"${key}\"`);\n },\n });\n }\n return this._proxyReadonlyValue;\n }\n}\n","import { useMemo } from 'react';\n\nimport { ReactiveState } from '../core/reactive-state';\nimport { useObserve } from './use-observe';\n\nexport function useReactiveState<T extends Record<string, any>>(v: ReactiveState<T> | T): T {\n const state = useMemo<ReactiveState<T>>(\n () => (v instanceof ReactiveState ? v : new ReactiveState(v)),\n [],\n );\n return useObserve<T>(state.value);\n}\n","import { useCallback, useEffect, useMemo } from 'react';\n\nimport { useRefresh } from '@flowgram.ai/utils';\n\nimport { createProxy } from '../utils/create-proxy';\nimport { Tracker } from '../core/tracker';\n\nimport Computation = Tracker.Computation;\n\nexport function useObserve<T extends Record<string, any>>(value: T | undefined): T {\n const refresh = useRefresh();\n const computationMap = useMemo<Map<string, Computation>>(() => new Map(), []);\n const clear = useCallback(() => {\n computationMap.forEach((comp) => comp.stop());\n computationMap.clear();\n }, []);\n useEffect(() => clear, []);\n // 重新渲染需要清空依赖\n clear();\n return useMemo(() => {\n if (value === undefined) return {} as T;\n return createProxy(value, {\n get(target, key: string) {\n let computation = computationMap.get(key);\n if (!computation) {\n computation = new Tracker.Computation((c) => {\n if (!c.firstRun) {\n refresh();\n return;\n }\n return value[key];\n });\n computationMap.set(key, computation);\n }\n return value[key];\n },\n });\n }, [value]);\n}\n","import { ReactiveState } from '../core/reactive-state';\nimport { useObserve } from './use-observe';\n\nexport function useReadonlyReactiveState<T extends Record<string, any>>(\n state: ReactiveState<T>,\n): Readonly<T> {\n return useObserve<T>(state.readonlyValue);\n}\n","import React, { useRef, useEffect } from 'react';\n\nimport { useRefresh } from '@flowgram.ai/utils';\n\nimport { Tracker } from '../core/tracker';\n\nimport Computation = Tracker.Computation;\n\nexport function observe<T = any>(fc: React.FC<T>): React.FC<T> {\n return function ReactiveObserver(props: T) {\n const childrenRef = useRef<React.ReactElement<any, any> | null>();\n const computationRef = useRef<Computation | undefined>();\n const refresh = useRefresh();\n computationRef.current?.stop();\n computationRef.current = new Tracker.Computation(c => {\n if (c.firstRun) {\n childrenRef.current = fc(props);\n } else {\n refresh();\n }\n });\n useEffect(\n () => () => {\n computationRef.current?.stop();\n },\n [],\n );\n return childrenRef.current!;\n };\n}\n"],"mappings":"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","names":["Dependency","Tracker","Computation","Dependency","import_react","import_react","import_utils","Dependency"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/tracker.ts","../src/core/reactive-base-state.ts","../src/utils/create-proxy.ts","../src/core/reactive-state.ts","../src/hooks/use-reactive-state.ts","../src/hooks/use-observe.ts","../src/hooks/use-readonly-reactive-state.ts","../src/react/observe.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Tracker } from './core/tracker';\n\nexport { Tracker } from './core/tracker';\nexport { ReactiveState } from './core/reactive-state';\nexport { ReactiveBaseState } from './core/reactive-base-state';\nexport { useReactiveState } from './hooks/use-reactive-state';\nexport { useReadonlyReactiveState } from './hooks/use-readonly-reactive-state';\nexport { useObserve } from './hooks/use-observe';\nexport { observe } from './react/observe';\nexport const { Dependency, Computation } = Tracker;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\n/**\n * Fork from: https://github.com/meteor/meteor/blob/devel/packages/tracker/tracker.js\n */\ntype ICallback<ARG = void, RET = void> = (arg: ARG) => RET;\n\n/**\n * Tracker 是一套 响应式依赖追踪 库,来源于 Meteor.Tracker\n * https://docs.meteor.com/api/Tracker.html#tracker-autorun-and-async-callbacks\n * https://github.com/meteor/meteor/blob/devel/packages/tracker/tracker.js\n *\n * 相关论文:https://dl.acm.org/doi/fullHtml/10.1145/3184558.3185978\n */\nexport namespace Tracker {\n const _pendingComputations: Computation[] = [];\n const _afterFlushCallbacks: ICallback[] = [];\n // `true` if a Tracker.flush is scheduled, or if we are in Tracker.flush now\n let _willFlush = false;\n // `true` if we are in Tracker.flush now\n let _inFlush = false;\n // `true` if we are computing a computation now, either first time\n // or recompute. This matches Tracker.active unless we are inside\n // Tracker.nonreactive, which nullfies currentComputation even though\n // an enclosing computation may still be running.\n let _inCompute = false;\n let _currentComputation: Computation | undefined = undefined;\n // `true` if the `_throwFirstError` option was passed in to the call\n // to Tracker.flush that we are in. When set, throw rather than log the\n // first error encountered while flushing. Before throwing the error,\n // finish flushing (from a finally block), logging any subsequent\n // errors.\n let _throwFirstError = false;\n\n export interface FlushOptions {\n finishSynchronously?: boolean;\n throwFirstError?: boolean;\n }\n\n function _throwOrLog(msg: string, e: any) {\n if (_throwFirstError) {\n throw e;\n } else {\n console.error(`[Tracker error] ${msg}`, e);\n }\n }\n\n // Run all pending computations and afterFlush callbacks. If we were not called\n // directly via Tracker.flush, this may return before they're all done to allow\n // the event loop to run a little before continuing.\n function _runFlush(options?: FlushOptions) {\n // Nested flush could plausibly happen if, say, a flush causes\n // DOM mutation, which causes a \"blur\" event, which runs an\n // app event handler that calls Tracker.flush. At the moment\n // Spark blocks event handlers during DOM mutation anyway,\n // because the LiveRange tree isn't valid. And we don't have\n // any useful notion of a nested flush.\n if (inFlush()) throw new Error(\"Can't call Tracker.flush while flushing\");\n\n if (_inCompute) throw new Error(\"Can't flush inside Tracker.autorun\");\n\n options = options || {};\n\n _inFlush = true;\n _willFlush = true;\n _throwFirstError = !!options.throwFirstError;\n\n var recomputedCount = 0;\n var finishedTry = false;\n try {\n while (_pendingComputations.length || _afterFlushCallbacks.length) {\n // recompute all pending computations\n while (_pendingComputations.length) {\n var comp = _pendingComputations.shift()!;\n comp._recompute();\n if (comp._needsRecompute()) {\n _pendingComputations.unshift(comp);\n }\n\n if (!options.finishSynchronously && ++recomputedCount > 100) {\n finishedTry = true;\n return;\n }\n }\n\n if (_afterFlushCallbacks.length) {\n // call one afterFlush callback, which may\n // invalidate more computations\n var func = _afterFlushCallbacks.shift()!;\n try {\n func();\n } catch (e: any) {\n _throwOrLog('afterFlush', e);\n }\n }\n }\n finishedTry = true;\n } finally {\n if (!finishedTry) {\n // we're erroring due to throwFirstError being true.\n _inFlush = false; // needed before calling `Tracker.flush()` again\n // finish flushing\n _runFlush({\n finishSynchronously: options.finishSynchronously,\n throwFirstError: false,\n });\n }\n _willFlush = false;\n _inFlush = false;\n if (_pendingComputations.length || _afterFlushCallbacks.length) {\n // We're yielding because we ran a bunch of computations and we aren't\n // required to finish synchronously, so we'd like to give the event loop a\n // chance. We should flush again soon.\n if (options.finishSynchronously) {\n throw new Error('still have more to do?'); // shouldn't happen\n }\n setTimeout(_requireFlush, 10);\n }\n }\n }\n\n function _requireFlush() {\n if (!_willFlush) {\n setTimeout(_runFlush, 0);\n _willFlush = true;\n }\n }\n\n /******************************** Tracker Base API ******************************************/\n\n /**\n * 函数在响应式模块中执行\n * @param computation\n * @param f\n */\n export function withComputation<T = any>(\n computation: Computation,\n f: ICallback<Computation, T>,\n ): T {\n let previousComputation = _currentComputation;\n _currentComputation = computation;\n try {\n return f.call(null, computation);\n } finally {\n _currentComputation = previousComputation;\n }\n }\n\n /**\n * 函数在非响应式模块中执行\n */\n export function withoutComputation<T = any>(f: ICallback<undefined, T>): T {\n let previousComputation = _currentComputation;\n _currentComputation = undefined;\n try {\n return f(undefined);\n } finally {\n _currentComputation = previousComputation;\n }\n }\n\n export function isActive(): boolean {\n return !!_currentComputation;\n }\n\n export function getCurrentComputation(): Computation | undefined {\n return _currentComputation;\n }\n\n /**\n * Run a function now and rerun it later whenever its dependencies\n * change. Returns a Computation object that can be used to stop or observe the\n * rerunning.\n */\n export function autorun<T = any>(\n f: IComputationCallback<T>,\n options?: { onError: ICallback<Error> },\n ): Computation<T> {\n var c = new Computation<T>(f, _currentComputation, options?.onError);\n\n if (isActive())\n Tracker.onInvalidate(function () {\n c.stop();\n });\n\n return c;\n }\n\n export function onInvalidate(f: ICallback<Computation | undefined>) {\n if (!_currentComputation) {\n throw new Error('Tracker.onInvalidate requires a currentComputation');\n }\n _currentComputation.onInvalidate(f);\n }\n\n /**\n * True if we are computing a computation now, either first time or recompute. This matches Tracker.active unless we are inside Tracker.nonreactive, which nullfies currentComputation even though an enclosing computation may still be running.\n */\n export function inFlush(): boolean {\n return _inFlush;\n }\n\n /**\n * Process all reactive updates immediately and ensure that all invalidated computations are rerun.\n */\n export function flush(options?: Omit<FlushOptions, 'finishSynchronously'>) {\n _runFlush({\n finishSynchronously: true,\n throwFirstError: options && options.throwFirstError,\n });\n }\n\n /**\n * Schedules a function to be called during the next flush, or later in the current flush if one is in progress, after all invalidated computations have been rerun. The function will be run once and not on subsequent flushes unless `afterFlush` is called again.\n */\n export function afterFlush(f: ICallback) {\n _afterFlushCallbacks.push(f);\n _requireFlush();\n }\n\n /********************************************************************************************/\n\n export type IComputationCallback<V = any> = ICallback<Computation, V>;\n\n /**\n * A Computation object represents code that is repeatedly rerun\n * in response to\n * reactive data changes. Computations don't have return values; they just\n * perform actions, such as rerendering a template on the screen. Computations\n * are created using Tracker.autorun. Use stop to prevent further rerunning of a\n * computation.\n */\n export class Computation<V = any> {\n private _onInvalidateCallbacks: IComputationCallback[] = [];\n\n private _onStopCallbacks: IComputationCallback[] = [];\n\n private _recomputing = false;\n\n private _result: V;\n\n /**\n * 是否停止\n */\n public stopped = false;\n\n /**\n * 未开始执行则返回 false\n */\n public invalidated = false;\n\n /**\n * 是否第一次执行\n */\n public firstRun = true;\n\n constructor(\n private _fn: IComputationCallback<V>,\n public readonly parent?: Computation,\n private readonly _onError?: ICallback<Error>,\n ) {\n let hasError = true;\n try {\n this._compute();\n hasError = false;\n } finally {\n this.firstRun = false;\n if (hasError) {\n this.stop();\n }\n }\n }\n\n onInvalidate(f: IComputationCallback): void {\n if (this.invalidated) {\n withoutComputation(f.bind(null, this));\n } else {\n this._onInvalidateCallbacks.push(f);\n }\n }\n\n /**\n * @summary Invalidates this computation so that it will be rerun.\n */\n invalidate() {\n if (!this.invalidated) {\n // if we're currently in _recompute(), don't enqueue\n // ourselves, since we'll rerun immediately anyway.\n if (!this._recomputing && !this.stopped) {\n _requireFlush();\n _pendingComputations.push(this);\n }\n\n this.invalidated = true;\n\n // callbacks can't add callbacks, because\n // this.invalidated === true.\n for (var i = 0, f: IComputationCallback; (f = this._onInvalidateCallbacks[i]); i++) {\n withoutComputation(f.bind(null, this));\n }\n this._onInvalidateCallbacks = [];\n }\n }\n\n /**\n * @summary Prevents this computation from rerunning.\n * @locus Client\n */\n stop() {\n if (!this.stopped) {\n this.stopped = true;\n this.invalidate();\n for (let i = 0, f: IComputationCallback; (f = this._onStopCallbacks[i]); i++) {\n withoutComputation(f.bind(null, this));\n }\n this._onStopCallbacks = [];\n }\n }\n\n onStop(f: IComputationCallback): void {\n if (this.stopped) {\n withoutComputation(f.bind(null, this));\n } else {\n this._onStopCallbacks.push(f);\n }\n }\n\n private _compute(): void {\n this.invalidated = false;\n\n var previousInCompute = _inCompute;\n _inCompute = true;\n try {\n this._result = Tracker.withComputation<V>(this, this._fn);\n } finally {\n _inCompute = previousInCompute;\n }\n }\n\n _needsRecompute() {\n return this.invalidated && !this.stopped;\n }\n\n _recompute() {\n this._recomputing = true;\n try {\n if (this._needsRecompute()) {\n try {\n this._compute();\n } catch (e: any) {\n if (this._onError) {\n this._onError(e);\n } else {\n _throwOrLog('recompute', e);\n }\n }\n }\n } finally {\n this._recomputing = false;\n }\n }\n\n /**\n * @summary Process the reactive updates for this computation immediately\n * and ensure that the computation is rerun. The computation is rerun only\n * if it is invalidated.\n */\n flush() {\n if (this._recomputing) return;\n\n this._recompute();\n }\n\n /**\n * @summary Causes the function inside this computation to run and\n * synchronously process all reactive updtes.\n * @locus Client\n */\n run() {\n this.invalidate();\n this.flush();\n }\n\n get result(): V {\n return this._result;\n }\n }\n\n /**\n * A Dependency represents an atomic unit of reactive data that a\n * computation might depend on. Reactive data sources such as Session or\n * Minimongo internally create different Dependency objects for different\n * pieces of data, each of which may be depended on by multiple computations.\n * When the data changes, the computations are invalidated.\n */\n export class Dependency {\n private _dependents: Set<Computation> = new Set<Computation>();\n\n /**\n * Declares that the current computation (or `fromComputation` if given) depends on `dependency`. The computation will be invalidated the next time `dependency` changes.\n * If there is no current computation and `depend()` is called with no arguments, it does nothing and returns false.\n * Returns true if the computation is a new dependent of `dependency` rather than an existing one.\n */\n depend(computation?: Computation): boolean {\n if (!computation) {\n if (!isActive()) {\n return false;\n }\n computation = _currentComputation;\n }\n if (!this._dependents.has(computation!)) {\n this._dependents.add(computation!);\n computation!.onInvalidate(() => {\n this._dependents.delete(computation!);\n });\n return true;\n }\n return false;\n }\n\n /**\n * Invalidate all dependent computations immediately and remove them as dependents.\n */\n changed() {\n for (const dep of this._dependents) {\n dep.invalidate();\n }\n }\n\n /**\n * True if this Dependency has one or more dependent Computations, which would be invalidated if this Dependency were to change.\n */\n hasDependents() {\n return this._dependents.size !== 0;\n }\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Tracker } from './tracker';\n\ntype IStateEqual = (a: any, b: any) => boolean;\n\nexport class ReactiveBaseState<V> {\n protected _dep = new Tracker.Dependency();\n\n protected _value: V;\n\n protected _isEqual: IStateEqual = (a: any, b: any) => a == b;\n\n protected _addDepend(dep: Tracker.Dependency): void {\n if (Tracker.isActive()) {\n dep.depend();\n }\n }\n\n constructor(initialValue: V, opts?: { isEqual?: IStateEqual }) {\n this._value = initialValue;\n if (opts?.isEqual) {\n this._isEqual = opts.isEqual;\n }\n }\n\n hasDependents(): boolean {\n return this._dep.hasDependents();\n }\n\n get value(): V {\n this._addDepend(this._dep);\n return this._value;\n }\n\n set value(newValue: V) {\n if (!this._isEqual(this._value, newValue)) {\n this._value = newValue;\n this._dep.changed();\n }\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\ninterface ProxyOptions<V> {\n get?: (target: V, key: string) => any;\n set?: (target: V, key: string, newValue: any) => boolean;\n}\n\nexport function createProxy<V extends Record<string, any>>(target: V, opts: ProxyOptions<V>): V {\n let useProxy = 'Proxy' in window;\n if (process.env.NODE_ENV === 'test') {\n if ((global as any).__ignoreProxy) {\n useProxy = false;\n }\n }\n if (useProxy) {\n return new Proxy<V>(target, opts);\n }\n const result: V = {} as V;\n for (const key in target) {\n Object.defineProperty(result, key, {\n enumerable: true,\n get: opts.get ? () => opts.get!(target, key) : undefined,\n set: opts.set ? (newValue: any) => opts.set!(target, key, newValue) : undefined,\n });\n }\n return result;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Tracker } from './tracker';\n\nimport Dependency = Tracker.Dependency;\n\nimport { ReactiveBaseState } from './reactive-base-state';\nimport { createProxy } from '../utils/create-proxy';\n\nexport class ReactiveState<V extends Record<string, any>> extends ReactiveBaseState<V> {\n private _keyDeps: Map<string, Dependency> = new Map();\n\n set(key: keyof V & string, value: any): boolean {\n this._ensureKey(key);\n const oldValue = this._value[key];\n if (!this._isEqual(oldValue, value)) {\n this._value[key] = value;\n this._keyDeps.get(key)!.changed();\n return true;\n }\n return false;\n }\n\n get(key: keyof V & string) {\n this._ensureKey(key);\n this._addDepend(this._keyDeps.get(key)!);\n return this._value[key];\n }\n\n protected _ensureKey(key: keyof V & string) {\n if (!this._keyDeps.has(key)) {\n this._keyDeps.set(key, new Dependency());\n }\n }\n\n hasDependents(): boolean {\n if (this._dep.hasDependents()) return true;\n for (const dep of this._keyDeps.values()) {\n if (dep.hasDependents()) return true;\n }\n return false;\n }\n\n keys(): string[] {\n return Object.keys(this._value);\n }\n\n set value(newValue: V) {\n if (!this._isEqual(this._value, newValue)) {\n this._value = newValue;\n this._keyDeps.clear();\n this._dep.changed();\n }\n }\n\n private _proxyValue: V;\n\n get value(): V {\n this._addDepend(this._dep);\n if (!this._proxyValue) {\n this._proxyValue = createProxy<V>(this._value, {\n get: (target, key: string) => this.get(key),\n set: (target, key: string, newValue) => {\n this.set(key, newValue);\n return true;\n },\n });\n }\n return this._proxyValue;\n }\n\n private _proxyReadonlyValue: V;\n\n get readonlyValue(): Readonly<V> {\n this._addDepend(this._dep);\n if (!this._proxyReadonlyValue) {\n this._proxyReadonlyValue = createProxy(this._value, {\n get: (target, key: string) => this.get(key),\n set: (newValue, key: string) => {\n throw new Error(`[ReactiveState] Cannnot set readonly field \"${key}\"`);\n },\n });\n }\n return this._proxyReadonlyValue;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useMemo } from 'react';\n\nimport { ReactiveState } from '../core/reactive-state';\nimport { useObserve } from './use-observe';\n\nexport function useReactiveState<T extends Record<string, any>>(v: ReactiveState<T> | T): T {\n const state = useMemo<ReactiveState<T>>(\n () => (v instanceof ReactiveState ? v : new ReactiveState(v)),\n [],\n );\n return useObserve<T>(state.value);\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useCallback, useEffect, useMemo } from 'react';\n\nimport { useRefresh } from '@flowgram.ai/utils';\n\nimport { createProxy } from '../utils/create-proxy';\nimport { Tracker } from '../core/tracker';\n\nimport Computation = Tracker.Computation;\n\nexport function useObserve<T extends Record<string, any>>(value: T | undefined): T {\n const refresh = useRefresh();\n const computationMap = useMemo<Map<string, Computation>>(() => new Map(), []);\n const clear = useCallback(() => {\n computationMap.forEach((comp) => comp.stop());\n computationMap.clear();\n }, []);\n useEffect(() => clear, []);\n // 重新渲染需要清空依赖\n clear();\n return useMemo(() => {\n if (value === undefined) return {} as T;\n return createProxy(value, {\n get(target, key: string) {\n let computation = computationMap.get(key);\n if (!computation) {\n computation = new Tracker.Computation((c) => {\n if (!c.firstRun) {\n refresh();\n return;\n }\n return value[key];\n });\n computationMap.set(key, computation);\n }\n return value[key];\n },\n });\n }, [value]);\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { ReactiveState } from '../core/reactive-state';\nimport { useObserve } from './use-observe';\n\nexport function useReadonlyReactiveState<T extends Record<string, any>>(\n state: ReactiveState<T>,\n): Readonly<T> {\n return useObserve<T>(state.readonlyValue);\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React, { useRef, useEffect } from 'react';\n\nimport { useRefresh } from '@flowgram.ai/utils';\n\nimport { Tracker } from '../core/tracker';\n\nimport Computation = Tracker.Computation;\n\nexport function observe<T = any>(fc: React.FC<T>): React.FC<T> {\n return function ReactiveObserver(props: T) {\n const childrenRef = useRef<React.ReactElement<any, any> | null>();\n const computationRef = useRef<Computation | undefined>();\n const refresh = useRefresh();\n computationRef.current?.stop();\n computationRef.current = new Tracker.Computation(c => {\n if (c.firstRun) {\n childrenRef.current = fc(props);\n } else {\n refresh();\n }\n });\n useEffect(\n () => () => {\n computationRef.current?.stop();\n },\n [],\n );\n return childrenRef.current!;\n };\n}\n"],"mappings":"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","names":["Dependency","Tracker","Computation","Dependency","import_react","import_react","import_utils","Dependency"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowgram.ai/reactive",
3
- "version": "0.2.16",
3
+ "version": "0.2.17",
4
4
  "homepage": "https://flowgram.ai/",
5
5
  "repository": "https://github.com/bytedance/flowgram.ai",
6
6
  "license": "MIT",
@@ -16,7 +16,7 @@
16
16
  "dist"
17
17
  ],
18
18
  "dependencies": {
19
- "@flowgram.ai/utils": "0.2.16"
19
+ "@flowgram.ai/utils": "0.2.17"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@testing-library/react": "^12",
@@ -31,8 +31,8 @@
31
31
  "tsup": "^8.0.1",
32
32
  "typescript": "^5.0.4",
33
33
  "vitest": "^0.34.6",
34
- "@flowgram.ai/ts-config": "0.2.16",
35
- "@flowgram.ai/eslint-config": "0.2.16"
34
+ "@flowgram.ai/ts-config": "0.2.17",
35
+ "@flowgram.ai/eslint-config": "0.2.17"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "react": ">=16.8",