diff --git a/package.json b/package.json index acd29c98..443c9676 100644 --- a/package.json +++ b/package.json @@ -158,8 +158,8 @@ "postinstall-postinstall": "^2.1.0", "prettier": "^3.0.3", "proxy-memoize": "^2.0.4", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "18.3.0-canary-c47c306a7-20231109", + "react-dom": "18.3.0-canary-c47c306a7-20231109", "redux": "^4.2.1", "rollup": "^4.2.0", "rollup-plugin-esbuild": "^6.1.0", diff --git a/src/react.ts b/src/react.ts index ec8dc009..39557c87 100644 --- a/src/react.ts +++ b/src/react.ts @@ -1,12 +1,6 @@ /// -import ReactExports, { - useCallback, - useDebugValue, - useEffect, - useMemo, - useRef, -} from 'react' +import { useCallback, useDebugValue, useEffect, useMemo, useRef } from 'react' import { affectedToPathList, createProxy as createProxyToCompare, @@ -21,7 +15,6 @@ import useSyncExternalStoreExports from 'use-sync-external-store/shim' import { snapshot, subscribe } from './vanilla.ts' import type { INTERNAL_Snapshot as Snapshot } from './vanilla.ts' -const { use } = ReactExports const { useSyncExternalStore } = useSyncExternalStoreExports const useAffectedDebugValue = ( @@ -133,7 +126,7 @@ export function useSnapshot( [proxyObject, notifyInSync] ), () => { - const nextSnapshot = snapshot(proxyObject, use) + const nextSnapshot = snapshot(proxyObject) try { if ( !inRender && @@ -154,7 +147,7 @@ export function useSnapshot( } return nextSnapshot }, - () => snapshot(proxyObject, use) + () => snapshot(proxyObject) ) inRender = false const currAffected = new WeakMap() diff --git a/src/vanilla.ts b/src/vanilla.ts index 2685c7d7..0c829ef5 100644 --- a/src/vanilla.ts +++ b/src/vanilla.ts @@ -33,8 +33,6 @@ type SnapshotIgnore = type Snapshot = T extends SnapshotIgnore ? T - : T extends Promise - ? Awaited : T extends object ? { readonly [K in keyof T]: Snapshot } : T @@ -45,13 +43,7 @@ type Snapshot = T extends SnapshotIgnore */ export type INTERNAL_Snapshot = Snapshot -type HandlePromise =

>(promise: P) => Awaited

