@yoltra/react 0.2.0 → 0.4.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.
package/LICENSE CHANGED
File without changes
package/README.es.md CHANGED
@@ -1,4 +1,4 @@
1
- ![yoltra logo](../../assets/yoltra-logo.png)
1
+ ![Yoltra logo](https://yoltra.dev/assets/yoltra-logo.png)
2
2
 
3
3
  # @yoltra/react
4
4
 
@@ -77,16 +77,16 @@ export const { store, useAtomicProp, useEmit, StoreProvider } = createYoltra({
77
77
  ### 2. Usa los hooks — sin provider
78
78
 
79
79
  Los hooks usan por defecto el store de arriba, asi que puedes renderizar componentes directamente.
80
- Suscribete con un **accessor tipado**: `s` autocompleta la forma de tu estado y el tipo de retorno
81
- se infiere.
80
+ Suscribete con una spec **`{ reducer, property }`**: el `property` con puntos nombra la ruta exacta
81
+ a leer.
82
82
 
83
83
  ```tsx
84
84
  // Counter.tsx
85
85
  import { useAtomicProp, useEmit } from "./yoltra";
86
86
 
87
87
  export function Counter() {
88
- // Accessor tipado — se re-renderiza solo cuando counter.value cambia. Sin selectores, sin memo.
89
- const value = useAtomicProp("counter", (s) => s.value);
88
+ // Forma objeto — se re-renderiza solo cuando counter.value cambia. Sin selectores, sin memo.
89
+ const value = useAtomicProp({ reducer: "counter", property: "value" });
90
90
  const emit = useEmit();
91
91
 
92
92
  return (
@@ -122,8 +122,17 @@ export const AppStoreContext = createContext<StoreInstance<"counter", AppState,
122
122
  null,
123
123
  );
124
124
 
125
- export const { useStore, useEmit, useSelector, useAtomicProp, useAtomicProps, useEvent, shallowEqual } =
126
- createHooks(AppStoreContext);
125
+ export const {
126
+ useStore,
127
+ useEmit,
128
+ useSelector,
129
+ useAtomicProp,
130
+ useAtomicProps,
131
+ useEvent,
132
+ useSuspenseAtomicProp,
133
+ useSuspenseAtomicProps,
134
+ shallowEqual,
135
+ } = createHooks(AppStoreContext);
127
136
  ```
128
137
 
129
138
  Provee el store con `<AppStoreContext.Provider value={store}>` en tu raiz.
@@ -132,21 +141,18 @@ Provee el store con `<AppStoreContext.Provider value={store}>` en tu raiz.
132
141
 
133
142
  ## API de Hooks
134
143
 
135
- ### `useAtomicProp(reducer, accessor)` — o `useAtomicProp({ reducer, property }, map?, isEqual?)`
144
+ ### `useAtomicProp({ reducer, property }, map?, isEqual?)`
136
145
 
137
- Selector de ruta unica con grano fino. Se re-renderiza solo cuando la hoja especificada cambia.
138
- Prefiere la forma de **accessor tipado** — autocompleta la forma del estado e infiere el tipo de
139
- retorno; usa la forma string para rutas dinamicas o con comodines.
146
+ Selector de ruta unica con grano fino. Se re-renderiza solo cuando la hoja especificada cambia. El
147
+ `property` con puntos nombra la ruta exacta — incluyendo rutas dinamicas
148
+ (`` `items.${id}.title` ``) y con comodines.
140
149
 
141
150
  ```tsx
142
- // Accessor tipado (recomendado) — autocompleta items[0].title, infiere string
143
- const title = useAtomicProp("todos", (s) => s.items[0].title);
151
+ // Forma objeto (recomendada) — suscribete a la ruta exacta
152
+ const title = useAtomicProp({ reducer: "todos", property: "items.0.title" });
144
153
 
145
- // Forma string — misma suscripcion, para rutas dinamicas
146
- const sameTitle = useAtomicProp({
147
- reducer: "todos",
148
- property: "items.0.title",
149
- });
154
+ // Ruta dinamica — interpola la clave
155
+ const byId = useAtomicProp({ reducer: "todos", property: `items.${id}.title` });
150
156
 
151
157
  // Con mapper — derivar un valor de la ruta
152
158
  const count = useAtomicProp({ reducer: "todos", property: "items" }, (items) => items.length);
@@ -159,6 +165,9 @@ const allTitles = useAtomicProp(
159
165
  );
160
166
  ```
161
167
 
168
+ > Tambien existe una sobrecarga con accessor tipado — `useAtomicProp("todos", (s) => s.items[0].title)`
169
+ > — para rutas estaticas; autocompleta la forma del estado e infiere el tipo de retorno.
170
+
162
171
  **Patrones soportados:**
163
172
 
164
173
  - `"items.0.title"` -- ruta exacta (incluyendo indices numericos de array)
@@ -252,9 +261,19 @@ Retorna la instancia del store. Lanza error si se llama fuera de un provider.
252
261
 
253
262
  ```tsx
254
263
  const store = useStore();
255
- const state = store.getState();
264
+
265
+ // ✅ En un callback o un efecto: lee el valor en el momento en que se quiere.
266
+ const onSave = () => save(store.getState());
267
+
268
+ // ❌ En el cuerpo del render: esto no se suscribe a nada.
269
+ const value = store.getState().counter.value;
256
270
  ```
257
271
 
272
+ `getState()` es una lectura, no una suscripción. Llamado durante el render, el componente se
273
+ renderiza una vez con ese valor y nunca más — nada le avisó de que el valor cambió. Parece que
274
+ funciona hasta que el estado cambia y la pantalla no. Lee con `useAtomicProp` o `useSelector` lo
275
+ que vayas a renderizar, y deja `getState()` para callbacks y efectos, que es para lo que es.
276
+
258
277
  ---
259
278
 
260
279
  ## Hooks de Suspense
@@ -296,6 +315,27 @@ const stats = useSuspenseAtomicProps(
296
315
  );
297
316
  ```
298
317
 
318
+ ### Importalos de tu conjunto de hooks, no del barrel
319
+
320
+ `createYoltra` y `createHooks` devuelven estos dos junto con el resto, ligados al mismo contexto.
321
+ Deliberadamente **no** se exportan desde el barrel del paquete: una copia a nivel de paquete seria
322
+ identica en forma y aun asi lanzaria `useStore must be used inside <StoreProvider>` en tiempo de
323
+ ejecucion cuando el contexto que lee nunca se lleno — un error que los tipos no podian atrapar.
324
+ Importarlos desde cualquier sitio que no sea el resultado de tu propio `createYoltra`/`createHooks`
325
+ es ahora un error de compilacion, que es el mismo aviso llegando en el momento correcto.
326
+
327
+ ```tsx
328
+ // store.ts
329
+ export const { store, useAtomicProp, useSuspenseAtomicProp } = createYoltra({ ... });
330
+
331
+ // Forecast.tsx
332
+ import { useSuspenseAtomicProp } from "./store"; // ✅ conoce el store
333
+ ```
334
+
335
+ Los valores en cache tienen alcance por store, asi que dos stores que compartan nombre de reducer
336
+ y ruta mantienen entradas separadas; las utilidades de invalidacion de abajo reciben una ruta y la
337
+ limpian en todos los stores que la hayan cacheado.
338
+
299
339
  ### Utilidades de cache
300
340
 
301
341
  ```typescript
@@ -377,10 +417,10 @@ function TodoItem({ index }: { index: number }) {
377
417
  ## Ejemplos
378
418
 
379
419
  - **[App de Tareas con Profiler](../../examples/v0/yoltra-in-react)** -- CRUD completo con
380
- comparacion de flamegraph
420
+ comparacion de flamegraph · [▶ Abrir la demo en vivo](https://yoltra.dev/es/demos/in-react)
381
421
  - **[Logo Cinetico (3000 particulas)](../../examples/v0/yoltra-kinetic-logo)** -- Suscripciones
382
- independientes por circulo SVG
383
- - **[Next.js (Pages Router)](../../examples/v0/yoltra-in-nextjs)** -- estado de cliente + cambio de tema
422
+ independientes por circulo SVG · [▶ Abrir la demo en vivo](https://yoltra.dev/es/demos/kinetic-logo)
423
+ - **[Next.js (Pages Router)](../../examples/v0/yoltra-in-nextjs)** -- estado de cliente + cambio de tema · [▶ Abrir la demo en vivo](https://yoltra.dev/es/demos/in-nextjs)
384
424
 
385
425
  ---
386
426
 
@@ -411,6 +451,25 @@ antes de v1.0.0.
411
451
 
412
452
  ---
413
453
 
454
+ ## Colecciones normalizadas
455
+
456
+ `useEntityIds`, `useEntity` y `useEntityField` se emparejan con `createEntityAdapter` de
457
+ `@yoltra/core`. Son envoltorios delgados sobre `useAtomicProp`; el valor esta en que la ruta viene
458
+ del adapter en vez de escribirse a mano en un componente, donde nada la verifica.
459
+
460
+ ```tsx
461
+ function List() {
462
+ const ids = useEntityIds('todos', todos);
463
+ return <>{ids.map((id) => <Row key={id} id={id} />)}</>;
464
+ }
465
+
466
+ function Row({ id }: { id: string }) {
467
+ // Despierta cuando cambia este titulo, y no cuando cambia el de otra fila.
468
+ const title = useEntityField('todos', todos, id, 'title');
469
+ return <li>{title}</li>;
470
+ }
471
+ ```
472
+
414
473
  ## Licencia
415
474
 
416
475
  **MIT** -- Libre para usar en proyectos comerciales y de codigo abierto.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- ![yoltra logo](../../assets/yoltra-logo.png)
1
+ ![Yoltra logo](https://yoltra.dev/assets/yoltra-logo.png)
2
2
 
3
3
  # @yoltra/react
4
4
 
@@ -77,15 +77,15 @@ export const { store, useAtomicProp, useEmit, StoreProvider } = createYoltra({
77
77
  ### 2. Use the hooks — no provider required
78
78
 
79
79
  The hooks default to the store above, so you can render components directly. Subscribe with a
80
- **typed accessor**: `s` autocompletes your state shape and the return type is inferred.
80
+ **`{ reducer, property }`** spec: the dotted `property` names the exact path to read.
81
81
 
82
82
  ```tsx
83
83
  // Counter.tsx
84
84
  import { useAtomicProp, useEmit } from "./yoltra";
85
85
 
86
86
  export function Counter() {
87
- // Typed accessor — re-renders only when counter.value changes. No selectors, no memo.
88
- const value = useAtomicProp("counter", (s) => s.value);
87
+ // Object form — re-renders only when counter.value changes. No selectors, no memo.
88
+ const value = useAtomicProp({ reducer: "counter", property: "value" });
89
89
  const emit = useEmit();
90
90
 
91
91
  return (
@@ -121,8 +121,17 @@ export const AppStoreContext = createContext<StoreInstance<"counter", AppState,
121
121
  null,
122
122
  );
123
123
 
124
- export const { useStore, useEmit, useSelector, useAtomicProp, useAtomicProps, useEvent, shallowEqual } =
125
- createHooks(AppStoreContext);
124
+ export const {
125
+ useStore,
126
+ useEmit,
127
+ useSelector,
128
+ useAtomicProp,
129
+ useAtomicProps,
130
+ useEvent,
131
+ useSuspenseAtomicProp,
132
+ useSuspenseAtomicProps,
133
+ shallowEqual,
134
+ } = createHooks(AppStoreContext);
126
135
  ```
127
136
 
128
137
  Provide the store with `<AppStoreContext.Provider value={store}>` at your root.
@@ -131,21 +140,17 @@ Provide the store with `<AppStoreContext.Provider value={store}>` at your root.
131
140
 
132
141
  ## Hooks API
133
142
 
134
- ### `useAtomicProp(reducer, accessor)` — or `useAtomicProp({ reducer, property }, map?, isEqual?)`
143
+ ### `useAtomicProp({ reducer, property }, map?, isEqual?)`
135
144
 
136
- Fine-grained single-path selector. Re-renders only when the specified leaf changes. Prefer the
137
- **typed accessor** form — it autocompletes the state shape and infers the return type; use the
138
- string form for dynamic or wildcard paths.
145
+ Fine-grained single-path selector. Re-renders only when the specified leaf changes. The dotted
146
+ `property` names the exact path — including dynamic (`` `items.${id}.title` ``) and wildcard paths.
139
147
 
140
148
  ```tsx
141
- // Typed accessor (recommended) — autocompletes items[0].title, infers string
142
- const title = useAtomicProp("todos", (s) => s.items[0].title);
149
+ // Object form (recommended) — subscribe to the exact path
150
+ const title = useAtomicProp({ reducer: "todos", property: "items.0.title" });
143
151
 
144
- // String form — same subscription, for dynamic paths
145
- const sameTitle = useAtomicProp({
146
- reducer: "todos",
147
- property: "items.0.title",
148
- });
152
+ // Dynamic path — interpolate the key
153
+ const byId = useAtomicProp({ reducer: "todos", property: `items.${id}.title` });
149
154
 
150
155
  // With mapper — derive a value from the path
151
156
  const count = useAtomicProp({ reducer: "todos", property: "items" }, (items) => items.length);
@@ -158,6 +163,9 @@ const allTitles = useAtomicProp(
158
163
  );
159
164
  ```
160
165
 
166
+ > A typed-accessor overload — `useAtomicProp("todos", (s) => s.items[0].title)` — is also available
167
+ > for static paths; it autocompletes the state shape and infers the return type.
168
+
161
169
  **Supported patterns:**
162
170
 
163
171
  - `"items.0.title"` — exact path (including numeric array indices)
@@ -249,9 +257,19 @@ Returns the store instance. Throws if called outside a provider.
249
257
 
250
258
  ```tsx
251
259
  const store = useStore();
252
- const state = store.getState();
260
+
261
+ // ✅ In a callback or an effect: read the value at the moment it is wanted.
262
+ const onSave = () => save(store.getState());
263
+
264
+ // ❌ In the render body: this subscribes to nothing.
265
+ const value = store.getState().counter.value;
253
266
  ```
254
267
 
268
+ `getState()` is a read, not a subscription. Called while rendering, the component renders once
269
+ with that value and never again — nothing told it the value moved. It looks like it works right
270
+ up until the state changes and the screen does not. Read what you render with `useAtomicProp` or
271
+ `useSelector`, and keep `getState()` for callbacks and effects, which is what it is for.
272
+
255
273
  ---
256
274
 
257
275
  ## Suspense Hooks
@@ -293,6 +311,26 @@ const stats = useSuspenseAtomicProps(
293
311
  );
294
312
  ```
295
313
 
314
+ ### Import them from your hook set, not the barrel
315
+
316
+ `createYoltra` and `createHooks` return these two alongside the rest, bound to the same context.
317
+ They are deliberately **not** exported from the package barrel: a package-level copy would be
318
+ identical in shape and still throw `useStore must be used inside <StoreProvider>` at runtime
319
+ whenever the context it reads was never filled — a mistake the types could not catch. Importing
320
+ them from anywhere but your own `createYoltra`/`createHooks` result is now a compile error,
321
+ which is the same warning arriving at the right time.
322
+
323
+ ```tsx
324
+ // store.ts
325
+ export const { store, useAtomicProp, useSuspenseAtomicProp } = createYoltra({ ... });
326
+
327
+ // Forecast.tsx
328
+ import { useSuspenseAtomicProp } from "./store"; // ✅ knows the store
329
+ ```
330
+
331
+ Cached values are scoped per store, so two stores sharing a reducer name and path keep separate
332
+ entries; the invalidation helpers below take a path and clear it in every store that cached it.
333
+
296
334
  ### Cache utilities
297
335
 
298
336
  ```typescript
@@ -374,10 +412,10 @@ function TodoItem({ index }: { index: number }) {
374
412
  ## Examples
375
413
 
376
414
  - **[Todo App with Profiler](../../examples/v0/yoltra-in-react)** — Full CRUD with flamegraph
377
- comparison
415
+ comparison · [▶ Open the live demo](https://yoltra.dev/en/demos/in-react)
378
416
  - **[Kinetic Logo (3000 particles)](../../examples/v0/yoltra-kinetic-logo)** — Independent
379
- subscriptions per circle
380
- - **[Next.js (Pages Router)](../../examples/v0/yoltra-in-nextjs)** — client-side state + theme switcher
417
+ subscriptions per circle · [▶ Open the live demo](https://yoltra.dev/en/demos/kinetic-logo)
418
+ - **[Next.js (Pages Router)](../../examples/v0/yoltra-in-nextjs)** — client-side state + theme switcher · [▶ Open the live demo](https://yoltra.dev/en/demos/in-nextjs)
381
419
 
382
420
  ---
383
421
 
@@ -408,6 +446,25 @@ v1.0.0.
408
446
 
409
447
  ---
410
448
 
449
+ ## Normalised collections
450
+
451
+ `useEntityIds`, `useEntity` and `useEntityField` pair with `createEntityAdapter` from
452
+ `@yoltra/core`. They are thin wrappers over `useAtomicProp`; the value is that the path comes
453
+ from the adapter rather than being typed into a component, where nothing checks it.
454
+
455
+ ```tsx
456
+ function List() {
457
+ const ids = useEntityIds('todos', todos);
458
+ return <>{ids.map((id) => <Row key={id} id={id} />)}</>;
459
+ }
460
+
461
+ function Row({ id }: { id: string }) {
462
+ // Wakes when this title changes, and not when any other row does.
463
+ const title = useEntityField('todos', todos, id, 'title');
464
+ return <li>{title}</li>;
465
+ }
466
+ ```
467
+
411
468
  ## License
412
469
 
413
470
  **MIT** — Free to use in commercial and open-source projects.
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @yoltra/react v0.2.0
2
+ * @yoltra/react v0.4.0
3
3
  * (c) 2026 Manu Ramirez <@pixerael>
4
4
  * License: MIT
5
5
  * Homepage: https://yoltra.dev
@@ -7,10 +7,26 @@
7
7
  * This source code is licensed under the MIT license found in the
8
8
  * LICENSE file in the root directory of this source tree
9
9
  */
10
- "use strict";var be=Object.defineProperty;var ve=(t,e,n)=>e in t?be(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var oe=(t,e,n)=>ve(t,typeof e!="symbol"?e+"":e,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react"),he=require("@yoltra/core"),H=c.createContext(null);var z={exports:{}},D={};var se;function Re(){if(se)return D;se=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function n(o,s,u){var m=null;if(u!==void 0&&(m=""+u),s.key!==void 0&&(m=""+s.key),"key"in s){u={};for(var y in s)y!=="key"&&(u[y]=s[y])}else u=s;return s=u.ref,{$$typeof:t,type:o,key:m,ref:s!==void 0?s:null,props:u}}return D.Fragment=e,D.jsx=n,D.jsxs=n,D}var F={};var ce;function Ee(){return ce||(ce=1,process.env.NODE_ENV!=="production"&&(function(){function t(r){if(r==null)return null;if(typeof r=="function")return r.$$typeof===Z?null:r.displayName||r.name||null;if(typeof r=="string")return r;switch(r){case R:return"Fragment";case P:return"Profiler";case v:return"StrictMode";case M:return"Suspense";case g:return"SuspenseList";case T:return"Activity"}if(typeof r=="object")switch(typeof r.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),r.$$typeof){case b:return"Portal";case N:return(r.displayName||"Context")+".Provider";case k:return(r._context.displayName||"Context")+".Consumer";case $:var i=r.render;return r=r.displayName,r||(r=i.displayName||i.name||"",r=r!==""?"ForwardRef("+r+")":"ForwardRef"),r;case w:return i=r.displayName||null,i!==null?i:t(r.type)||"Memo";case W:i=r._payload,r=r._init;try{return t(r(i))}catch{}}return null}function e(r){return""+r}function n(r){try{e(r);var i=!1}catch{i=!0}if(i){i=console;var S=i.error,E=typeof Symbol=="function"&&Symbol.toStringTag&&r[Symbol.toStringTag]||r.constructor.name||"Object";return S.call(i,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",E),e(r)}}function o(r){if(r===R)return"<>";if(typeof r=="object"&&r!==null&&r.$$typeof===W)return"<...>";try{var i=t(r);return i?"<"+i+">":"<...>"}catch{return"<...>"}}function s(){var r=Y.A;return r===null?null:r.getOwner()}function u(){return Error("react-stack-top-frame")}function m(r){if(Q.call(r,"key")){var i=Object.getOwnPropertyDescriptor(r,"key").get;if(i&&i.isReactWarning)return!1}return r.key!==void 0}function y(r,i){function S(){K||(K=!0,console.error("%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)",i))}S.isReactWarning=!0,Object.defineProperty(r,"key",{get:S,configurable:!0})}function h(){var r=t(this.type);return ee[r]||(ee[r]=!0,console.error("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.")),r=this.props.ref,r!==void 0?r:null}function a(r,i,S,E,j,x,J,q){return S=x.ref,r={$$typeof:p,type:r,key:i,props:x,_owner:j},(S!==void 0?S:null)!==null?Object.defineProperty(r,"ref",{enumerable:!1,get:h}):Object.defineProperty(r,"ref",{enumerable:!1,value:null}),r._store={},Object.defineProperty(r._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(r,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(r,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:J}),Object.defineProperty(r,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:q}),Object.freeze&&(Object.freeze(r.props),Object.freeze(r)),r}function l(r,i,S,E,j,x,J,q){var A=i.children;if(A!==void 0)if(E)if(ye(A)){for(E=0;E<A.length;E++)d(A[E]);Object.freeze&&Object.freeze(A)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else d(A);if(Q.call(i,"key")){A=t(r);var I=Object.keys(i).filter(function(Se){return Se!=="key"});E=0<I.length?"{key: someKey, "+I.join(": ..., ")+": ...}":"{key: someKey}",ne[A+E]||(I=0<I.length?"{"+I.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
10
+ "use strict";var Ee=Object.defineProperty;var Re=(t,e,n)=>e in t?Ee(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var ue=(t,e,n)=>Re(t,typeof e!="symbol"?e+"":e,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react"),Ae=require("@yoltra/core"),K=c.createContext(null);var W={exports:{}},D={};/**
11
+ * @license React
12
+ * react-jsx-runtime.production.js
13
+ *
14
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
15
+ *
16
+ * This source code is licensed under the MIT license found in the
17
+ * LICENSE file in the root directory of this source tree.
18
+ */var ce;function Pe(){if(ce)return D;ce=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function n(o,s,u){var a=null;if(u!==void 0&&(a=""+u),s.key!==void 0&&(a=""+s.key),"key"in s){u={};for(var h in s)h!=="key"&&(u[h]=s[h])}else u=s;return s=u.ref,{$$typeof:t,type:o,key:a,ref:s!==void 0?s:null,props:u}}return D.Fragment=e,D.jsx=n,D.jsxs=n,D}var F={};/**
19
+ * @license React
20
+ * react-jsx-runtime.development.js
21
+ *
22
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
23
+ *
24
+ * This source code is licensed under the MIT license found in the
25
+ * LICENSE file in the root directory of this source tree.
26
+ */var ae;function ge(){return ae||(ae=1,process.env.NODE_ENV!=="production"&&(function(){function t(r){if(r==null)return null;if(typeof r=="function")return r.$$typeof===V?null:r.displayName||r.name||null;if(typeof r=="string")return r;switch(r){case S:return"Fragment";case k:return"Profiler";case b:return"StrictMode";case $:return"Suspense";case I:return"SuspenseList";case O:return"Activity"}if(typeof r=="object")switch(typeof r.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),r.$$typeof){case v:return"Portal";case P:return(r.displayName||"Context")+".Provider";case _:return(r._context.displayName||"Context")+".Consumer";case j:var i=r.render;return r=r.displayName,r||(r=i.displayName||i.name||"",r=r!==""?"ForwardRef("+r+")":"ForwardRef"),r;case M:return i=r.displayName||null,i!==null?i:t(r.type)||"Memo";case A:i=r._payload,r=r._init;try{return t(r(i))}catch{}}return null}function e(r){return""+r}function n(r){try{e(r);var i=!1}catch{i=!0}if(i){i=console;var p=i.error,E=typeof Symbol=="function"&&Symbol.toStringTag&&r[Symbol.toStringTag]||r.constructor.name||"Object";return p.call(i,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",E),e(r)}}function o(r){if(r===S)return"<>";if(typeof r=="object"&&r!==null&&r.$$typeof===A)return"<...>";try{var i=t(r);return i?"<"+i+">":"<...>"}catch{return"<...>"}}function s(){var r=x.A;return r===null?null:r.getOwner()}function u(){return Error("react-stack-top-frame")}function a(r){if(B.call(r,"key")){var i=Object.getOwnPropertyDescriptor(r,"key").get;if(i&&i.isReactWarning)return!1}return r.key!==void 0}function h(r,i){function p(){te||(te=!0,console.error("%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)",i))}p.isReactWarning=!0,Object.defineProperty(r,"key",{get:p,configurable:!0})}function y(){var r=t(this.type);return re[r]||(re[r]=!0,console.error("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.")),r=this.props.ref,r!==void 0?r:null}function g(r,i,p,E,C,w,X,H){return p=w.ref,r={$$typeof:f,type:r,key:i,props:w,_owner:C},(p!==void 0?p:null)!==null?Object.defineProperty(r,"ref",{enumerable:!1,get:y}):Object.defineProperty(r,"ref",{enumerable:!1,value:null}),r._store={},Object.defineProperty(r._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(r,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(r,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:X}),Object.defineProperty(r,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:H}),Object.freeze&&(Object.freeze(r.props),Object.freeze(r)),r}function d(r,i,p,E,C,w,X,H){var R=i.children;if(R!==void 0)if(E)if(J(R)){for(E=0;E<R.length;E++)l(R[E]);Object.freeze&&Object.freeze(R)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else l(R);if(B.call(i,"key")){R=t(r);var Y=Object.keys(i).filter(function(be){return be!=="key"});E=0<Y.length?"{key: someKey, "+Y.join(": ..., ")+": ...}":"{key: someKey}",se[R+E]||(Y=0<Y.length?"{"+Y.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
11
27
  let props = %s;
12
28
  <%s {...props} />
13
29
  React keys must be passed directly to JSX without using spread:
14
30
  let props = %s;
15
- <%s key={someKey} {...props} />`,E,A,I,A),ne[A+E]=!0)}if(A=null,S!==void 0&&(n(S),A=""+S),m(i)&&(n(i.key),A=""+i.key),"key"in i){S={};for(var B in i)B!=="key"&&(S[B]=i[B])}else S=i;return A&&y(S,typeof r=="function"?r.displayName||r.name||"Unknown":r),a(r,A,x,j,s(),S,J,q)}function d(r){typeof r=="object"&&r!==null&&r.$$typeof===p&&r._store&&(r._store.validated=1)}var f=c,p=Symbol.for("react.transitional.element"),b=Symbol.for("react.portal"),R=Symbol.for("react.fragment"),v=Symbol.for("react.strict_mode"),P=Symbol.for("react.profiler"),k=Symbol.for("react.consumer"),N=Symbol.for("react.context"),$=Symbol.for("react.forward_ref"),M=Symbol.for("react.suspense"),g=Symbol.for("react.suspense_list"),w=Symbol.for("react.memo"),W=Symbol.for("react.lazy"),T=Symbol.for("react.activity"),Z=Symbol.for("react.client.reference"),Y=f.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,Q=Object.prototype.hasOwnProperty,ye=Array.isArray,U=console.createTask?console.createTask:function(){return null};f={react_stack_bottom_frame:function(r){return r()}};var K,ee={},re=f.react_stack_bottom_frame.bind(f,u)(),te=U(o(u)),ne={};F.Fragment=R,F.jsx=function(r,i,S,E,j){var x=1e4>Y.recentlyCreatedOwnerStacks++;return l(r,i,S,!1,E,j,x?Error("react-stack-top-frame"):re,x?U(o(r)):te)},F.jsxs=function(r,i,S,E,j){var x=1e4>Y.recentlyCreatedOwnerStacks++;return l(r,i,S,!0,E,j,x?Error("react-stack-top-frame"):re,x?U(o(r)):te)}})()),F}var ue;function Ae(){return ue||(ue=1,process.env.NODE_ENV==="production"?z.exports=Re():z.exports=Ee()),z.exports}var ie=Ae();const Pe=({store:t,children:e})=>ie.jsx(H.Provider,{value:t,children:e}),ae=new Set;function ge(t,e){process.env.NODE_ENV!=="production"&&(ae.has(t)||(ae.add(t),console.warn(e)))}function V(t){return t.includes("*")}function _(t){return t.replace(/^\./,"")}function _e(t){return _(t).split(".").filter(Boolean)}function le(t){const e=n=>`${n.length}:${n}`;return t.map(n=>{const o=Array.isArray(n.property)?n.property:[n.property];return e(n.reducer)+e(String(o.length))+o.map(e).join("")}).join("")}const fe=Symbol("yoltra.pathSegments");function pe(t){const e=()=>{};return new Proxy(e,{get(n,o){if(o===fe)return t;if(typeof o!="symbol")return pe([...t,String(o)])},apply(){throw new Error(`[yoltra] A typed path accessor called a method (near "${t.join(".")}"). The accessor must be a plain member chain like \`p => p.items[0].title\` — it cannot call functions such as \`.map()\` or \`.toString()\`. Compute derived values in the component or a selector, or use the \`{ reducer, property }\` string form.`)}})}function ke(t){const e=t(pe([])),n=e!=null?e[fe]:void 0,s=(Array.isArray(n)?n:[]).join(".");return s===""&&ge("yoltra.toDottedPath.empty","[yoltra] A typed path accessor recorded no property access, so it will subscribe to the entire slice. The accessor must be a plain member chain like `p => p.items[0].title` and cannot return a computed value or a default. For a whole-slice or dynamic subscription, use the `{ reducer, property }` string form instead."),s}function G(t,e){if(!e)return t;let n=t;for(const o of _e(e)){if(n==null)return;n=n[o]}return n}function L(t,e,n){const o=c.useRef(t);o.current=t;const s=c.useRef(e);s.current=e;const u=c.useMemo(()=>({has:!1,value:void 0}),n);return c.useCallback(()=>{const m=o.current();return(!u.has||!s.current(u.value,m))&&(u.has=!0,u.value=m),u.value},[u])}function me(t,e){if(Object.is(t,e))return!0;if(!t||!e)return!1;const n=Object.keys(t),o=Object.keys(e);if(n.length!==o.length)return!1;for(const s of n)if(!Object.is(t[s],e[s]))return!1;return!0}function C(){const t=c.useContext(H);if(!t)throw new Error("useStore must be used inside <StoreProvider>");return t}function xe(){return C().emit}function we(t,e=Object.is){const n=C(),o=c.useMemo(()=>u=>n.subscribe(u),[n]),s=L(()=>t(n.getState()),e,[n]);return c.useSyncExternalStore(o,s,s)}function Te(t,e,n=Object.is){const o=C(),s=c.useMemo(()=>{const h=_(t.property);return{reducer:t.reducer,property:h}},[t.reducer,t.property]),u=c.useMemo(()=>h=>o.connect({reducer:s.reducer,property:s.property},()=>h()),[o,s]),m=V(s.property),y=L(()=>{const a=o.getState()[s.reducer],l=m?a:G(a,s.property);return e?e(l):l},n,[o,s]);return c.useSyncExternalStore(u,y,y)}function je(t,e,n=Object.is){return Te(t,e,n)}function Oe(t,e,n=Object.is){return Ce(t,e,n)}function Ce(t,e,n=Object.is){const o=C(),s=c.useRef(0),u=c.useRef(void 0),m=c.useRef(-1),y=c.useRef(!1),h=c.useRef(e);h.current=e;const a=c.useRef(n);a.current=n;const l=c.useMemo(()=>t.map(p=>({reducer:p.reducer,property:Array.isArray(p.property)?p.property.map(b=>_(b)):_(p.property)})),[le(t)]),d=c.useMemo(()=>p=>{const b=()=>{s.current++,p()},R=l.flatMap(v=>(Array.isArray(v.property)?v.property:[v.property]).map(k=>o.connect({reducer:v.reducer,property:k},b)));return()=>{for(const v of R)v()}},[o,l]),f=c.useCallback(()=>{if(m.current!==s.current||!y.current){const p=h.current(o.getState());(!y.current||!a.current(u.current,p))&&(u.current=p,y.current=!0),m.current=s.current}return u.current},[o]);return c.useSyncExternalStore(d,f,f)}function Me(t,e,n,o="committed"){const s=C(),u=c.useRef(n);u.current=n,c.useEffect(()=>s.onEvent(t,e,(m,y,h,a)=>{u.current(m,y,h,a)},o),[s,t,e,o])}function Ne(t){return t==null||t<=0?null:Date.now()+t}class $e{constructor(){oe(this,"store",new Map)}read(e,n,o){const s=Date.now(),u=this.store.get(e);if(u&&u.status==="ready"&&(u.expiresAt==null||u.expiresAt>s))return u.value;if(u&&u.status==="pending")throw u.promise;if(u&&u.status==="error")throw u.error;const m=Promise.resolve().then(n).then(y=>{this.store.set(e,{status:"ready",value:y,expiresAt:Ne(o)})}).catch(y=>{this.store.set(e,{status:"error",error:y,expiresAt:null})});throw this.store.set(e,{status:"pending",promise:m,expiresAt:null}),m}invalidate(e){this.store.delete(e)}invalidatePrefix(e){for(const n of this.store.keys())n.startsWith(e)&&this.store.delete(n)}clear(){this.store.clear()}}const O=new $e;function X(t,e,n){const o=Array.isArray(e)?e.map(_).sort().join("|"):_(e);return n?`${t}::${o}::${n}`:`${t}::${o}`}function Ie(t,e){return Ye(t,e)}function Ye(t,e){const n=C(),o=t.reducer,s=_(t.property),u=X(o,s,e.key),m=c.useMemo(()=>l=>n.connect({reducer:o,property:s},()=>{O.invalidate(u),l()}),[n,o,s,u]),y=c.useRef(e);y.current=e;const h=c.useMemo(()=>{const l=V(s);return()=>{var R;const f=n.getState()[o],p=l?f:G(f,s),b=y.current;return O.read(u,()=>b.load(p,f),(R=b.staleTime)!=null?R:0)}},[n,o,s,u]),a=c.useMemo(()=>{const l=V(s);return()=>{const f=n.getState()[o];return l?f:G(f,s)}},[n,o,s]);return c.useSyncExternalStore(m,h,a)}function De(t,e){return Fe(t,e)}function Fe(t,e){const n=C(),o=c.useMemo(()=>t.map(a=>({reducer:a.reducer,property:Array.isArray(a.property)?a.property.map(l=>_(l)):_(a.property)})),[JSON.stringify(t)]),s=c.useMemo(()=>{const a=o.map(l=>X(l.reducer,l.property)).sort().join("||");return e.key?`${a}::${e.key}`:a},[o,e.key]),u=c.useMemo(()=>a=>{const l=()=>{O.invalidate(s),a()},d=o.map(f=>n.connect(f,l));return()=>{for(const f of d)f()}},[n,o,s]),m=c.useRef(e);m.current=e;const y=c.useMemo(()=>()=>{var d;const a=n.getState(),l=m.current;return O.read(s,()=>l.load(a),(d=l.staleTime)!=null?d:0)},[n,s]),h=()=>{const a=m.current.load(n.getState());return a instanceof Promise?void 0:a};return c.useSyncExternalStore(u,y,h)}function We(t,e,n){O.invalidate(X(t,e,n))}function ze(t){O.invalidatePrefix(`${t}::`)}function Ve(){O.clear()}function de(t){function e(){const a=c.useContext(t);if(!a)throw new Error("[yoltra] No store in context. Wrap your tree in <StoreProvider store={...}>, or use the hooks returned by createYoltra (which default to their own store).");return a}function n(){return e().emit}function o(a,l=Object.is){const d=e(),f=c.useMemo(()=>b=>d.subscribe(b),[d]),p=L(()=>a(d.getState()),l,[d]);return c.useSyncExternalStore(f,p,p)}return{useStore:e,useEmit:n,useSelector:o,useAtomicProp:(a,l,d)=>{const f=e(),p=typeof a=="string",b=p?a:a.reducer,R=p?ke(l):a.property,v=p?void 0:l,P=c.useMemo(()=>({reducer:b,property:_(R)}),[b,R]),k=c.useMemo(()=>M=>f.connect({reducer:P.reducer,property:P.property},()=>M()),[f,P]),N=V(P.property),$=L(()=>{const g=f.getState()[P.reducer],w=N?g:G(g,P.property);return v?v(w):w},d!=null?d:Object.is,[f,P]);return c.useSyncExternalStore(k,$,$)},useAtomicProps:(a,l,d=Object.is)=>{const f=e(),p=c.useRef(0),b=c.useRef(void 0),R=c.useRef(-1),v=c.useRef(!1),P=c.useRef(l);P.current=l;const k=c.useRef(d);k.current=d;const N=c.useMemo(()=>a.map(g=>({reducer:g.reducer,property:Array.isArray(g.property)?g.property.map(w=>_(w)):_(g.property)})),[le(a)]),$=c.useMemo(()=>g=>{const w=()=>{p.current++,g()},W=N.flatMap(T=>(Array.isArray(T.property)?T.property:[T.property]).map(Y=>f.connect({reducer:T.reducer,property:Y},w)));return()=>{for(const T of W)T()}},[f,N]),M=c.useCallback(()=>{if(R.current!==p.current||!v.current){const g=P.current(f.getState());(!v.current||!k.current(b.current,g))&&(b.current=g,v.current=!0),R.current=p.current}return b.current},[f]);return c.useSyncExternalStore($,M,M)},useEvent:(a,l,d,f="committed")=>{const p=e(),b=c.useRef(d);b.current=d,c.useEffect(()=>p.onEvent(a,l,(R,v,P,k)=>{b.current(R,v,P,k)},f),[p,a,l,f])},shallowEqual:me}}function Ge(t){const e=he.createStore(t),n=c.createContext(e),o=de(n);return{store:e,StoreContext:n,StoreProvider:({store:u,children:m})=>ie.jsx(n.Provider,{value:u!=null?u:e,children:m}),...o}}exports.StoreContext=H;exports.StoreProvider=Pe;exports.clearSuspenseCache=Ve;exports.createHooks=de;exports.createYoltra=Ge;exports.invalidateAtomicProp=We;exports.invalidateAtomicPropsByReducer=ze;exports.shallowEqual=me;exports.suspenseCache=O;exports.useAtomicProp=je;exports.useAtomicProps=Oe;exports.useEmit=xe;exports.useEvent=Me;exports.useSelector=we;exports.useStore=C;exports.useSuspenseAtomicProp=Ie;exports.useSuspenseAtomicProps=De;
31
+ <%s key={someKey} {...props} />`,E,R,Y,R),se[R+E]=!0)}if(R=null,p!==void 0&&(n(p),R=""+p),a(i)&&(n(i.key),R=""+i.key),"key"in i){p={};for(var Z in i)Z!=="key"&&(p[Z]=i[Z])}else p=i;return R&&h(p,typeof r=="function"?r.displayName||r.name||"Unknown":r),g(r,R,w,C,s(),p,X,H)}function l(r){typeof r=="object"&&r!==null&&r.$$typeof===f&&r._store&&(r._store.validated=1)}var m=c,f=Symbol.for("react.transitional.element"),v=Symbol.for("react.portal"),S=Symbol.for("react.fragment"),b=Symbol.for("react.strict_mode"),k=Symbol.for("react.profiler"),_=Symbol.for("react.consumer"),P=Symbol.for("react.context"),j=Symbol.for("react.forward_ref"),$=Symbol.for("react.suspense"),I=Symbol.for("react.suspense_list"),M=Symbol.for("react.memo"),A=Symbol.for("react.lazy"),O=Symbol.for("react.activity"),V=Symbol.for("react.client.reference"),x=m.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,B=Object.prototype.hasOwnProperty,J=Array.isArray,q=console.createTask?console.createTask:function(){return null};m={react_stack_bottom_frame:function(r){return r()}};var te,re={},ne=m.react_stack_bottom_frame.bind(m,u)(),oe=q(o(u)),se={};F.Fragment=S,F.jsx=function(r,i,p,E,C){var w=1e4>x.recentlyCreatedOwnerStacks++;return d(r,i,p,!1,E,C,w?Error("react-stack-top-frame"):ne,w?q(o(r)):oe)},F.jsxs=function(r,i,p,E,C){var w=1e4>x.recentlyCreatedOwnerStacks++;return d(r,i,p,!0,E,C,w?Error("react-stack-top-frame"):ne,w?q(o(r)):oe)}})()),F}var ie;function _e(){return ie||(ie=1,process.env.NODE_ENV==="production"?W.exports=Pe():W.exports=ge()),W.exports}var de=_e();const xe=({store:t,children:e})=>de.jsx(K.Provider,{value:t,children:e}),le=new Set;function we(t,e){process.env.NODE_ENV!=="production"&&(le.has(t)||(le.add(t),console.warn(e)))}function G(t){return t.includes("*")}function T(t){return t.replace(/^\./,"")}function Te(t){return T(t).split(".").filter(Boolean)}function ke(t){const e=n=>`${n.length}:${n}`;return t.map(n=>{const o=Array.isArray(n.property)?n.property:[n.property];return e(n.reducer)+e(String(o.length))+o.map(e).join("")}).join("")}const me=Symbol("yoltra.pathSegments");function he(t){const e=()=>{};return new Proxy(e,{get(n,o){if(o===me)return t;if(typeof o!="symbol")return he([...t,String(o)])},apply(){throw new Error(`[yoltra] A typed path accessor called a method (near "${t.join(".")}"). The accessor must be a plain member chain like \`p => p.items[0].title\` — it cannot call functions such as \`.map()\` or \`.toString()\`. Compute derived values in the component or a selector, or use the \`{ reducer, property }\` string form.`)}})}function je(t){const e=t(he([])),n=e!=null?e[me]:void 0,s=(Array.isArray(n)?n:[]).join(".");return s===""&&we("yoltra.toDottedPath.empty","[yoltra] A typed path accessor recorded no property access, so it will subscribe to the entire slice. The accessor must be a plain member chain like `p => p.items[0].title` and cannot return a computed value or a default. For a whole-slice or dynamic subscription, use the `{ reducer, property }` string form instead."),s}function L(t,e){if(!e)return t;let n=t;for(const o of Te(e)){if(n==null)return;n=n[o]}return n}function U(t,e,n){const o=c.useRef(t);o.current=t;const s=c.useRef(e);s.current=e;const u=c.useMemo(()=>({has:!1,value:void 0}),n);return c.useCallback(()=>{const a=o.current();return(!u.has||!s.current(u.value,a))&&(u.has=!0,u.value=a),u.value},[u])}function Se(t,e){if(Object.is(t,e))return!0;if(!t||!e)return!1;const n=Object.keys(t),o=Object.keys(e);if(n.length!==o.length)return!1;for(const s of n)if(!Object.is(t[s],e[s]))return!1;return!0}function z(){const t=c.useContext(K);if(!t)throw new Error("useStore must be used inside <StoreProvider>");return t}function Oe(){return z().emit}function Ce(t,e=Object.is){const n=z(),o=c.useMemo(()=>u=>n.subscribe(u),[n]),s=U(()=>t(n.getState()),e,[n]);return c.useSyncExternalStore(o,s,s)}function Ne(t,e,n=Object.is){const o=z(),s=c.useMemo(()=>{const y=T(t.property);return{reducer:t.reducer,property:y}},[t.reducer,t.property]),u=c.useMemo(()=>y=>o.connect({reducer:s.reducer,property:s.property},()=>y()),[o,s]),a=G(s.property),h=U(()=>{const g=o.getState()[s.reducer];return a?g:L(g,s.property)},n,[o,s]);return c.useSyncExternalStore(u,h,h)}function Q(t,e,n=Object.is){return Ne(t,e,n)}function Me(t,e,n,o="committed"){const s=z(),u=c.useRef(n);u.current=n,c.useEffect(()=>s.onEvent(t,e,(a,h,y,g)=>{u.current(a,h,y,g)},o),[s,t,e,o])}function $e(t){return t==null||t<=0?null:Date.now()+t}function Ie(t){return t===null?null:t===void 0||t<=0?0:Date.now()+t}const Ye=2e3;class De{constructor(){ue(this,"store",new Map)}touch(e){this.store.has(e)&&this.store.delete(e)}evict(){for(;this.store.size>Ye;){const e=this.store.keys().next();if(e.done===!0)return;const n=this.store.get(e.value);if((n==null?void 0:n.status)==="pending"){this.store.delete(e.value),this.store.set(e.value,n);continue}this.store.delete(e.value)}}get size(){return this.store.size}read(e,n,o,s){const u=Date.now(),a=this.store.get(e);if(a&&a.status==="ready"&&(a.expiresAt==null||a.expiresAt>u))return this.touch(e),this.store.set(e,a),a.value;if(a&&a.status==="pending")throw a.promise;if(a&&a.status==="error"){if(a.delivered!==!0)throw this.store.set(e,{...a,delivered:!0}),a.error;if(a.expiresAt===null||a.expiresAt>u)throw a.error;this.store.delete(e)}const h=Promise.resolve().then(n).then(y=>{this.store.set(e,{status:"ready",value:y,expiresAt:$e(o)})}).catch(y=>{this.store.set(e,{status:"error",error:y,expiresAt:Ie(s)})});throw this.store.set(e,{status:"pending",promise:h,expiresAt:null}),this.evict(),h}invalidate(e){this.store.delete(e)}invalidatePathKey(e){for(const n of this.store.keys())pe(n)===e&&this.store.delete(n)}invalidateReducer(e){const n=`${e}::`;for(const o of this.store.keys())pe(o).split("||").some(s=>s.startsWith(n))&&this.store.delete(o)}clear(){this.store.clear()}}const N=new De,fe=new WeakMap;let Fe=0;function ye(t){let e=fe.get(t);return e===void 0&&(e=`s${++Fe}`,fe.set(t,e)),e}function pe(t){return t.slice(t.indexOf("::")+2)}function ee(t,e,n){const o=Array.isArray(e)?e.map(T).sort().join("|"):T(e);return n?`${t}::${o}::${n}`:`${t}::${o}`}function ze(t,e,n){const o=t(),s=e.reducer,u=T(e.property),a=`${ye(o)}::${ee(s,u,n.key)}`,h=c.useMemo(()=>l=>o.connect({reducer:s,property:u},()=>{N.invalidate(a),l()}),[o,s,u,a]),y=c.useRef(n);y.current=n;const g=c.useMemo(()=>{const l=G(u);return()=>{var b;const f=o.getState()[s],v=l?f:L(f,u),S=y.current;return N.read(a,()=>S.load(v,f),(b=S.staleTime)!=null?b:0,S.errorTtlMs)}},[o,s,u,a]),d=c.useMemo(()=>{const l=G(u);return()=>{const f=o.getState()[s];return l?f:L(f,u)}},[o,s,u]);return c.useSyncExternalStore(h,g,d)}function We(t,e,n){const o=t(),s=c.useMemo(()=>e.map(d=>({reducer:d.reducer,property:Array.isArray(d.property)?d.property.map(l=>T(l)):T(d.property)})),[JSON.stringify(e)]),u=c.useMemo(()=>{const d=s.map(l=>ee(l.reducer,l.property)).sort().join("||");return`${ye(o)}::${n.key?`${d}::${n.key}`:d}`},[o,s,n.key]),a=c.useMemo(()=>d=>{const l=()=>{N.invalidate(u),d()},m=s.map(f=>o.connect(f,l));return()=>{for(const f of m)f()}},[o,s,u]),h=c.useRef(n);h.current=n;const y=c.useMemo(()=>()=>{var m;const d=o.getState(),l=h.current;return N.read(u,()=>l.load(d),(m=l.staleTime)!=null?m:0,l.errorTtlMs)},[o,u]),g=()=>{const d=h.current.load(o.getState());return d instanceof Promise?void 0:d};return c.useSyncExternalStore(a,y,g)}function Ge(t,e,n){N.invalidatePathKey(ee(t,e,n))}function Le(t){N.invalidateReducer(t)}function Ue(){N.clear()}function Ve(t){return{useSuspenseAtomicProp:(o,s)=>ze(t,o,s),useSuspenseAtomicProps:(o,s)=>We(t,o,s)}}function ve(t){function e(){const l=c.useContext(t);if(!l)throw new Error("[yoltra] No store in context. Wrap your tree in <StoreProvider store={...}>, or use the hooks returned by createYoltra (which default to their own store).");return l}function n(){return e().emit}function o(l,m=Object.is){const f=e(),v=c.useMemo(()=>b=>f.subscribe(b),[f]),S=U(()=>l(f.getState()),m,[f]);return c.useSyncExternalStore(v,S,S)}const u=(l,m,f)=>{const v=e(),S=typeof l=="string",b=S?l:l.reducer,k=S?je(m):l.property,_=S?void 0:m,P=c.useMemo(()=>({reducer:b,property:T(k)}),[b,k]),j=c.useMemo(()=>M=>v.connect({reducer:P.reducer,property:P.property},()=>M()),[v,P]),$=G(P.property),I=U(()=>{const A=v.getState()[P.reducer],O=$?A:L(A,P.property);return _?_(O):O},f!=null?f:Object.is,[v,P]);return c.useSyncExternalStore(j,I,I)},h=(l,m,f=Object.is)=>{const v=e(),S=c.useRef(0),b=c.useRef(void 0),k=c.useRef(-1),_=c.useRef(!1),P=c.useRef(m);P.current=m;const j=c.useRef(f);j.current=f;const $=c.useMemo(()=>l.map(A=>({reducer:A.reducer,property:Array.isArray(A.property)?A.property.map(O=>T(O)):T(A.property)})),[ke(l)]),I=c.useMemo(()=>A=>{const O=()=>{S.current++,A()},V=$.flatMap(x=>(Array.isArray(x.property)?x.property:[x.property]).map(J=>v.connect({reducer:x.reducer,property:J},O)));return()=>{for(const x of V)x()}},[v,$]),M=c.useCallback(()=>{if(k.current!==S.current||!_.current){const A=P.current(v.getState());(!_.current||!j.current(b.current,A))&&(b.current=A,_.current=!0),k.current=S.current}return b.current},[v]);return c.useSyncExternalStore(I,M,M)},y=(l,m,f,v="committed")=>{const S=e(),b=c.useRef(f);b.current=f,c.useEffect(()=>S.onEvent(l,m,(k,_,P,j)=>{b.current(k,_,P,j)},v),[S,l,m,v])},{useSuspenseAtomicProp:g,useSuspenseAtomicProps:d}=Ve(e);return{useStore:e,useEmit:n,useSelector:o,useAtomicProp:u,useAtomicProps:h,useEvent:y,useSuspenseAtomicProp:g,useSuspenseAtomicProps:d,shallowEqual:Se}}function Be(t){const e=Ae.createStore(t),n=c.createContext(e),o=ve(n);return{store:e,StoreContext:n,StoreProvider:({store:u,children:a})=>de.jsx(n.Provider,{value:u!=null?u:e,children:a}),...o}}function Je(t,e){return Q({reducer:t,property:e.idsPath})}function qe(t,e,n){return Q({reducer:t,property:e.pathTo(n)})}function Xe(t,e,n,o){return Q({reducer:t,property:e.pathTo(n,o)})}exports.StoreContext=K;exports.StoreProvider=xe;exports.clearSuspenseCache=Ue;exports.createHooks=ve;exports.createYoltra=Be;exports.invalidateAtomicProp=Ge;exports.invalidateAtomicPropsByReducer=Le;exports.shallowEqual=Se;exports.suspenseCache=N;exports.useEmit=Oe;exports.useEntity=qe;exports.useEntityField=Xe;exports.useEntityIds=Je;exports.useEvent=Me;exports.useSelector=Ce;exports.useStore=z;
16
32
  //# sourceMappingURL=index.cjs.map