@bluelibs/runner 4.8.6 → 4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI.md +8 -0
- package/README.md +39 -4
- package/dist/browser/index.cjs +543 -418
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.d.mts +2221 -0
- package/dist/browser/index.d.ts +2221 -0
- package/dist/browser/index.mjs +543 -418
- package/dist/browser/index.mjs.map +1 -1
- package/dist/edge/index.cjs +543 -418
- package/dist/edge/index.cjs.map +1 -1
- package/dist/edge/index.d.mts +2221 -0
- package/dist/edge/index.d.ts +2221 -0
- package/dist/edge/index.mjs +543 -418
- package/dist/edge/index.mjs.map +1 -1
- package/dist/node/node.cjs +584 -436
- package/dist/node/node.cjs.map +1 -1
- package/dist/node/node.d.mts +2472 -0
- package/dist/node/node.d.ts +2425 -55
- package/dist/node/node.mjs +584 -436
- package/dist/node/node.mjs.map +1 -1
- package/dist/universal/index.cjs +541 -418
- package/dist/universal/index.cjs.map +1 -1
- package/dist/universal/index.d.mts +2221 -0
- package/dist/universal/index.d.ts +2221 -0
- package/dist/universal/index.mjs +541 -418
- package/dist/universal/index.mjs.map +1 -1
- package/package.json +5 -5
- package/dist/define.d.ts +0 -9
- package/dist/definers/builders/asyncContext.d.ts +0 -13
- package/dist/definers/builders/core.d.ts +0 -30
- package/dist/definers/builders/error.d.ts +0 -15
- package/dist/definers/builders/event.d.ts +0 -12
- package/dist/definers/builders/hook.d.ts +0 -20
- package/dist/definers/builders/middleware.d.ts +0 -39
- package/dist/definers/builders/resource.d.ts +0 -40
- package/dist/definers/builders/tag.d.ts +0 -10
- package/dist/definers/builders/task.d.ts +0 -37
- package/dist/definers/builders/task.phantom.d.ts +0 -27
- package/dist/definers/builders/utils.d.ts +0 -4
- package/dist/definers/defineAsyncContext.d.ts +0 -15
- package/dist/definers/defineError.d.ts +0 -26
- package/dist/definers/defineEvent.d.ts +0 -2
- package/dist/definers/defineHook.d.ts +0 -6
- package/dist/definers/defineOverride.d.ts +0 -17
- package/dist/definers/defineResource.d.ts +0 -2
- package/dist/definers/defineResourceMiddleware.d.ts +0 -2
- package/dist/definers/defineTag.d.ts +0 -12
- package/dist/definers/defineTask.d.ts +0 -18
- package/dist/definers/defineTaskMiddleware.d.ts +0 -2
- package/dist/definers/tools.d.ts +0 -53
- package/dist/defs.d.ts +0 -31
- package/dist/errors.d.ts +0 -62
- package/dist/globals/debug.d.ts +0 -10
- package/dist/globals/globalEvents.d.ts +0 -8
- package/dist/globals/globalMiddleware.d.ts +0 -31
- package/dist/globals/globalResources.d.ts +0 -41
- package/dist/globals/globalTags.d.ts +0 -11
- package/dist/globals/middleware/cache.middleware.d.ts +0 -27
- package/dist/globals/middleware/requireContext.middleware.d.ts +0 -6
- package/dist/globals/middleware/retry.middleware.d.ts +0 -21
- package/dist/globals/middleware/timeout.middleware.d.ts +0 -9
- package/dist/globals/middleware/tunnel.middleware.d.ts +0 -2
- package/dist/globals/resources/debug/debug.resource.d.ts +0 -7
- package/dist/globals/resources/debug/debug.tag.d.ts +0 -2
- package/dist/globals/resources/debug/debugConfig.resource.d.ts +0 -22
- package/dist/globals/resources/debug/executionTracker.middleware.d.ts +0 -50
- package/dist/globals/resources/debug/globalEvent.hook.d.ts +0 -27
- package/dist/globals/resources/debug/hook.hook.d.ts +0 -30
- package/dist/globals/resources/debug/index.d.ts +0 -6
- package/dist/globals/resources/debug/middleware.hook.d.ts +0 -30
- package/dist/globals/resources/debug/types.d.ts +0 -25
- package/dist/globals/resources/debug/utils.d.ts +0 -2
- package/dist/globals/resources/httpClientFactory.resource.d.ts +0 -28
- package/dist/globals/resources/queue.resource.d.ts +0 -10
- package/dist/globals/resources/tunnel/ejson-extensions.d.ts +0 -1
- package/dist/globals/resources/tunnel/error-utils.d.ts +0 -1
- package/dist/globals/resources/tunnel/plan.d.ts +0 -19
- package/dist/globals/resources/tunnel/protocol.d.ts +0 -47
- package/dist/globals/resources/tunnel/serializer.d.ts +0 -9
- package/dist/globals/resources/tunnel/tunnel.policy.tag.d.ts +0 -18
- package/dist/globals/resources/tunnel/tunnel.tag.d.ts +0 -2
- package/dist/globals/resources/tunnel/types.d.ts +0 -42
- package/dist/globals/tunnels/index.d.ts +0 -23
- package/dist/globals/types.d.ts +0 -4
- package/dist/http-client.d.ts +0 -25
- package/dist/http-fetch-tunnel.resource.d.ts +0 -11
- package/dist/index.d.ts +0 -117
- package/dist/models/DependencyProcessor.d.ts +0 -48
- package/dist/models/EventManager.d.ts +0 -153
- package/dist/models/LogPrinter.d.ts +0 -55
- package/dist/models/Logger.d.ts +0 -85
- package/dist/models/MiddlewareManager.d.ts +0 -75
- package/dist/models/OverrideManager.d.ts +0 -13
- package/dist/models/Queue.d.ts +0 -26
- package/dist/models/ResourceInitializer.d.ts +0 -20
- package/dist/models/RunResult.d.ts +0 -35
- package/dist/models/Semaphore.d.ts +0 -61
- package/dist/models/Store.d.ts +0 -73
- package/dist/models/StoreRegistry.d.ts +0 -49
- package/dist/models/StoreValidator.d.ts +0 -8
- package/dist/models/TaskRunner.d.ts +0 -27
- package/dist/models/UnhandledError.d.ts +0 -11
- package/dist/models/index.d.ts +0 -11
- package/dist/models/middleware/InterceptorRegistry.d.ts +0 -56
- package/dist/models/middleware/MiddlewareResolver.d.ts +0 -31
- package/dist/models/middleware/ResourceMiddlewareComposer.d.ts +0 -34
- package/dist/models/middleware/TaskMiddlewareComposer.d.ts +0 -43
- package/dist/models/middleware/ValidationHelper.d.ts +0 -20
- package/dist/models/middleware/index.d.ts +0 -6
- package/dist/models/middleware/types.d.ts +0 -10
- package/dist/models/utils/findCircularDependencies.d.ts +0 -16
- package/dist/models/utils/safeStringify.d.ts +0 -3
- package/dist/node/exposure/allowList.d.ts +0 -3
- package/dist/node/exposure/authenticator.d.ts +0 -6
- package/dist/node/exposure/cors.d.ts +0 -4
- package/dist/node/exposure/createNodeExposure.d.ts +0 -2
- package/dist/node/exposure/exposureServer.d.ts +0 -18
- package/dist/node/exposure/httpResponse.d.ts +0 -10
- package/dist/node/exposure/logging.d.ts +0 -4
- package/dist/node/exposure/multipart.d.ts +0 -27
- package/dist/node/exposure/requestBody.d.ts +0 -11
- package/dist/node/exposure/requestContext.d.ts +0 -17
- package/dist/node/exposure/requestHandlers.d.ts +0 -24
- package/dist/node/exposure/resourceTypes.d.ts +0 -60
- package/dist/node/exposure/router.d.ts +0 -17
- package/dist/node/exposure/serverLifecycle.d.ts +0 -13
- package/dist/node/exposure/types.d.ts +0 -31
- package/dist/node/exposure/utils.d.ts +0 -17
- package/dist/node/exposure.resource.d.ts +0 -12
- package/dist/node/files.d.ts +0 -9
- package/dist/node/http-mixed-client.d.ts +0 -30
- package/dist/node/http-smart-client.model.d.ts +0 -24
- package/dist/node/index.d.ts +0 -1
- package/dist/node/inputFile.model.d.ts +0 -22
- package/dist/node/inputFile.utils.d.ts +0 -14
- package/dist/node/platform/createFile.d.ts +0 -9
- package/dist/node/resources/http-mixed-client.factory.resource.d.ts +0 -17
- package/dist/node/resources/http-smart-client.factory.resource.d.ts +0 -16
- package/dist/node/tunnel.allowlist.d.ts +0 -7
- package/dist/node/upload/manifest.d.ts +0 -22
- package/dist/platform/adapters/browser.d.ts +0 -14
- package/dist/platform/adapters/edge.d.ts +0 -5
- package/dist/platform/adapters/node-als.d.ts +0 -1
- package/dist/platform/adapters/node.d.ts +0 -15
- package/dist/platform/adapters/universal-generic.d.ts +0 -14
- package/dist/platform/adapters/universal.d.ts +0 -17
- package/dist/platform/createFile.d.ts +0 -10
- package/dist/platform/createWebFile.d.ts +0 -11
- package/dist/platform/factory.d.ts +0 -2
- package/dist/platform/index.d.ts +0 -27
- package/dist/platform/types.d.ts +0 -29
- package/dist/processHooks.d.ts +0 -2
- package/dist/run.d.ts +0 -14
- package/dist/testing.d.ts +0 -25
- package/dist/tools/getCallerFile.d.ts +0 -1
- package/dist/tunnels/buildUniversalManifest.d.ts +0 -24
- package/dist/types/asyncContext.d.ts +0 -41
- package/dist/types/contracts.d.ts +0 -63
- package/dist/types/error.d.ts +0 -36
- package/dist/types/event.d.ts +0 -74
- package/dist/types/hook.d.ts +0 -23
- package/dist/types/inputFile.d.ts +0 -34
- package/dist/types/meta.d.ts +0 -22
- package/dist/types/resource.d.ts +0 -87
- package/dist/types/resourceMiddleware.d.ts +0 -47
- package/dist/types/runner.d.ts +0 -68
- package/dist/types/storeTypes.d.ts +0 -40
- package/dist/types/symbols.d.ts +0 -32
- package/dist/types/tag.d.ts +0 -46
- package/dist/types/task.d.ts +0 -54
- package/dist/types/taskMiddleware.d.ts +0 -48
- package/dist/types/utilities.d.ts +0 -113
- package/dist/utils/detectRunnerMode.d.ts +0 -9
package/dist/browser/index.mjs
CHANGED
|
@@ -171,78 +171,87 @@ var cacheMiddleware = defineTaskMiddleware({
|
|
|
171
171
|
}
|
|
172
172
|
});
|
|
173
173
|
|
|
174
|
-
// src/
|
|
175
|
-
function
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
const err = new Error();
|
|
179
|
-
let callerfile;
|
|
180
|
-
let currentfile;
|
|
181
|
-
Error.prepareStackTrace = (err2, stack2) => stack2;
|
|
182
|
-
const stack = err.stack;
|
|
183
|
-
stack.shift();
|
|
184
|
-
currentfile = stack.shift()?.getFileName?.();
|
|
185
|
-
callerfile = stack.shift()?.getFileName?.();
|
|
186
|
-
return callerfile;
|
|
187
|
-
} finally {
|
|
188
|
-
Error.prepareStackTrace = originalFunc;
|
|
189
|
-
}
|
|
174
|
+
// src/platform/adapters/node-als.ts
|
|
175
|
+
async function loadAsyncLocalStorageClass() {
|
|
176
|
+
const mod = __require("async_hooks");
|
|
177
|
+
return mod.AsyncLocalStorage;
|
|
190
178
|
}
|
|
191
|
-
__name(
|
|
179
|
+
__name(loadAsyncLocalStorageClass, "loadAsyncLocalStorageClass");
|
|
192
180
|
|
|
193
|
-
// src/
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
181
|
+
// src/platform/adapters/node.ts
|
|
182
|
+
var NodePlatformAdapter = class {
|
|
183
|
+
constructor() {
|
|
184
|
+
this.id = "node";
|
|
185
|
+
this.setTimeout = globalThis.setTimeout;
|
|
186
|
+
this.clearTimeout = globalThis.clearTimeout;
|
|
187
|
+
}
|
|
188
|
+
static {
|
|
189
|
+
__name(this, "NodePlatformAdapter");
|
|
190
|
+
}
|
|
191
|
+
async init() {
|
|
192
|
+
this.alsClass = await loadAsyncLocalStorageClass();
|
|
193
|
+
}
|
|
194
|
+
onUncaughtException(handler) {
|
|
195
|
+
process.on("uncaughtException", handler);
|
|
196
|
+
return () => process.off("uncaughtException", handler);
|
|
197
|
+
}
|
|
198
|
+
onUnhandledRejection(handler) {
|
|
199
|
+
const h = /* @__PURE__ */ __name((reason) => handler(reason), "h");
|
|
200
|
+
process.on("unhandledRejection", h);
|
|
201
|
+
return () => process.off("unhandledRejection", h);
|
|
202
|
+
}
|
|
203
|
+
onShutdownSignal(handler) {
|
|
204
|
+
process.on("SIGINT", handler);
|
|
205
|
+
process.on("SIGTERM", handler);
|
|
206
|
+
return () => {
|
|
207
|
+
process.off("SIGINT", handler);
|
|
208
|
+
process.off("SIGTERM", handler);
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
exit(code) {
|
|
212
|
+
process.exit(code);
|
|
213
|
+
}
|
|
214
|
+
getEnv(key) {
|
|
215
|
+
return process.env[key];
|
|
216
|
+
}
|
|
217
|
+
hasAsyncLocalStorage() {
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
createAsyncLocalStorage() {
|
|
221
|
+
let instance;
|
|
222
|
+
const ensure = /* @__PURE__ */ __name(() => {
|
|
223
|
+
if (!this.alsClass) {
|
|
224
|
+
let als;
|
|
225
|
+
const forceNoop = typeof process !== "undefined" && !!process.env?.RUNNER_FORCE_NOOP_ALS;
|
|
226
|
+
if (!forceNoop) {
|
|
227
|
+
try {
|
|
228
|
+
const mod = __require("async_hooks");
|
|
229
|
+
als = mod?.AsyncLocalStorage;
|
|
230
|
+
} catch (_) {
|
|
231
|
+
als = void 0;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
this.alsClass = als ? als : class NoopAsyncLocalStorage {
|
|
235
|
+
static {
|
|
236
|
+
__name(this, "NoopAsyncLocalStorage");
|
|
237
|
+
}
|
|
238
|
+
getStore() {
|
|
239
|
+
return void 0;
|
|
240
|
+
}
|
|
241
|
+
run(_store, callback) {
|
|
242
|
+
return callback();
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
return instance ??= new this.alsClass();
|
|
247
|
+
}, "ensure");
|
|
248
|
+
return {
|
|
249
|
+
getStore: /* @__PURE__ */ __name(() => ensure().getStore(), "getStore"),
|
|
250
|
+
run: /* @__PURE__ */ __name((store2, callback) => ensure().run(store2, callback), "run")
|
|
251
|
+
};
|
|
252
|
+
}
|
|
227
253
|
};
|
|
228
254
|
|
|
229
|
-
// src/definers/defineHook.ts
|
|
230
|
-
function defineHook(hookDef) {
|
|
231
|
-
const filePath = getCallerFile();
|
|
232
|
-
return {
|
|
233
|
-
[symbolHook]: true,
|
|
234
|
-
[symbolFilePath]: filePath,
|
|
235
|
-
id: hookDef.id,
|
|
236
|
-
dependencies: hookDef.dependencies || {},
|
|
237
|
-
on: hookDef.on,
|
|
238
|
-
order: hookDef.order,
|
|
239
|
-
run: hookDef.run,
|
|
240
|
-
meta: hookDef.meta || {},
|
|
241
|
-
tags: hookDef.tags || []
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
__name(defineHook, "defineHook");
|
|
245
|
-
|
|
246
255
|
// src/errors.ts
|
|
247
256
|
var errors_exports = {};
|
|
248
257
|
__export(errors_exports, {
|
|
@@ -369,86 +378,93 @@ function errorBuilder(id2) {
|
|
|
369
378
|
__name(errorBuilder, "errorBuilder");
|
|
370
379
|
var error = errorBuilder;
|
|
371
380
|
|
|
372
|
-
// src/
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
process.on("unhandledRejection", h);
|
|
399
|
-
return () => process.off("unhandledRejection", h);
|
|
400
|
-
}
|
|
401
|
-
onShutdownSignal(handler) {
|
|
402
|
-
process.on("SIGINT", handler);
|
|
403
|
-
process.on("SIGTERM", handler);
|
|
404
|
-
return () => {
|
|
405
|
-
process.off("SIGINT", handler);
|
|
406
|
-
process.off("SIGTERM", handler);
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
exit(code) {
|
|
410
|
-
process.exit(code);
|
|
411
|
-
}
|
|
412
|
-
getEnv(key) {
|
|
413
|
-
return process.env[key];
|
|
414
|
-
}
|
|
415
|
-
hasAsyncLocalStorage() {
|
|
416
|
-
return true;
|
|
417
|
-
}
|
|
418
|
-
createAsyncLocalStorage() {
|
|
419
|
-
let instance;
|
|
420
|
-
const ensure = /* @__PURE__ */ __name(() => {
|
|
421
|
-
if (!this.alsClass) {
|
|
422
|
-
let als;
|
|
423
|
-
const forceNoop = typeof process !== "undefined" && !!process.env?.RUNNER_FORCE_NOOP_ALS;
|
|
424
|
-
if (!forceNoop) {
|
|
425
|
-
try {
|
|
426
|
-
const mod = __require("async_hooks");
|
|
427
|
-
als = mod?.AsyncLocalStorage;
|
|
428
|
-
} catch (_) {
|
|
429
|
-
als = void 0;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
this.alsClass = als ? als : class NoopAsyncLocalStorage {
|
|
433
|
-
static {
|
|
434
|
-
__name(this, "NoopAsyncLocalStorage");
|
|
435
|
-
}
|
|
436
|
-
getStore() {
|
|
437
|
-
return void 0;
|
|
438
|
-
}
|
|
439
|
-
run(_store, callback) {
|
|
440
|
-
return callback();
|
|
441
|
-
}
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
return instance ??= new this.alsClass();
|
|
445
|
-
}, "ensure");
|
|
446
|
-
return {
|
|
447
|
-
getStore: /* @__PURE__ */ __name(() => ensure().getStore(), "getStore"),
|
|
448
|
-
run: /* @__PURE__ */ __name((store2, callback) => ensure().run(store2, callback), "run")
|
|
449
|
-
};
|
|
381
|
+
// src/errors.ts
|
|
382
|
+
var duplicateRegistrationError = error("runner.errors.duplicateRegistration").format(
|
|
383
|
+
({ type, id: id2 }) => `${type} "${id2.toString()}" already registered. You might have used the same 'id' in two different components or you may have registered the same element twice.`
|
|
384
|
+
).build();
|
|
385
|
+
var dependencyNotFoundError = error("runner.errors.dependencyNotFound").format(
|
|
386
|
+
({ key }) => `Dependency ${key.toString()} not found. Did you forget to register it through a resource?`
|
|
387
|
+
).build();
|
|
388
|
+
var unknownItemTypeError = error(
|
|
389
|
+
"runner.errors.unknownItemType"
|
|
390
|
+
).format(
|
|
391
|
+
({ item }) => `Unknown item type: ${String(
|
|
392
|
+
item
|
|
393
|
+
)}. Please ensure you are not using different versions of '@bluelibs/runner'`
|
|
394
|
+
).build();
|
|
395
|
+
var contextError = error(
|
|
396
|
+
"runner.errors.context"
|
|
397
|
+
).format(({ details }) => details ?? "Context error").build();
|
|
398
|
+
var circularDependenciesError = error("runner.errors.circularDependencies").format(({ cycles }) => {
|
|
399
|
+
const cycleDetails = cycles.map((cycle) => ` \u2022 ${cycle}`).join("\n");
|
|
400
|
+
const hasMiddleware = cycles.some((cycle) => cycle.includes("middleware"));
|
|
401
|
+
let guidance = "\n\nTo resolve circular dependencies:";
|
|
402
|
+
guidance += "\n \u2022 Consider refactoring to reduce coupling between components";
|
|
403
|
+
guidance += "\n \u2022 Extract shared dependencies into separate resources";
|
|
404
|
+
if (hasMiddleware) {
|
|
405
|
+
guidance += "\n \u2022 For middleware: you can filter out tasks/resources using everywhere(fn)";
|
|
406
|
+
guidance += "\n \u2022 Consider using events for communication instead of direct dependencies";
|
|
450
407
|
}
|
|
451
|
-
|
|
408
|
+
return `Circular dependencies detected:
|
|
409
|
+
${cycleDetails}${guidance}`;
|
|
410
|
+
}).build();
|
|
411
|
+
var eventNotFoundError = error(
|
|
412
|
+
"runner.errors.eventNotFound"
|
|
413
|
+
).format(
|
|
414
|
+
({ id: id2 }) => `Event "${id2.toString()}" not found. Did you forget to register it?`
|
|
415
|
+
).build();
|
|
416
|
+
var resourceNotFoundError = error(
|
|
417
|
+
"runner.errors.resourceNotFound"
|
|
418
|
+
).format(
|
|
419
|
+
({ id: id2 }) => `Resource "${id2.toString()}" not found. Did you forget to register it or are you using the correct id?`
|
|
420
|
+
).build();
|
|
421
|
+
var middlewareNotRegisteredError = error("runner.errors.middlewareNotRegistered").format(
|
|
422
|
+
({ type, source, middlewareId }) => `Middleware inside ${type} "${source}" depends on "${middlewareId}" but it's not registered. Did you forget to register it?`
|
|
423
|
+
).build();
|
|
424
|
+
var tagNotFoundError = error(
|
|
425
|
+
"runner.errors.tagNotFound"
|
|
426
|
+
).format(
|
|
427
|
+
({ id: id2 }) => `Tag "${id2}" not registered. Did you forget to register it inside a resource?`
|
|
428
|
+
).build();
|
|
429
|
+
var lockedError = error(
|
|
430
|
+
"runner.errors.locked"
|
|
431
|
+
).format(
|
|
432
|
+
({ what }) => `Cannot modify the ${what.toString()} when it is locked.`
|
|
433
|
+
).build();
|
|
434
|
+
var storeAlreadyInitializedError = error(
|
|
435
|
+
"runner.errors.storeAlreadyInitialized"
|
|
436
|
+
).format(() => "Store already initialized. Cannot reinitialize.").build();
|
|
437
|
+
var validationError = error("runner.errors.validation").format(({ subject, id: id2, originalError }) => {
|
|
438
|
+
const errorMessage = originalError instanceof Error ? originalError.message : String(originalError);
|
|
439
|
+
return `${subject} validation failed for ${id2.toString()}: ${errorMessage}`;
|
|
440
|
+
}).build();
|
|
441
|
+
var eventCycleError = error("runner.errors.eventCycle").format(({ path }) => {
|
|
442
|
+
const chain = path.map((p) => `${p.id}\u2190${p.source}`).join(" -> ");
|
|
443
|
+
return `Event emission cycle detected:
|
|
444
|
+
${chain}
|
|
445
|
+
|
|
446
|
+
Break the cycle by changing hook logic (avoid mutual emits) or gate with conditions/tags.`;
|
|
447
|
+
}).build();
|
|
448
|
+
var eventEmissionCycleError = error("runner.errors.eventEmissionCycle").format(({ cycles }) => {
|
|
449
|
+
const list = cycles.map((c) => ` \u2022 ${c}`).join("\n");
|
|
450
|
+
return `Event emission cycles detected between hooks and events:
|
|
451
|
+
${list}
|
|
452
|
+
|
|
453
|
+
This was detected at compile time (dry-run). Break the cycle by avoiding mutual emits between hooks or scoping hooks using tags.`;
|
|
454
|
+
}).build();
|
|
455
|
+
var platformUnsupportedFunctionError = error("runner.errors.platformUnsupportedFunction").format(
|
|
456
|
+
({ functionName }) => `Platform function not supported in this environment: ${functionName}. Detected platform: ${detectEnvironment()}.`
|
|
457
|
+
).build();
|
|
458
|
+
var cancellationError = error(
|
|
459
|
+
"runner.errors.cancellation"
|
|
460
|
+
).format(({ reason }) => reason || "Operation cancelled").build();
|
|
461
|
+
var tunnelOwnershipConflictError = error("runner.errors.tunnelOwnershipConflict").format(
|
|
462
|
+
({ taskId, currentOwnerId, attemptedOwnerId }) => `Task "${taskId}" is already tunneled by resource "${currentOwnerId}". Resource "${attemptedOwnerId}" cannot tunnel it again. Ensure each task is owned by a single tunnel client.`
|
|
463
|
+
).build();
|
|
464
|
+
function isCancellationError(err) {
|
|
465
|
+
return cancellationError.is(err);
|
|
466
|
+
}
|
|
467
|
+
__name(isCancellationError, "isCancellationError");
|
|
452
468
|
|
|
453
469
|
// src/platform/adapters/browser.ts
|
|
454
470
|
var BrowserPlatformAdapter = class {
|
|
@@ -757,6 +773,12 @@ function setPlatform(adapter) {
|
|
|
757
773
|
adapter.id;
|
|
758
774
|
}
|
|
759
775
|
__name(setPlatform, "setPlatform");
|
|
776
|
+
function isNode() {
|
|
777
|
+
{
|
|
778
|
+
return false;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
__name(isNode, "isNode");
|
|
760
782
|
var PlatformAdapter = class {
|
|
761
783
|
constructor(env) {
|
|
762
784
|
this.setTimeout = globalThis.setTimeout;
|
|
@@ -810,93 +832,79 @@ var PlatformAdapter = class {
|
|
|
810
832
|
}
|
|
811
833
|
};
|
|
812
834
|
|
|
813
|
-
// src/
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
var circularDependenciesError = error("runner.errors.circularDependencies").format(({ cycles }) => {
|
|
831
|
-
const cycleDetails = cycles.map((cycle) => ` \u2022 ${cycle}`).join("\n");
|
|
832
|
-
const hasMiddleware = cycles.some((cycle) => cycle.includes("middleware"));
|
|
833
|
-
let guidance = "\n\nTo resolve circular dependencies:";
|
|
834
|
-
guidance += "\n \u2022 Consider refactoring to reduce coupling between components";
|
|
835
|
-
guidance += "\n \u2022 Extract shared dependencies into separate resources";
|
|
836
|
-
if (hasMiddleware) {
|
|
837
|
-
guidance += "\n \u2022 For middleware: you can filter out tasks/resources using everywhere(fn)";
|
|
838
|
-
guidance += "\n \u2022 Consider using events for communication instead of direct dependencies";
|
|
835
|
+
// src/tools/getCallerFile.ts
|
|
836
|
+
function getCallerFile() {
|
|
837
|
+
const originalPrepare = Error.prepareStackTrace;
|
|
838
|
+
try {
|
|
839
|
+
if (isNode()) {
|
|
840
|
+
const err = new Error();
|
|
841
|
+
Error.prepareStackTrace = (_err, stack2) => stack2;
|
|
842
|
+
const stack = err.stack;
|
|
843
|
+
stack.shift();
|
|
844
|
+
stack.shift();
|
|
845
|
+
const candidate = stack.shift();
|
|
846
|
+
const file = candidate?.getFileName?.();
|
|
847
|
+
return file;
|
|
848
|
+
}
|
|
849
|
+
return "unknown";
|
|
850
|
+
} finally {
|
|
851
|
+
Error.prepareStackTrace = originalPrepare;
|
|
839
852
|
}
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
}).build();
|
|
843
|
-
var eventNotFoundError = error(
|
|
844
|
-
"runner.errors.eventNotFound"
|
|
845
|
-
).format(
|
|
846
|
-
({ id: id2 }) => `Event "${id2.toString()}" not found. Did you forget to register it?`
|
|
847
|
-
).build();
|
|
848
|
-
var resourceNotFoundError = error(
|
|
849
|
-
"runner.errors.resourceNotFound"
|
|
850
|
-
).format(
|
|
851
|
-
({ id: id2 }) => `Resource "${id2.toString()}" not found. Did you forget to register it or are you using the correct id?`
|
|
852
|
-
).build();
|
|
853
|
-
var middlewareNotRegisteredError = error("runner.errors.middlewareNotRegistered").format(
|
|
854
|
-
({ type, source, middlewareId }) => `Middleware inside ${type} "${source}" depends on "${middlewareId}" but it's not registered. Did you forget to register it?`
|
|
855
|
-
).build();
|
|
856
|
-
var tagNotFoundError = error(
|
|
857
|
-
"runner.errors.tagNotFound"
|
|
858
|
-
).format(
|
|
859
|
-
({ id: id2 }) => `Tag "${id2}" not registered. Did you forget to register it inside a resource?`
|
|
860
|
-
).build();
|
|
861
|
-
var lockedError = error(
|
|
862
|
-
"runner.errors.locked"
|
|
863
|
-
).format(
|
|
864
|
-
({ what }) => `Cannot modify the ${what.toString()} when it is locked.`
|
|
865
|
-
).build();
|
|
866
|
-
var storeAlreadyInitializedError = error(
|
|
867
|
-
"runner.errors.storeAlreadyInitialized"
|
|
868
|
-
).format(() => "Store already initialized. Cannot reinitialize.").build();
|
|
869
|
-
var validationError = error("runner.errors.validation").format(({ subject, id: id2, originalError }) => {
|
|
870
|
-
const errorMessage = originalError instanceof Error ? originalError.message : String(originalError);
|
|
871
|
-
return `${subject} validation failed for ${id2.toString()}: ${errorMessage}`;
|
|
872
|
-
}).build();
|
|
873
|
-
var eventCycleError = error("runner.errors.eventCycle").format(({ path }) => {
|
|
874
|
-
const chain = path.map((p) => `${p.id}\u2190${p.source}`).join(" -> ");
|
|
875
|
-
return `Event emission cycle detected:
|
|
876
|
-
${chain}
|
|
877
|
-
|
|
878
|
-
Break the cycle by changing hook logic (avoid mutual emits) or gate with conditions/tags.`;
|
|
879
|
-
}).build();
|
|
880
|
-
var eventEmissionCycleError = error("runner.errors.eventEmissionCycle").format(({ cycles }) => {
|
|
881
|
-
const list = cycles.map((c) => ` \u2022 ${c}`).join("\n");
|
|
882
|
-
return `Event emission cycles detected between hooks and events:
|
|
883
|
-
${list}
|
|
853
|
+
}
|
|
854
|
+
__name(getCallerFile, "getCallerFile");
|
|
884
855
|
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
856
|
+
// src/definers/defineTask.ts
|
|
857
|
+
function defineTask(taskConfig) {
|
|
858
|
+
const filePath = getCallerFile();
|
|
859
|
+
const id2 = taskConfig.id;
|
|
860
|
+
return {
|
|
861
|
+
[symbolTask]: true,
|
|
862
|
+
[symbolFilePath]: filePath,
|
|
863
|
+
id: id2,
|
|
864
|
+
dependencies: taskConfig.dependencies || {},
|
|
865
|
+
middleware: taskConfig.middleware || [],
|
|
866
|
+
run: taskConfig.run,
|
|
867
|
+
inputSchema: taskConfig.inputSchema,
|
|
868
|
+
resultSchema: taskConfig.resultSchema,
|
|
869
|
+
meta: taskConfig.meta || {},
|
|
870
|
+
tags: taskConfig.tags || [],
|
|
871
|
+
// autorun,
|
|
872
|
+
optional() {
|
|
873
|
+
return {
|
|
874
|
+
inner: this,
|
|
875
|
+
[symbolOptionalDependency]: true
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
__name(defineTask, "defineTask");
|
|
881
|
+
defineTask.phantom = (taskConfig) => {
|
|
882
|
+
const taskDef = defineTask({
|
|
883
|
+
...taskConfig,
|
|
884
|
+
run: /* @__PURE__ */ __name(async (input) => {
|
|
885
|
+
return void 0;
|
|
886
|
+
}, "run")
|
|
887
|
+
});
|
|
888
|
+
taskDef[symbolPhantomTask] = true;
|
|
889
|
+
return taskDef;
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
// src/definers/defineHook.ts
|
|
893
|
+
function defineHook(hookDef) {
|
|
894
|
+
const filePath = getCallerFile();
|
|
895
|
+
return {
|
|
896
|
+
[symbolHook]: true,
|
|
897
|
+
[symbolFilePath]: filePath,
|
|
898
|
+
id: hookDef.id,
|
|
899
|
+
dependencies: hookDef.dependencies || {},
|
|
900
|
+
on: hookDef.on,
|
|
901
|
+
order: hookDef.order,
|
|
902
|
+
run: hookDef.run,
|
|
903
|
+
meta: hookDef.meta || {},
|
|
904
|
+
tags: hookDef.tags || []
|
|
905
|
+
};
|
|
898
906
|
}
|
|
899
|
-
__name(
|
|
907
|
+
__name(defineHook, "defineHook");
|
|
900
908
|
|
|
901
909
|
// src/definers/defineResource.ts
|
|
902
910
|
function defineResource(constConfig) {
|
|
@@ -957,6 +965,7 @@ function defineEvent(config) {
|
|
|
957
965
|
[symbolEvent]: true,
|
|
958
966
|
// This is a workaround
|
|
959
967
|
tags: eventConfig.tags || [],
|
|
968
|
+
parallel: eventConfig.parallel,
|
|
960
969
|
optional() {
|
|
961
970
|
return {
|
|
962
971
|
inner: this,
|
|
@@ -3487,30 +3496,279 @@ var DependencyProcessor = class {
|
|
|
3487
3496
|
}
|
|
3488
3497
|
};
|
|
3489
3498
|
|
|
3490
|
-
// src/models/
|
|
3499
|
+
// src/models/event/types.ts
|
|
3491
3500
|
var HandlerOptionsDefaults = { order: 0 };
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3501
|
+
|
|
3502
|
+
// src/models/event/ListenerRegistry.ts
|
|
3503
|
+
var ListenerRegistry = class {
|
|
3504
|
+
constructor(isExcludedFromGlobal) {
|
|
3495
3505
|
this.listeners = /* @__PURE__ */ new Map();
|
|
3496
3506
|
this.globalListeners = [];
|
|
3497
|
-
// Caching system for merged listeners to improve performance
|
|
3498
3507
|
this.cachedMergedListeners = /* @__PURE__ */ new Map();
|
|
3499
|
-
this.
|
|
3500
|
-
|
|
3508
|
+
this._globalListenersCacheValid = true;
|
|
3509
|
+
this.isExcludedFromGlobal = isExcludedFromGlobal ?? ((event2) => globalTags.excludeFromGlobalHooks.exists(event2));
|
|
3510
|
+
}
|
|
3511
|
+
static {
|
|
3512
|
+
__name(this, "ListenerRegistry");
|
|
3513
|
+
}
|
|
3514
|
+
get globalListenersCacheValid() {
|
|
3515
|
+
return this._globalListenersCacheValid;
|
|
3516
|
+
}
|
|
3517
|
+
addListener(eventId, newListener) {
|
|
3518
|
+
const listeners = this.listeners.get(eventId);
|
|
3519
|
+
if (listeners) {
|
|
3520
|
+
this.insertListener(listeners, newListener);
|
|
3521
|
+
} else {
|
|
3522
|
+
this.listeners.set(eventId, [newListener]);
|
|
3523
|
+
}
|
|
3524
|
+
this.invalidateCache(eventId);
|
|
3525
|
+
}
|
|
3526
|
+
addGlobalListener(newListener) {
|
|
3527
|
+
this.insertListener(this.globalListeners, newListener);
|
|
3528
|
+
this.invalidateCache();
|
|
3529
|
+
}
|
|
3530
|
+
getListenersForEmit(eventDefinition) {
|
|
3531
|
+
const excludeGlobal = this.isExcludedFromGlobal(eventDefinition);
|
|
3532
|
+
if (excludeGlobal) {
|
|
3533
|
+
return this.listeners.get(eventDefinition.id) || [];
|
|
3534
|
+
}
|
|
3535
|
+
return this.getCachedMergedListeners(eventDefinition.id);
|
|
3536
|
+
}
|
|
3537
|
+
hasListeners(eventDefinition) {
|
|
3538
|
+
const eventListeners = this.listeners.get(eventDefinition.id) || [];
|
|
3539
|
+
if (eventListeners.length > 0) {
|
|
3540
|
+
return true;
|
|
3541
|
+
}
|
|
3542
|
+
if (this.globalListeners.length === 0) {
|
|
3543
|
+
return false;
|
|
3544
|
+
}
|
|
3545
|
+
return !this.isExcludedFromGlobal(eventDefinition);
|
|
3546
|
+
}
|
|
3547
|
+
/**
|
|
3548
|
+
* Cached merge between event-specific and global listeners.
|
|
3549
|
+
* Exposed for backward compatibility with existing tests.
|
|
3550
|
+
*/
|
|
3551
|
+
getCachedMergedListeners(eventId) {
|
|
3552
|
+
if (!this._globalListenersCacheValid) {
|
|
3553
|
+
this.cachedMergedListeners.clear();
|
|
3554
|
+
this._globalListenersCacheValid = true;
|
|
3555
|
+
}
|
|
3556
|
+
let cached = this.cachedMergedListeners.get(eventId);
|
|
3557
|
+
if (!cached) {
|
|
3558
|
+
const eventListeners = this.listeners.get(eventId) || [];
|
|
3559
|
+
if (eventListeners.length === 0 && this.globalListeners.length === 0) {
|
|
3560
|
+
cached = [];
|
|
3561
|
+
} else if (eventListeners.length === 0) {
|
|
3562
|
+
cached = this.globalListeners;
|
|
3563
|
+
} else if (this.globalListeners.length === 0) {
|
|
3564
|
+
cached = eventListeners;
|
|
3565
|
+
} else {
|
|
3566
|
+
cached = this.mergeSortedListeners(eventListeners, this.globalListeners);
|
|
3567
|
+
}
|
|
3568
|
+
this.cachedMergedListeners.set(eventId, cached);
|
|
3569
|
+
}
|
|
3570
|
+
return cached;
|
|
3571
|
+
}
|
|
3572
|
+
invalidateCache(eventId) {
|
|
3573
|
+
if (eventId) {
|
|
3574
|
+
this.cachedMergedListeners.delete(eventId);
|
|
3575
|
+
} else {
|
|
3576
|
+
this._globalListenersCacheValid = false;
|
|
3577
|
+
}
|
|
3578
|
+
}
|
|
3579
|
+
mergeSortedListeners(a, b) {
|
|
3580
|
+
const result = [];
|
|
3581
|
+
let i = 0;
|
|
3582
|
+
let j = 0;
|
|
3583
|
+
while (i < a.length && j < b.length) {
|
|
3584
|
+
if (a[i].order <= b[j].order) {
|
|
3585
|
+
result.push(a[i++]);
|
|
3586
|
+
} else {
|
|
3587
|
+
result.push(b[j++]);
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
while (i < a.length) result.push(a[i++]);
|
|
3591
|
+
while (j < b.length) result.push(b[j++]);
|
|
3592
|
+
return result;
|
|
3593
|
+
}
|
|
3594
|
+
insertListener(listeners, newListener) {
|
|
3595
|
+
let low = 0;
|
|
3596
|
+
let high = listeners.length;
|
|
3597
|
+
while (low < high) {
|
|
3598
|
+
const mid = low + high >>> 1;
|
|
3599
|
+
if (listeners[mid].order < newListener.order) {
|
|
3600
|
+
low = mid + 1;
|
|
3601
|
+
} else {
|
|
3602
|
+
high = mid;
|
|
3603
|
+
}
|
|
3604
|
+
}
|
|
3605
|
+
listeners.splice(low, 0, newListener);
|
|
3606
|
+
}
|
|
3607
|
+
};
|
|
3608
|
+
function createListener(newListener) {
|
|
3609
|
+
return {
|
|
3610
|
+
handler: newListener.handler,
|
|
3611
|
+
order: newListener.order ?? HandlerOptionsDefaults.order,
|
|
3612
|
+
filter: newListener.filter,
|
|
3613
|
+
id: newListener.id,
|
|
3614
|
+
isGlobal: newListener.isGlobal ?? false
|
|
3615
|
+
};
|
|
3616
|
+
}
|
|
3617
|
+
__name(createListener, "createListener");
|
|
3618
|
+
|
|
3619
|
+
// src/models/event/InterceptorPipeline.ts
|
|
3620
|
+
function composeInterceptors(interceptors, base) {
|
|
3621
|
+
return interceptors.slice().reverse().reduce(
|
|
3622
|
+
(next, interceptor) => (...args) => interceptor(next, ...args),
|
|
3623
|
+
base
|
|
3624
|
+
);
|
|
3625
|
+
}
|
|
3626
|
+
__name(composeInterceptors, "composeInterceptors");
|
|
3627
|
+
|
|
3628
|
+
// src/models/event/EmissionExecutor.ts
|
|
3629
|
+
async function executeSequentially({
|
|
3630
|
+
listeners,
|
|
3631
|
+
event: event2,
|
|
3632
|
+
isPropagationStopped
|
|
3633
|
+
}) {
|
|
3634
|
+
for (const listener of listeners) {
|
|
3635
|
+
if (isPropagationStopped()) {
|
|
3636
|
+
break;
|
|
3637
|
+
}
|
|
3638
|
+
if (shouldExecuteListener(listener, event2)) {
|
|
3639
|
+
await listener.handler(event2);
|
|
3640
|
+
}
|
|
3641
|
+
}
|
|
3642
|
+
}
|
|
3643
|
+
__name(executeSequentially, "executeSequentially");
|
|
3644
|
+
async function executeInParallel({
|
|
3645
|
+
listeners,
|
|
3646
|
+
event: event2
|
|
3647
|
+
}) {
|
|
3648
|
+
if (listeners.length === 0 || event2.isPropagationStopped()) {
|
|
3649
|
+
return;
|
|
3650
|
+
}
|
|
3651
|
+
let currentOrder = listeners[0].order;
|
|
3652
|
+
let currentBatch = [];
|
|
3653
|
+
const executeBatch = /* @__PURE__ */ __name(async (batch) => {
|
|
3654
|
+
const results = await Promise.allSettled(
|
|
3655
|
+
batch.map(async (listener) => {
|
|
3656
|
+
if (shouldExecuteListener(listener, event2)) {
|
|
3657
|
+
await listener.handler(event2);
|
|
3658
|
+
}
|
|
3659
|
+
})
|
|
3660
|
+
);
|
|
3661
|
+
const errors = results.map((result, index) => ({ result, listener: batch[index] })).filter(
|
|
3662
|
+
(r2) => r2.result.status === "rejected"
|
|
3663
|
+
).map(({ result, listener }) => {
|
|
3664
|
+
const reason = result.reason;
|
|
3665
|
+
const errObj = reason && typeof reason === "object" ? reason : new Error(String(reason));
|
|
3666
|
+
if (errObj.listenerId === void 0) {
|
|
3667
|
+
errObj.listenerId = listener.id;
|
|
3668
|
+
}
|
|
3669
|
+
if (errObj.listenerOrder === void 0) {
|
|
3670
|
+
errObj.listenerOrder = listener.order;
|
|
3671
|
+
}
|
|
3672
|
+
return errObj;
|
|
3673
|
+
});
|
|
3674
|
+
if (errors.length > 0) {
|
|
3675
|
+
if (errors.length === 1) {
|
|
3676
|
+
throw errors[0];
|
|
3677
|
+
}
|
|
3678
|
+
const aggregateError = new Error(
|
|
3679
|
+
`${errors.length} listeners failed in parallel batch`
|
|
3680
|
+
);
|
|
3681
|
+
aggregateError.errors = errors;
|
|
3682
|
+
aggregateError.name = "AggregateError";
|
|
3683
|
+
throw aggregateError;
|
|
3684
|
+
}
|
|
3685
|
+
}, "executeBatch");
|
|
3686
|
+
for (const listener of listeners) {
|
|
3687
|
+
if (listener.order !== currentOrder) {
|
|
3688
|
+
await executeBatch(currentBatch);
|
|
3689
|
+
currentBatch = [];
|
|
3690
|
+
currentOrder = listener.order;
|
|
3691
|
+
if (event2.isPropagationStopped()) {
|
|
3692
|
+
break;
|
|
3693
|
+
}
|
|
3694
|
+
}
|
|
3695
|
+
currentBatch.push(listener);
|
|
3696
|
+
}
|
|
3697
|
+
if (currentBatch.length > 0 && !event2.isPropagationStopped()) {
|
|
3698
|
+
await executeBatch(currentBatch);
|
|
3699
|
+
}
|
|
3700
|
+
}
|
|
3701
|
+
__name(executeInParallel, "executeInParallel");
|
|
3702
|
+
function shouldExecuteListener(listener, event2) {
|
|
3703
|
+
if (listener.id && listener.id === event2.source) {
|
|
3704
|
+
return false;
|
|
3705
|
+
}
|
|
3706
|
+
return !listener.filter || listener.filter(event2);
|
|
3707
|
+
}
|
|
3708
|
+
__name(shouldExecuteListener, "shouldExecuteListener");
|
|
3709
|
+
|
|
3710
|
+
// src/models/event/CycleContext.ts
|
|
3711
|
+
var CycleContext = class {
|
|
3712
|
+
static {
|
|
3713
|
+
__name(this, "CycleContext");
|
|
3714
|
+
}
|
|
3715
|
+
constructor(runtimeCycleDetection) {
|
|
3716
|
+
const platform3 = getPlatform();
|
|
3717
|
+
if (platform3.hasAsyncLocalStorage() && runtimeCycleDetection) {
|
|
3718
|
+
this.emissionStack = platform3.createAsyncLocalStorage();
|
|
3719
|
+
this.currentHookIdContext = platform3.createAsyncLocalStorage();
|
|
3720
|
+
this.isEnabled = true;
|
|
3721
|
+
} else {
|
|
3722
|
+
this.emissionStack = null;
|
|
3723
|
+
this.currentHookIdContext = null;
|
|
3724
|
+
this.isEnabled = false;
|
|
3725
|
+
}
|
|
3726
|
+
}
|
|
3727
|
+
runEmission(frame, source, processEmission) {
|
|
3728
|
+
if (!this.isEnabled || !this.emissionStack || !this.currentHookIdContext) {
|
|
3729
|
+
return processEmission();
|
|
3730
|
+
}
|
|
3731
|
+
const currentStack = this.emissionStack.getStore();
|
|
3732
|
+
if (currentStack) {
|
|
3733
|
+
const cycleStart = currentStack.findIndex(
|
|
3734
|
+
(f) => f.id === frame.id
|
|
3735
|
+
);
|
|
3736
|
+
if (cycleStart !== -1) {
|
|
3737
|
+
const top = currentStack[currentStack.length - 1];
|
|
3738
|
+
const currentHookId = this.currentHookIdContext.getStore();
|
|
3739
|
+
const safeReEmitBySameHook = top.id === frame.id && currentHookId && currentHookId === source;
|
|
3740
|
+
if (!safeReEmitBySameHook) {
|
|
3741
|
+
eventCycleError.throw({
|
|
3742
|
+
path: [...currentStack.slice(cycleStart), frame]
|
|
3743
|
+
});
|
|
3744
|
+
}
|
|
3745
|
+
}
|
|
3746
|
+
}
|
|
3747
|
+
const nextStack = currentStack ? [...currentStack, frame] : [frame];
|
|
3748
|
+
return this.emissionStack.run(nextStack, processEmission);
|
|
3749
|
+
}
|
|
3750
|
+
runHook(hookId, execute) {
|
|
3751
|
+
if (!this.isEnabled || !this.currentHookIdContext) {
|
|
3752
|
+
return execute();
|
|
3753
|
+
}
|
|
3754
|
+
return this.currentHookIdContext.run(hookId, execute);
|
|
3755
|
+
}
|
|
3756
|
+
};
|
|
3757
|
+
|
|
3758
|
+
// src/models/EventManager.ts
|
|
3759
|
+
var EventManager = class {
|
|
3760
|
+
constructor(options) {
|
|
3761
|
+
// Interceptors storage (tests access these directly)
|
|
3501
3762
|
this.emissionInterceptors = [];
|
|
3502
3763
|
this.hookInterceptors = [];
|
|
3503
3764
|
// Locking mechanism to prevent modifications after initialization
|
|
3504
3765
|
this.#isLocked = false;
|
|
3505
3766
|
this.runtimeCycleDetection = options?.runtimeCycleDetection ?? true;
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
this.emissionStack = null;
|
|
3512
|
-
this.currentHookIdContext = null;
|
|
3513
|
-
}
|
|
3767
|
+
this.registry = new ListenerRegistry();
|
|
3768
|
+
this.cycleContext = new CycleContext(this.runtimeCycleDetection);
|
|
3769
|
+
this.listeners = this.registry.listeners;
|
|
3770
|
+
this.globalListeners = this.registry.globalListeners;
|
|
3771
|
+
this.cachedMergedListeners = this.registry.cachedMergedListeners;
|
|
3514
3772
|
}
|
|
3515
3773
|
static {
|
|
3516
3774
|
__name(this, "EventManager");
|
|
@@ -3551,8 +3809,7 @@ var EventManager = class {
|
|
|
3551
3809
|
}
|
|
3552
3810
|
const frame = { id: eventDefinition.id, source };
|
|
3553
3811
|
const processEmission = /* @__PURE__ */ __name(async () => {
|
|
3554
|
-
const
|
|
3555
|
-
const allListeners = excludeFromGlobal ? this.listeners.get(eventDefinition.id) || [] : this.getCachedMergedListeners(eventDefinition.id);
|
|
3812
|
+
const allListeners = this.registry.getListenersForEmit(eventDefinition);
|
|
3556
3813
|
let propagationStopped = false;
|
|
3557
3814
|
const event2 = {
|
|
3558
3815
|
id: eventDefinition.id,
|
|
@@ -3570,49 +3827,23 @@ var EventManager = class {
|
|
|
3570
3827
|
if (allListeners.length === 0) {
|
|
3571
3828
|
return;
|
|
3572
3829
|
}
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
}
|
|
3581
|
-
if (!listener.filter || listener.filter(eventToEmit)) {
|
|
3582
|
-
await listener.handler(eventToEmit);
|
|
3583
|
-
}
|
|
3830
|
+
if (eventDefinition.parallel) {
|
|
3831
|
+
await executeInParallel({ listeners: allListeners, event: eventToEmit });
|
|
3832
|
+
} else {
|
|
3833
|
+
await executeSequentially({
|
|
3834
|
+
listeners: allListeners,
|
|
3835
|
+
event: eventToEmit,
|
|
3836
|
+
isPropagationStopped: /* @__PURE__ */ __name(() => propagationStopped, "isPropagationStopped")
|
|
3837
|
+
});
|
|
3584
3838
|
}
|
|
3585
3839
|
}, "baseEmit");
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
emitWithInterceptors = /* @__PURE__ */ __name(async (eventToEmit) => interceptor(nextFunction, eventToEmit), "emitWithInterceptors");
|
|
3591
|
-
}
|
|
3840
|
+
const emitWithInterceptors = composeInterceptors(
|
|
3841
|
+
this.emissionInterceptors,
|
|
3842
|
+
baseEmit
|
|
3843
|
+
);
|
|
3592
3844
|
await emitWithInterceptors(event2);
|
|
3593
3845
|
}, "processEmission");
|
|
3594
|
-
|
|
3595
|
-
const currentStack = this.emissionStack.getStore();
|
|
3596
|
-
if (currentStack) {
|
|
3597
|
-
const cycleStart = currentStack.findIndex(
|
|
3598
|
-
(f) => f.id === frame.id
|
|
3599
|
-
);
|
|
3600
|
-
if (cycleStart !== -1) {
|
|
3601
|
-
const top = currentStack[currentStack.length - 1];
|
|
3602
|
-
const currentHookId = this.currentHookIdContext.getStore();
|
|
3603
|
-
const safeReEmitBySameHook = top.id === frame.id && currentHookId && currentHookId === source;
|
|
3604
|
-
if (!safeReEmitBySameHook) {
|
|
3605
|
-
eventCycleError.throw({
|
|
3606
|
-
path: [...currentStack.slice(cycleStart), frame]
|
|
3607
|
-
});
|
|
3608
|
-
}
|
|
3609
|
-
}
|
|
3610
|
-
}
|
|
3611
|
-
const nextStack = currentStack ? [...currentStack, frame] : [frame];
|
|
3612
|
-
await this.emissionStack.run(nextStack, processEmission);
|
|
3613
|
-
} else {
|
|
3614
|
-
await processEmission();
|
|
3615
|
-
}
|
|
3846
|
+
await this.cycleContext.runEmission(frame, source, processEmission);
|
|
3616
3847
|
}
|
|
3617
3848
|
/**
|
|
3618
3849
|
* Registers an event listener for specific event(s).
|
|
@@ -3624,24 +3855,18 @@ var EventManager = class {
|
|
|
3624
3855
|
*/
|
|
3625
3856
|
addListener(event2, handler, options = HandlerOptionsDefaults) {
|
|
3626
3857
|
this.checkLock();
|
|
3627
|
-
const newListener = {
|
|
3858
|
+
const newListener = createListener({
|
|
3628
3859
|
handler,
|
|
3629
|
-
order: options.order
|
|
3860
|
+
order: options.order,
|
|
3630
3861
|
filter: options.filter,
|
|
3631
3862
|
id: options.id,
|
|
3632
3863
|
isGlobal: false
|
|
3633
|
-
};
|
|
3864
|
+
});
|
|
3634
3865
|
if (Array.isArray(event2)) {
|
|
3635
3866
|
event2.forEach((id2) => this.addListener(id2, handler, options));
|
|
3636
3867
|
} else {
|
|
3637
3868
|
const eventId = event2.id;
|
|
3638
|
-
|
|
3639
|
-
if (listeners) {
|
|
3640
|
-
this.insertListener(listeners, newListener);
|
|
3641
|
-
} else {
|
|
3642
|
-
this.listeners.set(eventId, [newListener]);
|
|
3643
|
-
}
|
|
3644
|
-
this.invalidateCache(eventId);
|
|
3869
|
+
this.registry.addListener(eventId, newListener);
|
|
3645
3870
|
}
|
|
3646
3871
|
}
|
|
3647
3872
|
/**
|
|
@@ -3653,15 +3878,14 @@ var EventManager = class {
|
|
|
3653
3878
|
*/
|
|
3654
3879
|
addGlobalListener(handler, options = HandlerOptionsDefaults) {
|
|
3655
3880
|
this.checkLock();
|
|
3656
|
-
const newListener = {
|
|
3881
|
+
const newListener = createListener({
|
|
3657
3882
|
handler,
|
|
3658
|
-
order: options.order
|
|
3883
|
+
order: options.order,
|
|
3659
3884
|
filter: options.filter,
|
|
3660
3885
|
id: options.id,
|
|
3661
3886
|
isGlobal: true
|
|
3662
|
-
};
|
|
3663
|
-
this.
|
|
3664
|
-
this.invalidateCache();
|
|
3887
|
+
});
|
|
3888
|
+
this.registry.addGlobalListener(newListener);
|
|
3665
3889
|
}
|
|
3666
3890
|
/**
|
|
3667
3891
|
* Checks if there are any listeners registered for the given event
|
|
@@ -3670,15 +3894,7 @@ var EventManager = class {
|
|
|
3670
3894
|
* @returns true if listeners exist, false otherwise
|
|
3671
3895
|
*/
|
|
3672
3896
|
hasListeners(eventDefinition) {
|
|
3673
|
-
|
|
3674
|
-
if (eventListeners.length > 0) {
|
|
3675
|
-
return true;
|
|
3676
|
-
}
|
|
3677
|
-
if (this.globalListeners.length === 0) {
|
|
3678
|
-
return false;
|
|
3679
|
-
}
|
|
3680
|
-
const isExcludedFromGlobal = globalTags.excludeFromGlobalHooks.exists(eventDefinition);
|
|
3681
|
-
return !isExcludedFromGlobal;
|
|
3897
|
+
return this.registry.hasListeners(eventDefinition);
|
|
3682
3898
|
}
|
|
3683
3899
|
/**
|
|
3684
3900
|
* Adds an interceptor for all event emissions
|
|
@@ -3723,20 +3939,14 @@ var EventManager = class {
|
|
|
3723
3939
|
throw err;
|
|
3724
3940
|
}
|
|
3725
3941
|
}, "baseExecute");
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
hook2.id,
|
|
3735
|
-
async () => await executeWithInterceptors(hook2, event2)
|
|
3736
|
-
);
|
|
3737
|
-
} else {
|
|
3738
|
-
return await executeWithInterceptors(hook2, event2);
|
|
3739
|
-
}
|
|
3942
|
+
const executeWithInterceptors = composeInterceptors(
|
|
3943
|
+
this.hookInterceptors,
|
|
3944
|
+
baseExecute
|
|
3945
|
+
);
|
|
3946
|
+
return this.cycleContext.isEnabled ? await this.cycleContext.runHook(
|
|
3947
|
+
hook2.id,
|
|
3948
|
+
() => executeWithInterceptors(hook2, event2)
|
|
3949
|
+
) : await executeWithInterceptors(hook2, event2);
|
|
3740
3950
|
}
|
|
3741
3951
|
// ==================== PRIVATE METHODS ====================
|
|
3742
3952
|
/**
|
|
@@ -3747,102 +3957,12 @@ var EventManager = class {
|
|
|
3747
3957
|
lockedError.throw({ what: "EventManager" });
|
|
3748
3958
|
}
|
|
3749
3959
|
}
|
|
3750
|
-
/**
|
|
3751
|
-
* Merges two sorted arrays of listeners while maintaining order.
|
|
3752
|
-
* Used to combine event-specific listeners with global listeners.
|
|
3753
|
-
*
|
|
3754
|
-
* @param a - First array of listeners
|
|
3755
|
-
* @param b - Second array of listeners
|
|
3756
|
-
* @returns Merged and sorted array of listeners
|
|
3757
|
-
*/
|
|
3758
|
-
mergeSortedListeners(a, b) {
|
|
3759
|
-
const result = [];
|
|
3760
|
-
let i = 0, j = 0;
|
|
3761
|
-
while (i < a.length && j < b.length) {
|
|
3762
|
-
if (a[i].order <= b[j].order) {
|
|
3763
|
-
result.push(a[i++]);
|
|
3764
|
-
} else {
|
|
3765
|
-
result.push(b[j++]);
|
|
3766
|
-
}
|
|
3767
|
-
}
|
|
3768
|
-
while (i < a.length) result.push(a[i++]);
|
|
3769
|
-
while (j < b.length) result.push(b[j++]);
|
|
3770
|
-
return result;
|
|
3771
|
-
}
|
|
3772
|
-
/**
|
|
3773
|
-
* Inserts a new listener into a sorted array using binary search.
|
|
3774
|
-
* Maintains order based on listener priority.
|
|
3775
|
-
*
|
|
3776
|
-
* @param listeners - Array to insert into
|
|
3777
|
-
* @param newListener - Listener to insert
|
|
3778
|
-
*/
|
|
3779
|
-
insertListener(listeners, newListener) {
|
|
3780
|
-
let low = 0;
|
|
3781
|
-
let high = listeners.length;
|
|
3782
|
-
while (low < high) {
|
|
3783
|
-
const mid = low + high >>> 1;
|
|
3784
|
-
if (listeners[mid].order < newListener.order) {
|
|
3785
|
-
low = mid + 1;
|
|
3786
|
-
} else {
|
|
3787
|
-
high = mid;
|
|
3788
|
-
}
|
|
3789
|
-
}
|
|
3790
|
-
listeners.splice(low, 0, newListener);
|
|
3791
|
-
}
|
|
3792
|
-
/**
|
|
3793
|
-
* Returns true if the given emission carries the tag that marks
|
|
3794
|
-
* it as excluded from global ("*") listeners.
|
|
3795
|
-
*
|
|
3796
|
-
* @param event - The event emission to check
|
|
3797
|
-
* @returns true if event should exclude global listeners
|
|
3798
|
-
*/
|
|
3799
|
-
isExcludedFromGlobal(event2) {
|
|
3800
|
-
return globalTags.excludeFromGlobalHooks.exists(event2);
|
|
3801
|
-
}
|
|
3802
3960
|
/**
|
|
3803
3961
|
* Retrieves cached merged listeners for an event, or creates them if not cached.
|
|
3804
|
-
*
|
|
3805
|
-
*
|
|
3806
|
-
* @param eventId - The event ID to get listeners for
|
|
3807
|
-
* @returns Array of merged listeners sorted by priority
|
|
3962
|
+
* Kept for backward compatibility (tests spy on this).
|
|
3808
3963
|
*/
|
|
3809
3964
|
getCachedMergedListeners(eventId) {
|
|
3810
|
-
|
|
3811
|
-
this.cachedMergedListeners.clear();
|
|
3812
|
-
this.globalListenersCacheValid = true;
|
|
3813
|
-
}
|
|
3814
|
-
let cached = this.cachedMergedListeners.get(eventId);
|
|
3815
|
-
if (!cached) {
|
|
3816
|
-
const eventListeners = this.listeners.get(eventId) || [];
|
|
3817
|
-
if (eventListeners.length === 0 && this.globalListeners.length === 0) {
|
|
3818
|
-
cached = [];
|
|
3819
|
-
} else if (eventListeners.length === 0) {
|
|
3820
|
-
cached = this.globalListeners;
|
|
3821
|
-
} else if (this.globalListeners.length === 0) {
|
|
3822
|
-
cached = eventListeners;
|
|
3823
|
-
} else {
|
|
3824
|
-
cached = this.mergeSortedListeners(
|
|
3825
|
-
eventListeners,
|
|
3826
|
-
this.globalListeners
|
|
3827
|
-
);
|
|
3828
|
-
}
|
|
3829
|
-
this.cachedMergedListeners.set(eventId, cached);
|
|
3830
|
-
}
|
|
3831
|
-
return cached;
|
|
3832
|
-
}
|
|
3833
|
-
/**
|
|
3834
|
-
* Invalidates the cached merged listeners.
|
|
3835
|
-
* If eventId is provided, only invalidates cache for that specific event.
|
|
3836
|
-
* Otherwise, invalidates the global cache.
|
|
3837
|
-
*
|
|
3838
|
-
* @param eventId - Optional specific event ID to invalidate
|
|
3839
|
-
*/
|
|
3840
|
-
invalidateCache(eventId) {
|
|
3841
|
-
if (eventId) {
|
|
3842
|
-
this.cachedMergedListeners.delete(eventId);
|
|
3843
|
-
} else {
|
|
3844
|
-
this.globalListenersCacheValid = false;
|
|
3845
|
-
}
|
|
3965
|
+
return this.registry.getCachedMergedListeners(eventId);
|
|
3846
3966
|
}
|
|
3847
3967
|
};
|
|
3848
3968
|
|
|
@@ -5788,6 +5908,10 @@ function makeEventBuilder(state) {
|
|
|
5788
5908
|
const next = clone5(state, { meta: m });
|
|
5789
5909
|
return makeEventBuilder(next);
|
|
5790
5910
|
},
|
|
5911
|
+
parallel(enabled = true) {
|
|
5912
|
+
const next = clone5(state, { parallel: enabled });
|
|
5913
|
+
return makeEventBuilder(next);
|
|
5914
|
+
},
|
|
5791
5915
|
build() {
|
|
5792
5916
|
const event2 = defineEvent({
|
|
5793
5917
|
...state
|
|
@@ -5806,7 +5930,8 @@ function eventBuilder(id2) {
|
|
|
5806
5930
|
filePath,
|
|
5807
5931
|
meta: {},
|
|
5808
5932
|
payloadSchema: void 0,
|
|
5809
|
-
tags: []
|
|
5933
|
+
tags: [],
|
|
5934
|
+
parallel: void 0
|
|
5810
5935
|
});
|
|
5811
5936
|
return makeEventBuilder(initial);
|
|
5812
5937
|
}
|