make Derived and Effect inherit from Reaction, rather than Reaction being a union of Derived and Effect

pull/10760/head
Rich Harris 2 years ago
parent 514c8ea188
commit e7d0fdb48c

@ -38,7 +38,7 @@ export function source(value) {
}; };
if (DEV) { if (DEV) {
/** @type {import('#client').SourceDebug<V>} */ (source).inspect = new Set(); /** @type {import('#client').ValueDebug<V>} */ (source).inspect = new Set();
} }
return source; return source;

@ -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 type EffectType = typeof EFFECT | typeof PRE_EFFECT | typeof RENDER_EFFECT;
export interface Source<V = unknown> { export interface Signal {
/** Flags bitmask */
f: number;
}
export interface Value<V = unknown> extends Signal {
/** Signals that read from this signal */ /** Signals that read from this signal */
reactions: null | Reaction[]; reactions: null | Reaction[];
/** Equality function */ /** Equality function */
eq: Equals; eq: Equals;
/** Flags bitmask */
f: number;
/** The latest value for this signal */ /** The latest value for this signal */
v: V; v: V;
/** Write version */ /** Write version */
w: number; w: number;
} }
export interface SourceDebug<V = unknown> extends Source<V> { export interface Reaction extends Signal {
inspect: Set<Function>; /** The reaction function */
} fn: null | Function;
export interface Derived<V = unknown> extends Source<V> {
/** Signals that this signal reads from */ /** Signals that this signal reads from */
deps: null | Value[]; deps: null | Value[];
/** The derived function */
fn: () => V;
/** Effects created inside this signal */ /** Effects created inside this signal */
effects: null | Effect[]; effects: null | Effect[];
/** Deriveds created inside this signal */ /** Deriveds created inside this signal */
deriveds: null | Derived[]; deriveds: null | Derived[];
} }
export interface DerivedDebug<V = unknown> extends Derived<V> { export interface Derived<V = unknown> extends Value<V>, Reaction {
inspect: Set<Function>; fn: () => V;
} }
export type Effect = { export interface Effect extends Reaction {
/** block: The block associated with this effect/computed */ /** block: The block associated with this effect/computed */
block: null | Block; block: null | Block;
/** context: The associated component if this signal is an effect/computed */ /** context: The associated component if this signal is an effect/computed */
ctx: null | ComponentContext; ctx: null | ComponentContext;
/** dependencies: Signals that this signal reads from */
deps: null | Value[];
/** destroy: Thing(s) that need destroying */ /** destroy: Thing(s) that need destroying */
y: null | (() => void); y: null | (() => void);
/** Flags bitmask */
f: number;
/** init: The function that we invoke for effects and computeds */ /** init: The function that we invoke for effects and computeds */
fn: null | (() => void | (() => void)) | ((b: Block, s: Signal) => void | (() => void)); 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 */ /** value: The latest value for this signal, doubles as the teardown for effects */
v: null | Function; v: null | Function;
/** level: the depth from the root signal, used for ordering render/pre-effects topologically **/ /** level: the depth from the root signal, used for ordering render/pre-effects topologically **/
l: number; l: number;
/** write version: used for unowned signals to track if their depdendencies are dirty or not **/ /** write version: used for unowned signals to track if their depdendencies are dirty or not **/
w: number; w: number;
}; }
export type Reaction = Derived | Effect;
export type MaybeSignal<T = unknown> = T | Source<T>; export interface ValueDebug<V = unknown> extends Value<V> {
inspect: Set<Function>;
}
export type UnwrappedSignal<T> = T extends Value<infer U> ? U : T; export interface DerivedDebug<V = unknown> extends Derived<V>, ValueDebug<V> {}
export type Value<V = unknown> = Source<V> | Derived<V>; export type Source<V = unknown> = Value<V>;
export type ValueDebug<V = unknown> = SourceDebug<V> | DerivedDebug<V>; export type MaybeSignal<T = unknown> = T | Source<T>;
export type Signal = Source | Derived | Effect; export type UnwrappedSignal<T> = T extends Value<infer U> ? U : T;

@ -164,7 +164,7 @@ export function batch_inspect(target, prop, receiver) {
*/ */
function is_signal_dirty(signal) { function is_signal_dirty(signal) {
const flags = signal.f; const flags = signal.f;
if ((flags & DIRTY) !== 0 || signal.v === UNINITIALIZED) { if ((flags & DIRTY) !== 0) {
return true; return true;
} }
if ((flags & MAYBE_DIRTY) !== 0) { 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 // that state has changed to a newer version and thus this unowned signal
// is also dirty. // is also dirty.
const is_unowned = (flags & UNOWNED) !== 0; 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; const dep_write_version = dependency.w;
if (is_unowned && dep_write_version > write_version) { if (is_unowned && dep_write_version > write_version) {
signal.w = dep_write_version; /** @type {import('#client').Derived} */ (signal).w = dep_write_version;
return true; return true;
} }
} }
@ -708,7 +708,7 @@ function update_derived(signal, force_schedule) {
// @ts-expect-error // @ts-expect-error
if (DEV && signal.inspect && force_schedule) { 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); schedule_effect(/** @type {import('#client').Effect} */ (reaction), false);
} else { } else {
mark_reactions( mark_reactions(
/** @type {import('#client').Value} */ (reaction), /** @type {import('#client').Derived} */ (reaction),
MAYBE_DIRTY, MAYBE_DIRTY,
force_schedule force_schedule
); );

Loading…
Cancel
Save