@@ -27,7 +27,7 @@ import {
27
27
import { flush_tasks } from './dom/task.js' ;
28
28
import { add_owner } from './dev/ownership.js' ;
29
29
import { mutate , set , source } from './reactivity/sources.js' ;
30
- import { destroy_derived , update_derived } from './reactivity/deriveds.js' ;
30
+ import { destroy_derived , execute_derived , update_derived } from './reactivity/deriveds.js' ;
31
31
import * as e from './errors.js' ;
32
32
import { lifecycle_outside_component } from '../shared/errors.js' ;
33
33
import { FILENAME } from '../../constants.js' ;
@@ -300,40 +300,44 @@ export function update_reaction(reaction) {
300
300
var previous_reaction = active_reaction ;
301
301
var previous_skip_reaction = skip_reaction ;
302
302
var prev_derived_sources = derived_sources ;
303
+ var flags = reaction . f ;
303
304
304
305
new_deps = /** @type {null | Value[] } */ ( null ) ;
305
306
skipped_deps = 0 ;
306
307
untracked_writes = null ;
307
- active_reaction = ( reaction . f & ( BRANCH_EFFECT | ROOT_EFFECT ) ) === 0 ? reaction : null ;
308
- skip_reaction = ! is_flushing_effect && ( reaction . f & UNOWNED ) !== 0 ;
308
+ active_reaction = ( flags & ( BRANCH_EFFECT | ROOT_EFFECT ) ) === 0 ? reaction : null ;
309
+ skip_reaction = ! is_flushing_effect && ( flags & UNOWNED ) !== 0 ;
309
310
derived_sources = null ;
310
311
311
312
try {
312
313
var result = /** @type {Function } */ ( 0 , reaction . fn ) ( ) ;
313
314
var deps = reaction . deps ;
314
315
315
- if ( new_deps !== null ) {
316
- var i ;
316
+ // Avoid doing work on an effect/derived that might have become destroyed
317
+ if ( ( flags & DESTROYED ) === 0 ) {
318
+ if ( new_deps !== null ) {
319
+ var i ;
317
320
318
- remove_reactions ( reaction , skipped_deps ) ;
321
+ remove_reactions ( reaction , skipped_deps ) ;
319
322
320
- if ( deps !== null && skipped_deps > 0 ) {
321
- deps . length = skipped_deps + new_deps . length ;
322
- for ( i = 0 ; i < new_deps . length ; i ++ ) {
323
- deps [ skipped_deps + i ] = new_deps [ i ] ;
323
+ if ( deps !== null && skipped_deps > 0 ) {
324
+ deps . length = skipped_deps + new_deps . length ;
325
+ for ( i = 0 ; i < new_deps . length ; i ++ ) {
326
+ deps [ skipped_deps + i ] = new_deps [ i ] ;
327
+ }
328
+ } else {
329
+ reaction . deps = deps = new_deps ;
324
330
}
325
- } else {
326
- reaction . deps = deps = new_deps ;
327
- }
328
331
329
- if ( ! skip_reaction ) {
330
- for ( i = skipped_deps ; i < deps . length ; i ++ ) {
331
- ( deps [ i ] . reactions ??= [ ] ) . push ( reaction ) ;
332
+ if ( ! skip_reaction ) {
333
+ for ( i = skipped_deps ; i < deps . length ; i ++ ) {
334
+ ( deps [ i ] . reactions ??= [ ] ) . push ( reaction ) ;
335
+ }
332
336
}
337
+ } else if ( deps !== null && skipped_deps < deps . length ) {
338
+ remove_reactions ( reaction , skipped_deps ) ;
339
+ deps . length = skipped_deps ;
333
340
}
334
- } else if ( deps !== null && skipped_deps < deps . length ) {
335
- remove_reactions ( reaction , skipped_deps ) ;
336
- deps . length = skipped_deps ;
337
341
}
338
342
339
343
return result ;
@@ -739,9 +743,12 @@ export async function tick() {
739
743
*/
740
744
export function get ( signal ) {
741
745
var flags = signal . f ;
746
+ var is_derived = ( flags & DERIVED ) !== 0 ;
742
747
743
- if ( ( flags & DESTROYED ) !== 0 ) {
744
- return signal . v ;
748
+ // If the derived is destroyed, just execute it again without retaining
749
+ // it's memoisation properties – as the derived is stale
750
+ if ( is_derived && ( flags & DESTROYED ) !== 0 ) {
751
+ return execute_derived ( /** @type {Derived } */ ( signal ) ) ;
745
752
}
746
753
747
754
if ( is_signals_recorded ) {
@@ -778,7 +785,7 @@ export function get(signal) {
778
785
}
779
786
}
780
787
781
- if ( ( flags & DERIVED ) !== 0 ) {
788
+ if ( is_derived ) {
782
789
var derived = /** @type {Derived } */ ( signal ) ;
783
790
784
791
if ( check_dirtiness ( derived ) ) {
0 commit comments