blockless
Rich Harris 10 months ago
parent 530fd650c3
commit d109adcaea

@ -1,7 +1,6 @@
import { DEV } from 'esm-env';
import { CLEAN, DERIVED, UNINITIALIZED, UNOWNED } from '../constants.js';
import { current_consumer, current_effect } from '../runtime.js';
import { push_reference } from './utils.js';
import { default_equals, safe_equal } from './equality.js';
/**
@ -11,15 +10,15 @@ import { default_equals, safe_equal } from './equality.js';
*/
/*#__NO_SIDE_EFFECTS__*/
export function derived(fn) {
const is_unowned = current_effect === null;
const flags = is_unowned ? DERIVED | UNOWNED : DERIVED;
let flags = DERIVED | CLEAN;
if (current_effect === null) flags |= UNOWNED;
/** @type {import('#client').Derived<V>} */
const signal = {
c: null,
d: null,
e: default_equals,
f: flags | CLEAN,
f: flags,
i: fn,
r: null,
// @ts-expect-error
@ -35,7 +34,11 @@ export function derived(fn) {
}
if (current_consumer !== null) {
push_reference(current_consumer, signal);
if (current_consumer.r === null) {
current_consumer.r = [signal];
} else {
current_consumer.r.push(signal);
}
}
return signal;

@ -18,7 +18,6 @@ import {
ROOT_EFFECT,
DESTROYED
} from '../constants.js';
import { push_reference } from './utils.js';
/**
* @param {import('./types.js').EffectType} type
@ -45,7 +44,8 @@ function create_effect(type, fn, sync, schedule) {
out: null,
dom: null,
ran: false,
parent: current_effect
parent: current_effect,
children: null
};
if (DEV) {
@ -55,7 +55,12 @@ function create_effect(type, fn, sync, schedule) {
if (current_effect !== null) {
signal.l = current_effect.l + 1;
push_reference(current_effect, signal);
if (current_effect.children === null) {
current_effect.children = [signal];
} else {
current_effect.children.push(signal);
}
}
if (schedule) {
@ -240,8 +245,8 @@ function pause_children(effect, transitions, local) {
}
}
if (effect.r) {
for (const child of effect.r) {
if (effect.children) {
for (const child of effect.children) {
pause_children(child, transitions, false); // TODO separate child effects from child deriveds
}
}
@ -263,8 +268,8 @@ export function destroy_effect(effect) {
remove(effect.dom);
}
if (effect.r) {
for (const child of effect.r) {
if (effect.children) {
for (const child of effect.children) {
destroy_effect(child);
}
}
@ -286,8 +291,8 @@ function resume_children(effect, local) {
execute_effect(/** @type {import('#client').Effect} */ (effect));
}
if (effect.r) {
for (const child of effect.r) {
if (effect.children) {
for (const child of effect.children) {
resume_children(child, false);
}
}

@ -67,8 +67,8 @@ export interface Effect {
f: SignalFlags;
/** init: The function that we invoke for effects and computeds */
i: null | (() => void | (() => void));
/** references: Anything that a signal owns */
r: null | Reaction[];
/** deriveds belonging to this effect */
r: null | Derived[];
/** teardown */
v: null | (() => void);
/** level: the depth from the root signal, used for ordering render/pre-effects topologically **/
@ -83,8 +83,8 @@ export interface Effect {
dom: null | TemplateNode | Array<TemplateNode>;
/** Whether the effect ran or not */
ran: boolean;
/** The parent effect */
parent: null | Effect;
children: null | Effect[];
}
export type Reaction = Derived | Effect;

@ -1,13 +0,0 @@
/**
* @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);
}
}

@ -356,16 +356,16 @@ function remove_consumers(signal, start_index) {
}
/**
* @param {import('#client').Reaction} signal
* @param {import('#client').Effect} effect
* @returns {void}
*/
function destroy_references(signal) {
const references = signal.r;
signal.r = null;
if (references !== null) {
function destroy_references(effect) {
const deriveds = effect.r;
effect.r = null;
if (deriveds !== null) {
let i;
for (i = 0; i < references.length; i++) {
destroy_signal(references[i]);
for (i = 0; i < deriveds.length; i++) {
destroy_signal(deriveds[i]);
}
}
}
@ -656,7 +656,6 @@ export async function tick() {
function update_derived(signal, force_schedule) {
const previous_updating_derived = updating_derived;
updating_derived = true;
destroy_references(signal);
const value = execute_signal_fn(signal);
updating_derived = previous_updating_derived;
const status =

Loading…
Cancel
Save