From e7d0fdb48c6adfc068373ec4d2dd924876561f04 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 11 Mar 2024 17:15:24 -0400 Subject: [PATCH] make Derived and Effect inherit from Reaction, rather than Reaction being a union of Derived and Effect --- .../src/internal/client/reactivity/sources.js | 2 +- .../src/internal/client/reactivity/types.d.ts | 49 ++++++++----------- .../svelte/src/internal/client/runtime.js | 10 ++-- 3 files changed, 26 insertions(+), 35 deletions(-) diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index e41a9e4935..6fb547dbb3 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -38,7 +38,7 @@ export function source(value) { }; if (DEV) { - /** @type {import('#client').SourceDebug} */ (source).inspect = new Set(); + /** @type {import('#client').ValueDebug} */ (source).inspect = new Set(); } return source; diff --git a/packages/svelte/src/internal/client/reactivity/types.d.ts b/packages/svelte/src/internal/client/reactivity/types.d.ts index bd3b0db021..7fa9fc8e39 100644 --- a/packages/svelte/src/internal/client/reactivity/types.d.ts +++ b/packages/svelte/src/internal/client/reactivity/types.d.ts @@ -3,71 +3,62 @@ import type { EFFECT, PRE_EFFECT, RENDER_EFFECT } from '../constants'; export type EffectType = typeof EFFECT | typeof PRE_EFFECT | typeof RENDER_EFFECT; -export interface Source { +export interface Signal { + /** Flags bitmask */ + f: number; +} + +export interface Value extends Signal { /** Signals that read from this signal */ reactions: null | Reaction[]; /** Equality function */ eq: Equals; - /** Flags bitmask */ - f: number; /** The latest value for this signal */ v: V; /** Write version */ w: number; } -export interface SourceDebug extends Source { - inspect: Set; -} - -export interface Derived extends Source { +export interface Reaction extends Signal { + /** The reaction function */ + fn: null | Function; /** Signals that this signal reads from */ deps: null | Value[]; - /** The derived function */ - fn: () => V; /** Effects created inside this signal */ effects: null | Effect[]; /** Deriveds created inside this signal */ deriveds: null | Derived[]; } -export interface DerivedDebug extends Derived { - inspect: Set; +export interface Derived extends Value, Reaction { + fn: () => V; } -export type Effect = { +export interface Effect extends Reaction { /** block: The block associated with this effect/computed */ block: null | Block; /** context: The associated component if this signal is an effect/computed */ ctx: null | ComponentContext; - /** dependencies: Signals that this signal reads from */ - deps: null | Value[]; /** destroy: Thing(s) that need destroying */ y: null | (() => void); - /** Flags bitmask */ - f: number; /** init: The function that we invoke for effects and computeds */ fn: null | (() => void | (() => void)) | ((b: Block, s: Signal) => void | (() => void)); - /** Effects created inside this signal */ - effects: null | Effect[]; - /** Deriveds created inside this signal */ - deriveds: null | Derived[]; /** value: The latest value for this signal, doubles as the teardown for effects */ v: null | Function; /** level: the depth from the root signal, used for ordering render/pre-effects topologically **/ l: number; /** write version: used for unowned signals to track if their depdendencies are dirty or not **/ w: number; -}; - -export type Reaction = Derived | Effect; +} -export type MaybeSignal = T | Source; +export interface ValueDebug extends Value { + inspect: Set; +} -export type UnwrappedSignal = T extends Value ? U : T; +export interface DerivedDebug extends Derived, ValueDebug {} -export type Value = Source | Derived; +export type Source = Value; -export type ValueDebug = SourceDebug | DerivedDebug; +export type MaybeSignal = T | Source; -export type Signal = Source | Derived | Effect; +export type UnwrappedSignal = T extends Value ? U : T; diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index bd932ffb0e..6eda0a9f55 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -164,7 +164,7 @@ export function batch_inspect(target, prop, receiver) { */ function is_signal_dirty(signal) { const flags = signal.f; - if ((flags & DIRTY) !== 0 || signal.v === UNINITIALIZED) { + if ((flags & DIRTY) !== 0) { return true; } if ((flags & MAYBE_DIRTY) !== 0) { @@ -198,10 +198,10 @@ function is_signal_dirty(signal) { // that state has changed to a newer version and thus this unowned signal // is also dirty. const is_unowned = (flags & UNOWNED) !== 0; - const write_version = signal.w; + const write_version = /** @type {import('#client').Derived} */ (signal).w; const dep_write_version = dependency.w; if (is_unowned && dep_write_version > write_version) { - signal.w = dep_write_version; + /** @type {import('#client').Derived} */ (signal).w = dep_write_version; return true; } } @@ -708,7 +708,7 @@ function update_derived(signal, force_schedule) { // @ts-expect-error if (DEV && signal.inspect && force_schedule) { - for (const fn of /** @type {import('./types.js').ValueDebug} */ (signal).inspect) fn(); + for (const fn of /** @type {import('./types.js').DerivedDebug} */ (signal).inspect) fn(); } } } @@ -914,7 +914,7 @@ export function mark_reactions(signal, to_status, force_schedule) { schedule_effect(/** @type {import('#client').Effect} */ (reaction), false); } else { mark_reactions( - /** @type {import('#client').Value} */ (reaction), + /** @type {import('#client').Derived} */ (reaction), MAYBE_DIRTY, force_schedule );