Skip to content

Commit 7ecd52e

Browse files
committed
chore: document and test signals edge case
1 parent 2e238ad commit 7ecd52e

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
@@ -76,7 +76,11 @@ export let current_effect = null;
7676
/** @type {null | import('./types.js').Signal[]} */
7777
let current_dependencies = null;
7878
let current_dependencies_index = 0;
79-
/** @type {null | import('./types.js').Signal[]} */
79+
/**
80+
* Tracks writes that the effect it's executed in doesn't listen to yet,
81+
* so that the dependency can be added to the effect later on if it then reads it
82+
* @type {null | import('./types.js').Signal[]}
83+
*/
8084
let current_untracked_writes = null;
8185
/** @type {null | import('./types.js').SignalDebug} */
8286
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
@@ -6,15 +6,15 @@ import * as $ from '../../src/internal/client/runtime';
66
* @param fn A function that returns a function because we first need to setup all the signals
77
* and then execute the test in order to simulate a real component
88
*/
9-
function run_test(runes: boolean, fn: () => () => void) {
9+
function run_test(runes: boolean, fn: (runes: boolean) => () => void) {
1010
return () => {
1111
// Create a component context to test runes vs legacy mode
1212
$.push({}, runes);
1313
// Create a render context so that effect validations etc don't fail
1414
let execute: any;
1515
const signal = $.render_effect(
1616
() => {
17-
execute = fn();
17+
execute = fn(runes);
1818
},
1919
null,
2020
true,
@@ -26,7 +26,7 @@ function run_test(runes: boolean, fn: () => () => void) {
2626
};
2727
}
2828

29-
function test(text: string, fn: () => any) {
29+
function test(text: string, fn: (runes: boolean) => any) {
3030
it(`${text} (legacy mode)`, run_test(false, fn));
3131
it(`${text} (runes mode)`, run_test(true, fn));
3232
}
@@ -228,4 +228,25 @@ describe('signals', () => {
228228
assert.deepEqual(count.c, null);
229229
};
230230
});
231+
232+
test('schedules rerun when writing to signal before reading it', (runes) => {
233+
if (!runes) return () => {};
234+
235+
const value = $.source({ count: 0 });
236+
$.user_effect(() => {
237+
$.set(value, { count: 0 });
238+
$.get(value);
239+
});
240+
241+
return () => {
242+
let errored = false;
243+
try {
244+
$.flushSync();
245+
} catch (e: any) {
246+
assert.include(e.message, 'ERR_SVELTE_TOO_MANY_UPDATES');
247+
errored = true;
248+
}
249+
assert.equal(errored, true);
250+
};
251+
});
231252
});

0 commit comments

Comments
 (0)