File tree Expand file tree Collapse file tree 6 files changed +43
-3
lines changed
src/internal/client/reactivity
tests/runtime-runes/samples/flush-sync-inside-attachment Expand file tree Collapse file tree 6 files changed +43
-3
lines changed Original file line number Diff line number Diff line change
1
+ ---
2
+ ' svelte ' : patch
3
+ ---
4
+
5
+ fix: don't fail on ` flushSync ` while flushing effects
Original file line number Diff line number Diff line change @@ -1268,7 +1268,7 @@ export interface HTMLMetaAttributes extends HTMLAttributes<HTMLMetaElement> {
1268
1268
charset ?: string | undefined | null ;
1269
1269
content ?: string | undefined | null ;
1270
1270
'http-equiv' ?:
1271
- | 'accept-ch'
1271
+ | 'accept-ch'
1272
1272
| 'content-security-policy'
1273
1273
| 'content-type'
1274
1274
| 'default-style'
Original file line number Diff line number Diff line change @@ -187,7 +187,7 @@ export class Batch {
187
187
// if there are multiple batches, we are 'time travelling' —
188
188
// we need to undo the changes belonging to any batch
189
189
// other than the current one
190
- if ( batches . size > 1 ) {
190
+ if ( async_mode_flag && batches . size > 1 ) {
191
191
current_values = new Map ( ) ;
192
192
batch_deriveds = new Map ( ) ;
193
193
@@ -484,6 +484,7 @@ export class Batch {
484
484
*/
485
485
export function flushSync ( fn ) {
486
486
if ( async_mode_flag && active_effect !== null ) {
487
+ // We disallow this because it creates super-hard to reason about stack trace and because it's generally a bad idea
487
488
e . flush_sync_in_effect ( ) ;
488
489
}
489
490
@@ -622,7 +623,9 @@ function flush_queued_effects(effects) {
622
623
}
623
624
}
624
625
625
- if ( eager_block_effects . length > 0 ) {
626
+ // If update_effect() has a flushSync() in it, we may have flushed another flush_queued_effects(),
627
+ // which already handled this logic and did set eager_block_effects to null.
628
+ if ( eager_block_effects ?. length > 0 ) {
626
629
// TODO this feels incorrect! it gets the tests passing
627
630
old_values . clear ( ) ;
628
631
Original file line number Diff line number Diff line change
1
+ <script >
2
+ let { text } = $props ();
3
+
4
+ $effect (() => console .log (text));
5
+ </script >
6
+
7
+ {text }
Original file line number Diff line number Diff line change
1
+ import { async_mode } from '../../../helpers' ;
2
+ import { test } from '../../test' ;
3
+
4
+ export default test ( {
5
+ // In legacy mode this succeeds and logs 'hello'
6
+ // In async mode this throws an error because flushSync is called inside an effect
7
+ async test ( { assert, target, logs } ) {
8
+ assert . htmlEqual ( target . innerHTML , `<button>show</button> <div>hello</div>` ) ;
9
+ assert . deepEqual ( logs , [ 'hello' ] ) ;
10
+ } ,
11
+ runtime_error : async_mode ? 'flush_sync_in_effect' : undefined
12
+ } ) ;
Original file line number Diff line number Diff line change
1
+ <script >
2
+ import { flushSync , mount } from ' svelte'
3
+ import Child from ' ./Child.svelte' ;
4
+
5
+ let show = $state (false );
6
+ </script >
7
+
8
+ <button onclick ={() => show = true }>show</button >
9
+
10
+ <div {@attach (target ) => {
11
+ mount (Child , { target , props: { text: ' hello' } });
12
+ flushSync ();
13
+ }}></div >
You can’t perform that action at this time.
0 commit comments