|
|
@ -371,7 +371,11 @@ const createProxy = ( |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// Set-specific access & structural patch emission.
|
|
|
|
// Set-specific access & structural patch emission.
|
|
|
|
function getFromSet(raw: Set<any>, key: string, receiver: object): any { |
|
|
|
function getFromSet( |
|
|
|
|
|
|
|
raw: Set<any>, |
|
|
|
|
|
|
|
key: string | symbol, |
|
|
|
|
|
|
|
receiver: object |
|
|
|
|
|
|
|
): any { |
|
|
|
const meta = proxyMeta.get(receiver); |
|
|
|
const meta = proxyMeta.get(receiver); |
|
|
|
// Helper to proxy a single entry (object) & assign synthetic id if needed.
|
|
|
|
// Helper to proxy a single entry (object) & assign synthetic id if needed.
|
|
|
|
const ensureEntryProxy = (entry: any) => { |
|
|
|
const ensureEntryProxy = (entry: any) => { |
|
|
@ -516,8 +520,27 @@ function getFromSet(raw: Set<any>, key: string, receiver: object): any { |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Properly handle native iteration (for..of, Array.from, spread) by binding to the raw Set.
|
|
|
|
|
|
|
|
if (key === Symbol.iterator) { |
|
|
|
|
|
|
|
// Return a function whose `this` is the raw Set (avoids brand check failure on the proxy).
|
|
|
|
|
|
|
|
return function (this: any) { |
|
|
|
|
|
|
|
// Use raw.values() so we can still ensure child entries are proxied lazily.
|
|
|
|
|
|
|
|
const iterable = raw.values(); |
|
|
|
|
|
|
|
return { |
|
|
|
|
|
|
|
[Symbol.iterator]() { |
|
|
|
|
|
|
|
return this; |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
next() { |
|
|
|
|
|
|
|
const n = iterable.next(); |
|
|
|
|
|
|
|
if (n.done) return n; |
|
|
|
|
|
|
|
const entry = ensureEntryProxy(n.value); |
|
|
|
|
|
|
|
return { value: entry, done: false }; |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
} as Iterator<any>; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
if (key === Symbol.iterator.toString()) { |
|
|
|
if (key === Symbol.iterator.toString()) { |
|
|
|
// string form access of iterator symbol; pass through
|
|
|
|
// string form access of iterator symbol; pass through (rare path)
|
|
|
|
} |
|
|
|
} |
|
|
|
const val = (raw as any)[key]; |
|
|
|
const val = (raw as any)[key]; |
|
|
|
if (typeof val === "function") return val.bind(raw); |
|
|
|
if (typeof val === "function") return val.bind(raw); |
|
|
@ -601,8 +624,8 @@ const get = |
|
|
|
(target: object, fullKey: string, receiver: object): unknown => { |
|
|
|
(target: object, fullKey: string, receiver: object): unknown => { |
|
|
|
if (peeking) return Reflect.get(target, fullKey, receiver); |
|
|
|
if (peeking) return Reflect.get(target, fullKey, receiver); |
|
|
|
// Set handling delegated completely.
|
|
|
|
// Set handling delegated completely.
|
|
|
|
if (target instanceof Set && typeof fullKey === "string") { |
|
|
|
if (target instanceof Set) { |
|
|
|
return getFromSet(target as Set<any>, fullKey, receiver); |
|
|
|
return getFromSet(target as Set<any>, fullKey as any, receiver); |
|
|
|
} |
|
|
|
} |
|
|
|
const norm = normalizeKey(target, fullKey, isArrayMeta, receiver); |
|
|
|
const norm = normalizeKey(target, fullKey, isArrayMeta, receiver); |
|
|
|
if ((norm as any).shortCircuit) return (norm as any).shortCircuit; // returned meta proxy
|
|
|
|
if ((norm as any).shortCircuit) return (norm as any).shortCircuit; // returned meta proxy
|
|
|
|