{
  "version": 3,
  "sources": ["../../../src/components/use-select/index.ts"],
  "sourcesContent": ["// useSelect is a low-level hook that intentionally breaks rules-of-hooks\n// in its internal helpers (_useStaticSelect, _useMappingSelect) where\n// hooks are called inside non-hook functions and conditionally dispatched.\n/* eslint-disable react-hooks/rules-of-hooks, react-compiler/react-compiler */\n\n/**\n * WordPress dependencies\n */\nimport { createQueue } from '@wordpress/priority-queue';\nimport {\n\tuseRef,\n\tuseCallback,\n\tuseMemo,\n\tuseSyncExternalStore,\n\tuseDebugValue,\n} from '@wordpress/element';\nimport { isShallowEqual } from '@wordpress/is-shallow-equal';\n\n/**\n * Internal dependencies\n */\nimport useRegistry from '../registry-provider/use-registry';\nimport useAsyncMode from '../async-mode-provider/use-async-mode';\nimport type {\n\tMapSelect,\n\tSelectFunction,\n\tStoreDescriptor,\n\tAnyConfig,\n\tUseSelectReturn,\n\tDataRegistry,\n} from '../../types';\n\nconst renderQueue = createQueue();\n\nfunction warnOnUnstableReference(\n\ta: Record< string, unknown >,\n\tb: Record< string, unknown >\n): void {\n\tif ( ! a || ! b ) {\n\t\treturn;\n\t}\n\n\tconst keys =\n\t\ttypeof a === 'object' && typeof b === 'object'\n\t\t\t? Object.keys( a ).filter( ( k ) => a[ k ] !== b[ k ] )\n\t\t\t: [];\n\n\t// eslint-disable-next-line no-console\n\tconsole.warn(\n\t\t'The `useSelect` hook returns different values when called with the same state and parameters.\\n' +\n\t\t\t'This can lead to unnecessary re-renders and performance issues if not fixed.\\n\\n' +\n\t\t\t'Non-equal value keys: %s\\n\\n',\n\t\tkeys.join( ', ' )\n\t);\n}\n\ninterface StoreSubscriber {\n\tsubscribe: ( listener: () => void ) => () => void;\n\tupdateStores: ( newStores: string[] ) => void;\n}\n\nfunction Store( registry: DataRegistry, suspense: boolean ) {\n\tconst select = ( suspense\n\t\t? registry.suspendSelect\n\t\t: registry.select ) as unknown as SelectFunction;\n\tconst queueContext = {};\n\tlet lastMapSelect: MapSelect | undefined;\n\tlet lastMapResult: unknown;\n\tlet lastMapResultValid = false;\n\tlet lastIsAsync: boolean | undefined;\n\tlet subscriber: StoreSubscriber | undefined;\n\tlet didWarnUnstableReference: boolean | undefined;\n\tconst storeStatesOnMount = new Map< string, unknown >();\n\n\tfunction getStoreState( name: string ): unknown {\n\t\t// If there's no store property (custom generic store), return an empty\n\t\t// object. When comparing the state, the empty objects will cause the\n\t\t// equality check to fail, setting `lastMapResultValid` to false.\n\t\treturn registry.stores[ name ]?.store?.getState?.() ?? {};\n\t}\n\n\tconst createSubscriber = ( stores: string[] ): StoreSubscriber => {\n\t\t// The set of stores the `subscribe` function is supposed to subscribe to. Here it is\n\t\t// initialized, and then the `updateStores` function can add new stores to it.\n\t\tconst activeStores = [ ...stores ];\n\n\t\t// The `subscribe` function, which is passed to the `useSyncExternalStore` hook, could\n\t\t// be called multiple times to establish multiple subscriptions. That's why we need to\n\t\t// keep a set of active subscriptions;\n\t\tconst activeSubscriptions = new Set< ( storeName: string ) => void >();\n\n\t\tfunction subscribe( listener: () => void ): () => void {\n\t\t\t// Maybe invalidate the value right after subscription was created.\n\t\t\t// React will call `getValue` after subscribing, to detect store\n\t\t\t// updates that happened in the interval between the `getValue` call\n\t\t\t// during render and creating the subscription, which is slightly\n\t\t\t// delayed. We need to ensure that this second `getValue` call will\n\t\t\t// compute a fresh value only if any of the store states have\n\t\t\t// changed in the meantime.\n\t\t\tif ( lastMapResultValid ) {\n\t\t\t\tfor ( const name of activeStores ) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tstoreStatesOnMount.get( name ) !== getStoreState( name )\n\t\t\t\t\t) {\n\t\t\t\t\t\tlastMapResultValid = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstoreStatesOnMount.clear();\n\n\t\t\tconst onStoreChange = () => {\n\t\t\t\t// Invalidate the value on store update, so that a fresh value is computed.\n\t\t\t\tlastMapResultValid = false;\n\t\t\t\tlistener();\n\t\t\t};\n\n\t\t\tconst onChange = () => {\n\t\t\t\tif ( lastIsAsync ) {\n\t\t\t\t\trenderQueue.add( queueContext, onStoreChange );\n\t\t\t\t} else {\n\t\t\t\t\tonStoreChange();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst unsubs: Array< VoidFunction > = [];\n\t\t\tfunction subscribeStore( storeName: string ) {\n\t\t\t\tunsubs.push( registry.subscribe( onChange, storeName ) );\n\t\t\t}\n\n\t\t\tfor ( const storeName of activeStores ) {\n\t\t\t\tsubscribeStore( storeName );\n\t\t\t}\n\n\t\t\tactiveSubscriptions.add( subscribeStore );\n\n\t\t\treturn () => {\n\t\t\t\tactiveSubscriptions.delete( subscribeStore );\n\n\t\t\t\tfor ( const unsub of unsubs.values() ) {\n\t\t\t\t\t// The return value of the subscribe function could be undefined if the store is a custom generic store.\n\t\t\t\t\tunsub?.();\n\t\t\t\t}\n\t\t\t\t// Cancel existing store updates that were already scheduled.\n\t\t\t\trenderQueue.cancel( queueContext );\n\t\t\t};\n\t\t}\n\n\t\t// Check if `newStores` contains some stores we're not subscribed to yet, and add them.\n\t\tfunction updateStores( newStores: string[] ) {\n\t\t\tfor ( const newStore of newStores ) {\n\t\t\t\tif ( activeStores.includes( newStore ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// New `subscribe` calls will subscribe to `newStore`, too.\n\t\t\t\tactiveStores.push( newStore );\n\n\t\t\t\t// Add `newStore` to existing subscriptions.\n\t\t\t\tfor ( const subscription of activeSubscriptions ) {\n\t\t\t\t\tsubscription( newStore );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { subscribe, updateStores };\n\t};\n\n\treturn ( mapSelect: MapSelect, isAsync: boolean ) => {\n\t\tfunction updateValue(): void {\n\t\t\t// If the last value is valid, and the `mapSelect` callback hasn't changed,\n\t\t\t// then we can safely return the cached value. The value can change only on\n\t\t\t// store update, and in that case value will be invalidated by the listener.\n\t\t\tif ( lastMapResultValid && mapSelect === lastMapSelect ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst listeningStores = { current: null as string[] | null };\n\t\t\tconst mapResult = registry.__unstableMarkListeningStores(\n\t\t\t\t() => mapSelect( select, registry ),\n\t\t\t\tlisteningStores\n\t\t\t);\n\n\t\t\tif ( ( globalThis as any ).SCRIPT_DEBUG ) {\n\t\t\t\tif ( ! didWarnUnstableReference ) {\n\t\t\t\t\tconst secondMapResult = mapSelect( select, registry );\n\t\t\t\t\tif ( ! isShallowEqual( mapResult, secondMapResult ) ) {\n\t\t\t\t\t\twarnOnUnstableReference( mapResult, secondMapResult );\n\t\t\t\t\t\tdidWarnUnstableReference = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( ! subscriber ) {\n\t\t\t\tfor ( const name of listeningStores.current! ) {\n\t\t\t\t\tstoreStatesOnMount.set( name, getStoreState( name ) );\n\t\t\t\t}\n\t\t\t\tsubscriber = createSubscriber( listeningStores.current! );\n\t\t\t} else {\n\t\t\t\tsubscriber.updateStores( listeningStores.current! );\n\t\t\t}\n\n\t\t\t// If the new value is shallow-equal to the old one, keep the old one so\n\t\t\t// that we don't trigger unwanted updates that do a `===` check.\n\t\t\tif ( ! isShallowEqual( lastMapResult, mapResult ) ) {\n\t\t\t\tlastMapResult = mapResult;\n\t\t\t}\n\t\t\tlastMapSelect = mapSelect;\n\t\t\tlastMapResultValid = true;\n\t\t}\n\n\t\tfunction getValue() {\n\t\t\t// Update the value in case it's been invalidated or `mapSelect` has changed.\n\t\t\tupdateValue();\n\t\t\treturn lastMapResult;\n\t\t}\n\n\t\t// When transitioning from async to sync mode, cancel existing store updates\n\t\t// that have been scheduled, and invalidate the value so that it's freshly\n\t\t// computed. It might have been changed by the update we just cancelled.\n\t\tif ( lastIsAsync && ! isAsync ) {\n\t\t\tlastMapResultValid = false;\n\t\t\trenderQueue.cancel( queueContext );\n\t\t}\n\n\t\tupdateValue();\n\n\t\tlastIsAsync = isAsync;\n\n\t\t// Return a pair of functions that can be passed to `useSyncExternalStore`.\n\t\treturn { subscribe: subscriber!.subscribe, getValue };\n\t};\n}\n\nfunction _useStaticSelect( storeName: StoreDescriptor< AnyConfig > | string ) {\n\treturn useRegistry().select( storeName );\n}\n\nfunction _useMappingSelect(\n\tsuspense: boolean,\n\tmapSelect: MapSelect,\n\tdeps: unknown[]\n) {\n\tconst registry = useRegistry();\n\tconst isAsync = useAsyncMode();\n\tconst store = useMemo(\n\t\t() => Store( registry, suspense ),\n\t\t[ registry, suspense ]\n\t);\n\n\t// These are \"pass-through\" dependencies from the parent hook,\n\t// and the parent should catch any hook rule violations.\n\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\tconst selector = useCallback( mapSelect, deps );\n\tconst { subscribe, getValue } = store( selector, isAsync );\n\tconst result = useSyncExternalStore( subscribe, getValue, getValue );\n\tuseDebugValue( result );\n\treturn result;\n}\n\n/**\n * Custom react hook for retrieving props from registered selectors.\n *\n * In general, this custom React hook follows the\n * [rules of hooks](https://react.dev/reference/rules/rules-of-hooks).\n *\n * @param mapSelect Function called on every state change. The returned value is\n *                  exposed to the component implementing this hook. The function\n *                  receives the `registry.select` method on the first argument\n *                  and the `registry` on the second argument.\n *                  When a store key is passed, all selectors for the store will be\n *                  returned. This is only meant for usage of these selectors in event\n *                  callbacks, not for data needed to create the element tree.\n * @param deps      If provided, this memoizes the mapSelect so the same `mapSelect` is\n *                  invoked on every state change unless the dependencies change.\n *\n * @example\n * ```js\n * import { useSelect } from '@wordpress/data';\n * import { store as myCustomStore } from 'my-custom-store';\n *\n * function HammerPriceDisplay( { currency } ) {\n *   const price = useSelect( ( select ) => {\n *     return select( myCustomStore ).getPrice( 'hammer', currency );\n *   }, [ currency ] );\n *   return new Intl.NumberFormat( 'en-US', {\n *     style: 'currency',\n *     currency,\n *   } ).format( price );\n * }\n *\n * // Rendered in the application:\n * // <HammerPriceDisplay currency=\"USD\" />\n * ```\n *\n * In the above example, when `HammerPriceDisplay` is rendered into an\n * application, the price will be retrieved from the store state using the\n * `mapSelect` callback on `useSelect`. If the currency prop changes then\n * any price in the state for that currency is retrieved. If the currency prop\n * doesn't change and other props are passed in that do change, the price will\n * not change because the dependency is just the currency.\n *\n * When data is only used in an event callback, the data should not be retrieved\n * on render, so it may be useful to get the selectors function instead.\n *\n * **Don't use `useSelect` this way when calling the selectors in the render\n * function because your component won't re-render on a data change.**\n *\n * ```js\n * import { useSelect } from '@wordpress/data';\n * import { store as myCustomStore } from 'my-custom-store';\n *\n * function Paste( { children } ) {\n *   const { getSettings } = useSelect( myCustomStore );\n *   function onPaste() {\n *     // Do something with the settings.\n *     const settings = getSettings();\n *   }\n *   return <div onPaste={ onPaste }>{ children }</div>;\n * }\n * ```\n *\n * @return The selected data or store selectors.\n */\nexport default function useSelect<\n\tT extends MapSelect | StoreDescriptor< AnyConfig >,\n>( mapSelect: T, deps?: unknown[] ): UseSelectReturn< T > {\n\t// On initial call, on mount, determine the mode of this `useSelect` call\n\t// and then never allow it to change on subsequent updates.\n\tconst staticSelectMode = typeof mapSelect !== 'function';\n\tconst staticSelectModeRef = useRef( staticSelectMode );\n\n\tif ( staticSelectMode !== staticSelectModeRef.current ) {\n\t\tconst prevMode = staticSelectModeRef.current ? 'static' : 'mapping';\n\t\tconst nextMode = staticSelectMode ? 'static' : 'mapping';\n\t\tthrow new Error(\n\t\t\t`Switching useSelect from ${ prevMode } to ${ nextMode } is not allowed`\n\t\t);\n\t}\n\n\t// `staticSelectMode` is not allowed to change during the hook instance's,\n\t// lifetime, so the rules of hooks are not really violated.\n\n\treturn (\n\t\tstaticSelectMode\n\t\t\t? _useStaticSelect( mapSelect as StoreDescriptor< AnyConfig > )\n\t\t\t: _useMappingSelect( false, mapSelect as MapSelect, deps! )\n\t) as UseSelectReturn< T >;\n}\n\n/**\n * A variant of the `useSelect` hook that has the same API, but is a compatible\n * Suspense-enabled data source.\n *\n * @param mapSelect Function called on every state change. The\n *                  returned value is exposed to the component\n *                  using this hook. The function receives the\n *                  `registry.suspendSelect` method as the first\n *                  argument and the `registry` as the second one.\n * @param deps      A dependency array used to memoize the `mapSelect`\n *                  so that the same `mapSelect` is invoked on every\n *                  state change unless the dependencies change.\n *\n * @throws A suspense Promise that is thrown if any of the called\n * selectors is in an unresolved state.\n *\n * @return Data object returned by the `mapSelect` function.\n */\nexport function useSuspenseSelect< T extends MapSelect >(\n\tmapSelect: T,\n\tdeps: unknown[]\n): ReturnType< T > {\n\treturn _useMappingSelect( true, mapSelect, deps ) as ReturnType< T >;\n}\n/* eslint-enable react-hooks/rules-of-hooks, react-compiler/react-compiler */\n"],
  "mappings": "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",
  "names": []
}
