@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.
- package/LICENSE +0 -0
- package/README.es.md +63 -58
- package/README.md +61 -60
- package/dist/index.cjs +6 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +483 -453
- package/dist/index.mjs.map +1 -1
- package/dist/types/createYoltra.d.ts +79 -0
- package/dist/types/hooks/createHooks.d.ts +27 -19
- package/dist/types/hooks/hooks.d.ts +1 -16
- package/dist/types/hooks/suspense.d.ts +24 -2
- package/dist/types/index.d.ts +3 -1
- package/dist/types/utils/shallowEqual.d.ts +19 -0
- package/dist/types/utils/useStableSnapshot.d.ts +4 -0
- package/package.json +15 -16
package/LICENSE
CHANGED
|
File without changes
|
package/README.es.md
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
# @yoltra/react
|
|
4
4
|
|
|
5
5
|
> π π²π½ VersiΓ³n en EspaΓ±ol |
|
|
6
|
-
> [ πΊπΈ English Version](
|
|
6
|
+
> [ πΊπΈ English Version](./README.md)
|
|
7
7
|
|
|
8
8
|

|
|
9
9
|

|
|
10
10
|
|
|
11
|
-
**Hooks de React para [yoltra](
|
|
11
|
+
**Hooks de React para [yoltra](../../README.md) con
|
|
12
12
|
suscripciones de grano fino por ruta.**
|
|
13
13
|
|
|
14
14
|
Suscribete a `"items.0.title"` o `"items.*.done"` -- el componente se re-renderiza solo cuando
|
|
@@ -28,24 +28,24 @@ npm install @yoltra/core @yoltra/react
|
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
31
|
-
## Configuracion con `
|
|
31
|
+
## Configuracion con `createYoltra` (recomendado)
|
|
32
32
|
|
|
33
|
-
`
|
|
34
|
-
|
|
33
|
+
`createYoltra` crea el store **y** todos los hooks tipados en una sola llamada β sin archivo de
|
|
34
|
+
context aparte, sin cableado de `createHooks`, sin provider obligatorio. Todos los parametros de
|
|
35
|
+
tipo se infieren de tu reducer, asi que los componentes no necesitan generics explicitos.
|
|
35
36
|
|
|
36
|
-
### 1.
|
|
37
|
+
### 1. Crea el store y los hooks
|
|
37
38
|
|
|
38
|
-
```
|
|
39
|
-
//
|
|
40
|
-
import {
|
|
39
|
+
```tsx
|
|
40
|
+
// yoltra.ts
|
|
41
|
+
import { eventKeys } from "@yoltra/core";
|
|
42
|
+
import { createYoltra } from "@yoltra/react";
|
|
41
43
|
|
|
42
44
|
export type AppEM = {
|
|
43
45
|
counter: { increment: number; decrement: number; reset: null };
|
|
44
46
|
};
|
|
45
47
|
|
|
46
|
-
export
|
|
47
|
-
|
|
48
|
-
export const store = createStore<AppState, AppEM>({
|
|
48
|
+
export const { store, useAtomicProp, useEmit, StoreProvider } = createYoltra({
|
|
49
49
|
name: "App",
|
|
50
50
|
reducer: {
|
|
51
51
|
counter: {
|
|
@@ -74,38 +74,18 @@ export const store = createStore<AppState, AppEM>({
|
|
|
74
74
|
});
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
### 2.
|
|
77
|
+
### 2. Usa los hooks β sin provider
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
import { createHooks } from "@yoltra/react";
|
|
83
|
-
import type { StoreInstance } from "@yoltra/core";
|
|
84
|
-
import type { AppState, AppEM } from "./store";
|
|
85
|
-
|
|
86
|
-
export const AppStoreContext = createContext<StoreInstance<"counter", AppState, AppEM> | null>(
|
|
87
|
-
null,
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
export const {
|
|
91
|
-
useStore,
|
|
92
|
-
useEmit,
|
|
93
|
-
useSelector,
|
|
94
|
-
useAtomicProp,
|
|
95
|
-
useAtomicProps,
|
|
96
|
-
useEvent,
|
|
97
|
-
shallowEqual,
|
|
98
|
-
} = createHooks(AppStoreContext);
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### 3. Proveer y usar
|
|
79
|
+
Los hooks usan por defecto el store de arriba, asi que puedes renderizar componentes directamente.
|
|
80
|
+
Suscribete con una spec **`{ reducer, property }`**: el `property` con puntos nombra la ruta exacta
|
|
81
|
+
a leer.
|
|
102
82
|
|
|
103
83
|
```tsx
|
|
104
|
-
//
|
|
105
|
-
import {
|
|
106
|
-
import { AppStoreContext, useAtomicProp, useEmit } from "./hooks";
|
|
84
|
+
// Counter.tsx
|
|
85
|
+
import { useAtomicProp, useEmit } from "./yoltra";
|
|
107
86
|
|
|
108
|
-
function Counter() {
|
|
87
|
+
export function Counter() {
|
|
88
|
+
// Forma objeto β se re-renderiza solo cuando counter.value cambia. Sin selectores, sin memo.
|
|
109
89
|
const value = useAtomicProp({ reducer: "counter", property: "value" });
|
|
110
90
|
const emit = useEmit();
|
|
111
91
|
|
|
@@ -118,30 +98,52 @@ function Counter() {
|
|
|
118
98
|
</div>
|
|
119
99
|
);
|
|
120
100
|
}
|
|
101
|
+
```
|
|
121
102
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
103
|
+
Un `<StoreProvider>` solo se necesita para acotar una instancia **diferente** del store a un
|
|
104
|
+
subarbol (p. ej. un store nuevo por test) β `createYoltra` devuelve uno justo para eso.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Avanzado: cableado manual con `createHooks`
|
|
109
|
+
|
|
110
|
+
Cuando necesites un mismo conjunto de hooks compartido entre varias instancias de store a traves
|
|
111
|
+
de tu propio context de React, vinculalos tu mismo con `createHooks(context)`. `createYoltra` es
|
|
112
|
+
este mismo cableado colapsado en una sola llamada.
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// hooks.ts
|
|
116
|
+
import { createContext } from "react";
|
|
117
|
+
import { createHooks } from "@yoltra/react";
|
|
118
|
+
import type { StoreInstance } from "@yoltra/core";
|
|
119
|
+
import type { AppState, AppEM } from "./store";
|
|
120
|
+
|
|
121
|
+
export const AppStoreContext = createContext<StoreInstance<"counter", AppState, AppEM> | null>(
|
|
122
|
+
null,
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
export const { useStore, useEmit, useSelector, useAtomicProp, useAtomicProps, useEvent, shallowEqual } =
|
|
126
|
+
createHooks(AppStoreContext);
|
|
129
127
|
```
|
|
130
128
|
|
|
129
|
+
Provee el store con `<AppStoreContext.Provider value={store}>` en tu raiz.
|
|
130
|
+
|
|
131
131
|
---
|
|
132
132
|
|
|
133
133
|
## API de Hooks
|
|
134
134
|
|
|
135
135
|
### `useAtomicProp({ reducer, property }, map?, isEqual?)`
|
|
136
136
|
|
|
137
|
-
Selector de ruta unica con grano fino. Se re-renderiza solo cuando la
|
|
137
|
+
Selector de ruta unica con grano fino. Se re-renderiza solo cuando la hoja especificada cambia. El
|
|
138
|
+
`property` con puntos nombra la ruta exacta β incluyendo rutas dinamicas
|
|
139
|
+
(`` `items.${id}.title` ``) y con comodines.
|
|
138
140
|
|
|
139
141
|
```tsx
|
|
140
|
-
//
|
|
141
|
-
const title = useAtomicProp({
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
});
|
|
142
|
+
// Forma objeto (recomendada) β suscribete a la ruta exacta
|
|
143
|
+
const title = useAtomicProp({ reducer: "todos", property: "items.0.title" });
|
|
144
|
+
|
|
145
|
+
// Ruta dinamica β interpola la clave
|
|
146
|
+
const byId = useAtomicProp({ reducer: "todos", property: `items.${id}.title` });
|
|
145
147
|
|
|
146
148
|
// Con mapper β derivar un valor de la ruta
|
|
147
149
|
const count = useAtomicProp({ reducer: "todos", property: "items" }, (items) => items.length);
|
|
@@ -154,6 +156,9 @@ const allTitles = useAtomicProp(
|
|
|
154
156
|
);
|
|
155
157
|
```
|
|
156
158
|
|
|
159
|
+
> Tambien existe una sobrecarga con accessor tipado β `useAtomicProp("todos", (s) => s.items[0].title)`
|
|
160
|
+
> β para rutas estaticas; autocompleta la forma del estado e infiere el tipo de retorno.
|
|
161
|
+
|
|
157
162
|
**Patrones soportados:**
|
|
158
163
|
|
|
159
164
|
- `"items.0.title"` -- ruta exacta (incluyendo indices numericos de array)
|
|
@@ -372,18 +377,18 @@ function TodoItem({ index }: { index: number }) {
|
|
|
372
377
|
## Ejemplos
|
|
373
378
|
|
|
374
379
|
- **[App de Tareas con Profiler](../../examples/v0/yoltra-in-react)** -- CRUD completo con
|
|
375
|
-
comparacion de flamegraph
|
|
380
|
+
comparacion de flamegraph Β· [βΆ Abrir la demo en vivo](https://yoltra.dev/es/demos/in-react)
|
|
376
381
|
- **[Logo Cinetico (3000 particulas)](../../examples/v0/yoltra-kinetic-logo)** -- Suscripciones
|
|
377
|
-
independientes por circulo SVG
|
|
378
|
-
- **[Next.js
|
|
382
|
+
independientes por circulo SVG Β· [βΆ Abrir la demo en vivo](https://yoltra.dev/es/demos/kinetic-logo)
|
|
383
|
+
- **[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)
|
|
379
384
|
|
|
380
385
|
---
|
|
381
386
|
|
|
382
387
|
## Documentacion
|
|
383
388
|
|
|
384
|
-
- **[README raiz de yoltra](
|
|
389
|
+
- **[README raiz de yoltra](../../README.md)** --
|
|
385
390
|
Descripcion general y configuracion rapida
|
|
386
|
-
- **[API de @yoltra/core](
|
|
391
|
+
- **[API de @yoltra/core](../core/README.md)**
|
|
387
392
|
-- Store, middleware, efectos, matchers `When`
|
|
388
393
|
- **[Guia de Inicio Rapido](https://github.com/yoltra/yoltra/blob/main/docs/en/QUICK_START_GUIDE.md)**
|
|
389
394
|
-- Cinco pasos hacia una app funcional
|
package/README.md
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
# @yoltra/react
|
|
4
4
|
|
|
5
|
-
> [ π²π½ VersiΓ³n en EspaΓ±ol](
|
|
5
|
+
> [ π²π½ VersiΓ³n en EspaΓ±ol](./README.es.md)
|
|
6
6
|
> | π πΊπΈ English Version
|
|
7
7
|
|
|
8
8
|

|
|
9
9
|

|
|
10
10
|
|
|
11
|
-
**React hooks for [yoltra](
|
|
11
|
+
**React hooks for [yoltra](../../README.md) with
|
|
12
12
|
fine-grained path subscriptions.**
|
|
13
13
|
|
|
14
14
|
Subscribe to `"items.0.title"` or `"items.*.done"` β the component re-renders only when that
|
|
@@ -28,24 +28,24 @@ npm install @yoltra/core @yoltra/react
|
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
31
|
-
## Setup with `
|
|
31
|
+
## Setup with `createYoltra` (recommended)
|
|
32
32
|
|
|
33
|
-
`
|
|
34
|
-
no
|
|
33
|
+
`createYoltra` creates the store **and** every fully-typed hook in one call β no separate context
|
|
34
|
+
file, no `createHooks` wiring, no required provider. All type parameters are inferred from your
|
|
35
|
+
reducer, so components need no explicit generics.
|
|
35
36
|
|
|
36
|
-
### 1.
|
|
37
|
+
### 1. Create the store and hooks
|
|
37
38
|
|
|
38
|
-
```
|
|
39
|
-
//
|
|
40
|
-
import {
|
|
39
|
+
```tsx
|
|
40
|
+
// yoltra.ts
|
|
41
|
+
import { eventKeys } from "@yoltra/core";
|
|
42
|
+
import { createYoltra } from "@yoltra/react";
|
|
41
43
|
|
|
42
44
|
export type AppEM = {
|
|
43
45
|
counter: { increment: number; decrement: number; reset: null };
|
|
44
46
|
};
|
|
45
47
|
|
|
46
|
-
export
|
|
47
|
-
|
|
48
|
-
export const store = createStore<AppState, AppEM>({
|
|
48
|
+
export const { store, useAtomicProp, useEmit, StoreProvider } = createYoltra({
|
|
49
49
|
name: "App",
|
|
50
50
|
reducer: {
|
|
51
51
|
counter: {
|
|
@@ -74,40 +74,17 @@ export const store = createStore<AppState, AppEM>({
|
|
|
74
74
|
});
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
### 2.
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
// hooks.ts
|
|
81
|
-
import { createContext } from "react";
|
|
82
|
-
|
|
83
|
-
import { createHooks } from "@yoltra/react";
|
|
84
|
-
import type { StoreInstance } from "@yoltra/core";
|
|
85
|
-
|
|
86
|
-
import type { AppState, AppEM } from "./store";
|
|
77
|
+
### 2. Use the hooks β no provider required
|
|
87
78
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
export const {
|
|
93
|
-
useStore,
|
|
94
|
-
useEmit,
|
|
95
|
-
useSelector,
|
|
96
|
-
useAtomicProp,
|
|
97
|
-
useAtomicProps,
|
|
98
|
-
useEvent,
|
|
99
|
-
shallowEqual,
|
|
100
|
-
} = createHooks(AppStoreContext);
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### 3. Provide and use
|
|
79
|
+
The hooks default to the store above, so you can render components directly. Subscribe with a
|
|
80
|
+
**`{ reducer, property }`** spec: the dotted `property` names the exact path to read.
|
|
104
81
|
|
|
105
82
|
```tsx
|
|
106
|
-
//
|
|
107
|
-
import {
|
|
108
|
-
import { AppStoreContext, useAtomicProp, useEmit } from "./hooks";
|
|
83
|
+
// Counter.tsx
|
|
84
|
+
import { useAtomicProp, useEmit } from "./yoltra";
|
|
109
85
|
|
|
110
|
-
function Counter() {
|
|
86
|
+
export function Counter() {
|
|
87
|
+
// Object form β re-renders only when counter.value changes. No selectors, no memo.
|
|
111
88
|
const value = useAtomicProp({ reducer: "counter", property: "value" });
|
|
112
89
|
const emit = useEmit();
|
|
113
90
|
|
|
@@ -120,30 +97,51 @@ function Counter() {
|
|
|
120
97
|
</div>
|
|
121
98
|
);
|
|
122
99
|
}
|
|
100
|
+
```
|
|
123
101
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
102
|
+
A `<StoreProvider>` is only needed to scope a **different** store instance to a subtree (e.g. a
|
|
103
|
+
fresh store per test) β `createYoltra` returns one for exactly that.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Advanced: manual wiring with `createHooks`
|
|
108
|
+
|
|
109
|
+
When you need one set of hooks shared across several store instances through your own React
|
|
110
|
+
context, bind them yourself with `createHooks(context)`. `createYoltra` is this same wiring
|
|
111
|
+
collapsed into a single call.
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// hooks.ts
|
|
115
|
+
import { createContext } from "react";
|
|
116
|
+
import { createHooks } from "@yoltra/react";
|
|
117
|
+
import type { StoreInstance } from "@yoltra/core";
|
|
118
|
+
import type { AppState, AppEM } from "./store";
|
|
119
|
+
|
|
120
|
+
export const AppStoreContext = createContext<StoreInstance<"counter", AppState, AppEM> | null>(
|
|
121
|
+
null,
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
export const { useStore, useEmit, useSelector, useAtomicProp, useAtomicProps, useEvent, shallowEqual } =
|
|
125
|
+
createHooks(AppStoreContext);
|
|
131
126
|
```
|
|
132
127
|
|
|
128
|
+
Provide the store with `<AppStoreContext.Provider value={store}>` at your root.
|
|
129
|
+
|
|
133
130
|
---
|
|
134
131
|
|
|
135
132
|
## Hooks API
|
|
136
133
|
|
|
137
134
|
### `useAtomicProp({ reducer, property }, map?, isEqual?)`
|
|
138
135
|
|
|
139
|
-
Fine-grained single-path selector. Re-renders only when the specified
|
|
136
|
+
Fine-grained single-path selector. Re-renders only when the specified leaf changes. The dotted
|
|
137
|
+
`property` names the exact path β including dynamic (`` `items.${id}.title` ``) and wildcard paths.
|
|
140
138
|
|
|
141
139
|
```tsx
|
|
142
|
-
//
|
|
143
|
-
const title = useAtomicProp({
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
});
|
|
140
|
+
// Object form (recommended) β subscribe to the exact path
|
|
141
|
+
const title = useAtomicProp({ reducer: "todos", property: "items.0.title" });
|
|
142
|
+
|
|
143
|
+
// Dynamic path β interpolate the key
|
|
144
|
+
const byId = useAtomicProp({ reducer: "todos", property: `items.${id}.title` });
|
|
147
145
|
|
|
148
146
|
// With mapper β derive a value from the path
|
|
149
147
|
const count = useAtomicProp({ reducer: "todos", property: "items" }, (items) => items.length);
|
|
@@ -156,6 +154,9 @@ const allTitles = useAtomicProp(
|
|
|
156
154
|
);
|
|
157
155
|
```
|
|
158
156
|
|
|
157
|
+
> A typed-accessor overload β `useAtomicProp("todos", (s) => s.items[0].title)` β is also available
|
|
158
|
+
> for static paths; it autocompletes the state shape and infers the return type.
|
|
159
|
+
|
|
159
160
|
**Supported patterns:**
|
|
160
161
|
|
|
161
162
|
- `"items.0.title"` β exact path (including numeric array indices)
|
|
@@ -372,18 +373,18 @@ function TodoItem({ index }: { index: number }) {
|
|
|
372
373
|
## Examples
|
|
373
374
|
|
|
374
375
|
- **[Todo App with Profiler](../../examples/v0/yoltra-in-react)** β Full CRUD with flamegraph
|
|
375
|
-
comparison
|
|
376
|
+
comparison Β· [βΆ Open the live demo](https://yoltra.dev/en/demos/in-react)
|
|
376
377
|
- **[Kinetic Logo (3000 particles)](../../examples/v0/yoltra-kinetic-logo)** β Independent
|
|
377
|
-
subscriptions per circle
|
|
378
|
-
- **[Next.js
|
|
378
|
+
subscriptions per circle Β· [βΆ Open the live demo](https://yoltra.dev/en/demos/kinetic-logo)
|
|
379
|
+
- **[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)
|
|
379
380
|
|
|
380
381
|
---
|
|
381
382
|
|
|
382
383
|
## Documentation
|
|
383
384
|
|
|
384
|
-
- **[yoltra Root README](
|
|
385
|
+
- **[yoltra Root README](../../README.md)** β Overview and
|
|
385
386
|
quick start
|
|
386
|
-
- **[@yoltra/core API](
|
|
387
|
+
- **[@yoltra/core API](../core/README.md)** β
|
|
387
388
|
Store, middleware, effects, `When` matchers
|
|
388
389
|
- **[Quick Start Guide](https://github.com/yoltra/yoltra/blob/main/docs/en/QUICK_START_GUIDE.md)**
|
|
389
390
|
β Five steps to a working app
|
package/dist/index.cjs
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @yoltra/react v0.
|
|
2
|
+
* @yoltra/react v0.3.0
|
|
3
3
|
* (c) 2026 Manu Ramirez <@pixerael>
|
|
4
4
|
* License: MIT
|
|
5
5
|
* Homepage: https://yoltra.dev
|
|
6
|
+
*
|
|
7
|
+
* This source code is licensed under the MIT license found in the
|
|
8
|
+
* LICENSE file in the root directory of this source tree
|
|
6
9
|
*/
|
|
7
|
-
"use strict";var
|
|
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:
|
|
8
11
|
let props = %s;
|
|
9
12
|
<%s {...props} />
|
|
10
13
|
React keys must be passed directly to JSX without using spread:
|
|
11
14
|
let props = %s;
|
|
12
|
-
<%s key={someKey} {...props} />`,A,
|
|
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;
|
|
13
16
|
//# sourceMappingURL=index.cjs.map
|