@pumped-fn/core-next 0.5.53 → 0.5.55
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 +1294 -0
- package/dist/index.d.cts +490 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +144 -40
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +373 -79
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1294 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name$1 in all) __defProp(target, name$1, {
|
|
5
|
+
get: all[name$1],
|
|
6
|
+
enumerable: true
|
|
7
|
+
});
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
//#endregion
|
|
11
|
+
|
|
12
|
+
//#region src/types.ts
|
|
13
|
+
const executorSymbol = Symbol.for("@pumped-fn/core/executor");
|
|
14
|
+
const metaSymbol = Symbol.for("@pumped-fn/core/meta");
|
|
15
|
+
var SchemaError = class extends Error {
|
|
16
|
+
issues;
|
|
17
|
+
constructor(issues) {
|
|
18
|
+
super(issues[0].message);
|
|
19
|
+
this.name = "SchemaError";
|
|
20
|
+
this.issues = issues;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
var ExecutorResolutionError = class extends Error {
|
|
24
|
+
context;
|
|
25
|
+
code;
|
|
26
|
+
category;
|
|
27
|
+
constructor(message, context, code, category = "USER_ERROR", options) {
|
|
28
|
+
super(message);
|
|
29
|
+
if (options && "cause" in options) this.cause = options.cause;
|
|
30
|
+
this.name = "ExecutorResolutionError";
|
|
31
|
+
this.context = context;
|
|
32
|
+
this.code = code;
|
|
33
|
+
this.category = category;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
var FactoryExecutionError = class extends ExecutorResolutionError {
|
|
37
|
+
constructor(message, context, code, options) {
|
|
38
|
+
super(message, {
|
|
39
|
+
...context,
|
|
40
|
+
resolutionStage: "factory-execution"
|
|
41
|
+
}, code, "USER_ERROR", options);
|
|
42
|
+
this.name = "FactoryExecutionError";
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
var DependencyResolutionError = class extends ExecutorResolutionError {
|
|
46
|
+
missingDependency;
|
|
47
|
+
constructor(message, context, code, missingDependency, options) {
|
|
48
|
+
super(message, {
|
|
49
|
+
...context,
|
|
50
|
+
resolutionStage: "dependency-resolution"
|
|
51
|
+
}, code, "USER_ERROR", options);
|
|
52
|
+
this.name = "DependencyResolutionError";
|
|
53
|
+
this.missingDependency = missingDependency;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/ssch.ts
|
|
59
|
+
function validate(schema, data$1) {
|
|
60
|
+
const result = schema["~standard"].validate(data$1);
|
|
61
|
+
if ("then" in result) throw new Error("validating async is not supported");
|
|
62
|
+
if (result.issues) throw new SchemaError(result.issues);
|
|
63
|
+
return result.value;
|
|
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
|
+
function custom() {
|
|
76
|
+
return { "~standard": {
|
|
77
|
+
vendor: "pumped-fn",
|
|
78
|
+
version: 1,
|
|
79
|
+
validate: (value) => {
|
|
80
|
+
return { value };
|
|
81
|
+
}
|
|
82
|
+
} };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/meta.ts
|
|
87
|
+
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
|
+
});
|
|
95
|
+
Object.defineProperty(fn, "key", {
|
|
96
|
+
value: _key,
|
|
97
|
+
configurable: false,
|
|
98
|
+
enumerable: false,
|
|
99
|
+
writable: false
|
|
100
|
+
});
|
|
101
|
+
Object.defineProperty(fn, metaSymbol, {
|
|
102
|
+
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
|
+
}
|
|
134
|
+
});
|
|
135
|
+
return fn;
|
|
136
|
+
};
|
|
137
|
+
function getValue(meta$1) {
|
|
138
|
+
return validate(meta$1.schema, meta$1.value);
|
|
139
|
+
}
|
|
140
|
+
function findValues(executor, meta$1) {
|
|
141
|
+
if (!executor) return [];
|
|
142
|
+
const metas = Array.isArray(executor) ? executor : executor.metas ?? [];
|
|
143
|
+
const maybeMeta = metas.filter((m) => m.key === meta$1.key);
|
|
144
|
+
return maybeMeta.map((m) => getValue(m));
|
|
145
|
+
}
|
|
146
|
+
function findValue(executor, meta$1) {
|
|
147
|
+
const values = findValues(executor, meta$1);
|
|
148
|
+
return values.at(0);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
//#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;
|
|
209
|
+
}
|
|
210
|
+
function isLazyExecutor(executor) {
|
|
211
|
+
return executor[executorSymbol] === "lazy";
|
|
212
|
+
}
|
|
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;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
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;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
//#endregion
|
|
363
|
+
//#region src/error-codes.ts
|
|
364
|
+
/**
|
|
365
|
+
* Systematic error codes for Pumped Functions
|
|
366
|
+
*/
|
|
367
|
+
const ErrorCodes = {
|
|
368
|
+
FACTORY_EXECUTION_FAILED: "F001",
|
|
369
|
+
FACTORY_THREW_ERROR: "F002",
|
|
370
|
+
FACTORY_RETURNED_INVALID_TYPE: "F003",
|
|
371
|
+
FACTORY_ASYNC_ERROR: "F004",
|
|
372
|
+
FACTORY_GENERATOR_ERROR: "F005",
|
|
373
|
+
DEPENDENCY_NOT_FOUND: "D001",
|
|
374
|
+
CIRCULAR_DEPENDENCY: "D002",
|
|
375
|
+
DEPENDENCY_RESOLUTION_FAILED: "D003",
|
|
376
|
+
INVALID_DEPENDENCY_TYPE: "D004",
|
|
377
|
+
DEPENDENCY_CHAIN_TOO_DEEP: "D005",
|
|
378
|
+
SCOPE_DISPOSED: "S001",
|
|
379
|
+
EXECUTOR_NOT_RESOLVED: "S002",
|
|
380
|
+
INVALID_SCOPE_STATE: "S003",
|
|
381
|
+
SCOPE_CLEANUP_FAILED: "S004",
|
|
382
|
+
REACTIVE_EXECUTOR_IN_POD: "S005",
|
|
383
|
+
UPDATE_CALLBACK_ON_DISPOSING_SCOPE: "S006",
|
|
384
|
+
SCHEMA_VALIDATION_FAILED: "V001",
|
|
385
|
+
META_VALIDATION_FAILED: "V002",
|
|
386
|
+
INPUT_TYPE_MISMATCH: "V003",
|
|
387
|
+
OUTPUT_TYPE_MISMATCH: "V004",
|
|
388
|
+
ASYNC_VALIDATION_NOT_SUPPORTED: "V005",
|
|
389
|
+
INTERNAL_RESOLUTION_ERROR: "SYS001",
|
|
390
|
+
CACHE_CORRUPTION: "SYS002",
|
|
391
|
+
MEMORY_LEAK_DETECTED: "SYS003",
|
|
392
|
+
PLUGIN_SYSTEM_ERROR: "SYS004",
|
|
393
|
+
INVALID_EXECUTOR_CONFIG: "C001",
|
|
394
|
+
MALFORMED_DEPENDENCIES: "C002",
|
|
395
|
+
INVALID_FACTORY_SIGNATURE: "C003",
|
|
396
|
+
PRESET_APPLICATION_FAILED: "C004",
|
|
397
|
+
FLOW_EXECUTION_FAILED: "FL001",
|
|
398
|
+
FLOW_CONTEXT_MISSING: "FL002",
|
|
399
|
+
FLOW_PLUGIN_ERROR: "FL003",
|
|
400
|
+
FLOW_INPUT_VALIDATION_FAILED: "FL004",
|
|
401
|
+
FLOW_OUTPUT_VALIDATION_FAILED: "FL005"
|
|
402
|
+
};
|
|
403
|
+
/**
|
|
404
|
+
* Error message templates with placeholder support
|
|
405
|
+
*/
|
|
406
|
+
const ErrorMessages = {
|
|
407
|
+
[ErrorCodes.FACTORY_EXECUTION_FAILED]: "Factory function execution failed for executor '{executorName}'. {cause}",
|
|
408
|
+
[ErrorCodes.FACTORY_THREW_ERROR]: "Factory function threw an error in executor '{executorName}': {originalMessage}",
|
|
409
|
+
[ErrorCodes.FACTORY_RETURNED_INVALID_TYPE]: "Factory function returned invalid type. Expected {expectedType}, got {actualType}",
|
|
410
|
+
[ErrorCodes.FACTORY_ASYNC_ERROR]: "Async factory function failed with error: {originalMessage}",
|
|
411
|
+
[ErrorCodes.FACTORY_GENERATOR_ERROR]: "Generator factory function failed during execution: {originalMessage}",
|
|
412
|
+
[ErrorCodes.DEPENDENCY_NOT_FOUND]: "Dependency '{dependencyName}' could not be resolved in the current scope",
|
|
413
|
+
[ErrorCodes.CIRCULAR_DEPENDENCY]: "Circular dependency detected in chain: {dependencyChain}",
|
|
414
|
+
[ErrorCodes.DEPENDENCY_RESOLUTION_FAILED]: "Failed to resolve dependencies for executor '{executorName}': {cause}",
|
|
415
|
+
[ErrorCodes.INVALID_DEPENDENCY_TYPE]: "Invalid dependency type provided. Expected Executor, got {actualType}",
|
|
416
|
+
[ErrorCodes.DEPENDENCY_CHAIN_TOO_DEEP]: "Dependency resolution chain exceeded maximum depth of {maxDepth}",
|
|
417
|
+
[ErrorCodes.SCOPE_DISPOSED]: "Cannot perform operation on disposed scope",
|
|
418
|
+
[ErrorCodes.EXECUTOR_NOT_RESOLVED]: "Executor '{executorName}' is not resolved. Call resolve() first or check if resolution failed",
|
|
419
|
+
[ErrorCodes.INVALID_SCOPE_STATE]: "Scope is in invalid state for this operation: {currentState}",
|
|
420
|
+
[ErrorCodes.SCOPE_CLEANUP_FAILED]: "Scope cleanup failed: {cause}",
|
|
421
|
+
[ErrorCodes.REACTIVE_EXECUTOR_IN_POD]: "Reactive executors cannot be used in pod environments",
|
|
422
|
+
[ErrorCodes.UPDATE_CALLBACK_ON_DISPOSING_SCOPE]: "Cannot register update callback on a disposing scope",
|
|
423
|
+
[ErrorCodes.SCHEMA_VALIDATION_FAILED]: "Schema validation failed: {validationMessage}",
|
|
424
|
+
[ErrorCodes.META_VALIDATION_FAILED]: "Meta validation failed for key '{metaKey}': {validationMessage}",
|
|
425
|
+
[ErrorCodes.INPUT_TYPE_MISMATCH]: "Input type validation failed: {validationMessage}",
|
|
426
|
+
[ErrorCodes.OUTPUT_TYPE_MISMATCH]: "Output type validation failed: {validationMessage}",
|
|
427
|
+
[ErrorCodes.ASYNC_VALIDATION_NOT_SUPPORTED]: "Async validation is not currently supported",
|
|
428
|
+
[ErrorCodes.INTERNAL_RESOLUTION_ERROR]: "Internal error during executor resolution. This is likely a bug in Pumped Functions",
|
|
429
|
+
[ErrorCodes.CACHE_CORRUPTION]: "Executor cache corruption detected. Scope integrity compromised",
|
|
430
|
+
[ErrorCodes.MEMORY_LEAK_DETECTED]: "Potential memory leak detected in scope {scopeId}",
|
|
431
|
+
[ErrorCodes.PLUGIN_SYSTEM_ERROR]: "Plugin system error: {pluginName} - {cause}",
|
|
432
|
+
[ErrorCodes.INVALID_EXECUTOR_CONFIG]: "Invalid executor configuration: {configError}",
|
|
433
|
+
[ErrorCodes.MALFORMED_DEPENDENCIES]: "Malformed dependency structure: {dependencyError}",
|
|
434
|
+
[ErrorCodes.INVALID_FACTORY_SIGNATURE]: "Factory function has invalid signature. Expected (dependencies, controller) => value",
|
|
435
|
+
[ErrorCodes.PRESET_APPLICATION_FAILED]: "Failed to apply preset: {presetError}",
|
|
436
|
+
[ErrorCodes.FLOW_EXECUTION_FAILED]: "Flow execution failed: {flowName}",
|
|
437
|
+
[ErrorCodes.FLOW_CONTEXT_MISSING]: "Flow execution context is missing or invalid",
|
|
438
|
+
[ErrorCodes.FLOW_PLUGIN_ERROR]: "Flow plugin '{pluginName}' failed: {cause}",
|
|
439
|
+
[ErrorCodes.FLOW_INPUT_VALIDATION_FAILED]: "Flow input validation failed: {validationMessage}",
|
|
440
|
+
[ErrorCodes.FLOW_OUTPUT_VALIDATION_FAILED]: "Flow output validation failed: {validationMessage}"
|
|
441
|
+
};
|
|
442
|
+
/**
|
|
443
|
+
* Utility function to format error messages with context
|
|
444
|
+
*/
|
|
445
|
+
function formatErrorMessage(code, context = {}) {
|
|
446
|
+
let message = ErrorMessages[code];
|
|
447
|
+
for (const [key, value] of Object.entries(context)) {
|
|
448
|
+
const placeholder = `{${key}}`;
|
|
449
|
+
message = message.replace(new RegExp(placeholder, "g"), String(value));
|
|
450
|
+
}
|
|
451
|
+
return message;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Utility functions for creating enhanced errors with proper context
|
|
455
|
+
*/
|
|
456
|
+
function createFactoryError(code, executorName, dependencyChain, originalError, additionalContext = {}) {
|
|
457
|
+
const context = {
|
|
458
|
+
executorName,
|
|
459
|
+
dependencyChain,
|
|
460
|
+
timestamp: Date.now(),
|
|
461
|
+
additionalInfo: additionalContext
|
|
462
|
+
};
|
|
463
|
+
const messageContext = {
|
|
464
|
+
executorName,
|
|
465
|
+
originalMessage: originalError instanceof Error ? originalError.message : String(originalError),
|
|
466
|
+
cause: originalError instanceof Error ? originalError.message : String(originalError),
|
|
467
|
+
...additionalContext
|
|
468
|
+
};
|
|
469
|
+
const message = formatErrorMessage(code, messageContext);
|
|
470
|
+
return new FactoryExecutionError(message, context, code, { cause: originalError });
|
|
471
|
+
}
|
|
472
|
+
function createDependencyError(code, executorName, dependencyChain, missingDependency, originalError, additionalContext = {}) {
|
|
473
|
+
const context = {
|
|
474
|
+
executorName,
|
|
475
|
+
dependencyChain,
|
|
476
|
+
timestamp: Date.now(),
|
|
477
|
+
additionalInfo: additionalContext
|
|
478
|
+
};
|
|
479
|
+
const messageContext = {
|
|
480
|
+
executorName,
|
|
481
|
+
dependencyName: missingDependency,
|
|
482
|
+
dependencyChain: dependencyChain.join(" -> "),
|
|
483
|
+
cause: originalError instanceof Error ? originalError.message : String(originalError),
|
|
484
|
+
...additionalContext
|
|
485
|
+
};
|
|
486
|
+
const message = formatErrorMessage(code, messageContext);
|
|
487
|
+
return new DependencyResolutionError(message, context, code, missingDependency, { cause: originalError });
|
|
488
|
+
}
|
|
489
|
+
function createSystemError(code, executorName, dependencyChain, originalError, additionalContext = {}) {
|
|
490
|
+
const context = {
|
|
491
|
+
executorName,
|
|
492
|
+
dependencyChain,
|
|
493
|
+
resolutionStage: "post-processing",
|
|
494
|
+
timestamp: Date.now(),
|
|
495
|
+
additionalInfo: additionalContext
|
|
496
|
+
};
|
|
497
|
+
const messageContext = {
|
|
498
|
+
executorName,
|
|
499
|
+
cause: originalError instanceof Error ? originalError.message : String(originalError),
|
|
500
|
+
...additionalContext
|
|
501
|
+
};
|
|
502
|
+
const message = formatErrorMessage(code, messageContext);
|
|
503
|
+
return new ExecutorResolutionError(message, context, code, "SYSTEM_ERROR", { cause: originalError });
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Helper to extract executor name from executor object for error context
|
|
507
|
+
*/
|
|
508
|
+
function getExecutorName(executor) {
|
|
509
|
+
if (executor?.metas && Array.isArray(executor.metas)) for (const meta$1 of executor.metas) {
|
|
510
|
+
if (meta$1?.key && typeof meta$1.key === "symbol") {
|
|
511
|
+
const keyString = meta$1.key.toString();
|
|
512
|
+
if (keyString.includes("name") || keyString.includes("pumped-fn/name")) return String(meta$1.value);
|
|
513
|
+
}
|
|
514
|
+
if (typeof meta$1?.key === "string" && meta$1.key.includes("name")) return String(meta$1.value);
|
|
515
|
+
}
|
|
516
|
+
if (executor?.factory?.name && executor.factory.name !== "factory") return executor.factory.name;
|
|
517
|
+
if (executor) {
|
|
518
|
+
const kind = executor[Symbol.for("@pumped-fn/core/executor")] || "unknown";
|
|
519
|
+
return `${kind}-executor-${Math.random().toString(36).substr(2, 9)}`;
|
|
520
|
+
}
|
|
521
|
+
return "unknown-executor";
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Helper to build dependency chain for error context
|
|
525
|
+
*/
|
|
526
|
+
function buildDependencyChain(executorStack) {
|
|
527
|
+
return executorStack.map((executor) => getExecutorName(executor));
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
//#endregion
|
|
531
|
+
//#region src/scope.ts
|
|
532
|
+
function getExecutor(e) {
|
|
533
|
+
if (isLazyExecutor(e) || isReactiveExecutor(e) || isStaticExecutor(e)) return e.executor;
|
|
534
|
+
return e;
|
|
535
|
+
}
|
|
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()
|
|
544
|
+
};
|
|
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);
|
|
555
|
+
}
|
|
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();
|
|
559
|
+
}
|
|
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);
|
|
570
|
+
}
|
|
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();
|
|
583
|
+
}
|
|
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;
|
|
593
|
+
}
|
|
594
|
+
return r;
|
|
595
|
+
}
|
|
596
|
+
"~ensureNotDisposed"() {
|
|
597
|
+
if (this.disposed) throw new Error("Scope is disposed");
|
|
598
|
+
}
|
|
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);
|
|
619
|
+
const cached = entry?.value;
|
|
620
|
+
if (cached && !force) if (cached.kind === "resolved") return Promise.resolve(cached.value);
|
|
621
|
+
else if (cached.kind === "rejected") throw cached.error;
|
|
622
|
+
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;
|
|
627
|
+
if (replacer) {
|
|
628
|
+
const value = replacer.value;
|
|
629
|
+
if (!isExecutor(value)) return setTimeout(() => {
|
|
630
|
+
this.cache.set(requestor, {
|
|
631
|
+
accessor,
|
|
632
|
+
value: {
|
|
633
|
+
kind: "resolved",
|
|
634
|
+
value: replacer.value
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
resolve$1(replacer.value);
|
|
638
|
+
}, 0);
|
|
639
|
+
factory = value.factory;
|
|
640
|
+
dependencies = value.dependencies;
|
|
641
|
+
}
|
|
642
|
+
this["~resolveDependencies"](dependencies, requestor).then((dependencies$1) => {
|
|
643
|
+
try {
|
|
644
|
+
const factoryResult = factory(dependencies$1, controller);
|
|
645
|
+
if (factoryResult instanceof Promise) return factoryResult.catch((asyncError) => {
|
|
646
|
+
const executorName = getExecutorName(requestor);
|
|
647
|
+
const dependencyChain = [executorName];
|
|
648
|
+
const factoryError = createFactoryError(ErrorCodes.FACTORY_ASYNC_ERROR, executorName, dependencyChain, asyncError, {
|
|
649
|
+
dependenciesResolved: dependencies$1 !== void 0,
|
|
650
|
+
factoryType: typeof factory,
|
|
651
|
+
isAsyncFactory: true
|
|
652
|
+
});
|
|
653
|
+
throw factoryError;
|
|
654
|
+
});
|
|
655
|
+
return factoryResult;
|
|
656
|
+
} catch (error) {
|
|
657
|
+
const executorName = getExecutorName(requestor);
|
|
658
|
+
const dependencyChain = [executorName];
|
|
659
|
+
const factoryError = createFactoryError(ErrorCodes.FACTORY_THREW_ERROR, executorName, dependencyChain, error, {
|
|
660
|
+
dependenciesResolved: dependencies$1 !== void 0,
|
|
661
|
+
factoryType: typeof factory,
|
|
662
|
+
isAsyncFactory: false
|
|
663
|
+
});
|
|
664
|
+
throw factoryError;
|
|
665
|
+
}
|
|
666
|
+
}).then(async (result) => {
|
|
667
|
+
let current = result;
|
|
668
|
+
if (isGenerator(result) || isAsyncGenerator(result)) try {
|
|
669
|
+
const { returned } = await collectFromGenerator(result);
|
|
670
|
+
current = returned;
|
|
671
|
+
} catch (generatorError) {
|
|
672
|
+
const executorName = getExecutorName(requestor);
|
|
673
|
+
const dependencyChain = [executorName];
|
|
674
|
+
const factoryError = createFactoryError(ErrorCodes.FACTORY_GENERATOR_ERROR, executorName, dependencyChain, generatorError, {
|
|
675
|
+
generatorType: isGenerator(result) ? "sync" : "async",
|
|
676
|
+
factoryType: typeof factory
|
|
677
|
+
});
|
|
678
|
+
throw factoryError;
|
|
679
|
+
}
|
|
680
|
+
const events = this.onEvents.change;
|
|
681
|
+
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;
|
|
684
|
+
}
|
|
685
|
+
this.cache.set(requestor, {
|
|
686
|
+
accessor,
|
|
687
|
+
value: {
|
|
688
|
+
kind: "resolved",
|
|
689
|
+
value: current
|
|
690
|
+
}
|
|
691
|
+
});
|
|
692
|
+
resolve$1(current);
|
|
693
|
+
}).catch((error) => {
|
|
694
|
+
let enhancedError = error;
|
|
695
|
+
let errorContext = void 0;
|
|
696
|
+
if (error?.context && error?.code) {
|
|
697
|
+
enhancedError = error;
|
|
698
|
+
errorContext = error.context;
|
|
699
|
+
} else {
|
|
700
|
+
const executorName = getExecutorName(requestor);
|
|
701
|
+
const dependencyChain = [executorName];
|
|
702
|
+
enhancedError = createSystemError(ErrorCodes.INTERNAL_RESOLUTION_ERROR, executorName, dependencyChain, error, {
|
|
703
|
+
errorType: error?.constructor?.name || "UnknownError",
|
|
704
|
+
resolutionPhase: "post-factory"
|
|
705
|
+
});
|
|
706
|
+
errorContext = enhancedError.context;
|
|
707
|
+
}
|
|
708
|
+
this.cache.set(requestor, {
|
|
709
|
+
accessor,
|
|
710
|
+
value: {
|
|
711
|
+
kind: "rejected",
|
|
712
|
+
error,
|
|
713
|
+
context: errorContext,
|
|
714
|
+
enhancedError
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
reject(enhancedError);
|
|
718
|
+
});
|
|
719
|
+
});
|
|
720
|
+
this.cache.set(requestor, {
|
|
721
|
+
accessor,
|
|
722
|
+
value: {
|
|
723
|
+
kind: "pending",
|
|
724
|
+
promise
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
return promise;
|
|
728
|
+
};
|
|
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);
|
|
750
|
+
},
|
|
751
|
+
set: async (value) => {
|
|
752
|
+
return this.update(requestor, value);
|
|
753
|
+
},
|
|
754
|
+
subscribe: (cb) => {
|
|
755
|
+
this["~ensureNotDisposed"]();
|
|
756
|
+
return this.onUpdate(requestor, cb);
|
|
757
|
+
}
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
accessor(executor) {
|
|
761
|
+
this["~ensureNotDisposed"]();
|
|
762
|
+
return this["~makeAccessor"](executor);
|
|
763
|
+
}
|
|
764
|
+
entries() {
|
|
765
|
+
return Array.from(this.cache.entries()).map(([executor, entry]) => {
|
|
766
|
+
return [executor, entry.accessor];
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
async resolve(executor, force = false) {
|
|
770
|
+
this["~ensureNotDisposed"]();
|
|
771
|
+
const accessor = this["~makeAccessor"](executor);
|
|
772
|
+
await accessor.resolve(force);
|
|
773
|
+
return accessor.get();
|
|
774
|
+
}
|
|
775
|
+
async resolveAccessor(executor, force = false) {
|
|
776
|
+
this["~ensureNotDisposed"]();
|
|
777
|
+
const accessor = this["~makeAccessor"](executor);
|
|
778
|
+
await accessor.resolve(force);
|
|
779
|
+
return accessor;
|
|
780
|
+
}
|
|
781
|
+
async update(e, u) {
|
|
782
|
+
if (this.isDisposing) return;
|
|
783
|
+
this["~ensureNotDisposed"]();
|
|
784
|
+
this["~triggerCleanup"](e);
|
|
785
|
+
const accessor = this["~makeAccessor"](e);
|
|
786
|
+
let value;
|
|
787
|
+
if (typeof u === "function") {
|
|
788
|
+
const fn = u;
|
|
789
|
+
value = fn(accessor.get());
|
|
790
|
+
} else value = u;
|
|
791
|
+
const events = this.onEvents.change;
|
|
792
|
+
for (const event of events) {
|
|
793
|
+
const updated = await event("update", e, value, this);
|
|
794
|
+
if (updated !== void 0 && e === updated.executor) value = updated.value;
|
|
795
|
+
}
|
|
796
|
+
this.cache.set(e, {
|
|
797
|
+
accessor,
|
|
798
|
+
value: {
|
|
799
|
+
kind: "resolved",
|
|
800
|
+
value
|
|
801
|
+
}
|
|
802
|
+
});
|
|
803
|
+
await this["~triggerUpdate"](e);
|
|
804
|
+
}
|
|
805
|
+
async set(e, value) {
|
|
806
|
+
return this.update(e, value);
|
|
807
|
+
}
|
|
808
|
+
async release(e, s = false) {
|
|
809
|
+
this["~ensureNotDisposed"]();
|
|
810
|
+
const ce = this.cache.get(e);
|
|
811
|
+
if (!ce && !s) throw new Error("Executor is not yet resolved");
|
|
812
|
+
await this["~triggerCleanup"](e);
|
|
813
|
+
const events = this.onEvents.release;
|
|
814
|
+
for (const event of events) await event("release", e, this);
|
|
815
|
+
const ou = this.onUpdates.get(e);
|
|
816
|
+
if (ou) {
|
|
817
|
+
for (const t of Array.from(ou.values())) if (isMainExecutor(t)) await this.release(t, true);
|
|
818
|
+
this.onUpdates.delete(e);
|
|
819
|
+
}
|
|
820
|
+
this.cache.delete(e);
|
|
821
|
+
}
|
|
822
|
+
async dispose() {
|
|
823
|
+
this["~ensureNotDisposed"]();
|
|
824
|
+
this.isDisposing = true;
|
|
825
|
+
for (const pod of this.pods) await this.disposePod(pod);
|
|
826
|
+
const disposeEvents = this.plugins.map((m) => m.dispose?.(this) ?? Promise.resolve());
|
|
827
|
+
await Promise.all(disposeEvents);
|
|
828
|
+
const currents = this.cache.keys();
|
|
829
|
+
for (const current of currents) await this.release(current, true);
|
|
830
|
+
this.disposed = true;
|
|
831
|
+
this.cache.clear();
|
|
832
|
+
this.cleanups.clear();
|
|
833
|
+
this.onUpdates.clear();
|
|
834
|
+
this.onEvents.change.clear();
|
|
835
|
+
this.onEvents.release.clear();
|
|
836
|
+
}
|
|
837
|
+
onUpdate(e, cb) {
|
|
838
|
+
this["~ensureNotDisposed"]();
|
|
839
|
+
if (this.isDisposing) throw new Error("Cannot register update callback on a disposing scope");
|
|
840
|
+
const ou = this.onUpdates.get(e) ?? new Set();
|
|
841
|
+
this.onUpdates.set(e, ou);
|
|
842
|
+
ou.add(cb);
|
|
843
|
+
return () => {
|
|
844
|
+
this["~ensureNotDisposed"]();
|
|
845
|
+
const ou$1 = this.onUpdates.get(e);
|
|
846
|
+
if (ou$1) {
|
|
847
|
+
ou$1.delete(cb);
|
|
848
|
+
if (ou$1.size === 0) this.onUpdates.delete(e);
|
|
849
|
+
}
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
onChange(callback) {
|
|
853
|
+
this["~ensureNotDisposed"]();
|
|
854
|
+
if (this.isDisposing) throw new Error("Cannot register update callback on a disposing scope");
|
|
855
|
+
this.onEvents["change"].add(callback);
|
|
856
|
+
return () => {
|
|
857
|
+
this["~ensureNotDisposed"]();
|
|
858
|
+
this.onEvents["change"].delete(callback);
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
onRelease(cb) {
|
|
862
|
+
this["~ensureNotDisposed"]();
|
|
863
|
+
if (this.isDisposing) throw new Error("Cannot register update callback on a disposing scope");
|
|
864
|
+
this.onEvents["release"].add(cb);
|
|
865
|
+
return () => {
|
|
866
|
+
this["~ensureNotDisposed"]();
|
|
867
|
+
this.onEvents["release"].delete(cb);
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
use(plugin$1) {
|
|
871
|
+
this["~ensureNotDisposed"]();
|
|
872
|
+
if (this.isDisposing) throw new Error("Cannot register update callback on a disposing scope");
|
|
873
|
+
this.plugins.push(plugin$1);
|
|
874
|
+
plugin$1.init?.(this, { registry: this.registry });
|
|
875
|
+
return () => {
|
|
876
|
+
this["~ensureNotDisposed"]();
|
|
877
|
+
this.plugins = this.plugins.filter((m) => m !== plugin$1);
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
pods = new Set();
|
|
881
|
+
pod(...preset$1) {
|
|
882
|
+
this["~ensureNotDisposed"]();
|
|
883
|
+
if (this.isDisposing) throw new Error("Cannot register update callback on a disposing scope");
|
|
884
|
+
const pod = new Pod(this, { initialValues: preset$1 });
|
|
885
|
+
this.pods.add(pod);
|
|
886
|
+
return pod;
|
|
887
|
+
}
|
|
888
|
+
async disposePod(pod) {
|
|
889
|
+
this["~ensureNotDisposed"]();
|
|
890
|
+
if (this.isDisposing) return;
|
|
891
|
+
await pod.dispose();
|
|
892
|
+
this.pods.delete(pod);
|
|
893
|
+
}
|
|
894
|
+
};
|
|
895
|
+
function createScope(...opt) {
|
|
896
|
+
if (opt.at(0) === void 0) return new BaseScope();
|
|
897
|
+
if (opt.length === 1 && !isPreset(opt[0])) return new BaseScope(opt[0]);
|
|
898
|
+
return new BaseScope({ initialValues: opt });
|
|
899
|
+
}
|
|
900
|
+
function plugin(m) {
|
|
901
|
+
return m;
|
|
902
|
+
}
|
|
903
|
+
var Pod = class extends BaseScope {
|
|
904
|
+
parentScope;
|
|
905
|
+
constructor(scope, option) {
|
|
906
|
+
super(option);
|
|
907
|
+
this.parentScope = scope;
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* Expect to resolve everything in pod. Unless it's already resolved in the main
|
|
911
|
+
* @param executor
|
|
912
|
+
* @param force
|
|
913
|
+
* @returns
|
|
914
|
+
*/
|
|
915
|
+
async resolve(executor, force) {
|
|
916
|
+
if (this.cache.has(executor)) return super.resolve(executor, force);
|
|
917
|
+
if (this.parentScope["cache"].has(executor)) {
|
|
918
|
+
const { value } = this.parentScope["cache"].get(executor);
|
|
919
|
+
const accessor = super["~makeAccessor"](executor);
|
|
920
|
+
this["cache"].set(executor, {
|
|
921
|
+
accessor,
|
|
922
|
+
value
|
|
923
|
+
});
|
|
924
|
+
if (value.kind === "rejected") throw value.error;
|
|
925
|
+
if (value.kind === "resolved") return value.value;
|
|
926
|
+
if (value.kind === "pending") return await value.promise;
|
|
927
|
+
}
|
|
928
|
+
return await super.resolve(executor, force);
|
|
929
|
+
}
|
|
930
|
+
async "~resolveExecutor"(ie, ref) {
|
|
931
|
+
if (isReactiveExecutor(ie)) throw new Error("Reactive executors cannot be used in pod");
|
|
932
|
+
const t = getExecutor(ie);
|
|
933
|
+
const a = this["~makeAccessor"](t);
|
|
934
|
+
if (this.parentScope["cache"].has(t)) {
|
|
935
|
+
const { value } = this.parentScope["cache"].get(t);
|
|
936
|
+
this["cache"].set(t, {
|
|
937
|
+
accessor: a,
|
|
938
|
+
value
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
return await super["~resolveExecutor"](ie, ref);
|
|
942
|
+
}
|
|
943
|
+
};
|
|
944
|
+
|
|
945
|
+
//#endregion
|
|
946
|
+
//#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
|
|
954
|
+
});
|
|
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);
|
|
960
|
+
}
|
|
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;
|
|
988
|
+
}
|
|
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
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* Get the original enhanced error if available
|
|
1007
|
+
*/
|
|
1008
|
+
getEnhancedError() {
|
|
1009
|
+
return this.details?.enhancedError;
|
|
1010
|
+
}
|
|
1011
|
+
/**
|
|
1012
|
+
* Get the error context from enhanced error if available
|
|
1013
|
+
*/
|
|
1014
|
+
getErrorContext() {
|
|
1015
|
+
return this.details?.errorContext;
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
1018
|
+
* Get flow-specific context
|
|
1019
|
+
*/
|
|
1020
|
+
getFlowContext() {
|
|
1021
|
+
return {
|
|
1022
|
+
flowName: this.details?.flowName,
|
|
1023
|
+
flowDescription: this.details?.flowDescription
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
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
|
+
}
|
|
1077
|
+
};
|
|
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
|
+
}
|
|
1105
|
+
}
|
|
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);
|
|
1118
|
+
}
|
|
1119
|
+
};
|
|
1120
|
+
const controller = createController(context, opt);
|
|
1121
|
+
const flowWithContext = {
|
|
1122
|
+
...flow,
|
|
1123
|
+
context
|
|
1124
|
+
};
|
|
1125
|
+
let executionResult;
|
|
1126
|
+
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);
|
|
1133
|
+
}
|
|
1134
|
+
const result = await execution();
|
|
1135
|
+
executionResult = {
|
|
1136
|
+
kind: "success",
|
|
1137
|
+
value: result
|
|
1138
|
+
};
|
|
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];
|
|
1176
|
+
}
|
|
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 });
|
|
1191
|
+
}
|
|
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
|
+
}
|
|
1212
|
+
|
|
1213
|
+
//#endregion
|
|
1214
|
+
//#region src/plugins.ts
|
|
1215
|
+
var plugins_exports = {};
|
|
1216
|
+
__export(plugins_exports, { eager: () => eager });
|
|
1217
|
+
const eager = {
|
|
1218
|
+
meta: meta(Symbol.for("@pumped-fn/plugin/eager"), custom()),
|
|
1219
|
+
plugin: () => ({ init(scope, { registry }) {
|
|
1220
|
+
for (const executor of registry) {
|
|
1221
|
+
const isEager = eager.meta.find(executor);
|
|
1222
|
+
if (isEager) scope.resolve(executor);
|
|
1223
|
+
}
|
|
1224
|
+
} })
|
|
1225
|
+
};
|
|
1226
|
+
|
|
1227
|
+
//#endregion
|
|
1228
|
+
//#region src/index.ts
|
|
1229
|
+
const name = meta("pumped-fn/name", custom());
|
|
1230
|
+
|
|
1231
|
+
//#endregion
|
|
1232
|
+
exports.DependencyResolutionError = DependencyResolutionError;
|
|
1233
|
+
exports.ErrorCodes = ErrorCodes;
|
|
1234
|
+
exports.ErrorMessages = ErrorMessages;
|
|
1235
|
+
exports.ExecutorResolutionError = ExecutorResolutionError;
|
|
1236
|
+
exports.FactoryExecutionError = FactoryExecutionError;
|
|
1237
|
+
exports.FlowError = FlowError;
|
|
1238
|
+
exports.SchemaError = SchemaError;
|
|
1239
|
+
exports.adapt = adapt;
|
|
1240
|
+
exports.buildDependencyChain = buildDependencyChain;
|
|
1241
|
+
exports.collectFromGenerator = collectFromGenerator;
|
|
1242
|
+
exports.createDependencyError = createDependencyError;
|
|
1243
|
+
exports.createFactoryError = createFactoryError;
|
|
1244
|
+
exports.createScope = createScope;
|
|
1245
|
+
exports.createSystemError = createSystemError;
|
|
1246
|
+
exports.custom = custom;
|
|
1247
|
+
exports.dataAccessor = data;
|
|
1248
|
+
exports.derive = derive;
|
|
1249
|
+
exports.executorSymbol = executorSymbol;
|
|
1250
|
+
exports.findValue = findValue;
|
|
1251
|
+
exports.findValues = findValues;
|
|
1252
|
+
Object.defineProperty(exports, 'flow', {
|
|
1253
|
+
enumerable: true,
|
|
1254
|
+
get: function () {
|
|
1255
|
+
return flow_exports;
|
|
1256
|
+
}
|
|
1257
|
+
});
|
|
1258
|
+
exports.formatErrorMessage = formatErrorMessage;
|
|
1259
|
+
exports.getExecutorName = getExecutorName;
|
|
1260
|
+
exports.getValue = getValue;
|
|
1261
|
+
exports.isAsyncGenerator = isAsyncGenerator;
|
|
1262
|
+
exports.isAsyncGeneratorFunction = isAsyncGeneratorFunction;
|
|
1263
|
+
exports.isExecutor = isExecutor;
|
|
1264
|
+
exports.isGenerator = isGenerator;
|
|
1265
|
+
exports.isGeneratorFunction = isGeneratorFunction;
|
|
1266
|
+
exports.isIterableOrAsyncIterable = isIterableOrAsyncIterable;
|
|
1267
|
+
exports.isLazyExecutor = isLazyExecutor;
|
|
1268
|
+
exports.isMainExecutor = isMainExecutor;
|
|
1269
|
+
exports.isPreset = isPreset;
|
|
1270
|
+
exports.isReactiveExecutor = isReactiveExecutor;
|
|
1271
|
+
exports.isStaticExecutor = isStaticExecutor;
|
|
1272
|
+
exports.meta = meta;
|
|
1273
|
+
exports.metaSymbol = metaSymbol;
|
|
1274
|
+
Object.defineProperty(exports, 'multi', {
|
|
1275
|
+
enumerable: true,
|
|
1276
|
+
get: function () {
|
|
1277
|
+
return multi_exports;
|
|
1278
|
+
}
|
|
1279
|
+
});
|
|
1280
|
+
exports.name = name;
|
|
1281
|
+
exports.plugin = plugin;
|
|
1282
|
+
Object.defineProperty(exports, 'plugins', {
|
|
1283
|
+
enumerable: true,
|
|
1284
|
+
get: function () {
|
|
1285
|
+
return plugins_exports;
|
|
1286
|
+
}
|
|
1287
|
+
});
|
|
1288
|
+
exports.prepare = prepare;
|
|
1289
|
+
exports.preset = preset;
|
|
1290
|
+
exports.processGenerator = processGenerator;
|
|
1291
|
+
exports.provide = provide;
|
|
1292
|
+
exports.resolves = resolves;
|
|
1293
|
+
exports.validate = validate;
|
|
1294
|
+
exports.validateAsync = validateAsync;
|