storion 0.8.3 → 0.10.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/CHANGELOG.md +127 -21
- package/README.md +42 -2021
- package/dist/async/abortable.d.ts +295 -0
- package/dist/async/abortable.d.ts.map +1 -0
- package/dist/async/async.d.ts +86 -5
- package/dist/async/async.d.ts.map +1 -1
- package/dist/async/context.d.ts +15 -0
- package/dist/async/context.d.ts.map +1 -0
- package/dist/async/index.d.ts +16 -3
- package/dist/async/index.d.ts.map +1 -1
- package/dist/async/index.js +407 -137
- package/dist/async/safe.d.ts +221 -0
- package/dist/async/safe.d.ts.map +1 -0
- package/dist/async/types.d.ts +77 -29
- package/dist/async/types.d.ts.map +1 -1
- package/dist/async/wrappers.d.ts +217 -0
- package/dist/async/wrappers.d.ts.map +1 -0
- package/dist/core/effect.d.ts +34 -26
- package/dist/core/effect.d.ts.map +1 -1
- package/dist/core/equality.d.ts +25 -0
- package/dist/core/equality.d.ts.map +1 -1
- package/dist/core/focus.d.ts +20 -0
- package/dist/core/focus.d.ts.map +1 -0
- package/dist/core/focusHelpers.d.ts +258 -0
- package/dist/core/focusHelpers.d.ts.map +1 -0
- package/dist/core/middleware.d.ts +4 -4
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/storeContext.d.ts +2 -9
- package/dist/core/storeContext.d.ts.map +1 -1
- package/dist/dev.d.ts +0 -10
- package/dist/dev.d.ts.map +1 -1
- package/dist/{index-C8B6Mo8r.js → effect-BDQU8Voz.js} +1241 -583
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/network/index.d.ts +69 -0
- package/dist/network/index.d.ts.map +1 -0
- package/dist/network/retry.d.ts +53 -0
- package/dist/network/retry.d.ts.map +1 -0
- package/dist/network/services.d.ts +58 -0
- package/dist/network/services.d.ts.map +1 -0
- package/dist/network/store.d.ts +36 -0
- package/dist/network/store.d.ts.map +1 -0
- package/dist/network/utils.d.ts +9 -0
- package/dist/network/utils.d.ts.map +1 -0
- package/dist/persist/index.d.ts +1 -1
- package/dist/persist/index.d.ts.map +1 -1
- package/dist/persist/index.js +55 -31
- package/dist/persist/persist.d.ts +119 -62
- package/dist/persist/persist.d.ts.map +1 -1
- package/dist/pool.d.ts +77 -0
- package/dist/pool.d.ts.map +1 -0
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +245 -244
- package/dist/react/stable.d.ts +27 -0
- package/dist/react/stable.d.ts.map +1 -0
- package/dist/react/useStore.d.ts +38 -13
- package/dist/react/useStore.d.ts.map +1 -1
- package/dist/react/withStore.d.ts.map +1 -1
- package/dist/storion.js +911 -37
- package/dist/trigger.d.ts +12 -7
- package/dist/trigger.d.ts.map +1 -1
- package/dist/types.d.ts +133 -22
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/storeTuple.d.ts +7 -0
- package/dist/utils/storeTuple.d.ts.map +1 -0
- package/package.json +5 -1
- package/dist/collection.d.ts +0 -34
- package/dist/collection.d.ts.map +0 -1
- package/dist/core/proxy.d.ts +0 -47
- package/dist/core/proxy.d.ts.map +0 -1
- package/dist/effect-C6h0PDDI.js +0 -446
- package/dist/isPromiseLike-bFkfHAbm.js +0 -6
- package/dist/react/useLocalStore.d.ts +0 -48
- package/dist/react/useLocalStore.d.ts.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,31 +8,122 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
|
+
|
|
12
|
+
- `SelectorContext.scoped()` for component-local stores that auto-dispose on unmount
|
|
13
|
+
```tsx
|
|
14
|
+
const { value, setValue } = useStore(({ scoped }) => {
|
|
15
|
+
const [state, actions, instance] = scoped(formStore);
|
|
16
|
+
return { value: state.value, setValue: actions.setValue };
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
- `async.mixin()` for component-local async state (mutations, form submissions)
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
// Define mutation - no store needed
|
|
23
|
+
const submitForm = async.mixin(async (ctx, data: FormData) => {
|
|
24
|
+
const res = await fetch("/api/submit", {
|
|
25
|
+
method: "POST",
|
|
26
|
+
body: JSON.stringify(data),
|
|
27
|
+
signal: ctx.signal,
|
|
28
|
+
});
|
|
29
|
+
return res.json();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Use as mixin - state is component-local, auto-disposed
|
|
33
|
+
const { status, submit } = useStore(({ mixin }) => {
|
|
34
|
+
const [state, actions] = mixin(submitForm);
|
|
35
|
+
return { status: state.status, submit: actions.dispatch };
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- `AsyncContext.get()` allows async handlers to access other stores' state
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
// Access other stores for cross-store mutations
|
|
43
|
+
const checkout = async.mixin(async (ctx, paymentMethod: string) => {
|
|
44
|
+
const [user] = ctx.get(userStore);
|
|
45
|
+
const [cart] = ctx.get(cartStore);
|
|
46
|
+
return fetch("/api/checkout", {
|
|
47
|
+
body: JSON.stringify({ userId: user.id, items: cart.items }),
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
11
52
|
- `MetaEntry.fields` now supports arrays for applying meta to multiple fields at once
|
|
12
53
|
```ts
|
|
13
|
-
meta: [notPersisted.for(["password", "token"])]
|
|
54
|
+
meta: [notPersisted.for(["password", "token"])];
|
|
14
55
|
```
|
|
15
56
|
- `MetaQuery.fields(type, predicate?)` method to get field names with a specific meta type
|
|
16
57
|
```ts
|
|
17
|
-
const sessionFields = ctx.meta.fields(sessionStore);
|
|
18
|
-
const highPriority = ctx.meta.fields(priority, v => v > 5);
|
|
19
|
-
```
|
|
20
|
-
- `persistMiddleware` `fields` option for multi-storage patterns
|
|
21
|
-
```ts
|
|
22
|
-
// Split fields between session and local storage
|
|
23
|
-
persistMiddleware({
|
|
24
|
-
filter: ({ meta }) => meta.any(sessionStore),
|
|
25
|
-
fields: ({ meta }) => meta.fields(sessionStore),
|
|
26
|
-
save: (ctx, state) => sessionStorage.setItem(ctx.displayName, JSON.stringify(state)),
|
|
27
|
-
})
|
|
58
|
+
const sessionFields = ctx.meta.fields(sessionStore); // ['token', 'userId']
|
|
59
|
+
const highPriority = ctx.meta.fields(priority, (v) => v > 5);
|
|
28
60
|
```
|
|
29
61
|
- `applyFor` now supports object form to map patterns to different middleware
|
|
30
62
|
```ts
|
|
31
63
|
applyFor({
|
|
32
|
-
|
|
64
|
+
userStore: loggingMiddleware,
|
|
33
65
|
"auth*": [authMiddleware, securityMiddleware],
|
|
34
66
|
"*Cache": cacheMiddleware,
|
|
35
|
-
})
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Removed
|
|
71
|
+
|
|
72
|
+
- **BREAKING**: `useLocalStore` hook removed - use `scoped()` in `useStore` selector instead
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
// Before
|
|
76
|
+
const [state, actions] = useLocalStore(formStore);
|
|
77
|
+
|
|
78
|
+
// After
|
|
79
|
+
const { state, actions } = useStore(({ scoped }) => {
|
|
80
|
+
const [s, a] = scoped(formStore);
|
|
81
|
+
return { state: s, actions: a };
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- **BREAKING**: `SelectorContext.create()` removed - creates uncontrolled instances without disposal tracking. Use `get()` for cached services or `scoped()` for component-local stores instead.
|
|
86
|
+
|
|
87
|
+
### Changed
|
|
88
|
+
|
|
89
|
+
- **BREAKING**: `persist` API refactored for better encapsulation (renamed from `persistMiddleware`)
|
|
90
|
+
|
|
91
|
+
- New `handler` option replaces `load`/`save` callbacks
|
|
92
|
+
- `persistMiddleware` is now deprecated, use `persist` instead
|
|
93
|
+
- Handler receives `PersistContext` (extends `StoreMiddlewareContext` with `store` instance)
|
|
94
|
+
- Handler returns `{ load, save }` object (can be sync or async)
|
|
95
|
+
- `onError` signature changed to `(error, operation)` where operation is `"init" | "load" | "save"`
|
|
96
|
+
- Enables encapsulated async initialization (e.g., IndexedDB)
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
// Before (old API)
|
|
100
|
+
persistMiddleware({
|
|
101
|
+
load: (ctx) => localStorage.getItem(ctx.displayName),
|
|
102
|
+
save: (ctx, state) =>
|
|
103
|
+
localStorage.setItem(ctx.displayName, JSON.stringify(state)),
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// After (new API)
|
|
107
|
+
persist({
|
|
108
|
+
handler: (ctx) => {
|
|
109
|
+
const key = `app:${ctx.displayName}`;
|
|
110
|
+
return {
|
|
111
|
+
load: () => JSON.parse(localStorage.getItem(key) || "null"),
|
|
112
|
+
save: (state) => localStorage.setItem(key, JSON.stringify(state)),
|
|
113
|
+
};
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Async handler (IndexedDB)
|
|
118
|
+
persist({
|
|
119
|
+
handler: async (ctx) => {
|
|
120
|
+
const db = await openDB("app-db");
|
|
121
|
+
return {
|
|
122
|
+
load: () => db.get("stores", ctx.displayName),
|
|
123
|
+
save: (state) => db.put("stores", state, ctx.displayName),
|
|
124
|
+
};
|
|
125
|
+
},
|
|
126
|
+
});
|
|
36
127
|
```
|
|
37
128
|
|
|
38
129
|
---
|
|
@@ -40,8 +131,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
40
131
|
## [0.8.0] - 2024-12-21
|
|
41
132
|
|
|
42
133
|
### Added
|
|
134
|
+
|
|
43
135
|
- **Persist Module** (`storion/persist`)
|
|
44
|
-
- `
|
|
136
|
+
- `persist(options)` for automatic state persistence
|
|
45
137
|
- `notPersisted` meta for excluding stores or fields from persistence
|
|
46
138
|
- Supports sync and async `load`/`save` handlers
|
|
47
139
|
- `force` option to override dirty state during hydration
|
|
@@ -58,6 +150,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
58
150
|
- `store.hydrate(state, { force })` - force option to override dirty properties
|
|
59
151
|
|
|
60
152
|
### Changed
|
|
153
|
+
|
|
61
154
|
- `StoreMiddlewareContext` now includes `meta` property for querying store metadata
|
|
62
155
|
- `FactoryMiddlewareContext` now includes `meta` property for querying factory metadata
|
|
63
156
|
|
|
@@ -66,6 +159,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
66
159
|
## [0.7.0] - 2024-12-15
|
|
67
160
|
|
|
68
161
|
### Added
|
|
162
|
+
|
|
69
163
|
- **DevTools Module** (`storion/devtools`)
|
|
70
164
|
- `devtoolsMiddleware()` for state inspection
|
|
71
165
|
- `__revertState` and `__takeSnapshot` injected actions
|
|
@@ -79,6 +173,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
79
173
|
- `create()` shorthand for single-store apps returning `[instance, useHook, withStore]`
|
|
80
174
|
|
|
81
175
|
### Changed
|
|
176
|
+
|
|
82
177
|
- Improved TypeScript inference for store actions
|
|
83
178
|
|
|
84
179
|
---
|
|
@@ -86,6 +181,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
86
181
|
## [0.6.0] - 2024-12-01
|
|
87
182
|
|
|
88
183
|
### Added
|
|
184
|
+
|
|
89
185
|
- **Async Module** (`storion/async`)
|
|
90
186
|
- `async.fresh<T>()` - throws during loading (Suspense-compatible)
|
|
91
187
|
- `async.stale<T>(initialData)` - returns stale data during loading
|
|
@@ -95,6 +191,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
95
191
|
- `trigger(action, deps, ...args)` for declarative data fetching in components
|
|
96
192
|
|
|
97
193
|
### Changed
|
|
194
|
+
|
|
98
195
|
- Effects now require synchronous functions (use `ctx.safe()` for async)
|
|
99
196
|
|
|
100
197
|
---
|
|
@@ -102,6 +199,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
102
199
|
## [0.5.0] - 2024-11-15
|
|
103
200
|
|
|
104
201
|
### Added
|
|
202
|
+
|
|
105
203
|
- **Focus (Lens-like Access)**
|
|
106
204
|
- `focus(path)` for nested state access
|
|
107
205
|
- Returns `[getter, setter]` tuple
|
|
@@ -119,6 +217,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
119
217
|
## [0.4.0] - 2024-11-01
|
|
120
218
|
|
|
121
219
|
### Added
|
|
220
|
+
|
|
122
221
|
- **Middleware System**
|
|
123
222
|
- `container({ middleware: [...] })` for middleware injection
|
|
124
223
|
- Middleware receives `MiddlewareContext` with `type`, `next`, `resolver`
|
|
@@ -127,6 +226,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
127
226
|
- `createValidationMiddleware()` built-in middleware
|
|
128
227
|
|
|
129
228
|
### Changed
|
|
229
|
+
|
|
130
230
|
- Container now uses middleware chain pattern
|
|
131
231
|
|
|
132
232
|
---
|
|
@@ -134,6 +234,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
134
234
|
## [0.3.0] - 2024-10-15
|
|
135
235
|
|
|
136
236
|
### Added
|
|
237
|
+
|
|
137
238
|
- **Store Lifecycle**
|
|
138
239
|
- `lifetime: "keepAlive"` (default) - persists until container disposal
|
|
139
240
|
- `lifetime: "autoDispose"` - disposes when no subscribers
|
|
@@ -145,6 +246,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
145
246
|
- `store.reset()` to restore initial state
|
|
146
247
|
|
|
147
248
|
### Changed
|
|
249
|
+
|
|
148
250
|
- Stores now track dirty state automatically
|
|
149
251
|
|
|
150
252
|
---
|
|
@@ -152,6 +254,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
152
254
|
## [0.2.0] - 2024-10-01
|
|
153
255
|
|
|
154
256
|
### Added
|
|
257
|
+
|
|
155
258
|
- **Dependency Injection**
|
|
156
259
|
- `container()` for managing store instances
|
|
157
260
|
- `get(factory)` for resolving dependencies
|
|
@@ -161,6 +264,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
161
264
|
- `useContainer()` hook
|
|
162
265
|
|
|
163
266
|
### Changed
|
|
267
|
+
|
|
164
268
|
- Stores are now lazily instantiated via container
|
|
165
269
|
|
|
166
270
|
---
|
|
@@ -168,6 +272,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
168
272
|
## [0.1.0] - 2024-09-15
|
|
169
273
|
|
|
170
274
|
### Added
|
|
275
|
+
|
|
171
276
|
- **Core Store**
|
|
172
277
|
- `store(options)` factory function
|
|
173
278
|
- `state` - reactive state object
|
|
@@ -195,22 +300,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
195
300
|
### Migrating to 0.8.0
|
|
196
301
|
|
|
197
302
|
#### Meta System Changes
|
|
303
|
+
|
|
198
304
|
If you were using internal meta APIs, update to the new public API:
|
|
199
305
|
|
|
200
306
|
```ts
|
|
201
307
|
// Before (internal)
|
|
202
|
-
spec.meta // was MetaEntry[]
|
|
308
|
+
spec.meta; // was MetaEntry[]
|
|
203
309
|
|
|
204
310
|
// After (0.8.0)
|
|
205
|
-
ctx.meta(persistMeta).store
|
|
206
|
-
ctx.meta(persistMeta).fields
|
|
207
|
-
ctx.meta.all(type)
|
|
208
|
-
ctx.meta.any(type1, type2)
|
|
311
|
+
ctx.meta(persistMeta).store; // query store-level
|
|
312
|
+
ctx.meta(persistMeta).fields; // query field-level
|
|
313
|
+
ctx.meta.all(type); // get all values
|
|
314
|
+
ctx.meta.any(type1, type2); // check existence
|
|
209
315
|
```
|
|
210
316
|
|
|
211
317
|
### Migrating to 0.6.0
|
|
212
318
|
|
|
213
319
|
#### Async Effects
|
|
320
|
+
|
|
214
321
|
Effects must now be synchronous:
|
|
215
322
|
|
|
216
323
|
```ts
|
|
@@ -239,4 +346,3 @@ effect((ctx) => {
|
|
|
239
346
|
[0.3.0]: https://github.com/linq2js/storion/compare/v0.2.0...v0.3.0
|
|
240
347
|
[0.2.0]: https://github.com/linq2js/storion/compare/v0.1.0...v0.2.0
|
|
241
348
|
[0.1.0]: https://github.com/linq2js/storion/releases/tag/v0.1.0
|
|
242
|
-
|