diff --git a/src/alternate-renderers.ts b/src/alternate-renderers.ts index 24135f415..96df1efcb 100644 --- a/src/alternate-renderers.ts +++ b/src/alternate-renderers.ts @@ -6,9 +6,11 @@ import { useSyncExternalStore } from 'use-sync-external-store/shim' import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector' -import { setSyncFunctions } from './utils/useSyncExternalStore' +import { initializeUseSelector } from './hooks/useSelector' +import { initializeConnect } from './components/connect' -setSyncFunctions(useSyncExternalStore, useSyncExternalStoreWithSelector) +initializeUseSelector(useSyncExternalStoreWithSelector) +initializeConnect(useSyncExternalStore) import { getBatch } from './utils/batch' diff --git a/src/compat.ts b/src/compat.ts index 781602c80..12ca09367 100644 --- a/src/compat.ts +++ b/src/compat.ts @@ -5,11 +5,14 @@ import { useSyncExternalStore } from 'use-sync-external-store/shim' import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector' -import { setSyncFunctions } from './utils/useSyncExternalStore' import { unstable_batchedUpdates as batch } from './utils/reactBatchedUpdates' import { setBatch } from './utils/batch' -setSyncFunctions(useSyncExternalStore, useSyncExternalStoreWithSelector) +import { initializeUseSelector } from './hooks/useSelector' +import { initializeConnect } from './components/connect' + +initializeUseSelector(useSyncExternalStoreWithSelector) +initializeConnect(useSyncExternalStore) // Enable batched updates in our subscriptions for use // with standard React renderers (ReactDOM, React Native) diff --git a/src/components/connect.tsx b/src/components/connect.tsx index 4213a6e44..a3f4d9317 100644 --- a/src/components/connect.tsx +++ b/src/components/connect.tsx @@ -28,7 +28,6 @@ import defaultMergePropsFactories from '../connect/mergeProps' import { createSubscription, Subscription } from '../utils/Subscription' import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect' -import { getSyncFunctions } from '../utils/useSyncExternalStore' import shallowEqual from '../utils/shallowEqual' import { @@ -37,7 +36,13 @@ import { ReactReduxContextInstance, } from './Context' -const [useSyncExternalStore] = getSyncFunctions() +import type { uSES } from '../utils/useSyncExternalStore' +import { notInitialized } from '../utils/useSyncExternalStore' + +let useSyncExternalStore = notInitialized as uSES +export const initializeConnect = (fn: uSES) => { + useSyncExternalStore = fn +} // Define some constant arrays just to avoid re-creating these const EMPTY_ARRAY: [unknown, number] = [null, 0] diff --git a/src/hooks/useSelector.ts b/src/hooks/useSelector.ts index e7dd0c2f3..2a93f941e 100644 --- a/src/hooks/useSelector.ts +++ b/src/hooks/useSelector.ts @@ -2,10 +2,14 @@ import { useContext, useDebugValue } from 'react' import { useReduxContext as useDefaultReduxContext } from './useReduxContext' import { ReactReduxContext } from '../components/Context' -import { getSyncFunctions } from '../utils/useSyncExternalStore' import type { DefaultRootState, EqualityFn } from '../types' +import type { uSESWS } from '../utils/useSyncExternalStore' +import { notInitialized } from '../utils/useSyncExternalStore' -const [, useSyncExternalStoreWithSelector] = getSyncFunctions() +let useSyncExternalStoreWithSelector = notInitialized as uSESWS +export const initializeUseSelector = (fn: uSESWS) => { + useSyncExternalStoreWithSelector = fn +} const refEquality: EqualityFn = (a, b) => a === b diff --git a/src/index.ts b/src/index.ts index dddf53e98..ed301fc10 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,11 +7,14 @@ import { useSyncExternalStore } from 'react' import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector' -import { setSyncFunctions } from './utils/useSyncExternalStore' import { unstable_batchedUpdates as batch } from './utils/reactBatchedUpdates' import { setBatch } from './utils/batch' -setSyncFunctions(useSyncExternalStore, useSyncExternalStoreWithSelector) +import { initializeUseSelector } from './hooks/useSelector' +import { initializeConnect } from './components/connect' + +initializeUseSelector(useSyncExternalStoreWithSelector) +initializeConnect(useSyncExternalStore) // Enable batched updates in our subscriptions for use // with standard React renderers (ReactDOM, React Native) diff --git a/src/utils/useSyncExternalStore.ts b/src/utils/useSyncExternalStore.ts index 392c041c2..b7f777391 100644 --- a/src/utils/useSyncExternalStore.ts +++ b/src/utils/useSyncExternalStore.ts @@ -1,21 +1,9 @@ import type { useSyncExternalStore } from 'use-sync-external-store' import type { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector' -const notInitialized = () => { - throw new Error('Not initialize!') +export const notInitialized = () => { + throw new Error('uSES not initialized!') } -let uSES: typeof useSyncExternalStore = notInitialized -let uSESWS: typeof useSyncExternalStoreWithSelector = notInitialized - -// Allow injecting the actual functions from the entry points -export const setSyncFunctions = ( - sync: typeof useSyncExternalStore, - withSelector: typeof useSyncExternalStoreWithSelector -) => { - uSES = sync - uSESWS = withSelector -} - -// Supply a getter just to skip dealing with ESM bindings -export const getSyncFunctions = () => [uSES, uSESWS] as const +export type uSES = typeof useSyncExternalStore +export type uSESWS = typeof useSyncExternalStoreWithSelector