@pumped-fn/core-next 0.5.55 → 0.5.58

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/dist/index.cjs CHANGED
@@ -56,22 +56,12 @@ var DependencyResolutionError = class extends ExecutorResolutionError {
56
56
 
57
57
  //#endregion
58
58
  //#region src/ssch.ts
59
- function validate(schema, data$1) {
60
- const result = schema["~standard"].validate(data$1);
59
+ function validate(schema, data) {
60
+ const result = schema["~standard"].validate(data);
61
61
  if ("then" in result) throw new Error("validating async is not supported");
62
62
  if (result.issues) throw new SchemaError(result.issues);
63
63
  return result.value;
64
64
  }
65
- async function validateAsync(schema, data$1) {
66
- const result = schema["~standard"].validate(data$1);
67
- if ("then" in result) {
68
- const result_1 = await result;
69
- if (result_1.issues) throw new SchemaError(result_1.issues);
70
- return result_1.value;
71
- }
72
- if (result.issues) throw new SchemaError(result.issues);
73
- return Promise.resolve(result.value);
74
- }
75
65
  function custom() {
76
66
  return { "~standard": {
77
67
  vendor: "pumped-fn",
@@ -84,54 +74,52 @@ function custom() {
84
74
 
85
75
  //#endregion
86
76
  //#region src/meta.ts
77
+ var MetaFunction = class {
78
+ key;
79
+ schema;
80
+ [metaSymbol] = true;
81
+ constructor(key, schema) {
82
+ this.key = typeof key === "string" ? Symbol(key) : key;
83
+ this.schema = schema;
84
+ }
85
+ __call(value) {
86
+ return {
87
+ [metaSymbol]: true,
88
+ key: this.key,
89
+ schema: this.schema,
90
+ value
91
+ };
92
+ }
93
+ partial(d) {
94
+ return Object.assign({}, this.__call({}), d);
95
+ }
96
+ some(source) {
97
+ return findValues(source, this);
98
+ }
99
+ find(source) {
100
+ return findValue(source, this);
101
+ }
102
+ get(source) {
103
+ return getValue(findValue(source, this));
104
+ }
105
+ };
87
106
  const meta = (key, schema) => {
88
- const _key = typeof key === "string" ? Symbol(key) : key;
89
- const fn = (value) => ({
90
- [metaSymbol]: true,
91
- key: _key,
92
- schema,
93
- value
94
- });
107
+ const metaFunc = new MetaFunction(key, schema);
108
+ const fn = (value) => metaFunc.__call(value);
95
109
  Object.defineProperty(fn, "key", {
96
- value: _key,
97
- configurable: false,
98
- enumerable: false,
99
- writable: false
110
+ value: metaFunc.key,
111
+ writable: false,
112
+ configurable: false
100
113
  });
101
114
  Object.defineProperty(fn, metaSymbol, {
102
115
  value: true,
103
- configurable: false,
104
- enumerable: false,
105
- writable: false
106
- });
107
- Object.defineProperties(fn, {
108
- partial: {
109
- value: (d) => {
110
- return Object.assign({}, fn({}), d);
111
- },
112
- configurable: false,
113
- enumerable: false,
114
- writable: false
115
- },
116
- some: {
117
- value: (source) => findValues(source, fn),
118
- configurable: false,
119
- enumerable: false,
120
- writable: false
121
- },
122
- find: {
123
- value: (source) => findValue(source, fn),
124
- configurable: false,
125
- enumerable: false,
126
- writable: false
127
- },
128
- get: {
129
- value: (source) => getValue(findValue(source, fn)),
130
- configurable: false,
131
- enumerable: false,
132
- writable: false
133
- }
116
+ writable: false,
117
+ configurable: false
134
118
  });
119
+ fn.partial = metaFunc.partial.bind(metaFunc);
120
+ fn.some = metaFunc.some.bind(metaFunc);
121
+ fn.find = metaFunc.find.bind(metaFunc);
122
+ fn.get = metaFunc.get.bind(metaFunc);
135
123
  return fn;
136
124
  };
137
125
  function getValue(meta$1) {
@@ -149,214 +137,81 @@ function findValue(executor, meta$1) {
149
137
  }
150
138
 
151
139
  //#endregion
152
- //#region src/executor.ts
153
- function createExecutor(factory, dependencies, metas) {
154
- const executor = {
155
- [executorSymbol]: "main",
156
- factory: (_, controller) => {
157
- if (dependencies === void 0) {
158
- const f$1 = factory;
159
- return f$1(controller);
160
- }
161
- const f = factory;
162
- return f(_, controller);
163
- },
164
- dependencies,
165
- metas
166
- };
167
- const lazyExecutor = {
168
- [executorSymbol]: "lazy",
169
- dependencies: void 0,
170
- executor,
171
- factory: void 0,
172
- metas
173
- };
174
- const reactiveExecutor = {
175
- [executorSymbol]: "reactive",
176
- executor,
177
- factory: void 0,
178
- dependencies: void 0,
179
- metas
180
- };
181
- const staticExecutor = {
182
- [executorSymbol]: "static",
183
- dependencies: void 0,
184
- factory: void 0,
185
- metas,
186
- executor
187
- };
188
- Object.defineProperties(executor, {
189
- lazy: {
190
- value: lazyExecutor,
191
- writable: false,
192
- configurable: false,
193
- enumerable: false
194
- },
195
- reactive: {
196
- value: reactiveExecutor,
197
- writable: false,
198
- configurable: false,
199
- enumerable: false
200
- },
201
- static: {
202
- value: staticExecutor,
203
- writable: false,
204
- configurable: false,
205
- enumerable: false
206
- }
207
- });
208
- return executor;
140
+ //#region src/accessor.ts
141
+ function isDataStore(source) {
142
+ return "get" in source && "set" in source;
209
143
  }
210
- function isLazyExecutor(executor) {
211
- return executor[executorSymbol] === "lazy";
144
+ function isMetaArray(source) {
145
+ return Array.isArray(source);
212
146
  }
213
- function isReactiveExecutor(executor) {
214
- return executor[executorSymbol] === "reactive";
215
- }
216
- function isStaticExecutor(executor) {
217
- return executor[executorSymbol] === "static";
218
- }
219
- function isMainExecutor(executor) {
220
- return isExecutor(executor) && executor[executorSymbol] === "main";
221
- }
222
- function isExecutor(input) {
223
- return typeof input === "object" && input !== null && executorSymbol in input;
224
- }
225
- function isPreset(input) {
226
- return typeof input === "object" && input !== null && executorSymbol in input && input[executorSymbol] === "preset";
227
- }
228
- function provide(factory, ...metas) {
229
- return createExecutor(factory, void 0, metas);
230
- }
231
- function derive(pdependencies, pfactory, ...metas) {
232
- return createExecutor(pfactory, pdependencies, metas);
233
- }
234
- function preset(e, v) {
235
- const executor = isExecutor(e) ? e : e.escape();
236
- return {
237
- [executorSymbol]: "preset",
238
- value: v,
239
- executor
240
- };
241
- }
242
-
243
- //#endregion
244
- //#region src/multi.ts
245
- var multi_exports = {};
246
- __export(multi_exports, {
247
- derive: () => derive$2,
248
- provide: () => provide$2
249
- });
250
- function createMultiExecutor(option, poolId, keyPool, createNewExecutor, providerMetas) {
251
- const processKey = (key) => {
252
- const validatedKey = validate(option.keySchema, key);
253
- const transformedKey = option.keyTransform ? option.keyTransform(validatedKey) : validatedKey;
254
- return {
255
- validatedKey,
256
- transformedKey
257
- };
258
- };
259
- const newProvider = (key) => {
260
- const { transformedKey } = processKey(key);
261
- const executor = createNewExecutor(key);
262
- keyPool.set(transformedKey, executor);
263
- return executor;
264
- };
265
- const provider = createExecutor((ctl) => {
266
- return (key) => {
267
- const { transformedKey } = processKey(key);
268
- let executor = keyPool.get(transformedKey);
269
- if (!executor) executor = newProvider(key);
270
- return ctl.scope.accessor(executor);
271
- };
272
- }, void 0, providerMetas);
273
- const multiExecutor = (key) => {
274
- const { transformedKey } = processKey(key);
275
- return keyPool.get(transformedKey) || newProvider(key);
276
- };
277
- Object.assign(multiExecutor, provider);
278
- multiExecutor.release = async (scope) => {
279
- const entries = scope.entries();
280
- for (const [executor] of entries) {
281
- const check = poolId.some ? poolId.some(executor) : poolId.find(executor);
282
- if (check && (Array.isArray(check) ? check.length > 0 : check)) await scope.release(executor);
283
- }
284
- };
285
- multiExecutor.id = poolId;
286
- return multiExecutor;
287
- }
288
- function provide$2(option, valueFn, ...metas) {
289
- const poolId = meta(Symbol(), custom());
290
- const keyPool = new Map();
291
- const createNewExecutor = (key) => {
292
- const validatedKey = validate(option.keySchema, key);
293
- return createExecutor((ctl) => valueFn(validatedKey, ctl), void 0, [poolId(void 0), ...metas]);
294
- };
295
- return createMultiExecutor(option, poolId, keyPool, createNewExecutor, [poolId(void 0), ...metas]);
296
- }
297
- function derive$2(option, valueFn, ...metas) {
298
- const poolId = meta(Symbol(), custom());
299
- const keyPool = new Map();
300
- const createNewExecutor = (key) => {
301
- const validatedKey = validate(option.keySchema, key);
302
- return createExecutor((dependencies, ctl) => valueFn(dependencies, validatedKey, ctl), option.dependencies, metas);
303
- };
304
- return createMultiExecutor(option, poolId, keyPool, createNewExecutor, metas);
305
- }
306
-
307
- //#endregion
308
- //#region src/generator-utils.ts
309
- function isGenerator(value) {
310
- return value != null && typeof value === "object" && typeof value[Symbol.iterator] === "function" && typeof value.next === "function" && typeof value.return === "function" && typeof value.throw === "function";
311
- }
312
- function isAsyncGenerator(value) {
313
- return value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function" && typeof value.next === "function" && typeof value.return === "function" && typeof value.throw === "function";
314
- }
315
- function isGeneratorFunction(fn) {
316
- return typeof fn === "function" && fn.constructor && fn.constructor.name === "GeneratorFunction";
317
- }
318
- function isAsyncGeneratorFunction(fn) {
319
- return typeof fn === "function" && fn.constructor && fn.constructor.name === "AsyncGeneratorFunction";
320
- }
321
- function isIterableOrAsyncIterable(value) {
322
- return isGenerator(value) || isAsyncGenerator(value);
323
- }
324
- async function collectFromGenerator(gen) {
325
- const yielded = [];
326
- let returned;
327
- try {
328
- let result;
329
- do {
330
- result = await gen.next();
331
- if (!result.done) yielded.push(result.value);
332
- else returned = result.value;
333
- } while (!result.done);
334
- return {
335
- yielded,
336
- returned
337
- };
338
- } catch (error) {
339
- await gen.return?.(void 0);
340
- throw error;
147
+ function extractFromSource(source, key, schema) {
148
+ if (isDataStore(source)) {
149
+ const value = source.get(key);
150
+ return value === void 0 ? void 0 : validate(schema, value);
341
151
  }
152
+ if (isMetaArray(source)) {
153
+ const meta$2 = source.find((m) => m.key === key);
154
+ return meta$2 ? validate(schema, meta$2.value) : void 0;
155
+ }
156
+ const metas = source.metas ?? [];
157
+ const meta$1 = metas.find((m) => m.key === key);
158
+ return meta$1 ? validate(schema, meta$1.value) : void 0;
342
159
  }
343
- async function processGenerator(gen, handler) {
344
- let index = 0;
345
- try {
346
- let result;
347
- do {
348
- result = await gen.next();
349
- if (!result.done) await handler.onYield?.(result.value, index++);
350
- else {
351
- await handler.onReturn?.(result.value);
352
- return result.value;
353
- }
354
- } while (true);
355
- } catch (error) {
356
- await handler.onError?.(error);
357
- await gen.return?.(void 0);
358
- throw error;
160
+ var AccessorImpl$1 = class {
161
+ key;
162
+ schema;
163
+ constructor(key, schema) {
164
+ this.key = typeof key === "string" ? Symbol(key) : key;
165
+ this.schema = schema;
359
166
  }
167
+ get(source) {
168
+ const value = extractFromSource(source, this.key, this.schema);
169
+ if (value === void 0) throw new Error(`Value not found for key: ${this.key.toString()}`);
170
+ return value;
171
+ }
172
+ find(source) {
173
+ return extractFromSource(source, this.key, this.schema);
174
+ }
175
+ set(source, value) {
176
+ if (!isDataStore(source)) throw new Error("set() can only be used with DataStore");
177
+ const validated = validate(this.schema, value);
178
+ source.set(this.key, validated);
179
+ }
180
+ preset(value) {
181
+ const validated = validate(this.schema, value);
182
+ return [this.key, validated];
183
+ }
184
+ };
185
+ var AccessorWithDefaultImpl = class {
186
+ key;
187
+ schema;
188
+ defaultValue;
189
+ constructor(key, schema, defaultValue) {
190
+ this.key = typeof key === "string" ? Symbol(key) : key;
191
+ this.schema = schema;
192
+ this.defaultValue = validate(schema, defaultValue);
193
+ }
194
+ get(source) {
195
+ const value = extractFromSource(source, this.key, this.schema);
196
+ return value ?? this.defaultValue;
197
+ }
198
+ find(source) {
199
+ const value = extractFromSource(source, this.key, this.schema);
200
+ return value ?? this.defaultValue;
201
+ }
202
+ set(source, value) {
203
+ if (!isDataStore(source)) throw new Error("set() can only be used with DataStore");
204
+ const validated = validate(this.schema, value);
205
+ source.set(this.key, validated);
206
+ }
207
+ preset(value) {
208
+ const validated = validate(this.schema, value);
209
+ return [this.key, validated];
210
+ }
211
+ };
212
+ function accessor(key, schema, defaultValue) {
213
+ if (defaultValue !== void 0) return new AccessorWithDefaultImpl(key, schema, defaultValue);
214
+ return new AccessorImpl$1(key, schema);
360
215
  }
361
216
 
362
217
  //#endregion
@@ -528,122 +383,345 @@ function buildDependencyChain(executorStack) {
528
383
  }
529
384
 
530
385
  //#endregion
531
- //#region src/scope.ts
532
- function getExecutor(e) {
533
- if (isLazyExecutor(e) || isReactiveExecutor(e) || isStaticExecutor(e)) return e.executor;
534
- return e;
386
+ //#region src/executor.ts
387
+ function createExecutor(factory, dependencies, metas) {
388
+ const executor = {
389
+ [executorSymbol]: "main",
390
+ factory: (_, controller) => {
391
+ if (dependencies === void 0) {
392
+ const f$1 = factory;
393
+ return f$1(controller);
394
+ }
395
+ const f = factory;
396
+ return f(_, controller);
397
+ },
398
+ dependencies,
399
+ metas
400
+ };
401
+ const lazyExecutor = {
402
+ [executorSymbol]: "lazy",
403
+ dependencies: void 0,
404
+ executor,
405
+ factory: void 0,
406
+ metas
407
+ };
408
+ const reactiveExecutor = {
409
+ [executorSymbol]: "reactive",
410
+ executor,
411
+ factory: void 0,
412
+ dependencies: void 0,
413
+ metas
414
+ };
415
+ const staticExecutor = {
416
+ [executorSymbol]: "static",
417
+ dependencies: void 0,
418
+ factory: void 0,
419
+ metas,
420
+ executor
421
+ };
422
+ Object.defineProperties(executor, {
423
+ lazy: {
424
+ value: lazyExecutor,
425
+ writable: false,
426
+ configurable: false,
427
+ enumerable: false
428
+ },
429
+ reactive: {
430
+ value: reactiveExecutor,
431
+ writable: false,
432
+ configurable: false,
433
+ enumerable: false
434
+ },
435
+ static: {
436
+ value: staticExecutor,
437
+ writable: false,
438
+ configurable: false,
439
+ enumerable: false
440
+ }
441
+ });
442
+ return executor;
535
443
  }
536
- var BaseScope = class {
537
- disposed = false;
538
- cache = new Map();
539
- cleanups = new Map();
540
- onUpdates = new Map();
541
- onEvents = {
542
- change: new Set(),
543
- release: new Set()
444
+ function isLazyExecutor(executor) {
445
+ return executor[executorSymbol] === "lazy";
446
+ }
447
+ function isReactiveExecutor(executor) {
448
+ return executor[executorSymbol] === "reactive";
449
+ }
450
+ function isStaticExecutor(executor) {
451
+ return executor[executorSymbol] === "static";
452
+ }
453
+ function isMainExecutor(executor) {
454
+ return isExecutor(executor) && executor[executorSymbol] === "main";
455
+ }
456
+ function isExecutor(input) {
457
+ return typeof input === "object" && input !== null && executorSymbol in input;
458
+ }
459
+ function isPreset(input) {
460
+ return typeof input === "object" && input !== null && executorSymbol in input && input[executorSymbol] === "preset";
461
+ }
462
+ function provide(factory, ...metas) {
463
+ return createExecutor(factory, void 0, metas);
464
+ }
465
+ function derive(pdependencies, pfactory, ...metas) {
466
+ return createExecutor(pfactory, pdependencies, metas);
467
+ }
468
+ function preset(e, v) {
469
+ const executor = isExecutor(e) ? e : e.escape();
470
+ return {
471
+ [executorSymbol]: "preset",
472
+ value: v,
473
+ executor
544
474
  };
545
- isPod;
546
- isDisposing = false;
547
- plugins = [];
548
- registry = [];
549
- initialValues = [];
550
- constructor(options) {
551
- this.isPod = options?.pod || false;
552
- if (options?.registry) this.registry = [...options.registry];
553
- if (options?.initialValues) this.initialValues = options.initialValues;
554
- if (options?.plugins) for (const plugin$1 of options.plugins) this.use(plugin$1);
475
+ }
476
+
477
+ //#endregion
478
+ //#region src/generator-utils.ts
479
+ function isGenerator(value) {
480
+ return value != null && typeof value === "object" && typeof value[Symbol.iterator] === "function" && typeof value.next === "function" && typeof value.return === "function" && typeof value.throw === "function";
481
+ }
482
+ function isAsyncGenerator(value) {
483
+ return value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function" && typeof value.next === "function" && typeof value.return === "function" && typeof value.throw === "function";
484
+ }
485
+ function isGeneratorFunction(fn) {
486
+ return typeof fn === "function" && fn.constructor && fn.constructor.name === "GeneratorFunction";
487
+ }
488
+ function isAsyncGeneratorFunction(fn) {
489
+ return typeof fn === "function" && fn.constructor && fn.constructor.name === "AsyncGeneratorFunction";
490
+ }
491
+ function isIterableOrAsyncIterable(value) {
492
+ return isGenerator(value) || isAsyncGenerator(value);
493
+ }
494
+ async function collectFromGenerator(gen) {
495
+ const yielded = [];
496
+ let returned;
497
+ try {
498
+ let result;
499
+ do {
500
+ result = await gen.next();
501
+ if (!result.done) yielded.push(result.value);
502
+ else returned = result.value;
503
+ } while (!result.done);
504
+ return {
505
+ yielded,
506
+ returned
507
+ };
508
+ } catch (error) {
509
+ await gen.return?.(void 0);
510
+ throw error;
555
511
  }
556
- async "~triggerCleanup"(e) {
557
- const cs = this.cleanups.get(e);
558
- if (cs) for (const c of Array.from(cs.values()).reverse()) await c();
512
+ }
513
+ async function processGenerator(gen, handler) {
514
+ let index = 0;
515
+ try {
516
+ let result;
517
+ do {
518
+ result = await gen.next();
519
+ if (!result.done) await handler.onYield?.(result.value, index++);
520
+ else {
521
+ await handler.onReturn?.(result.value);
522
+ return result.value;
523
+ }
524
+ } while (true);
525
+ } catch (error) {
526
+ await handler.onError?.(error);
527
+ await gen.return?.(void 0);
528
+ throw error;
559
529
  }
560
- async "~triggerUpdate"(e) {
561
- const ce = this.cache.get(e);
562
- if (!ce) throw new Error("Executor is not yet resolved");
563
- const ou = this.onUpdates.get(e);
564
- if (ou) for (const t of Array.from(ou.values())) if (isMainExecutor(t)) {
565
- if (this.cleanups.has(t)) this["~triggerCleanup"](t);
566
- const a = this.cache.get(t);
567
- await a.accessor.resolve(true);
568
- if (this.onUpdates.has(t)) await this["~triggerUpdate"](t);
569
- } else await t(ce.accessor);
530
+ }
531
+
532
+ //#endregion
533
+ //#region src/helpers.ts
534
+ async function resolves(scope, executors) {
535
+ const objectOutput = {};
536
+ const arrayOutput = [];
537
+ const isArray = Array.isArray(executors);
538
+ for (const [index, executor] of Object.entries(executors)) {
539
+ const target = !isExecutor(executor) ? executor.escape() : isLazyExecutor(executor) || isReactiveExecutor(executor) || isStaticExecutor(executor) ? executor.executor : executor;
540
+ const result$1 = await scope.resolve(target);
541
+ if (isArray) arrayOutput.push(result$1);
542
+ else Object.assign(objectOutput, { [index]: result$1 });
543
+ }
544
+ const result = isArray ? arrayOutput : objectOutput;
545
+ return result;
546
+ }
547
+ var PreparedExecutorImpl = class {
548
+ scope;
549
+ executor;
550
+ constructor(scope, executor) {
551
+ this.scope = scope;
552
+ this.executor = executor;
553
+ }
554
+ async __call() {
555
+ return await this.scope.resolve(this.executor);
556
+ }
557
+ escape() {
558
+ return this.executor;
559
+ }
560
+ };
561
+ function prepare(scope, executor) {
562
+ const impl = new PreparedExecutorImpl(scope, executor);
563
+ const fn = async () => impl.__call();
564
+ fn.escape = () => impl.escape();
565
+ return fn;
566
+ }
567
+ var AdaptedExecutorImpl = class {
568
+ scope;
569
+ executor;
570
+ constructor(scope, executor) {
571
+ this.scope = scope;
572
+ this.executor = executor;
573
+ }
574
+ async __call(...args) {
575
+ const fn = await this.scope.resolve(this.executor);
576
+ return await fn(...args);
577
+ }
578
+ escape() {
579
+ return this.executor;
580
+ }
581
+ };
582
+ function adapt(scope, executor) {
583
+ const impl = new AdaptedExecutorImpl(scope, executor);
584
+ const fn = async (...args) => impl.__call(...args);
585
+ fn.escape = () => impl.escape();
586
+ return fn;
587
+ }
588
+
589
+ //#endregion
590
+ //#region src/multi.ts
591
+ var multi_exports = {};
592
+ __export(multi_exports, {
593
+ derive: () => derive$1,
594
+ provide: () => provide$1
595
+ });
596
+ var MultiExecutorImpl = class {
597
+ option;
598
+ poolId;
599
+ keyPool;
600
+ createNewExecutor;
601
+ id;
602
+ constructor(option, poolId, keyPool, createNewExecutor) {
603
+ this.option = option;
604
+ this.poolId = poolId;
605
+ this.keyPool = keyPool;
606
+ this.createNewExecutor = createNewExecutor;
607
+ this.id = poolId;
608
+ }
609
+ processKey(key) {
610
+ const validatedKey = validate(this.option.keySchema, key);
611
+ const transformedKey = this.option.keyTransform ? this.option.keyTransform(validatedKey) : validatedKey;
612
+ return {
613
+ validatedKey,
614
+ transformedKey
615
+ };
616
+ }
617
+ newProvider(key) {
618
+ const { transformedKey } = this.processKey(key);
619
+ const executor = this.createNewExecutor(key);
620
+ this.keyPool.set(transformedKey, executor);
621
+ return executor;
622
+ }
623
+ __call(key) {
624
+ const { transformedKey } = this.processKey(key);
625
+ return this.keyPool.get(transformedKey) || this.newProvider(key);
570
626
  }
571
- async "~resolveExecutor"(ie, ref) {
572
- const e = getExecutor(ie);
573
- const a = this["~makeAccessor"](e);
574
- if (isLazyExecutor(ie)) return a;
575
- if (isReactiveExecutor(ie)) {
576
- const c = this.onUpdates.get(ie.executor) ?? new Set();
577
- this.onUpdates.set(ie.executor, c);
578
- c.add(ref);
579
- }
580
- await a.resolve(false);
581
- if (isStaticExecutor(ie)) return a;
582
- return a.get();
627
+ providerFactory(ctl) {
628
+ return (key) => {
629
+ const { transformedKey } = this.processKey(key);
630
+ let executor = this.keyPool.get(transformedKey);
631
+ if (!executor) executor = this.newProvider(key);
632
+ return ctl.scope.accessor(executor);
633
+ };
583
634
  }
584
- async "~resolveDependencies"(ie, ref) {
585
- if (ie === void 0) return void 0;
586
- if (isExecutor(ie)) return this["~resolveExecutor"](ie, ref);
587
- if (Array.isArray(ie)) return await Promise.all(ie.map((item) => this["~resolveDependencies"](item, ref)));
588
- const r = {};
589
- for (const k of Object.keys(ie)) {
590
- const t = ie[k];
591
- const rd = await this["~resolveDependencies"](t, ref);
592
- r[k] = rd;
635
+ async release(scope) {
636
+ const entries = scope.entries();
637
+ for (const [executor] of entries) {
638
+ const check = this.poolId.some ? this.poolId.some(executor) : this.poolId.find(executor);
639
+ if (check && (Array.isArray(check) ? check.length > 0 : check)) await scope.release(executor);
593
640
  }
594
- return r;
595
641
  }
596
- "~ensureNotDisposed"() {
597
- if (this.disposed) throw new Error("Scope is disposed");
642
+ };
643
+ function createMultiExecutor(option, poolId, keyPool, createNewExecutor, providerMetas) {
644
+ const impl = new MultiExecutorImpl(option, poolId, keyPool, createNewExecutor);
645
+ const provider = createExecutor((ctl) => impl.providerFactory(ctl), void 0, providerMetas);
646
+ const multiExecutor = (key) => impl.__call(key);
647
+ Object.assign(multiExecutor, provider);
648
+ multiExecutor.release = (scope) => impl.release(scope);
649
+ multiExecutor.id = impl.id;
650
+ return multiExecutor;
651
+ }
652
+ function provide$1(option, valueFn, ...metas) {
653
+ const poolId = meta(Symbol(), custom());
654
+ const keyPool = new Map();
655
+ const createNewExecutor = (key) => {
656
+ const validatedKey = validate(option.keySchema, key);
657
+ return createExecutor((ctl) => valueFn(validatedKey, ctl), void 0, [poolId(void 0), ...metas]);
658
+ };
659
+ return createMultiExecutor(option, poolId, keyPool, createNewExecutor, [poolId(void 0), ...metas]);
660
+ }
661
+ function derive$1(option, valueFn, ...metas) {
662
+ const poolId = meta(Symbol(), custom());
663
+ const keyPool = new Map();
664
+ const createNewExecutor = (key) => {
665
+ const validatedKey = validate(option.keySchema, key);
666
+ return createExecutor((dependencies, ctl) => valueFn(dependencies, validatedKey, ctl), option.dependencies, metas);
667
+ };
668
+ return createMultiExecutor(option, poolId, keyPool, createNewExecutor, metas);
669
+ }
670
+
671
+ //#endregion
672
+ //#region src/scope.ts
673
+ var AccessorImpl = class {
674
+ metas;
675
+ scope;
676
+ requestor;
677
+ currentPromise = null;
678
+ resolve;
679
+ constructor(scope, requestor, metas) {
680
+ this.scope = scope;
681
+ this.requestor = requestor;
682
+ this.metas = metas;
683
+ this.resolve = this.createResolveFunction();
684
+ const existing = this.scope["cache"].get(requestor);
685
+ if (!existing || !existing.accessor) this.scope["cache"].set(requestor, {
686
+ accessor: this,
687
+ value: existing?.value || void 0
688
+ });
598
689
  }
599
- "~makeAccessor"(e) {
600
- let requestor = isLazyExecutor(e) || isReactiveExecutor(e) || isStaticExecutor(e) ? e.executor : e;
601
- const cachedAccessor = this.cache.get(requestor);
602
- if (cachedAccessor) return cachedAccessor.accessor;
603
- const accessor = {};
604
- const controller = {
605
- cleanup: (cleanup) => {
606
- const currentSet = this.cleanups.get(requestor) ?? new Set();
607
- this.cleanups.set(requestor, currentSet);
608
- currentSet.add(cleanup);
609
- },
610
- release: async () => this.release(requestor),
611
- reload: async () => {
612
- await this.resolve(requestor, true);
613
- },
614
- scope: this
615
- };
616
- const resolve = (force) => {
617
- this["~ensureNotDisposed"]();
618
- const entry = this.cache.get(requestor);
690
+ createResolveFunction() {
691
+ return (force = false) => {
692
+ this.scope["~ensureNotDisposed"]();
693
+ const entry = this.scope["cache"].get(this.requestor);
619
694
  const cached = entry?.value;
620
695
  if (cached && !force) if (cached.kind === "resolved") return Promise.resolve(cached.value);
621
696
  else if (cached.kind === "rejected") throw cached.error;
622
697
  else return cached.promise;
623
- const promise = new Promise((resolve$1, reject) => {
624
- const replacer = this.initialValues.find((item) => item.executor === requestor);
625
- let factory = requestor.factory;
626
- let dependencies = requestor.dependencies;
698
+ if (this.currentPromise && !force) return this.currentPromise;
699
+ this.scope["~addToResolutionChain"](this.requestor, this.requestor);
700
+ this.currentPromise = new Promise((resolve, reject) => {
701
+ const replacer = this.scope["initialValues"].find((item) => item.executor === this.requestor);
702
+ let factory = this.requestor.factory;
703
+ let dependencies = this.requestor.dependencies;
627
704
  if (replacer) {
628
705
  const value = replacer.value;
629
706
  if (!isExecutor(value)) return setTimeout(() => {
630
- this.cache.set(requestor, {
631
- accessor,
707
+ this.scope["cache"].set(this.requestor, {
708
+ accessor: this,
632
709
  value: {
633
710
  kind: "resolved",
634
711
  value: replacer.value
635
712
  }
636
713
  });
637
- resolve$1(replacer.value);
714
+ resolve(replacer.value);
638
715
  }, 0);
639
716
  factory = value.factory;
640
717
  dependencies = value.dependencies;
641
718
  }
642
- this["~resolveDependencies"](dependencies, requestor).then((dependencies$1) => {
719
+ const controller = this.createController();
720
+ this.scope["~resolveDependencies"](dependencies, this.requestor).then((dependencies$1) => {
643
721
  try {
644
722
  const factoryResult = factory(dependencies$1, controller);
645
723
  if (factoryResult instanceof Promise) return factoryResult.catch((asyncError) => {
646
- const executorName = getExecutorName(requestor);
724
+ const executorName = getExecutorName(this.requestor);
647
725
  const dependencyChain = [executorName];
648
726
  const factoryError = createFactoryError(ErrorCodes.FACTORY_ASYNC_ERROR, executorName, dependencyChain, asyncError, {
649
727
  dependenciesResolved: dependencies$1 !== void 0,
@@ -654,7 +732,7 @@ var BaseScope = class {
654
732
  });
655
733
  return factoryResult;
656
734
  } catch (error) {
657
- const executorName = getExecutorName(requestor);
735
+ const executorName = getExecutorName(this.requestor);
658
736
  const dependencyChain = [executorName];
659
737
  const factoryError = createFactoryError(ErrorCodes.FACTORY_THREW_ERROR, executorName, dependencyChain, error, {
660
738
  dependenciesResolved: dependencies$1 !== void 0,
@@ -669,7 +747,7 @@ var BaseScope = class {
669
747
  const { returned } = await collectFromGenerator(result);
670
748
  current = returned;
671
749
  } catch (generatorError) {
672
- const executorName = getExecutorName(requestor);
750
+ const executorName = getExecutorName(this.requestor);
673
751
  const dependencyChain = [executorName];
674
752
  const factoryError = createFactoryError(ErrorCodes.FACTORY_GENERATOR_ERROR, executorName, dependencyChain, generatorError, {
675
753
  generatorType: isGenerator(result) ? "sync" : "async",
@@ -677,19 +755,21 @@ var BaseScope = class {
677
755
  });
678
756
  throw factoryError;
679
757
  }
680
- const events = this.onEvents.change;
758
+ const events = this.scope["onEvents"].change;
681
759
  for (const event of events) {
682
- const updated = await event("resolve", requestor, current, this);
683
- if (updated !== void 0 && updated.executor === requestor) current = updated.value;
760
+ const updated = await event("resolve", this.requestor, current, this.scope);
761
+ if (updated !== void 0 && updated.executor === this.requestor) current = updated.value;
684
762
  }
685
- this.cache.set(requestor, {
686
- accessor,
763
+ this.scope["cache"].set(this.requestor, {
764
+ accessor: this,
687
765
  value: {
688
766
  kind: "resolved",
689
767
  value: current
690
768
  }
691
769
  });
692
- resolve$1(current);
770
+ this.scope["~removeFromResolutionChain"](this.requestor);
771
+ this.currentPromise = null;
772
+ resolve(current);
693
773
  }).catch((error) => {
694
774
  let enhancedError = error;
695
775
  let errorContext = void 0;
@@ -697,7 +777,7 @@ var BaseScope = class {
697
777
  enhancedError = error;
698
778
  errorContext = error.context;
699
779
  } else {
700
- const executorName = getExecutorName(requestor);
780
+ const executorName = getExecutorName(this.requestor);
701
781
  const dependencyChain = [executorName];
702
782
  enhancedError = createSystemError(ErrorCodes.INTERNAL_RESOLUTION_ERROR, executorName, dependencyChain, error, {
703
783
  errorType: error?.constructor?.name || "UnknownError",
@@ -705,8 +785,8 @@ var BaseScope = class {
705
785
  });
706
786
  errorContext = enhancedError.context;
707
787
  }
708
- this.cache.set(requestor, {
709
- accessor,
788
+ this.scope["cache"].set(this.requestor, {
789
+ accessor: this,
710
790
  value: {
711
791
  kind: "rejected",
712
792
  error,
@@ -714,48 +794,186 @@ var BaseScope = class {
714
794
  enhancedError
715
795
  }
716
796
  });
797
+ this.scope["~removeFromResolutionChain"](this.requestor);
798
+ this.scope["~triggerError"](enhancedError, this.requestor);
799
+ this.currentPromise = null;
717
800
  reject(enhancedError);
718
801
  });
719
802
  });
720
- this.cache.set(requestor, {
721
- accessor,
803
+ this.scope["cache"].set(this.requestor, {
804
+ accessor: this,
722
805
  value: {
723
806
  kind: "pending",
724
- promise
807
+ promise: this.currentPromise
725
808
  }
726
809
  });
727
- return promise;
810
+ return this.currentPromise;
728
811
  };
729
- return Object.assign(accessor, {
730
- get: () => {
731
- this["~ensureNotDisposed"]();
732
- const cacheEntry = this.cache.get(requestor)?.value;
733
- if (!cacheEntry || cacheEntry.kind === "pending") throw new Error("Executor is not resolved");
734
- if (cacheEntry.kind === "rejected") throw cacheEntry.enhancedError || cacheEntry.error;
735
- return cacheEntry.value;
736
- },
737
- lookup: () => {
738
- this["~ensureNotDisposed"]();
739
- const cacheEntry = this.cache.get(requestor);
740
- if (!cacheEntry) return void 0;
741
- return cacheEntry.value;
742
- },
743
- metas: e.metas,
744
- resolve,
745
- release: async (soft = false) => {
746
- this.release(requestor, soft);
747
- },
748
- update: (updateFn) => {
749
- return this.update(requestor, updateFn);
812
+ }
813
+ lookup() {
814
+ this.scope["~ensureNotDisposed"]();
815
+ const cacheEntry = this.scope["cache"].get(this.requestor);
816
+ if (!cacheEntry) return void 0;
817
+ return cacheEntry.value || void 0;
818
+ }
819
+ get() {
820
+ this.scope["~ensureNotDisposed"]();
821
+ const cacheEntry = this.scope["cache"].get(this.requestor)?.value;
822
+ if (!cacheEntry || cacheEntry.kind === "pending") throw new Error("Executor is not resolved");
823
+ if (cacheEntry.kind === "rejected") throw cacheEntry.enhancedError || cacheEntry.error;
824
+ return cacheEntry.value;
825
+ }
826
+ async release(soft = false) {
827
+ this.scope.release(this.requestor, soft);
828
+ }
829
+ async update(updateFn) {
830
+ return this.scope.update(this.requestor, updateFn);
831
+ }
832
+ async set(value) {
833
+ return this.scope.update(this.requestor, value);
834
+ }
835
+ subscribe(cb) {
836
+ this.scope["~ensureNotDisposed"]();
837
+ return this.scope.onUpdate(this.requestor, cb);
838
+ }
839
+ createController() {
840
+ return {
841
+ cleanup: (cleanup) => {
842
+ const currentSet = this.scope["cleanups"].get(this.requestor) ?? new Set();
843
+ this.scope["cleanups"].set(this.requestor, currentSet);
844
+ currentSet.add(cleanup);
750
845
  },
751
- set: async (value) => {
752
- return this.update(requestor, value);
846
+ release: async () => this.scope.release(this.requestor),
847
+ reload: async () => {
848
+ await this.scope.resolve(this.requestor, true);
753
849
  },
754
- subscribe: (cb) => {
755
- this["~ensureNotDisposed"]();
756
- return this.onUpdate(requestor, cb);
757
- }
758
- });
850
+ scope: this.scope
851
+ };
852
+ }
853
+ };
854
+ function getExecutor(e) {
855
+ if (isLazyExecutor(e) || isReactiveExecutor(e) || isStaticExecutor(e)) return e.executor;
856
+ return e;
857
+ }
858
+ var BaseScope = class {
859
+ disposed = false;
860
+ cache = new Map();
861
+ cleanups = new Map();
862
+ onUpdates = new Map();
863
+ onEvents = {
864
+ change: new Set(),
865
+ release: new Set(),
866
+ error: new Set()
867
+ };
868
+ onErrors = new Map();
869
+ isPod;
870
+ isDisposing = false;
871
+ resolutionChain = new Map();
872
+ plugins = [];
873
+ registry = [];
874
+ initialValues = [];
875
+ constructor(options) {
876
+ this.isPod = options?.pod || false;
877
+ if (options?.registry) this.registry = [...options.registry];
878
+ if (options?.initialValues) this.initialValues = options.initialValues;
879
+ if (options?.plugins) for (const plugin$1 of options.plugins) this.use(plugin$1);
880
+ }
881
+ "~checkCircularDependency"(executor, resolvingExecutor) {
882
+ const currentChain = this.resolutionChain.get(resolvingExecutor);
883
+ if (currentChain && currentChain.has(executor)) {
884
+ const chainArray = Array.from(currentChain);
885
+ const dependencyChain = buildDependencyChain(chainArray);
886
+ throw createDependencyError(ErrorCodes.CIRCULAR_DEPENDENCY, getExecutorName(executor), dependencyChain, getExecutorName(executor), void 0, {
887
+ circularPath: dependencyChain.join(" -> ") + " -> " + getExecutorName(executor),
888
+ detectedAt: getExecutorName(resolvingExecutor)
889
+ });
890
+ }
891
+ }
892
+ "~addToResolutionChain"(executor, resolvingExecutor) {
893
+ const currentChain = this.resolutionChain.get(resolvingExecutor) || new Set();
894
+ currentChain.add(executor);
895
+ this.resolutionChain.set(resolvingExecutor, currentChain);
896
+ }
897
+ "~removeFromResolutionChain"(executor) {
898
+ this.resolutionChain.delete(executor);
899
+ }
900
+ "~propagateResolutionChain"(fromExecutor, toExecutor) {
901
+ const fromChain = this.resolutionChain.get(fromExecutor);
902
+ if (fromChain) {
903
+ const newChain = new Set(fromChain);
904
+ newChain.add(fromExecutor);
905
+ this.resolutionChain.set(toExecutor, newChain);
906
+ }
907
+ }
908
+ async "~triggerCleanup"(e) {
909
+ const cs = this.cleanups.get(e);
910
+ if (cs) for (const c of Array.from(cs.values()).reverse()) await c();
911
+ }
912
+ async "~triggerUpdate"(e) {
913
+ const ce = this.cache.get(e);
914
+ if (!ce) throw new Error("Executor is not yet resolved");
915
+ const ou = this.onUpdates.get(e);
916
+ if (ou) for (const t of Array.from(ou.values())) if (isMainExecutor(t)) {
917
+ if (this.cleanups.has(t)) this["~triggerCleanup"](t);
918
+ const a = this.cache.get(t);
919
+ await a.accessor.resolve(true);
920
+ if (this.onUpdates.has(t)) await this["~triggerUpdate"](t);
921
+ } else await t(ce.accessor);
922
+ }
923
+ async "~triggerError"(error, executor) {
924
+ const executorCallbacks = this.onErrors.get(executor);
925
+ if (executorCallbacks) for (const callback of Array.from(executorCallbacks.values())) try {
926
+ await callback(error, executor, this);
927
+ } catch (callbackError) {
928
+ console.error("Error in error callback:", callbackError);
929
+ }
930
+ for (const callback of Array.from(this.onEvents.error.values())) try {
931
+ await callback(error, executor, this);
932
+ } catch (callbackError) {
933
+ console.error("Error in global error callback:", callbackError);
934
+ }
935
+ for (const plugin$1 of this.plugins) if (plugin$1.onError) try {
936
+ await plugin$1.onError(error, executor, this);
937
+ } catch (pluginError) {
938
+ console.error("Error in plugin error handler:", pluginError);
939
+ }
940
+ }
941
+ async "~resolveExecutor"(ie, ref) {
942
+ const e = getExecutor(ie);
943
+ this["~checkCircularDependency"](e, ref);
944
+ this["~propagateResolutionChain"](ref, e);
945
+ const a = this["~makeAccessor"](e);
946
+ if (isLazyExecutor(ie)) return a;
947
+ if (isReactiveExecutor(ie)) {
948
+ const c = this.onUpdates.get(ie.executor) ?? new Set();
949
+ this.onUpdates.set(ie.executor, c);
950
+ c.add(ref);
951
+ }
952
+ await a.resolve(false);
953
+ if (isStaticExecutor(ie)) return a;
954
+ return a.get();
955
+ }
956
+ async "~resolveDependencies"(ie, ref) {
957
+ if (ie === void 0) return void 0;
958
+ if (isExecutor(ie)) return this["~resolveExecutor"](ie, ref);
959
+ if (Array.isArray(ie)) return await Promise.all(ie.map((item) => this["~resolveDependencies"](item, ref)));
960
+ const r = {};
961
+ for (const k of Object.keys(ie)) {
962
+ const t = ie[k];
963
+ const rd = await this["~resolveDependencies"](t, ref);
964
+ r[k] = rd;
965
+ }
966
+ return r;
967
+ }
968
+ "~ensureNotDisposed"() {
969
+ if (this.disposed) throw new Error("Scope is disposed");
970
+ }
971
+ "~makeAccessor"(e) {
972
+ let requestor = isLazyExecutor(e) || isReactiveExecutor(e) || isStaticExecutor(e) ? e.executor : e;
973
+ const cachedAccessor = this.cache.get(requestor);
974
+ if (cachedAccessor && cachedAccessor.accessor) return cachedAccessor.accessor;
975
+ const accessor$1 = new AccessorImpl(this, requestor, e.metas);
976
+ return accessor$1;
759
977
  }
760
978
  accessor(executor) {
761
979
  this["~ensureNotDisposed"]();
@@ -768,25 +986,25 @@ var BaseScope = class {
768
986
  }
769
987
  async resolve(executor, force = false) {
770
988
  this["~ensureNotDisposed"]();
771
- const accessor = this["~makeAccessor"](executor);
772
- await accessor.resolve(force);
773
- return accessor.get();
989
+ const accessor$1 = this["~makeAccessor"](executor);
990
+ await accessor$1.resolve(force);
991
+ return accessor$1.get();
774
992
  }
775
993
  async resolveAccessor(executor, force = false) {
776
994
  this["~ensureNotDisposed"]();
777
- const accessor = this["~makeAccessor"](executor);
778
- await accessor.resolve(force);
779
- return accessor;
995
+ const accessor$1 = this["~makeAccessor"](executor);
996
+ await accessor$1.resolve(force);
997
+ return accessor$1;
780
998
  }
781
999
  async update(e, u) {
782
1000
  if (this.isDisposing) return;
783
1001
  this["~ensureNotDisposed"]();
784
1002
  this["~triggerCleanup"](e);
785
- const accessor = this["~makeAccessor"](e);
1003
+ const accessor$1 = this["~makeAccessor"](e);
786
1004
  let value;
787
1005
  if (typeof u === "function") {
788
1006
  const fn = u;
789
- value = fn(accessor.get());
1007
+ value = fn(accessor$1.get());
790
1008
  } else value = u;
791
1009
  const events = this.onEvents.change;
792
1010
  for (const event of events) {
@@ -794,7 +1012,7 @@ var BaseScope = class {
794
1012
  if (updated !== void 0 && e === updated.executor) value = updated.value;
795
1013
  }
796
1014
  this.cache.set(e, {
797
- accessor,
1015
+ accessor: accessor$1,
798
1016
  value: {
799
1017
  kind: "resolved",
800
1018
  value
@@ -833,6 +1051,9 @@ var BaseScope = class {
833
1051
  this.onUpdates.clear();
834
1052
  this.onEvents.change.clear();
835
1053
  this.onEvents.release.clear();
1054
+ this.onEvents.error.clear();
1055
+ this.onErrors.clear();
1056
+ this.resolutionChain.clear();
836
1057
  }
837
1058
  onUpdate(e, cb) {
838
1059
  this["~ensureNotDisposed"]();
@@ -867,6 +1088,32 @@ var BaseScope = class {
867
1088
  this.onEvents["release"].delete(cb);
868
1089
  };
869
1090
  }
1091
+ onError(executorOrCallback, callback) {
1092
+ this["~ensureNotDisposed"]();
1093
+ if (this.isDisposing) throw new Error("Cannot register error callback on a disposing scope");
1094
+ if (typeof executorOrCallback === "function") {
1095
+ this.onEvents["error"].add(executorOrCallback);
1096
+ return () => {
1097
+ this["~ensureNotDisposed"]();
1098
+ this.onEvents["error"].delete(executorOrCallback);
1099
+ };
1100
+ }
1101
+ if (callback) {
1102
+ const executor = executorOrCallback;
1103
+ const errorCallbacks = this.onErrors.get(executor) ?? new Set();
1104
+ this.onErrors.set(executor, errorCallbacks);
1105
+ errorCallbacks.add(callback);
1106
+ return () => {
1107
+ this["~ensureNotDisposed"]();
1108
+ const callbacks = this.onErrors.get(executor);
1109
+ if (callbacks) {
1110
+ callbacks.delete(callback);
1111
+ if (callbacks.size === 0) this.onErrors.delete(executor);
1112
+ }
1113
+ };
1114
+ }
1115
+ throw new Error("Invalid arguments for onError");
1116
+ }
870
1117
  use(plugin$1) {
871
1118
  this["~ensureNotDisposed"]();
872
1119
  if (this.isDisposing) throw new Error("Cannot register update callback on a disposing scope");
@@ -916,9 +1163,9 @@ var Pod = class extends BaseScope {
916
1163
  if (this.cache.has(executor)) return super.resolve(executor, force);
917
1164
  if (this.parentScope["cache"].has(executor)) {
918
1165
  const { value } = this.parentScope["cache"].get(executor);
919
- const accessor = super["~makeAccessor"](executor);
1166
+ const accessor$1 = super["~makeAccessor"](executor);
920
1167
  this["cache"].set(executor, {
921
- accessor,
1168
+ accessor: accessor$1,
922
1169
  value
923
1170
  });
924
1171
  if (value.kind === "rejected") throw value.error;
@@ -930,6 +1177,8 @@ var Pod = class extends BaseScope {
930
1177
  async "~resolveExecutor"(ie, ref) {
931
1178
  if (isReactiveExecutor(ie)) throw new Error("Reactive executors cannot be used in pod");
932
1179
  const t = getExecutor(ie);
1180
+ this["~checkCircularDependency"](t, ref);
1181
+ this["~propagateResolutionChain"](ref, t);
933
1182
  const a = this["~makeAccessor"](t);
934
1183
  if (this.parentScope["cache"].has(t)) {
935
1184
  const { value } = this.parentScope["cache"].get(t);
@@ -944,270 +1193,135 @@ var Pod = class extends BaseScope {
944
1193
 
945
1194
  //#endregion
946
1195
  //#region src/flow.ts
947
- var flow_exports = {};
948
- __export(flow_exports, {
949
- FlowError: () => FlowError,
950
- createInitialContext: () => createInitialContext,
951
- derive: () => derive$1,
952
- execute: () => execute,
953
- provide: () => provide$1
1196
+ const ok = (data) => ({
1197
+ type: "ok",
1198
+ data
954
1199
  });
955
- function createInitialContext(initializers) {
956
- const context = new Map();
957
- for (const [_, config] of Object.entries(initializers)) {
958
- const { accessor, value } = config;
959
- context.set(accessor.key, value);
1200
+ const ko = (data) => ({
1201
+ type: "ko",
1202
+ data
1203
+ });
1204
+ const FlowExecutionContext = {
1205
+ depth: accessor("flow.depth", custom(), 0),
1206
+ flowName: accessor("flow.name", custom()),
1207
+ parentFlowName: accessor("flow.parentName", custom()),
1208
+ isParallel: accessor("flow.isParallel", custom(), false)
1209
+ };
1210
+ var FlowDefinition = class {
1211
+ constructor(name$1, version, input, success, error) {
1212
+ this.name = name$1;
1213
+ this.version = version;
1214
+ this.input = input;
1215
+ this.success = success;
1216
+ this.error = error;
960
1217
  }
961
- return context;
962
- }
963
- function provide$1(config, handler) {
964
- const executor = createExecutor(() => ({
965
- execution: handler,
966
- input: config.input,
967
- output: config.output,
968
- plugins: config.plugins || [],
969
- metas: config.metas || [],
970
- name: config.name,
971
- description: config.description
972
- }), void 0, config.metas || []);
973
- Object.assign(executor, config);
974
- return executor;
975
- }
976
- function derive$1({ dependencies,...config }, handler) {
977
- const executor = createExecutor((deps) => ({
978
- execution: (input, controller) => handler(deps, input, controller),
979
- input: config.input,
980
- output: config.output,
981
- plugins: config.plugins || [],
982
- metas: config.metas || [],
983
- name: config.name,
984
- description: config.description
985
- }), dependencies, config.metas || []);
986
- Object.assign(executor, config);
987
- return executor;
1218
+ provide(handler) {
1219
+ return createExecutor(() => {
1220
+ const flowHandler = async (ctx) => {
1221
+ return handler(ctx, ctx.input);
1222
+ };
1223
+ flowHandler.def = this;
1224
+ return flowHandler;
1225
+ }, void 0, void 0);
1226
+ }
1227
+ derive(dependencies, handler) {
1228
+ return createExecutor((deps) => {
1229
+ const flowHandler = async (ctx) => {
1230
+ return handler(deps, ctx, ctx.input);
1231
+ };
1232
+ flowHandler.def = this;
1233
+ return flowHandler;
1234
+ }, dependencies, void 0);
1235
+ }
1236
+ };
1237
+ function flow(config) {
1238
+ return new FlowDefinition(config.name, config.version || "1.0.0", config.input, config.success, config.error);
988
1239
  }
989
- var FlowError = class extends Error {
990
- code;
991
- category;
992
- constructor(message, details) {
993
- super(message);
994
- this.details = details;
995
- if (details && "cause" in details) this.cause = details.cause;
996
- this.name = "FlowError";
997
- if (details?.enhancedError) {
998
- this.code = details.errorCode || ErrorCodes.FLOW_EXECUTION_FAILED;
999
- this.category = details.errorCategory || "USER_ERROR";
1000
- } else {
1001
- this.code = ErrorCodes.FLOW_EXECUTION_FAILED;
1002
- this.category = "USER_ERROR";
1003
- }
1240
+ var FlowContext = class FlowContext {
1241
+ contextData = new Map();
1242
+ constructor(input, pod, plugins, parent) {
1243
+ this.input = input;
1244
+ this.pod = pod;
1245
+ this.plugins = plugins;
1246
+ this.parent = parent;
1004
1247
  }
1005
- /**
1006
- * Get the original enhanced error if available
1007
- */
1008
- getEnhancedError() {
1009
- return this.details?.enhancedError;
1248
+ initializeExecutionContext(flowName, isParallel = false) {
1249
+ const currentDepth = this.parent ? (FlowExecutionContext.depth.find(this.parent) || 0) + 1 : 0;
1250
+ const parentFlowName = this.parent ? FlowExecutionContext.flowName.find(this.parent) : void 0;
1251
+ FlowExecutionContext.depth.set(this, currentDepth);
1252
+ FlowExecutionContext.flowName.set(this, flowName);
1253
+ FlowExecutionContext.parentFlowName.set(this, parentFlowName);
1254
+ FlowExecutionContext.isParallel.set(this, isParallel);
1010
1255
  }
1011
- /**
1012
- * Get the error context from enhanced error if available
1013
- */
1014
- getErrorContext() {
1015
- return this.details?.errorContext;
1256
+ ok = (data) => ok(data);
1257
+ ko = (data) => ko(data);
1258
+ get(key) {
1259
+ if (this.contextData.has(key)) return this.contextData.get(key);
1260
+ return this.parent?.get(key);
1016
1261
  }
1017
- /**
1018
- * Get flow-specific context
1019
- */
1020
- getFlowContext() {
1021
- return {
1022
- flowName: this.details?.flowName,
1023
- flowDescription: this.details?.flowDescription
1024
- };
1262
+ set(key, value) {
1263
+ this.contextData.set(key, value);
1264
+ return value;
1025
1265
  }
1026
- };
1027
- function createController(context, opt) {
1028
- const controller = {
1029
- context,
1030
- safeExecute: async (flowDef, param, opts) => {
1031
- try {
1032
- let resolvedFlow;
1033
- if ("execution" in flowDef && typeof flowDef.execution === "function") resolvedFlow = flowDef;
1034
- else if (context.scope) resolvedFlow = await context.scope.pod().resolve(flowDef);
1035
- else throw new FlowError("Cannot resolve executor without a scope");
1036
- const validatedInput = validate(resolvedFlow.input, param);
1037
- const childData = new Map(context.data);
1038
- if (opts?.initialContext) for (const [key, value] of opts.initialContext) childData.set(key, value);
1039
- const childContext = {
1040
- data: childData,
1041
- parent: context,
1042
- scope: context.scope,
1043
- plugins: [...context.plugins, ...opts?.plugins || []],
1044
- flow: resolvedFlow,
1045
- get(key) {
1046
- return childData.get(key);
1047
- },
1048
- set(key, value) {
1049
- return childData.set(key, value);
1050
- }
1051
- };
1052
- const childController = createController(childContext, opt);
1053
- let execution = async () => resolvedFlow.execution(validatedInput, childController);
1054
- for (let i = childContext.plugins.length - 1; i >= 0; i--) {
1055
- const plugin$1 = childContext.plugins[i];
1056
- const prevExecution = execution;
1057
- execution = () => plugin$1.wrap(childContext, prevExecution);
1058
- }
1059
- const result = await execution();
1060
- return {
1061
- kind: "success",
1062
- value: result
1063
- };
1064
- } catch (error) {
1065
- const wrappedError = error instanceof FlowError ? error : new FlowError(error instanceof Error ? error.message : "Flow execution failed", { cause: error });
1066
- return {
1067
- kind: "error",
1068
- error: wrappedError
1069
- };
1070
- }
1071
- },
1072
- execute: async (flowDef, param, opts) => {
1073
- const result = await controller.safeExecute(flowDef, param, opts);
1074
- if (result.kind === "error") throw result.error;
1075
- return result.value;
1076
- }
1266
+ output = (success, value) => {
1267
+ return success ? this.ok(value) : this.ko(value);
1077
1268
  };
1078
- return controller;
1079
- }
1080
- async function execute(executor, input, opt) {
1081
- const isOwnScope = !opt?.scope;
1082
- const scope = opt?.scope || createScope();
1083
- const pod = scope.pod(...opt?.presets || []);
1084
- let flow;
1085
- try {
1086
- flow = await pod.resolve(executor);
1087
- } catch (error) {
1088
- if (error instanceof ExecutorResolutionError || error instanceof FactoryExecutionError) throw new FlowError(`Flow execution failed: ${error.message}`, {
1089
- cause: error,
1090
- enhancedError: error,
1091
- errorCode: error.code,
1092
- errorCategory: error.category,
1093
- errorContext: error.context,
1094
- flowName: opt?.name,
1095
- flowDescription: opt?.description
1096
- });
1097
- else {
1098
- const errorMessage = error instanceof Error ? error.message : String(error);
1099
- throw new FlowError(`Failed to resolve executor: ${errorMessage}`, {
1100
- cause: error,
1101
- flowName: opt?.name,
1102
- flowDescription: opt?.description
1103
- });
1104
- }
1269
+ async execute(flow$1, input) {
1270
+ const handler = await this.pod.resolve(flow$1);
1271
+ const childContext = new FlowContext(input, this.pod, this.plugins, this);
1272
+ childContext.initializeExecutionContext(handler.def.name, false);
1273
+ return await this.executeWithPlugins(handler, childContext);
1105
1274
  }
1106
- const contextData = opt?.initialContext || new Map();
1107
- const context = {
1108
- data: contextData,
1109
- parent: void 0,
1110
- scope,
1111
- plugins: opt?.plugins || [],
1112
- flow,
1113
- get(key) {
1114
- return contextData.get(key);
1115
- },
1116
- set(key, value) {
1117
- return contextData.set(key, value);
1275
+ async executeParallel(flows) {
1276
+ return Promise.all(flows.map(async ([flow$1, input]) => {
1277
+ const childContext = new FlowContext(input, this.pod, this.plugins, this);
1278
+ const handler = await this.pod.resolve(flow$1);
1279
+ childContext.initializeExecutionContext(handler.def.name, true);
1280
+ return this.executeWithPlugins(handler, childContext);
1281
+ }));
1282
+ }
1283
+ async executeWithPlugins(handler, context) {
1284
+ const executeCore = async () => handler(context);
1285
+ let executor = executeCore;
1286
+ for (const plugin$1 of [...this.plugins].reverse()) if (plugin$1.wrap) {
1287
+ const currentExecutor = executor;
1288
+ executor = async () => plugin$1.wrap(context, currentExecutor);
1118
1289
  }
1119
- };
1120
- const controller = createController(context, opt);
1121
- const flowWithContext = {
1122
- ...flow,
1123
- context
1124
- };
1125
- let executionResult;
1290
+ return executor();
1291
+ }
1292
+ };
1293
+ async function execute(flow$1, input, options) {
1294
+ const scope = options?.scope || createScope();
1295
+ const shouldDisposeScope = !options?.scope;
1296
+ const pod = scope.pod(...options?.presets || []);
1126
1297
  try {
1127
- const validatedInput = validate(flow.input, input);
1128
- let execution = async () => flow.execution(validatedInput, controller);
1129
- for (let i = context.plugins.length - 1; i >= 0; i--) {
1130
- const plugin$1 = context.plugins[i];
1131
- const prevExecution = execution;
1132
- execution = () => plugin$1.wrap(context, prevExecution);
1298
+ const context = new FlowContext(input, pod, options?.plugins || []);
1299
+ if (options?.initialContext) {
1300
+ if (Array.isArray(options.initialContext)) for (const [accessor$1, value] of options.initialContext) accessor$1.set(context, value);
1301
+ else if (options.initialContext instanceof Map) for (const [key, value] of options.initialContext) context.set(key, value);
1133
1302
  }
1134
- const result = await execution();
1135
- executionResult = {
1136
- kind: "success",
1137
- value: result
1303
+ for (const plugin$1 of options?.plugins || []) await plugin$1.init?.(pod, context);
1304
+ const executeCore = async () => {
1305
+ const handler = await pod.resolve(flow$1);
1306
+ const validated = validate(handler.def.input, input);
1307
+ context.input = validated;
1308
+ context.initializeExecutionContext(handler.def.name, false);
1309
+ const result = await handler(context);
1310
+ if (result.type === "ok") validate(handler.def.success, result.data);
1311
+ else validate(handler.def.error, result.data);
1312
+ return result;
1138
1313
  };
1139
- } catch (error) {
1140
- const wrappedError = error instanceof FlowError ? error : new FlowError(error instanceof Error ? error.message : "Flow execution failed", { cause: error });
1141
- executionResult = {
1142
- kind: "error",
1143
- error: wrappedError
1144
- };
1145
- }
1146
- if (isOwnScope) await scope.dispose();
1147
- else await scope.disposePod(pod);
1148
- return {
1149
- context: flowWithContext.context,
1150
- result: executionResult
1151
- };
1152
- }
1153
-
1154
- //#endregion
1155
- //#region src/data-accessor.ts
1156
- const data = (key, schema) => {
1157
- const _key = typeof key === "string" ? Symbol(key) : key;
1158
- return {
1159
- key: _key,
1160
- get(store) {
1161
- const value = store.get(_key);
1162
- if (value === void 0) throw new Error(`Data not found for key: ${String(key)}`);
1163
- return validate(schema, value);
1164
- },
1165
- find(store) {
1166
- const maybeValue = store.get(_key);
1167
- if (maybeValue) return validate(schema, maybeValue);
1168
- return void 0;
1169
- },
1170
- set(store, value) {
1171
- const validated = validate(schema, value);
1172
- store.set(_key, validated);
1173
- },
1174
- preset(value) {
1175
- return [_key, value];
1314
+ let executor = executeCore;
1315
+ for (const plugin$1 of [...options?.plugins || []].reverse()) if (plugin$1.wrap) {
1316
+ const currentExecutor = executor;
1317
+ executor = () => plugin$1.wrap(context, currentExecutor);
1176
1318
  }
1177
- };
1178
- };
1179
-
1180
- //#endregion
1181
- //#region src/helpers.ts
1182
- async function resolves(scope, executors) {
1183
- const objectOutput = {};
1184
- const arrayOutput = [];
1185
- const isArray = Array.isArray(executors);
1186
- for (const [index, executor] of Object.entries(executors)) {
1187
- const target = !isExecutor(executor) ? executor.escape() : isLazyExecutor(executor) || isReactiveExecutor(executor) || isStaticExecutor(executor) ? executor.executor : executor;
1188
- const result$1 = await scope.resolve(target);
1189
- if (isArray) arrayOutput.push(result$1);
1190
- else Object.assign(objectOutput, { [index]: result$1 });
1319
+ return await executor();
1320
+ } finally {
1321
+ for (const plugin$1 of options?.plugins || []) await plugin$1.dispose?.(pod);
1322
+ await scope.disposePod(pod);
1323
+ if (shouldDisposeScope) await scope.dispose();
1191
1324
  }
1192
- const result = isArray ? arrayOutput : objectOutput;
1193
- return result;
1194
- }
1195
- function prepare(scope, executor) {
1196
- const fn = async () => {
1197
- return await scope.resolve(executor);
1198
- };
1199
- return Object.assign(fn, { escape: () => {
1200
- return executor;
1201
- } });
1202
- }
1203
- function adapt(scope, executor) {
1204
- const fn = async (...args) => {
1205
- const fn$1 = await scope.resolve(executor);
1206
- return await fn$1(...args);
1207
- };
1208
- return Object.assign(fn, { escape: () => {
1209
- return executor;
1210
- } });
1211
1325
  }
1212
1326
 
1213
1327
  //#endregion
@@ -1234,8 +1348,9 @@ exports.ErrorCodes = ErrorCodes;
1234
1348
  exports.ErrorMessages = ErrorMessages;
1235
1349
  exports.ExecutorResolutionError = ExecutorResolutionError;
1236
1350
  exports.FactoryExecutionError = FactoryExecutionError;
1237
- exports.FlowError = FlowError;
1351
+ exports.FlowExecutionContext = FlowExecutionContext;
1238
1352
  exports.SchemaError = SchemaError;
1353
+ exports.accessor = accessor;
1239
1354
  exports.adapt = adapt;
1240
1355
  exports.buildDependencyChain = buildDependencyChain;
1241
1356
  exports.collectFromGenerator = collectFromGenerator;
@@ -1244,17 +1359,12 @@ exports.createFactoryError = createFactoryError;
1244
1359
  exports.createScope = createScope;
1245
1360
  exports.createSystemError = createSystemError;
1246
1361
  exports.custom = custom;
1247
- exports.dataAccessor = data;
1248
1362
  exports.derive = derive;
1363
+ exports.execute = execute;
1249
1364
  exports.executorSymbol = executorSymbol;
1250
1365
  exports.findValue = findValue;
1251
1366
  exports.findValues = findValues;
1252
- Object.defineProperty(exports, 'flow', {
1253
- enumerable: true,
1254
- get: function () {
1255
- return flow_exports;
1256
- }
1257
- });
1367
+ exports.flow = flow;
1258
1368
  exports.formatErrorMessage = formatErrorMessage;
1259
1369
  exports.getExecutorName = getExecutorName;
1260
1370
  exports.getValue = getValue;
@@ -1290,5 +1400,4 @@ exports.preset = preset;
1290
1400
  exports.processGenerator = processGenerator;
1291
1401
  exports.provide = provide;
1292
1402
  exports.resolves = resolves;
1293
- exports.validate = validate;
1294
- exports.validateAsync = validateAsync;
1403
+ exports.validate = validate;