separate reaction.r into reaction.effects and reaction.deriveds

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

@ -7,7 +7,6 @@ import {
remove_reactions,
set_signal_status
} from '../runtime.js';
import { push_reference } from './effects.js';
import { default_equals, safe_equals } from './equality.js';
/**
@ -27,9 +26,9 @@ export function derived(fn) {
eq: default_equals,
f: flags,
fn,
r: null,
// @ts-expect-error
v: UNINITIALIZED,
effects: null,
deriveds: null,
v: /** @type {V} */ (UNINITIALIZED),
w: 0
};
@ -38,7 +37,11 @@ export function derived(fn) {
}
if (current_reaction !== null) {
push_reference(current_reaction, signal);
if (current_reaction.deriveds === null) {
current_reaction.deriveds = [signal];
} else {
current_reaction.deriveds.push(signal);
}
}
return signal;
@ -64,6 +67,6 @@ export function destroy_derived(signal) {
destroy_references(signal);
remove_reactions(signal, 0);
// @ts-expect-error `signal.i` cannot be `null` while the signal is alive
signal.fn = signal.r = signal.x = signal.b = signal.deps = signal.reactions = null;
signal.fn = signal.effects = signal.x = signal.b = signal.deps = signal.reactions = null;
set_signal_status(signal, DESTROYED);
}

@ -3,6 +3,7 @@ import {
current_block,
current_component_context,
current_effect,
current_reaction,
destroy_references,
flush_local_render_effects,
get,
@ -17,20 +18,6 @@ import { set } from './sources.js';
import { is_array } from '../utils.js';
import { run_all } from '../../common.js';
/**
* @param {import('#client').Reaction} target_signal
* @param {import('#client').Reaction} ref_signal
* @returns {void}
*/
export function push_reference(target_signal, ref_signal) {
const references = target_signal.r;
if (references === null) {
target_signal.r = [ref_signal];
} else {
references.push(ref_signal);
}
}
/**
* @param {import('./types.js').EffectType} type
* @param {(() => void | (() => void)) | ((b: import('#client').Block) => void | (() => void))} fn
@ -47,7 +34,8 @@ function create_effect(type, fn, sync, block, schedule) {
f: type | DIRTY,
l: 0,
fn,
r: null,
effects: null,
deriveds: null,
v: null,
w: 0,
ctx: current_component_context,
@ -56,8 +44,15 @@ function create_effect(type, fn, sync, block, schedule) {
if (current_effect !== null) {
signal.l = current_effect.l + 1;
}
if ((type & MANAGED) === 0) {
push_reference(current_effect, signal);
if (current_reaction !== null) {
if (current_reaction.effects === null) {
current_reaction.effects = [signal];
} else {
current_reaction.effects.push(signal);
}
}
}
@ -253,7 +248,7 @@ export function destroy_effect(signal) {
const destroy = signal.y;
destroy_references(signal);
remove_reactions(signal, 0);
signal.fn = signal.r = signal.y = signal.ctx = signal.block = signal.deps = null;
signal.fn = signal.effects = signal.y = signal.ctx = signal.block = signal.deps = null;
set_signal_status(signal, DESTROYED);
if (destroy !== null) {
if (is_array(destroy)) {

@ -25,11 +25,10 @@ export interface Derived<V = unknown> extends Source<V> {
deps: null | Value[];
/** The derived function */
fn: () => V;
// TODO get rid of these
/** references: Anything that a signal owns */
r: null | Reaction[];
/** Effects created inside this signal */
effects: null | Effect[];
/** Deriveds created inside this signal */
deriveds: null | Derived[];
}
export interface DerivedDebug<V = unknown> extends Derived<V> {
@ -49,8 +48,10 @@ export type Effect = {
f: number;
/** init: The function that we invoke for effects and computeds */
fn: null | (() => void | (() => void)) | ((b: Block, s: Signal) => void | (() => void));
/** references: Anything that a signal owns */
r: null | Reaction[];
/** 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 **/

@ -373,19 +373,18 @@ export function remove_reactions(signal, start_index) {
* @returns {void}
*/
export function destroy_references(signal) {
const references = signal.r;
signal.r = null;
if (references !== null) {
let i;
for (i = 0; i < references.length; i++) {
var reference = references[i];
if ((reference.f & DERIVED) !== 0) {
// TODO make signal.r only contain deriveds or effects
destroy_derived(/** @type {import('#client').Derived} */ (reference));
} else {
destroy_effect(/** @type {import('#client').Effect} */ (reference));
if (signal.effects) {
for (var i = 0; i < signal.effects.length; i += 1) {
destroy_effect(signal.effects[i]);
}
signal.effects = null;
}
if (signal.deriveds) {
for (var i = 0; i < signal.deriveds.length; i += 1) {
destroy_derived(signal.deriveds[i]);
}
signal.deriveds = null;
}
}
@ -822,7 +821,7 @@ export function invalidate_inner_signals(fn) {
* @returns {void}
*/
function mark_subtree_children_inert(signal, inert, visited_blocks) {
const references = signal.r;
const references = signal.effects;
if (references !== null) {
let i;
for (i = 0; i < references.length; i++) {

Loading…
Cancel
Save