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> {
12681268 charset ?: string | undefined | null ;
12691269 content ?: string | undefined | null ;
12701270 'http-equiv' ?:
1271- | 'accept-ch'
1271+ | 'accept-ch'
12721272 | 'content-security-policy'
12731273 | 'content-type'
12741274 | 'default-style'
Original file line number Diff line number Diff line change @@ -187,7 +187,7 @@ export class Batch {
187187 // if there are multiple batches, we are 'time travelling' —
188188 // we need to undo the changes belonging to any batch
189189 // other than the current one
190- if ( batches . size > 1 ) {
190+ if ( async_mode_flag && batches . size > 1 ) {
191191 current_values = new Map ( ) ;
192192 batch_deriveds = new Map ( ) ;
193193
@@ -484,6 +484,7 @@ export class Batch {
484484 */
485485export function flushSync ( fn ) {
486486 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
487488 e . flush_sync_in_effect ( ) ;
488489 }
489490
@@ -622,7 +623,9 @@ function flush_queued_effects(effects) {
622623 }
623624 }
624625
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 ) {
626629 // TODO this feels incorrect! it gets the tests passing
627630 old_values . clear ( ) ;
628631
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