@yoltra/react 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/context/StoreContext.ts","../../../common/temp/node_modules/.pnpm/react@19.1.1/node_modules/react/cjs/react-jsx-runtime.production.js","../../../common/temp/node_modules/.pnpm/react@19.1.1/node_modules/react/cjs/react-jsx-runtime.development.js","../../../common/temp/node_modules/.pnpm/react@19.1.1/node_modules/react/jsx-runtime.js","../src/context/StoreProvider.tsx","../src/utils/warnOnce.ts","../src/utils/path.ts","../src/utils/useStableSnapshot.ts","../src/utils/shallowEqual.ts","../src/hooks/hooks.ts","../src/hooks/suspense.ts","../src/hooks/createHooks.ts","../src/createYoltra.tsx","../src/entity/useEntity.ts"],"sourcesContent":["/**\n * @module @yoltra/react\n */\n\nimport { createContext } from \"react\";\nimport type { StoreInstance } from \"@yoltra/core\";\n\n/**\n * React Context carrying a {@link StoreInstance} for yoltra React bindings.\n *\n * @remarks\n * - The default value is `null`. Consumers should either:\n * 1) Be wrapped with {@link StoreProvider}, or\n * 2) Use a helper hook that throws a friendly error when the context is `null`.\n * - You can scope multiple independent stores by nesting multiple providers.\n *\n * @example Basic usage\n * ```tsx\n * import { useContext } from \"react\";\n * import { StoreContext } from \"@yoltra/react\";\n *\n * export function Counter() {\n * const store = useContext(StoreContext);\n * if (!store) throw new Error(\"StoreProvider is missing\");\n * const state = store.getState();\n * return <span>{state.counter.value}</span>;\n * }\n * ```\n *\n * @public\n */\nexport const StoreContext = createContext<StoreInstance<any, any, any> | null>(null);","/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","/**\n * @license React\n * react-jsx-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return (type.displayName || \"Context\") + \".Provider\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(\n type,\n key,\n self,\n source,\n owner,\n props,\n debugStack,\n debugTask\n ) {\n self = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== self ? self : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function jsxDEVImpl(\n type,\n config,\n maybeKey,\n isStaticChildren,\n source,\n self,\n debugStack,\n debugTask\n ) {\n var children = config.children;\n if (void 0 !== children)\n if (isStaticChildren)\n if (isArrayImpl(children)) {\n for (\n isStaticChildren = 0;\n isStaticChildren < children.length;\n isStaticChildren++\n )\n validateChildKeys(children[isStaticChildren]);\n Object.freeze && Object.freeze(children);\n } else\n console.error(\n \"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.\"\n );\n else validateChildKeys(children);\n if (hasOwnProperty.call(config, \"key\")) {\n children = getComponentNameFromType(type);\n var keys = Object.keys(config).filter(function (k) {\n return \"key\" !== k;\n });\n isStaticChildren =\n 0 < keys.length\n ? \"{key: someKey, \" + keys.join(\": ..., \") + \": ...}\"\n : \"{key: someKey}\";\n didWarnAboutKeySpread[children + isStaticChildren] ||\n ((keys =\n 0 < keys.length ? \"{\" + keys.join(\": ..., \") + \": ...}\" : \"{}\"),\n console.error(\n 'A props object containing a \"key\" prop is being spread into JSX:\\n let props = %s;\\n <%s {...props} />\\nReact keys must be passed directly to JSX without using spread:\\n let props = %s;\\n <%s key={someKey} {...props} />',\n isStaticChildren,\n children,\n keys,\n children\n ),\n (didWarnAboutKeySpread[children + isStaticChildren] = !0));\n }\n children = null;\n void 0 !== maybeKey &&\n (checkKeyStringCoercion(maybeKey), (children = \"\" + maybeKey));\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (children = \"\" + config.key));\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n children &&\n defineKeyPropWarningGetter(\n maybeKey,\n \"function\" === typeof type\n ? type.displayName || type.name || \"Unknown\"\n : type\n );\n return ReactElement(\n type,\n children,\n self,\n source,\n getOwner(),\n maybeKey,\n debugStack,\n debugTask\n );\n }\n function validateChildKeys(node) {\n \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_ELEMENT_TYPE &&\n node._store &&\n (node._store.validated = 1);\n }\n var React = require(\"react\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\");\n Symbol.for(\"react.provider\");\n var REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\"),\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n hasOwnProperty = Object.prototype.hasOwnProperty,\n isArrayImpl = Array.isArray,\n createTask = console.createTask\n ? console.createTask\n : function () {\n return null;\n };\n React = {\n react_stack_bottom_frame: function (callStackForError) {\n return callStackForError();\n }\n };\n var specialPropKeyWarningShown;\n var didWarnAboutElementRef = {};\n var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(\n React,\n UnknownOwner\n )();\n var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));\n var didWarnAboutKeySpread = {};\n exports.Fragment = REACT_FRAGMENT_TYPE;\n exports.jsx = function (type, config, maybeKey, source, self) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !1,\n source,\n self,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n exports.jsxs = function (type, config, maybeKey, source, self) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !0,\n source,\n self,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","/**\n * @module @yoltra/react\n */\n\nimport type { StoreInstance } from \"@yoltra/core\";\nimport React, { type ReactNode } from \"react\";\n\nimport { StoreContext } from \"./StoreContext\";\n\n/**\n * React provider that places a {@link StoreInstance} into {@link StoreContext}.\n *\n * @param props.store - The yoltra store instance to expose to descendant components.\n * @param props.children - React subtree that will consume the store.\n *\n * @remarks\n * - Wrap your app (or a subtree) to make the store available via `useContext(StoreContext)`\n * or any higher-level hooks you expose (e.g., `useAtomicProp`, `useEmit`).\n * - You may nest multiple `StoreProvider`s to scope different stores to different subtrees.\n * - In Next.js App Router, this component must be used in a **client** boundary.\n *\n * @example App wrapper with createHooks (recommended)\n * ```tsx\n * // store.ts\n * import { createStore, eventKeys } from '@yoltra/core';\n * import { createContext } from 'react';\n * import { createHooks, StoreProvider } from '@yoltra/react';\n *\n * type AppEM = { ui: { increment: number } };\n * type AppState = { counter: { value: number } };\n *\n * export const store = createStore<AppState, AppEM>({\n * name: 'App',\n * reducer: {\n * counter: {\n * state: { value: 0 },\n * when: { keys: eventKeys<AppEM>()([['ui', 'increment']]) },\n * reducer: (s, evt) => evt.type === 'increment'\n * ? { value: s.value + evt.payload }\n * : s,\n * },\n * },\n * });\n *\n * const AppStoreContext = createContext<typeof store | null>(null);\n * export const { useAtomicProp, useEmit } = createHooks(AppStoreContext);\n *\n * // App.tsx\n * export function App({ children }: { children: React.ReactNode }) {\n * return <StoreProvider store={store}>{children}</StoreProvider>;\n * }\n * ```\n *\n * @public\n */\nexport const StoreProvider: React.FC<{\n /** yoltra store instance placed into context. */\n store: StoreInstance<any, any, any>;\n /** Descendant subtree that can consume the store. */\n children: ReactNode;\n}> = ({ store, children }) => (\n <StoreContext.Provider value={store}>{children}</StoreContext.Provider>\n);\n","/**\n * @module @yoltra/react\n */\n\n/**\n * Set of warning keys already logged (to prevent spam).\n * @internal\n */\nconst warned = new Set<string>();\n\n/**\n * Logs a warning **once** per unique key (dev only).\n *\n * @param key - Unique identifier for this warning.\n * @param message - Warning message to log.\n *\n * @remarks\n * - In production, this is a no-op.\n * - Useful for deprecation warnings that shouldn't flood the console.\n *\n * @example\n * ```ts\n * warnOnce('my-feature', 'This feature is deprecated.');\n * warnOnce('my-feature', 'This feature is deprecated.'); // no-op (already warned)\n * ```\n *\n * @internal\n */\nexport function warnOnce(key: string, message: string): void {\n if (process.env.NODE_ENV === \"production\") return;\n if (warned.has(key)) return;\n\n warned.add(key);\n console.warn(message);\n}","import { warnOnce } from \"./warnOnce\";\n\n/** @internal */\nexport function hasWildcard(p: string): boolean {\n return p.includes(\"*\");\n}\n\n/** @internal */\nexport function normalizePath(p: string): string {\n return p.replace(/^\\./, \"\");\n}\n\n/** @internal */\nexport function splitPath(p: string): string[] {\n return normalizePath(p).split(\".\").filter(Boolean);\n}\n\n/**\n * Stable signature for a specs array, for use as a `useMemo` dependency instead\n * of `JSON.stringify` — deterministic and avoids serializing arbitrary values.\n *\n * Every segment is **length-prefixed** (`\"<len>:<value>\"`), so no delimiter\n * character in a reducer name or path can make two semantically different spec\n * arrays collide (the array length is encoded too, so `[\"a\"]` and `[\"a\", \"\"]`\n * differ).\n * @internal\n */\nexport function specsSignature(\n specs: ReadonlyArray<{ reducer: string; property: string | readonly string[] }>,\n): string {\n const enc = (s: string) => `${s.length}:${s}`;\n return specs\n .map((s) => {\n const props = Array.isArray(s.property)\n ? (s.property as readonly string[])\n : [s.property as string];\n return enc(s.reducer) + enc(String(props.length)) + props.map(enc).join(\"\");\n })\n .join(\"\");\n}\n\nconst PATH_SEGMENTS = Symbol(\"yoltra.pathSegments\");\n\nfunction makePathProxy(segments: string[]): unknown {\n // The target is a function so that *calling* the proxy hits the `apply` trap\n // (a plain-object target is simply not callable and throws an opaque\n // \"x is not a function\"). This lets us reject method calls inside an accessor\n // — e.g. `p => p.items.map(...)` — with a message that says what went wrong.\n const target = () => undefined;\n return new Proxy(target, {\n get(_target, prop) {\n if (prop === PATH_SEGMENTS) return segments;\n if (typeof prop === \"symbol\") return undefined;\n return makePathProxy([...segments, String(prop)]);\n },\n apply() {\n throw new Error(\n `[yoltra] A typed path accessor called a method (near \"${segments.join(\".\")}\"). ` +\n \"The accessor must be a plain member chain like `p => p.items[0].title` — it cannot \" +\n \"call functions such as `.map()` or `.toString()`. Compute derived values in the \" +\n \"component or a selector, or use the `{ reducer, property }` string form.\",\n );\n },\n });\n}\n\n/**\n * Converts a typed path accessor (e.g. `p => p.items[0].title`) into a dotted\n * path string (`\"items.0.title\"`) by recording property accesses on a proxy.\n *\n * The accessor **must be a pure member chain**. It cannot return a computed\n * value (`p => p.a.b ?? 0`, `p => 5`) or call a method (`p => p.items.map(...)`):\n * - a method call throws immediately (see the proxy's `apply` trap);\n * - anything that records no property access yields an empty path — which would\n * silently subscribe to the whole slice — so we `warnOnce` in dev.\n *\n * @internal\n */\nexport function toDottedPath(accessor: (p: any) => unknown): string {\n const leaf = accessor(makePathProxy([]));\n const recorded = leaf != null ? (leaf as any)[PATH_SEGMENTS] : undefined;\n const segments: string[] = Array.isArray(recorded) ? recorded : [];\n const path = segments.join(\".\");\n\n if (path === \"\") {\n warnOnce(\n \"yoltra.toDottedPath.empty\",\n \"[yoltra] A typed path accessor recorded no property access, so it will subscribe to the \" +\n \"entire slice. The accessor must be a plain member chain like `p => p.items[0].title` and \" +\n \"cannot return a computed value or a default. For a whole-slice or dynamic subscription, \" +\n \"use the `{ reducer, property }` string form instead.\",\n );\n }\n\n return path;\n}\n\n/**\n * Reads a dotted path from an object; returns `undefined` when a segment is\n * missing. The caller may supply the expected value type via `T`.\n * @internal\n */\nexport function getAtPath<T = unknown>(obj: unknown, path: string): T {\n if (!path) return obj as T;\n\n let cur: any = obj;\n for (const seg of splitPath(path)) {\n if (cur == null) return undefined as T;\n cur = cur[seg];\n }\n\n return cur as T;\n}\n","/**\n * @module @yoltra/react\n */\n\nimport { useCallback, useMemo, useRef, type DependencyList } from \"react\";\n\n/**\n * Builds a **stable** `getSnapshot` for `useSyncExternalStore` that survives\n * inline `read`/`isEqual` functions — the `useSyncExternalStoreWithSelector`\n * pattern.\n *\n * The latest `read` and `isEqual` closures are kept in refs, so passing them\n * inline (the common case) does **not** rebuild the snapshot on every render and\n * discard its memoized value. The derived value is cached until `isEqual`\n * reports a change; presence is tracked with a separate boolean so a value of\n * `undefined` still hits the cache instead of recomputing forever. The cache is\n * reset only when `structuralDeps` change (e.g. the subscribed path/spec), which\n * is also when the returned function's identity changes.\n *\n * @typeParam T - Derived snapshot value type.\n * @param read - Reads the current derived value from the store.\n * @param isEqual - Equality comparator for the derived value.\n * @param structuralDeps - Deps identifying the subscription target; a change\n * resets the value cache and returns a new snapshot function.\n * @returns A `getSnapshot` function stable across renders that don't change\n * `structuralDeps`.\n *\n * @internal\n */\nexport function useStableSnapshot<T>(\n read: () => T,\n isEqual: (a: T, b: T) => boolean,\n structuralDeps: DependencyList,\n): () => T {\n const readRef = useRef(read);\n readRef.current = read;\n const isEqualRef = useRef(isEqual);\n isEqualRef.current = isEqual;\n\n // A fresh cache object whenever the subscription target changes.\n const cache = useMemo<{ has: boolean; value: T }>(\n () => ({ has: false, value: undefined as T }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n structuralDeps,\n );\n\n return useCallback(() => {\n const next = readRef.current();\n if (!cache.has || !isEqualRef.current(cache.value, next)) {\n cache.has = true;\n cache.value = next;\n }\n return cache.value;\n }, [cache]);\n}\n","/**\n * @module @yoltra/react\n */\n\n/**\n * Shallow object equality using `Object.is` per-key.\n *\n * Useful as the `isEqual` argument for `useAtomicProp` and `useAtomicProps`\n * when the derived value is a plain object. Also available from the object\n * returned by {@link createHooks} and {@link createYoltra}.\n *\n * @example\n * ```ts\n * shallowEqual({ a: 1 }, { a: 1 }); // true\n * shallowEqual({ a: 1 }, { a: 2 }); // false\n * ```\n *\n * @public\n */\nexport function shallowEqual<T extends Record<string, unknown>>(a: T, b: T): boolean {\n if (Object.is(a, b)) return true;\n if (!a || !b) return false;\n\n const ka = Object.keys(a),\n kb = Object.keys(b);\n if (ka.length !== kb.length) return false;\n\n for (const k of ka) {\n if (!Object.is(a[k], (b as Record<string, unknown>)[k])) return false;\n }\n\n return true;\n}\n","/**\n * @module @yoltra/react\n */\n\nimport type {\n DeepReadonly,\n Dotted,\n Emit,\n Event,\n EventMapBase,\n EventPhase,\n PathValue,\n StoreInstance,\n WithGlob,\n} from \"@yoltra/core\";\nimport { useCallback, useContext, useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport { StoreContext } from \"../context/StoreContext\";\nimport { guardProjection, projectDeclared } from \"../utils/declaredProjection\";\nimport { getAtPath, hasWildcard, normalizePath, specsSignature } from \"../utils/path\";\nimport { useStableSnapshot } from \"../utils/useStableSnapshot\";\n\n/**\n * Re-export of {@link PathValue} from `@yoltra/core`.\n *\n * Resolves the TypeScript type at a dotted path `P` within object type `T`.\n * See the core definition for full documentation.\n *\n * @public\n */\nexport type { PathValue };\n\n/**\n * Accepts either a single value or a readonly array of that value.\n * Useful for APIs that take one-or-many keys.\n *\n * @example\n * ```ts\n * function takeIds(ids: OneOrMany<string>) { /* ... *\\/ }\n * takeIds('a');\n * takeIds(['a','b'] as const);\n * ```\n *\n * @public\n */\nexport type OneOrMany<T> = T | readonly T[];\n\n/**\n * Returns the current {@link StoreInstance} from {@link StoreContext}.\n * Throws if used outside of a `<StoreProvider>`.\n *\n * @typeParam EM - Event map type.\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n *\n * @example\n * ```tsx\n * const store = useStore<MyEM, 'counter' | 'todos', AppState>();\n * const state = store.getState();\n * ```\n *\n * @public\n */\nexport function useStore<\n EM extends EventMapBase,\n R extends string,\n S extends Record<R, any>,\n>(): StoreInstance<R, S, EM> {\n const ctx = useContext(StoreContext);\n if (!ctx) throw new Error(\"useStore must be used inside <StoreProvider>\");\n\n return ctx as StoreInstance<R, S, EM>;\n}\n\n/**\n * Returns the store's `emit` function (stable reference).\n *\n * @typeParam EM - Event map type.\n *\n * @example\n * ```tsx\n * const emit = useEmit<MyEM>();\n * await emit('ui', 'toggle', true);\n * ```\n *\n * @public\n */\nexport function useEmit<EM extends EventMapBase>(): Emit<EM> {\n return useStore<EM, any, any>().emit;\n}\n\n// `shallowEqual` is single-sourced in `../utils/shallowEqual` and re-exported\n// here so both the public barrel (`@yoltra/react`) and the object returned by\n// `createHooks`/`createYoltra` reference the same symbol (avoids a TS2742\n// non-portable-type leak in `createYoltra`'s inferred return type).\nexport { shallowEqual } from \"../utils/shallowEqual\";\n\n/**\n * Selects a derived value from the store using an external-store subscription.\n * Re-renders when the selected value changes per `isEqual`.\n *\n * @typeParam S - State type returned by `getState()`.\n * @typeParam T - Selected value type.\n * @param selector - `(state) => value` derived from the current state.\n * @param isEqual - Optional equality comparator (defaults to `Object.is`).\n *\n * @example\n * ```tsx\n * const total = useSelector((s: AppState) => s.todos.items.length);\n * ```\n *\n * @public\n */\nexport function useSelector<S extends Record<any, any>, T>(\n selector: (state: DeepReadonly<S>) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n const store = useStore<any, any, S>();\n\n const subscribe = useMemo(() => (notify: () => void) => store.subscribe(notify), [store]);\n\n const getSnapshot = useStableSnapshot(\n () => selector(store.getState() as DeepReadonly<S>),\n isEqual,\n [store],\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/** @internal */\nfunction useAtomicPropImpl<R extends string, S extends Record<R, any>, T = any>(\n spec: { reducer: R; property: string },\n map?: (value: any) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n const store = useStore<any, R, S>();\n\n const normalizedSpec = useMemo(() => {\n const prop = normalizePath(spec.property);\n return { reducer: spec.reducer, property: prop } as const;\n }, [spec.reducer, spec.property]);\n\n const subscribe = useMemo(\n () => (notify: () => void) =>\n store.connect(\n { reducer: normalizedSpec.reducer, property: normalizedSpec.property },\n () => notify(),\n ),\n [store, normalizedSpec],\n );\n\n const isGlob = hasWildcard(normalizedSpec.property);\n const getSnapshot = useStableSnapshot(\n () => {\n const full = store.getState() as S;\n const slice = (full as any)[normalizedSpec.reducer];\n const source = isGlob ? slice : getAtPath(slice, normalizedSpec.property);\n return map ? map(source) : (source as unknown as T);\n },\n isEqual,\n [store, normalizedSpec],\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot) as any;\n}\n\n/**\n * Fine-grained **single-path** selector for a reducer's state.\n *\n * Re-renders only when the specified `reducer.property` (dotted path) actually changes.\n * For most applications, prefer using the typed version from {@link createHooks}\n * which infers all type parameters automatically.\n *\n * **Supports**\n * - Exact root prop: `{ reducer: \"todo\", property: \"data\" }`\n * - Exact deep path: `{ reducer: \"todo\", property: \"data.123.title\" }`\n * - Wildcards (pattern): `{ reducer: \"todo\", property: \"data.*\" }` or `\"data.**\"`\n *\n * **Overloads**\n * - Exact path (no `*`): returns the precise `PathValue` when `map` is omitted\n * - Exact path + `map`: returns `T` from `map(value)`\n * - Glob path (with `*`/`**`): requires `map` and returns `T` from `map(state)`\n *\n * @example Via createHooks (recommended)\n * ```tsx\n * const { useAtomicProp } = createHooks(AppStoreContext);\n *\n * function TodoTitle({ index }: { index: number }) {\n * // Types are inferred — no explicit generics needed\n * const title = useAtomicProp({\n * reducer: 'todos',\n * property: `items.${index}.title`,\n * });\n * return <span>{title}</span>;\n * }\n * ```\n *\n * @example Standalone with explicit generics\n * ```tsx\n * const title = useAtomicProp<'todos', AppState, 'todos', 'items.0.title'>(\n * { reducer: 'todos', property: 'items.0.title' }\n * );\n * ```\n *\n * @example Map over exact path\n * ```tsx\n * const len = useAtomicProp(\n * { reducer: 'todos', property: 'items' },\n * items => items.length\n * );\n * ```\n *\n * @example Glob pattern over state\n * ```tsx\n * const titles = useAtomicProp(\n * { reducer: 'todos', property: 'items.**' },\n * state => state.items.map(x => x.title),\n * shallowEqual\n * );\n * ```\n *\n * @public\n */\nexport function useAtomicProp<\n R extends string,\n S extends Record<R, any>,\n R1 extends R,\n P extends Dotted<S[R1]>,\n>(spec: { reducer: R1; property: P }): PathValue<S[R1], P>;\nexport function useAtomicProp<\n R extends string,\n S extends Record<R, any>,\n R1 extends R,\n P extends Dotted<S[R1]>,\n T,\n>(\n spec: { reducer: R1; property: P },\n map: (value: PathValue<S[R1], P>) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useAtomicProp<\n R extends string,\n S extends Record<R, any>,\n R1 extends R,\n P extends WithGlob<Dotted<S[R1]>>,\n T,\n>(\n spec: { reducer: R1; property: P },\n map: (value: any) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useAtomicProp<R extends string, S extends Record<R, any>>(spec: {\n reducer: R;\n property: string;\n}): unknown;\nexport function useAtomicProp<R extends string, S extends Record<R, any>, T>(\n spec: { reducer: R; property: string },\n map: (value: any) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useAtomicProp<R extends string, S extends Record<R, any>, T = any>(\n spec: { reducer: R; property: string },\n map?: (value: any) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n // One implementation regardless of whether `map` is passed, so toggling `map`\n // presence between renders never changes the hook call order (Rules of Hooks).\n return useAtomicPropImpl<R, S, T>(spec, map, isEqual);\n}\n\n/**\n * **Multi-path** fine-grained selector.\n *\n * Subscribes to several `reducer.property` paths (supports deep & wildcard)\n * and recomputes `selector(state)` when any of them change.\n *\n * @typeParam R - Slice name union.\n * @typeParam S - State record keyed by `R`.\n * @typeParam T - Derived value type.\n *\n * @param specs - Array of `{ reducer, property }`, where `property` can be a string or array of strings. Supports `*`/`**`.\n * @param selector - `(state) => T` function run against the full state.\n * @param isEqual - Equality comparator for the derived value (defaults to `Object.is`).\n *\n * @example\n * ```tsx\n * const total = useAtomicProps<'todos' | 'filter', AppState, number>(\n * [\n * { reducer: 'todos', property: 'items.**' },\n * { reducer: 'filter', property: 'q' }\n * ],\n * (s) => s.todos.items.filter(x => x.title.includes(s.filter.q)).length\n * );\n * ```\n *\n * @remarks\n * The selector receives **only the paths declared in `specs`**, not the whole store. Reading\n * anything else yields `undefined` in production and throws in development, naming the path.\n *\n * That is deliberate, and it replaced a real bug: the two arguments used to be independent, so\n * a component could subscribe to one path and read another. It compiled, it ran, and it worked\n * for as long as the two happened to change together — this repository shipped exactly that in\n * its own example, where a list subscribed to `todo.filter` while reading `todo.data` and\n * re-rendered only because adding a todo also rewrote `filter.categories`.\n *\n * Correct code is unaffected. Code that read more than it declared was already wrong, and now\n * says so on the first render rather than on the first day the coincidence breaks.\n *\n * @public\n */\nexport function useAtomicProps<R extends string, S extends Record<R, any>, T>(\n specs: Array<{ reducer: R; property: OneOrMany<WithGlob<Dotted<S[R]>>> }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useAtomicProps<R extends string, S extends Record<R, any>, T>(\n specs: Array<{ reducer: R; property: OneOrMany<string> }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useAtomicProps<R extends string, S extends Record<R, any>, T>(\n specs: Array<{\n reducer: R;\n property: OneOrMany<string> | OneOrMany<WithGlob<Dotted<S[R]>>>;\n }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n return useAtomicPropsImpl<R, S, T>(specs as any, selector, isEqual);\n}\n\n/** @internal */\nfunction useAtomicPropsImpl<R extends string, S extends Record<R, any>, T>(\n specs: Array<{\n reducer: R;\n property: OneOrMany<string> | OneOrMany<WithGlob<Dotted<S[R]>>>;\n }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n const store = useStore<EventMapBase, R, S>();\n\n const versionRef = useRef(0);\n const lastSelRef = useRef<T | undefined>(undefined);\n const lastVerRef = useRef<number>(-1);\n const hasValueRef = useRef(false);\n\n // Latest selector/isEqual via refs so passing them inline does not rebuild\n // getSnapshot (which would drop the memoized value) every render.\n const selectorRef = useRef(selector);\n selectorRef.current = selector;\n const isEqualRef = useRef(isEqual);\n isEqualRef.current = isEqual;\n\n const normalizedSpecs = useMemo(() => {\n return specs.map((sp) => ({\n reducer: sp.reducer,\n property: Array.isArray(sp.property)\n ? (sp.property as readonly string[]).map((p) => normalizePath(p as string))\n : normalizePath(sp.property as string),\n }));\n // `specsSignature` is a stable structural key for `specs`; keying the memo\n // on it (not the array, a fresh reference each render) is intentional and\n // already covers `specs`.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [specsSignature(specs)]);\n\n const subscribe = useMemo(\n () => (notify: () => void) => {\n const tick = () => {\n versionRef.current++;\n notify();\n };\n\n const unsubs = normalizedSpecs.flatMap((sp) => {\n const props = Array.isArray(sp.property) ? sp.property : [sp.property];\n return props.map((p) => store.connect({ reducer: sp.reducer, property: p }, tick));\n });\n\n return () => {\n for (const u of unsubs) u();\n };\n },\n [store, normalizedSpecs],\n );\n\n // Derived from the very specs that drive the subscriptions above, so what the selector can\n // see and what wakes the component come from one source and cannot drift apart.\n const declared = useMemo(\n () =>\n normalizedSpecs.flatMap((sp) =>\n (Array.isArray(sp.property) ? sp.property : [sp.property]).map((property) => ({\n reducer: sp.reducer as string,\n property,\n })),\n ),\n [normalizedSpecs],\n );\n\n const getSnapshot = useCallback(() => {\n if (lastVerRef.current !== versionRef.current || !hasValueRef.current) {\n const projection = projectDeclared(store.getState(), declared);\n const visible =\n process.env.NODE_ENV !== \"production\" ? guardProjection(projection, declared) : projection;\n const next = selectorRef.current(visible as DeepReadonly<S>);\n\n // Track presence with a boolean so an `undefined` selection still caches\n // (using `undefined` as \"no value yet\" would disable the equality cache).\n if (!hasValueRef.current || !isEqualRef.current(lastSelRef.current as T, next)) {\n lastSelRef.current = next;\n hasValueRef.current = true;\n }\n\n lastVerRef.current = versionRef.current;\n }\n\n return lastSelRef.current as T;\n }, [store, declared]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Subscribe to store events from a React component.\n *\n * This hook enables reactive UI patterns by allowing components to respond\n * to specific events without selecting state. Useful for:\n * - Showing notifications on certain events\n * - Triggering animations\n * - Logging/analytics\n * - Responding to rejected (uncommitted) events\n *\n * **Phases:**\n * - `'committed'` (default): Events that passed middleware and reached reducers\n * - `'uncommitted'`: Events rejected by middleware\n * - `'all'`: Both committed and uncommitted events (handler receives phase parameter)\n *\n * @typeParam EM - Event map type.\n * @typeParam C - Channel key within `EM`.\n * @typeParam T - Event type key within channel `C`.\n *\n * @param channel - Event channel to subscribe to.\n * @param type - Event type to subscribe to.\n * @param handler - Handler called when the event fires. Receives `(event, getState, emit, phase)`.\n * @param phase - Event phase to subscribe to (default: `'committed'`).\n *\n * @example Committed events (default)\n * ```tsx\n * useEvent('ui', 'save', (event, getState, emit, phase) => {\n * showToast('Saved successfully!');\n * });\n * ```\n *\n * @example Rejected events\n * ```tsx\n * useEvent('ui', 'delete', (event, getState, emit, phase) => {\n * showToast('Delete was blocked by middleware');\n * }, 'uncommitted');\n * ```\n *\n * @example All events\n * ```tsx\n * useEvent('ui', 'action', (event, getState, emit, phase) => {\n * console.log('Action:', phase); // 'committed' or 'uncommitted'\n * }, 'all');\n * ```\n *\n * @public\n */\nexport function useEvent<\n EM extends EventMapBase,\n C extends keyof EM & string,\n T extends keyof EM[C] & string,\n>(\n channel: C,\n type: T,\n handler: (\n event: Event<EM, C, T>,\n getState: () => DeepReadonly<any>,\n emit: Emit<EM>,\n phase: \"committed\" | \"uncommitted\",\n ) => void | Promise<void>,\n phase: EventPhase = \"committed\",\n): void {\n const store = useStore<EM, any, any>();\n const handlerRef = useRef(handler);\n handlerRef.current = handler; // Always keep latest handler (solves stale closures)\n\n useEffect(() => {\n return store.onEvent(\n channel,\n type,\n (event, getState, emit, eventPhase) => {\n handlerRef.current(event as Event<EM, C, T>, getState, emit, eventPhase);\n },\n phase,\n );\n }, [store, channel, type, phase]);\n}\n","/**\n * @module @yoltra/react\n */\n\nimport { useMemo, useRef, useSyncExternalStore } from \"react\";\nimport type { EventMapBase, StoreInstance, Dotted, WithGlob } from \"@yoltra/core\";\n\nimport { useStore } from \"./hooks\";\nimport { hasWildcard, normalizePath, getAtPath } from \"../utils/path\";\n\n/**\n * The `useStore` a Suspense hook reads through.\n *\n * @remarks\n * Passed in rather than imported so the same implementation can serve both the package-level\n * hooks and the ones {@link createSuspenseHooks} binds to a caller's own context.\n *\n * @internal\n */\ntype UseStoreHook<\n R extends string,\n S extends Record<R, any>,\n EM extends EventMapBase = EventMapBase,\n> = () => StoreInstance<R, S, EM>;\n\n/** @internal */\ntype CacheKey = string;\n\n/** @internal */\ntype CacheEntry<T> =\n | { status: \"ready\"; value: T; expiresAt: number | null }\n | { status: \"pending\"; promise: Promise<void>; expiresAt: number | null }\n | {\n status: \"error\";\n error: any;\n expiresAt: number | null;\n /**\n * Whether the error has been thrown to a boundary yet.\n *\n * @remarks\n * A failure must reach the boundary at least once, and time alone cannot express that.\n * The load rejects, the wrapper caches the error and *resolves*, React re-renders, and\n * only then does anybody read the entry. Expiring it by clock would drop it during that\n * gap, so the component would suspend again instead of surfacing the error — a silent\n * retry loop in place of a visible failure.\n */\n delivered?: boolean;\n };\n\n/**\n * Time-based expiry for a **settled** (`ready`) entry. A non-positive or `null`\n * `staleTime` means \"no time expiry\" — the entry is served until it is\n * invalidated (by a store change on the subscribed path, or an explicit\n * `invalidate`/`clear`). Only a positive `staleTime` adds a wall-clock bound.\n *\n * Critically, `staleTime: 0` (the default) must NOT map to `Date.now()` here:\n * an entry that expires on the same tick it was created would be re-loaded on\n * the very next render, throwing a fresh promise each time (infinite suspend).\n * @internal\n */\nfunction computeExpiry(staleTime: number | null): number | null {\n return staleTime == null || staleTime <= 0 ? null : Date.now() + staleTime;\n}\n\n/**\n * Expiry for a **failed** entry.\n *\n * @remarks\n * Cached errors used to be held until something invalidated them, which made a retry button\n * unable to retry: the boundary resets, the component renders, and the stored error is thrown\n * again without the loader ever running a second time. A network blip became permanent for\n * the life of the page.\n *\n * So an error is delivered and then discarded by default — the next read starts a fresh load.\n * A positive `errorTtlMs` puts a floor between attempts, and `null` restores the old behaviour\n * for a caller who genuinely wants a failure to stick until they clear it.\n *\n * Returns `0` rather than `Date.now()` for the default: an entry stamped with the current\n * millisecond would still be served for the rest of that millisecond, which is exactly the\n * window a re-render after a boundary reset falls into.\n *\n * @internal\n */\nfunction computeErrorExpiry(errorTtlMs: number | null | undefined): number | null {\n if (errorTtlMs === null) return null;\n if (errorTtlMs === undefined || errorTtlMs <= 0) return 0;\n return Date.now() + errorTtlMs;\n}\n\n/**\n * Upper bound on cached entries.\n *\n * @remarks\n * Keys are built from the reducer and the subscribed path, so a component reading a dynamic path\n * — `byId.${userId}.name` and its like — mints a new one per value it has ever seen. Unbounded,\n * that grows for the lifetime of the process, and because the cache is module-scoped it does so\n * across server requests too. A few thousand entries is far past any real working set while\n * still being a bound.\n *\n * @internal\n */\nconst MAX_ENTRIES = 2000;\n\n/** @internal */\nclass SuspenseCache {\n private store = new Map<CacheKey, CacheEntry<any>>();\n\n /**\n * Marks a key as most recently used, and evicts the coldest entries past the cap.\n *\n * @remarks\n * A `Map` iterates in insertion order, so deleting and re-inserting a key moves it to the end\n * and the first key is the least recently used. That is the whole LRU: no timestamps, no\n * second structure.\n *\n * @internal\n */\n private touch(key: CacheKey): void {\n if (this.store.has(key)) this.store.delete(key);\n }\n\n /** @internal */\n private evict(): void {\n while (this.store.size > MAX_ENTRIES) {\n const oldest = this.store.keys().next();\n if (oldest.done === true) return;\n // Never evict a load in flight: the promise is what a suspended component is waiting on,\n // and dropping it would leave that component suspended forever.\n const entry = this.store.get(oldest.value);\n if (entry?.status === \"pending\") {\n // Move it to the end and look at the next candidate instead.\n this.store.delete(oldest.value);\n this.store.set(oldest.value, entry);\n continue;\n }\n this.store.delete(oldest.value);\n }\n }\n\n /** Number of entries currently held. */\n get size(): number {\n return this.store.size;\n }\n\n read<T>(\n key: CacheKey,\n load: () => T | Promise<T>,\n staleTime: number | null,\n errorTtlMs: number | null | undefined,\n ): T {\n const now = Date.now();\n const entry = this.store.get(key);\n\n // A ready value is served until it time-expires (staleTime > 0) or is\n // invalidated. With staleTime 0/null it never time-expires (expiresAt null).\n if (entry && entry.status === \"ready\" && (entry.expiresAt == null || entry.expiresAt > now)) {\n // Re-inserting keeps this key young; without it the eviction order would reflect when a\n // value was first loaded rather than when it was last wanted.\n this.touch(key);\n this.store.set(key, entry);\n return entry.value as T;\n }\n // A load already in flight: always re-throw the SAME promise until it\n // settles. Pending entries are never time-expired — otherwise every render\n // during the load would spawn a fresh load (infinite suspend / request storm).\n if (entry && entry.status === \"pending\") {\n throw entry.promise;\n }\n // A cached error is re-thrown to the nearest error boundary while it is still held. Once\n // it expires — immediately, by default — it is dropped and the load below runs again, so\n // resetting the boundary genuinely retries instead of re-delivering the same failure.\n // Error caching is independent of staleTime, which governs successful values.\n if (entry && entry.status === \"error\") {\n // Always surface it once: the boundary has not seen it yet.\n if (entry.delivered !== true) {\n this.store.set(key, { ...entry, delivered: true });\n throw entry.error;\n }\n // Seen. Held only while a caller asked for it to be held; otherwise the read below\n // retries, which is what makes resetting a boundary retry rather than re-deliver.\n if (entry.expiresAt === null || entry.expiresAt > now) throw entry.error;\n this.store.delete(key);\n }\n\n const promise = Promise.resolve()\n .then(load)\n .then((value) => {\n this.store.set(key, { status: \"ready\", value, expiresAt: computeExpiry(staleTime) });\n })\n .catch((err) => {\n this.store.set(key, {\n status: \"error\",\n error: err,\n expiresAt: computeErrorExpiry(errorTtlMs),\n });\n });\n\n this.store.set(key, { status: \"pending\", promise, expiresAt: null });\n this.evict();\n throw promise;\n }\n\n invalidate(key: CacheKey) {\n this.store.delete(key);\n }\n\n /**\n * Drops the entry for one `reducer::path` in **every** store that has one.\n *\n * @remarks\n * Entry keys carry a store id, but {@link invalidateAtomicProp} names only a path — a caller\n * holding a path has no handle on the store instances that cached it. Matching on the part\n * after the id invalidates that path wherever it was loaded, which is what the un-scoped\n * public function has always meant.\n *\n * @internal\n */\n invalidatePathKey(pathKey: string) {\n for (const k of this.store.keys()) {\n if (stripStoreId(k) === pathKey) this.store.delete(k);\n }\n }\n\n /**\n * Drops every entry that reads from `reducer`, in any store.\n *\n * @remarks\n * A multi-path entry joins its parts with `||`, so the reducer can appear anywhere in the key\n * rather than only at the front — checking each part catches the composite entries that a\n * plain prefix match would leave stale.\n *\n * @internal\n */\n invalidateReducer(reducer: string) {\n const needle = `${reducer}::`;\n for (const k of this.store.keys()) {\n if (stripStoreId(k).split(\"||\").some((part) => part.startsWith(needle))) this.store.delete(k);\n }\n }\n\n clear() {\n this.store.clear();\n }\n}\n\n/**\n * Default Suspense cache instance shared by all `useSuspense*` hooks.\n *\n * Use {@link invalidateAtomicProp}, {@link invalidateAtomicPropsByReducer},\n * or {@link clearSuspenseCache} to manage the cache from outside hooks.\n *\n * @public\n */\nexport const suspenseCache = new SuspenseCache();\n\n/**\n * Stable per-store id, minted lazily.\n *\n * @remarks\n * Cache keys used to be `reducer::path`, which is not unique across stores: two stores with a\n * `fleet` reducer would share one entry, and whichever loaded first would serve the other. That\n * was reachable through `StoreProvider` scoping and is reachable now through\n * {@link createSuspenseHooks}, where a store's own Suspense hooks are the normal way to call\n * them. Prefixing the key with the store's identity keeps the entries apart.\n *\n * A `WeakMap` because the id must not keep a discarded store alive — a per-request store in SSR\n * is collected as soon as the request ends, and with it any reason to remember its id.\n *\n * @internal\n */\nconst storeIds = new WeakMap<object, string>();\n/** @internal */\nlet nextStoreId = 0;\n\n/** @internal */\nfunction storeKey(store: object): string {\n let id = storeIds.get(store);\n if (id === undefined) {\n id = `s${++nextStoreId}`;\n storeIds.set(store, id);\n }\n return id;\n}\n\n/**\n * The part of an entry key that names the data, with the store id removed.\n * Ids are `s<n>` and contain no `::`, so the first separator ends the id.\n * @internal\n */\nfunction stripStoreId(key: CacheKey): string {\n return key.slice(key.indexOf(\"::\") + 2);\n}\n\n/**\n * The path half of an entry key: `reducer::path[::extraKey]`.\n * Combine with {@link storeKey} to address an actual entry.\n * @internal\n */\nfunction buildKey(reducer: string, props: string[] | string, extraKey?: string): string {\n const p = Array.isArray(props) ? props.map(normalizePath).sort().join(\"|\") : normalizePath(props);\n return extraKey ? `${reducer}::${p}::${extraKey}` : `${reducer}::${p}`;\n}\n\n/**\n * Options for {@link useSuspenseAtomicProp}.\n *\n * @typeParam T - The resolved value type after loading.\n * @typeParam S - Store state record.\n *\n * @example\n * ```ts\n * const options: SuspenseAtomicPropOptions<User, AppState> = {\n * load: async (userId) => fetchUser(userId),\n * staleTime: 30_000, // cache for 30 seconds\n * key: 'user-detail',\n * };\n * ```\n *\n * @public\n */\nexport interface SuspenseAtomicPropOptions<T, S> {\n /** Async loader that receives the value at the path and the full slice. */\n load: (valueAtPath: any, slice: S[keyof S]) => Promise<T> | T;\n /**\n * Extra wall-clock TTL (ms) for a resolved value. `0` (the default) or omitted\n * means the cached value is served until the subscribed path changes or you\n * invalidate it explicitly; a positive value additionally expires it after that\n * many ms. Cached errors ignore this and are re-thrown until invalidated.\n */\n staleTime?: number;\n /**\n * How long a **failed** load is remembered, in milliseconds.\n *\n * @remarks\n * `0` or omitted — the default — delivers the error to the nearest boundary and then forgets\n * it, so resetting that boundary retries the load. Held errors made a retry button unable to\n * retry, which turned a transient failure into a permanent one.\n *\n * A positive value puts a floor between attempts, for a loader that fails fast and would\n * otherwise be re-attempted on every reset. `null` holds the failure until something calls\n * `invalidate`, which is the old behaviour and is now something you ask for.\n */\n errorTtlMs?: number | null;\n /** Optional extra key to differentiate cache entries for the same path. */\n key?: string;\n}\n\n/**\n * Suspense-compatible version of `useAtomicProp` that throws a promise while loading.\n *\n * Subscribes to a single dotted path and calls `options.load` to produce the\n * resolved value. While the promise is pending, React Suspense catches it and\n * renders the nearest `<Suspense>` fallback.\n *\n * @remarks\n * **Client-only loading.** During server rendering this hook does not suspend\n * (throwing a promise would crash `renderToString`): `getServerSnapshot` returns\n * the current value at the path **without** invoking `options.load`. Perform the\n * actual load on the client.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n * @typeParam P - Dotted path within `S[R]`.\n * @typeParam T - Resolved value type.\n *\n * @param storeSpec - `{ reducer, property }` identifying the path to subscribe to.\n * @param options - Loading options (see {@link SuspenseAtomicPropOptions}).\n * @returns The resolved value of type `T`.\n *\n * @throws A `Promise` while loading (caught by React Suspense).\n * @throws If called outside a `<StoreProvider>`.\n *\n * @example\n * ```tsx\n * function UserName({ userId }: { userId: string }) {\n * const name = useSuspenseAtomicProp(\n * { reducer: 'users', property: `byId.${userId}.name` },\n * { load: async (name) => name ?? (await fetchUser(userId)).name },\n * );\n * return <span>{name}</span>;\n * }\n *\n * // Wrap with Suspense\n * <Suspense fallback={<Spinner />}>\n * <UserName userId=\"123\" />\n * </Suspense>\n * ```\n *\n * @public\n */\nexport function useSuspenseAtomicProp<\n R extends string,\n S extends Record<R, any>,\n P extends Dotted<S[R]>,\n T,\n>(storeSpec: { reducer: R; property: P }, options: SuspenseAtomicPropOptions<T, S>): T;\nexport function useSuspenseAtomicProp<R extends string, S extends Record<R, any>, T>(\n storeSpec: { reducer: R; property: string },\n options: SuspenseAtomicPropOptions<T, S>,\n): T;\nexport function useSuspenseAtomicProp<R extends string, S extends Record<R, any>, T>(\n storeSpec: { reducer: R; property: string },\n options: SuspenseAtomicPropOptions<T, S>,\n): T {\n return useSuspenseAtomicPropImpl<R, S, any, T>(\n useStore as UseStoreHook<R, S>,\n storeSpec as any,\n options,\n );\n}\n\n/** @internal */\nfunction useSuspenseAtomicPropImpl<\n R extends string,\n S extends Record<R, any>,\n P extends Dotted<S[R]>,\n T,\n EM extends EventMapBase = EventMapBase,\n>(\n useStoreHook: UseStoreHook<R, S, EM>,\n storeSpec: { reducer: R; property: P },\n options: SuspenseAtomicPropOptions<T, S>,\n): T {\n const store = useStoreHook();\n const reducer = storeSpec.reducer;\n const path = normalizePath(storeSpec.property as string);\n const key = `${storeKey(store)}::${buildKey(reducer, path, options.key)}`;\n\n const subscribe = useMemo(() => {\n return (notify: () => void) =>\n store.connect({ reducer, property: path }, () => {\n suspenseCache.invalidate(key);\n notify();\n });\n }, [store, reducer, path, key]);\n\n // Keep the latest options in a ref so an inline `options` object doesn't\n // rebuild getSnapshot every render (RX-5).\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const getSnapshot = useMemo(() => {\n const isGlob = hasWildcard(path);\n return () => {\n const state = store.getState() as S;\n const slice = state[reducer];\n const val = isGlob ? slice : getAtPath(slice, path);\n const opts = optionsRef.current;\n return suspenseCache.read<T>(key, () => opts.load(val, slice), opts.staleTime ?? 0, opts.errorTtlMs);\n };\n }, [store, reducer, path, key]);\n\n // Server render must NOT suspend — throwing a promise from getServerSnapshot\n // crashes renderToString. Return the current value at the path without loading\n // (client-only Suspense loading; see the hook's SSR note).\n const getServerSnapshot = useMemo(() => {\n const isGlob = hasWildcard(path);\n return () => {\n const state = store.getState() as S;\n const slice = state[reducer];\n return (isGlob ? slice : getAtPath(slice, path)) as T;\n };\n }, [store, reducer, path]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\n/**\n * Options for {@link useSuspenseAtomicProps}.\n *\n * @typeParam T - The resolved value type after loading.\n * @typeParam S - Store state record.\n *\n * @public\n */\nexport interface SuspenseAtomicPropsOptions<T, S> {\n /** Async loader that receives the full store state. */\n load: (state: S) => Promise<T> | T;\n /**\n * Extra wall-clock TTL (ms) for a resolved value. `0` (the default) or omitted\n * means the cached value is served until the subscribed path changes or you\n * invalidate it explicitly; a positive value additionally expires it after that\n * many ms. Cached errors ignore this and are re-thrown until invalidated.\n */\n staleTime?: number;\n /**\n * How long a **failed** load is remembered, in milliseconds.\n *\n * @remarks\n * `0` or omitted — the default — delivers the error to the nearest boundary and then forgets\n * it, so resetting that boundary retries the load. Held errors made a retry button unable to\n * retry, which turned a transient failure into a permanent one.\n *\n * A positive value puts a floor between attempts, for a loader that fails fast and would\n * otherwise be re-attempted on every reset. `null` holds the failure until something calls\n * `invalidate`, which is the old behaviour and is now something you ask for.\n */\n errorTtlMs?: number | null;\n /** Optional extra key to differentiate cache entries. */\n key?: string;\n}\n\n/**\n * Suspense-compatible version of `useAtomicProps` that throws a promise while loading.\n *\n * Subscribes to multiple dotted paths and calls `options.load` with the full state\n * to produce the resolved value. While the promise is pending, React Suspense\n * renders the nearest `<Suspense>` fallback.\n *\n * @remarks\n * **Client-only loading.** During server rendering this hook does not suspend\n * (throwing a promise would crash `renderToString`): `getServerSnapshot` uses a\n * synchronous `options.load` result if one is available, otherwise `undefined`.\n * Perform the actual load on the client.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n * @typeParam T - Resolved value type.\n *\n * @param specs - Array of `{ reducer, property }` paths to subscribe to.\n * @param options - Loading options (see {@link SuspenseAtomicPropsOptions}).\n * @returns The resolved value of type `T`.\n *\n * @throws A `Promise` while loading (caught by React Suspense).\n * @throws If called outside a `<StoreProvider>`.\n *\n * @example\n * ```tsx\n * function Dashboard() {\n * const stats = useSuspenseAtomicProps(\n * [\n * { reducer: 'orders', property: 'items.**' },\n * { reducer: 'users', property: 'active' },\n * ],\n * { load: async (state) => computeDashboardStats(state) },\n * );\n * return <StatsGrid data={stats} />;\n * }\n * ```\n *\n * @public\n */\nexport function useSuspenseAtomicProps<R extends string, S extends Record<R, any>, T>(\n specs: Array<{\n reducer: R;\n property: Dotted<S[R]> | WithGlob<Dotted<S[R]>> | ReadonlyArray<WithGlob<Dotted<S[R]>>>;\n }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n): T;\nexport function useSuspenseAtomicProps<R extends string, S extends Record<R, any>, T>(\n specs: Array<{ reducer: R; property: string | readonly string[] }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n): T;\nexport function useSuspenseAtomicProps<R extends string, S extends Record<R, any>, T>(\n specs: Array<{\n reducer: R;\n property:\n | string\n | readonly string[]\n | Dotted<S[R]>\n | WithGlob<Dotted<S[R]>>\n | ReadonlyArray<WithGlob<Dotted<S[R]>>>;\n }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n): T {\n return useSuspenseAtomicPropsImpl<R, S, T>(useStore as UseStoreHook<R, S>, specs as any, options);\n}\n\n/** @internal */\nfunction useSuspenseAtomicPropsImpl<\n R extends string,\n S extends Record<R, any>,\n T,\n EM extends EventMapBase = EventMapBase,\n>(\n useStoreHook: UseStoreHook<R, S, EM>,\n specs: Array<{\n reducer: R;\n property:\n | string\n | readonly string[]\n | Dotted<S[R]>\n | WithGlob<Dotted<S[R]>>\n | ReadonlyArray<WithGlob<Dotted<S[R]>>>;\n }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n): T {\n const store = useStoreHook();\n\n const normalized = useMemo(\n () =>\n specs.map((sp) => ({\n reducer: sp.reducer,\n property: Array.isArray(sp.property)\n ? (sp.property as readonly string[]).map((p) => normalizePath(p as string))\n : normalizePath(sp.property as string),\n })),\n // `specs` is a fresh reference each render; keying the memo on its JSON\n // signature is intentional and already covers `specs`.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [JSON.stringify(specs)],\n );\n\n const key = useMemo(() => {\n const parts = normalized\n .map((sp) => buildKey(sp.reducer, sp.property))\n .sort()\n .join(\"||\");\n return `${storeKey(store)}::${options.key ? `${parts}::${options.key}` : parts}`;\n }, [store, normalized, options.key]);\n\n const subscribe = useMemo(() => {\n return (notify: () => void) => {\n const wrapped = () => {\n suspenseCache.invalidate(key);\n notify();\n };\n const unsubs = normalized.map((sp) => store.connect(sp as any, wrapped));\n return () => {\n for (const u of unsubs) u();\n };\n };\n }, [store, normalized, key]);\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const getSnapshot = useMemo(() => {\n return () => {\n const state = store.getState() as S;\n const opts = optionsRef.current;\n return suspenseCache.read<T>(key, () => opts.load(state), opts.staleTime ?? 0, opts.errorTtlMs);\n };\n }, [store, key]);\n\n // Server render must NOT suspend. Use a synchronous load result if one is\n // available; otherwise render `undefined` rather than throwing a promise.\n const getServerSnapshot = () => {\n const result = optionsRef.current.load(store.getState() as S);\n return (result instanceof Promise ? undefined : result) as T;\n };\n\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\n/**\n * Invalidates the Suspense cache entry for a specific `reducer.property` path.\n *\n * @param reducer - Reducer (slice) name.\n * @param property - Dotted property path.\n * @param extraKey - Optional extra key if the hook was created with `options.key`.\n *\n * @example\n * ```ts\n * invalidateAtomicProp('users', 'byId.123.name');\n * ```\n *\n * @public\n */\nexport function invalidateAtomicProp(reducer: string, property: string, extraKey?: string) {\n suspenseCache.invalidatePathKey(buildKey(reducer, property, extraKey));\n}\n\n/**\n * Invalidates all Suspense cache entries for a given reducer (slice).\n *\n * @param reducer - Reducer (slice) name whose cache entries should be cleared.\n *\n * @example\n * ```ts\n * invalidateAtomicPropsByReducer('users');\n * ```\n *\n * @public\n */\nexport function invalidateAtomicPropsByReducer(reducer: string) {\n suspenseCache.invalidateReducer(reducer);\n}\n\n/**\n * Clears the entire Suspense cache, forcing all `useSuspense*` hooks to re-load.\n *\n * @example\n * ```ts\n * // After a logout, clear all cached data\n * clearSuspenseCache();\n * ```\n *\n * @public\n */\nexport function clearSuspenseCache() {\n suspenseCache.clear();\n}\n\n/**\n * Call signature for the typed `useSuspenseAtomicProp` returned by `createHooks`.\n *\n * Identical in behaviour to the package-level {@link useSuspenseAtomicProp}; the reducer union\n * and state shape are fixed by the store the hooks were created for, so neither has to be\n * supplied at the call site.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n *\n * @public\n */\nexport type UseSuspenseAtomicProp<R extends string, S extends Record<R, any>> = {\n <R1 extends R, P extends Dotted<S[R1]>, T>(\n storeSpec: { reducer: R1; property: P },\n options: SuspenseAtomicPropOptions<T, S>,\n ): T;\n <R1 extends R, T>(\n storeSpec: { reducer: R1; property: string },\n options: SuspenseAtomicPropOptions<T, S>,\n ): T;\n};\n\n/**\n * Call signature for the typed `useSuspenseAtomicProps` returned by `createHooks`.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n *\n * @public\n */\nexport type UseSuspenseAtomicProps<R extends string, S extends Record<R, any>> = {\n <R1 extends R, T>(\n specs: Array<{\n reducer: R1;\n property: WithGlob<Dotted<S[R1]>> | ReadonlyArray<WithGlob<Dotted<S[R1]>>>;\n }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n ): T;\n <R1 extends R, T>(\n specs: Array<{ reducer: R1; property: string | readonly string[] }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n ): T;\n};\n\n/**\n * Builds the Suspense hooks against a caller-supplied `useStore`.\n *\n * @remarks\n * The package-level `useSuspenseAtomicProp`/`useSuspenseAtomicProps` read the package-level\n * `StoreContext`. `createHooks` is given a *different* context, so its hook set used to stop\n * short of Suspense: mixing the two families threw \"useStore must be used inside\n * <StoreProvider>\" at runtime, with nothing in the types to warn about it, because the store\n * was in the other context all along. Building them here from the same `useStore` the rest of\n * the set uses makes the set complete.\n *\n * @internal\n */\nexport function createSuspenseHooks<\n R extends string,\n S extends Record<R, any>,\n EM extends EventMapBase = EventMapBase,\n>(\n useStoreHook: UseStoreHook<R, S, EM>,\n): {\n useSuspenseAtomicProp: UseSuspenseAtomicProp<R, S>;\n useSuspenseAtomicProps: UseSuspenseAtomicProps<R, S>;\n} {\n const useSuspenseAtomicPropBound = <T,>(\n storeSpec: { reducer: R; property: string },\n options: SuspenseAtomicPropOptions<T, S>,\n ): T => useSuspenseAtomicPropImpl<R, S, any, T, EM>(useStoreHook, storeSpec as any, options);\n\n const useSuspenseAtomicPropsBound = <T,>(\n specs: Array<{ reducer: R; property: string | readonly string[] }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n ): T => useSuspenseAtomicPropsImpl<R, S, T, EM>(useStoreHook, specs as any, options);\n\n return {\n useSuspenseAtomicProp: useSuspenseAtomicPropBound as UseSuspenseAtomicProp<R, S>,\n useSuspenseAtomicProps: useSuspenseAtomicPropsBound as UseSuspenseAtomicProps<R, S>,\n };\n}","/**\n * @module @yoltra/react\n */\n\nimport type {\n DeepReadonly,\n Dotted,\n Emit,\n Event,\n EventMapBase,\n EventPhase,\n PathValue,\n StoreInstance,\n WithGlob,\n} from \"@yoltra/core\";\nimport * as React from \"react\";\nimport { useCallback, useContext, useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport { getAtPath, hasWildcard, normalizePath, specsSignature, toDottedPath } from \"../utils/path\";\nimport { shallowEqual } from \"../utils/shallowEqual\";\nimport { useStableSnapshot } from \"../utils/useStableSnapshot\";\nimport {\n createSuspenseHooks,\n type UseSuspenseAtomicProp,\n type UseSuspenseAtomicProps,\n} from \"./suspense\";\n\n/**\n * Call signature for the typed `useAtomicProp` hook returned by {@link createHooks}.\n *\n * Subscribes to a specific dotted path in a reducer's state and re-renders\n * only when that path changes. All type parameters are inferred automatically\n * from the store context — no explicit generics needed.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n *\n * @example\n * ```tsx\n * const { useAtomicProp } = createHooks(AppStoreContext);\n *\n * function TodoTitle({ index }: { index: number }) {\n * const title = useAtomicProp({\n * reducer: 'todos',\n * property: `items.${index}.title`,\n * });\n * return <span>{title}</span>;\n * }\n * ```\n *\n * @public\n */\nexport type UseAtomicProp<R extends string, S extends Record<R, any>> = {\n // Typed accessor form: `p => p.a.b.c` gives full autocomplete + inferred return type.\n <R1 extends R, V>(\n reducer: R1,\n accessor: (state: DeepReadonly<S[R1]>) => V,\n isEqual?: (a: V, b: V) => boolean,\n ): V;\n <R1 extends R, P extends Dotted<S[R1]>>(spec: {\n reducer: R1;\n property: P;\n }): PathValue<S[R1], P>;\n <R1 extends R, P extends Dotted<S[R1]>, T>(\n spec: { reducer: R1; property: P },\n map: (value: PathValue<S[R1], P>) => T,\n isEqual?: (a: T, b: T) => boolean,\n ): T;\n <R1 extends R, P extends WithGlob<Dotted<S[R1]>>, T>(\n spec: { reducer: R1; property: P },\n map: (value: unknown) => T,\n isEqual?: (a: T, b: T) => boolean,\n ): T;\n <R1 extends R>(spec: { reducer: R1; property: string }): unknown;\n <R1 extends R, T>(\n spec: { reducer: R1; property: string },\n map: (value: unknown) => T,\n isEqual?: (a: T, b: T) => boolean,\n ): T;\n};\n\n/**\n * Call signature for the typed `useAtomicProps` hook returned by {@link createHooks}.\n *\n * Subscribes to multiple dotted paths across one or more reducers and recomputes\n * a derived value when any of them change.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n *\n * @example\n * ```tsx\n * const { useAtomicProps } = createHooks(AppStoreContext);\n *\n * function FilteredCount() {\n * const count = useAtomicProps(\n * [\n * { reducer: 'todos', property: 'items.**' },\n * { reducer: 'filter', property: 'q' },\n * ],\n * (s) => s.todos.items.filter(x => x.title.includes(s.filter.q)).length,\n * );\n * return <span>{count}</span>;\n * }\n * ```\n *\n * @public\n */\nexport type UseAtomicProps<R extends string, S extends Record<R, any>> = {\n <R1 extends R, T>(\n specs: Array<{\n reducer: R1;\n property: WithGlob<Dotted<S[R1]>> | readonly WithGlob<Dotted<S[R1]>>[];\n }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual?: (a: T, b: T) => boolean,\n ): T;\n <R1 extends R, T>(\n specs: Array<{ reducer: R1; property: string | readonly string[] }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual?: (a: T, b: T) => boolean,\n ): T;\n};\n\n/**\n * Call signature for the typed `useEvent` hook returned by {@link createHooks}.\n *\n * Subscribes to store events from a React component. Useful for notifications,\n * animations, analytics, and responding to rejected (uncommitted) events.\n *\n * @typeParam EM - Event map type.\n * @typeParam S - Store state type.\n *\n * @example\n * ```tsx\n * const { useEvent } = createHooks(AppStoreContext);\n *\n * function SaveNotifier() {\n * useEvent('ui', 'save', (event) => {\n * showToast('Saved!');\n * });\n * return null;\n * }\n * ```\n *\n * @public\n */\nexport type UseEvent<EM extends EventMapBase, S> = <\n C extends keyof EM & string,\n T extends keyof EM[C] & string,\n>(\n channel: C,\n type: T,\n handler: (\n event: Event<EM, C, T>,\n getState: () => DeepReadonly<S>,\n emit: Emit<EM>,\n phase: \"committed\" | \"uncommitted\",\n ) => void | Promise<void>,\n phase?: EventPhase,\n) => void;\n\n/**\n * The bundle of fully-typed hooks returned by {@link createHooks} (and, with the\n * store and provider added, by {@link createYoltra}).\n *\n * Naming this return shape explicitly — rather than letting it be inferred —\n * keeps `createYoltra`'s emitted `.d.ts` portable: the inferred form would leak\n * a reference to a non-re-exported internal symbol and trip TS2742 in\n * `composite`/`declaration` consumers.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n * @typeParam EM - Event map.\n *\n * @public\n */\nexport interface YoltraHooks<\n R extends string,\n S extends Record<R, any>,\n EM extends EventMapBase,\n> {\n /** Reads the current store from context (falling back to the default store). */\n useStore: () => StoreInstance<R, S, EM>;\n /** Returns the store's typed `emit`. */\n useEmit: () => Emit<EM>;\n /** Subscribes to a derived value with an optional equality comparator. */\n useSelector: <T>(selector: (state: DeepReadonly<S>) => T, isEqual?: (a: T, b: T) => boolean) => T;\n /** Subscribes to a single dotted path (or typed accessor). */\n useAtomicProp: UseAtomicProp<R, S>;\n /** Subscribes to several paths and derives a value from the full state. */\n useAtomicProps: UseAtomicProps<R, S>;\n /** Runs a handler for a specific `(channel, type)` event. */\n useEvent: UseEvent<EM, S>;\n /** Suspense-loading variant of `useAtomicProp`, bound to the same context. */\n useSuspenseAtomicProp: UseSuspenseAtomicProp<R, S>;\n /** Suspense-loading variant of `useAtomicProps`, bound to the same context. */\n useSuspenseAtomicProps: UseSuspenseAtomicProps<R, S>;\n /** Shallow object equality using `Object.is` per-key. */\n shallowEqual: <T extends Record<string, unknown>>(a: T, b: T) => boolean;\n}\n\n/**\n * Factory that creates fully-typed React hooks bound to a specific store context.\n *\n * This is the **recommended** setup pattern for yoltra + React. It eliminates\n * the need for explicit type parameters on every hook call — all types are\n * inferred from the store context once, at creation time.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n * @typeParam EM - Event map.\n *\n * @param StoreContext - A React context carrying a `StoreInstance<R, S, EM>`.\n * @returns An object with typed hooks: `useStore`, `useEmit`, `useSelector`,\n * `useAtomicProp`, `useAtomicProps`, `useEvent`, `useSuspenseAtomicProp`,\n * `useSuspenseAtomicProps`, and `shallowEqual`.\n *\n * @throws If any returned hook is called outside a `<StoreProvider>`.\n *\n * @example Complete setup\n * ```tsx\n * // 1. Define your event map and state\n * type AppEM = { ui: { increment: number; decrement: number } };\n * type AppState = { counter: { value: number } };\n *\n * // 2. Create a typed context\n * import { createContext } from 'react';\n * import { StoreInstance } from '@yoltra/core';\n * const AppStoreContext = createContext<\n * StoreInstance<'counter', AppState, AppEM> | null\n * >(null);\n *\n * // 3. Create typed hooks (do this once, export from a shared module)\n * const { useAtomicProp, useEmit, useEvent } = createHooks(AppStoreContext);\n *\n * // 4. Use in components — no explicit generics needed\n * function Counter() {\n * const value = useAtomicProp({ reducer: 'counter', property: 'value' });\n * const emit = useEmit();\n * return (\n * <button onClick={() => emit('ui', 'increment', 1)}>\n * Count: {value}\n * </button>\n * );\n * }\n * ```\n *\n * @public\n */\nexport function createHooks<\n R extends string,\n S extends Record<R, any>,\n EM extends EventMapBase,\n>(StoreContext: React.Context<StoreInstance<R, S, EM> | null>): YoltraHooks<R, S, EM> {\n function useStore(): StoreInstance<R, S, EM> {\n const ctx = useContext(StoreContext);\n if (!ctx) {\n // These hooks come from createHooks(context)/createYoltra. createYoltra\n // defaults the context to its own store, so this only fires when the\n // context was created with a `null` default and no StoreProvider supplied\n // a store above this component.\n throw new Error(\n \"[yoltra] No store in context. Wrap your tree in <StoreProvider store={...}>, \" +\n \"or use the hooks returned by createYoltra (which default to their own store).\",\n );\n }\n return ctx;\n }\n\n function useEmit(): Emit<EM> {\n return useStore().emit;\n }\n\n function useSelector<T>(\n selector: (state: DeepReadonly<S>) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n ): T {\n const store = useStore();\n const subscribe = useMemo(() => (notify: () => void) => store.subscribe(notify), [store]);\n const getSnapshot = useStableSnapshot(() => selector(store.getState()), isEqual, [store]);\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n }\n\n type UseAtomicPropOverloads = UseAtomicProp<R, S>;\n\n const useAtomicPropImpl = (\n specOrReducer: { reducer: R; property: string } | R,\n mapOrAccessor?: (value: any) => unknown,\n isEqual?: (a: unknown, b: unknown) => boolean,\n ): unknown => {\n const store = useStore();\n\n // Two calling conventions, normalized to { reducer, property } + optional map:\n // - useAtomicProp({ reducer, property }, map?, isEqual?) (dotted-path string)\n // - useAtomicProp(reducer, p => p.a.b, isEqual?) (typed accessor)\n const accessorForm = typeof specOrReducer === \"string\";\n const reducer = (accessorForm ? specOrReducer : specOrReducer.reducer) as R;\n const rawProperty = accessorForm\n ? toDottedPath(mapOrAccessor as (p: any) => any)\n : specOrReducer.property;\n const map = accessorForm ? undefined : mapOrAccessor;\n\n const normalizedSpec = useMemo(() => {\n return { reducer, property: normalizePath(rawProperty) } as const;\n }, [reducer, rawProperty]);\n\n const subscribe = useMemo(\n () => (notify: () => void) =>\n store.connect(\n { reducer: normalizedSpec.reducer, property: normalizedSpec.property },\n () => notify(),\n ),\n [store, normalizedSpec],\n );\n\n const isGlob = hasWildcard(normalizedSpec.property);\n const getSnapshot = useStableSnapshot(\n () => {\n const full = store.getState() as DeepReadonly<S>;\n const slice = (full as any)[normalizedSpec.reducer];\n const source = isGlob ? slice : getAtPath(slice, normalizedSpec.property);\n return map ? map(source) : source;\n },\n isEqual ?? Object.is,\n [store, normalizedSpec],\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n };\n\n const useAtomicProp = useAtomicPropImpl as unknown as UseAtomicPropOverloads;\n\n type OneOrMany<T> = T | readonly T[];\n type UseAtomicPropsOverloads = UseAtomicProps<R, S>;\n\n const useAtomicPropsImpl = <T>(\n specs: Array<{ reducer: R; property: OneOrMany<string> }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n ): T => {\n const store = useStore();\n const versionRef = useRef(0);\n const lastSelRef = useRef<T | undefined>(undefined);\n const lastVerRef = useRef<number>(-1);\n const hasValueRef = useRef(false);\n\n // Keep the latest selector/isEqual in refs so passing them inline does not\n // rebuild getSnapshot (which would drop the memoized value) every render.\n const selectorRef = useRef(selector);\n selectorRef.current = selector;\n const isEqualRef = useRef(isEqual);\n isEqualRef.current = isEqual;\n\n const normalizedSpecs = useMemo(() => {\n return specs.map((sp) => ({\n reducer: sp.reducer,\n property: Array.isArray(sp.property)\n ? (sp.property as readonly string[]).map((p) => normalizePath(p))\n : normalizePath(sp.property as string),\n }));\n // `specsSignature` is a stable structural key for `specs`; keying the memo\n // on it (not the array, a fresh reference each render) is intentional and\n // already covers `specs`.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [specsSignature(specs)]);\n\n const subscribe = useMemo(\n () => (notify: () => void) => {\n const tick = () => {\n versionRef.current++;\n notify();\n };\n const unsubs = normalizedSpecs.flatMap((sp) => {\n const props = Array.isArray(sp.property) ? sp.property : [sp.property];\n return props.map((p) => store.connect({ reducer: sp.reducer, property: p }, tick));\n });\n return () => {\n for (const u of unsubs) u();\n };\n },\n [store, normalizedSpecs],\n );\n\n const getSnapshot = useCallback(() => {\n if (lastVerRef.current !== versionRef.current || !hasValueRef.current) {\n const next = selectorRef.current(store.getState());\n // Track presence with a boolean so an `undefined` selection still caches\n // (using `undefined` as \"no value yet\" would disable the equality cache).\n if (!hasValueRef.current || !isEqualRef.current(lastSelRef.current as T, next)) {\n lastSelRef.current = next;\n hasValueRef.current = true;\n }\n lastVerRef.current = versionRef.current;\n }\n return lastSelRef.current as T;\n }, [store]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n };\n\n const useAtomicProps = useAtomicPropsImpl as unknown as UseAtomicPropsOverloads;\n\n type UseEventOverloads = UseEvent<EM, S>;\n\n const useEvent: UseEventOverloads = <\n C extends keyof EM & string,\n T extends keyof EM[C] & string,\n >(\n channel: C,\n type: T,\n handler: (\n event: Event<EM, C, T>,\n getState: () => DeepReadonly<S>,\n emit: Emit<EM>,\n phase: \"committed\" | \"uncommitted\",\n ) => void | Promise<void>,\n phase: EventPhase = \"committed\",\n ): void => {\n const store = useStore();\n const handlerRef = useRef(handler);\n handlerRef.current = handler; // Always keep latest handler (solves stale closures)\n\n useEffect(() => {\n return store.onEvent(\n channel,\n type,\n (event, getState, emit, eventPhase) => {\n handlerRef.current(\n event as Event<EM, C, T>,\n getState as () => DeepReadonly<S>,\n emit,\n eventPhase,\n );\n },\n phase,\n );\n }, [store, channel, type, phase]);\n };\n\n // Bound to the context above, not the package-level one, so the returned set is complete:\n // a caller who has these hooks never has to also mount a `<StoreProvider>` to reach Suspense.\n const { useSuspenseAtomicProp, useSuspenseAtomicProps } = createSuspenseHooks<R, S, EM>(useStore);\n\n return {\n useStore,\n useEmit,\n useSelector,\n useAtomicProp,\n useAtomicProps,\n useEvent,\n useSuspenseAtomicProp,\n useSuspenseAtomicProps,\n shallowEqual,\n };\n}\n","/**\n * @module @yoltra/react\n */\n\nimport {\n createStore,\n type DeepReadonly,\n type EffectSpec,\n type EMFromReducersStrict,\n type EventMapBase,\n type EventUnion,\n type MiddlewareFunction,\n type ReducersMapAny,\n type StateFromReducers,\n type StoreInstance,\n} from \"@yoltra/core\";\nimport React, { createContext, type ReactNode } from \"react\";\n\nimport { createHooks, type YoltraHooks } from \"./hooks/createHooks\";\n\n/**\n * The value returned by {@link createYoltra}: the created `store`, an optional\n * `StoreProvider` (plus its raw `StoreContext`), and the full set of typed hooks\n * from {@link YoltraHooks}.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n * @typeParam EM - Event map.\n *\n * @public\n */\nexport interface Yoltra<R extends string, S extends Record<R, any>, EM extends EventMapBase>\n extends YoltraHooks<R, S, EM> {\n /** The store created by this call; the hooks default to it (no Provider needed). */\n store: StoreInstance<R, S, EM>;\n /** Raw context carrying the store — usually you only need `StoreProvider`. */\n StoreContext: React.Context<StoreInstance<R, S, EM> | null>;\n /** Optional provider to scope a different store instance to a subtree. */\n StoreProvider: React.FC<{ store?: StoreInstance<R, S, EM>; children: ReactNode }>;\n}\n\n/**\n * One-call setup: create a store and its fully-typed React hooks together.\n *\n * @remarks\n * Collapses the `createStore` + context + `createHooks` boilerplate into a\n * single call. The returned hooks default to the created store, so wrapping your\n * tree in a `<StoreProvider>` is **optional** — use it only to scope a different\n * store instance to a subtree (e.g. a fresh store per test).\n *\n * **Client-only convenience.** The store created here is a module-level\n * singleton, and the Suspense hooks share a module-global cache. Do not reuse a\n * `createYoltra(...)` module across SSR requests — state and cache would bleed\n * between them. For SSR, create a store per request and scope it with\n * `StoreProvider`.\n *\n * **The Suspense hooks are part of this set.** Take `useSuspenseAtomicProp` and\n * `useSuspenseAtomicProps` from here, not from the `@yoltra/react` barrel: the\n * barrel's copies read the *package-level* context, which this function never\n * fills, so they would throw `useStore must be used inside <StoreProvider>` at\n * runtime with nothing in the types to warn you — the two are identical in\n * shape. The ones returned here are bound to this store's own context and need\n * no provider, like the rest of the set.\n *\n * @example Suspense alongside createYoltra\n * ```tsx\n * export const { store, useAtomicProp, useSuspenseAtomicProp } = createYoltra({ ... });\n *\n * // No <StoreProvider> anywhere: every hook above already knows this store.\n * createRoot(el).render(<App />);\n * ```\n *\n * @typeParam RM - Reducers map; state shape and event map are inferred from it.\n * @param cfg - The same configuration accepted by {@link createStore}.\n * @returns The `store`, an optional `StoreProvider`, the raw `StoreContext`, and\n * the full set of typed hooks (`useAtomicProp`, `useAtomicProps`, `useEmit`,\n * `useEvent`, `useSelector`, `useStore`, `useSuspenseAtomicProp`,\n * `useSuspenseAtomicProps`, `shallowEqual`).\n *\n * @example\n * ```tsx\n * export const { store, useAtomicProp, useEmit } = createYoltra({\n * name: 'App',\n * reducer: {\n * counter: {\n * state: { value: 0 },\n * when: { keys: [['ui', 'increment']] },\n * reducer: (s, e) => (e.type === 'increment' ? { value: s.value + e.payload } : s),\n * },\n * },\n * });\n *\n * function Counter() {\n * const value = useAtomicProp({ reducer: 'counter', property: 'value' });\n * const emit = useEmit();\n * return <button onClick={() => emit('ui', 'increment', 1)}>{value}</button>;\n * }\n * ```\n *\n * @public\n */\nexport function createYoltra<RM extends ReducersMapAny>(cfg: {\n name: string;\n reducer: RM;\n middleware?: MiddlewareFunction<DeepReadonly<StateFromReducers<RM>>, EMFromReducersStrict<RM>>[];\n effects?: Array<EffectSpec<DeepReadonly<StateFromReducers<RM>>, EMFromReducersStrict<RM>>>;\n dedupWindowMs?: number;\n devtools?: { allowReplay?: boolean };\n onEffectError?: (error: unknown, event: EventUnion<EMFromReducersStrict<RM>>) => void;\n}): Yoltra<keyof RM & string, StateFromReducers<RM>, EMFromReducersStrict<RM>> {\n type S = StateFromReducers<RM>;\n type EM = EMFromReducersStrict<RM>;\n type R = keyof RM & string;\n\n const store: StoreInstance<R, S, EM> = createStore(cfg);\n\n // Default the context value to the store so components work WITHOUT a Provider.\n const StoreContext = createContext<StoreInstance<R, S, EM> | null>(store);\n\n const hooks = createHooks<R, S, EM>(StoreContext);\n\n /**\n * Optional provider — only needed to scope a different store instance to a\n * subtree; otherwise the hooks use the store created above.\n */\n const StoreProvider: React.FC<{ store?: StoreInstance<R, S, EM>; children: ReactNode }> = ({\n store: override,\n children,\n }) => <StoreContext.Provider value={override ?? store}>{children}</StoreContext.Provider>;\n\n return { store, StoreContext, StoreProvider, ...hooks };\n}\n","/**\n * Hooks for normalised collections, so a row subscribes to itself rather than to the list.\n *\n * @remarks\n * These are thin wrappers over {@link useAtomicProp}. Their whole value is that the path\n * comes from the adapter rather than being written by hand: `entities.abc.title` typed into a\n * component is a string nothing checks, and it is the kind of string that silently stops\n * matching when an id format changes.\n *\n * @module @yoltra/react\n */\n\nimport type { EntityAdapter, EntityId, EntityState } from \"@yoltra/core\";\n\nimport { useAtomicProp } from \"../hooks/hooks\";\n\n/**\n * Subscribes to a collection's order.\n *\n * @remarks\n * This is the subscription a list container wants, and the only one that should wake when the\n * collection is reordered. Rows use {@link useEntity} or {@link useEntityField} and stay\n * asleep through a sort.\n *\n * @public\n */\nexport function useEntityIds<T, Id extends EntityId, R extends string>(\n reducer: R,\n adapter: EntityAdapter<T, Id>,\n): readonly Id[] {\n return useAtomicProp<R, Record<R, EntityState<T, Id>>, R, never>({\n reducer,\n property: adapter.idsPath as never,\n }) as unknown as readonly Id[];\n}\n\n/**\n * Subscribes to one entity.\n *\n * @returns The entity, or `undefined` once it has been removed — a row that outlives its data\n * for one render is normal, and returning `undefined` is what lets it render nothing rather\n * than throw.\n *\n * @public\n */\nexport function useEntity<T, Id extends EntityId, R extends string>(\n reducer: R,\n adapter: EntityAdapter<T, Id>,\n id: Id,\n): T | undefined {\n return useAtomicProp<R, Record<R, EntityState<T, Id>>, R, never>({\n reducer,\n property: adapter.pathTo(id) as never,\n }) as unknown as T | undefined;\n}\n\n/**\n * Subscribes to one field of one entity.\n *\n * @remarks\n * The narrowest subscription available, and the reason the shape is worth adopting: editing a\n * title wakes the components reading that title and nothing else.\n *\n * @public\n */\nexport function useEntityField<T, Id extends EntityId, R extends string, K extends keyof T & string>(\n reducer: R,\n adapter: EntityAdapter<T, Id>,\n id: Id,\n field: K,\n): T[K] | undefined {\n return useAtomicProp<R, Record<R, EntityState<T, Id>>, R, never>({\n reducer,\n property: adapter.pathTo(id, field) as never,\n }) as unknown as T[K] | undefined;\n}\n"],"names":["require$$0","createContext","useRef","useMemo","useCallback","useEffect","useSyncExternalStore","useContext","createStore","StoreContext","jsxRuntime","reactJsxRuntime_production","REACT_ELEMENT_TYPE","REACT_FRAGMENT_TYPE","jsxProd","type","config","maybeKey","key","propName","getComponentNameFromType","REACT_CLIENT_REFERENCE","REACT_PROFILER_TYPE","REACT_STRICT_MODE_TYPE","REACT_SUSPENSE_TYPE","REACT_SUSPENSE_LIST_TYPE","REACT_ACTIVITY_TYPE","REACT_PORTAL_TYPE","REACT_CONTEXT_TYPE","REACT_CONSUMER_TYPE","REACT_FORWARD_REF_TYPE","innerType","REACT_MEMO_TYPE","REACT_LAZY_TYPE","testStringCoercion","value","checkKeyStringCoercion","JSCompiler_inline_result","JSCompiler_temp_const","JSCompiler_inline_result$jscomp$0","getTaskName","name","getOwner","dispatcher","ReactSharedInternals","UnknownOwner","hasValidKey","hasOwnProperty","getter","defineKeyPropWarningGetter","props","displayName","warnAboutAccessingKey","specialPropKeyWarningShown","elementRefGetterWithDeprecationWarning","componentName","didWarnAboutElementRef","ReactElement","self","source","owner","debugStack","debugTask","jsxDEVImpl","isStaticChildren","children","isArrayImpl","validateChildKeys","keys","k","didWarnAboutKeySpread","node","React","createTask","callStackForError","unknownOwnerDebugStack","unknownOwnerDebugTask","reactJsxRuntime_development","trackActualOwner","jsxRuntimeModule","require$$1","StoreProvider","store","jsx","warned","warnOnce","message","hasWildcard","p","normalizePath","splitPath","specsSignature","specs","enc","s","PATH_SEGMENTS","makePathProxy","segments","target","_target","prop","toDottedPath","accessor","leaf","recorded","path","getAtPath","obj","cur","seg","useStableSnapshot","read","isEqual","structuralDeps","readRef","isEqualRef","cache","next","shallowEqual","a","b","ka","kb","useStore","ctx","useEmit","useSelector","selector","subscribe","notify","getSnapshot","useAtomicPropImpl","spec","map","normalizedSpec","isGlob","slice","useAtomicProp","useEvent","channel","handler","phase","handlerRef","event","getState","emit","eventPhase","computeExpiry","staleTime","computeErrorExpiry","errorTtlMs","MAX_ENTRIES","SuspenseCache","__publicField","oldest","entry","load","now","promise","err","pathKey","stripStoreId","reducer","needle","part","suspenseCache","storeIds","nextStoreId","storeKey","id","buildKey","extraKey","useSuspenseAtomicPropImpl","useStoreHook","storeSpec","options","optionsRef","_a","val","opts","getServerSnapshot","useSuspenseAtomicPropsImpl","normalized","sp","parts","wrapped","unsubs","u","state","result","invalidateAtomicProp","property","invalidateAtomicPropsByReducer","clearSuspenseCache","createSuspenseHooks","createHooks","specOrReducer","mapOrAccessor","accessorForm","rawProperty","useAtomicProps","versionRef","lastSelRef","lastVerRef","hasValueRef","selectorRef","normalizedSpecs","tick","useSuspenseAtomicProp","useSuspenseAtomicProps","createYoltra","cfg","hooks","override","useEntityIds","adapter","useEntity","useEntityField","field"],"mappings":"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","x_google_ignoreList":[1,2,3]}
1
+ {"version":3,"file":"index.mjs","sources":["../src/context/StoreContext.ts","../../../common/temp/node_modules/.pnpm/react@19.1.1/node_modules/react/cjs/react-jsx-runtime.production.js","../../../common/temp/node_modules/.pnpm/react@19.1.1/node_modules/react/cjs/react-jsx-runtime.development.js","../../../common/temp/node_modules/.pnpm/react@19.1.1/node_modules/react/jsx-runtime.js","../src/context/StoreProvider.tsx","../src/utils/warnOnce.ts","../src/utils/path.ts","../src/utils/useStableSnapshot.ts","../src/utils/shallowEqual.ts","../src/hooks/hooks.ts","../src/hooks/suspense.ts","../src/hooks/createHooks.ts","../src/createYoltra.tsx","../src/entity/useEntity.ts"],"sourcesContent":["/**\n * @module @yoltra/react\n */\n\nimport { createContext } from \"react\";\nimport type { StoreInstance } from \"@yoltra/core\";\n\n/**\n * React Context carrying a {@link StoreInstance} for yoltra React bindings.\n *\n * @remarks\n * - The default value is `null`. Consumers should either:\n * 1) Be wrapped with {@link StoreProvider}, or\n * 2) Use a helper hook that throws a friendly error when the context is `null`.\n * - You can scope multiple independent stores by nesting multiple providers.\n *\n * @example Basic usage\n * ```tsx\n * import { useContext } from \"react\";\n * import { StoreContext } from \"@yoltra/react\";\n *\n * export function Counter() {\n * const store = useContext(StoreContext);\n * if (!store) throw new Error(\"StoreProvider is missing\");\n * const state = store.getState();\n * return <span>{state.counter.value}</span>;\n * }\n * ```\n *\n * @public\n */\nexport const StoreContext = createContext<StoreInstance<any, any, any> | null>(null);","/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","/**\n * @license React\n * react-jsx-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return (type.displayName || \"Context\") + \".Provider\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(\n type,\n key,\n self,\n source,\n owner,\n props,\n debugStack,\n debugTask\n ) {\n self = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== self ? self : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function jsxDEVImpl(\n type,\n config,\n maybeKey,\n isStaticChildren,\n source,\n self,\n debugStack,\n debugTask\n ) {\n var children = config.children;\n if (void 0 !== children)\n if (isStaticChildren)\n if (isArrayImpl(children)) {\n for (\n isStaticChildren = 0;\n isStaticChildren < children.length;\n isStaticChildren++\n )\n validateChildKeys(children[isStaticChildren]);\n Object.freeze && Object.freeze(children);\n } else\n console.error(\n \"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.\"\n );\n else validateChildKeys(children);\n if (hasOwnProperty.call(config, \"key\")) {\n children = getComponentNameFromType(type);\n var keys = Object.keys(config).filter(function (k) {\n return \"key\" !== k;\n });\n isStaticChildren =\n 0 < keys.length\n ? \"{key: someKey, \" + keys.join(\": ..., \") + \": ...}\"\n : \"{key: someKey}\";\n didWarnAboutKeySpread[children + isStaticChildren] ||\n ((keys =\n 0 < keys.length ? \"{\" + keys.join(\": ..., \") + \": ...}\" : \"{}\"),\n console.error(\n 'A props object containing a \"key\" prop is being spread into JSX:\\n let props = %s;\\n <%s {...props} />\\nReact keys must be passed directly to JSX without using spread:\\n let props = %s;\\n <%s key={someKey} {...props} />',\n isStaticChildren,\n children,\n keys,\n children\n ),\n (didWarnAboutKeySpread[children + isStaticChildren] = !0));\n }\n children = null;\n void 0 !== maybeKey &&\n (checkKeyStringCoercion(maybeKey), (children = \"\" + maybeKey));\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (children = \"\" + config.key));\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n children &&\n defineKeyPropWarningGetter(\n maybeKey,\n \"function\" === typeof type\n ? type.displayName || type.name || \"Unknown\"\n : type\n );\n return ReactElement(\n type,\n children,\n self,\n source,\n getOwner(),\n maybeKey,\n debugStack,\n debugTask\n );\n }\n function validateChildKeys(node) {\n \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_ELEMENT_TYPE &&\n node._store &&\n (node._store.validated = 1);\n }\n var React = require(\"react\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\");\n Symbol.for(\"react.provider\");\n var REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\"),\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n hasOwnProperty = Object.prototype.hasOwnProperty,\n isArrayImpl = Array.isArray,\n createTask = console.createTask\n ? console.createTask\n : function () {\n return null;\n };\n React = {\n react_stack_bottom_frame: function (callStackForError) {\n return callStackForError();\n }\n };\n var specialPropKeyWarningShown;\n var didWarnAboutElementRef = {};\n var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(\n React,\n UnknownOwner\n )();\n var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));\n var didWarnAboutKeySpread = {};\n exports.Fragment = REACT_FRAGMENT_TYPE;\n exports.jsx = function (type, config, maybeKey, source, self) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !1,\n source,\n self,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n exports.jsxs = function (type, config, maybeKey, source, self) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !0,\n source,\n self,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","/**\n * @module @yoltra/react\n */\n\nimport type { StoreInstance } from \"@yoltra/core\";\nimport React, { type ReactNode } from \"react\";\n\nimport { StoreContext } from \"./StoreContext\";\n\n/**\n * React provider that places a {@link StoreInstance} into {@link StoreContext}.\n *\n * @param props.store - The yoltra store instance to expose to descendant components.\n * @param props.children - React subtree that will consume the store.\n *\n * @remarks\n * - Wrap your app (or a subtree) to make the store available via `useContext(StoreContext)`\n * or any higher-level hooks you expose (e.g., `useAtomicProp`, `useEmit`).\n * - You may nest multiple `StoreProvider`s to scope different stores to different subtrees.\n * - In Next.js App Router, this component must be used in a **client** boundary.\n *\n * @example App wrapper with createHooks (recommended)\n * ```tsx\n * // store.ts\n * import { createStore, eventKeys } from '@yoltra/core';\n * import { createContext } from 'react';\n * import { createHooks, StoreProvider } from '@yoltra/react';\n *\n * type AppEM = { ui: { increment: number } };\n * type AppState = { counter: { value: number } };\n *\n * export const store = createStore<AppState, AppEM>({\n * name: 'App',\n * reducer: {\n * counter: {\n * state: { value: 0 },\n * when: { keys: eventKeys<AppEM>()([['ui', 'increment']]) },\n * reducer: (s, evt) => evt.type === 'increment'\n * ? { value: s.value + evt.payload }\n * : s,\n * },\n * },\n * });\n *\n * const AppStoreContext = createContext<typeof store | null>(null);\n * export const { useAtomicProp, useEmit } = createHooks(AppStoreContext);\n *\n * // App.tsx\n * export function App({ children }: { children: React.ReactNode }) {\n * return <StoreProvider store={store}>{children}</StoreProvider>;\n * }\n * ```\n *\n * @public\n */\nexport const StoreProvider: React.FC<{\n /** yoltra store instance placed into context. */\n store: StoreInstance<any, any, any>;\n /** Descendant subtree that can consume the store. */\n children: ReactNode;\n}> = ({ store, children }) => (\n <StoreContext.Provider value={store}>{children}</StoreContext.Provider>\n);\n","/**\n * @module @yoltra/react\n */\n\n/**\n * Set of warning keys already logged (to prevent spam).\n * @internal\n */\nconst warned = new Set<string>();\n\n/**\n * Logs a warning **once** per unique key (dev only).\n *\n * @param key - Unique identifier for this warning.\n * @param message - Warning message to log.\n *\n * @remarks\n * - In production, this is a no-op.\n * - Useful for deprecation warnings that shouldn't flood the console.\n *\n * @example\n * ```ts\n * warnOnce('my-feature', 'This feature is deprecated.');\n * warnOnce('my-feature', 'This feature is deprecated.'); // no-op (already warned)\n * ```\n *\n * @internal\n */\nexport function warnOnce(key: string, message: string): void {\n if (process.env.NODE_ENV === \"production\") return;\n if (warned.has(key)) return;\n\n warned.add(key);\n console.warn(message);\n}","import { warnOnce } from \"./warnOnce\";\n\n/** @internal */\nexport function hasWildcard(p: string): boolean {\n return p.includes(\"*\");\n}\n\n/** @internal */\nexport function normalizePath(p: string): string {\n return p.replace(/^\\./, \"\");\n}\n\n/** @internal */\nexport function splitPath(p: string): string[] {\n return normalizePath(p).split(\".\").filter(Boolean);\n}\n\n/**\n * Stable signature for a specs array, for use as a `useMemo` dependency instead\n * of `JSON.stringify` — deterministic and avoids serializing arbitrary values.\n *\n * Every segment is **length-prefixed** (`\"<len>:<value>\"`), so no delimiter\n * character in a reducer name or path can make two semantically different spec\n * arrays collide (the array length is encoded too, so `[\"a\"]` and `[\"a\", \"\"]`\n * differ).\n * @internal\n */\nexport function specsSignature(\n specs: ReadonlyArray<{ reducer: string; property: string | readonly string[] }>,\n): string {\n const enc = (s: string) => `${s.length}:${s}`;\n return specs\n .map((s) => {\n const props = Array.isArray(s.property)\n ? (s.property as readonly string[])\n : [s.property as string];\n return enc(s.reducer) + enc(String(props.length)) + props.map(enc).join(\"\");\n })\n .join(\"\");\n}\n\nconst PATH_SEGMENTS = Symbol(\"yoltra.pathSegments\");\n\nfunction makePathProxy(segments: string[]): unknown {\n // The target is a function so that *calling* the proxy hits the `apply` trap\n // (a plain-object target is simply not callable and throws an opaque\n // \"x is not a function\"). This lets us reject method calls inside an accessor\n // — e.g. `p => p.items.map(...)` — with a message that says what went wrong.\n const target = () => undefined;\n return new Proxy(target, {\n get(_target, prop) {\n if (prop === PATH_SEGMENTS) return segments;\n if (typeof prop === \"symbol\") return undefined;\n return makePathProxy([...segments, String(prop)]);\n },\n apply() {\n throw new Error(\n `[yoltra] A typed path accessor called a method (near \"${segments.join(\".\")}\"). ` +\n \"The accessor must be a plain member chain like `p => p.items[0].title` — it cannot \" +\n \"call functions such as `.map()` or `.toString()`. Compute derived values in the \" +\n \"component or a selector, or use the `{ reducer, property }` string form.\",\n );\n },\n });\n}\n\n/**\n * Converts a typed path accessor (e.g. `p => p.items[0].title`) into a dotted\n * path string (`\"items.0.title\"`) by recording property accesses on a proxy.\n *\n * The accessor **must be a pure member chain**. It cannot return a computed\n * value (`p => p.a.b ?? 0`, `p => 5`) or call a method (`p => p.items.map(...)`):\n * - a method call throws immediately (see the proxy's `apply` trap);\n * - anything that records no property access yields an empty path — which would\n * silently subscribe to the whole slice — so we `warnOnce` in dev.\n *\n * @internal\n */\nexport function toDottedPath(accessor: (p: any) => unknown): string {\n const leaf = accessor(makePathProxy([]));\n const recorded = leaf != null ? (leaf as any)[PATH_SEGMENTS] : undefined;\n const segments: string[] = Array.isArray(recorded) ? recorded : [];\n const path = segments.join(\".\");\n\n if (path === \"\") {\n warnOnce(\n \"yoltra.toDottedPath.empty\",\n \"[yoltra] A typed path accessor recorded no property access, so it subscribed to the \" +\n \"slice root. That fires only when the slice's whole value is replaced — which for a \" +\n \"slice holding an object means never, since its changes are reported at their leaves. \" +\n \"The accessor must be a plain member chain like `p => p.items[0].title` and cannot \" +\n \"return a computed value or a default. For a dynamic subscription, or for a slice whose \" +\n \"state is a single value, use the `{ reducer, property }` string form instead.\",\n );\n }\n\n return path;\n}\n\n/**\n * Reads a dotted path from an object; returns `undefined` when a segment is\n * missing. The caller may supply the expected value type via `T`.\n * @internal\n */\nexport function getAtPath<T = unknown>(obj: unknown, path: string): T {\n if (!path) return obj as T;\n\n let cur: any = obj;\n for (const seg of splitPath(path)) {\n if (cur == null) return undefined as T;\n cur = cur[seg];\n }\n\n return cur as T;\n}\n","/**\n * @module @yoltra/react\n */\n\nimport { useCallback, useMemo, useRef, type DependencyList } from \"react\";\n\n/**\n * Builds a **stable** `getSnapshot` for `useSyncExternalStore` that survives\n * inline `read`/`isEqual` functions — the `useSyncExternalStoreWithSelector`\n * pattern.\n *\n * The latest `read` and `isEqual` closures are kept in refs, so passing them\n * inline (the common case) does **not** rebuild the snapshot on every render and\n * discard its memoized value. The derived value is cached until `isEqual`\n * reports a change; presence is tracked with a separate boolean so a value of\n * `undefined` still hits the cache instead of recomputing forever. The cache is\n * reset only when `structuralDeps` change (e.g. the subscribed path/spec), which\n * is also when the returned function's identity changes.\n *\n * @typeParam T - Derived snapshot value type.\n * @param read - Reads the current derived value from the store.\n * @param isEqual - Equality comparator for the derived value.\n * @param structuralDeps - Deps identifying the subscription target; a change\n * resets the value cache and returns a new snapshot function.\n * @returns A `getSnapshot` function stable across renders that don't change\n * `structuralDeps`.\n *\n * @internal\n */\nexport function useStableSnapshot<T>(\n read: () => T,\n isEqual: (a: T, b: T) => boolean,\n structuralDeps: DependencyList,\n): () => T {\n const readRef = useRef(read);\n readRef.current = read;\n const isEqualRef = useRef(isEqual);\n isEqualRef.current = isEqual;\n\n // A fresh cache object whenever the subscription target changes.\n const cache = useMemo<{ has: boolean; value: T }>(\n () => ({ has: false, value: undefined as T }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n structuralDeps,\n );\n\n return useCallback(() => {\n const next = readRef.current();\n if (!cache.has || !isEqualRef.current(cache.value, next)) {\n cache.has = true;\n cache.value = next;\n }\n return cache.value;\n }, [cache]);\n}\n","/**\n * @module @yoltra/react\n */\n\n/**\n * Shallow object equality using `Object.is` per-key.\n *\n * Useful as the `isEqual` argument for `useAtomicProp` and `useAtomicProps`\n * when the derived value is a plain object. Also available from the object\n * returned by {@link createHooks} and {@link createYoltra}.\n *\n * @example\n * ```ts\n * shallowEqual({ a: 1 }, { a: 1 }); // true\n * shallowEqual({ a: 1 }, { a: 2 }); // false\n * ```\n *\n * @public\n */\nexport function shallowEqual<T extends Record<string, unknown>>(a: T, b: T): boolean {\n if (Object.is(a, b)) return true;\n if (!a || !b) return false;\n\n const ka = Object.keys(a),\n kb = Object.keys(b);\n if (ka.length !== kb.length) return false;\n\n for (const k of ka) {\n if (!Object.is(a[k], (b as Record<string, unknown>)[k])) return false;\n }\n\n return true;\n}\n","/**\n * @module @yoltra/react\n */\n\nimport type {\n DeepReadonly,\n Dotted,\n Emit,\n Event,\n EventMapBase,\n EventPhase,\n PathValue,\n StoreInstance,\n WithGlob,\n} from \"@yoltra/core\";\nimport { useCallback, useContext, useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport { StoreContext } from \"../context/StoreContext\";\nimport { guardProjection, projectDeclared } from \"../utils/declaredProjection\";\nimport { getAtPath, hasWildcard, normalizePath, specsSignature } from \"../utils/path\";\nimport { useStableSnapshot } from \"../utils/useStableSnapshot\";\n\n/**\n * Re-export of {@link PathValue} from `@yoltra/core`.\n *\n * Resolves the TypeScript type at a dotted path `P` within object type `T`.\n * See the core definition for full documentation.\n *\n * @public\n */\nexport type { PathValue };\n\n/**\n * Accepts either a single value or a readonly array of that value.\n * Useful for APIs that take one-or-many keys.\n *\n * @example\n * ```ts\n * function takeIds(ids: OneOrMany<string>) { /* ... *\\/ }\n * takeIds('a');\n * takeIds(['a','b'] as const);\n * ```\n *\n * @public\n */\nexport type OneOrMany<T> = T | readonly T[];\n\n/**\n * Returns the current {@link StoreInstance} from {@link StoreContext}.\n * Throws if used outside of a `<StoreProvider>`.\n *\n * @typeParam EM - Event map type.\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n *\n * @example\n * ```tsx\n * const store = useStore<MyEM, 'counter' | 'todos', AppState>();\n * const state = store.getState();\n * ```\n *\n * @public\n */\nexport function useStore<\n EM extends EventMapBase,\n R extends string,\n S extends Record<R, any>,\n>(): StoreInstance<R, S, EM> {\n const ctx = useContext(StoreContext);\n if (!ctx) throw new Error(\"useStore must be used inside <StoreProvider>\");\n\n return ctx as StoreInstance<R, S, EM>;\n}\n\n/**\n * Returns the store's `emit` function (stable reference).\n *\n * @typeParam EM - Event map type.\n *\n * @example\n * ```tsx\n * const emit = useEmit<MyEM>();\n * await emit('ui', 'toggle', true);\n * ```\n *\n * @public\n */\nexport function useEmit<EM extends EventMapBase>(): Emit<EM> {\n return useStore<EM, any, any>().emit;\n}\n\n// `shallowEqual` is single-sourced in `../utils/shallowEqual` and re-exported\n// here so both the public barrel (`@yoltra/react`) and the object returned by\n// `createHooks`/`createYoltra` reference the same symbol (avoids a TS2742\n// non-portable-type leak in `createYoltra`'s inferred return type).\nexport { shallowEqual } from \"../utils/shallowEqual\";\n\n/**\n * Selects a derived value from the store using an external-store subscription.\n * Re-renders when the selected value changes per `isEqual`.\n *\n * @typeParam S - State type returned by `getState()`.\n * @typeParam T - Selected value type.\n * @param selector - `(state) => value` derived from the current state.\n * @param isEqual - Optional equality comparator (defaults to `Object.is`).\n *\n * @example\n * ```tsx\n * const total = useSelector((s: AppState) => s.todos.items.length);\n * ```\n *\n * @public\n */\nexport function useSelector<S extends Record<any, any>, T>(\n selector: (state: DeepReadonly<S>) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n const store = useStore<any, any, S>();\n\n const subscribe = useMemo(() => (notify: () => void) => store.subscribe(notify), [store]);\n\n const getSnapshot = useStableSnapshot(\n () => selector(store.getState() as DeepReadonly<S>),\n isEqual,\n [store],\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/** @internal */\nfunction useAtomicPropImpl<R extends string, S extends Record<R, any>, T = any>(\n spec: { reducer: R; property: string },\n map?: (value: any) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n const store = useStore<any, R, S>();\n\n const normalizedSpec = useMemo(() => {\n const prop = normalizePath(spec.property);\n return { reducer: spec.reducer, property: prop } as const;\n }, [spec.reducer, spec.property]);\n\n const subscribe = useMemo(\n () => (notify: () => void) =>\n store.connect(\n { reducer: normalizedSpec.reducer, property: normalizedSpec.property },\n () => notify(),\n ),\n [store, normalizedSpec],\n );\n\n const isGlob = hasWildcard(normalizedSpec.property);\n const getSnapshot = useStableSnapshot(\n () => {\n const full = store.getState() as S;\n const slice = (full as any)[normalizedSpec.reducer];\n const source = isGlob ? slice : getAtPath(slice, normalizedSpec.property);\n return map ? map(source) : (source as unknown as T);\n },\n isEqual,\n [store, normalizedSpec],\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot) as any;\n}\n\n/**\n * Fine-grained **single-path** selector for a reducer's state.\n *\n * Re-renders only when the specified `reducer.property` (dotted path) actually changes.\n * For most applications, prefer using the typed version from {@link createHooks}\n * which infers all type parameters automatically.\n *\n * **Supports**\n * - Exact root prop: `{ reducer: \"todo\", property: \"data\" }`\n * - Exact deep path: `{ reducer: \"todo\", property: \"data.123.title\" }`\n * - Wildcards (pattern): `{ reducer: \"todo\", property: \"data.*\" }` or `\"data.**\"`\n *\n * **Overloads**\n * - Exact path (no `*`): returns the precise `PathValue` when `map` is omitted\n * - Exact path + `map`: returns `T` from `map(value)`\n * - Glob path (with `*`/`**`): requires `map` and returns `T` from `map(state)`\n *\n * @example Via createHooks (recommended)\n * ```tsx\n * const { useAtomicProp } = createHooks(AppStoreContext);\n *\n * function TodoTitle({ index }: { index: number }) {\n * // Types are inferred — no explicit generics needed\n * const title = useAtomicProp({\n * reducer: 'todos',\n * property: `items.${index}.title`,\n * });\n * return <span>{title}</span>;\n * }\n * ```\n *\n * @example Standalone with explicit generics\n * ```tsx\n * const title = useAtomicProp<'todos', AppState, 'todos', 'items.0.title'>(\n * { reducer: 'todos', property: 'items.0.title' }\n * );\n * ```\n *\n * @example Map over exact path\n * ```tsx\n * const len = useAtomicProp(\n * { reducer: 'todos', property: 'items' },\n * items => items.length\n * );\n * ```\n *\n * @example Glob pattern over state\n * ```tsx\n * const titles = useAtomicProp(\n * { reducer: 'todos', property: 'items.**' },\n * state => state.items.map(x => x.title),\n * shallowEqual\n * );\n * ```\n *\n * @public\n */\nexport function useAtomicProp<\n R extends string,\n S extends Record<R, any>,\n R1 extends R,\n P extends Dotted<S[R1]>,\n>(spec: { reducer: R1; property: P }): PathValue<S[R1], P>;\nexport function useAtomicProp<\n R extends string,\n S extends Record<R, any>,\n R1 extends R,\n P extends Dotted<S[R1]>,\n T,\n>(\n spec: { reducer: R1; property: P },\n map: (value: PathValue<S[R1], P>) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useAtomicProp<\n R extends string,\n S extends Record<R, any>,\n R1 extends R,\n P extends WithGlob<Dotted<S[R1]>>,\n T,\n>(\n spec: { reducer: R1; property: P },\n map: (value: any) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useAtomicProp<R extends string, S extends Record<R, any>>(spec: {\n reducer: R;\n property: string;\n}): unknown;\nexport function useAtomicProp<R extends string, S extends Record<R, any>, T>(\n spec: { reducer: R; property: string },\n map: (value: any) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useAtomicProp<R extends string, S extends Record<R, any>, T = any>(\n spec: { reducer: R; property: string },\n map?: (value: any) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n // One implementation regardless of whether `map` is passed, so toggling `map`\n // presence between renders never changes the hook call order (Rules of Hooks).\n return useAtomicPropImpl<R, S, T>(spec, map, isEqual);\n}\n\n/**\n * **Multi-path** fine-grained selector.\n *\n * Subscribes to several `reducer.property` paths (supports deep & wildcard)\n * and recomputes `selector(state)` when any of them change.\n *\n * @typeParam R - Slice name union.\n * @typeParam S - State record keyed by `R`.\n * @typeParam T - Derived value type.\n *\n * @param specs - Array of `{ reducer, property }`, where `property` can be a string or array of strings. Supports `*`/`**`.\n * @param selector - `(state) => T` function run against the full state.\n * @param isEqual - Equality comparator for the derived value (defaults to `Object.is`).\n *\n * @example\n * ```tsx\n * const total = useAtomicProps<'todos' | 'filter', AppState, number>(\n * [\n * { reducer: 'todos', property: 'items.**' },\n * { reducer: 'filter', property: 'q' }\n * ],\n * (s) => s.todos.items.filter(x => x.title.includes(s.filter.q)).length\n * );\n * ```\n *\n * @remarks\n * The selector receives **only the paths declared in `specs`**, not the whole store. Reading\n * anything else yields `undefined` in production and throws in development, naming the path.\n *\n * That is deliberate, and it replaced a real bug: the two arguments used to be independent, so\n * a component could subscribe to one path and read another. It compiled, it ran, and it worked\n * for as long as the two happened to change together — this repository shipped exactly that in\n * its own example, where a list subscribed to `todo.filter` while reading `todo.data` and\n * re-rendered only because adding a todo also rewrote `filter.categories`.\n *\n * Correct code is unaffected. Code that read more than it declared was already wrong, and now\n * says so on the first render rather than on the first day the coincidence breaks.\n *\n * @public\n */\nexport function useAtomicProps<R extends string, S extends Record<R, any>, T>(\n specs: Array<{ reducer: R; property: OneOrMany<WithGlob<Dotted<S[R]>>> }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useAtomicProps<R extends string, S extends Record<R, any>, T>(\n specs: Array<{ reducer: R; property: OneOrMany<string> }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useAtomicProps<R extends string, S extends Record<R, any>, T>(\n specs: Array<{\n reducer: R;\n property: OneOrMany<string> | OneOrMany<WithGlob<Dotted<S[R]>>>;\n }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n return useAtomicPropsImpl<R, S, T>(specs as any, selector, isEqual);\n}\n\n/** @internal */\nfunction useAtomicPropsImpl<R extends string, S extends Record<R, any>, T>(\n specs: Array<{\n reducer: R;\n property: OneOrMany<string> | OneOrMany<WithGlob<Dotted<S[R]>>>;\n }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n const store = useStore<EventMapBase, R, S>();\n\n const versionRef = useRef(0);\n const lastSelRef = useRef<T | undefined>(undefined);\n const lastVerRef = useRef<number>(-1);\n const hasValueRef = useRef(false);\n\n // Latest selector/isEqual via refs so passing them inline does not rebuild\n // getSnapshot (which would drop the memoized value) every render.\n const selectorRef = useRef(selector);\n selectorRef.current = selector;\n const isEqualRef = useRef(isEqual);\n isEqualRef.current = isEqual;\n\n const normalizedSpecs = useMemo(() => {\n return specs.map((sp) => ({\n reducer: sp.reducer,\n property: Array.isArray(sp.property)\n ? (sp.property as readonly string[]).map((p) => normalizePath(p as string))\n : normalizePath(sp.property as string),\n }));\n // `specsSignature` is a stable structural key for `specs`; keying the memo\n // on it (not the array, a fresh reference each render) is intentional and\n // already covers `specs`.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [specsSignature(specs)]);\n\n const subscribe = useMemo(\n () => (notify: () => void) => {\n const tick = () => {\n versionRef.current++;\n notify();\n };\n\n const unsubs = normalizedSpecs.flatMap((sp) => {\n const props = Array.isArray(sp.property) ? sp.property : [sp.property];\n return props.map((p) => store.connect({ reducer: sp.reducer, property: p }, tick));\n });\n\n return () => {\n for (const u of unsubs) u();\n };\n },\n [store, normalizedSpecs],\n );\n\n // Derived from the very specs that drive the subscriptions above, so what the selector can\n // see and what wakes the component come from one source and cannot drift apart.\n const declared = useMemo(\n () =>\n normalizedSpecs.flatMap((sp) =>\n (Array.isArray(sp.property) ? sp.property : [sp.property]).map((property) => ({\n reducer: sp.reducer as string,\n property,\n })),\n ),\n [normalizedSpecs],\n );\n\n const getSnapshot = useCallback(() => {\n if (lastVerRef.current !== versionRef.current || !hasValueRef.current) {\n const projection = projectDeclared(store.getState(), declared);\n const visible =\n process.env.NODE_ENV !== \"production\" ? guardProjection(projection, declared) : projection;\n const next = selectorRef.current(visible as DeepReadonly<S>);\n\n // Track presence with a boolean so an `undefined` selection still caches\n // (using `undefined` as \"no value yet\" would disable the equality cache).\n if (!hasValueRef.current || !isEqualRef.current(lastSelRef.current as T, next)) {\n lastSelRef.current = next;\n hasValueRef.current = true;\n }\n\n lastVerRef.current = versionRef.current;\n }\n\n return lastSelRef.current as T;\n }, [store, declared]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Subscribe to store events from a React component.\n *\n * This hook enables reactive UI patterns by allowing components to respond\n * to specific events without selecting state. Useful for:\n * - Showing notifications on certain events\n * - Triggering animations\n * - Logging/analytics\n * - Responding to rejected (uncommitted) events\n *\n * **Phases:**\n * - `'committed'` (default): Events that passed middleware and reached reducers\n * - `'uncommitted'`: Events rejected by middleware\n * - `'all'`: Both committed and uncommitted events (handler receives phase parameter)\n *\n * @typeParam EM - Event map type.\n * @typeParam C - Channel key within `EM`.\n * @typeParam T - Event type key within channel `C`.\n *\n * @param channel - Event channel to subscribe to.\n * @param type - Event type to subscribe to.\n * @param handler - Handler called when the event fires. Receives `(event, getState, emit, phase)`.\n * @param phase - Event phase to subscribe to (default: `'committed'`).\n *\n * @example Committed events (default)\n * ```tsx\n * useEvent('ui', 'save', (event, getState, emit, phase) => {\n * showToast('Saved successfully!');\n * });\n * ```\n *\n * @example Rejected events\n * ```tsx\n * useEvent('ui', 'delete', (event, getState, emit, phase) => {\n * showToast('Delete was blocked by middleware');\n * }, 'uncommitted');\n * ```\n *\n * @example All events\n * ```tsx\n * useEvent('ui', 'action', (event, getState, emit, phase) => {\n * console.log('Action:', phase); // 'committed' or 'uncommitted'\n * }, 'all');\n * ```\n *\n * @public\n */\nexport function useEvent<\n EM extends EventMapBase,\n C extends keyof EM & string,\n T extends keyof EM[C] & string,\n>(\n channel: C,\n type: T,\n handler: (\n event: Event<EM, C, T>,\n getState: () => DeepReadonly<any>,\n emit: Emit<EM>,\n phase: \"committed\" | \"uncommitted\",\n ) => void | Promise<void>,\n phase: EventPhase = \"committed\",\n): void {\n const store = useStore<EM, any, any>();\n const handlerRef = useRef(handler);\n handlerRef.current = handler; // Always keep latest handler (solves stale closures)\n\n useEffect(() => {\n return store.onEvent(\n channel,\n type,\n (event, getState, emit, eventPhase) => {\n handlerRef.current(event as Event<EM, C, T>, getState, emit, eventPhase);\n },\n phase,\n );\n }, [store, channel, type, phase]);\n}\n","/**\n * @module @yoltra/react\n */\n\nimport { useMemo, useRef, useSyncExternalStore } from \"react\";\nimport type { EventMapBase, StoreInstance, Dotted, WithGlob } from \"@yoltra/core\";\n\nimport { useStore } from \"./hooks\";\nimport { hasWildcard, normalizePath, getAtPath } from \"../utils/path\";\n\n/**\n * The `useStore` a Suspense hook reads through.\n *\n * @remarks\n * Passed in rather than imported so the same implementation can serve both the package-level\n * hooks and the ones {@link createSuspenseHooks} binds to a caller's own context.\n *\n * @internal\n */\ntype UseStoreHook<\n R extends string,\n S extends Record<R, any>,\n EM extends EventMapBase = EventMapBase,\n> = () => StoreInstance<R, S, EM>;\n\n/** @internal */\ntype CacheKey = string;\n\n/** @internal */\ntype CacheEntry<T> =\n | { status: \"ready\"; value: T; expiresAt: number | null }\n | { status: \"pending\"; promise: Promise<void>; expiresAt: number | null }\n | {\n status: \"error\";\n error: any;\n expiresAt: number | null;\n /**\n * Whether the error has been thrown to a boundary yet.\n *\n * @remarks\n * A failure must reach the boundary at least once, and time alone cannot express that.\n * The load rejects, the wrapper caches the error and *resolves*, React re-renders, and\n * only then does anybody read the entry. Expiring it by clock would drop it during that\n * gap, so the component would suspend again instead of surfacing the error — a silent\n * retry loop in place of a visible failure.\n */\n delivered?: boolean;\n };\n\n/**\n * Time-based expiry for a **settled** (`ready`) entry. A non-positive or `null`\n * `staleTime` means \"no time expiry\" — the entry is served until it is\n * invalidated (by a store change on the subscribed path, or an explicit\n * `invalidate`/`clear`). Only a positive `staleTime` adds a wall-clock bound.\n *\n * Critically, `staleTime: 0` (the default) must NOT map to `Date.now()` here:\n * an entry that expires on the same tick it was created would be re-loaded on\n * the very next render, throwing a fresh promise each time (infinite suspend).\n * @internal\n */\nfunction computeExpiry(staleTime: number | null): number | null {\n return staleTime == null || staleTime <= 0 ? null : Date.now() + staleTime;\n}\n\n/**\n * Expiry for a **failed** entry.\n *\n * @remarks\n * Cached errors used to be held until something invalidated them, which made a retry button\n * unable to retry: the boundary resets, the component renders, and the stored error is thrown\n * again without the loader ever running a second time. A network blip became permanent for\n * the life of the page.\n *\n * So an error is delivered and then discarded by default — the next read starts a fresh load.\n * A positive `errorTtlMs` puts a floor between attempts, and `null` restores the old behaviour\n * for a caller who genuinely wants a failure to stick until they clear it.\n *\n * Returns `0` rather than `Date.now()` for the default: an entry stamped with the current\n * millisecond would still be served for the rest of that millisecond, which is exactly the\n * window a re-render after a boundary reset falls into.\n *\n * @internal\n */\nfunction computeErrorExpiry(errorTtlMs: number | null | undefined): number | null {\n if (errorTtlMs === null) return null;\n if (errorTtlMs === undefined || errorTtlMs <= 0) return 0;\n return Date.now() + errorTtlMs;\n}\n\n/**\n * Upper bound on cached entries.\n *\n * @remarks\n * Keys are built from the reducer and the subscribed path, so a component reading a dynamic path\n * — `byId.${userId}.name` and its like — mints a new one per value it has ever seen. Unbounded,\n * that grows for the lifetime of the process, and because the cache is module-scoped it does so\n * across server requests too. A few thousand entries is far past any real working set while\n * still being a bound.\n *\n * @internal\n */\nconst MAX_ENTRIES = 2000;\n\n/** @internal */\nclass SuspenseCache {\n private store = new Map<CacheKey, CacheEntry<any>>();\n\n /**\n * Marks a key as most recently used, and evicts the coldest entries past the cap.\n *\n * @remarks\n * A `Map` iterates in insertion order, so deleting and re-inserting a key moves it to the end\n * and the first key is the least recently used. That is the whole LRU: no timestamps, no\n * second structure.\n *\n * @internal\n */\n private touch(key: CacheKey): void {\n if (this.store.has(key)) this.store.delete(key);\n }\n\n /** @internal */\n private evict(): void {\n while (this.store.size > MAX_ENTRIES) {\n const oldest = this.store.keys().next();\n if (oldest.done === true) return;\n // Never evict a load in flight: the promise is what a suspended component is waiting on,\n // and dropping it would leave that component suspended forever.\n const entry = this.store.get(oldest.value);\n if (entry?.status === \"pending\") {\n // Move it to the end and look at the next candidate instead.\n this.store.delete(oldest.value);\n this.store.set(oldest.value, entry);\n continue;\n }\n this.store.delete(oldest.value);\n }\n }\n\n /** Number of entries currently held. */\n get size(): number {\n return this.store.size;\n }\n\n read<T>(\n key: CacheKey,\n load: () => T | Promise<T>,\n staleTime: number | null,\n errorTtlMs: number | null | undefined,\n ): T {\n const now = Date.now();\n const entry = this.store.get(key);\n\n // A ready value is served until it time-expires (staleTime > 0) or is\n // invalidated. With staleTime 0/null it never time-expires (expiresAt null).\n if (entry && entry.status === \"ready\" && (entry.expiresAt == null || entry.expiresAt > now)) {\n // Re-inserting keeps this key young; without it the eviction order would reflect when a\n // value was first loaded rather than when it was last wanted.\n this.touch(key);\n this.store.set(key, entry);\n return entry.value as T;\n }\n // A load already in flight: always re-throw the SAME promise until it\n // settles. Pending entries are never time-expired — otherwise every render\n // during the load would spawn a fresh load (infinite suspend / request storm).\n if (entry && entry.status === \"pending\") {\n throw entry.promise;\n }\n // A cached error is re-thrown to the nearest error boundary while it is still held. Once\n // it expires — immediately, by default — it is dropped and the load below runs again, so\n // resetting the boundary genuinely retries instead of re-delivering the same failure.\n // Error caching is independent of staleTime, which governs successful values.\n if (entry && entry.status === \"error\") {\n // Always surface it once: the boundary has not seen it yet.\n if (entry.delivered !== true) {\n this.store.set(key, { ...entry, delivered: true });\n throw entry.error;\n }\n // Seen. Held only while a caller asked for it to be held; otherwise the read below\n // retries, which is what makes resetting a boundary retry rather than re-deliver.\n if (entry.expiresAt === null || entry.expiresAt > now) throw entry.error;\n this.store.delete(key);\n }\n\n const promise = Promise.resolve()\n .then(load)\n .then((value) => {\n this.store.set(key, { status: \"ready\", value, expiresAt: computeExpiry(staleTime) });\n })\n .catch((err) => {\n this.store.set(key, {\n status: \"error\",\n error: err,\n expiresAt: computeErrorExpiry(errorTtlMs),\n });\n });\n\n this.store.set(key, { status: \"pending\", promise, expiresAt: null });\n this.evict();\n throw promise;\n }\n\n invalidate(key: CacheKey) {\n this.store.delete(key);\n }\n\n /**\n * Drops the entry for one `reducer::path` in **every** store that has one.\n *\n * @remarks\n * Entry keys carry a store id, but {@link invalidateAtomicProp} names only a path — a caller\n * holding a path has no handle on the store instances that cached it. Matching on the part\n * after the id invalidates that path wherever it was loaded, which is what the un-scoped\n * public function has always meant.\n *\n * @internal\n */\n invalidatePathKey(pathKey: string) {\n for (const k of this.store.keys()) {\n if (stripStoreId(k) === pathKey) this.store.delete(k);\n }\n }\n\n /**\n * Drops every entry that reads from `reducer`, in any store.\n *\n * @remarks\n * A multi-path entry joins its parts with `||`, so the reducer can appear anywhere in the key\n * rather than only at the front — checking each part catches the composite entries that a\n * plain prefix match would leave stale.\n *\n * @internal\n */\n invalidateReducer(reducer: string) {\n const needle = `${reducer}::`;\n for (const k of this.store.keys()) {\n if (stripStoreId(k).split(\"||\").some((part) => part.startsWith(needle))) this.store.delete(k);\n }\n }\n\n clear() {\n this.store.clear();\n }\n}\n\n/**\n * Default Suspense cache instance shared by all `useSuspense*` hooks.\n *\n * Use {@link invalidateAtomicProp}, {@link invalidateAtomicPropsByReducer},\n * or {@link clearSuspenseCache} to manage the cache from outside hooks.\n *\n * @public\n */\nexport const suspenseCache = new SuspenseCache();\n\n/**\n * Stable per-store id, minted lazily.\n *\n * @remarks\n * Cache keys used to be `reducer::path`, which is not unique across stores: two stores with a\n * `fleet` reducer would share one entry, and whichever loaded first would serve the other. That\n * was reachable through `StoreProvider` scoping and is reachable now through\n * {@link createSuspenseHooks}, where a store's own Suspense hooks are the normal way to call\n * them. Prefixing the key with the store's identity keeps the entries apart.\n *\n * A `WeakMap` because the id must not keep a discarded store alive — a per-request store in SSR\n * is collected as soon as the request ends, and with it any reason to remember its id.\n *\n * @internal\n */\nconst storeIds = new WeakMap<object, string>();\n/** @internal */\nlet nextStoreId = 0;\n\n/** @internal */\nfunction storeKey(store: object): string {\n let id = storeIds.get(store);\n if (id === undefined) {\n id = `s${++nextStoreId}`;\n storeIds.set(store, id);\n }\n return id;\n}\n\n/**\n * The part of an entry key that names the data, with the store id removed.\n * Ids are `s<n>` and contain no `::`, so the first separator ends the id.\n * @internal\n */\nfunction stripStoreId(key: CacheKey): string {\n return key.slice(key.indexOf(\"::\") + 2);\n}\n\n/**\n * The path half of an entry key: `reducer::path[::extraKey]`.\n * Combine with {@link storeKey} to address an actual entry.\n * @internal\n */\nfunction buildKey(reducer: string, props: string[] | string, extraKey?: string): string {\n const p = Array.isArray(props) ? props.map(normalizePath).sort().join(\"|\") : normalizePath(props);\n return extraKey ? `${reducer}::${p}::${extraKey}` : `${reducer}::${p}`;\n}\n\n/**\n * Options for {@link useSuspenseAtomicProp}.\n *\n * @typeParam T - The resolved value type after loading.\n * @typeParam S - Store state record.\n *\n * @example\n * ```ts\n * const options: SuspenseAtomicPropOptions<User, AppState> = {\n * load: async (userId) => fetchUser(userId),\n * staleTime: 30_000, // cache for 30 seconds\n * key: 'user-detail',\n * };\n * ```\n *\n * @public\n */\nexport interface SuspenseAtomicPropOptions<T, S> {\n /** Async loader that receives the value at the path and the full slice. */\n load: (valueAtPath: any, slice: S[keyof S]) => Promise<T> | T;\n /**\n * Extra wall-clock TTL (ms) for a resolved value. `0` (the default) or omitted\n * means the cached value is served until the subscribed path changes or you\n * invalidate it explicitly; a positive value additionally expires it after that\n * many ms. Cached errors ignore this and are re-thrown until invalidated.\n */\n staleTime?: number;\n /**\n * How long a **failed** load is remembered, in milliseconds.\n *\n * @remarks\n * `0` or omitted — the default — delivers the error to the nearest boundary and then forgets\n * it, so resetting that boundary retries the load. Held errors made a retry button unable to\n * retry, which turned a transient failure into a permanent one.\n *\n * A positive value puts a floor between attempts, for a loader that fails fast and would\n * otherwise be re-attempted on every reset. `null` holds the failure until something calls\n * `invalidate`, which is the old behaviour and is now something you ask for.\n */\n errorTtlMs?: number | null;\n /** Optional extra key to differentiate cache entries for the same path. */\n key?: string;\n}\n\n/**\n * Suspense-compatible version of `useAtomicProp` that throws a promise while loading.\n *\n * Subscribes to a single dotted path and calls `options.load` to produce the\n * resolved value. While the promise is pending, React Suspense catches it and\n * renders the nearest `<Suspense>` fallback.\n *\n * @remarks\n * **Client-only loading.** During server rendering this hook does not suspend\n * (throwing a promise would crash `renderToString`): `getServerSnapshot` returns\n * the current value at the path **without** invoking `options.load`. Perform the\n * actual load on the client.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n * @typeParam P - Dotted path within `S[R]`.\n * @typeParam T - Resolved value type.\n *\n * @param storeSpec - `{ reducer, property }` identifying the path to subscribe to.\n * @param options - Loading options (see {@link SuspenseAtomicPropOptions}).\n * @returns The resolved value of type `T`.\n *\n * @throws A `Promise` while loading (caught by React Suspense).\n * @throws If called outside a `<StoreProvider>`.\n *\n * @example\n * ```tsx\n * function UserName({ userId }: { userId: string }) {\n * const name = useSuspenseAtomicProp(\n * { reducer: 'users', property: `byId.${userId}.name` },\n * { load: async (name) => name ?? (await fetchUser(userId)).name },\n * );\n * return <span>{name}</span>;\n * }\n *\n * // Wrap with Suspense\n * <Suspense fallback={<Spinner />}>\n * <UserName userId=\"123\" />\n * </Suspense>\n * ```\n *\n * @public\n */\nexport function useSuspenseAtomicProp<\n R extends string,\n S extends Record<R, any>,\n P extends Dotted<S[R]>,\n T,\n>(storeSpec: { reducer: R; property: P }, options: SuspenseAtomicPropOptions<T, S>): T;\nexport function useSuspenseAtomicProp<R extends string, S extends Record<R, any>, T>(\n storeSpec: { reducer: R; property: string },\n options: SuspenseAtomicPropOptions<T, S>,\n): T;\nexport function useSuspenseAtomicProp<R extends string, S extends Record<R, any>, T>(\n storeSpec: { reducer: R; property: string },\n options: SuspenseAtomicPropOptions<T, S>,\n): T {\n return useSuspenseAtomicPropImpl<R, S, any, T>(\n useStore as UseStoreHook<R, S>,\n storeSpec as any,\n options,\n );\n}\n\n/** @internal */\nfunction useSuspenseAtomicPropImpl<\n R extends string,\n S extends Record<R, any>,\n P extends Dotted<S[R]>,\n T,\n EM extends EventMapBase = EventMapBase,\n>(\n useStoreHook: UseStoreHook<R, S, EM>,\n storeSpec: { reducer: R; property: P },\n options: SuspenseAtomicPropOptions<T, S>,\n): T {\n const store = useStoreHook();\n const reducer = storeSpec.reducer;\n const path = normalizePath(storeSpec.property as string);\n const key = `${storeKey(store)}::${buildKey(reducer, path, options.key)}`;\n\n const subscribe = useMemo(() => {\n return (notify: () => void) =>\n store.connect({ reducer, property: path }, () => {\n suspenseCache.invalidate(key);\n notify();\n });\n }, [store, reducer, path, key]);\n\n // Keep the latest options in a ref so an inline `options` object doesn't\n // rebuild getSnapshot every render (RX-5).\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const getSnapshot = useMemo(() => {\n const isGlob = hasWildcard(path);\n return () => {\n const state = store.getState() as S;\n const slice = state[reducer];\n const val = isGlob ? slice : getAtPath(slice, path);\n const opts = optionsRef.current;\n return suspenseCache.read<T>(key, () => opts.load(val, slice), opts.staleTime ?? 0, opts.errorTtlMs);\n };\n }, [store, reducer, path, key]);\n\n // Server render must NOT suspend — throwing a promise from getServerSnapshot\n // crashes renderToString. Return the current value at the path without loading\n // (client-only Suspense loading; see the hook's SSR note).\n const getServerSnapshot = useMemo(() => {\n const isGlob = hasWildcard(path);\n return () => {\n const state = store.getState() as S;\n const slice = state[reducer];\n return (isGlob ? slice : getAtPath(slice, path)) as T;\n };\n }, [store, reducer, path]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\n/**\n * Options for {@link useSuspenseAtomicProps}.\n *\n * @typeParam T - The resolved value type after loading.\n * @typeParam S - Store state record.\n *\n * @public\n */\nexport interface SuspenseAtomicPropsOptions<T, S> {\n /** Async loader that receives the full store state. */\n load: (state: S) => Promise<T> | T;\n /**\n * Extra wall-clock TTL (ms) for a resolved value. `0` (the default) or omitted\n * means the cached value is served until the subscribed path changes or you\n * invalidate it explicitly; a positive value additionally expires it after that\n * many ms. Cached errors ignore this and are re-thrown until invalidated.\n */\n staleTime?: number;\n /**\n * How long a **failed** load is remembered, in milliseconds.\n *\n * @remarks\n * `0` or omitted — the default — delivers the error to the nearest boundary and then forgets\n * it, so resetting that boundary retries the load. Held errors made a retry button unable to\n * retry, which turned a transient failure into a permanent one.\n *\n * A positive value puts a floor between attempts, for a loader that fails fast and would\n * otherwise be re-attempted on every reset. `null` holds the failure until something calls\n * `invalidate`, which is the old behaviour and is now something you ask for.\n */\n errorTtlMs?: number | null;\n /** Optional extra key to differentiate cache entries. */\n key?: string;\n}\n\n/**\n * Suspense-compatible version of `useAtomicProps` that throws a promise while loading.\n *\n * Subscribes to multiple dotted paths and calls `options.load` with the full state\n * to produce the resolved value. While the promise is pending, React Suspense\n * renders the nearest `<Suspense>` fallback.\n *\n * @remarks\n * **Client-only loading.** During server rendering this hook does not suspend\n * (throwing a promise would crash `renderToString`): `getServerSnapshot` uses a\n * synchronous `options.load` result if one is available, otherwise `undefined`.\n * Perform the actual load on the client.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n * @typeParam T - Resolved value type.\n *\n * @param specs - Array of `{ reducer, property }` paths to subscribe to.\n * @param options - Loading options (see {@link SuspenseAtomicPropsOptions}).\n * @returns The resolved value of type `T`.\n *\n * @throws A `Promise` while loading (caught by React Suspense).\n * @throws If called outside a `<StoreProvider>`.\n *\n * @example\n * ```tsx\n * function Dashboard() {\n * const stats = useSuspenseAtomicProps(\n * [\n * { reducer: 'orders', property: 'items.**' },\n * { reducer: 'users', property: 'active' },\n * ],\n * { load: async (state) => computeDashboardStats(state) },\n * );\n * return <StatsGrid data={stats} />;\n * }\n * ```\n *\n * @public\n */\nexport function useSuspenseAtomicProps<R extends string, S extends Record<R, any>, T>(\n specs: Array<{\n reducer: R;\n property: Dotted<S[R]> | WithGlob<Dotted<S[R]>> | ReadonlyArray<WithGlob<Dotted<S[R]>>>;\n }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n): T;\nexport function useSuspenseAtomicProps<R extends string, S extends Record<R, any>, T>(\n specs: Array<{ reducer: R; property: string | readonly string[] }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n): T;\nexport function useSuspenseAtomicProps<R extends string, S extends Record<R, any>, T>(\n specs: Array<{\n reducer: R;\n property:\n | string\n | readonly string[]\n | Dotted<S[R]>\n | WithGlob<Dotted<S[R]>>\n | ReadonlyArray<WithGlob<Dotted<S[R]>>>;\n }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n): T {\n return useSuspenseAtomicPropsImpl<R, S, T>(useStore as UseStoreHook<R, S>, specs as any, options);\n}\n\n/** @internal */\nfunction useSuspenseAtomicPropsImpl<\n R extends string,\n S extends Record<R, any>,\n T,\n EM extends EventMapBase = EventMapBase,\n>(\n useStoreHook: UseStoreHook<R, S, EM>,\n specs: Array<{\n reducer: R;\n property:\n | string\n | readonly string[]\n | Dotted<S[R]>\n | WithGlob<Dotted<S[R]>>\n | ReadonlyArray<WithGlob<Dotted<S[R]>>>;\n }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n): T {\n const store = useStoreHook();\n\n const normalized = useMemo(\n () =>\n specs.map((sp) => ({\n reducer: sp.reducer,\n property: Array.isArray(sp.property)\n ? (sp.property as readonly string[]).map((p) => normalizePath(p as string))\n : normalizePath(sp.property as string),\n })),\n // `specs` is a fresh reference each render; keying the memo on its JSON\n // signature is intentional and already covers `specs`.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [JSON.stringify(specs)],\n );\n\n const key = useMemo(() => {\n const parts = normalized\n .map((sp) => buildKey(sp.reducer, sp.property))\n .sort()\n .join(\"||\");\n return `${storeKey(store)}::${options.key ? `${parts}::${options.key}` : parts}`;\n }, [store, normalized, options.key]);\n\n const subscribe = useMemo(() => {\n return (notify: () => void) => {\n const wrapped = () => {\n suspenseCache.invalidate(key);\n notify();\n };\n const unsubs = normalized.map((sp) => store.connect(sp as any, wrapped));\n return () => {\n for (const u of unsubs) u();\n };\n };\n }, [store, normalized, key]);\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const getSnapshot = useMemo(() => {\n return () => {\n const state = store.getState() as S;\n const opts = optionsRef.current;\n return suspenseCache.read<T>(key, () => opts.load(state), opts.staleTime ?? 0, opts.errorTtlMs);\n };\n }, [store, key]);\n\n // Server render must NOT suspend. Use a synchronous load result if one is\n // available; otherwise render `undefined` rather than throwing a promise.\n const getServerSnapshot = () => {\n const result = optionsRef.current.load(store.getState() as S);\n return (result instanceof Promise ? undefined : result) as T;\n };\n\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\n/**\n * Invalidates the Suspense cache entry for a specific `reducer.property` path.\n *\n * @param reducer - Reducer (slice) name.\n * @param property - Dotted property path.\n * @param extraKey - Optional extra key if the hook was created with `options.key`.\n *\n * @example\n * ```ts\n * invalidateAtomicProp('users', 'byId.123.name');\n * ```\n *\n * @public\n */\nexport function invalidateAtomicProp(reducer: string, property: string, extraKey?: string) {\n suspenseCache.invalidatePathKey(buildKey(reducer, property, extraKey));\n}\n\n/**\n * Invalidates all Suspense cache entries for a given reducer (slice).\n *\n * @param reducer - Reducer (slice) name whose cache entries should be cleared.\n *\n * @example\n * ```ts\n * invalidateAtomicPropsByReducer('users');\n * ```\n *\n * @public\n */\nexport function invalidateAtomicPropsByReducer(reducer: string) {\n suspenseCache.invalidateReducer(reducer);\n}\n\n/**\n * Clears the entire Suspense cache, forcing all `useSuspense*` hooks to re-load.\n *\n * @example\n * ```ts\n * // After a logout, clear all cached data\n * clearSuspenseCache();\n * ```\n *\n * @public\n */\nexport function clearSuspenseCache() {\n suspenseCache.clear();\n}\n\n/**\n * Call signature for the typed `useSuspenseAtomicProp` returned by `createHooks`.\n *\n * Identical in behaviour to the package-level {@link useSuspenseAtomicProp}; the reducer union\n * and state shape are fixed by the store the hooks were created for, so neither has to be\n * supplied at the call site.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n *\n * @public\n */\nexport type UseSuspenseAtomicProp<R extends string, S extends Record<R, any>> = {\n <R1 extends R, P extends Dotted<S[R1]>, T>(\n storeSpec: { reducer: R1; property: P },\n options: SuspenseAtomicPropOptions<T, S>,\n ): T;\n <R1 extends R, T>(\n storeSpec: { reducer: R1; property: string },\n options: SuspenseAtomicPropOptions<T, S>,\n ): T;\n};\n\n/**\n * Call signature for the typed `useSuspenseAtomicProps` returned by `createHooks`.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n *\n * @public\n */\nexport type UseSuspenseAtomicProps<R extends string, S extends Record<R, any>> = {\n <R1 extends R, T>(\n specs: Array<{\n reducer: R1;\n property: WithGlob<Dotted<S[R1]>> | ReadonlyArray<WithGlob<Dotted<S[R1]>>>;\n }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n ): T;\n <R1 extends R, T>(\n specs: Array<{ reducer: R1; property: string | readonly string[] }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n ): T;\n};\n\n/**\n * Builds the Suspense hooks against a caller-supplied `useStore`.\n *\n * @remarks\n * The package-level `useSuspenseAtomicProp`/`useSuspenseAtomicProps` read the package-level\n * `StoreContext`. `createHooks` is given a *different* context, so its hook set used to stop\n * short of Suspense: mixing the two families threw \"useStore must be used inside\n * <StoreProvider>\" at runtime, with nothing in the types to warn about it, because the store\n * was in the other context all along. Building them here from the same `useStore` the rest of\n * the set uses makes the set complete.\n *\n * @internal\n */\nexport function createSuspenseHooks<\n R extends string,\n S extends Record<R, any>,\n EM extends EventMapBase = EventMapBase,\n>(\n useStoreHook: UseStoreHook<R, S, EM>,\n): {\n useSuspenseAtomicProp: UseSuspenseAtomicProp<R, S>;\n useSuspenseAtomicProps: UseSuspenseAtomicProps<R, S>;\n} {\n const useSuspenseAtomicPropBound = <T,>(\n storeSpec: { reducer: R; property: string },\n options: SuspenseAtomicPropOptions<T, S>,\n ): T => useSuspenseAtomicPropImpl<R, S, any, T, EM>(useStoreHook, storeSpec as any, options);\n\n const useSuspenseAtomicPropsBound = <T,>(\n specs: Array<{ reducer: R; property: string | readonly string[] }>,\n options: SuspenseAtomicPropsOptions<T, S>,\n ): T => useSuspenseAtomicPropsImpl<R, S, T, EM>(useStoreHook, specs as any, options);\n\n return {\n useSuspenseAtomicProp: useSuspenseAtomicPropBound as UseSuspenseAtomicProp<R, S>,\n useSuspenseAtomicProps: useSuspenseAtomicPropsBound as UseSuspenseAtomicProps<R, S>,\n };\n}","/**\n * @module @yoltra/react\n */\n\nimport type {\n DeepReadonly,\n Dotted,\n Emit,\n Event,\n EventMapBase,\n EventPhase,\n PathValue,\n StoreInstance,\n WithGlob,\n} from \"@yoltra/core\";\nimport * as React from \"react\";\nimport { useCallback, useContext, useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport { getAtPath, hasWildcard, normalizePath, specsSignature, toDottedPath } from \"../utils/path\";\nimport { shallowEqual } from \"../utils/shallowEqual\";\nimport { useStableSnapshot } from \"../utils/useStableSnapshot\";\nimport {\n createSuspenseHooks,\n type UseSuspenseAtomicProp,\n type UseSuspenseAtomicProps,\n} from \"./suspense\";\n\n/**\n * Call signature for the typed `useAtomicProp` hook returned by {@link createHooks}.\n *\n * Subscribes to a specific dotted path in a reducer's state and re-renders\n * only when that path changes. All type parameters are inferred automatically\n * from the store context — no explicit generics needed.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n *\n * @example\n * ```tsx\n * const { useAtomicProp } = createHooks(AppStoreContext);\n *\n * function TodoTitle({ index }: { index: number }) {\n * const title = useAtomicProp({\n * reducer: 'todos',\n * property: `items.${index}.title`,\n * });\n * return <span>{title}</span>;\n * }\n * ```\n *\n * @public\n */\nexport type UseAtomicProp<R extends string, S extends Record<R, any>> = {\n // Typed accessor form: `p => p.a.b.c` gives full autocomplete + inferred return type.\n <R1 extends R, V>(\n reducer: R1,\n accessor: (state: DeepReadonly<S[R1]>) => V,\n isEqual?: (a: V, b: V) => boolean,\n ): V;\n <R1 extends R, P extends Dotted<S[R1]>>(spec: {\n reducer: R1;\n property: P;\n }): PathValue<S[R1], P>;\n <R1 extends R, P extends Dotted<S[R1]>, T>(\n spec: { reducer: R1; property: P },\n map: (value: PathValue<S[R1], P>) => T,\n isEqual?: (a: T, b: T) => boolean,\n ): T;\n <R1 extends R, P extends WithGlob<Dotted<S[R1]>>, T>(\n spec: { reducer: R1; property: P },\n map: (value: unknown) => T,\n isEqual?: (a: T, b: T) => boolean,\n ): T;\n <R1 extends R>(spec: { reducer: R1; property: string }): unknown;\n <R1 extends R, T>(\n spec: { reducer: R1; property: string },\n map: (value: unknown) => T,\n isEqual?: (a: T, b: T) => boolean,\n ): T;\n};\n\n/**\n * Call signature for the typed `useAtomicProps` hook returned by {@link createHooks}.\n *\n * Subscribes to multiple dotted paths across one or more reducers and recomputes\n * a derived value when any of them change.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n *\n * @example\n * ```tsx\n * const { useAtomicProps } = createHooks(AppStoreContext);\n *\n * function FilteredCount() {\n * const count = useAtomicProps(\n * [\n * { reducer: 'todos', property: 'items.**' },\n * { reducer: 'filter', property: 'q' },\n * ],\n * (s) => s.todos.items.filter(x => x.title.includes(s.filter.q)).length,\n * );\n * return <span>{count}</span>;\n * }\n * ```\n *\n * @public\n */\nexport type UseAtomicProps<R extends string, S extends Record<R, any>> = {\n <R1 extends R, T>(\n specs: Array<{\n reducer: R1;\n property: WithGlob<Dotted<S[R1]>> | readonly WithGlob<Dotted<S[R1]>>[];\n }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual?: (a: T, b: T) => boolean,\n ): T;\n <R1 extends R, T>(\n specs: Array<{ reducer: R1; property: string | readonly string[] }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual?: (a: T, b: T) => boolean,\n ): T;\n};\n\n/**\n * Call signature for the typed `useEvent` hook returned by {@link createHooks}.\n *\n * Subscribes to store events from a React component. Useful for notifications,\n * animations, analytics, and responding to rejected (uncommitted) events.\n *\n * @typeParam EM - Event map type.\n * @typeParam S - Store state type.\n *\n * @example\n * ```tsx\n * const { useEvent } = createHooks(AppStoreContext);\n *\n * function SaveNotifier() {\n * useEvent('ui', 'save', (event) => {\n * showToast('Saved!');\n * });\n * return null;\n * }\n * ```\n *\n * @public\n */\nexport type UseEvent<EM extends EventMapBase, S> = <\n C extends keyof EM & string,\n T extends keyof EM[C] & string,\n>(\n channel: C,\n type: T,\n handler: (\n event: Event<EM, C, T>,\n getState: () => DeepReadonly<S>,\n emit: Emit<EM>,\n phase: \"committed\" | \"uncommitted\",\n ) => void | Promise<void>,\n phase?: EventPhase,\n) => void;\n\n/**\n * The bundle of fully-typed hooks returned by {@link createHooks} (and, with the\n * store and provider added, by {@link createYoltra}).\n *\n * Naming this return shape explicitly — rather than letting it be inferred —\n * keeps `createYoltra`'s emitted `.d.ts` portable: the inferred form would leak\n * a reference to a non-re-exported internal symbol and trip TS2742 in\n * `composite`/`declaration` consumers.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n * @typeParam EM - Event map.\n *\n * @public\n */\nexport interface YoltraHooks<\n R extends string,\n S extends Record<R, any>,\n EM extends EventMapBase,\n> {\n /** Reads the current store from context (falling back to the default store). */\n useStore: () => StoreInstance<R, S, EM>;\n /** Returns the store's typed `emit`. */\n useEmit: () => Emit<EM>;\n /** Subscribes to a derived value with an optional equality comparator. */\n useSelector: <T>(selector: (state: DeepReadonly<S>) => T, isEqual?: (a: T, b: T) => boolean) => T;\n /** Subscribes to a single dotted path (or typed accessor). */\n useAtomicProp: UseAtomicProp<R, S>;\n /** Subscribes to several paths and derives a value from the full state. */\n useAtomicProps: UseAtomicProps<R, S>;\n /** Runs a handler for a specific `(channel, type)` event. */\n useEvent: UseEvent<EM, S>;\n /** Suspense-loading variant of `useAtomicProp`, bound to the same context. */\n useSuspenseAtomicProp: UseSuspenseAtomicProp<R, S>;\n /** Suspense-loading variant of `useAtomicProps`, bound to the same context. */\n useSuspenseAtomicProps: UseSuspenseAtomicProps<R, S>;\n /** Shallow object equality using `Object.is` per-key. */\n shallowEqual: <T extends Record<string, unknown>>(a: T, b: T) => boolean;\n}\n\n/**\n * Factory that creates fully-typed React hooks bound to a specific store context.\n *\n * This is the **recommended** setup pattern for yoltra + React. It eliminates\n * the need for explicit type parameters on every hook call — all types are\n * inferred from the store context once, at creation time.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n * @typeParam EM - Event map.\n *\n * @param StoreContext - A React context carrying a `StoreInstance<R, S, EM>`.\n * @returns An object with typed hooks: `useStore`, `useEmit`, `useSelector`,\n * `useAtomicProp`, `useAtomicProps`, `useEvent`, `useSuspenseAtomicProp`,\n * `useSuspenseAtomicProps`, and `shallowEqual`.\n *\n * @throws If any returned hook is called outside a `<StoreProvider>`.\n *\n * @example Complete setup\n * ```tsx\n * // 1. Define your event map and state\n * type AppEM = { ui: { increment: number; decrement: number } };\n * type AppState = { counter: { value: number } };\n *\n * // 2. Create a typed context\n * import { createContext } from 'react';\n * import { StoreInstance } from '@yoltra/core';\n * const AppStoreContext = createContext<\n * StoreInstance<'counter', AppState, AppEM> | null\n * >(null);\n *\n * // 3. Create typed hooks (do this once, export from a shared module)\n * const { useAtomicProp, useEmit, useEvent } = createHooks(AppStoreContext);\n *\n * // 4. Use in components — no explicit generics needed\n * function Counter() {\n * const value = useAtomicProp({ reducer: 'counter', property: 'value' });\n * const emit = useEmit();\n * return (\n * <button onClick={() => emit('ui', 'increment', 1)}>\n * Count: {value}\n * </button>\n * );\n * }\n * ```\n *\n * @public\n */\nexport function createHooks<\n R extends string,\n S extends Record<R, any>,\n EM extends EventMapBase,\n>(StoreContext: React.Context<StoreInstance<R, S, EM> | null>): YoltraHooks<R, S, EM> {\n function useStore(): StoreInstance<R, S, EM> {\n const ctx = useContext(StoreContext);\n if (!ctx) {\n // These hooks come from createHooks(context)/createYoltra. createYoltra\n // defaults the context to its own store, so this only fires when the\n // context was created with a `null` default and no StoreProvider supplied\n // a store above this component.\n throw new Error(\n \"[yoltra] No store in context. Wrap your tree in <StoreProvider store={...}>, \" +\n \"or use the hooks returned by createYoltra (which default to their own store).\",\n );\n }\n return ctx;\n }\n\n function useEmit(): Emit<EM> {\n return useStore().emit;\n }\n\n function useSelector<T>(\n selector: (state: DeepReadonly<S>) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n ): T {\n const store = useStore();\n const subscribe = useMemo(() => (notify: () => void) => store.subscribe(notify), [store]);\n const getSnapshot = useStableSnapshot(() => selector(store.getState()), isEqual, [store]);\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n }\n\n type UseAtomicPropOverloads = UseAtomicProp<R, S>;\n\n const useAtomicPropImpl = (\n specOrReducer: { reducer: R; property: string } | R,\n mapOrAccessor?: (value: any) => unknown,\n isEqual?: (a: unknown, b: unknown) => boolean,\n ): unknown => {\n const store = useStore();\n\n // Two calling conventions, normalized to { reducer, property } + optional map:\n // - useAtomicProp({ reducer, property }, map?, isEqual?) (dotted-path string)\n // - useAtomicProp(reducer, p => p.a.b, isEqual?) (typed accessor)\n const accessorForm = typeof specOrReducer === \"string\";\n const reducer = (accessorForm ? specOrReducer : specOrReducer.reducer) as R;\n const rawProperty = accessorForm\n ? toDottedPath(mapOrAccessor as (p: any) => any)\n : specOrReducer.property;\n const map = accessorForm ? undefined : mapOrAccessor;\n\n const normalizedSpec = useMemo(() => {\n return { reducer, property: normalizePath(rawProperty) } as const;\n }, [reducer, rawProperty]);\n\n const subscribe = useMemo(\n () => (notify: () => void) =>\n store.connect(\n { reducer: normalizedSpec.reducer, property: normalizedSpec.property },\n () => notify(),\n ),\n [store, normalizedSpec],\n );\n\n const isGlob = hasWildcard(normalizedSpec.property);\n const getSnapshot = useStableSnapshot(\n () => {\n const full = store.getState() as DeepReadonly<S>;\n const slice = (full as any)[normalizedSpec.reducer];\n const source = isGlob ? slice : getAtPath(slice, normalizedSpec.property);\n return map ? map(source) : source;\n },\n isEqual ?? Object.is,\n [store, normalizedSpec],\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n };\n\n const useAtomicProp = useAtomicPropImpl as unknown as UseAtomicPropOverloads;\n\n type OneOrMany<T> = T | readonly T[];\n type UseAtomicPropsOverloads = UseAtomicProps<R, S>;\n\n const useAtomicPropsImpl = <T>(\n specs: Array<{ reducer: R; property: OneOrMany<string> }>,\n selector: (state: DeepReadonly<S>) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n ): T => {\n const store = useStore();\n const versionRef = useRef(0);\n const lastSelRef = useRef<T | undefined>(undefined);\n const lastVerRef = useRef<number>(-1);\n const hasValueRef = useRef(false);\n\n // Keep the latest selector/isEqual in refs so passing them inline does not\n // rebuild getSnapshot (which would drop the memoized value) every render.\n const selectorRef = useRef(selector);\n selectorRef.current = selector;\n const isEqualRef = useRef(isEqual);\n isEqualRef.current = isEqual;\n\n const normalizedSpecs = useMemo(() => {\n return specs.map((sp) => ({\n reducer: sp.reducer,\n property: Array.isArray(sp.property)\n ? (sp.property as readonly string[]).map((p) => normalizePath(p))\n : normalizePath(sp.property as string),\n }));\n // `specsSignature` is a stable structural key for `specs`; keying the memo\n // on it (not the array, a fresh reference each render) is intentional and\n // already covers `specs`.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [specsSignature(specs)]);\n\n const subscribe = useMemo(\n () => (notify: () => void) => {\n const tick = () => {\n versionRef.current++;\n notify();\n };\n const unsubs = normalizedSpecs.flatMap((sp) => {\n const props = Array.isArray(sp.property) ? sp.property : [sp.property];\n return props.map((p) => store.connect({ reducer: sp.reducer, property: p }, tick));\n });\n return () => {\n for (const u of unsubs) u();\n };\n },\n [store, normalizedSpecs],\n );\n\n const getSnapshot = useCallback(() => {\n if (lastVerRef.current !== versionRef.current || !hasValueRef.current) {\n const next = selectorRef.current(store.getState());\n // Track presence with a boolean so an `undefined` selection still caches\n // (using `undefined` as \"no value yet\" would disable the equality cache).\n if (!hasValueRef.current || !isEqualRef.current(lastSelRef.current as T, next)) {\n lastSelRef.current = next;\n hasValueRef.current = true;\n }\n lastVerRef.current = versionRef.current;\n }\n return lastSelRef.current as T;\n }, [store]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n };\n\n const useAtomicProps = useAtomicPropsImpl as unknown as UseAtomicPropsOverloads;\n\n type UseEventOverloads = UseEvent<EM, S>;\n\n const useEvent: UseEventOverloads = <\n C extends keyof EM & string,\n T extends keyof EM[C] & string,\n >(\n channel: C,\n type: T,\n handler: (\n event: Event<EM, C, T>,\n getState: () => DeepReadonly<S>,\n emit: Emit<EM>,\n phase: \"committed\" | \"uncommitted\",\n ) => void | Promise<void>,\n phase: EventPhase = \"committed\",\n ): void => {\n const store = useStore();\n const handlerRef = useRef(handler);\n handlerRef.current = handler; // Always keep latest handler (solves stale closures)\n\n useEffect(() => {\n return store.onEvent(\n channel,\n type,\n (event, getState, emit, eventPhase) => {\n handlerRef.current(\n event as Event<EM, C, T>,\n getState as () => DeepReadonly<S>,\n emit,\n eventPhase,\n );\n },\n phase,\n );\n }, [store, channel, type, phase]);\n };\n\n // Bound to the context above, not the package-level one, so the returned set is complete:\n // a caller who has these hooks never has to also mount a `<StoreProvider>` to reach Suspense.\n const { useSuspenseAtomicProp, useSuspenseAtomicProps } = createSuspenseHooks<R, S, EM>(useStore);\n\n return {\n useStore,\n useEmit,\n useSelector,\n useAtomicProp,\n useAtomicProps,\n useEvent,\n useSuspenseAtomicProp,\n useSuspenseAtomicProps,\n shallowEqual,\n };\n}\n","/**\n * @module @yoltra/react\n */\n\nimport {\n createStore,\n type DeepReadonly,\n type EffectSpec,\n type EMFromReducersStrict,\n type EventMapBase,\n type EventUnion,\n type MiddlewareFunction,\n type ReducersMapAny,\n type StateFromReducers,\n type StoreInstance,\n} from \"@yoltra/core\";\nimport React, { createContext, type ReactNode } from \"react\";\n\nimport { createHooks, type YoltraHooks } from \"./hooks/createHooks\";\n\n/**\n * The value returned by {@link createYoltra}: the created `store`, an optional\n * `StoreProvider` (plus its raw `StoreContext`), and the full set of typed hooks\n * from {@link YoltraHooks}.\n *\n * @typeParam R - Reducer name union.\n * @typeParam S - State record keyed by `R`.\n * @typeParam EM - Event map.\n *\n * @public\n */\nexport interface Yoltra<R extends string, S extends Record<R, any>, EM extends EventMapBase>\n extends YoltraHooks<R, S, EM> {\n /** The store created by this call; the hooks default to it (no Provider needed). */\n store: StoreInstance<R, S, EM>;\n /** Raw context carrying the store — usually you only need `StoreProvider`. */\n StoreContext: React.Context<StoreInstance<R, S, EM> | null>;\n /** Optional provider to scope a different store instance to a subtree. */\n StoreProvider: React.FC<{ store?: StoreInstance<R, S, EM>; children: ReactNode }>;\n}\n\n/**\n * One-call setup: create a store and its fully-typed React hooks together.\n *\n * @remarks\n * Collapses the `createStore` + context + `createHooks` boilerplate into a\n * single call. The returned hooks default to the created store, so wrapping your\n * tree in a `<StoreProvider>` is **optional** — use it only to scope a different\n * store instance to a subtree (e.g. a fresh store per test).\n *\n * **Client-only convenience.** The store created here is a module-level\n * singleton, and the Suspense hooks share a module-global cache. Do not reuse a\n * `createYoltra(...)` module across SSR requests — state and cache would bleed\n * between them. For SSR, create a store per request and scope it with\n * `StoreProvider`.\n *\n * **The Suspense hooks are part of this set.** Take `useSuspenseAtomicProp` and\n * `useSuspenseAtomicProps` from here, not from the `@yoltra/react` barrel: the\n * barrel's copies read the *package-level* context, which this function never\n * fills, so they would throw `useStore must be used inside <StoreProvider>` at\n * runtime with nothing in the types to warn you — the two are identical in\n * shape. The ones returned here are bound to this store's own context and need\n * no provider, like the rest of the set.\n *\n * @example Suspense alongside createYoltra\n * ```tsx\n * export const { store, useAtomicProp, useSuspenseAtomicProp } = createYoltra({ ... });\n *\n * // No <StoreProvider> anywhere: every hook above already knows this store.\n * createRoot(el).render(<App />);\n * ```\n *\n * @typeParam RM - Reducers map; state shape and event map are inferred from it.\n * @param cfg - The same configuration accepted by {@link createStore}.\n * @returns The `store`, an optional `StoreProvider`, the raw `StoreContext`, and\n * the full set of typed hooks (`useAtomicProp`, `useAtomicProps`, `useEmit`,\n * `useEvent`, `useSelector`, `useStore`, `useSuspenseAtomicProp`,\n * `useSuspenseAtomicProps`, `shallowEqual`).\n *\n * @example\n * ```tsx\n * export const { store, useAtomicProp, useEmit } = createYoltra({\n * name: 'App',\n * reducer: {\n * counter: {\n * state: { value: 0 },\n * when: { keys: [['ui', 'increment']] },\n * reducer: (s, e) => (e.type === 'increment' ? { value: s.value + e.payload } : s),\n * },\n * },\n * });\n *\n * function Counter() {\n * const value = useAtomicProp({ reducer: 'counter', property: 'value' });\n * const emit = useEmit();\n * return <button onClick={() => emit('ui', 'increment', 1)}>{value}</button>;\n * }\n * ```\n *\n * @public\n */\nexport function createYoltra<RM extends ReducersMapAny>(cfg: {\n name: string;\n reducer: RM;\n middleware?: MiddlewareFunction<DeepReadonly<StateFromReducers<RM>>, EMFromReducersStrict<RM>>[];\n effects?: Array<EffectSpec<DeepReadonly<StateFromReducers<RM>>, EMFromReducersStrict<RM>>>;\n dedupWindowMs?: number;\n devtools?: { allowReplay?: boolean };\n onEffectError?: (error: unknown, event: EventUnion<EMFromReducersStrict<RM>>) => void;\n}): Yoltra<keyof RM & string, StateFromReducers<RM>, EMFromReducersStrict<RM>> {\n type S = StateFromReducers<RM>;\n type EM = EMFromReducersStrict<RM>;\n type R = keyof RM & string;\n\n const store: StoreInstance<R, S, EM> = createStore(cfg);\n\n // Default the context value to the store so components work WITHOUT a Provider.\n const StoreContext = createContext<StoreInstance<R, S, EM> | null>(store);\n\n const hooks = createHooks<R, S, EM>(StoreContext);\n\n /**\n * Optional provider — only needed to scope a different store instance to a\n * subtree; otherwise the hooks use the store created above.\n */\n const StoreProvider: React.FC<{ store?: StoreInstance<R, S, EM>; children: ReactNode }> = ({\n store: override,\n children,\n }) => <StoreContext.Provider value={override ?? store}>{children}</StoreContext.Provider>;\n\n return { store, StoreContext, StoreProvider, ...hooks };\n}\n","/**\n * Hooks for normalised collections, so a row subscribes to itself rather than to the list.\n *\n * @remarks\n * These are thin wrappers over {@link useAtomicProp}. Their whole value is that the path\n * comes from the adapter rather than being written by hand: `entities.abc.title` typed into a\n * component is a string nothing checks, and it is the kind of string that silently stops\n * matching when an id format changes.\n *\n * @module @yoltra/react\n */\n\nimport type { EntityAdapter, EntityId, EntityState } from \"@yoltra/core\";\n\nimport { useAtomicProp } from \"../hooks/hooks\";\n\n/**\n * Subscribes to a collection's order.\n *\n * @remarks\n * This is the subscription a list container wants, and the only one that should wake when the\n * collection is reordered. Rows use {@link useEntity} or {@link useEntityField} and stay\n * asleep through a sort.\n *\n * @public\n */\nexport function useEntityIds<T, Id extends EntityId, R extends string>(\n reducer: R,\n adapter: EntityAdapter<T, Id>,\n): readonly Id[] {\n return useAtomicProp<R, Record<R, EntityState<T, Id>>, R, never>({\n reducer,\n property: adapter.idsPath as never,\n }) as unknown as readonly Id[];\n}\n\n/**\n * Subscribes to one entity.\n *\n * @returns The entity, or `undefined` once it has been removed — a row that outlives its data\n * for one render is normal, and returning `undefined` is what lets it render nothing rather\n * than throw.\n *\n * @public\n */\nexport function useEntity<T, Id extends EntityId, R extends string>(\n reducer: R,\n adapter: EntityAdapter<T, Id>,\n id: Id,\n): T | undefined {\n return useAtomicProp<R, Record<R, EntityState<T, Id>>, R, never>({\n reducer,\n property: adapter.pathTo(id) as never,\n }) as unknown as T | undefined;\n}\n\n/**\n * Subscribes to one field of one entity.\n *\n * @remarks\n * The narrowest subscription available, and the reason the shape is worth adopting: editing a\n * title wakes the components reading that title and nothing else.\n *\n * @public\n */\nexport function useEntityField<T, Id extends EntityId, R extends string, K extends keyof T & string>(\n reducer: R,\n adapter: EntityAdapter<T, Id>,\n id: Id,\n field: K,\n): T[K] | undefined {\n return useAtomicProp<R, Record<R, EntityState<T, Id>>, R, never>({\n reducer,\n property: adapter.pathTo(id, field) as never,\n }) as unknown as T[K] | undefined;\n}\n"],"names":["require$$0","createContext","useRef","useMemo","useCallback","useEffect","useSyncExternalStore","useContext","createStore","StoreContext","jsxRuntime","reactJsxRuntime_production","REACT_ELEMENT_TYPE","REACT_FRAGMENT_TYPE","jsxProd","type","config","maybeKey","key","propName","getComponentNameFromType","REACT_CLIENT_REFERENCE","REACT_PROFILER_TYPE","REACT_STRICT_MODE_TYPE","REACT_SUSPENSE_TYPE","REACT_SUSPENSE_LIST_TYPE","REACT_ACTIVITY_TYPE","REACT_PORTAL_TYPE","REACT_CONTEXT_TYPE","REACT_CONSUMER_TYPE","REACT_FORWARD_REF_TYPE","innerType","REACT_MEMO_TYPE","REACT_LAZY_TYPE","testStringCoercion","value","checkKeyStringCoercion","JSCompiler_inline_result","JSCompiler_temp_const","JSCompiler_inline_result$jscomp$0","getTaskName","name","getOwner","dispatcher","ReactSharedInternals","UnknownOwner","hasValidKey","hasOwnProperty","getter","defineKeyPropWarningGetter","props","displayName","warnAboutAccessingKey","specialPropKeyWarningShown","elementRefGetterWithDeprecationWarning","componentName","didWarnAboutElementRef","ReactElement","self","source","owner","debugStack","debugTask","jsxDEVImpl","isStaticChildren","children","isArrayImpl","validateChildKeys","keys","k","didWarnAboutKeySpread","node","React","createTask","callStackForError","unknownOwnerDebugStack","unknownOwnerDebugTask","reactJsxRuntime_development","trackActualOwner","jsxRuntimeModule","require$$1","StoreProvider","store","jsx","warned","warnOnce","message","hasWildcard","p","normalizePath","splitPath","specsSignature","specs","enc","s","PATH_SEGMENTS","makePathProxy","segments","target","_target","prop","toDottedPath","accessor","leaf","recorded","path","getAtPath","obj","cur","seg","useStableSnapshot","read","isEqual","structuralDeps","readRef","isEqualRef","cache","next","shallowEqual","a","b","ka","kb","useStore","ctx","useEmit","useSelector","selector","subscribe","notify","getSnapshot","useAtomicPropImpl","spec","map","normalizedSpec","isGlob","slice","useAtomicProp","useEvent","channel","handler","phase","handlerRef","event","getState","emit","eventPhase","computeExpiry","staleTime","computeErrorExpiry","errorTtlMs","MAX_ENTRIES","SuspenseCache","__publicField","oldest","entry","load","now","promise","err","pathKey","stripStoreId","reducer","needle","part","suspenseCache","storeIds","nextStoreId","storeKey","id","buildKey","extraKey","useSuspenseAtomicPropImpl","useStoreHook","storeSpec","options","optionsRef","_a","val","opts","getServerSnapshot","useSuspenseAtomicPropsImpl","normalized","sp","parts","wrapped","unsubs","u","state","result","invalidateAtomicProp","property","invalidateAtomicPropsByReducer","clearSuspenseCache","createSuspenseHooks","createHooks","specOrReducer","mapOrAccessor","accessorForm","rawProperty","useAtomicProps","versionRef","lastSelRef","lastVerRef","hasValueRef","selectorRef","normalizedSpecs","tick","useSuspenseAtomicProp","useSuspenseAtomicProps","createYoltra","cfg","hooks","override","useEntityIds","adapter","useEntity","useEntityField","field"],"mappings":"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","x_google_ignoreList":[1,2,3]}