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