From f03009351bfa4d244c27baf338a069cd55a6130e Mon Sep 17 00:00:00 2001 From: daishi Date: Sat, 4 Sep 2021 21:07:03 +0900 Subject: [PATCH 01/11] wip: use-sync-external-store --- package.json | 3 + src/core/Provider.ts | 12 ++-- src/core/contexts.ts | 30 ++++---- src/core/store.ts | 5 -- src/core/useAtom.ts | 57 +++++++-------- src/core/useMutableSource.ts | 116 ------------------------------- src/devtools/useAtomsSnapshot.ts | 17 ++--- src/index.ts | 6 -- yarn.lock | 5 ++ 9 files changed, 60 insertions(+), 191 deletions(-) delete mode 100644 src/core/useMutableSource.ts diff --git a/package.json b/package.json index a7fe6eb65b..eaa9b8ee5e 100644 --- a/package.json +++ b/package.json @@ -170,6 +170,9 @@ "tests/**/*.{js,ts,tsx}" ] }, + "dependencies": { + "use-sync-external-store": "^0.0.0-experimental-1314299c7-20210901" + }, "devDependencies": { "@babel/core": "^7.15.0", "@babel/plugin-transform-react-jsx": "^7.14.9", diff --git a/src/core/Provider.ts b/src/core/Provider.ts index e7552607f4..f5fa56ae87 100644 --- a/src/core/Provider.ts +++ b/src/core/Provider.ts @@ -1,5 +1,7 @@ import { createElement, useCallback, useDebugValue, useRef } from 'react' import type { PropsWithChildren } from 'react' +// @ts-ignore +import { useSyncExternalStore } from 'use-sync-external-store' import type { Atom, Scope } from './atom' import { ScopeContainer, @@ -10,7 +12,6 @@ import { import type { ScopeContainerForDevelopment } from './contexts' import { DEV_GET_ATOM_STATE, DEV_GET_MOUNTED } from './store' import type { AtomState, Store } from './store' -import { useMutableSource } from './useMutableSource' export const Provider = ({ initialValues, @@ -75,11 +76,10 @@ const stateToPrintable = ([store, atoms]: [Store, Atom[]]) => // We keep a reference to the atoms in Provider's registeredAtoms in dev mode, // so atoms aren't garbage collected by the WeakMap of mounted atoms const useDebugState = (scopeContainer: ScopeContainerForDevelopment) => { - const [store, , devMutableSource, devSubscribe] = scopeContainer - const atoms = useMutableSource( - devMutableSource, - useCallback((devContainer) => devContainer.atoms, []), - devSubscribe + const [store, devStore] = scopeContainer + const atoms = useSyncExternalStore( + devStore.subscribe, + useCallback(() => devStore.atoms, [devStore]) ) useDebugValue([store, atoms], stateToPrintable) } diff --git a/src/core/contexts.ts b/src/core/contexts.ts index cada3fc217..687ca7a2b5 100644 --- a/src/core/contexts.ts +++ b/src/core/contexts.ts @@ -1,50 +1,44 @@ import { createContext } from 'react' import type { Context } from 'react' import type { Atom, Scope } from './atom' -import { GET_VERSION, createStore } from './store' -import { createMutableSource } from './useMutableSource' +import { createStore } from './store' const createScopeContainerForProduction = ( initialValues?: Iterable, unknown]> ) => { const store = createStore(initialValues) - const mutableSource = createMutableSource(store, store[GET_VERSION]) - return [store, mutableSource] as const + return [store] as const } const createScopeContainerForDevelopment = ( initialValues?: Iterable, unknown]> ) => { - let devVersion = 0 - const devListeners = new Set<() => void>() - const devContainer = { + const devStore = { + listeners: new Set<() => void>(), + subscribe: (callback: () => void) => { + devStore.listeners.add(callback) + return () => devStore.listeners.delete(callback) + }, atoms: Array.from(initialValues ?? []).map(([a]) => a), } const stateListener = (updatedAtom: Atom, isNewAtom: boolean) => { - ++devVersion if (isNewAtom) { // FIXME memory leak // we should probably remove unmounted atoms eventually - devContainer.atoms = [...devContainer.atoms, updatedAtom] + devStore.atoms = [...devStore.atoms, updatedAtom] } Promise.resolve().then(() => { - devListeners.forEach((listener) => listener()) + devStore.listeners.forEach((listener) => listener()) }) } const store = createStore(initialValues, stateListener) - const mutableSource = createMutableSource(store, store[GET_VERSION]) - const devMutableSource = createMutableSource(devContainer, () => devVersion) - const devSubscribe = (_: unknown, callback: () => void) => { - devListeners.add(callback) - return () => devListeners.delete(callback) - } - return [store, mutableSource, devMutableSource, devSubscribe] as const + return [store, devStore] as const } export const isDevScopeContainer = ( scopeContainer: ScopeContainer ): scopeContainer is ScopeContainerForDevelopment => { - return scopeContainer.length > 2 + return scopeContainer.length > 1 } type ScopeContainerForProduction = ReturnType< diff --git a/src/core/store.ts b/src/core/store.ts index a9075bc5bc..e83a9213e9 100644 --- a/src/core/store.ts +++ b/src/core/store.ts @@ -66,7 +66,6 @@ type Mounted = { type StateListener = (updatedAtom: AnyAtom, isNewAtom: boolean) => void // store methods -export const GET_VERSION = 'v' export const READ_ATOM = 'r' export const WRITE_ATOM = 'w' export const FLUSH_PENDING = 'f' @@ -79,7 +78,6 @@ export const createStore = ( initialValues?: Iterable, stateListener?: StateListener ) => { - let version = 0 const atomStateMap = new WeakMap() const mountedMap = new WeakMap() const pendingMap = new Map() @@ -569,7 +567,6 @@ export const createStore = ( if (stateListener) { stateListener(atom, isNewAtom) } - ++version if (!pendingMap.has(atom)) { pendingMap.set(atom, prevDependencies) } @@ -619,7 +616,6 @@ export const createStore = ( if (typeof process === 'object' && process.env.NODE_ENV !== 'production') { return { - [GET_VERSION]: () => version, [READ_ATOM]: readAtom, [WRITE_ATOM]: writeAtom, [FLUSH_PENDING]: flushPending, @@ -630,7 +626,6 @@ export const createStore = ( } } return { - [GET_VERSION]: () => version, [READ_ATOM]: readAtom, [WRITE_ATOM]: writeAtom, [FLUSH_PENDING]: flushPending, diff --git a/src/core/useAtom.ts b/src/core/useAtom.ts index 76cfeec748..04d6ab3022 100644 --- a/src/core/useAtom.ts +++ b/src/core/useAtom.ts @@ -1,9 +1,9 @@ import { useCallback, useContext, useDebugValue, useEffect } from 'react' +// @ts-ignore +import { useSyncExternalStore } from 'use-sync-external-store' import type { Atom, Scope, SetAtom, WritableAtom } from './atom' import { getScopeContext } from './contexts' import { FLUSH_PENDING, READ_ATOM, SUBSCRIBE_ATOM, WRITE_ATOM } from './store' -import type { Store } from './store' -import { useMutableSource } from './useMutableSource' const isWritable = ( atom: Atom | WritableAtom @@ -41,32 +41,6 @@ export function useAtom( atom: Atom | WritableAtom, scope?: Scope ) { - const getAtomValue = useCallback( - (store: Store) => { - const atomState = store[READ_ATOM](atom) - if (atomState.e) { - throw atomState.e // read error - } - if (atomState.p) { - throw atomState.p // read promise - } - if (atomState.w) { - throw atomState.w // write promise - } - if ('v' in atomState) { - return atomState.v as Value - } - throw new Error('no atom value') - }, - [atom] - ) - - const subscribe = useCallback( - (store: Store, callback: () => void) => - store[SUBSCRIBE_ATOM](atom, callback), - [atom] - ) - if ('scope' in atom) { console.warn( 'atom.scope is deprecated. Please do useAtom(atom, scope) instead.' @@ -75,8 +49,31 @@ export function useAtom( } const ScopeContext = getScopeContext(scope) - const [store, mutableSource] = useContext(ScopeContext) - const value = useMutableSource(mutableSource, getAtomValue, subscribe) + const [store] = useContext(ScopeContext) + + const subscribe = useCallback( + (callback: () => void) => store[SUBSCRIBE_ATOM](atom, callback), + [store, atom] + ) + + const getAtomValue = useCallback(() => { + const atomState = store[READ_ATOM](atom) + if (atomState.e) { + throw atomState.e // read error + } + if (atomState.p) { + throw atomState.p // read promise + } + if (atomState.w) { + throw atomState.w // write promise + } + if ('v' in atomState) { + return atomState.v as Value + } + throw new Error('no atom value') + }, [store, atom]) + + const value = useSyncExternalStore(subscribe, getAtomValue) useEffect(() => { store[FLUSH_PENDING]() }) diff --git a/src/core/useMutableSource.ts b/src/core/useMutableSource.ts deleted file mode 100644 index 2b1599e21e..0000000000 --- a/src/core/useMutableSource.ts +++ /dev/null @@ -1,116 +0,0 @@ -/* -export { - unstable_createMutableSource as createMutableSource, - unstable_useMutableSource as useMutableSource, -} from 'react' -*/ - -// useMutableSource emulation almost equivalent to useSubscription - -import { useEffect, useRef, useState } from 'react' - -const TARGET = '_uMS_T' -const GET_VERSION = '_uMS_V' - -type MutableSource = { - [TARGET]: T - [GET_VERSION]: (target: T) => V -} - -export const createMutableSource = ( - target: T, - getVersion: (target: T) => V -): MutableSource => ({ - [TARGET]: target, - [GET_VERSION]: getVersion, -}) - -export const useMutableSource = ( - source: MutableSource, - getSnapshot: (target: T) => S, - subscribe: (target: T, callback: () => void) => () => void -) => { - const lastVersion = useRef() - const currentVersion = source[GET_VERSION](source[TARGET]) - const [state, setState] = useState( - () => - [ - /* [0] */ source, - /* [1] */ getSnapshot, - /* [2] */ subscribe, - /* [3] */ currentVersion, - /* [4] */ getSnapshot(source[TARGET]), - ] as const - ) - let currentSnapshot = state[4] - if ( - state[0] !== source || - state[1] !== getSnapshot || - state[2] !== subscribe - ) { - currentSnapshot = getSnapshot(source[TARGET]) - setState([ - /* [0] */ source, - /* [1] */ getSnapshot, - /* [2] */ subscribe, - /* [3] */ currentVersion, - /* [4] */ currentSnapshot, - ]) - } else if ( - currentVersion !== state[3] && - currentVersion !== lastVersion.current - ) { - currentSnapshot = getSnapshot(source[TARGET]) - if (!Object.is(currentSnapshot, state[4])) { - setState([ - /* [0] */ source, - /* [1] */ getSnapshot, - /* [2] */ subscribe, - /* [3] */ currentVersion, - /* [4] */ currentSnapshot, - ]) - } - } - useEffect(() => { - let didUnsubscribe = false - const checkForUpdates = () => { - if (didUnsubscribe) { - return - } - try { - const nextSnapshot = getSnapshot(source[TARGET]) - const nextVersion = source[GET_VERSION](source[TARGET]) - lastVersion.current = nextVersion - setState((prev) => { - if ( - prev[0] !== source || - prev[1] !== getSnapshot || - prev[2] !== subscribe - ) { - return prev - } - if (Object.is(prev[4], nextSnapshot)) { - return prev - } - return [ - /* [0] */ prev[0], - /* [1] */ prev[1], - /* [2] */ prev[2], - /* [3] */ nextVersion, - /* [4] */ nextSnapshot, - ] - }) - } catch (e) { - // schedule update - setState((prev) => [...prev]) - } - } - const unsubscribe = subscribe(source[TARGET], checkForUpdates) - checkForUpdates() - return () => { - didUnsubscribe = true - unsubscribe() - } - }, [source, getSnapshot, subscribe]) - return currentSnapshot -} diff --git a/src/devtools/useAtomsSnapshot.ts b/src/devtools/useAtomsSnapshot.ts index cad49e1305..02f2791ca9 100644 --- a/src/devtools/useAtomsSnapshot.ts +++ b/src/devtools/useAtomsSnapshot.ts @@ -1,8 +1,7 @@ import { useCallback, useContext } from 'react' -import { - SECRET_INTERNAL_getScopeContext as getScopeContext, - SECRET_INTERNAL_useMutableSource as useMutableSource, -} from 'jotai' +// @ts-ignore +import { useSyncExternalStore } from 'use-sync-external-store' +import { SECRET_INTERNAL_getScopeContext as getScopeContext } from 'jotai' import type { Atom, Scope } from '../core/atom' // NOTE importing from '../core/contexts' is across bundles and actually copying code import { isDevScopeContainer } from '../core/contexts' @@ -19,13 +18,11 @@ export function useAtomsSnapshot(scope?: Scope): AtomsSnapshot { throw Error('useAtomsSnapshot can only be used in dev mode.') } - const [store, , devMutableSource, devSubscribe] = scopeContainer + const [store, devStore] = scopeContainer - const atoms = useMutableSource( - devMutableSource, - // FIXME HACK creating new reference to force re-render - useCallback((devContainer) => [...devContainer.atoms], []), - devSubscribe + const atoms: Atom[] = useSyncExternalStore( + devStore.subscribe, + useCallback(() => devStore.atoms, [devStore]) ) const atomToAtomValueTuples = atoms diff --git a/src/index.ts b/src/index.ts index 49dd947e1d..33a51f704c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,9 +15,3 @@ export type { * It can change without notice. Do not use it in application code. */ export { getScopeContext as SECRET_INTERNAL_getScopeContext } from './core/contexts' - -/** - * This is exported for internal use only. - * It can change without notice. Do not use it in application code. - */ -export { useMutableSource as SECRET_INTERNAL_useMutableSource } from './core/useMutableSource' diff --git a/yarn.lock b/yarn.lock index 19e756b6e3..119a6cfbd1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7222,6 +7222,11 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" +use-sync-external-store@^0.0.0-experimental-1314299c7-20210901: + version "0.0.0-experimental-1314299c7-20210901" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-0.0.0-experimental-1314299c7-20210901.tgz#813df01533d654913463becb4baf21d012630b41" + integrity sha512-Iu5x3XZTSw/ORhEu0AUvQc05cLBc7UV8tXiP1zuXJlxEF5dYV+Dmz3YFJHWcb8L+7aBTUIhCfat/qvQNf5LdKw== + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" From 3b5741e280c5f553e8a95c22a90a733807b5c053 Mon Sep 17 00:00:00 2001 From: daishi Date: Sun, 5 Sep 2021 10:05:44 +0900 Subject: [PATCH 02/11] use reducer just like that --- package.json | 4 +--- src/core/Provider.ts | 21 ++++++++++++++------- src/core/contexts.ts | 4 +++- src/core/useAtom.ts | 24 +++++++++++++++--------- src/devtools/useAtomsSnapshot.ts | 15 ++++++++------- yarn.lock | 5 ----- 6 files changed, 41 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index eaa9b8ee5e..daa02ec890 100644 --- a/package.json +++ b/package.json @@ -170,9 +170,7 @@ "tests/**/*.{js,ts,tsx}" ] }, - "dependencies": { - "use-sync-external-store": "^0.0.0-experimental-1314299c7-20210901" - }, + "dependencies": {}, "devDependencies": { "@babel/core": "^7.15.0", "@babel/plugin-transform-react-jsx": "^7.14.9", diff --git a/src/core/Provider.ts b/src/core/Provider.ts index f5fa56ae87..2be28a3aa6 100644 --- a/src/core/Provider.ts +++ b/src/core/Provider.ts @@ -1,7 +1,11 @@ -import { createElement, useCallback, useDebugValue, useRef } from 'react' +import { + createElement, + useDebugValue, + useEffect, + useRef, + useState, +} from 'react' import type { PropsWithChildren } from 'react' -// @ts-ignore -import { useSyncExternalStore } from 'use-sync-external-store' import type { Atom, Scope } from './atom' import { ScopeContainer, @@ -77,9 +81,12 @@ const stateToPrintable = ([store, atoms]: [Store, Atom[]]) => // so atoms aren't garbage collected by the WeakMap of mounted atoms const useDebugState = (scopeContainer: ScopeContainerForDevelopment) => { const [store, devStore] = scopeContainer - const atoms = useSyncExternalStore( - devStore.subscribe, - useCallback(() => devStore.atoms, [devStore]) - ) + const [atoms, setAtoms] = useState(devStore.atoms) + useEffect(() => { + const callback = () => setAtoms(devStore.atoms) + const unsubscribe = devStore.subscribe(callback) + callback() + return unsubscribe + }, [devStore]) useDebugValue([store, atoms], stateToPrintable) } diff --git a/src/core/contexts.ts b/src/core/contexts.ts index 687ca7a2b5..4681e6460f 100644 --- a/src/core/contexts.ts +++ b/src/core/contexts.ts @@ -17,7 +17,9 @@ const createScopeContainerForDevelopment = ( listeners: new Set<() => void>(), subscribe: (callback: () => void) => { devStore.listeners.add(callback) - return () => devStore.listeners.delete(callback) + return () => { + devStore.listeners.delete(callback) + } }, atoms: Array.from(initialValues ?? []).map(([a]) => a), } diff --git a/src/core/useAtom.ts b/src/core/useAtom.ts index 04d6ab3022..b95625f9bb 100644 --- a/src/core/useAtom.ts +++ b/src/core/useAtom.ts @@ -1,6 +1,10 @@ -import { useCallback, useContext, useDebugValue, useEffect } from 'react' -// @ts-ignore -import { useSyncExternalStore } from 'use-sync-external-store' +import { + useCallback, + useContext, + useDebugValue, + useEffect, + useReducer, +} from 'react' import type { Atom, Scope, SetAtom, WritableAtom } from './atom' import { getScopeContext } from './contexts' import { FLUSH_PENDING, READ_ATOM, SUBSCRIBE_ATOM, WRITE_ATOM } from './store' @@ -51,11 +55,6 @@ export function useAtom( const ScopeContext = getScopeContext(scope) const [store] = useContext(ScopeContext) - const subscribe = useCallback( - (callback: () => void) => store[SUBSCRIBE_ATOM](atom, callback), - [store, atom] - ) - const getAtomValue = useCallback(() => { const atomState = store[READ_ATOM](atom) if (atomState.e) { @@ -73,7 +72,14 @@ export function useAtom( throw new Error('no atom value') }, [store, atom]) - const value = useSyncExternalStore(subscribe, getAtomValue) + const [value, forceUpdate] = useReducer(getAtomValue, undefined, getAtomValue) + + useEffect(() => { + const unsubscribe = store[SUBSCRIBE_ATOM](atom, forceUpdate) + forceUpdate() + return unsubscribe + }, [store, atom]) + useEffect(() => { store[FLUSH_PENDING]() }) diff --git a/src/devtools/useAtomsSnapshot.ts b/src/devtools/useAtomsSnapshot.ts index 02f2791ca9..caed236e36 100644 --- a/src/devtools/useAtomsSnapshot.ts +++ b/src/devtools/useAtomsSnapshot.ts @@ -1,6 +1,4 @@ -import { useCallback, useContext } from 'react' -// @ts-ignore -import { useSyncExternalStore } from 'use-sync-external-store' +import { useContext, useEffect, useState } from 'react' import { SECRET_INTERNAL_getScopeContext as getScopeContext } from 'jotai' import type { Atom, Scope } from '../core/atom' // NOTE importing from '../core/contexts' is across bundles and actually copying code @@ -20,10 +18,13 @@ export function useAtomsSnapshot(scope?: Scope): AtomsSnapshot { const [store, devStore] = scopeContainer - const atoms: Atom[] = useSyncExternalStore( - devStore.subscribe, - useCallback(() => devStore.atoms, [devStore]) - ) + const [atoms, setAtoms] = useState(devStore.atoms) + useEffect(() => { + const callback = () => setAtoms(devStore.atoms) + const unsubscribe = devStore.subscribe(callback) + callback() + return unsubscribe + }, [devStore]) const atomToAtomValueTuples = atoms .filter((atom) => !!store[DEV_GET_MOUNTED]?.(atom)) diff --git a/yarn.lock b/yarn.lock index 119a6cfbd1..19e756b6e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7222,11 +7222,6 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" -use-sync-external-store@^0.0.0-experimental-1314299c7-20210901: - version "0.0.0-experimental-1314299c7-20210901" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-0.0.0-experimental-1314299c7-20210901.tgz#813df01533d654913463becb4baf21d012630b41" - integrity sha512-Iu5x3XZTSw/ORhEu0AUvQc05cLBc7UV8tXiP1zuXJlxEF5dYV+Dmz3YFJHWcb8L+7aBTUIhCfat/qvQNf5LdKw== - use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" From 9661e6fab6c1aeeca600a083deb12c2011f2ab5a Mon Sep 17 00:00:00 2001 From: daishi Date: Sun, 5 Sep 2021 11:44:23 +0900 Subject: [PATCH 03/11] fix: avoid reading atom value twice --- src/core/store.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/store.ts b/src/core/store.ts index e83a9213e9..f927b2cb65 100644 --- a/src/core/store.ts +++ b/src/core/store.ts @@ -140,6 +140,9 @@ export const createStore = ( if (!('v' in atomState) || !Object.is(atomState.v, value)) { atomState.v = value ++atomState.r // increment revision + if (atomState.d.has(atom)) { + atomState.d.set(atom, atomState.r) + } } commitAtomState(atom, atomState, dependencies && prevDependencies) } From 33a40b0cd199c9663f592e29c72dbc28dfb1b7db Mon Sep 17 00:00:00 2001 From: daishi Date: Sun, 5 Sep 2021 11:59:37 +0900 Subject: [PATCH 04/11] fix useAtomsSnapshot --- src/devtools/useAtomsSnapshot.ts | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/devtools/useAtomsSnapshot.ts b/src/devtools/useAtomsSnapshot.ts index caed236e36..2d80cdee4a 100644 --- a/src/devtools/useAtomsSnapshot.ts +++ b/src/devtools/useAtomsSnapshot.ts @@ -18,19 +18,23 @@ export function useAtomsSnapshot(scope?: Scope): AtomsSnapshot { const [store, devStore] = scopeContainer - const [atoms, setAtoms] = useState(devStore.atoms) + const [atomsSnaphost, setAtomsSnaphost] = useState(new Map()) useEffect(() => { - const callback = () => setAtoms(devStore.atoms) + const callback = () => { + const { atoms } = devStore + const atomToAtomValueTuples = atoms + .filter((atom) => !!store[DEV_GET_MOUNTED]?.(atom)) + .map<[Atom, unknown]>((atom) => { + const atomState = + store[DEV_GET_ATOM_STATE]?.(atom) ?? ({} as AtomState) + return [atom, atomState.v] + }) + setAtomsSnaphost(new Map(atomToAtomValueTuples)) + } const unsubscribe = devStore.subscribe(callback) callback() return unsubscribe - }, [devStore]) + }, [store, devStore]) - const atomToAtomValueTuples = atoms - .filter((atom) => !!store[DEV_GET_MOUNTED]?.(atom)) - .map<[Atom, unknown]>((atom) => { - const atomState = store[DEV_GET_ATOM_STATE]?.(atom) ?? ({} as AtomState) - return [atom, atomState.v] - }) - return new Map(atomToAtomValueTuples) + return atomsSnaphost } From e030230fab5347a19529fbe9c6c91217b0c2eea7 Mon Sep 17 00:00:00 2001 From: daishi Date: Sun, 5 Sep 2021 22:10:39 +0900 Subject: [PATCH 05/11] update size snapshot --- .size-snapshot.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.size-snapshot.json b/.size-snapshot.json index b79302fbf1..1cd4bb9164 100644 --- a/.size-snapshot.json +++ b/.size-snapshot.json @@ -1,8 +1,8 @@ { "index.js": { - "bundled": 22130, - "minified": 8884, - "gzipped": 3283, + "bundled": 19758, + "minified": 8210, + "gzipped": 3041, "treeshaked": { "rollup": { "code": 14, @@ -14,9 +14,9 @@ } }, "index.mjs": { - "bundled": 22130, - "minified": 8884, - "gzipped": 3283, + "bundled": 19758, + "minified": 8210, + "gzipped": 3041, "treeshaked": { "rollup": { "code": 14, @@ -56,9 +56,9 @@ } }, "devtools.js": { - "bundled": 20426, - "minified": 8380, - "gzipped": 3171, + "bundled": 20062, + "minified": 8222, + "gzipped": 3114, "treeshaked": { "rollup": { "code": 28, @@ -70,9 +70,9 @@ } }, "devtools.mjs": { - "bundled": 20426, - "minified": 8380, - "gzipped": 3171, + "bundled": 20062, + "minified": 8222, + "gzipped": 3114, "treeshaked": { "rollup": { "code": 28, From 9d1003071dd85eb40c6941c9590b948cf44eb44f Mon Sep 17 00:00:00 2001 From: daishi Date: Sun, 5 Sep 2021 22:30:02 +0900 Subject: [PATCH 06/11] a workaround for react devtools --- src/core/Provider.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/Provider.ts b/src/core/Provider.ts index 2be28a3aa6..f9fd40d438 100644 --- a/src/core/Provider.ts +++ b/src/core/Provider.ts @@ -83,7 +83,8 @@ const useDebugState = (scopeContainer: ScopeContainerForDevelopment) => { const [store, devStore] = scopeContainer const [atoms, setAtoms] = useState(devStore.atoms) useEffect(() => { - const callback = () => setAtoms(devStore.atoms) + // HACK creating a new reference for useDebugValue to update + const callback = () => setAtoms([...devStore.atoms]) const unsubscribe = devStore.subscribe(callback) callback() return unsubscribe From e3fa7e854ad88ae6e5f804b38575dc48ffce11bd Mon Sep 17 00:00:00 2001 From: daishi Date: Sun, 5 Sep 2021 23:21:29 +0900 Subject: [PATCH 07/11] update size snapshot --- .size-snapshot.json | 12 ++++++------ src/core/Provider.ts | 4 +--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.size-snapshot.json b/.size-snapshot.json index 1cd4bb9164..37a07c1641 100644 --- a/.size-snapshot.json +++ b/.size-snapshot.json @@ -1,8 +1,8 @@ { "index.js": { - "bundled": 19758, - "minified": 8210, - "gzipped": 3041, + "bundled": 19763, + "minified": 8215, + "gzipped": 3043, "treeshaked": { "rollup": { "code": 14, @@ -14,9 +14,9 @@ } }, "index.mjs": { - "bundled": 19758, - "minified": 8210, - "gzipped": 3041, + "bundled": 19763, + "minified": 8215, + "gzipped": 3043, "treeshaked": { "rollup": { "code": 14, diff --git a/src/core/Provider.ts b/src/core/Provider.ts index f9fd40d438..88b1166fec 100644 --- a/src/core/Provider.ts +++ b/src/core/Provider.ts @@ -45,9 +45,7 @@ export const Provider = ({ return createElement( ScopeContainerContext.Provider, { - value: scopeContainerRef.current as ReturnType< - typeof createScopeContainer - >, + value: scopeContainerRef.current, }, children ) From 3105e75843488244290eebfd7a753763aaa81bb8 Mon Sep 17 00:00:00 2001 From: daishi Date: Mon, 6 Sep 2021 07:12:05 +0900 Subject: [PATCH 08/11] empty commit From c180cd8c480d0ee7658432aa0e99e13ee438ce3b Mon Sep 17 00:00:00 2001 From: Daishi Kato Date: Wed, 8 Sep 2021 20:31:56 +0900 Subject: [PATCH 09/11] Update src/devtools/useAtomsSnapshot.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mathis Møller --- src/devtools/useAtomsSnapshot.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devtools/useAtomsSnapshot.ts b/src/devtools/useAtomsSnapshot.ts index 2d80cdee4a..f3c3e7c095 100644 --- a/src/devtools/useAtomsSnapshot.ts +++ b/src/devtools/useAtomsSnapshot.ts @@ -18,7 +18,7 @@ export function useAtomsSnapshot(scope?: Scope): AtomsSnapshot { const [store, devStore] = scopeContainer - const [atomsSnaphost, setAtomsSnaphost] = useState(new Map()) + const [atomsSnapshot, setAtomsSnapshot] = useState(new Map()) useEffect(() => { const callback = () => { const { atoms } = devStore From eba06ea361495225f3ccfa23578f2a71f58e475f Mon Sep 17 00:00:00 2001 From: Daishi Kato Date: Wed, 8 Sep 2021 20:32:04 +0900 Subject: [PATCH 10/11] Update src/devtools/useAtomsSnapshot.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mathis Møller --- src/devtools/useAtomsSnapshot.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devtools/useAtomsSnapshot.ts b/src/devtools/useAtomsSnapshot.ts index f3c3e7c095..ed0922cc21 100644 --- a/src/devtools/useAtomsSnapshot.ts +++ b/src/devtools/useAtomsSnapshot.ts @@ -29,7 +29,7 @@ export function useAtomsSnapshot(scope?: Scope): AtomsSnapshot { store[DEV_GET_ATOM_STATE]?.(atom) ?? ({} as AtomState) return [atom, atomState.v] }) - setAtomsSnaphost(new Map(atomToAtomValueTuples)) + setAtomsSnapshot(new Map(atomToAtomValueTuples)) } const unsubscribe = devStore.subscribe(callback) callback() From 2e96c2cfbcb80fad807031dd95599f5cef37c115 Mon Sep 17 00:00:00 2001 From: Daishi Kato Date: Wed, 8 Sep 2021 20:32:12 +0900 Subject: [PATCH 11/11] Update src/devtools/useAtomsSnapshot.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mathis Møller --- src/devtools/useAtomsSnapshot.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devtools/useAtomsSnapshot.ts b/src/devtools/useAtomsSnapshot.ts index ed0922cc21..587ae19cf0 100644 --- a/src/devtools/useAtomsSnapshot.ts +++ b/src/devtools/useAtomsSnapshot.ts @@ -36,5 +36,5 @@ export function useAtomsSnapshot(scope?: Scope): AtomsSnapshot { return unsubscribe }, [store, devStore]) - return atomsSnaphost + return atomsSnapshot }