@ -1,18 +1,26 @@
/** @import { Derived, Source } from './types.js' */
/** @import { ComponentContext } from '#client' */
/** @import { Derived, Effect, Source } from './types.js' */
import { DEV } from 'esm-env' ;
import {
PROPS _IS _BINDABLE ,
PROPS _IS _IMMUTABLE ,
PROPS _IS _LAZY _INITIAL ,
PROPS _IS _RUNES ,
PROPS _IS _UPDATED
PROPS _IS _UPDATED ,
UNINITIALIZED
} from '../../../constants.js' ;
import { get _descriptor , is _function } from '../../shared/utils.js' ;
import { set , source , update } from './sources.js' ;
import { derived , derived _safe _equal } from './deriveds.js' ;
import { get , untrack } from '../runtime.js' ;
import {
active _effect ,
get ,
is _destroying _effect ,
set _active _effect ,
untrack
} from '../runtime.js' ;
import * as e from '../errors.js' ;
import { LEGACY _PROPS , STATE _SYMBOL } from '#client/constants' ;
import { DESTROYED, LEGACY_PROPS , STATE _SYMBOL } from '#client/constants' ;
import { proxy } from '../proxy.js' ;
import { capture _store _binding } from './store.js' ;
import { legacy _mode _flag } from '../../flags/index.js' ;
@ -92,7 +100,7 @@ export function rest_props(props, exclude, name) {
/ * *
* The proxy handler for legacy $$restProps and $$props
* @ type { ProxyHandler < { props : Record < string | symbol , unknown > , exclude : Array < string | symbol > , special : Record < string | symbol , ( v ? : unknown ) => unknown > , version : Source < number > } > } }
* @ type { ProxyHandler < { props : Record < string | symbol , unknown > , exclude : Array < string | symbol > , special : Record < string | symbol , ( v ? : unknown ) => unknown > , version : Source < number > , parent _effect : Effect } > } }
* /
const legacy _rest _props _handler = {
get ( target , key ) {
@ -102,17 +110,25 @@ const legacy_rest_props_handler = {
} ,
set ( target , key , value ) {
if ( ! ( key in target . special ) ) {
// Handle props that can temporarily get out of sync with the parent
/** @type {Record<string, (v?: unknown) => unknown>} */
target . special [ key ] = prop (
{
get [ key ] ( ) {
return target . props [ key ] ;
}
} ,
/** @type {string} */ ( key ) ,
PROPS _IS _UPDATED
) ;
var previous _effect = active _effect ;
try {
set _active _effect ( target . parent _effect ) ;
// Handle props that can temporarily get out of sync with the parent
/** @type {Record<string, (v?: unknown) => unknown>} */
target . special [ key ] = prop (
{
get [ key ] ( ) {
return target . props [ key ] ;
}
} ,
/** @type {string} */ ( key ) ,
PROPS _IS _UPDATED
) ;
} finally {
set _active _effect ( previous _effect ) ;
}
}
target . special [ key ] ( value ) ;
@ -151,7 +167,19 @@ const legacy_rest_props_handler = {
* @ returns { Record < string , unknown > }
* /
export function legacy _rest _props ( props , exclude ) {
return new Proxy ( { props , exclude , special : { } , version : source ( 0 ) } , legacy _rest _props _handler ) ;
return new Proxy (
{
props ,
exclude ,
special : { } ,
version : source ( 0 ) ,
// TODO this is only necessary because we need to track component
// destruction inside `prop`, because of `bind:this`, but it
// seems likely that we can simplify `bind:this` instead
parent _effect : /** @type {Effect} */ ( active _effect )
} ,
legacy _rest _props _handler
) ;
}
/ * *
@ -366,16 +394,24 @@ export function prop(props, key, flags, fallback) {
// create a derived that we can write to locally.
// Or we are in legacy mode where we always create a derived to replicate that
// Svelte 4 did not trigger updates when a primitive value was updated to the same value.
var d = ( ( flags & PROPS _IS _IMMUTABLE ) !== 0 ? derived : derived _safe _equal ) ( getter ) ;
var overridden = false ;
var d = ( ( flags & PROPS _IS _IMMUTABLE ) !== 0 ? derived : derived _safe _equal ) ( ( ) => {
overridden = false ;
return getter ( ) ;
} ) ;
// Capture the initial value if it's bindable
if ( bindable ) get ( d ) ;
var parent _effect = /** @type {Effect} */ ( active _effect ) ;
return function ( /** @type {any} */ value , /** @type {boolean} */ mutation ) {
if ( arguments . length > 0 ) {
const new _value = mutation ? get ( d ) : runes && bindable ? proxy ( value ) : value ;
set ( d , new _value ) ;
overridden = true ;
if ( fallback _value !== undefined ) {
fallback _value = new _value ;
@ -384,8 +420,12 @@ export function prop(props, key, flags, fallback) {
return value ;
}
// TODO is this still necessary post-#16263?
if ( has _destroyed _component _ctx ( d ) ) {
// special case — avoid recalculating the derived if we're in a
// teardown function and the prop was overridden locally, or the
// component was already destroyed (this latter part is necessary
// because `bind:this` can read props after the component has
// been destroyed. TODO simplify `bind:this`
if ( ( is _destroying _effect && overridden ) || ( parent _effect . f & DESTROYED ) !== 0 ) {
return d . v ;
}