rename value.c to value.reactions, remove from effect type

pull/10760/head
Rich Harris 2 years ago
parent 3e8eb9290b
commit cabd404889

@ -14,7 +14,7 @@ import { default_equals, safe_equal } from './equality.js';
/** /**
* @template V * @template V
* @param {() => V} fn * @param {() => V} fn
* @returns {import('../types.js').Derived<V>} * @returns {import('#client').Derived<V>}
*/ */
/*#__NO_SIDE_EFFECTS__*/ /*#__NO_SIDE_EFFECTS__*/
export function derived(fn) { export function derived(fn) {
@ -24,7 +24,7 @@ export function derived(fn) {
/** @type {import('#client').Derived<V>} */ /** @type {import('#client').Derived<V>} */
const signal = { const signal = {
b: current_block, b: current_block,
c: null, reactions: null,
d: null, d: null,
e: default_equals, e: default_equals,
f: flags, f: flags,
@ -68,6 +68,6 @@ export function destroy_derived(signal) {
destroy_references(signal); destroy_references(signal);
remove_consumers(signal, 0); remove_consumers(signal, 0);
// @ts-expect-error `signal.i` cannot be `null` while the signal is alive // @ts-expect-error `signal.i` cannot be `null` while the signal is alive
signal.i = signal.r = signal.x = signal.b = signal.d = signal.c = null; signal.i = signal.r = signal.x = signal.b = signal.d = signal.reactions = null;
set_signal_status(signal, DESTROYED); set_signal_status(signal, DESTROYED);
} }

@ -43,7 +43,6 @@ function create_effect(type, fn, sync, block, schedule) {
/** @type {import('#client').Effect} */ /** @type {import('#client').Effect} */
const signal = { const signal = {
b: block, b: block,
c: null,
d: null, d: null,
e: null, e: null,
f: type | DIRTY, f: type | DIRTY,
@ -255,7 +254,7 @@ export function destroy_effect(signal) {
const destroy = signal.y; const destroy = signal.y;
destroy_references(signal); destroy_references(signal);
remove_consumers(signal, 0); remove_consumers(signal, 0);
signal.i = signal.r = signal.y = signal.x = signal.b = signal.d = signal.c = null; signal.i = signal.r = signal.y = signal.x = signal.b = signal.d = null;
set_signal_status(signal, DESTROYED); set_signal_status(signal, DESTROYED);
if (destroy !== null) { if (destroy !== null) {
if (is_array(destroy)) { if (is_array(destroy)) {

@ -30,7 +30,7 @@ import { CLEAN, DERIVED, DIRTY, MANAGED, SOURCE } from '../constants.js';
export function source(value) { export function source(value) {
/** @type {import('#client').Source<V>} */ /** @type {import('#client').Source<V>} */
const source = { const source = {
c: null, reactions: null,
e: default_equals, e: default_equals,
f: SOURCE | CLEAN, f: SOURCE | CLEAN,
v: value, v: value,
@ -130,7 +130,6 @@ export function set(signal, value) {
is_runes(null) && is_runes(null) &&
!ignore_mutation_validation && !ignore_mutation_validation &&
current_effect !== null && current_effect !== null &&
current_effect.c === null &&
(current_effect.f & CLEAN) !== 0 && (current_effect.f & CLEAN) !== 0 &&
(current_effect.f & MANAGED) === 0 (current_effect.f & MANAGED) === 0
) { ) {

@ -10,8 +10,8 @@ export type SignalFlags =
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 Source<V = unknown> {
/** consumers: Signals that read from the current signal */ /** Signals that read from this signal */
c: null | Reaction[]; reactions: null | Reaction[];
/** equals: For value equality */ /** equals: For value equality */
e: null | EqualsFunctions; e: null | EqualsFunctions;
/** flags: The types that the signal represent, as a bitwise value */ /** flags: The types that the signal represent, as a bitwise value */
@ -49,8 +49,6 @@ export interface DerivedDebug<V = unknown> extends Derived<V> {
export type Effect = { export type Effect = {
/** block: The block associated with this effect/computed */ /** block: The block associated with this effect/computed */
b: null | Block; b: null | Block;
/** consumers: Signals that read from the current signal */
c: null | Reaction[];
/** context: The associated component if this signal is an effect/computed */ /** context: The associated component if this signal is an effect/computed */
x: null | ComponentContext; x: null | ComponentContext;
/** dependencies: Signals that this signal reads from */ /** dependencies: Signals that this signal reads from */

@ -291,10 +291,10 @@ function execute_signal_fn(signal) {
if (!current_skip_consumer) { if (!current_skip_consumer) {
for (i = current_dependencies_index; i < dependencies.length; i++) { for (i = current_dependencies_index; i < dependencies.length; i++) {
const dependency = dependencies[i]; const dependency = dependencies[i];
const consumers = dependency.c; const consumers = dependency.reactions;
if (consumers === null) { if (consumers === null) {
dependency.c = [signal]; dependency.reactions = [signal];
} else if (consumers[consumers.length - 1] !== signal) { } else if (consumers[consumers.length - 1] !== signal) {
// TODO: should this be: // TODO: should this be:
// //
@ -328,14 +328,14 @@ function execute_signal_fn(signal) {
* @returns {void} * @returns {void}
*/ */
function remove_consumer(signal, dependency) { function remove_consumer(signal, dependency) {
const consumers = dependency.c; const consumers = dependency.reactions;
let consumers_length = 0; let consumers_length = 0;
if (consumers !== null) { if (consumers !== null) {
consumers_length = consumers.length - 1; consumers_length = consumers.length - 1;
const index = consumers.indexOf(signal); const index = consumers.indexOf(signal);
if (index !== -1) { if (index !== -1) {
if (consumers_length === 0) { if (consumers_length === 0) {
dependency.c = null; dependency.reactions = null;
} else { } else {
// Swap with last element and then remove. // Swap with last element and then remove.
consumers[index] = consumers[consumers_length]; consumers[index] = consumers[consumers_length];
@ -868,14 +868,14 @@ export function mark_subtree_inert(signal, inert, visited_blocks = new Set()) {
} }
/** /**
* @param {import('./types.js').Signal} signal * @param {import('#client').Value} signal
* @param {number} to_status * @param {number} to_status
* @param {boolean} force_schedule * @param {boolean} force_schedule
* @returns {void} * @returns {void}
*/ */
export function mark_signal_consumers(signal, to_status, force_schedule) { export function mark_signal_consumers(signal, to_status, force_schedule) {
const runes = is_runes(null); const runes = is_runes(null);
const consumers = signal.c; const consumers = signal.reactions;
if (consumers !== null) { if (consumers !== null) {
const length = consumers.length; const length = consumers.length;
let i; let i;
@ -896,9 +896,13 @@ export function mark_signal_consumers(signal, to_status, force_schedule) {
const maybe_dirty = (flags & MAYBE_DIRTY) !== 0; const maybe_dirty = (flags & MAYBE_DIRTY) !== 0;
if ((flags & CLEAN) !== 0 || (maybe_dirty && unowned)) { if ((flags & CLEAN) !== 0 || (maybe_dirty && unowned)) {
if ((consumer.f & IS_EFFECT) !== 0) { if ((consumer.f & IS_EFFECT) !== 0) {
schedule_effect(/** @type {import('./types.js').Effect} */ (consumer), false); schedule_effect(/** @type {import('#client').Effect} */ (consumer), false);
} else { } else {
mark_signal_consumers(consumer, MAYBE_DIRTY, force_schedule); mark_signal_consumers(
/** @type {import('#client').Value} */ (consumer),
MAYBE_DIRTY,
force_schedule
);
} }
} }
} }

@ -198,13 +198,13 @@ describe('signals', () => {
return () => { return () => {
$.flushSync(() => set(count, 1)); $.flushSync(() => set(count, 1));
// Ensure we're not leaking consumers // Ensure we're not leaking consumers
assert.deepEqual(count.c?.length, 1); assert.deepEqual(count.reactions?.length, 1);
$.flushSync(() => set(count, 2)); $.flushSync(() => set(count, 2));
// Ensure we're not leaking consumers // Ensure we're not leaking consumers
assert.deepEqual(count.c?.length, 1); assert.deepEqual(count.reactions?.length, 1);
$.flushSync(() => set(count, 3)); $.flushSync(() => set(count, 3));
// Ensure we're not leaking consumers // Ensure we're not leaking consumers
assert.deepEqual(count.c?.length, 1); assert.deepEqual(count.reactions?.length, 1);
assert.deepEqual(log, [0, 1, 2, 3]); assert.deepEqual(log, [0, 1, 2, 3]);
}; };
}); });
@ -264,11 +264,11 @@ describe('signals', () => {
$.flushSync(() => set(count, 4)); $.flushSync(() => set(count, 4));
$.flushSync(() => set(count, 0)); $.flushSync(() => set(count, 0));
// Ensure we're not leaking consumers // Ensure we're not leaking consumers
assert.deepEqual(count.c?.length, 1); assert.deepEqual(count.reactions?.length, 1);
assert.deepEqual(log, [0, 2, 'limit', 0]); assert.deepEqual(log, [0, 2, 'limit', 0]);
destroy_effect(effect); destroy_effect(effect);
// Ensure we're not leaking consumers // Ensure we're not leaking consumers
assert.deepEqual(count.c, null); assert.deepEqual(count.reactions, null);
}; };
}); });

Loading…
Cancel
Save