File tree Expand file tree Collapse file tree 6 files changed +48
-1
lines changed 
src/internal/client/reactivity 
tests/runtime-runes/samples/1000-reading-derived-effects Expand file tree Collapse file tree 6 files changed +48
-1
lines changed Original file line number Diff line number Diff line change 1+ --- 
2+ ' svelte '  : patch 
3+ --- 
4+ 
5+ fix: exclude derived writes from effect abort and rescheduling
Original file line number Diff line number Diff line change @@ -31,6 +31,7 @@ import { invoke_error_boundary } from '../error-handling.js';
3131import  {  old_values  }  from  './sources.js' ; 
3232import  {  unlink_effect  }  from  './effects.js' ; 
3333import  {  unset_context  }  from  './async.js' ; 
34+ import  {  get_derived_writes ,  reset_derived_writes  }  from  './deriveds.js' ; 
3435
3536/** @type  {Set<Batch> } */ 
3637const  batches  =  new  Set ( ) ; 
@@ -546,6 +547,12 @@ function flush_queued_effects(effects) {
546547			if  ( is_dirty ( effect ) )  { 
547548				var  wv  =  write_version ; 
548549
550+ 				// updating a derived for also increase the write version but that doesn't mean 
551+ 				// state was written to in the user effect...so we reset the derived writes 
552+ 				// before running the effect so that we can subtract the amount of derived writes 
553+ 				// from the write version when we detect if state was written to in the user effect 
554+ 				reset_derived_writes ( ) ; 
555+ 
549556				update_effect ( effect ) ; 
550557
551558				// Effects with no dependencies or teardown do not get added to the effect tree. 
@@ -567,7 +574,7 @@ function flush_queued_effects(effects) {
567574
568575				// if state is written in a user effect, abort and re-schedule, lest we run 
569576				// effects that should be removed as a result of the state change 
570- 				if  ( write_version  >  wv  &&  ( effect . f  &  USER_EFFECT )  !==  0 )  { 
577+ 				if  ( write_version  -   get_derived_writes ( )   >  wv  &&  ( effect . f  &  USER_EFFECT )  !==  0 )  { 
571578					break ; 
572579				} 
573580			} 
Original file line number Diff line number Diff line change @@ -323,6 +323,20 @@ export function execute_derived(derived) {
323323	return  value ; 
324324} 
325325
326+ // in process_effects if state is written to in a user effect we reschedule the rest of the 
327+ // tree. However if a derived is updated in an effect we also increase the write version 
328+ // so we need to keep track of how many deriveds were written to in the effect so 
329+ // that we can subtract that from the write version before rescheduling unnnecessarily 
330+ let  derived_writes  =  0 ; 
331+ 
332+ export  function  get_derived_writes ( )  { 
333+ 	return  derived_writes ; 
334+ } 
335+ 
336+ export  function  reset_derived_writes ( )  { 
337+ 	derived_writes  =  0 ; 
338+ } 
339+ 
326340/** 
327341 * @param  {Derived } derived 
328342 * @returns  {void } 
@@ -333,6 +347,7 @@ export function update_derived(derived) {
333347	if  ( ! derived . equals ( value ) )  { 
334348		derived . v  =  value ; 
335349		derived . wv  =  increment_write_version ( ) ; 
350+ 		derived_writes ++ ; 
336351	} 
337352
338353	// don't mark derived clean if we're reading it inside a 
Original file line number Diff line number Diff line change 1+ <script >
2+ 	const  der  =  $derived (false ); 
3+ 
4+ 	$effect (() =>  { 
5+ 		der 
6+ 	}); 
7+  </script >
Original file line number Diff line number Diff line change 1+ import  {  test  }  from  '../../test' ; 
2+ 
3+ export  default  test ( { 
4+ 	async  test ( )  { } 
5+ } ) ; 
Original file line number Diff line number Diff line change 1+ <script >
2+ 	import  Component  from  ' ./Component.svelte'  	 
3+ 	const  arr  =  Array .from ({length:  10001 }); 
4+  </script >
5+ 
6+ {#each  arr }
7+ 	< Component  / > 
8+ {/ each }
    
 
   
 
     
   
   
          
     
  
    
     
 
    
      
     
 
     
    You can’t perform that action at this time.
  
 
    
  
     
    
      
        
     
 
       
      
     
   
 
    
    
  
 
  
 
     
    
0 commit comments