- -type CreateSnapshot = ( - target: T, - version: number, - handlePromise?: HandlePromise -) => T +type CreateSnapshot = (target: T, version: number) => T type RemoveListener = () => void type AddListener = (listener: Listener) => RemoveListener @@ -86,29 +78,11 @@ const buildProxyFunction = ( !(x instanceof RegExp) && !(x instanceof ArrayBuffer), - defaultHandlePromise =

>( - promise: P & { - status?: 'pending' | 'fulfilled' | 'rejected' - value?: Awaited

- reason?: unknown - } - ) => { - switch (promise.status) { - case 'fulfilled': - return promise.value as Awaited

- case 'rejected': - throw promise.reason - default: - throw promise - } - }, - snapCache = new WeakMap(), createSnapshot: CreateSnapshot = ( target: T, - version: number, - handlePromise: HandlePromise = defaultHandlePromise + version: number ): T => { const cache = snapCache.get(target) if (cache?.[0] === version) { @@ -138,18 +112,11 @@ const buildProxyFunction = ( } if (refSet.has(value as object)) { markToTrack(value as object, false) // mark not to track - } else if (value instanceof Promise) { - delete desc.value - desc.get = () => handlePromise(value) } else if (proxyStateMap.has(value as object)) { const [target, ensureVersion] = proxyStateMap.get( value as object ) as ProxyState - desc.value = createSnapshot( - target, - ensureVersion(), - handlePromise - ) as Snapshot + desc.value = createSnapshot(target, ensureVersion()) as Snapshot } Object.defineProperty(snap, key, desc) }) @@ -337,7 +304,6 @@ const buildProxyFunction = ( objectIs, newProxy, canProxy, - defaultHandlePromise, snapCache, createSnapshot, proxyCache, @@ -391,16 +357,13 @@ export function subscribe( } } -export function snapshot( - proxyObject: T, - handlePromise?: HandlePromise -): Snapshot { +export function snapshot(proxyObject: T): Snapshot { const proxyState = proxyStateMap.get(proxyObject as object) if (import.meta.env?.MODE !== 'production' && !proxyState) { console.warn('Please use proxy object') } const [target, ensureVersion, createSnapshot] = proxyState as ProxyState - return createSnapshot(target, ensureVersion(), handlePromise) as Snapshot + return createSnapshot(target, ensureVersion()) as Snapshot } export function ref(obj: T): T & AsRef { diff --git a/tests/async.test.tsx b/tests/async.test.tsx index ef4ef888..454f72be 100644 --- a/tests/async.test.tsx +++ b/tests/async.test.tsx @@ -1,4 +1,4 @@ -import { StrictMode, Suspense } from 'react' +import { StrictMode, Suspense, use } from 'react' import { fireEvent, render, waitFor } from '@testing-library/react' import { it } from 'vitest' import { proxy, useSnapshot } from 'valtio' @@ -8,6 +8,8 @@ const sleep = (ms: number) => setTimeout(resolve, ms) }) +const use2 = (x: T): T => (x instanceof Promise ? use(x) : x) + it('delayed increment', async () => { const state = proxy({ count: 0 }) const delayedIncrement = () => { @@ -19,7 +21,7 @@ it('delayed increment', async () => { const snap = useSnapshot(state) return ( <> -

count: {snap.count}
+
count: {use2(snap.count)}
) @@ -50,7 +52,7 @@ it('delayed object', async () => { const snap = useSnapshot(state) return ( <> -
text: {snap.object.text}
+
text: {use2(snap.object).text}
) @@ -85,8 +87,8 @@ it('delayed object update fulfilled', async () => { const snap = useSnapshot(state) return ( <> -
text: {snap.object.text}
-
count: {snap.object.count}
+
text: {use2(snap.object).text}
+
count: {use2(snap.object).count}
) @@ -125,7 +127,7 @@ it('delayed falsy value', async () => { const snap = useSnapshot(state) return ( <> -
value: {String(snap.value)}
+
value: {String(use2(snap.value))}
) diff --git a/tests/snapshot.test.ts b/tests/snapshot.test.ts index 6a6494d9..57f4e091 100644 --- a/tests/snapshot.test.ts +++ b/tests/snapshot.test.ts @@ -3,28 +3,6 @@ import { TypeEqual, expectType } from 'ts-expect' import { describe, expect, it } from 'vitest' import { INTERNAL_Snapshot as Snapshot, proxy, snapshot } from 'valtio' -const sleep = (ms: number) => - new Promise((resolve) => { - setTimeout(resolve, ms) - }) - -it('getter returns value after promise is resolved', async () => { - const state = proxy({ status: sleep(10).then(() => 'done') }) - const snap = snapshot(state) - - await new Promise((resolve) => { - resolve(snap.status) - }) - .catch((thrown) => { - expect(thrown).toBeInstanceOf(Promise) - return thrown - }) - .then((value) => { - expect(value).toBe('done') - expect(snap.status).toBe('done') - }) -}) - it('should return correct snapshots without subscribe', async () => { const child = proxy({ count: 0 }) const state = proxy({ child }) @@ -119,15 +97,6 @@ describe('snapsoht typings', () => { >(true) }) - it('infers Promise result from property value', () => { - expectType< - TypeEqual< - Snapshot<{ promise: Promise }>, - { readonly promise: string } - > - >(true) - }) - it('converts arrays to readonly arrays', () => { expectType, readonly number[]>>(true) }) diff --git a/yarn.lock b/yarn.lock index 70e6fa51..a4a7addd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4259,13 +4259,13 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -react-dom@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" - integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== +react-dom@18.3.0-canary-c47c306a7-20231109: + version "18.3.0-canary-c47c306a7-20231109" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.0-canary-c47c306a7-20231109.tgz#a5b881218f760a44e09469f7c1d38c8354b6e0b9" + integrity sha512-COjHi7Ve6fCDStLinhvKxUpAVRDwkHIXtH9m8crIc0d3KjE+PMTmmIwQQj3ceypDAARQ1VFwHOhMQgXcdRAxlA== dependencies: loose-envify "^1.1.0" - scheduler "^0.23.0" + scheduler "0.24.0-canary-c47c306a7-20231109" react-is@^16.13.1: version "16.13.1" @@ -4282,10 +4282,10 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== -react@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" - integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== +react@18.3.0-canary-c47c306a7-20231109: + version "18.3.0-canary-c47c306a7-20231109" + resolved "https://registry.yarnpkg.com/react/-/react-18.3.0-canary-c47c306a7-20231109.tgz#53878c332f829d5b25f6df6c8c3746cd12a3b922" + integrity sha512-LtL67Bc+Mkuhwud559dUCU+QXL6mmtgKTGEyT41m5bDiEQdGAyYCxXo5/pigAx4p8mQb+KIT2AvCWlEDKut+PQ== dependencies: loose-envify "^1.1.0" @@ -4522,10 +4522,10 @@ saxes@^6.0.0: dependencies: xmlchars "^2.2.0" -scheduler@^0.23.0: - version "0.23.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" - integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== +scheduler@0.24.0-canary-c47c306a7-20231109: + version "0.24.0-canary-c47c306a7-20231109" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.24.0-canary-c47c306a7-20231109.tgz#9d2f0329d603279093b38999f78eac04bf64f8a0" + integrity sha512-VGLhOyPt1EIAsoGqu7DMxnVPdGAoxTmSjNJlGX31exX0stiZsvb3QuK5bKT1BaTpDOJD4VnNFoonMRN7BNh3Cg== dependencies: loose-envify "^1.1.0"