@@ -10,10 +10,17 @@ import {
1010import { get_descriptor , is_function } from '../../shared/utils.js' ;
1111import { mutable_source , set , source } from './sources.js' ;
1212import { derived , derived_safe_equal } from './deriveds.js' ;
13- import { get , is_signals_recorded , untrack , update } from '../runtime.js' ;
13+ import {
14+ active_effect ,
15+ get ,
16+ is_signals_recorded ,
17+ set_active_effect ,
18+ untrack ,
19+ update
20+ } from '../runtime.js' ;
1421import { safe_equals } from './equality.js' ;
1522import * as e from '../errors.js' ;
16- import { LEGACY_DERIVED_PROP } from '../constants.js' ;
23+ import { BRANCH_EFFECT , LEGACY_DERIVED_PROP , ROOT_EFFECT } from '../constants.js' ;
1724import { proxy } from '../proxy.js' ;
1825
1926/**
@@ -217,6 +224,26 @@ export function spread_props(...props) {
217224 return new Proxy ( { props } , spread_props_handler ) ;
218225}
219226
227+ /**
228+ * @template T
229+ * @param {() => T } fn
230+ * @returns {T }
231+ */
232+ function with_parent_branch ( fn ) {
233+ var effect = active_effect ;
234+ var previous_effect = active_effect ;
235+
236+ while ( effect !== null && ( effect . f & ( BRANCH_EFFECT | ROOT_EFFECT ) ) === 0 ) {
237+ effect = effect . parent ;
238+ }
239+ try {
240+ set_active_effect ( effect ) ;
241+ return fn ( ) ;
242+ } finally {
243+ set_active_effect ( previous_effect ) ;
244+ }
245+ }
246+
220247/**
221248 * This function is responsible for synchronizing a possibly bound prop with the inner component state.
222249 * It is used whenever the compiler sees that the component writes to the prop, or when it has a default prop_value.
@@ -276,8 +303,8 @@ export function prop(props, key, flags, fallback) {
276303 } else {
277304 // Svelte 4 did not trigger updates when a primitive value was updated to the same value.
278305 // Replicate that behavior through using a derived
279- var derived_getter = ( immutable ? derived : derived_safe_equal ) (
280- ( ) => /** @type {V } */ ( props [ key ] )
306+ var derived_getter = with_parent_branch ( ( ) =>
307+ ( immutable ? derived : derived_safe_equal ) ( ( ) => /** @type {V } */ ( props [ key ] ) )
281308 ) ;
282309 derived_getter . f |= LEGACY_DERIVED_PROP ;
283310 getter = ( ) => {
@@ -321,19 +348,21 @@ export function prop(props, key, flags, fallback) {
321348 // The derived returns the current value. The underlying mutable
322349 // source is written to from various places to persist this value.
323350 var inner_current_value = mutable_source ( prop_value ) ;
324- var current_value = derived ( ( ) => {
325- var parent_value = getter ( ) ;
326- var child_value = get ( inner_current_value ) ;
327-
328- if ( from_child ) {
329- from_child = false ;
330- was_from_child = true ;
331- return child_value ;
332- }
351+ var current_value = with_parent_branch ( ( ) =>
352+ derived ( ( ) => {
353+ var parent_value = getter ( ) ;
354+ var child_value = get ( inner_current_value ) ;
355+
356+ if ( from_child ) {
357+ from_child = false ;
358+ was_from_child = true ;
359+ return child_value ;
360+ }
333361
334- was_from_child = false ;
335- return ( inner_current_value . v = parent_value ) ;
336- } ) ;
362+ was_from_child = false ;
363+ return ( inner_current_value . v = parent_value ) ;
364+ } )
365+ ) ;
337366
338367 if ( ! immutable ) current_value . equals = safe_equals ;
339368
0 commit comments