storion 0.2.3 → 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/README.md +705 -573
- package/dist/async/async.d.ts +87 -0
- package/dist/async/async.d.ts.map +1 -0
- package/dist/async/index.d.ts +13 -0
- package/dist/async/index.d.ts.map +1 -0
- package/dist/async/index.js +451 -0
- package/dist/async/types.d.ts +275 -0
- package/dist/async/types.d.ts.map +1 -0
- package/dist/collection.d.ts +42 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/core/container.d.ts +33 -2
- package/dist/core/container.d.ts.map +1 -1
- package/dist/core/createResolver.d.ts +47 -0
- package/dist/core/createResolver.d.ts.map +1 -0
- package/dist/core/equality.d.ts +23 -3
- package/dist/core/equality.d.ts.map +1 -1
- package/dist/core/fnWrapper.d.ts +54 -0
- package/dist/core/fnWrapper.d.ts.map +1 -0
- package/dist/core/pick.d.ts +6 -6
- package/dist/core/pick.d.ts.map +1 -1
- package/dist/core/store.d.ts +8 -8
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/storeContext.d.ts +63 -0
- package/dist/core/storeContext.d.ts.map +1 -0
- package/dist/devtools/controller.d.ts +4 -0
- package/dist/devtools/controller.d.ts.map +1 -0
- package/dist/devtools/index.d.ts +16 -0
- package/dist/devtools/index.d.ts.map +1 -0
- package/dist/devtools/index.js +229 -0
- package/dist/devtools/middleware.d.ts +22 -0
- package/dist/devtools/middleware.d.ts.map +1 -0
- package/dist/devtools/types.d.ts +116 -0
- package/dist/devtools/types.d.ts.map +1 -0
- package/dist/devtools-panel/DevtoolsPanel.d.ts +17 -0
- package/dist/devtools-panel/DevtoolsPanel.d.ts.map +1 -0
- package/dist/devtools-panel/components/CompareModal.d.ts +10 -0
- package/dist/devtools-panel/components/CompareModal.d.ts.map +1 -0
- package/dist/devtools-panel/components/EventEntry.d.ts +14 -0
- package/dist/devtools-panel/components/EventEntry.d.ts.map +1 -0
- package/dist/devtools-panel/components/EventFilterBar.d.ts +10 -0
- package/dist/devtools-panel/components/EventFilterBar.d.ts.map +1 -0
- package/dist/devtools-panel/components/EventsTab.d.ts +15 -0
- package/dist/devtools-panel/components/EventsTab.d.ts.map +1 -0
- package/dist/devtools-panel/components/ResizeHandle.d.ts +8 -0
- package/dist/devtools-panel/components/ResizeHandle.d.ts.map +1 -0
- package/dist/devtools-panel/components/StoreEntry.d.ts +13 -0
- package/dist/devtools-panel/components/StoreEntry.d.ts.map +1 -0
- package/dist/devtools-panel/components/StoresTab.d.ts +12 -0
- package/dist/devtools-panel/components/StoresTab.d.ts.map +1 -0
- package/dist/devtools-panel/components/TabLayout.d.ts +48 -0
- package/dist/devtools-panel/components/TabLayout.d.ts.map +1 -0
- package/dist/devtools-panel/components/icons.d.ts +27 -0
- package/dist/devtools-panel/components/icons.d.ts.map +1 -0
- package/dist/devtools-panel/components/index.d.ts +15 -0
- package/dist/devtools-panel/components/index.d.ts.map +1 -0
- package/dist/devtools-panel/hooks.d.ts +23 -0
- package/dist/devtools-panel/hooks.d.ts.map +1 -0
- package/dist/devtools-panel/index.d.ts +25 -0
- package/dist/devtools-panel/index.d.ts.map +1 -0
- package/dist/devtools-panel/index.js +3326 -0
- package/dist/devtools-panel/mount.d.ts +41 -0
- package/dist/devtools-panel/mount.d.ts.map +1 -0
- package/dist/devtools-panel/styles.d.ts +50 -0
- package/dist/devtools-panel/styles.d.ts.map +1 -0
- package/dist/devtools-panel/types.d.ts +15 -0
- package/dist/devtools-panel/types.d.ts.map +1 -0
- package/dist/devtools-panel/utils.d.ts +21 -0
- package/dist/devtools-panel/utils.d.ts.map +1 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/is.d.ts +69 -0
- package/dist/is.d.ts.map +1 -0
- package/dist/react/create.d.ts +1 -1
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +209 -33
- package/dist/react/useLocalStore.d.ts.map +1 -1
- package/dist/react/useStore.d.ts +2 -2
- package/dist/react/useStore.d.ts.map +1 -1
- package/dist/react/withStore.d.ts +140 -0
- package/dist/react/withStore.d.ts.map +1 -0
- package/dist/{index-rLf6DusB.js → store-XP2pujaJ.js} +537 -740
- package/dist/storion.js +740 -9
- package/dist/trigger.d.ts +40 -0
- package/dist/trigger.d.ts.map +1 -0
- package/dist/types.d.ts +516 -50
- package/dist/types.d.ts.map +1 -1
- package/package.json +13 -1
package/dist/storion.js
CHANGED
|
@@ -1,12 +1,743 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { e as emitter, i as isSpec, S as STORION_TYPE, u as untrack, y as getHooks, w as withHooks, r as resolveEquality, z as scheduleNotification, v as unwrapFn, o as shallowEqual } from "./store-XP2pujaJ.js";
|
|
2
|
+
import { m, p, n, g, a, j, d, h, l, f, k, b, x, s, q, t } from "./store-XP2pujaJ.js";
|
|
3
|
+
let defaultMiddlewareConfig = {};
|
|
4
|
+
const container = function(options = {}) {
|
|
5
|
+
const middleware = [
|
|
6
|
+
...defaultMiddlewareConfig.pre ?? [],
|
|
7
|
+
...options.middleware ?? [],
|
|
8
|
+
...defaultMiddlewareConfig.post ?? []
|
|
9
|
+
];
|
|
10
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
11
|
+
const factoryCache = /* @__PURE__ */ new Map();
|
|
12
|
+
const instancesById = /* @__PURE__ */ new Map();
|
|
13
|
+
const overrides = /* @__PURE__ */ new Map();
|
|
14
|
+
const factoryOverrides = /* @__PURE__ */ new Map();
|
|
15
|
+
const creationOrder = [];
|
|
16
|
+
const createEmitter = emitter();
|
|
17
|
+
const disposeEmitter = emitter();
|
|
18
|
+
const creating = /* @__PURE__ */ new Set();
|
|
19
|
+
const creatingFactories = /* @__PURE__ */ new Set();
|
|
20
|
+
const parent = options._parent;
|
|
21
|
+
const resolve = (spec) => overrides.get(spec) ?? spec;
|
|
22
|
+
function buildMiddlewareChain() {
|
|
23
|
+
let chain = (spec, next) => next(spec);
|
|
24
|
+
for (let i = middleware.length - 1; i >= 0; i--) {
|
|
25
|
+
const currentMiddleware = middleware[i];
|
|
26
|
+
const nextInChain = chain;
|
|
27
|
+
chain = (spec, next) => currentMiddleware(spec, (s2) => nextInChain(s2, next));
|
|
28
|
+
}
|
|
29
|
+
return (spec) => chain(spec, (s2) => s2(containerApi));
|
|
30
|
+
}
|
|
31
|
+
const createWithMiddleware = buildMiddlewareChain();
|
|
32
|
+
function createInstance(spec) {
|
|
33
|
+
const instance = untrack(() => createWithMiddleware(spec));
|
|
34
|
+
if (typeof instance.onDispose === "function") {
|
|
35
|
+
instance.onDispose(() => {
|
|
36
|
+
disposeEmitter.emit(instance);
|
|
37
|
+
cache2.delete(spec);
|
|
38
|
+
instancesById.delete(instance.id);
|
|
39
|
+
const index = creationOrder.indexOf(spec);
|
|
40
|
+
if (index !== -1) {
|
|
41
|
+
creationOrder.splice(index, 1);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return instance;
|
|
46
|
+
}
|
|
47
|
+
const containerApi = {
|
|
48
|
+
[STORION_TYPE]: "container",
|
|
49
|
+
// ========================================================================
|
|
50
|
+
// Resolver Methods
|
|
51
|
+
// ========================================================================
|
|
52
|
+
// Implementation handles multiple overloads
|
|
53
|
+
get(specOrIdOrFactory) {
|
|
54
|
+
if (typeof specOrIdOrFactory === "string") {
|
|
55
|
+
return instancesById.get(specOrIdOrFactory);
|
|
56
|
+
}
|
|
57
|
+
if (!isSpec(specOrIdOrFactory)) {
|
|
58
|
+
const factory = specOrIdOrFactory;
|
|
59
|
+
if (factoryCache.has(factory)) {
|
|
60
|
+
return factoryCache.get(factory);
|
|
61
|
+
}
|
|
62
|
+
if (parent && factoryOverrides.size === 0 && "tryGet" in parent && typeof parent.tryGet === "function") {
|
|
63
|
+
const parentInstance = parent.tryGet(factory);
|
|
64
|
+
if (parentInstance !== void 0) {
|
|
65
|
+
return parentInstance;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (creatingFactories.has(factory)) {
|
|
69
|
+
const name = factory.name || "anonymous";
|
|
70
|
+
throw new Error(
|
|
71
|
+
`Circular dependency detected: factory "${name}" is being created while already in creation stack.`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
creatingFactories.add(factory);
|
|
75
|
+
try {
|
|
76
|
+
const mapped = factoryOverrides.get(factory) ?? factory;
|
|
77
|
+
const instance = mapped(containerApi);
|
|
78
|
+
factoryCache.set(factory, instance);
|
|
79
|
+
return instance;
|
|
80
|
+
} finally {
|
|
81
|
+
creatingFactories.delete(factory);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const spec = specOrIdOrFactory;
|
|
85
|
+
if (cache2.has(spec)) {
|
|
86
|
+
return cache2.get(spec);
|
|
87
|
+
}
|
|
88
|
+
if (parent && overrides.size === 0 && parent.has(spec)) {
|
|
89
|
+
return parent.get(spec);
|
|
90
|
+
}
|
|
91
|
+
if (creating.has(spec)) {
|
|
92
|
+
const name = spec.name ?? "unknown";
|
|
93
|
+
throw new Error(
|
|
94
|
+
`Circular dependency detected: "${name}" is being created while already in creation stack.`
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
creating.add(spec);
|
|
98
|
+
try {
|
|
99
|
+
const mapped = resolve(spec);
|
|
100
|
+
const instance = createInstance(mapped);
|
|
101
|
+
cache2.set(spec, instance);
|
|
102
|
+
instancesById.set(instance.id, instance);
|
|
103
|
+
creationOrder.push(spec);
|
|
104
|
+
createEmitter.emit(instance);
|
|
105
|
+
return instance;
|
|
106
|
+
} finally {
|
|
107
|
+
creating.delete(spec);
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
// Implementation handles both StoreSpec and Factory overloads
|
|
111
|
+
create(specOrFactory) {
|
|
112
|
+
if (!isSpec(specOrFactory)) {
|
|
113
|
+
const factory = specOrFactory;
|
|
114
|
+
const mapped2 = factoryOverrides.get(factory) ?? factory;
|
|
115
|
+
return mapped2(containerApi);
|
|
116
|
+
}
|
|
117
|
+
const mapped = resolve(specOrFactory);
|
|
118
|
+
return createInstance(mapped);
|
|
119
|
+
},
|
|
120
|
+
set(spec, override) {
|
|
121
|
+
overrides.set(spec, override);
|
|
122
|
+
const existing = cache2.get(spec);
|
|
123
|
+
if (existing) {
|
|
124
|
+
existing.dispose();
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
has(spec) {
|
|
128
|
+
const inParent = parent && overrides.size === 0 && parent.has(spec);
|
|
129
|
+
return cache2.has(spec) || (inParent ?? false);
|
|
130
|
+
},
|
|
131
|
+
tryGet(spec) {
|
|
132
|
+
if (cache2.has(spec)) {
|
|
133
|
+
return cache2.get(spec);
|
|
134
|
+
}
|
|
135
|
+
if (parent && overrides.size === 0) {
|
|
136
|
+
return parent.tryGet(spec);
|
|
137
|
+
}
|
|
138
|
+
return void 0;
|
|
139
|
+
},
|
|
140
|
+
delete(spec) {
|
|
141
|
+
const instance = cache2.get(spec);
|
|
142
|
+
if (instance) {
|
|
143
|
+
instance.dispose();
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
return false;
|
|
147
|
+
},
|
|
148
|
+
// ========================================================================
|
|
149
|
+
// Container-Specific Methods
|
|
150
|
+
// ========================================================================
|
|
151
|
+
clear() {
|
|
152
|
+
const specs = [...creationOrder].reverse();
|
|
153
|
+
for (const spec of specs) {
|
|
154
|
+
const instance = cache2.get(spec);
|
|
155
|
+
if (instance) {
|
|
156
|
+
instance.dispose();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
cache2.clear();
|
|
160
|
+
instancesById.clear();
|
|
161
|
+
creationOrder.length = 0;
|
|
162
|
+
},
|
|
163
|
+
dispose(spec) {
|
|
164
|
+
return containerApi.delete(spec);
|
|
165
|
+
},
|
|
166
|
+
scope(scopeOptions = {}) {
|
|
167
|
+
return container({
|
|
168
|
+
middleware: scopeOptions.middleware ?? middleware,
|
|
169
|
+
_parent: containerApi
|
|
170
|
+
});
|
|
171
|
+
},
|
|
172
|
+
onCreate: createEmitter.on,
|
|
173
|
+
onDispose: disposeEmitter.on
|
|
174
|
+
};
|
|
175
|
+
return containerApi;
|
|
176
|
+
};
|
|
177
|
+
const defaultsFn = (config = {}) => {
|
|
178
|
+
defaultMiddlewareConfig = {
|
|
179
|
+
pre: [...defaultMiddlewareConfig.pre ?? [], ...config.pre ?? []],
|
|
180
|
+
post: [...defaultMiddlewareConfig.post ?? [], ...config.post ?? []]
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
defaultsFn.clear = () => {
|
|
184
|
+
defaultMiddlewareConfig = {};
|
|
185
|
+
};
|
|
186
|
+
container.defaults = defaultsFn;
|
|
187
|
+
function createResolver(options = {}) {
|
|
188
|
+
const { middleware = [], parent } = options;
|
|
189
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
190
|
+
const overrides = /* @__PURE__ */ new Map();
|
|
191
|
+
const resolve = (factory) => overrides.get(factory) ?? factory;
|
|
192
|
+
const invoke = (factory, resolver2) => {
|
|
193
|
+
const chain = middleware.reduceRight(
|
|
194
|
+
(next, mw) => () => mw({
|
|
195
|
+
factory,
|
|
196
|
+
resolver: resolver2,
|
|
197
|
+
next
|
|
198
|
+
}),
|
|
199
|
+
() => factory(resolver2)
|
|
200
|
+
);
|
|
201
|
+
return chain();
|
|
202
|
+
};
|
|
203
|
+
const resolver = {
|
|
204
|
+
get(factory) {
|
|
205
|
+
if (cache2.has(factory)) {
|
|
206
|
+
return cache2.get(factory);
|
|
207
|
+
}
|
|
208
|
+
if (parent && overrides.size === 0 && parent.has(factory)) {
|
|
209
|
+
return parent.get(factory);
|
|
210
|
+
}
|
|
211
|
+
const instance = invoke(resolve(factory), resolver);
|
|
212
|
+
cache2.set(factory, instance);
|
|
213
|
+
return instance;
|
|
214
|
+
},
|
|
215
|
+
create(factory) {
|
|
216
|
+
return invoke(resolve(factory), resolver);
|
|
217
|
+
},
|
|
218
|
+
set(factory, override) {
|
|
219
|
+
overrides.set(factory, override);
|
|
220
|
+
cache2.delete(factory);
|
|
221
|
+
},
|
|
222
|
+
has(factory) {
|
|
223
|
+
const inParent = parent && overrides.size === 0 && parent.has(factory);
|
|
224
|
+
return cache2.has(factory) || (inParent ?? false);
|
|
225
|
+
},
|
|
226
|
+
tryGet(factory) {
|
|
227
|
+
if (cache2.has(factory)) {
|
|
228
|
+
return cache2.get(factory);
|
|
229
|
+
}
|
|
230
|
+
if (parent && overrides.size === 0) {
|
|
231
|
+
return parent.tryGet(factory);
|
|
232
|
+
}
|
|
233
|
+
return void 0;
|
|
234
|
+
},
|
|
235
|
+
delete(factory) {
|
|
236
|
+
return cache2.delete(factory);
|
|
237
|
+
},
|
|
238
|
+
clear() {
|
|
239
|
+
cache2.clear();
|
|
240
|
+
},
|
|
241
|
+
scope(scopeOptions = {}) {
|
|
242
|
+
return createResolver({
|
|
243
|
+
middleware: scopeOptions.middleware ?? middleware,
|
|
244
|
+
parent: resolver,
|
|
245
|
+
...scopeOptions
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
return resolver;
|
|
250
|
+
}
|
|
251
|
+
function when(predicate, middleware) {
|
|
252
|
+
return (ctx) => {
|
|
253
|
+
if (predicate(ctx.factory)) {
|
|
254
|
+
return middleware(ctx);
|
|
255
|
+
}
|
|
256
|
+
return ctx.next();
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
function createLoggingMiddleware(prefix = "Resolver") {
|
|
260
|
+
return (ctx) => {
|
|
261
|
+
const name = ctx.factory.name || "anonymous";
|
|
262
|
+
console.log(`[${prefix}] Creating: ${name}`);
|
|
263
|
+
const start = performance.now();
|
|
264
|
+
const result = ctx.next();
|
|
265
|
+
const duration = (performance.now() - start).toFixed(2);
|
|
266
|
+
console.log(`[${prefix}] Created: ${name} (${duration}ms)`);
|
|
267
|
+
return result;
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
function createValidationMiddleware(validate) {
|
|
271
|
+
return (ctx) => {
|
|
272
|
+
const result = ctx.next();
|
|
273
|
+
validate(result, ctx.factory);
|
|
274
|
+
return result;
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
let pickIdCounter = 0;
|
|
278
|
+
function pick(selector, equality) {
|
|
279
|
+
var _a;
|
|
280
|
+
const parentHooks = getHooks();
|
|
281
|
+
if (!parentHooks.onRead) {
|
|
282
|
+
throw new Error(
|
|
283
|
+
"pick() must be called inside an effect or useStore selector. It requires an active hooks.onRead context."
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
const equalityFn = resolveEquality(equality);
|
|
287
|
+
const currentReads = [];
|
|
288
|
+
const evaluate = () => {
|
|
289
|
+
currentReads.length = 0;
|
|
290
|
+
const value = withHooks(
|
|
291
|
+
{
|
|
292
|
+
onRead: (event) => {
|
|
293
|
+
currentReads.push(event);
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
selector
|
|
297
|
+
);
|
|
298
|
+
return value;
|
|
299
|
+
};
|
|
300
|
+
let currentValue = evaluate();
|
|
301
|
+
if (!currentReads.length) {
|
|
302
|
+
return currentValue;
|
|
303
|
+
}
|
|
304
|
+
const pickKey = `pick:${++pickIdCounter}`;
|
|
305
|
+
const subscribe = (listener) => {
|
|
306
|
+
const onCleanup = emitter();
|
|
307
|
+
const setupSubscriptions = () => {
|
|
308
|
+
for (const read of currentReads) {
|
|
309
|
+
const unsub = read.subscribe(handleChange);
|
|
310
|
+
onCleanup.on(unsub);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
const clearSubscriptions = () => {
|
|
314
|
+
onCleanup.emitAndClear();
|
|
315
|
+
};
|
|
316
|
+
const handleChange = () => {
|
|
317
|
+
try {
|
|
318
|
+
const prevValue = currentValue;
|
|
319
|
+
clearSubscriptions();
|
|
320
|
+
currentValue = evaluate();
|
|
321
|
+
setupSubscriptions();
|
|
322
|
+
if (!equalityFn(prevValue, currentValue)) {
|
|
323
|
+
listener();
|
|
324
|
+
}
|
|
325
|
+
} catch (error) {
|
|
326
|
+
clearSubscriptions();
|
|
327
|
+
listener();
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
setupSubscriptions();
|
|
331
|
+
return clearSubscriptions;
|
|
332
|
+
};
|
|
333
|
+
(_a = parentHooks.onRead) == null ? void 0 : _a.call(parentHooks, {
|
|
334
|
+
key: pickKey,
|
|
335
|
+
value: currentValue,
|
|
336
|
+
subscribe
|
|
337
|
+
});
|
|
338
|
+
return currentValue;
|
|
339
|
+
}
|
|
340
|
+
function createEffectContext(nth, isStale) {
|
|
341
|
+
let cleanupEmitter = null;
|
|
342
|
+
let abortController = null;
|
|
343
|
+
const runCleanups = () => {
|
|
344
|
+
if (abortController) {
|
|
345
|
+
abortController.abort();
|
|
346
|
+
abortController = null;
|
|
347
|
+
}
|
|
348
|
+
if (cleanupEmitter && cleanupEmitter.size > 0) {
|
|
349
|
+
cleanupEmitter.emitAndClearLifo();
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
const context = {
|
|
353
|
+
nth,
|
|
354
|
+
get signal() {
|
|
355
|
+
if (!abortController) {
|
|
356
|
+
abortController = new AbortController();
|
|
357
|
+
}
|
|
358
|
+
return abortController.signal;
|
|
359
|
+
},
|
|
360
|
+
onCleanup(listener) {
|
|
361
|
+
if (!cleanupEmitter) {
|
|
362
|
+
cleanupEmitter = emitter();
|
|
363
|
+
}
|
|
364
|
+
return cleanupEmitter.on(listener);
|
|
365
|
+
},
|
|
366
|
+
safe(promiseOrCallback) {
|
|
367
|
+
if (promiseOrCallback instanceof Promise) {
|
|
368
|
+
return new Promise((resolve, reject) => {
|
|
369
|
+
promiseOrCallback.then(
|
|
370
|
+
(value) => {
|
|
371
|
+
if (!isStale()) {
|
|
372
|
+
resolve(value);
|
|
373
|
+
}
|
|
374
|
+
},
|
|
375
|
+
(error) => {
|
|
376
|
+
if (!isStale()) {
|
|
377
|
+
reject(error);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
);
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
return (...args) => {
|
|
384
|
+
if (!isStale()) {
|
|
385
|
+
return promiseOrCallback(...args);
|
|
386
|
+
}
|
|
387
|
+
return void 0;
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
return Object.assign(context, { _runCleanups: runCleanups });
|
|
392
|
+
}
|
|
393
|
+
function resolveErrorStrategy(effectOptions) {
|
|
394
|
+
return (effectOptions == null ? void 0 : effectOptions.onError) ?? "keepAlive";
|
|
395
|
+
}
|
|
396
|
+
function getRetryDelay(config, attempt) {
|
|
397
|
+
if (typeof config.delay === "function") {
|
|
398
|
+
return config.delay(attempt);
|
|
399
|
+
}
|
|
400
|
+
return config.delay ?? 100 * Math.pow(2, attempt);
|
|
401
|
+
}
|
|
402
|
+
function effect(fn, options) {
|
|
403
|
+
let currentContext = null;
|
|
404
|
+
let subscriptionEmitter = null;
|
|
405
|
+
let isStarted = false;
|
|
406
|
+
let isRunning = false;
|
|
407
|
+
let isDisposed = false;
|
|
408
|
+
let runGeneration = 0;
|
|
409
|
+
let retryCount = 0;
|
|
410
|
+
let retryTimeout = null;
|
|
411
|
+
let errorStrategy = "keepAlive";
|
|
412
|
+
let onErrorCallback = null;
|
|
413
|
+
let prevTrackedDeps = /* @__PURE__ */ new Map();
|
|
414
|
+
let prevSubscriptionEmitter = null;
|
|
415
|
+
let trackedDeps = /* @__PURE__ */ new Map();
|
|
416
|
+
const writtenProps = /* @__PURE__ */ new Set();
|
|
417
|
+
let newTrackedDeps = null;
|
|
418
|
+
const getSubscriptionEmitter = () => {
|
|
419
|
+
if (!subscriptionEmitter) {
|
|
420
|
+
subscriptionEmitter = emitter();
|
|
421
|
+
}
|
|
422
|
+
return subscriptionEmitter;
|
|
423
|
+
};
|
|
424
|
+
const clearSubscriptions = () => {
|
|
425
|
+
if (subscriptionEmitter && subscriptionEmitter.size > 0) {
|
|
426
|
+
subscriptionEmitter.emitAndClear();
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
const areDepsChanged = (prev, next) => {
|
|
430
|
+
if (prev.size !== next.size) return true;
|
|
431
|
+
for (const key of next.keys()) {
|
|
432
|
+
if (!prev.has(key)) return true;
|
|
433
|
+
}
|
|
434
|
+
return false;
|
|
435
|
+
};
|
|
436
|
+
const subscribeToTrackedDeps = () => {
|
|
437
|
+
for (const [key, dep] of trackedDeps) {
|
|
438
|
+
if (writtenProps.has(key)) continue;
|
|
439
|
+
const unsub = dep.subscribe(() => {
|
|
440
|
+
scheduleNotification(execute, fn);
|
|
441
|
+
});
|
|
442
|
+
getSubscriptionEmitter().on(unsub);
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
const handleError = (error) => {
|
|
446
|
+
onErrorCallback == null ? void 0 : onErrorCallback(error);
|
|
447
|
+
if (errorStrategy === "failFast") {
|
|
448
|
+
throw error;
|
|
449
|
+
}
|
|
450
|
+
if (errorStrategy === "keepAlive") {
|
|
451
|
+
console.error("Effect error (keepAlive):", error);
|
|
452
|
+
if (prevSubscriptionEmitter && prevSubscriptionEmitter.size > 0) {
|
|
453
|
+
trackedDeps = new Map(prevTrackedDeps);
|
|
454
|
+
subscriptionEmitter = prevSubscriptionEmitter;
|
|
455
|
+
prevSubscriptionEmitter = null;
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
if (newTrackedDeps && newTrackedDeps.size > 0) {
|
|
459
|
+
trackedDeps = newTrackedDeps;
|
|
460
|
+
}
|
|
461
|
+
subscribeToTrackedDeps();
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
if (typeof errorStrategy === "function") {
|
|
465
|
+
const retry = () => {
|
|
466
|
+
retryCount++;
|
|
467
|
+
execute();
|
|
468
|
+
};
|
|
469
|
+
errorStrategy({ error, retry, retryCount });
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
const retryConfig = errorStrategy;
|
|
473
|
+
if (retryCount < retryConfig.maxRetries) {
|
|
474
|
+
const delay = getRetryDelay(retryConfig, retryCount);
|
|
475
|
+
retryCount++;
|
|
476
|
+
retryTimeout = setTimeout(() => {
|
|
477
|
+
retryTimeout = null;
|
|
478
|
+
execute();
|
|
479
|
+
}, delay);
|
|
480
|
+
} else {
|
|
481
|
+
console.error(
|
|
482
|
+
`Effect failed after ${retryConfig.maxRetries} retries:`,
|
|
483
|
+
error
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
let cachedHooks = null;
|
|
488
|
+
const getTrackingHooks = (current) => {
|
|
489
|
+
if (!cachedHooks) {
|
|
490
|
+
cachedHooks = {
|
|
491
|
+
...current,
|
|
492
|
+
onRead: (event) => {
|
|
493
|
+
var _a;
|
|
494
|
+
(_a = current.onRead) == null ? void 0 : _a.call(current, event);
|
|
495
|
+
if (!newTrackedDeps.has(event.key)) {
|
|
496
|
+
newTrackedDeps.set(event.key, {
|
|
497
|
+
key: event.key,
|
|
498
|
+
value: event.value,
|
|
499
|
+
subscribe: event.subscribe
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
},
|
|
503
|
+
onWrite: (event) => {
|
|
504
|
+
var _a;
|
|
505
|
+
(_a = current.onWrite) == null ? void 0 : _a.call(current, event);
|
|
506
|
+
writtenProps.add(event.key);
|
|
507
|
+
},
|
|
508
|
+
scheduleNotification: current.scheduleNotification,
|
|
509
|
+
scheduleEffect: current.scheduleEffect
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
return cachedHooks;
|
|
513
|
+
};
|
|
514
|
+
const execute = () => {
|
|
515
|
+
if (isDisposed || isRunning) return;
|
|
516
|
+
isRunning = true;
|
|
517
|
+
const currentGeneration = ++runGeneration;
|
|
518
|
+
try {
|
|
519
|
+
currentContext == null ? void 0 : currentContext._runCleanups();
|
|
520
|
+
currentContext = null;
|
|
521
|
+
if (subscriptionEmitter && subscriptionEmitter.size > 0) {
|
|
522
|
+
prevTrackedDeps = new Map(trackedDeps);
|
|
523
|
+
prevSubscriptionEmitter = subscriptionEmitter;
|
|
524
|
+
subscriptionEmitter = null;
|
|
525
|
+
}
|
|
526
|
+
newTrackedDeps = /* @__PURE__ */ new Map();
|
|
527
|
+
writtenProps.clear();
|
|
528
|
+
const isStale = () => isDisposed || runGeneration !== currentGeneration;
|
|
529
|
+
let lazyContext = null;
|
|
530
|
+
const getOrCreateContext = () => {
|
|
531
|
+
if (!lazyContext) {
|
|
532
|
+
lazyContext = createEffectContext(currentGeneration, isStale);
|
|
533
|
+
}
|
|
534
|
+
return lazyContext;
|
|
535
|
+
};
|
|
536
|
+
const lazyContextProxy = new Proxy({}, {
|
|
537
|
+
get(_, prop) {
|
|
538
|
+
return getOrCreateContext()[prop];
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
withHooks(getTrackingHooks, () => {
|
|
542
|
+
const result = fn(lazyContextProxy);
|
|
543
|
+
if (result !== null && result !== void 0 && typeof result.then === "function") {
|
|
544
|
+
throw new Error(
|
|
545
|
+
"Effect function must be synchronous. Use ctx.safe(promise) for async operations instead of returning a Promise."
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
currentContext = lazyContext;
|
|
550
|
+
retryCount = 0;
|
|
551
|
+
const depsChanged = areDepsChanged(trackedDeps, newTrackedDeps);
|
|
552
|
+
if (depsChanged) {
|
|
553
|
+
if (prevSubscriptionEmitter && prevSubscriptionEmitter.size > 0) {
|
|
554
|
+
prevSubscriptionEmitter.emitAndClear();
|
|
555
|
+
}
|
|
556
|
+
trackedDeps = newTrackedDeps;
|
|
557
|
+
subscribeToTrackedDeps();
|
|
558
|
+
} else {
|
|
559
|
+
if (prevSubscriptionEmitter) {
|
|
560
|
+
subscriptionEmitter = prevSubscriptionEmitter;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
prevTrackedDeps.clear();
|
|
564
|
+
prevSubscriptionEmitter = null;
|
|
565
|
+
} catch (error) {
|
|
566
|
+
handleError(error);
|
|
567
|
+
} finally {
|
|
568
|
+
isRunning = false;
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
const dispose = () => {
|
|
572
|
+
if (isDisposed) return;
|
|
573
|
+
isDisposed = true;
|
|
574
|
+
runGeneration++;
|
|
575
|
+
if (retryTimeout) {
|
|
576
|
+
clearTimeout(retryTimeout);
|
|
577
|
+
retryTimeout = null;
|
|
578
|
+
}
|
|
579
|
+
currentContext == null ? void 0 : currentContext._runCleanups();
|
|
580
|
+
currentContext = null;
|
|
581
|
+
clearSubscriptions();
|
|
582
|
+
if (prevSubscriptionEmitter && prevSubscriptionEmitter.size > 0) {
|
|
583
|
+
prevSubscriptionEmitter.emitAndClear();
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
const start = (runOptions) => {
|
|
587
|
+
if (isStarted) return;
|
|
588
|
+
isStarted = true;
|
|
589
|
+
errorStrategy = resolveErrorStrategy(options);
|
|
590
|
+
onErrorCallback = (runOptions == null ? void 0 : runOptions.onError) ?? null;
|
|
591
|
+
execute();
|
|
592
|
+
};
|
|
593
|
+
getHooks().scheduleEffect((runOptions) => {
|
|
594
|
+
start(runOptions);
|
|
595
|
+
return dispose;
|
|
596
|
+
});
|
|
597
|
+
return dispose;
|
|
598
|
+
}
|
|
599
|
+
function patternToPredicate(pattern) {
|
|
600
|
+
if (pattern instanceof RegExp) {
|
|
601
|
+
return (name) => pattern.test(name);
|
|
602
|
+
}
|
|
603
|
+
const startsWithWildcard = pattern.startsWith("*");
|
|
604
|
+
const endsWithWildcard = pattern.endsWith("*");
|
|
605
|
+
if (startsWithWildcard && endsWithWildcard) {
|
|
606
|
+
const substr = pattern.slice(1, -1);
|
|
607
|
+
return (name) => name.includes(substr);
|
|
608
|
+
}
|
|
609
|
+
if (startsWithWildcard) {
|
|
610
|
+
const suffix = pattern.slice(1);
|
|
611
|
+
return (name) => name.endsWith(suffix);
|
|
612
|
+
}
|
|
613
|
+
if (endsWithWildcard) {
|
|
614
|
+
const prefix = pattern.slice(0, -1);
|
|
615
|
+
return (name) => name.startsWith(prefix);
|
|
616
|
+
}
|
|
617
|
+
return (name) => name === pattern;
|
|
618
|
+
}
|
|
619
|
+
function patternsToPredicate(patterns) {
|
|
620
|
+
if (Array.isArray(patterns)) {
|
|
621
|
+
const predicates = patterns.map(patternToPredicate);
|
|
622
|
+
return (spec) => predicates.some((p2) => p2(spec.name));
|
|
623
|
+
}
|
|
624
|
+
const predicate = patternToPredicate(patterns);
|
|
625
|
+
return (spec) => predicate(spec.name);
|
|
626
|
+
}
|
|
627
|
+
function compose(...middlewares) {
|
|
628
|
+
if (middlewares.length === 0) {
|
|
629
|
+
return (spec, next) => next(spec);
|
|
630
|
+
}
|
|
631
|
+
if (middlewares.length === 1) {
|
|
632
|
+
return middlewares[0];
|
|
633
|
+
}
|
|
634
|
+
return (spec, next) => {
|
|
635
|
+
let chain = next;
|
|
636
|
+
for (let i = middlewares.length - 1; i >= 0; i--) {
|
|
637
|
+
const middleware = middlewares[i];
|
|
638
|
+
const prevChain = chain;
|
|
639
|
+
chain = (s2) => middleware(s2, prevChain);
|
|
640
|
+
}
|
|
641
|
+
return chain(spec);
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
function applyFor(predicateOrPatterns, middleware) {
|
|
645
|
+
const predicate = typeof predicateOrPatterns === "function" ? predicateOrPatterns : patternsToPredicate(predicateOrPatterns);
|
|
646
|
+
const composedMiddleware = Array.isArray(middleware) ? compose(...middleware) : middleware;
|
|
647
|
+
return (spec, next) => {
|
|
648
|
+
if (predicate(spec)) {
|
|
649
|
+
return composedMiddleware(spec, next);
|
|
650
|
+
}
|
|
651
|
+
return next(spec);
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
function applyExcept(predicateOrPatterns, middleware) {
|
|
655
|
+
const matchPredicate = typeof predicateOrPatterns === "function" ? predicateOrPatterns : patternsToPredicate(predicateOrPatterns);
|
|
656
|
+
const invertedPredicate = (spec) => !matchPredicate(spec);
|
|
657
|
+
return applyFor(invertedPredicate, middleware);
|
|
658
|
+
}
|
|
659
|
+
const DEFAULT_KEY = {};
|
|
660
|
+
const cache = /* @__PURE__ */ new Map();
|
|
661
|
+
function getKeyCache(key) {
|
|
662
|
+
let keyCache = cache.get(key);
|
|
663
|
+
if (!keyCache) {
|
|
664
|
+
keyCache = /* @__PURE__ */ new WeakMap();
|
|
665
|
+
cache.set(key, keyCache);
|
|
666
|
+
}
|
|
667
|
+
return keyCache;
|
|
668
|
+
}
|
|
669
|
+
function trigger(keyOrFn, fnOrDepsOrOptions, depsOrFirstArg, ...restArgs) {
|
|
670
|
+
let key;
|
|
671
|
+
let fn;
|
|
672
|
+
let deps;
|
|
673
|
+
let equality;
|
|
674
|
+
let args;
|
|
675
|
+
if (typeof fnOrDepsOrOptions === "function") {
|
|
676
|
+
key = keyOrFn;
|
|
677
|
+
fn = fnOrDepsOrOptions;
|
|
678
|
+
deps = depsOrFirstArg ?? [];
|
|
679
|
+
args = restArgs;
|
|
680
|
+
} else if (Array.isArray(fnOrDepsOrOptions)) {
|
|
681
|
+
key = DEFAULT_KEY;
|
|
682
|
+
fn = keyOrFn;
|
|
683
|
+
deps = fnOrDepsOrOptions;
|
|
684
|
+
args = depsOrFirstArg !== void 0 ? [depsOrFirstArg, ...restArgs] : [];
|
|
685
|
+
} else {
|
|
686
|
+
const options = fnOrDepsOrOptions ?? {};
|
|
687
|
+
key = options.key ?? DEFAULT_KEY;
|
|
688
|
+
fn = keyOrFn;
|
|
689
|
+
deps = options.deps ?? [];
|
|
690
|
+
equality = options.equality ? resolveEquality(options.equality) : void 0;
|
|
691
|
+
args = depsOrFirstArg !== void 0 ? [depsOrFirstArg, ...restArgs] : [];
|
|
692
|
+
}
|
|
693
|
+
const cacheKey = unwrapFn(fn);
|
|
694
|
+
const keyCache = getKeyCache(key);
|
|
695
|
+
const cached = keyCache.get(cacheKey);
|
|
696
|
+
const eq = equality ?? (cached == null ? void 0 : cached.equality) ?? shallowEqual;
|
|
697
|
+
if (cached && eq(cached.deps, deps)) {
|
|
698
|
+
return cached.result;
|
|
699
|
+
}
|
|
700
|
+
const result = fn(...args);
|
|
701
|
+
keyCache.set(cacheKey, { deps, result, equality });
|
|
702
|
+
return result;
|
|
703
|
+
}
|
|
704
|
+
trigger.clear = (key) => {
|
|
705
|
+
cache.delete(key);
|
|
706
|
+
};
|
|
707
|
+
trigger.clearAll = () => {
|
|
708
|
+
cache.clear();
|
|
709
|
+
};
|
|
2
710
|
export {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
711
|
+
STORION_TYPE,
|
|
712
|
+
applyExcept,
|
|
713
|
+
applyFor,
|
|
714
|
+
m as batch,
|
|
715
|
+
compose,
|
|
716
|
+
container,
|
|
717
|
+
createLoggingMiddleware,
|
|
718
|
+
createResolver,
|
|
719
|
+
createValidationMiddleware,
|
|
720
|
+
p as deepEqual,
|
|
721
|
+
effect,
|
|
722
|
+
n as equality,
|
|
723
|
+
g as getKind,
|
|
724
|
+
a as is,
|
|
725
|
+
j as isAction,
|
|
726
|
+
d as isContainer,
|
|
727
|
+
h as isFocus,
|
|
728
|
+
l as isSelectorContext,
|
|
729
|
+
isSpec,
|
|
730
|
+
f as isStore,
|
|
731
|
+
k as isStoreContext,
|
|
732
|
+
b as isStorion,
|
|
733
|
+
x as isWrappedFn,
|
|
734
|
+
pick,
|
|
735
|
+
shallowEqual,
|
|
10
736
|
s as store,
|
|
11
|
-
|
|
737
|
+
q as strictEqual,
|
|
738
|
+
trigger,
|
|
739
|
+
untrack,
|
|
740
|
+
unwrapFn,
|
|
741
|
+
when,
|
|
742
|
+
t as wrapFn
|
|
12
743
|
};
|