diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 0ce8fd16..68d75b5a 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -537,19 +537,21 @@ declare class Computed extends Signal { _globalVersion: number; _flags: number; - constructor(fn: () => T); + constructor(fn: () => T, options?: SignalOptions); _notify(): void; get value(): T; } -function Computed(this: Computed, fn: () => unknown) { +function Computed(this: Computed, fn: () => unknown, options?: SignalOptions) { Signal.call(this, undefined); this._fn = fn; this._sources = undefined; this._globalVersion = globalVersion - 1; this._flags = OUTDATED; + this._watched = options?.watched; + this._unwatched = options?.unwatched; } Computed.prototype = new Signal() as Computed; @@ -626,9 +628,8 @@ Computed.prototype._subscribe = function (node) { Computed.prototype._unsubscribe = function (node) { // Only run the unsubscribe step if the computed signal has any subscribers. + Signal.prototype._unsubscribe.call(this, node); if (this._targets !== undefined) { - Signal.prototype._unsubscribe.call(this, node); - // Computed signal unsubscribes from its dependencies when it loses its last subscriber. // This makes it possible for unreferences subgraphs of computed signals to get garbage collected. if (this._targets === undefined) { @@ -699,8 +700,11 @@ interface ReadonlySignal { * @param fn The effect callback. * @returns A new read-only signal. */ -function computed(fn: () => T): ReadonlySignal { - return new Computed(fn); +function computed( + fn: () => T, + options?: SignalOptions +): ReadonlySignal { + return new Computed(fn, options); } function cleanupEffect(effect: Effect) { diff --git a/packages/preact/src/index.ts b/packages/preact/src/index.ts index f57e8447..7475fd93 100644 --- a/packages/preact/src/index.ts +++ b/packages/preact/src/index.ts @@ -372,11 +372,11 @@ export function useSignal(value?: T, options?: SignalOptions) { ); } -export function useComputed(compute: () => T) { +export function useComputed(compute: () => T, options?: SignalOptions) { const $compute = useRef(compute); $compute.current = compute; (currentComponent as AugmentedComponent)._updateFlags |= HAS_COMPUTEDS; - return useMemo(() => computed(() => $compute.current()), []); + return useMemo(() => computed(() => $compute.current(), options), []); } let oldNotify: (this: Effect) => void, diff --git a/packages/react/runtime/src/index.ts b/packages/react/runtime/src/index.ts index 7fc5a34b..f1017093 100644 --- a/packages/react/runtime/src/index.ts +++ b/packages/react/runtime/src/index.ts @@ -394,10 +394,13 @@ export function useSignal(value?: T, options?: SignalOptions) { ); } -export function useComputed(compute: () => T): ReadonlySignal { +export function useComputed( + compute: () => T, + options?: SignalOptions +): ReadonlySignal { const $compute = useRef(compute); $compute.current = compute; - return useMemo(() => computed(() => $compute.current()), Empty); + return useMemo(() => computed(() => $compute.current(), options), Empty); } export function useSignalEffect(cb: () => void | (() => void)) {