From ba7e1b0654ece7b698e1ec35c3e98dc84899bce2 Mon Sep 17 00:00:00 2001 From: Michael Sweeney Date: Sun, 10 May 2026 09:13:22 -0700 Subject: [PATCH 1/3] added initial pass at new methods --- src/react/utils/useProxy.ts | 2 +- src/vanilla/utils/proxyMap.ts | 50 ++++++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/react/utils/useProxy.ts b/src/react/utils/useProxy.ts index 38bb4322..ad145a00 100644 --- a/src/react/utils/useProxy.ts +++ b/src/react/utils/useProxy.ts @@ -33,7 +33,7 @@ export function useProxy( ;(snapshot as any)[DUMMY_SYMBOL] let isRendering = true - // eslint-disable-next-line react-hooks/immutability + useLayoutEffect(() => { // This is an intentional hack // It might not work with React Compiler diff --git a/src/vanilla/utils/proxyMap.ts b/src/vanilla/utils/proxyMap.ts index 12219f00..f4a94532 100644 --- a/src/vanilla/utils/proxyMap.ts +++ b/src/vanilla/utils/proxyMap.ts @@ -3,13 +3,19 @@ import { proxy, unstable_getInternalStates } from '../../vanilla.ts' const { proxyStateMap, snapCache } = unstable_getInternalStates() const isProxy = (x: any) => proxyStateMap.has(x) -type InternalProxyObject = Map & { - data: Array - index: number - epoch: number - toJSON: () => Map +type MapGetOrInsert = { + getOrInsert(key: K, defaultValue: V): V + getOrInsertComputed(key: K, callbackFn: (key: K) => V): V } +type InternalProxyObject = Map & + Partial> & { + data: Array + index: number + epoch: number + toJSON: () => Map + } + /** * Determines if an object is a proxy Map created with proxyMap */ @@ -178,12 +184,36 @@ export function proxyMap(entries?: Iterable<[K, V]> | undefined | null) { toJSON(): Map { return new Map(this.entries()) }, - // [ONLY-TS-5.9.3] [ONLY-TS-5.8.3] [ONLY-TS-5.7.3] [ONLY-TS-5.6.3] @ts-expect-error ignore - getOrInsert() { - throw new Error('not implemented') + // [ONLY-TS-5.9.3] [ONLY-TS-5.8.3] [ONLY-TS-5.7.3] [ONLY-TS-5.6.3] @ts-ignore ignore + getOrInsert(key: K, defaultValue: V): V { + if (!isProxy(this)) { + throw new Error('Cannot perform mutations on a snapshot') + } + const index = indexMap.get(key) + if (index !== undefined) { + return this.data[index]! + } + indexMap.set(key, this.index) + this.data[this.index] = defaultValue + this.index++ + this.epoch++ + return defaultValue }, - getOrInsertComputed() { - throw new Error('not implemented') + // [ONLY-TS-5.9.3] [ONLY-TS-5.8.3] [ONLY-TS-5.7.3] [ONLY-TS-5.6.3] @ts-ignore ignore + getOrInsertComputed(key: K, callbackFn: (key: K) => V): V { + if (!isProxy(this)) { + throw new Error('Cannot perform mutations on a snapshot') + } + const index = indexMap.get(key) + if (index !== undefined) { + return this.data[index]! + } + const value = callbackFn(key) + indexMap.set(key, this.index) + this.data[this.index] = value + this.index++ + this.epoch++ + return value }, } From 4e11f466a595e69c3e49892fdf49365ea0192dfc Mon Sep 17 00:00:00 2001 From: Michael Sweeney Date: Sun, 10 May 2026 16:05:45 -0700 Subject: [PATCH 2/3] removed unnecessary change --- src/react/utils/useProxy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/react/utils/useProxy.ts b/src/react/utils/useProxy.ts index ad145a00..38bb4322 100644 --- a/src/react/utils/useProxy.ts +++ b/src/react/utils/useProxy.ts @@ -33,7 +33,7 @@ export function useProxy( ;(snapshot as any)[DUMMY_SYMBOL] let isRendering = true - + // eslint-disable-next-line react-hooks/immutability useLayoutEffect(() => { // This is an intentional hack // It might not work with React Compiler From b0b71b786eb26cb06a3764db1cf6636be2657c22 Mon Sep 17 00:00:00 2001 From: daishi Date: Mon, 11 May 2026 10:15:29 +0900 Subject: [PATCH 3/3] eliminate type hack --- src/vanilla/utils/proxyMap.ts | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/vanilla/utils/proxyMap.ts b/src/vanilla/utils/proxyMap.ts index f4a94532..6bcc24e3 100644 --- a/src/vanilla/utils/proxyMap.ts +++ b/src/vanilla/utils/proxyMap.ts @@ -3,19 +3,13 @@ import { proxy, unstable_getInternalStates } from '../../vanilla.ts' const { proxyStateMap, snapCache } = unstable_getInternalStates() const isProxy = (x: any) => proxyStateMap.has(x) -type MapGetOrInsert = { - getOrInsert(key: K, defaultValue: V): V - getOrInsertComputed(key: K, callbackFn: (key: K) => V): V +type InternalProxyObject = Map & { + data: Array + index: number + epoch: number + toJSON: () => Map } -type InternalProxyObject = Map & - Partial> & { - data: Array - index: number - epoch: number - toJSON: () => Map - } - /** * Determines if an object is a proxy Map created with proxyMap */