@yoltra/react 0.1.0 → 0.3.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/path.ts","../src/hooks/hooks.ts","../src/hooks/suspense.ts","../src/hooks/createHooks.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","/** @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 * Reads a dotted path from an object; returns `undefined` when a segment is missing.\n * @internal\n */\nexport function getAtPath(obj: any, path: string): any {\n if (!path) return obj;\n\n let cur = obj;\n for (const seg of splitPath(path)) {\n if (cur == null) return undefined;\n cur = cur[seg];\n }\n\n return cur;\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 { useContext, useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport { StoreContext } from \"../context/StoreContext\";\nimport { getAtPath, hasWildcard, normalizePath } from \"../utils/path\";\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/**\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}.\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, any>>(a: T, b: T) {\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 any)[k])) return false;\n }\n\n return true;\n}\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 = useMemo(() => {\n let last = selector(store.getState() as DeepReadonly<S>);\n return () => {\n const next = selector(store.getState() as DeepReadonly<S>);\n return isEqual(last, next) ? last : (last = next);\n };\n }, [store, selector, isEqual]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n// Strongly-typed implementation for the common case\nfunction useAtomicPropImpl<\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> {\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 getSnapshot = useMemo(() => {\n const isGlob = hasWildcard(normalizedSpec.property);\n const read = () => {\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 source;\n };\n\n let last = read();\n return () => {\n const next = read();\n return Object.is(last, next) ? last : (last = next);\n };\n }, [store, normalizedSpec]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot) as PathValue<S[R1], P>;\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 getSnapshot = useMemo(() => {\n const isGlob = hasWildcard(normalizedSpec.property);\n const read = () => {\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\n let last = read();\n return () => {\n const next = read();\n return isEqual(last, next) ? last : (last = next);\n };\n }, [store, normalizedSpec, map, isEqual]);\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 if (!map && !hasWildcard(spec.property)) {\n return useAtomicPropImpl<R, S, any, any>(spec) as any;\n }\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 * @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\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 }, [JSON.stringify(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 const getSnapshot = useMemo(() => {\n return () => {\n if (lastVerRef.current !== versionRef.current) {\n const next = selector(store.getState() as DeepReadonly<S>);\n const prev = lastSelRef.current as T | undefined;\n\n if (prev === undefined || !isEqual(prev, next)) {\n lastSelRef.current = next;\n }\n\n lastVerRef.current = versionRef.current;\n }\n\n return lastSelRef.current as T;\n };\n }, [store, selector, isEqual]);\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, 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/** @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 | { status: \"error\"; error: any; expiresAt: number | null };\n\n/** @internal */\nclass SuspenseCache {\n private store = new Map<CacheKey, CacheEntry<any>>();\n\n read<T>(key: CacheKey, load: () => T | Promise<T>, staleTime: number | null): T {\n const now = Date.now();\n const entry = this.store.get(key);\n\n if (entry && entry.status === \"ready\" && (entry.expiresAt == null || entry.expiresAt > now)) {\n return entry.value as T;\n }\n if (\n entry &&\n entry.status === \"pending\" &&\n (entry.expiresAt == null || entry.expiresAt > now)\n ) {\n throw entry.promise;\n }\n if (entry && entry.status === \"error\" && (entry.expiresAt == null || entry.expiresAt > now)) {\n throw entry.error;\n }\n\n const promise = Promise.resolve()\n .then(load)\n .then((value) => {\n this.store.set(key, {\n status: \"ready\",\n value,\n expiresAt: staleTime == null ? null : Date.now() + staleTime,\n });\n })\n .catch((err) => {\n this.store.set(key, {\n status: \"error\",\n error: err,\n expiresAt: staleTime == null ? null : Date.now() + staleTime,\n });\n });\n\n this.store.set(key, {\n status: \"pending\",\n promise,\n expiresAt: staleTime == null ? null : Date.now() + staleTime,\n });\n throw promise;\n }\n\n invalidate(key: CacheKey) {\n this.store.delete(key);\n }\n invalidatePrefix(prefix: string) {\n for (const k of this.store.keys()) {\n if (k.startsWith(prefix)) this.store.delete(k);\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/** @internal */\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 /** Time in ms before the cached value is considered stale (default: 0). */\n staleTime?: number;\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 * @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>(storeSpec as any, options);\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>(storeSpec: { reducer: R; property: P }, options: SuspenseAtomicPropOptions<T, S>): T {\n const store = useStore<EventMapBase, R, S>() as StoreInstance<R, S, EventMapBase>;\n const reducer = storeSpec.reducer;\n const path = normalizePath(storeSpec.property as string);\n const key = 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 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 return suspenseCache.read<T>(key, () => options.load(val, slice), options.staleTime ?? 0);\n };\n }, [store, reducer, path, key, options]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\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 /** Time in ms before the cached value is considered stale (default: 0). */\n staleTime?: number;\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 * @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>(specs as any, options);\n}\n\n/** @internal */\nfunction _useSuspenseAtomicPropsImpl<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 const store = useStore<EventMapBase, R, S>() as StoreInstance<R, S, EventMapBase>;\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 [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 options.key ? `${parts}::${options.key}` : parts;\n }, [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 getSnapshot = useMemo(() => {\n return () => {\n const state = store.getState() as S;\n return suspenseCache.read<T>(key, () => options.load(state), options.staleTime ?? 0);\n };\n }, [store, key, options]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\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.invalidate(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.invalidatePrefix(`${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 * @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 { useContext, useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport { getAtPath, hasWildcard, normalizePath } from \"../utils/path\";\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 <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 * 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 as a standalone\n * export from `@yoltra/react` via {@link shallowEqual | hooks.shallowEqual}.\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) {\n if (Object.is(a, b)) return true;\n if (!a || !b) return false;\n const ka = Object.keys(a),\n kb = Object.keys(b);\n if (ka.length !== kb.length) return false;\n for (const k of ka) {\n if (!Object.is(a[k], (b as Record<string, unknown>)[k])) return false;\n }\n return true;\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`, 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>) {\n function useStore(): StoreInstance<R, S, EM> {\n const ctx = useContext(StoreContext);\n if (!ctx) throw new Error(\"useStore must be used inside <StoreProvider>\");\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 = useMemo(() => {\n let last = selector(store.getState());\n return () => {\n const next = selector(store.getState());\n return isEqual(last, next) ? last : (last = next);\n };\n }, [store, selector, isEqual]);\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n }\n\n type UseAtomicPropOverloads = UseAtomicProp<R, S>;\n\n const useAtomicPropImpl = (\n spec: { reducer: R; property: string },\n map?: (value: unknown) => unknown,\n isEqual?: (a: unknown, b: unknown) => boolean,\n ): unknown => {\n const store = useStore();\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 getSnapshot = useMemo(() => {\n const isGlob = hasWildcard(normalizedSpec.property);\n const read = () => {\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 const eq = isEqual ?? Object.is;\n let last = read();\n return () => {\n const next = read();\n return eq(last, next) ? last : (last = next);\n };\n }, [store, normalizedSpec, map, isEqual]);\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\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 }, [JSON.stringify(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 = useMemo(() => {\n return () => {\n if (lastVerRef.current !== versionRef.current) {\n const next = selector(store.getState());\n const prev = lastSelRef.current;\n if (prev === undefined || !isEqual(prev, next)) lastSelRef.current = next;\n lastVerRef.current = versionRef.current;\n }\n return lastSelRef.current as T;\n };\n }, [store, selector, isEqual]);\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 return {\n useStore,\n useEmit,\n useSelector,\n useAtomicProp,\n useAtomicProps,\n useEvent,\n shallowEqual,\n };\n}\n"],"names":["require$$0","createContext","useRef","useEffect","useMemo","useSyncExternalStore","useContext","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","hasWildcard","p","normalizePath","splitPath","getAtPath","obj","path","cur","seg","useStore","ctx","useEmit","shallowEqual","a","b","ka","kb","useSelector","selector","isEqual","subscribe","notify","getSnapshot","last","next","useAtomicPropImpl","spec","normalizedSpec","prop","isGlob","read","slice","_useAtomicPropImpl","map","useAtomicProp","useAtomicProps","specs","_useAtomicPropsImpl","versionRef","lastSelRef","lastVerRef","normalizedSpecs","sp","tick","unsubs","u","prev","useEvent","channel","handler","phase","handlerRef","event","getState","emit","eventPhase","SuspenseCache","__publicField","load","staleTime","now","entry","promise","err","prefix","suspenseCache","buildKey","reducer","extraKey","useSuspenseAtomicProp","storeSpec","options","_useSuspenseAtomicPropImpl","_a","val","useSuspenseAtomicProps","_useSuspenseAtomicPropsImpl","normalized","parts","wrapped","state","invalidateAtomicProp","property","invalidateAtomicPropsByReducer","clearSuspenseCache","createHooks","eq"],"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"],"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 { 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 * @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 const getSnapshot = useCallback(() => {\n if (lastVerRef.current !== versionRef.current || !hasValueRef.current) {\n const next = selectorRef.current(store.getState() 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]);\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/** @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 | { status: \"error\"; error: any; expiresAt: number | null };\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/** @internal */\nclass SuspenseCache {\n private store = new Map<CacheKey, CacheEntry<any>>();\n\n read<T>(key: CacheKey, load: () => T | Promise<T>, staleTime: number | null): 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 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 until it is\n // invalidated (by a store change on the subscribed path, or an explicit\n // invalidate/clear). Error caching is independent of staleTime.\n if (entry && entry.status === \"error\") {\n throw entry.error;\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, { status: \"error\", error: err, expiresAt: null });\n });\n\n this.store.set(key, { status: \"pending\", promise, expiresAt: null });\n throw promise;\n }\n\n invalidate(key: CacheKey) {\n this.store.delete(key);\n }\n invalidatePrefix(prefix: string) {\n for (const k of this.store.keys()) {\n if (k.startsWith(prefix)) this.store.delete(k);\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/** @internal */\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 /** 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>(storeSpec as any, options);\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>(storeSpec: { reducer: R; property: P }, options: SuspenseAtomicPropOptions<T, S>): T {\n const store = useStore<EventMapBase, R, S>() as StoreInstance<R, S, EventMapBase>;\n const reducer = storeSpec.reducer;\n const path = normalizePath(storeSpec.property as string);\n const key = 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);\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 /** 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>(specs as any, options);\n}\n\n/** @internal */\nfunction useSuspenseAtomicPropsImpl<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 const store = useStore<EventMapBase, R, S>() as StoreInstance<R, S, EventMapBase>;\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 options.key ? `${parts}::${options.key}` : parts;\n }, [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);\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.invalidate(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.invalidatePrefix(`${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 * @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\";\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 /** 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`, 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 return {\n useStore,\n useEmit,\n useSelector,\n useAtomicProp,\n useAtomicProps,\n useEvent,\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 * @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`, `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 * events: [['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"],"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","useAtomicProps","useAtomicPropsImpl","versionRef","lastSelRef","lastVerRef","hasValueRef","selectorRef","normalizedSpecs","sp","tick","unsubs","u","useEvent","channel","handler","phase","handlerRef","event","getState","emit","eventPhase","computeExpiry","staleTime","SuspenseCache","__publicField","load","now","entry","promise","err","prefix","suspenseCache","buildKey","reducer","extraKey","useSuspenseAtomicProp","storeSpec","options","useSuspenseAtomicPropImpl","optionsRef","_a","val","opts","getServerSnapshot","useSuspenseAtomicProps","useSuspenseAtomicPropsImpl","normalized","parts","wrapped","state","result","invalidateAtomicProp","property","invalidateAtomicPropsByReducer","clearSuspenseCache","createHooks","specOrReducer","mapOrAccessor","accessorForm","rawProperty","createYoltra","cfg","hooks","override"],"mappings":"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","x_google_ignoreList":[1,2,3]}
@@ -0,0 +1,79 @@
1
+ import { DeepReadonly, EffectSpec, EMFromReducersStrict, EventMapBase, EventUnion, MiddlewareFunction, ReducersMapAny, StateFromReducers, StoreInstance } from '@yoltra/core';
2
+ import { default as React, ReactNode } from 'react';
3
+ import { YoltraHooks } from './hooks/createHooks';
4
+ /**
5
+ * The value returned by {@link createYoltra}: the created `store`, an optional
6
+ * `StoreProvider` (plus its raw `StoreContext`), and the full set of typed hooks
7
+ * from {@link YoltraHooks}.
8
+ *
9
+ * @typeParam R - Reducer name union.
10
+ * @typeParam S - State record keyed by `R`.
11
+ * @typeParam EM - Event map.
12
+ *
13
+ * @public
14
+ */
15
+ export interface Yoltra<R extends string, S extends Record<R, any>, EM extends EventMapBase> extends YoltraHooks<R, S, EM> {
16
+ /** The store created by this call; the hooks default to it (no Provider needed). */
17
+ store: StoreInstance<R, S, EM>;
18
+ /** Raw context carrying the store — usually you only need `StoreProvider`. */
19
+ StoreContext: React.Context<StoreInstance<R, S, EM> | null>;
20
+ /** Optional provider to scope a different store instance to a subtree. */
21
+ StoreProvider: React.FC<{
22
+ store?: StoreInstance<R, S, EM>;
23
+ children: ReactNode;
24
+ }>;
25
+ }
26
+ /**
27
+ * One-call setup: create a store and its fully-typed React hooks together.
28
+ *
29
+ * @remarks
30
+ * Collapses the `createStore` + context + `createHooks` boilerplate into a
31
+ * single call. The returned hooks default to the created store, so wrapping your
32
+ * tree in a `<StoreProvider>` is **optional** — use it only to scope a different
33
+ * store instance to a subtree (e.g. a fresh store per test).
34
+ *
35
+ * **Client-only convenience.** The store created here is a module-level
36
+ * singleton, and the Suspense hooks share a module-global cache. Do not reuse a
37
+ * `createYoltra(...)` module across SSR requests — state and cache would bleed
38
+ * between them. For SSR, create a store per request and scope it with
39
+ * `StoreProvider`.
40
+ *
41
+ * @typeParam RM - Reducers map; state shape and event map are inferred from it.
42
+ * @param cfg - The same configuration accepted by {@link createStore}.
43
+ * @returns The `store`, an optional `StoreProvider`, the raw `StoreContext`, and
44
+ * the full set of typed hooks (`useAtomicProp`, `useAtomicProps`, `useEmit`,
45
+ * `useEvent`, `useSelector`, `useStore`, `shallowEqual`).
46
+ *
47
+ * @example
48
+ * ```tsx
49
+ * export const { store, useAtomicProp, useEmit } = createYoltra({
50
+ * name: 'App',
51
+ * reducer: {
52
+ * counter: {
53
+ * state: { value: 0 },
54
+ * events: [['ui', 'increment']],
55
+ * reducer: (s, e) => (e.type === 'increment' ? { value: s.value + e.payload } : s),
56
+ * },
57
+ * },
58
+ * });
59
+ *
60
+ * function Counter() {
61
+ * const value = useAtomicProp({ reducer: 'counter', property: 'value' });
62
+ * const emit = useEmit();
63
+ * return <button onClick={() => emit('ui', 'increment', 1)}>{value}</button>;
64
+ * }
65
+ * ```
66
+ *
67
+ * @public
68
+ */
69
+ export declare function createYoltra<RM extends ReducersMapAny>(cfg: {
70
+ name: string;
71
+ reducer: RM;
72
+ middleware?: MiddlewareFunction<DeepReadonly<StateFromReducers<RM>>, EMFromReducersStrict<RM>>[];
73
+ effects?: Array<EffectSpec<DeepReadonly<StateFromReducers<RM>>, EMFromReducersStrict<RM>>>;
74
+ dedupWindowMs?: number;
75
+ devtools?: {
76
+ allowReplay?: boolean;
77
+ };
78
+ onEffectError?: (error: unknown, event: EventUnion<EMFromReducersStrict<RM>>) => void;
79
+ }): Yoltra<keyof RM & string, StateFromReducers<RM>, EMFromReducersStrict<RM>>;
@@ -26,6 +26,7 @@ import * as React from "react";
26
26
  * @public
