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) {
/** @type {import('#client').SourceDebug<V>} */ (source).inspect = new Set();
/** @type {import('#client').ValueDebug<V>} */ (source).inspect = new Set();
}
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 interface Source<V = unknown> {
export interface Signal {
/** Flags bitmask */
f: number;
}
export interface Value<V = unknown> 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<V = unknown> extends Source<V> {
inspect: Set<Function>;
}
export interface Derived<V = unknown> extends Source<V> {
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<V = unknown> extends Derived<V> {
inspect: Set<Function>;
export interface Derived<V = unknown> extends Value<V>, 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 = 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) {
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
);

Loading…
Cancel
Save