@ -1,6 +1,6 @@
/** @import { ProxyMetadata, Source } from '#client' */
/** @import { ProxyMetadata, Source } from '#client' */
import { DEV } from 'esm-env' ;
import { DEV } from 'esm-env' ;
import { get , active _effect } from './runtime.js' ;
import { get , active _effect , active _reaction , set _active _reaction } from './runtime.js' ;
import { component _context } from './context.js' ;
import { component _context } from './context.js' ;
import {
import {
array _prototype ,
array _prototype ,
@ -17,14 +17,16 @@ import * as e from './errors.js';
import { get _stack } from './dev/tracing.js' ;
import { get _stack } from './dev/tracing.js' ;
import { tracing _mode _flag } from '../flags/index.js' ;
import { tracing _mode _flag } from '../flags/index.js' ;
/** @type {ProxyMetadata | null} */
var parent _metadata = null ;
/ * *
/ * *
* @ template T
* @ template T
* @ param { T } value
* @ param { T } value
* @ param { ProxyMetadata | null } [ parent ]
* @ param { Source < T > } [ prev ] dev mode only
* @ param { Source < T > } [ prev ] dev mode only
* @ returns { T }
* @ returns { T }
* /
* /
export function proxy ( value , p arent = null , p rev) {
export function proxy ( value , p rev) {
// if non-proxyable, or is already a proxy, return `value`
// if non-proxyable, or is already a proxy, return `value`
if ( typeof value !== 'object' || value === null || STATE _SYMBOL in value ) {
if ( typeof value !== 'object' || value === null || STATE _SYMBOL in value ) {
return value ;
return value ;
@ -42,6 +44,31 @@ export function proxy(value, parent = null, prev) {
var version = source ( 0 ) ;
var version = source ( 0 ) ;
var stack = DEV && tracing _mode _flag ? get _stack ( 'CreatedAt' ) : null ;
var stack = DEV && tracing _mode _flag ? get _stack ( 'CreatedAt' ) : null ;
var reaction = active _reaction ;
/ * *
* @ template T
* @ param { ( ) => T } fn
* /
var with _parent = ( fn ) => {
var previous _reaction = active _reaction ;
set _active _reaction ( reaction ) ;
/** @type {T} */
var result ;
if ( DEV ) {
var previous _metadata = parent _metadata ;
parent _metadata = metadata ;
result = fn ( ) ;
parent _metadata = previous _metadata ;
} else {
result = fn ( ) ;
}
set _active _reaction ( previous _reaction ) ;
return result ;
} ;
if ( is _proxied _array ) {
if ( is _proxied _array ) {
// We need to create the length source eagerly to ensure that
// We need to create the length source eagerly to ensure that
@ -54,7 +81,7 @@ export function proxy(value, parent = null, prev) {
if ( DEV ) {
if ( DEV ) {
metadata = {
metadata = {
parent ,
parent : parent _metadata ,
owners : null
owners : null
} ;
} ;
@ -66,7 +93,7 @@ export function proxy(value, parent = null, prev) {
metadata . owners = prev _owners ? new Set ( prev _owners ) : null ;
metadata . owners = prev _owners ? new Set ( prev _owners ) : null ;
} else {
} else {
metadata . owners =
metadata . owners =
parent === null
parent _metadata === null
? component _context !== null
? component _context !== null
? new Set ( [ component _context . function ] )
? new Set ( [ component _context . function ] )
: null
: null
@ -92,10 +119,13 @@ export function proxy(value, parent = null, prev) {
var s = sources . get ( prop ) ;
var s = sources . get ( prop ) ;
if ( s === undefined ) {
if ( s === undefined ) {
s = source( descriptor . value , stack ) ;
s = with_parent ( ( ) => source( descriptor . value , stack ) ) ;
sources . set ( prop , s ) ;
sources . set ( prop , s ) ;
} else {
} else {
set ( s , proxy ( descriptor . value , metadata ) ) ;
set (
s ,
with _parent ( ( ) => proxy ( descriptor . value ) )
) ;
}
}
return true ;
return true ;
@ -106,7 +136,10 @@ export function proxy(value, parent = null, prev) {
if ( s === undefined ) {
if ( s === undefined ) {
if ( prop in target ) {
if ( prop in target ) {
sources . set ( prop , source ( UNINITIALIZED , stack ) ) ;
sources . set (
prop ,
with _parent ( ( ) => source ( UNINITIALIZED , stack ) )
) ;
}
}
} 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
@ -140,7 +173,7 @@ export function proxy(value, parent = null, prev) {
// 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 = source( proxy ( exists ? target [ prop ] : UNINITIALIZED , metadata ), stack ) ;
s = with_parent ( ( ) => source( proxy ( exists ? target [ prop ] : UNINITIALIZED ), stack ) ) ;
sources . set ( prop , s ) ;
sources . set ( prop , s ) ;
}
}
@ -208,7 +241,7 @@ export function proxy(value, parent = null, prev) {
( 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 = source( has ? proxy ( target [ prop ] , metadata ) : UNINITIALIZED , stack ) ;
s = with_parent ( ( ) => source( has ? proxy ( target [ prop ] ) : UNINITIALIZED , stack ) ) ;
sources . set ( prop , s ) ;
sources . set ( prop , s ) ;
}
}
@ -235,7 +268,7 @@ export function proxy(value, parent = null, prev) {
// If the item exists in the original, we need to create a uninitialized source,
// If the item exists in the original, we need to create a uninitialized source,
// else a later read of the property would result in a source being created with
// else a later read of the property would result in a source being created with
// the value of the original item at that index.
// the value of the original item at that index.
other _s = source( UNINITIALIZED , stack ) ;
other _s = with_parent ( ( ) => source( UNINITIALIZED , stack ) ) ;
sources . set ( i + '' , other _s ) ;
sources . set ( i + '' , other _s ) ;
}
}
}
}
@ -247,13 +280,19 @@ export function proxy(value, parent = null, prev) {
// 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 = source ( undefined , stack ) ;
s = with _parent ( ( ) => source ( undefined , stack ) ) ;
set ( s , proxy ( value , metadata ) ) ;
set (
s ,
with _parent ( ( ) => proxy ( value ) )
) ;
sources . set ( prop , s ) ;
sources . set ( prop , s ) ;
}
}
} else {
} else {
has = s . v !== UNINITIALIZED ;
has = s . v !== UNINITIALIZED ;
set ( s , proxy ( value , metadata ) ) ;
set (
s ,
with _parent ( ( ) => proxy ( value ) )
) ;
}
}
if ( DEV ) {
if ( DEV ) {