27
27
  */
28
28
  export type UseAtomicProp<R extends string, S extends Record<R, any>> = {
29
+ <R1 extends R, V>(reducer: R1, accessor: (state: DeepReadonly<S[R1]>) => V, isEqual?: (a: V, b: V) => boolean): V;
29
30
  <R1 extends R, P extends Dotted<S[R1]>>(spec: {
30
31
  reducer: R1;
31
32
  property: P;
@@ -109,21 +110,36 @@ export type UseAtomicProps<R extends string, S extends Record<R, any>> = {
109
110
  */
110
111
  export type UseEvent<EM extends EventMapBase, S> = <C extends keyof EM & string, T extends keyof EM[C] & string>(channel: C, type: T, handler: (event: Event<EM, C, T>, getState: () => DeepReadonly<S>, emit: Emit<EM>, phase: "committed" | "uncommitted") => void | Promise<void>, phase?: EventPhase) => void;
111
112
  /**
112
- * Shallow object equality using `Object.is` per-key.
113
+ * The bundle of fully-typed hooks returned by {@link createHooks} (and, with the
114
+ * store and provider added, by {@link createYoltra}).
113
115
  *
114
- * Useful as the `isEqual` argument for `useAtomicProp` and `useAtomicProps`
115
- * when the derived value is a plain object. Also available as a standalone
116
- * export from `@yoltra/react` via {@link shallowEqual | hooks.shallowEqual}.
116
+ * Naming this return shape explicitly — rather than letting it be inferred —
117
+ * keeps `createYoltra`'s emitted `.d.ts` portable: the inferred form would leak
118
+ * a reference to a non-re-exported internal symbol and trip TS2742 in
119
+ * `composite`/`declaration` consumers.
117
120
  *
118
- * @example
119
- * ```ts
120
- * shallowEqual({ a: 1 }, { a: 1 }); // true
121
- * shallowEqual({ a: 1 }, { a: 2 }); // false
122
- * ```
121
+ * @typeParam R - Reducer name union.
122
+ * @typeParam S - State record keyed by `R`.
123
+ * @typeParam EM - Event map.
123
124
  *
124
125
  * @public
125
126
  */
126
- export declare function shallowEqual<T extends Record<string, unknown>>(a: T, b: T): boolean;
127
+ export interface YoltraHooks<R extends string, S extends Record<R, any>, EM extends EventMapBase> {
128
+ /** Reads the current store from context (falling back to the default store). */
129
+ useStore: () => StoreInstance<R, S, EM>;
130
+ /** Returns the store's typed `emit`. */
131
+ useEmit: () => Emit<EM>;
132
+ /** Subscribes to a derived value with an optional equality comparator. */
133
+ useSelector: <T>(selector: (state: DeepReadonly<S>) => T, isEqual?: (a: T, b: T) => boolean) => T;
134
+ /** Subscribes to a single dotted path (or typed accessor). */
135
+ useAtomicProp: UseAtomicProp<R, S>;
136
+ /** Subscribes to several paths and derives a value from the full state. */
137
+ useAtomicProps: UseAtomicProps<R, S>;
138
+ /** Runs a handler for a specific `(channel, type)` event. */
139
+ useEvent: UseEvent<EM, S>;
140
+ /** Shallow object equality using `Object.is` per-key. */
141
+ shallowEqual: <T extends Record<string, unknown>>(a: T, b: T) => boolean;
142
+ }
127
143
  /**
128
144
  * Factory that creates fully-typed React hooks bound to a specific store context.
129
145
  *
@@ -171,12 +187,4 @@ export declare function shallowEqual<T extends Record<string, unknown>>(a: T, b:
171
187
  *
172
188
  * @public
173
189
  */
174
- export declare function createHooks<R extends string, S extends Record<R, any>, EM extends EventMapBase>(StoreContext: React.Context<StoreInstance<R, S, EM> | null>): {
175
- useStore: () => StoreInstance<R, S, EM>;
176
- useEmit: () => Emit<EM>;
177
- useSelector: <T>(selector: (state: DeepReadonly<S>) => T, isEqual?: (a: T, b: T) => boolean) => T;
178
- useAtomicProp: UseAtomicProp<R, S>;
179
- useAtomicProps: UseAtomicProps<R, S>;
180
- useEvent: UseEvent<EM, S>;
181
- shallowEqual: typeof shallowEqual;
182
- };
190
+ export declare function createHooks<R extends string, S extends Record<R, any>, EM extends EventMapBase>(StoreContext: React.Context<StoreInstance<R, S, EM> | null>): YoltraHooks<R, S, EM>;