import { batch , getListener , DEV , $PROXY } from "solid-js" ; import { unwrap , isWrappable , getDataNodes , createDataNode , $RAW , $NODE , $NAME , StoreNode , setProperty , proxyDescriptor , ownKeys } from "./store" ; const proxyTraps = { get ( target , property , receiver ) { if ( property === $RAW ) return target ; if ( property === $PROXY ) return receiver ; const value = target [ property as string | number ] ; if ( property === $NODE || property === "__proto__" ) return value ; const wrappable = isWrappable ( value ) ; if ( getListener ( ) && ( typeof value !== "function" || target . hasOwnProperty ( property ) ) ) { let nodes , node ; if ( wrappable && ( nodes = getDataNodes ( value ) ) ) { node = nodes . _ || ( nodes . _ = createDataNode ( ) ) ; node ( ) ; } nodes = getDataNodes ( target ) ; node = nodes [ property ] || ( nodes [ property ] = createDataNode ( ) ) ; node ( ) ; } return wrappable ? wrap ( value , "_SOLID_DEV_" && target [ $NAME ] && `${ target [ $NAME ] }:${ property as string }` ) : value ; } , set ( target , property , value ) { setProperty ( target , property as string , unwrap ( value ) ) ; return true ; } , deleteProperty ( target , property ) { setProperty ( target , property as string , undefined ) ; return true ; } , ownKeys : ownKeys , getOwnPropertyDescriptor : proxyDescriptor } ; function wrap < T extends StoreNode > ( value , name ? ) { let p = value [ $PROXY ] ; if ( ! p ) { Object . defineProperty ( value , $PROXY , { value : ( p = new Proxy ( value , proxyTraps ) ) } ) ; const keys = Object . keys ( value ) , desc = Object . getOwnPropertyDescriptors ( value ) ; for ( let i = 0 , l = keys . length ; i < l ; i ++ ) { const prop = keys [ i ] ; if ( desc [ prop ] . get ) { const get = desc [ prop ] . get ! . bind ( p ) ; Object . defineProperty ( value , prop , { get } ) ; } if ( desc [ prop ] . set ) { const og = desc [ prop ] . set ! , set = ( v ) => batch ( ( ) => og . call ( p , v ) ) ; Object . defineProperty ( value , prop , { set } ) ; } } if ( "_SOLID_DEV_" && name ) Object . defineProperty ( value , $NAME , { value : name } ) ; } return p ; } export function createMutable < T extends StoreNode > ( state , options ? ) { const unwrappedStore = unwrap < T > ( state || { } ) ; const wrappedStore = wrap ( unwrappedStore , "_SOLID_DEV_" && ( ( options && options . name ) || DEV . hashValue ( unwrappedStore ) ) ) ; if ( "_SOLID_DEV_" ) { const name = ( options && options . name ) || DEV . hashValue ( unwrappedStore ) ; DEV . registerGraph ( name , { value : unwrappedStore } ) ; } return wrappedStore ; }