Skip to content

Commit ba0bdc7

Browse files
authored
chore: document and test signals edge case (#10228)
1 parent 3f75ea6 commit ba0bdc7

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

packages/svelte/src/internal/client/runtime.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,11 @@ export let current_effect = null;
7474
/** @type {null | import('./types.js').Signal[]} */
7575
let current_dependencies = null;
7676
let current_dependencies_index = 0;
77-
/** @type {null | import('./types.js').Signal[]} */
77+
/**
78+
* Tracks writes that the effect it's executed in doesn't listen to yet,
79+
* so that the dependency can be added to the effect later on if it then reads it
80+
* @type {null | import('./types.js').Signal[]}
81+
*/
7882
let current_untracked_writes = null;
7983
/** @type {null | import('./types.js').SignalDebug} */
8084
let last_inspected_signal = null;

packages/svelte/tests/signals/test.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ import type { ComputationSignal } from '../../src/internal/client/types';
77
* @param fn A function that returns a function because we first need to setup all the signals
88
* and then execute the test in order to simulate a real component
99
*/
10-
function run_test(runes: boolean, fn: () => () => void) {
10+
function run_test(runes: boolean, fn: (runes: boolean) => () => void) {
1111
return () => {
1212
// Create a component context to test runes vs legacy mode
1313
$.push({}, runes);
1414
// Create a render context so that effect validations etc don't fail
1515
let execute: any;
1616
const signal = $.render_effect(
1717
() => {
18-
execute = fn();
18+
execute = fn(runes);
1919
},
2020
null,
2121
true,
@@ -27,7 +27,7 @@ function run_test(runes: boolean, fn: () => () => void) {
2727
};
2828
}
2929

30-
function test(text: string, fn: () => any) {
30+
function test(text: string, fn: (runes: boolean) => any) {
3131
it(`${text} (legacy mode)`, run_test(false, fn));
3232
it(`${text} (runes mode)`, run_test(true, fn));
3333
}
@@ -262,4 +262,25 @@ describe('signals', () => {
262262
assert.deepEqual(count.c, null);
263263
};
264264
});
265+
266+
test('schedules rerun when writing to signal before reading it', (runes) => {
267+
if (!runes) return () => {};
268+
269+
const value = $.source({ count: 0 });
270+
$.user_effect(() => {
271+
$.set(value, { count: 0 });
272+
$.get(value);
273+
});
274+
275+
return () => {
276+
let errored = false;
277+
try {
278+
$.flushSync();
279+
} catch (e: any) {
280+
assert.include(e.message, 'ERR_SVELTE_TOO_MANY_UPDATES');
281+
errored = true;
282+
}
283+
assert.equal(errored, true);
284+
};
285+
});
265286
});

0 commit comments

Comments
 (0)