@ -9,12 +9,15 @@ import {
object _prototype
object _prototype
} from '../shared/utils.js' ;
} from '../shared/utils.js' ;
import { state as source , set } from './reactivity/sources.js' ;
import { state as source , set } from './reactivity/sources.js' ;
import { STATE_SYMBOL } from '#client/constants' ;
import { PROXY_PATH _SYMBOL , STATE_SYMBOL } from '#client/constants' ;
import { UNINITIALIZED } from '../../constants.js' ;
import { UNINITIALIZED } from '../../constants.js' ;
import * as e from './errors.js' ;
import * as e from './errors.js' ;
import { get _stack } from './dev/tracing.js' ;
import { get _stack , tag } from './dev/tracing.js' ;
import { tracing _mode _flag } from '../flags/index.js' ;
import { tracing _mode _flag } from '../flags/index.js' ;
// TODO move all regexes into shared module?
const regex _is _valid _identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/ ;
/ * *
/ * *
* @ template T
* @ template T
* @ param { T } value
* @ param { T } value
@ -61,6 +64,21 @@ export function proxy(value) {
sources . set ( 'length' , source ( /** @type {any[]} */ ( value ) . length , stack ) ) ;
sources . set ( 'length' , source ( /** @type {any[]} */ ( value ) . length , stack ) ) ;
}
}
/** Used in dev for $inspect.trace() */
var path = '' ;
/** @param {string} new_path */
function update _path ( new _path ) {
path = new _path ;
tag ( version , ` ${ path } version ` ) ;
// rename all child sources and child proxies
for ( const [ prop , source ] of sources ) {
tag ( source , get _label ( path , prop ) ) ;
}
}
return new Proxy ( /** @type {any} */ ( value ) , {
return new Proxy ( /** @type {any} */ ( value ) , {
defineProperty ( _ , prop , descriptor ) {
defineProperty ( _ , prop , descriptor ) {
if (
if (
@ -76,17 +94,20 @@ export function proxy(value) {
e . state _descriptors _fixed ( ) ;
e . state _descriptors _fixed ( ) ;
}
}
var s = sources . get ( prop ) ;
with _parent ( ( ) => {
var s = sources . get ( prop ) ;
if ( s === undefined ) {
if ( s === undefined ) {
s = with _parent ( ( ) => source ( descriptor . value , stack ) ) ;
s = source ( descriptor . value , stack ) ;
sources . set ( prop , s ) ;
sources . set ( prop , s ) ;
} else {
set (
if ( DEV && typeof prop === 'string' ) {
s ,
tag ( s , get _label ( path , prop ) ) ;
with _parent ( ( ) => proxy ( descriptor . value ) )
}
) ;
} else {
}
set ( s , descriptor . value , true ) ;
}
} ) ;
return true ;
return true ;
} ,
} ,
@ -96,11 +117,13 @@ export function proxy(value) {
if ( s === undefined ) {
if ( s === undefined ) {
if ( prop in target ) {
if ( prop in target ) {
sources . set (
const s = with _parent ( ( ) => source ( UNINITIALIZED , stack ) ) ;
prop ,
sources . set ( prop , s ) ;
with _parent ( ( ) => source ( UNINITIALIZED , stack ) )
) ;
update _version ( version ) ;
update _version ( version ) ;
if ( DEV ) {
tag ( s , get _label ( path , prop ) ) ;
}
}
}
} else {
} else {
// When working with arrays, we need to also ensure we update the length when removing
// When working with arrays, we need to also ensure we update the length when removing
@ -125,12 +148,26 @@ export function proxy(value) {
return value ;
return value ;
}
}
if ( DEV && prop === PROXY _PATH _SYMBOL ) {
return update _path ;
}
var s = sources . get ( prop ) ;
var s = sources . get ( prop ) ;
var exists = prop in target ;
var exists = prop in target ;
// create a source, but only if it's an own property and not a prototype property
// create a source, but only if it's an own property and not a prototype property
if ( s === undefined && ( ! exists || get _descriptor ( target , prop ) ? . writable ) ) {
if ( s === undefined && ( ! exists || get _descriptor ( target , prop ) ? . writable ) ) {
s = with _parent ( ( ) => source ( proxy ( exists ? target [ prop ] : UNINITIALIZED ) , stack ) ) ;
s = with _parent ( ( ) => {
var p = proxy ( exists ? target [ prop ] : UNINITIALIZED ) ;
var s = source ( p , stack ) ;
if ( DEV ) {
tag ( s , get _label ( path , prop ) ) ;
}
return s ;
} ) ;
sources . set ( prop , s ) ;
sources . set ( prop , s ) ;
}
}
@ -178,7 +215,17 @@ export function proxy(value) {
( active _effect !== null && ( ! has || get _descriptor ( target , prop ) ? . writable ) )
( active _effect !== null && ( ! has || get _descriptor ( target , prop ) ? . writable ) )
) {
) {
if ( s === undefined ) {
if ( s === undefined ) {
s = with _parent ( ( ) => source ( has ? proxy ( target [ prop ] ) : UNINITIALIZED , stack ) ) ;
s = with _parent ( ( ) => {
var p = has ? proxy ( target [ prop ] ) : UNINITIALIZED ;
var s = source ( p , stack ) ;
if ( DEV ) {
tag ( s , get _label ( path , prop ) ) ;
}
return s ;
} ) ;
sources . set ( prop , s ) ;
sources . set ( prop , s ) ;
}
}
@ -207,6 +254,10 @@ export function proxy(value) {
// the value of the original item at that index.
// the value of the original item at that index.
other _s = with _parent ( ( ) => source ( UNINITIALIZED , stack ) ) ;
other _s = with _parent ( ( ) => source ( UNINITIALIZED , stack ) ) ;
sources . set ( i + '' , other _s ) ;
sources . set ( i + '' , other _s ) ;
if ( DEV ) {
tag ( other _s , get _label ( path , i ) ) ;
}
}
}
}
}
}
}
@ -217,19 +268,23 @@ export function proxy(value) {
// object property before writing to that property.
// object property before writing to that property.
if ( s === undefined ) {
if ( s === undefined ) {
if ( ! has || get _descriptor ( target , prop ) ? . writable ) {
if ( ! has || get _descriptor ( target , prop ) ? . writable ) {
s = with _parent ( ( ) => source ( undefined , stack ) ) ;
s = with _parent ( ( ) => {
set (
var s = source ( undefined , stack ) ;
s ,
set ( s , proxy ( value ) ) ;
with _parent ( ( ) => proxy ( value ) )
return s ;
) ;
} ) ;
sources . set ( prop , s ) ;
sources . set ( prop , s ) ;
if ( DEV ) {
tag ( s , get _label ( path , prop ) ) ;
}
}
}
} else {
} else {
has = s . v !== UNINITIALIZED ;
has = s . v !== UNINITIALIZED ;
set (
s ,
var p = with _parent ( ( ) => proxy ( value ) ) ;
with _parent ( ( ) => proxy ( value ) )
set ( s , p ) ;
) ;
}
}
var descriptor = Reflect . getOwnPropertyDescriptor ( target , prop ) ;
var descriptor = Reflect . getOwnPropertyDescriptor ( target , prop ) ;
@ -282,6 +337,16 @@ export function proxy(value) {
} ) ;
} ) ;
}
}
/ * *
* @ param { string } path
* @ param { string | symbol } prop
* /
function get _label ( path , prop ) {
if ( typeof prop === 'symbol' ) return ` ${ path } [Symbol( ${ prop . description ? ? '' } )] ` ;
if ( regex _is _valid _identifier . test ( prop ) ) return ` ${ path } . ${ prop } ` ;
return /^\d+$/ . test ( prop ) ? ` ${ path } [ ${ prop } ] ` : ` ${ path } [' ${ prop } '] ` ;
}
/ * *
/ * *
* @ param { Source < number > } signal
* @ param { Source < number > } signal
* @ param { 1 | - 1 } [ d ]
* @ param { 1 | - 1 } [ d ]