@@ -28,12 +28,14 @@ import {
2828 UNOWNED ,
2929 MAYBE_DIRTY ,
3030 BLOCK_EFFECT ,
31- ROOT_EFFECT
31+ ROOT_EFFECT ,
32+ ASYNC_DERIVED
3233} from '../constants.js' ;
3334import * as e from '../errors.js' ;
3435import { legacy_mode_flag , tracing_mode_flag } from '../../flags/index.js' ;
3536import { get_stack } from '../dev/tracing.js' ;
3637import { component_context , is_runes } from '../context.js' ;
38+ import { get_boundary } from '../dom/blocks/boundary.js' ;
3739
3840export let inspect_effects = new Set ( ) ;
3941
@@ -169,6 +171,7 @@ export function set(source, value) {
169171 */
170172export function internal_set ( source , value ) {
171173 if ( ! source . equals ( value ) ) {
174+ possibly_fork ( source ) ;
172175
173176 mark_reactions ( source , DIRTY ) ;
174177
@@ -258,9 +261,10 @@ export function update_pre(source, d = 1) {
258261/**
259262 * @param {Value } signal
260263 * @param {number } status should be DIRTY or MAYBE_DIRTY
264+ * @param {Value } [parent]
261265 * @returns {void }
262266 */
263- export function mark_reactions ( signal , status ) {
267+ export function mark_reactions ( signal , status , parent , only_boundary = false ) {
264268 var reactions = signal . reactions ;
265269 if ( reactions === null ) return ;
266270
@@ -277,6 +281,24 @@ export function mark_reactions(signal, status) {
277281 // In legacy mode, skip the current effect to prevent infinite loops
278282 if ( ! runes && reaction === active_effect ) continue ;
279283
284+ if ( only_boundary ) {
285+ if ( ( flags & ( DERIVED ) ) === 0 ) {
286+ var boundary = get_boundary ( /** @type {Effect } */ ( reaction ) ) ;
287+ if ( ! boundary ) {
288+ continue ;
289+ }
290+ }
291+ } else if ( ( flags & ( DERIVED | ASYNC_DERIVED ) ) === 0 ) {
292+ boundary = get_boundary ( /** @type {Effect } */ ( reaction ) ) ;
293+ if ( boundary ) {
294+ // @ts -ignore
295+ var forks = boundary . fn . forks ;
296+ if ( forks . has ( signal ) || forks . has ( parent ) ) {
297+ continue ;
298+ }
299+ }
300+ }
301+
280302 // Inspect effects need to run immediately, so that the stack trace makes sense
281303 if ( DEV && ( flags & INSPECT_EFFECT ) !== 0 ) {
282304 inspect_effects . add ( reaction ) ;
@@ -288,10 +310,76 @@ export function mark_reactions(signal, status) {
288310 // If the signal a) was previously clean or b) is an unowned derived, then mark it
289311 if ( ( flags & ( CLEAN | UNOWNED ) ) !== 0 ) {
290312 if ( ( flags & DERIVED ) !== 0 ) {
291- mark_reactions ( /** @type {Derived } */ ( reaction ) , MAYBE_DIRTY ) ;
313+ mark_reactions ( /** @type {Derived } */ ( reaction ) , MAYBE_DIRTY , signal , only_boundary ) ;
292314 } else {
293315 schedule_effect ( /** @type {Effect } */ ( reaction ) ) ;
294316 }
295317 }
296318 }
297319}
320+
321+ /**
322+ * @param {Source | Derived } signal
323+ * @param {any } forks
324+ */
325+ function fork_dependencies ( signal , forks ) {
326+ var entry = forks . get ( signal ) ;
327+ if ( entry === undefined ) {
328+ entry = { v : signal . v } ;
329+ forks . set ( signal , entry ) ;
330+ if ( ( signal . f & DERIVED ) !== 0 ) {
331+ var deps = /** @type {Derived } */ ( signal ) . deps ;
332+ if ( deps !== null ) {
333+ for ( var i = 0 ; i < deps . length ; i ++ ) {
334+ fork_dependencies ( deps [ i ] , forks ) ;
335+ }
336+ }
337+ }
338+ }
339+ }
340+
341+ /**
342+ * @param {Value } signal
343+ * @returns {void }
344+ */
345+ function possibly_fork ( signal ) {
346+ var reactions = signal . reactions ;
347+ if ( reactions === null ) return ;
348+
349+ var runes = is_runes ( ) ;
350+ var length = reactions . length ;
351+
352+ for ( var i = 0 ; i < length ; i ++ ) {
353+ var reaction = reactions [ i ] ;
354+ var flags = reaction . f ;
355+
356+ // Skip any effects that are already dirty
357+ if ( ( flags & DIRTY ) !== 0 ) continue ;
358+
359+ // In legacy mode, skip the current effect to prevent infinite loops
360+ if ( ! runes && reaction === active_effect ) continue ;
361+
362+ // If the signal a) was previously clean or b) is an unowned derived, then mark it
363+ if ( ( flags & ( CLEAN | UNOWNED ) ) !== 0 ) {
364+ if ( ( flags & DERIVED ) !== 0 ) {
365+ possibly_fork ( /** @type {Derived } */ ( reaction ) ) ;
366+ } else {
367+ if ( ( reaction . f & ASYNC_DERIVED ) !== 0 ) {
368+ // if (active_effect === signal) {
369+ // set_signal_status(signal, MAYBE_DIRTY);
370+ // return;
371+ // }
372+ var boundary = get_boundary ( /** @type {Effect } */ ( reaction ) ) ;
373+ // @ts -ignore
374+ var forks = boundary . fn . forks ;
375+ var deps = reaction . deps ;
376+ if ( deps !== null ) {
377+ for ( var s = 0 ; s < deps . length ; s ++ ) {
378+ fork_dependencies ( deps [ s ] , forks ) ;
379+ }
380+ }
381+ }
382+ }
383+ }
384+ }
385+ }
0 commit comments