@@ -15,33 +15,21 @@ type CollectionRawType = "Set" | "Map" | "WeakMap";
1515const objectToString = Object . prototype . toString ;
1616const objectHasOwnProperty = Object . prototype . hasOwnProperty ;
1717
18- // Use arrays because Array.includes is faster than Set.has for small arrays
19- const SUPPORTED_RAW_TYPES = [ "Object" , "Array" , "Set" , "Map" , "WeakMap" ] ;
20- const COLLECTION_RAW_TYPES = [ "Set" , "Map" , "WeakMap" ] ;
21-
22- /**
23- * extract "RawType" from strings like "[object RawType]" => this lets us ignore
24- * many native objects such as Promise (whose toString is [object Promise])
25- * or Date ([object Date]), while also supporting collections without using
26- * instanceof in a loop
27- *
28- * @param obj the object to check
29- * @returns the raw type of the object
30- */
31- function rawType ( obj : any ) {
32- return objectToString . call ( toRaw ( obj ) ) . slice ( 8 , - 1 ) ;
33- }
3418/**
3519 * Checks whether a given value can be made into a proxy object.
3620 *
3721 * @param value the value to check
3822 * @returns whether the value can be made proxy
3923 */
4024function canBeMadeReactive ( value : any ) : boolean {
41- if ( typeof value !== "object" ) {
25+ if ( typeof value !== "object" || value === null ) {
4226 return false ;
4327 }
44- return SUPPORTED_RAW_TYPES . includes ( rawType ( value ) ) ;
28+ const raw = toRaw ( value ) ;
29+ if ( Array . isArray ( raw ) || raw instanceof Set || raw instanceof Map || raw instanceof WeakMap ) {
30+ return true ;
31+ }
32+ return objectToString . call ( raw ) === "[object Object]" ;
4533}
4634/**
4735 * Creates a proxy from the given object/callback if possible and returns it,
@@ -151,10 +139,16 @@ export function proxifyTarget<T extends Target>(target: T, atom: Atom | null): T
151139 return reactive as T ;
152140 }
153141
154- const targetRawType = rawType ( target ) ;
155- const handler = COLLECTION_RAW_TYPES . includes ( targetRawType )
156- ? collectionsProxyHandler ( target as Collection , targetRawType as CollectionRawType , atom )
157- : basicProxyHandler < T > ( atom ) ;
142+ let handler : ProxyHandler < any > ;
143+ if ( target instanceof Map ) {
144+ handler = collectionsProxyHandler ( target as unknown as Collection , "Map" , atom ) ;
145+ } else if ( target instanceof Set ) {
146+ handler = collectionsProxyHandler ( target as unknown as Collection , "Set" , atom ) ;
147+ } else if ( target instanceof WeakMap ) {
148+ handler = collectionsProxyHandler ( target as unknown as Collection , "WeakMap" , atom ) ;
149+ } else {
150+ handler = basicProxyHandler < T > ( atom ) ;
151+ }
158152 const proxy = new Proxy ( target , handler as ProxyHandler < T > ) as Reactive < T > ;
159153
160154 proxyCache . set ( target , proxy ) ;
@@ -203,13 +197,21 @@ export function proxy<T extends Target>(target: T): T {
203197function basicProxyHandler < T extends Target > ( atom : Atom | null ) : ProxyHandler < T > {
204198 return {
205199 get ( target , key , receiver ) {
200+ onReadTargetKey ( target , key , atom ) ;
201+ const value = Reflect . get ( target , key , receiver ) ;
202+ // Fast path: signal-based proxies and primitive values don't need wrapping
203+ if ( atom || typeof value !== "object" || value === null ) {
204+ return value ;
205+ }
206+ if ( ! canBeMadeReactive ( value ) ) {
207+ return value ;
208+ }
206209 // non-writable non-configurable properties cannot be made proxy
207210 const desc = Object . getOwnPropertyDescriptor ( target , key ) ;
208211 if ( desc && ! desc . writable && ! desc . configurable ) {
209- return Reflect . get ( target , key , receiver ) ;
212+ return value ;
210213 }
211- onReadTargetKey ( target , key , atom ) ;
212- return possiblyReactive ( Reflect . get ( target , key , receiver ) , atom ) ;
214+ return proxifyTarget ( value , null ) ;
213215 } ,
214216 set ( target , key , value , receiver ) {
215217 const hadKey = objectHasOwnProperty . call ( target , key ) ;
0 commit comments