@bluelibs/runner 5.2.1 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +54 -1
  2. package/dist/browser/index.cjs +977 -800
  3. package/dist/browser/index.cjs.map +1 -1
  4. package/dist/browser/index.mjs +975 -801
  5. package/dist/browser/index.mjs.map +1 -1
  6. package/dist/edge/index.cjs +977 -800
  7. package/dist/edge/index.cjs.map +1 -1
  8. package/dist/edge/index.mjs +975 -801
  9. package/dist/edge/index.mjs.map +1 -1
  10. package/dist/node/node.cjs +1994 -2056
  11. package/dist/node/node.cjs.map +1 -1
  12. package/dist/node/node.mjs +1990 -2010
  13. package/dist/node/node.mjs.map +1 -1
  14. package/dist/types/definers/builders/error/fluent-builder.interface.d.ts +6 -0
  15. package/dist/types/definers/builders/error/index.d.ts +10 -1
  16. package/dist/types/definers/builders/error/types.d.ts +2 -0
  17. package/dist/types/definers/builders/event/utils.d.ts +1 -4
  18. package/dist/types/definers/builders/hook/utils.d.ts +1 -4
  19. package/dist/types/definers/builders/middleware/utils.d.ts +1 -4
  20. package/dist/types/definers/builders/resource/utils.d.ts +1 -4
  21. package/dist/types/definers/builders/shared/mergeUtils.d.ts +5 -0
  22. package/dist/types/definers/builders/task/utils.d.ts +1 -4
  23. package/dist/types/definers/builders/utils.d.ts +1 -1
  24. package/dist/types/definers/defineError.d.ts +5 -3
  25. package/dist/types/defs.d.ts +1 -0
  26. package/dist/types/errors.d.ts +20 -21
  27. package/dist/types/globals/resources/tunnel/protocol.d.ts +3 -0
  28. package/dist/types/models/DependencyProcessor.d.ts +1 -1
  29. package/dist/types/models/MiddlewareManager.d.ts +2 -2
  30. package/dist/types/models/RunResult.d.ts +1 -1
  31. package/dist/types/models/Store.d.ts +15 -13
  32. package/dist/types/models/StoreRegistry.d.ts +19 -16
  33. package/dist/types/models/middleware/ResourceMiddlewareComposer.d.ts +2 -2
  34. package/dist/types/models/utils/buildDependencyGraph.d.ts +12 -0
  35. package/dist/types/models/utils/dependencyStrategies.d.ts +15 -0
  36. package/dist/types/models/utils/disposeOrder.d.ts +7 -0
  37. package/dist/types/node/durable/core/DurableResource.d.ts +24 -9
  38. package/dist/types/node/durable/core/DurableService.d.ts +15 -9
  39. package/dist/types/node/durable/core/interfaces/service.d.ts +27 -19
  40. package/dist/types/node/durable/core/interfaces/store.d.ts +1 -1
  41. package/dist/types/node/durable/core/managers/ExecutionManager.d.ts +34 -4
  42. package/dist/types/node/durable/core/managers/ScheduleManager.d.ts +5 -3
  43. package/dist/types/node/durable/core/managers/TaskRegistry.d.ts +5 -5
  44. package/dist/types/node/durable/core/managers/WaitManager.d.ts +1 -1
  45. package/dist/types/node/durable/core/resource.d.ts +5 -5
  46. package/dist/types/node/durable/index.d.ts +1 -0
  47. package/dist/types/node/durable/resources/memoryDurableResource.d.ts +5 -5
  48. package/dist/types/node/durable/resources/redisDurableResource.d.ts +5 -5
  49. package/dist/types/node/durable/tags/durableWorkflow.tag.d.ts +19 -0
  50. package/dist/types/node/exposure/requestContext.d.ts +1 -1
  51. package/dist/types/node/exposure/resource.d.ts +7 -7
  52. package/dist/types/node/http/http-mixed-client.factory.resource.d.ts +1 -1
  53. package/dist/types/node/http/http-smart-client.factory.resource.d.ts +1 -1
  54. package/dist/types/node/node.d.ts +1 -184
  55. package/dist/types/platform/adapters/edge.d.ts +17 -0
  56. package/dist/types/platform/adapters/universal-generic.d.ts +3 -0
  57. package/dist/types/platform/index.d.ts +1 -0
  58. package/dist/types/platform/types.d.ts +7 -1
  59. package/dist/types/public.d.ts +6 -1
  60. package/dist/types/testing.d.ts +0 -1
  61. package/dist/types/tools/LockableMap.d.ts +20 -0
  62. package/dist/types/types/error.d.ts +22 -1
  63. package/dist/types/types/resource.d.ts +2 -4
  64. package/dist/types/types/symbols.d.ts +3 -3
  65. package/dist/types/types/tagged.d.ts +18 -0
  66. package/dist/types/types/task.d.ts +1 -1
  67. package/dist/ui/assets/index-Bo7Gi6Vq.js +141 -0
  68. package/dist/ui/assets/index-Y_9aLumt.css +1 -0
  69. package/dist/ui/index.html +2 -3
  70. package/dist/universal/index.cjs +977 -800
  71. package/dist/universal/index.cjs.map +1 -1
  72. package/dist/universal/index.mjs +975 -801
  73. package/dist/universal/index.mjs.map +1 -1
  74. package/package.json +1 -2
  75. package/readmes/AI.md +59 -12
  76. package/dist/ui/assets/index-2cb8f39f.js +0 -141
  77. package/dist/ui/assets/index-b1f988bf.css +0 -1
  78. /package/dist/types/{tunnels → tools}/buildUniversalManifest.d.ts +0 -0
  79. /package/dist/types/{processHooks.d.ts → tools/processShutdownHooks.d.ts} +0 -0
@@ -1,13 +1,13 @@
1
- import * as http2 from 'http';
2
- import * as https from 'https';
3
- import { pipeline, Readable, Transform, PassThrough } from 'stream';
4
1
  import { LRUCache } from 'lru-cache';
5
2
  import * as crypto from 'crypto';
3
+ import * as http2 from 'http';
4
+ import { pipeline, Transform, Readable, PassThrough } from 'stream';
6
5
  import * as Busboy from 'busboy';
7
6
  import * as fs3 from 'fs';
8
7
  import * as os from 'os';
9
8
  import * as path3 from 'path';
10
9
  import { join } from 'path';
10
+ import * as https from 'https';
11
11
  import { setTimeout as setTimeout$1, clearTimeout as clearTimeout$1 } from 'timers';
12
12
  import { createRequire } from 'module';
13
13
  import { AsyncLocalStorage } from 'async_hooks';
@@ -25,16 +25,9 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
25
25
  if (typeof require !== "undefined") return require.apply(this, arguments);
26
26
  throw Error('Dynamic require of "' + x + '" is not supported');
27
27
  });
28
- var __esm = (fn, res) => function __init() {
29
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
30
- };
31
28
  var __commonJS = (cb, mod) => function __require2() {
32
29
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
33
30
  };
34
- var __export = (target, all) => {
35
- for (var name in all)
36
- __defProp(target, name, { get: all[name], enumerable: true });
37
- };
38
31
  var __copyProps = (to, from, except, desc) => {
39
32
  if (from && typeof from === "object" || typeof from === "function") {
40
33
  for (let key of __getOwnPropNames(from))
@@ -51,873 +44,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
51
44
  __defProp(target, "default", { value: mod, enumerable: true }) ,
52
45
  mod
53
46
  ));
54
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
55
-
56
- // src/serializer/regexp-validator.ts
57
- var regexp_validator_exports = {};
58
- __export(regexp_validator_exports, {
59
- assertRegExpPayload: () => assertRegExpPayload,
60
- isBoundedQuantifier: () => isBoundedQuantifier,
61
- isQuantifierAt: () => isQuantifierAt,
62
- isQuantifierChar: () => isQuantifierChar,
63
- isRegExpPatternSafe: () => isRegExpPatternSafe
64
- });
65
- var isQuantifierAt, isQuantifierChar, isBoundedQuantifier, isRegExpPatternSafe, assertRegExpPayload;
66
- var init_regexp_validator = __esm({
67
- "src/serializer/regexp-validator.ts"() {
68
- isQuantifierAt = /* @__PURE__ */ __name((pattern, index) => {
69
- if (index >= pattern.length) {
70
- return false;
71
- }
72
- const char = pattern[index];
73
- if (char === "*" || char === "+" || char === "?") {
74
- return true;
75
- }
76
- if (char === "{") {
77
- return isBoundedQuantifier(pattern, index);
78
- }
79
- return false;
80
- }, "isQuantifierAt");
81
- isQuantifierChar = /* @__PURE__ */ __name((char, pattern, index) => {
82
- if (char === "*" || char === "+") {
83
- return true;
84
- }
85
- if (char === "?") {
86
- if (index > 0 && pattern[index - 1] === "(") {
87
- return false;
88
- }
89
- return true;
90
- }
91
- if (char === "{") {
92
- return isBoundedQuantifier(pattern, index);
93
- }
94
- return false;
95
- }, "isQuantifierChar");
96
- isBoundedQuantifier = /* @__PURE__ */ __name((pattern, index) => {
97
- let sawDigit = false;
98
- let sawComma = false;
99
- for (let i = index + 1; i < pattern.length; i += 1) {
100
- const char = pattern[i];
101
- if (char >= "0" && char <= "9") {
102
- sawDigit = true;
103
- continue;
104
- }
105
- if (char === "," && !sawComma) {
106
- sawComma = true;
107
- continue;
108
- }
109
- if (char === "}") {
110
- return sawDigit;
111
- }
112
- return false;
113
- }
114
- return false;
115
- }, "isBoundedQuantifier");
116
- isRegExpPatternSafe = /* @__PURE__ */ __name((pattern) => {
117
- const groupStack = [];
118
- let escaped = false;
119
- let inCharClass = false;
120
- for (let index = 0; index < pattern.length; index += 1) {
121
- const char = pattern[index];
122
- if (escaped) {
123
- escaped = false;
124
- continue;
125
- }
126
- if (char === "\\") {
127
- escaped = true;
128
- continue;
129
- }
130
- if (inCharClass) {
131
- if (char === "]") {
132
- inCharClass = false;
133
- }
134
- continue;
135
- }
136
- if (char === "[") {
137
- inCharClass = true;
138
- continue;
139
- }
140
- if (char === "(") {
141
- groupStack.push({ hasQuantifier: false });
142
- if (pattern[index + 1] === "?") {
143
- index += 1;
144
- }
145
- continue;
146
- }
147
- if (char === ")") {
148
- const group = groupStack.pop();
149
- if (group?.hasQuantifier && isQuantifierAt(pattern, index + 1)) {
150
- return false;
151
- }
152
- if (group?.hasQuantifier && groupStack.length > 0) {
153
- groupStack[groupStack.length - 1].hasQuantifier = true;
154
- }
155
- continue;
156
- }
157
- if (isQuantifierChar(char, pattern, index)) {
158
- if (groupStack.length > 0) {
159
- groupStack[groupStack.length - 1].hasQuantifier = true;
160
- }
161
- }
162
- }
163
- return true;
164
- }, "isRegExpPatternSafe");
165
- assertRegExpPayload = /* @__PURE__ */ __name((value, options) => {
166
- if (!value || typeof value !== "object") {
167
- throw new Error("Invalid RegExp payload");
168
- }
169
- const record = value;
170
- if (typeof record.pattern !== "string" || typeof record.flags !== "string") {
171
- throw new Error("Invalid RegExp payload");
172
- }
173
- if (record.pattern.length > options.maxPatternLength) {
174
- throw new Error(
175
- `RegExp pattern exceeds limit (${options.maxPatternLength})`
176
- );
177
- }
178
- if (!options.allowUnsafe && !isRegExpPatternSafe(record.pattern)) {
179
- throw new Error("Unsafe RegExp pattern");
180
- }
181
- return { pattern: record.pattern, flags: record.flags };
182
- }, "assertRegExpPayload");
183
- }
184
- });
185
-
186
- // src/globals/resources/tunnel/protocol.ts
187
- function toTunnelError(input, fallbackMessage) {
188
- if (input instanceof Error) {
189
- return new TunnelError("UNKNOWN", input.message);
190
- }
191
- if (input && typeof input === "object" && "code" in input && "message" in input) {
192
- const typed = input;
193
- if (typeof typed.message === "string" && typeof typed.code === "string") {
194
- const pe = input;
195
- const msg = pe.message || fallbackMessage || "Tunnel error";
196
- return new TunnelError(pe.code, msg, pe.details, {
197
- id: pe.id,
198
- data: pe.data
199
- });
200
- }
201
- }
202
- if (input && typeof input === "object" && "message" in input) {
203
- const typed = input;
204
- if (typeof typed.message === "string") {
205
- return new TunnelError("UNKNOWN", typed.message);
206
- }
207
- }
208
- return new TunnelError(
209
- "UNKNOWN",
210
- typeof input === "string" && input || fallbackMessage || "Tunnel error"
211
- );
212
- }
213
- function assertOkEnvelope(envelope, opts) {
214
- if (!envelope || typeof envelope !== "object") {
215
- throw new TunnelError(
216
- "INVALID_RESPONSE",
217
- opts?.fallbackMessage || "Invalid or empty response"
218
- );
219
- }
220
- if (envelope.ok) {
221
- return envelope.result;
222
- }
223
- if (envelope.error) {
224
- return (() => {
225
- throw toTunnelError(envelope.error, opts?.fallbackMessage);
226
- })();
227
- }
228
- throw new TunnelError("UNKNOWN", opts?.fallbackMessage || "Tunnel error");
229
- }
230
- var TunnelError;
231
- var init_protocol = __esm({
232
- "src/globals/resources/tunnel/protocol.ts"() {
233
- TunnelError = class extends Error {
234
- static {
235
- __name(this, "TunnelError");
236
- }
237
- constructor(code, message, details, extras) {
238
- super(message);
239
- this.name = "TunnelError";
240
- this.code = code;
241
- this.details = details;
242
- this.id = extras?.id;
243
- this.data = extras?.data;
244
- }
245
- };
246
- __name(toTunnelError, "toTunnelError");
247
- __name(assertOkEnvelope, "assertOkEnvelope");
248
- }
249
- });
250
-
251
- // src/globals/resources/tunnel/error-utils.ts
252
- function normalizeError(input) {
253
- return input instanceof Error ? input : new Error(String(input));
254
- }
255
- var init_error_utils = __esm({
256
- "src/globals/resources/tunnel/error-utils.ts"() {
257
- __name(normalizeError, "normalizeError");
258
- }
259
- });
260
-
261
- // src/http-fetch-tunnel.resource.ts
262
- async function postSerialized(options) {
263
- const {
264
- fetch: fetchFn,
265
- url,
266
- body,
267
- headers,
268
- timeoutMs,
269
- serializer: serializer3,
270
- onRequest,
271
- contextHeaderText
272
- } = options;
273
- const controller = timeoutMs && timeoutMs > 0 ? new AbortController() : void 0;
274
- let timeout;
275
- try {
276
- if (controller) {
277
- timeout = setTimeout(() => controller.abort(), timeoutMs);
278
- }
279
- const reqHeaders = {
280
- "content-type": "application/json; charset=utf-8",
281
- ...headers
282
- };
283
- if (contextHeaderText) reqHeaders["x-runner-context"] = contextHeaderText;
284
- if (onRequest) await onRequest({ url, headers: reqHeaders });
285
- const res = await fetchFn(url, {
286
- method: "POST",
287
- headers: reqHeaders,
288
- body: serializer3.stringify(body),
289
- signal: controller?.signal
290
- });
291
- const text = await res.text();
292
- const json2 = text ? serializer3.parse(text) : void 0;
293
- return json2;
294
- } finally {
295
- if (timeout) clearTimeout(timeout);
296
- }
297
- }
298
- function createExposureFetch(cfg) {
299
- const baseUrl = cfg?.baseUrl?.replace(/\/$/, "");
300
- if (!baseUrl) throw new Error("createExposureFetch requires baseUrl");
301
- const headerName = (cfg?.auth?.header ?? "x-runner-token").toLowerCase();
302
- const buildHeaders = /* @__PURE__ */ __name(() => {
303
- const headers = {};
304
- if (cfg?.auth?.token) headers[headerName] = cfg.auth.token;
305
- return headers;
306
- }, "buildHeaders");
307
- const fetchImpl = cfg.fetchImpl ?? globalThis.fetch;
308
- if (typeof fetchImpl !== "function") {
309
- throw new Error(
310
- "global fetch is not available; provide fetchImpl in config"
311
- );
312
- }
313
- const buildContextHeader = /* @__PURE__ */ __name(() => {
314
- if (!cfg.contexts || cfg.contexts.length === 0) return void 0;
315
- const map = {};
316
- for (const ctx of cfg.contexts) {
317
- try {
318
- const v = ctx.use();
319
- map[ctx.id] = ctx.serialize(v);
320
- } catch {
321
- }
322
- }
323
- const keys = Object.keys(map);
324
- if (keys.length === 0) return void 0;
325
- return cfg.serializer.stringify(map);
326
- }, "buildContextHeader");
327
- return {
328
- async task(id2, input) {
329
- const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
330
- const r2 = await postSerialized({
331
- fetch: fetchImpl,
332
- url,
333
- body: { input },
334
- headers: buildHeaders(),
335
- timeoutMs: cfg?.timeoutMs,
336
- serializer: cfg.serializer,
337
- onRequest: cfg?.onRequest,
338
- contextHeaderText: buildContextHeader()
339
- });
340
- try {
341
- return assertOkEnvelope(r2, { fallbackMessage: "Tunnel task error" });
342
- } catch (e) {
343
- const te = e;
344
- if (cfg.errorRegistry && te.id && te.data) {
345
- const helper = cfg.errorRegistry.get(String(te.id));
346
- if (helper) helper.throw(te.data);
347
- }
348
- throw e;
349
- }
350
- },
351
- async event(id2, payload) {
352
- const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
353
- const r2 = await postSerialized({
354
- fetch: fetchImpl,
355
- url,
356
- body: { payload },
357
- headers: buildHeaders(),
358
- timeoutMs: cfg?.timeoutMs,
359
- serializer: cfg.serializer,
360
- onRequest: cfg?.onRequest,
361
- contextHeaderText: buildContextHeader()
362
- });
363
- try {
364
- assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
365
- } catch (e) {
366
- const te = e;
367
- if (cfg.errorRegistry && te.id && te.data) {
368
- const helper = cfg.errorRegistry.get(String(te.id));
369
- if (helper) helper.throw(te.data);
370
- }
371
- throw e;
372
- }
373
- },
374
- async eventWithResult(id2, payload) {
375
- const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
376
- const r2 = await postSerialized({
377
- fetch: fetchImpl,
378
- url,
379
- body: { payload, returnPayload: true },
380
- headers: buildHeaders(),
381
- timeoutMs: cfg?.timeoutMs,
382
- serializer: cfg.serializer,
383
- onRequest: cfg?.onRequest,
384
- contextHeaderText: buildContextHeader()
385
- });
386
- if (r2 && typeof r2 === "object" && r2.ok && !("result" in r2)) {
387
- throw new TunnelError(
388
- "INVALID_RESPONSE",
389
- "Tunnel event returnPayload requested but server did not include result. Upgrade the exposure server."
390
- );
391
- }
392
- try {
393
- return assertOkEnvelope(r2, {
394
- fallbackMessage: "Tunnel event error"
395
- });
396
- } catch (e) {
397
- const te = e;
398
- if (cfg.errorRegistry && te.id && te.data) {
399
- const helper = cfg.errorRegistry.get(String(te.id));
400
- if (helper) helper.throw(te.data);
401
- }
402
- throw e;
403
- }
404
- }
405
- };
406
- }
407
- var init_http_fetch_tunnel_resource = __esm({
408
- "src/http-fetch-tunnel.resource.ts"() {
409
- init_protocol();
410
- init_error_utils();
411
- __name(postSerialized, "postSerialized");
412
- __name(createExposureFetch, "createExposureFetch");
413
- }
414
- });
415
-
416
- // src/node/upload/manifest.ts
417
- function buildNodeManifest(input) {
418
- const files = [];
419
- function visit(value) {
420
- if (!value || typeof value !== "object") return value;
421
- const potentialFile = value;
422
- if (potentialFile.$runnerFile === "File" && typeof potentialFile.id === "string") {
423
- const id2 = potentialFile.id;
424
- const meta = potentialFile.meta;
425
- const local = potentialFile._node;
426
- if (local?.buffer) {
427
- files.push({
428
- id: id2,
429
- meta,
430
- source: { type: "buffer", buffer: local.buffer }
431
- });
432
- } else if (local?.stream) {
433
- files.push({
434
- id: id2,
435
- meta,
436
- source: { type: "stream", stream: local.stream }
437
- });
438
- }
439
- const copy = { $runnerFile: "File", id: id2, meta };
440
- return copy;
441
- }
442
- if (Array.isArray(value)) {
443
- return value.map((x) => visit(x));
444
- }
445
- const out = {};
446
- const obj = value;
447
- for (const k of Object.keys(obj)) {
448
- out[k] = visit(obj[k]);
449
- }
450
- return out;
451
- }
452
- __name(visit, "visit");
453
- const cloned = visit(input);
454
- return { input: cloned, files };
455
- }
456
- var init_manifest = __esm({
457
- "src/node/upload/manifest.ts"() {
458
- __name(buildNodeManifest, "buildNodeManifest");
459
- }
460
- });
461
-
462
- // src/node/http/http-smart-client.model.ts
463
- var http_smart_client_model_exports = {};
464
- __export(http_smart_client_model_exports, {
465
- createHttpSmartClient: () => createHttpSmartClient
466
- });
467
- function isReadable(value) {
468
- return !!value && typeof value.pipe === "function";
469
- }
470
- function hasNodeFile(value) {
471
- const isNodeFileSentinel = /* @__PURE__ */ __name((v) => {
472
- if (!v || typeof v !== "object") return false;
473
- const rec = v;
474
- if (rec.$runnerFile !== "File") return false;
475
- if (typeof rec.id !== "string") return false;
476
- const node = rec._node;
477
- if (!node || typeof node !== "object") return false;
478
- const n = node;
479
- return Boolean(n.stream || n.buffer);
480
- }, "isNodeFileSentinel");
481
- const visit = /* @__PURE__ */ __name((v) => {
482
- if (isNodeFileSentinel(v)) return true;
483
- if (!v || typeof v !== "object") return false;
484
- if (Array.isArray(v)) return v.some(visit);
485
- for (const k of Object.keys(v)) {
486
- if (visit(v[k])) return true;
487
- }
488
- return false;
489
- }, "visit");
490
- return visit(value);
491
- }
492
- function toHeaders2(auth) {
493
- const headers = {};
494
- if (auth?.token)
495
- headers[(auth.header ?? "x-runner-token").toLowerCase()] = auth.token;
496
- return headers;
497
- }
498
- function requestLib(url) {
499
- return url.protocol === "https:" ? https : http2;
500
- }
501
- async function postJson(cfg, url, body) {
502
- const serializer3 = cfg.serializer;
503
- const parsed = new URL(url);
504
- const lib = requestLib(parsed);
505
- const headers = {
506
- "content-type": "application/json; charset=utf-8",
507
- ...toHeaders2(cfg.auth)
508
- };
509
- if (cfg.contexts && cfg.contexts.length > 0) {
510
- const map = {};
511
- for (const ctx of cfg.contexts) {
512
- try {
513
- const v = ctx.use();
514
- map[ctx.id] = ctx.serialize(v);
515
- } catch {
516
- }
517
- }
518
- if (Object.keys(map).length > 0) {
519
- headers["x-runner-context"] = cfg.serializer.stringify(map);
520
- }
521
- }
522
- if (cfg.onRequest) await cfg.onRequest({ url, headers });
523
- return await new Promise((resolve, reject) => {
524
- const req = lib.request(
525
- {
526
- method: "POST",
527
- protocol: parsed.protocol,
528
- hostname: parsed.hostname,
529
- port: parsed.port,
530
- path: parsed.pathname + parsed.search,
531
- headers,
532
- timeout: cfg.timeoutMs
533
- },
534
- (res) => {
535
- const chunks = [];
536
- res.on("data", (c) => {
537
- chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(String(c)));
538
- });
539
- res.on("end", () => {
540
- const text = Buffer.concat(chunks).toString(
541
- "utf8"
542
- );
543
- const json2 = text ? serializer3.parse(text) : void 0;
544
- resolve(json2);
545
- });
546
- }
547
- );
548
- req.on("error", reject);
549
- req.write(serializer3.stringify(body));
550
- req.end();
551
- });
552
- }
553
- function escapeHeaderValue(value) {
554
- return value.replace(/"/g, '\\"');
555
- }
556
- function encodeMultipart(manifestText, files, boundary) {
557
- async function* gen() {
558
- const CRLF = "\r\n";
559
- const boundaryLine = `--${boundary}`;
560
- const partHeader = /* @__PURE__ */ __name((name, options) => {
561
- const h = [boundaryLine + CRLF];
562
- const cd = [
563
- `Content-Disposition: form-data; name="${escapeHeaderValue(name)}"`
564
- ];
565
- if (options?.filename) {
566
- cd.push(`; filename="${escapeHeaderValue(options.filename)}"`);
567
- }
568
- h.push(cd.join("") + CRLF);
569
- if (options?.headers) {
570
- for (const k of Object.keys(options.headers)) {
571
- h.push(`${k}: ${options.headers[k]}` + CRLF);
572
- }
573
- }
574
- h.push(CRLF);
575
- return Buffer.from(h.join(""), "utf8");
576
- }, "partHeader");
577
- yield partHeader("__manifest");
578
- yield Buffer.from(manifestText, "utf8");
579
- yield Buffer.from(CRLF, "utf8");
580
- for (const entry of files) {
581
- const filename = entry.meta?.name ?? "upload";
582
- const contentType = entry.meta?.type ?? "application/octet-stream";
583
- const headers = {
584
- "Content-Type": contentType
585
- };
586
- yield partHeader(`file:${entry.id}`, { headers, filename });
587
- if (entry.source.type === "buffer") {
588
- yield entry.source.buffer;
589
- } else {
590
- for await (const chunk of entry.source.stream) {
591
- yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
592
- }
593
- }
594
- yield Buffer.from(CRLF, "utf8");
595
- }
596
- yield Buffer.from(boundaryLine + "--" + CRLF, "utf8");
597
- }
598
- __name(gen, "gen");
599
- return Readable.from(gen());
600
- }
601
- async function postMultipart(cfg, url, manifestText, files) {
602
- const parsed = new URL(url);
603
- const lib = requestLib(parsed);
604
- const boundary = `runner-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
605
- const body = encodeMultipart(manifestText, files, boundary);
606
- const headers = {
607
- "content-type": `multipart/form-data; boundary=${boundary}`,
608
- ...toHeaders2(cfg.auth)
609
- };
610
- if (cfg.contexts && cfg.contexts.length > 0) {
611
- const map = {};
612
- for (const ctx of cfg.contexts) {
613
- try {
614
- const v = ctx.use();
615
- map[ctx.id] = ctx.serialize(v);
616
- } catch {
617
- }
618
- }
619
- if (Object.keys(map).length > 0) {
620
- headers["x-runner-context"] = cfg.serializer.stringify(map);
621
- }
622
- }
623
- if (cfg.onRequest) await cfg.onRequest({ url, headers });
624
- return await new Promise(
625
- (resolve, reject) => {
626
- const req = lib.request(
627
- {
628
- method: "POST",
629
- protocol: parsed.protocol,
630
- hostname: parsed.hostname,
631
- port: parsed.port,
632
- path: parsed.pathname + parsed.search,
633
- headers,
634
- timeout: cfg.timeoutMs
635
- },
636
- (res) => resolve({ stream: res, res })
637
- );
638
- req.on("error", reject);
639
- body.on("error", (e) => req.destroy(e));
640
- body.pipe(req);
641
- }
642
- );
643
- }
644
- async function postOctetStream(cfg, url, stream) {
645
- const parsed = new URL(url);
646
- const lib = requestLib(parsed);
647
- const headers = {
648
- "content-type": "application/octet-stream",
649
- ...toHeaders2(cfg.auth)
650
- };
651
- if (cfg.contexts && cfg.contexts.length > 0) {
652
- const map = {};
653
- for (const ctx of cfg.contexts) {
654
- try {
655
- const v = ctx.use();
656
- map[ctx.id] = ctx.serialize(v);
657
- } catch {
658
- }
659
- }
660
- if (Object.keys(map).length > 0) {
661
- headers["x-runner-context"] = cfg.serializer.stringify(map);
662
- }
663
- }
664
- if (cfg.onRequest) await cfg.onRequest({ url, headers });
665
- return await new Promise(
666
- (resolve, reject) => {
667
- let settled = false;
668
- const cleanup = [];
669
- const resolveOnce = /* @__PURE__ */ __name((value) => {
670
- settled = true;
671
- cleanup.forEach((fn) => fn());
672
- resolve(value);
673
- }, "resolveOnce");
674
- const rejectOnce = /* @__PURE__ */ __name((error2) => {
675
- settled = true;
676
- cleanup.forEach((fn) => fn());
677
- reject(error2 instanceof Error ? error2 : new Error(String(error2)));
678
- }, "rejectOnce");
679
- const req = lib.request(
680
- {
681
- method: "POST",
682
- protocol: parsed.protocol,
683
- hostname: parsed.hostname,
684
- port: parsed.port,
685
- path: parsed.pathname + parsed.search,
686
- headers,
687
- timeout: cfg.timeoutMs
688
- },
689
- (res) => {
690
- setImmediate(() => {
691
- if (!settled)
692
- resolveOnce({ stream: res, res });
693
- });
694
- }
695
- );
696
- const onReqError = /* @__PURE__ */ __name((e) => rejectOnce(e), "onReqError");
697
- req.on("error", onReqError);
698
- cleanup.push(() => req.removeListener("error", onReqError));
699
- const onPipelineDone = /* @__PURE__ */ __name((err) => {
700
- if (err) rejectOnce(err);
701
- }, "onPipelineDone");
702
- pipeline(stream, req, onPipelineDone);
703
- }
704
- );
705
- }
706
- function parseMaybeJsonResponse(res, serializer3) {
707
- const contentType = String(res.headers["content-type"]);
708
- if (/^application\/json/i.test(contentType)) {
709
- const chunks = [];
710
- return new Promise((resolve, reject) => {
711
- res.on("data", (c) => {
712
- chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(String(c)));
713
- });
714
- res.on("end", () => {
715
- try {
716
- const text = Buffer.concat(chunks).toString(
717
- "utf8"
718
- );
719
- const json2 = text ? serializer3.parse(text) : void 0;
720
- resolve(json2);
721
- } catch (e) {
722
- reject(e);
723
- }
724
- });
725
- res.on("error", reject);
726
- });
727
- }
728
- return Promise.resolve(res);
729
- }
730
- function rethrowTyped(registry, error2) {
731
- if (registry && error2 && typeof error2 === "object") {
732
- const err = error2;
733
- if (err.id && err.data) {
734
- const helper = registry.get(String(err.id));
735
- if (helper) helper.throw(err.data);
736
- }
737
- }
738
- throw error2;
739
- }
740
- function createHttpSmartClient(cfg) {
741
- const baseUrl = cfg.baseUrl.replace(/\/$/, "");
742
- if (!baseUrl) throw new Error("createHttpSmartClient requires baseUrl");
743
- const serializer3 = cfg.serializer;
744
- return {
745
- async task(id2, input) {
746
- const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
747
- if (isReadable(input)) {
748
- const { res } = await postOctetStream(cfg, url, input);
749
- return res;
750
- }
751
- if (hasNodeFile(input)) {
752
- const manifest = buildNodeManifest(input);
753
- const manifestText = serializer3.stringify({
754
- input: manifest.input
755
- });
756
- try {
757
- const { res } = await postMultipart(
758
- cfg,
759
- url,
760
- manifestText,
761
- manifest.files
762
- );
763
- const maybe = await parseMaybeJsonResponse(
764
- res,
765
- serializer3
766
- );
767
- if (isReadable(maybe)) return maybe;
768
- return assertOkEnvelope(maybe, {
769
- fallbackMessage: "Tunnel task error"
770
- });
771
- } catch (error2) {
772
- rethrowTyped(cfg.errorRegistry, error2);
773
- }
774
- }
775
- try {
776
- const r2 = await postJson(cfg, url, { input });
777
- return assertOkEnvelope(r2, {
778
- fallbackMessage: "Tunnel task error"
779
- });
780
- } catch (error2) {
781
- rethrowTyped(cfg.errorRegistry, error2);
782
- }
783
- },
784
- async event(id2, payload) {
785
- const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
786
- try {
787
- const r2 = await postJson(cfg, url, { payload });
788
- assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
789
- } catch (error2) {
790
- rethrowTyped(cfg.errorRegistry, error2);
791
- }
792
- },
793
- async eventWithResult(id2, payload) {
794
- const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
795
- try {
796
- const r2 = await postJson(cfg, url, {
797
- payload,
798
- returnPayload: true
799
- });
800
- if (r2 && typeof r2 === "object" && r2.ok && !("result" in r2)) {
801
- throw new TunnelError(
802
- "INVALID_RESPONSE",
803
- "Tunnel event returnPayload requested but server did not include result. Upgrade the exposure server."
804
- );
805
- }
806
- return assertOkEnvelope(r2, {
807
- fallbackMessage: "Tunnel event error"
808
- });
809
- } catch (error2) {
810
- rethrowTyped(cfg.errorRegistry, error2);
811
- }
812
- }
813
- };
814
- }
815
- var init_http_smart_client_model = __esm({
816
- "src/node/http/http-smart-client.model.ts"() {
817
- init_protocol();
818
- init_manifest();
819
- __name(isReadable, "isReadable");
820
- __name(hasNodeFile, "hasNodeFile");
821
- __name(toHeaders2, "toHeaders");
822
- __name(requestLib, "requestLib");
823
- __name(postJson, "postJson");
824
- __name(escapeHeaderValue, "escapeHeaderValue");
825
- __name(encodeMultipart, "encodeMultipart");
826
- __name(postMultipart, "postMultipart");
827
- __name(postOctetStream, "postOctetStream");
828
- __name(parseMaybeJsonResponse, "parseMaybeJsonResponse");
829
- __name(rethrowTyped, "rethrowTyped");
830
- __name(createHttpSmartClient, "createHttpSmartClient");
831
- }
832
- });
833
-
834
- // src/node/http/http-mixed-client.ts
835
- var http_mixed_client_exports = {};
836
- __export(http_mixed_client_exports, {
837
- createHttpMixedClient: () => createHttpMixedClient
838
- });
839
- function isReadable2(value) {
840
- return !!value && typeof value.pipe === "function";
841
- }
842
- function hasNodeFile2(value) {
843
- const isNodeFileSentinel = /* @__PURE__ */ __name((v) => {
844
- if (!v || typeof v !== "object") return false;
845
- const rec = v;
846
- if (rec.$runnerFile !== "File") return false;
847
- if (typeof rec.id !== "string") return false;
848
- const node = rec._node;
849
- if (!node || typeof node !== "object") return false;
850
- const n = node;
851
- return Boolean(n.stream || n.buffer);
852
- }, "isNodeFileSentinel");
853
- const visit = /* @__PURE__ */ __name((v) => {
854
- if (isNodeFileSentinel(v)) return true;
855
- if (!v || typeof v !== "object") return false;
856
- if (Array.isArray(v)) return v.some(visit);
857
- for (const k of Object.keys(v)) {
858
- if (visit(v[k])) return true;
859
- }
860
- return false;
861
- }, "visit");
862
- return visit(value);
863
- }
864
- async function shouldForceSmart(cfg, id2, input) {
865
- if (!cfg.forceSmart) return false;
866
- if (cfg.forceSmart === true) return true;
867
- return await cfg.forceSmart({ id: id2, input });
868
- }
869
- function createHttpMixedClient(cfg) {
870
- const baseUrl = cfg.baseUrl?.replace(/\/$/, "");
871
- if (!baseUrl) throw new Error("createMixedHttpClient requires baseUrl");
872
- const fetchClient = createExposureFetch({
873
- baseUrl,
874
- auth: cfg.auth,
875
- timeoutMs: cfg.timeoutMs,
876
- fetchImpl: cfg.fetchImpl,
877
- serializer: cfg.serializer,
878
- onRequest: cfg.onRequest,
879
- contexts: cfg.contexts,
880
- errorRegistry: cfg.errorRegistry
881
- });
882
- const smartClient = createHttpSmartClient({
883
- baseUrl,
884
- auth: cfg.auth,
885
- timeoutMs: cfg.timeoutMs,
886
- serializer: cfg.serializer,
887
- onRequest: cfg.onRequest,
888
- contexts: cfg.contexts,
889
- errorRegistry: cfg.errorRegistry
890
- });
891
- return {
892
- async task(id2, input) {
893
- if (isReadable2(input) || hasNodeFile2(input) || await shouldForceSmart(cfg, id2, input)) {
894
- return await smartClient.task(id2, input);
895
- }
896
- return await fetchClient.task(id2, input);
897
- },
898
- async event(id2, payload) {
899
- return await fetchClient.event(id2, payload);
900
- },
901
- async eventWithResult(id2, payload) {
902
- if (!fetchClient.eventWithResult) {
903
- throw new Error(
904
- "createHttpMixedClient: eventWithResult not available on underlying tunnel client."
905
- );
906
- }
907
- return await fetchClient.eventWithResult(id2, payload);
908
- }
909
- };
910
- }
911
- var init_http_mixed_client = __esm({
912
- "src/node/http/http-mixed-client.ts"() {
913
- init_http_fetch_tunnel_resource();
914
- init_http_smart_client_model();
915
- __name(isReadable2, "isReadable");
916
- __name(hasNodeFile2, "hasNodeFile");
917
- __name(shouldForceSmart, "shouldForceSmart");
918
- __name(createHttpMixedClient, "createHttpMixedClient");
919
- }
920
- });
921
47
 
922
48
  // node_modules/ms/index.js
923
49
  var require_ms = __commonJS({
@@ -28588,15 +27714,12 @@ var symbolPhantomTask = Symbol.for(
28588
27714
  "runner.task.phantom"
28589
27715
  );
28590
27716
  var symbolResource = Symbol.for("runner.resource");
28591
- var symbolResourceForkedFrom = Symbol.for(
28592
- "runner.resourceForkedFrom"
28593
- );
27717
+ var symbolForkedFrom = Symbol.for("runner.forkedFrom");
28594
27718
  var symbolResourceWithConfig = Symbol.for(
28595
27719
  "runner.resourceWithConfig"
28596
27720
  );
28597
27721
  var symbolEvent = Symbol.for("runner.event");
28598
27722
  var symbolError = Symbol.for("runner.error");
28599
- var symbolMiddleware = Symbol.for("runner.middleware");
28600
27723
  var symbolTaskMiddleware = Symbol.for(
28601
27724
  "runner.taskMiddleware"
28602
27725
  );
@@ -28645,235 +27768,27 @@ function getCallerFile() {
28645
27768
  }
28646
27769
  __name(getCallerFile, "getCallerFile");
28647
27770
 
28648
- // src/defs.ts
28649
- var defs_exports = {};
28650
- __export(defs_exports, {
28651
- CONTRACT: () => CONTRACT,
28652
- HookDependencyState: () => HookDependencyState,
28653
- RunnerMode: () => RunnerMode,
28654
- isOneOf: () => isOneOf,
28655
- onAnyOf: () => onAnyOf,
28656
- symbolAsyncContext: () => symbolAsyncContext,
28657
- symbolError: () => symbolError,
28658
- symbolEvent: () => symbolEvent,
28659
- symbolFilePath: () => symbolFilePath,
28660
- symbolHook: () => symbolHook,
28661
- symbolMiddleware: () => symbolMiddleware,
28662
- symbolMiddlewareConfigured: () => symbolMiddlewareConfigured,
28663
- symbolOptionalDependency: () => symbolOptionalDependency,
28664
- symbolPhantomTask: () => symbolPhantomTask,
28665
- symbolResource: () => symbolResource,
28666
- symbolResourceForkedFrom: () => symbolResourceForkedFrom,
28667
- symbolResourceMiddleware: () => symbolResourceMiddleware,
28668
- symbolResourceWithConfig: () => symbolResourceWithConfig,
28669
- symbolTag: () => symbolTag,
28670
- symbolTagConfigured: () => symbolTagConfigured,
28671
- symbolTask: () => symbolTask,
28672
- symbolTaskMiddleware: () => symbolTaskMiddleware,
28673
- symbolTunneledBy: () => symbolTunneledBy
28674
- });
28675
-
28676
- // src/types/event.ts
28677
- function onAnyOf(...defs) {
28678
- return defs;
28679
- }
28680
- __name(onAnyOf, "onAnyOf");
28681
- function isOneOf(emission, defs) {
28682
- return defs.some((d) => d.id === emission.id);
28683
- }
28684
- __name(isOneOf, "isOneOf");
28685
-
28686
- // src/types/runner.ts
28687
- var RunnerMode = /* @__PURE__ */ ((RunnerMode2) => {
28688
- RunnerMode2["TEST"] = "test";
28689
- RunnerMode2["DEV"] = "dev";
28690
- RunnerMode2["PROD"] = "prod";
28691
- return RunnerMode2;
28692
- })(RunnerMode || {});
28693
-
28694
- // src/types/contracts.ts
28695
- var CONTRACT = Symbol.for("runner.contract");
28696
-
28697
- // src/types/storeTypes.ts
28698
- var HookDependencyState = /* @__PURE__ */ ((HookDependencyState2) => {
28699
- HookDependencyState2["Pending"] = "pending";
28700
- HookDependencyState2["Computing"] = "computing";
28701
- HookDependencyState2["Ready"] = "ready";
28702
- return HookDependencyState2;
28703
- })(HookDependencyState || {});
28704
-
28705
- // src/definers/tools.ts
28706
- function isTask(definition) {
28707
- return definition && definition[symbolTask];
28708
- }
28709
- __name(isTask, "isTask");
28710
- function isResource(definition) {
28711
- return definition && definition[symbolResource];
28712
- }
28713
- __name(isResource, "isResource");
28714
- function isResourceWithConfig(definition) {
28715
- return definition && definition[symbolResourceWithConfig];
28716
- }
28717
- __name(isResourceWithConfig, "isResourceWithConfig");
28718
- function isEvent(definition) {
28719
- return definition && definition[symbolEvent];
28720
- }
28721
- __name(isEvent, "isEvent");
28722
- function isHook(definition) {
28723
- return definition && definition[symbolHook];
28724
- }
28725
- __name(isHook, "isHook");
28726
- function isTaskMiddleware(definition) {
28727
- return definition && definition[symbolTaskMiddleware];
28728
- }
28729
- __name(isTaskMiddleware, "isTaskMiddleware");
28730
- function isResourceMiddleware(definition) {
28731
- return definition && definition[symbolResourceMiddleware];
28732
- }
28733
- __name(isResourceMiddleware, "isResourceMiddleware");
28734
- function isTag(definition) {
28735
- return definition && definition[symbolTag];
28736
- }
28737
- __name(isTag, "isTag");
28738
- function isOptional(definition) {
28739
- return definition && definition[symbolOptionalDependency];
28740
- }
28741
- __name(isOptional, "isOptional");
28742
- function isError(definition) {
28743
- return Boolean(definition && definition[symbolError]);
28744
- }
28745
- __name(isError, "isError");
28746
- function isAsyncContext(definition) {
28747
- return Boolean(definition && definition[symbolAsyncContext]);
28748
- }
28749
- __name(isAsyncContext, "isAsyncContext");
28750
-
28751
- // src/tools/throws.ts
28752
- function invalidThrowsEntryError(owner, item) {
28753
- const got = item === null ? "null" : Array.isArray(item) ? "array" : typeof item === "object" ? "object" : typeof item;
28754
- return new Error(
28755
- `Invalid throws entry for ${owner.kind} ${owner.id}: expected error id string or Error helper, got ${got}`
28756
- );
28757
- }
28758
- __name(invalidThrowsEntryError, "invalidThrowsEntryError");
28759
- function toErrorIdList(owner, list) {
28760
- const ids = [];
28761
- const seen = /* @__PURE__ */ new Set();
28762
- for (const item of list) {
28763
- let id2;
28764
- if (typeof item === "string") {
28765
- if (item.trim().length === 0) {
28766
- throw invalidThrowsEntryError(owner, item);
28767
- }
28768
- id2 = item;
28769
- } else if (isError(item)) {
28770
- id2 = item.id;
28771
- if (typeof id2 !== "string" || id2.trim().length === 0) {
28772
- throw invalidThrowsEntryError(owner, item);
28773
- }
28774
- } else {
28775
- throw invalidThrowsEntryError(owner, item);
28776
- }
28777
- if (seen.has(id2)) continue;
28778
- seen.add(id2);
28779
- ids.push(id2);
28780
- }
28781
- return ids;
28782
- }
28783
- __name(toErrorIdList, "toErrorIdList");
28784
- function normalizeThrows(owner, throwsList) {
28785
- if (throwsList === void 0) return void 0;
28786
- return toErrorIdList(owner, throwsList);
28787
- }
28788
- __name(normalizeThrows, "normalizeThrows");
28789
-
28790
- // src/definers/defineTask.ts
28791
- function defineTask(taskConfig) {
28792
- const filePath = getCallerFile();
28793
- const id2 = taskConfig.id;
28794
- return {
28795
- [symbolTask]: true,
28796
- [symbolFilePath]: filePath,
28797
- id: id2,
28798
- dependencies: taskConfig.dependencies || {},
28799
- middleware: taskConfig.middleware || [],
28800
- run: taskConfig.run,
28801
- inputSchema: taskConfig.inputSchema,
28802
- resultSchema: taskConfig.resultSchema,
28803
- meta: taskConfig.meta || {},
28804
- tags: taskConfig.tags || [],
28805
- throws: normalizeThrows({ kind: "task", id: id2 }, taskConfig.throws),
28806
- // autorun,
28807
- optional() {
28808
- return {
28809
- inner: this,
28810
- [symbolOptionalDependency]: true
28811
- };
28812
- }
28813
- };
28814
- }
28815
- __name(defineTask, "defineTask");
28816
- defineTask.phantom = (taskConfig) => {
28817
- const taskDef = defineTask({
28818
- ...taskConfig,
28819
- run: /* @__PURE__ */ __name(async (_input) => {
28820
- return void 0;
28821
- }, "run")
28822
- });
28823
- taskDef[symbolPhantomTask] = true;
28824
- return taskDef;
28825
- };
28826
-
28827
- // src/definers/defineHook.ts
28828
- function defineHook(hookDef) {
28829
- const filePath = getCallerFile();
28830
- return {
28831
- [symbolHook]: true,
28832
- [symbolFilePath]: filePath,
28833
- id: hookDef.id,
28834
- dependencies: hookDef.dependencies || {},
28835
- on: hookDef.on,
28836
- order: hookDef.order,
28837
- run: hookDef.run,
28838
- meta: hookDef.meta || {},
28839
- tags: hookDef.tags || []
28840
- };
28841
- }
28842
- __name(defineHook, "defineHook");
28843
-
28844
- // src/errors.ts
28845
- var errors_exports = {};
28846
- __export(errors_exports, {
28847
- builderIncompleteError: () => builderIncompleteError,
28848
- cancellationError: () => cancellationError,
28849
- circularDependenciesError: () => circularDependenciesError,
28850
- contextError: () => contextError,
28851
- dependencyNotFoundError: () => dependencyNotFoundError,
28852
- duplicateRegistrationError: () => duplicateRegistrationError,
28853
- eventCycleError: () => eventCycleError,
28854
- eventEmissionCycleError: () => eventEmissionCycleError,
28855
- eventNotFoundError: () => eventNotFoundError,
28856
- isCancellationError: () => isCancellationError,
28857
- lockedError: () => lockedError,
28858
- middlewareNotRegisteredError: () => middlewareNotRegisteredError,
28859
- phantomTaskNotRoutedError: () => phantomTaskNotRoutedError,
28860
- platformUnsupportedFunctionError: () => platformUnsupportedFunctionError,
28861
- resourceNotFoundError: () => resourceNotFoundError,
28862
- storeAlreadyInitializedError: () => storeAlreadyInitializedError,
28863
- tagNotFoundError: () => tagNotFoundError,
28864
- taskNotRegisteredError: () => taskNotRegisteredError,
28865
- tunnelOwnershipConflictError: () => tunnelOwnershipConflictError,
28866
- unknownItemTypeError: () => unknownItemTypeError,
28867
- validationError: () => validationError
28868
- });
28869
-
28870
27771
  // src/definers/defineError.ts
27772
+ var isValidHttpCode = /* @__PURE__ */ __name((value) => Number.isInteger(value) && value >= 100 && value <= 599, "isValidHttpCode");
27773
+ var assertHttpCode = /* @__PURE__ */ __name((value) => {
27774
+ if (!isValidHttpCode(value)) {
27775
+ throw new Error(
27776
+ `Error httpCode must be an integer between 100 and 599. Received: ${value}`
27777
+ );
27778
+ }
27779
+ }, "assertHttpCode");
28871
27780
  var RunnerError = class extends Error {
28872
- constructor(id2, message, data) {
28873
- super(message);
27781
+ constructor(id2, message, data, httpCode, remediation) {
27782
+ super(
27783
+ remediation !== void 0 ? `${message}
27784
+
27785
+ Remediation: ${remediation}` : message
27786
+ );
28874
27787
  this.id = id2;
28875
27788
  this.data = data;
28876
27789
  this.name = id2;
27790
+ this.httpCode = httpCode;
27791
+ this.remediation = remediation;
28877
27792
  }
28878
27793
  static {
28879
27794
  __name(this, "RunnerError");
@@ -28893,10 +27808,20 @@ var ErrorHelper = class {
28893
27808
  get id() {
28894
27809
  return this.definition.id;
28895
27810
  }
27811
+ get httpCode() {
27812
+ return this.definition.httpCode;
27813
+ }
28896
27814
  throw(data) {
28897
27815
  const parsed = this.definition.dataSchema ? this.definition.dataSchema.parse(data) : data;
28898
27816
  const message = this.definition.format(parsed);
28899
- throw new RunnerError(this.definition.id, message, parsed);
27817
+ const remediation = typeof this.definition.remediation === "function" ? this.definition.remediation(parsed) : this.definition.remediation;
27818
+ throw new RunnerError(
27819
+ this.definition.id,
27820
+ message,
27821
+ parsed,
27822
+ this.definition.httpCode,
27823
+ remediation
27824
+ );
28900
27825
  }
28901
27826
  is(error2) {
28902
27827
  return error2 instanceof RunnerError && error2.name === this.definition.id;
@@ -28909,6 +27834,9 @@ var ErrorHelper = class {
28909
27834
  }
28910
27835
  };
28911
27836
  function defineError(definition, filePath) {
27837
+ if (definition.httpCode !== void 0) {
27838
+ assertHttpCode(definition.httpCode);
27839
+ }
28912
27840
  if (!definition.format) {
28913
27841
  definition.format = (data) => `${JSON.stringify(data)}`;
28914
27842
  }
@@ -28930,9 +27858,22 @@ function clone(s, patch) {
28930
27858
  __name(clone, "clone");
28931
27859
 
28932
27860
  // src/definers/builders/error/fluent-builder.ts
27861
+ var isValidHttpCode2 = /* @__PURE__ */ __name((value) => Number.isInteger(value) && value >= 100 && value <= 599, "isValidHttpCode");
27862
+ var assertHttpCode2 = /* @__PURE__ */ __name((value) => {
27863
+ if (!isValidHttpCode2(value)) {
27864
+ throw new Error(
27865
+ `Error httpCode must be an integer between 100 and 599. Received: ${value}`
27866
+ );
27867
+ }
27868
+ }, "assertHttpCode");
28933
27869
  function makeErrorBuilder(state) {
28934
27870
  const builder = {
28935
27871
  id: state.id,
27872
+ httpCode(code) {
27873
+ assertHttpCode2(code);
27874
+ const next = clone(state, { httpCode: code });
27875
+ return makeErrorBuilder(next);
27876
+ },
28936
27877
  serialize(fn) {
28937
27878
  const next = clone(state, { serialize: fn });
28938
27879
  return makeErrorBuilder(next);
@@ -28949,6 +27890,10 @@ function makeErrorBuilder(state) {
28949
27890
  const next = clone(state, { format: fn });
28950
27891
  return makeErrorBuilder(next);
28951
27892
  },
27893
+ remediation(advice) {
27894
+ const next = clone(state, { remediation: advice });
27895
+ return makeErrorBuilder(next);
27896
+ },
28952
27897
  meta(m) {
28953
27898
  const next = clone(state, { meta: m });
28954
27899
  return makeErrorBuilder(next);
@@ -28957,10 +27902,12 @@ function makeErrorBuilder(state) {
28957
27902
  return defineError(
28958
27903
  {
28959
27904
  id: state.id,
27905
+ httpCode: state.httpCode,
28960
27906
  serialize: state.serialize,
28961
27907
  parse: state.parse,
28962
27908
  dataSchema: state.dataSchema,
28963
27909
  format: state.format,
27910
+ remediation: state.remediation,
28964
27911
  meta: state.meta
28965
27912
  },
28966
27913
  state.filePath
@@ -28977,6 +27924,7 @@ function errorBuilder(id2) {
28977
27924
  const initial = Object.freeze({
28978
27925
  id: id2,
28979
27926
  filePath,
27927
+ httpCode: void 0,
28980
27928
  serialize: void 0,
28981
27929
  parse: void 0,
28982
27930
  dataSchema: void 0,
@@ -28985,7 +27933,13 @@ function errorBuilder(id2) {
28985
27933
  return makeErrorBuilder(initial);
28986
27934
  }
28987
27935
  __name(errorBuilder, "errorBuilder");
28988
- var error = errorBuilder;
27936
+ function isRunnerError(error2) {
27937
+ return error2 instanceof RunnerError;
27938
+ }
27939
+ __name(isRunnerError, "isRunnerError");
27940
+ var error = Object.assign(errorBuilder, {
27941
+ is: isRunnerError
27942
+ });
28989
27943
 
28990
27944
  // src/platform/adapters/node-als.ts
28991
27945
  async function loadAsyncLocalStorageClass() {
@@ -29151,20 +28105,67 @@ var EdgePlatformAdapter = class extends BrowserPlatformAdapter {
29151
28105
  constructor() {
29152
28106
  super(...arguments);
29153
28107
  this.id = "edge";
28108
+ this.alsClass = null;
28109
+ this.alsProbed = false;
29154
28110
  }
29155
28111
  static {
29156
28112
  __name(this, "EdgePlatformAdapter");
29157
28113
  }
28114
+ async init() {
28115
+ await this.probeAsyncLocalStorage();
28116
+ }
28117
+ /**
28118
+ * Attempt to discover AsyncLocalStorage from the runtime.
28119
+ * Checks globalThis first, then tries `import("node:async_hooks")`.
28120
+ */
28121
+ probeGlobalAsyncLocalStorage() {
28122
+ if (this.alsClass) return true;
28123
+ const g = globalThis;
28124
+ if (typeof g.AsyncLocalStorage === "function") {
28125
+ this.alsClass = g.AsyncLocalStorage;
28126
+ return true;
28127
+ }
28128
+ return false;
28129
+ }
28130
+ async probeAsyncLocalStorage() {
28131
+ if (this.alsProbed) return;
28132
+ if (this.probeGlobalAsyncLocalStorage()) {
28133
+ this.alsProbed = true;
28134
+ return;
28135
+ }
28136
+ try {
28137
+ const mod = await import('async_hooks');
28138
+ if (mod?.AsyncLocalStorage) {
28139
+ this.alsClass = mod.AsyncLocalStorage;
28140
+ }
28141
+ } catch {
28142
+ } finally {
28143
+ this.alsProbed = true;
28144
+ }
28145
+ }
29158
28146
  onShutdownSignal(_handler) {
29159
28147
  return () => {
29160
28148
  };
29161
28149
  }
28150
+ hasAsyncLocalStorage() {
28151
+ this.probeGlobalAsyncLocalStorage();
28152
+ return this.alsClass !== null;
28153
+ }
28154
+ createAsyncLocalStorage() {
28155
+ this.probeGlobalAsyncLocalStorage();
28156
+ if (this.alsClass) {
28157
+ return new this.alsClass();
28158
+ }
28159
+ return super.createAsyncLocalStorage();
28160
+ }
29162
28161
  };
29163
28162
 
29164
28163
  // src/platform/adapters/universal-generic.ts
29165
28164
  var GenericUniversalPlatformAdapter = class {
29166
28165
  constructor() {
29167
28166
  this.id = "universal";
28167
+ this.alsClass = null;
28168
+ this.alsProbed = false;
29168
28169
  this.setTimeout = globalThis.setTimeout;
29169
28170
  this.clearTimeout = globalThis.clearTimeout;
29170
28171
  }
@@ -29173,6 +28174,23 @@ var GenericUniversalPlatformAdapter = class {
29173
28174
  }
29174
28175
  async init() {
29175
28176
  }
28177
+ probeAsyncLocalStorage() {
28178
+ if (this.alsProbed) return;
28179
+ this.alsProbed = true;
28180
+ const g = globalThis;
28181
+ if (typeof g.Deno === "undefined") return;
28182
+ if (typeof g.AsyncLocalStorage === "function") {
28183
+ this.alsClass = g.AsyncLocalStorage;
28184
+ return;
28185
+ }
28186
+ try {
28187
+ const mod = __require("async_hooks");
28188
+ if (mod?.AsyncLocalStorage) {
28189
+ this.alsClass = mod.AsyncLocalStorage;
28190
+ }
28191
+ } catch {
28192
+ }
28193
+ }
29176
28194
  onUncaughtException(handler) {
29177
28195
  const tgt = globalThis;
29178
28196
  if (tgt.addEventListener) {
@@ -29227,9 +28245,14 @@ var GenericUniversalPlatformAdapter = class {
29227
28245
  return void 0;
29228
28246
  }
29229
28247
  hasAsyncLocalStorage() {
29230
- return false;
28248
+ this.probeAsyncLocalStorage();
28249
+ return this.alsClass !== null;
29231
28250
  }
29232
28251
  createAsyncLocalStorage() {
28252
+ this.probeAsyncLocalStorage();
28253
+ if (this.alsClass) {
28254
+ return new this.alsClass();
28255
+ }
29233
28256
  return {
29234
28257
  getStore: /* @__PURE__ */ __name(() => {
29235
28258
  platformUnsupportedFunctionError.throw({
@@ -29287,6 +28310,10 @@ var UniversalPlatformAdapter = class {
29287
28310
  if (this.inner) return;
29288
28311
  const kind = detectEnvironment();
29289
28312
  const global2 = globalThis;
28313
+ if (typeof global2.Deno !== "undefined") {
28314
+ this.inner = new GenericUniversalPlatformAdapter();
28315
+ return;
28316
+ }
29290
28317
  if (typeof global2.document !== "undefined" || typeof global2.addEventListener === "function") {
29291
28318
  this.inner = new BrowserPlatformAdapter();
29292
28319
  } else {
@@ -29355,70 +28382,17 @@ function getPlatform() {
29355
28382
  return platformInstance;
29356
28383
  }
29357
28384
  __name(getPlatform, "getPlatform");
29358
- function setPlatform(adapter) {
29359
- platformInstance = adapter;
29360
- adapter.id;
29361
- }
29362
- __name(setPlatform, "setPlatform");
29363
- var PlatformAdapter = class {
29364
- static {
29365
- __name(this, "PlatformAdapter");
29366
- }
29367
- constructor(env) {
29368
- const kind = env ?? detectEnvironment();
29369
- this.env = kind;
29370
- switch (kind) {
29371
- case "node":
29372
- this.inner = new NodePlatformAdapter();
29373
- break;
29374
- case "browser":
29375
- this.inner = new BrowserPlatformAdapter();
29376
- break;
29377
- case "edge":
29378
- this.inner = new EdgePlatformAdapter();
29379
- break;
29380
- case "universal":
29381
- this.inner = new GenericUniversalPlatformAdapter();
29382
- break;
29383
- default:
29384
- this.inner = new UniversalPlatformAdapter();
29385
- }
29386
- this.id = this.inner.id;
29387
- this.setTimeout = this.inner.setTimeout;
29388
- this.clearTimeout = this.inner.clearTimeout;
29389
- }
29390
- async init() {
29391
- return this.inner.init();
29392
- }
29393
- onUncaughtException(handler) {
29394
- return this.inner.onUncaughtException(handler);
29395
- }
29396
- onUnhandledRejection(handler) {
29397
- return this.inner.onUnhandledRejection(handler);
29398
- }
29399
- onShutdownSignal(handler) {
29400
- return this.inner.onShutdownSignal(handler);
29401
- }
29402
- exit(code) {
29403
- return this.inner.exit(code);
29404
- }
29405
- getEnv(key) {
29406
- return this.inner.getEnv(key);
29407
- }
29408
- hasAsyncLocalStorage() {
29409
- return this.inner.hasAsyncLocalStorage();
29410
- }
29411
- createAsyncLocalStorage() {
29412
- return this.inner.createAsyncLocalStorage();
29413
- }
29414
- };
29415
28385
 
29416
28386
  // src/errors.ts
29417
28387
  var duplicateRegistrationError = error("runner.errors.duplicateRegistration").format(
29418
28388
  ({ 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.`
28389
+ ).remediation(
28390
+ ({ type }) => `Ensure each ${type} has a unique id. If you need the same definition in multiple places, use .fork() to create a copy with a new id.`
29419
28391
  ).build();
29420
28392
  var dependencyNotFoundError = error("runner.errors.dependencyNotFound").format(
29421
28393
  ({ key }) => `Dependency ${key.toString()} not found. Did you forget to register it through a resource?`
28394
+ ).remediation(
28395
+ ({ key }) => `Register the dependency "${key.toString()}" in a parent resource using .register([${key.toString()}]). If the dependency is optional, use .optional() when declaring it.`
29422
28396
  ).build();
29423
28397
  var unknownItemTypeError = error(
29424
28398
  "runner.errors.unknownItemType"
@@ -29426,10 +28400,14 @@ var unknownItemTypeError = error(
29426
28400
  ({ item }) => `Unknown item type: ${String(
29427
28401
  item
29428
28402
  )}. Please ensure you are not using different versions of '@bluelibs/runner'`
28403
+ ).remediation(
28404
+ "Check that all packages depend on the same version of '@bluelibs/runner'. Run 'npm ls @bluelibs/runner' to detect duplicates."
29429
28405
  ).build();
29430
28406
  var contextError = error(
29431
28407
  "runner.errors.context"
29432
- ).format(({ details }) => details ?? "Context error").build();
28408
+ ).format(({ details }) => details ?? "Context error").remediation(
28409
+ "Verify the async context is registered in a parent resource and that .provide() was called before .use(). If the context is optional, use .optional() when declaring the dependency."
28410
+ ).build();
29433
28411
  var circularDependenciesError = error("runner.errors.circularDependencies").format(({ cycles }) => {
29434
28412
  const cycleDetails = cycles.map((cycle) => ` \u2022 ${cycle}`).join("\n");
29435
28413
  const hasMiddleware = cycles.some((cycle) => cycle.includes("middleware"));
@@ -29442,36 +28420,54 @@ var circularDependenciesError = error("runner.errors.circularDependencies").form
29442
28420
  }
29443
28421
  return `Circular dependencies detected:
29444
28422
  ${cycleDetails}${guidance}`;
29445
- }).build();
28423
+ }).remediation(
28424
+ "Break the cycle by extracting shared state into a new resource that both sides depend on, or use events for indirect communication."
28425
+ ).build();
29446
28426
  var eventNotFoundError = error(
29447
28427
  "runner.errors.eventNotFound"
29448
28428
  ).format(
29449
28429
  ({ id: id2 }) => `Event "${id2.toString()}" not found. Did you forget to register it?`
28430
+ ).remediation(
28431
+ ({ id: id2 }) => `Add the event "${id2.toString()}" to a parent resource via .register([yourEvent]). Ensure the event definition is built with r.event("${id2.toString()}").build().`
29450
28432
  ).build();
29451
- var resourceNotFoundError = error(
28433
+ error(
29452
28434
  "runner.errors.resourceNotFound"
29453
28435
  ).format(
29454
28436
  ({ id: id2 }) => `Resource "${id2.toString()}" not found. Did you forget to register it or are you using the correct id?`
28437
+ ).remediation(
28438
+ ({ id: id2 }) => `Register the resource "${id2.toString()}" in a parent resource via .register([yourResource]). Verify the id string matches exactly (ids are case-sensitive).`
29455
28439
  ).build();
29456
28440
  var middlewareNotRegisteredError = error("runner.errors.middlewareNotRegistered").format(
29457
28441
  ({ type, source, middlewareId }) => `Middleware inside ${type} "${source}" depends on "${middlewareId}" but it's not registered. Did you forget to register it?`
28442
+ ).remediation(
28443
+ ({ middlewareId }) => `Register the middleware "${middlewareId}" alongside its consumer in a parent resource via .register([yourMiddleware]).`
29458
28444
  ).build();
29459
28445
  var tagNotFoundError = error(
29460
28446
  "runner.errors.tagNotFound"
29461
28447
  ).format(
29462
28448
  ({ id: id2 }) => `Tag "${id2}" not registered. Did you forget to register it inside a resource?`
28449
+ ).remediation(
28450
+ ({ id: id2 }) => `Register the tag "${id2}" in a parent resource via .register([yourTag]). Tags must be registered before they can be queried.`
29463
28451
  ).build();
29464
28452
  var lockedError = error(
29465
28453
  "runner.errors.locked"
29466
28454
  ).format(
29467
28455
  ({ what }) => `Cannot modify the ${what.toString()} when it is locked.`
28456
+ ).remediation(
28457
+ ({ what }) => `The ${what.toString()} is locked after initialization. Perform all modifications before calling run().`
29468
28458
  ).build();
29469
28459
  var storeAlreadyInitializedError = error(
29470
28460
  "runner.errors.storeAlreadyInitialized"
29471
- ).format(() => "Store already initialized. Cannot reinitialize.").build();
28461
+ ).format(() => "Store already initialized. Cannot reinitialize.").remediation(
28462
+ "Do not call run() more than once on the same resource tree. Create a fresh resource if you need a separate runtime."
28463
+ ).build();
29472
28464
  var validationError = error("runner.errors.validation").format(({ subject, id: id2, originalError }) => {
29473
28465
  const errorMessage2 = originalError instanceof Error ? originalError.message : String(originalError);
29474
28466
  return `${subject} validation failed for ${id2.toString()}: ${errorMessage2}`;
28467
+ }).remediation(({ subject, id: id2 }) => {
28468
+ const lower = subject.toLowerCase();
28469
+ const schemaHint = lower.includes("input") ? "inputSchema" : lower.includes("config") ? "configSchema" : lower.includes("result") ? "resultSchema" : "schema";
28470
+ return `Check the ${subject} passed to "${id2.toString()}". Ensure it matches the schema defined via .${schemaHint}().`;
29475
28471
  }).build();
29476
28472
  var eventCycleError = error("runner.errors.eventCycle").format(({ path: path4 }) => {
29477
28473
  const chain = path4.map((p) => `${p.id}\u2190${p.source}`).join(" -> ");
@@ -29479,37 +28475,188 @@ var eventCycleError = error("runner.errors.eventCycle").format(({ path: path4 })
29479
28475
  ${chain}
29480
28476
 
29481
28477
  Break the cycle by changing hook logic (avoid mutual emits) or gate with conditions/tags.`;
29482
- }).build();
28478
+ }).remediation(
28479
+ "Refactor hooks to avoid circular event emissions. Use conditional guards, split events into finer-grained signals, or introduce an intermediate task to break the cycle."
28480
+ ).build();
29483
28481
  var eventEmissionCycleError = error("runner.errors.eventEmissionCycle").format(({ cycles }) => {
29484
28482
  const list = cycles.map((c) => ` \u2022 ${c}`).join("\n");
29485
28483
  return `Event emission cycles detected between hooks and events:
29486
28484
  ${list}
29487
28485
 
29488
28486
  This was detected at compile time (dry-run). Break the cycle by avoiding mutual emits between hooks or scoping hooks using tags.`;
29489
- }).build();
28487
+ }).remediation(
28488
+ "Redesign the event/hook graph so no hook emits an event that eventually triggers itself. Use tags or conditional logic to prevent re-entrant emissions."
28489
+ ).build();
29490
28490
  var platformUnsupportedFunctionError = error("runner.errors.platformUnsupportedFunction").format(
29491
28491
  ({ functionName }) => `Platform function not supported in this environment: ${functionName}. Detected platform: ${detectEnvironment()}.`
28492
+ ).remediation(
28493
+ ({ functionName }) => `The function "${functionName}" requires a Node.js environment. If running in a browser or edge runtime, use a platform-compatible alternative or guard the call with a platform check.`
29492
28494
  ).build();
29493
28495
  var cancellationError = error(
29494
28496
  "runner.errors.cancellation"
29495
- ).format(({ reason }) => reason || "Operation cancelled").build();
28497
+ ).format(({ reason }) => reason || "Operation cancelled").remediation(
28498
+ "The operation was cancelled, typically via an AbortController signal. If this is unexpected, check timeout middleware settings or ensure the caller is not aborting prematurely."
28499
+ ).build();
29496
28500
  var tunnelOwnershipConflictError = error("runner.errors.tunnelOwnershipConflict").format(
29497
28501
  ({ 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.`
28502
+ ).remediation(
28503
+ ({ taskId }) => `Each task can only be tunneled by one client. Remove the duplicate tunnel registration for "${taskId}" or split the task into separate definitions with distinct ids.`
29498
28504
  ).build();
29499
28505
  var phantomTaskNotRoutedError = error("runner.errors.phantomTaskNotRouted").format(
29500
28506
  ({ taskId }) => `Phantom task "${taskId}" is not routed through any tunnel. Ensure a tunnel client selects this task id (or avoid calling the phantom task directly).`
28507
+ ).remediation(
28508
+ ({ taskId }) => `Configure a tunnel client resource to select "${taskId}" so it routes to a remote server. Phantom tasks cannot be executed locally \u2014 they only serve as local proxies for remote tasks.`
29501
28509
  ).build();
29502
28510
  var taskNotRegisteredError = error("runner.errors.taskNotRegistered").format(
29503
28511
  ({ taskId }) => `Task "${taskId}" is not registered in the Store. This is an internal error\u2014ensure the task is registered before execution.`
28512
+ ).remediation(
28513
+ ({ taskId }) => `Register the task "${taskId}" in a parent resource via .register([yourTask]) before calling run(). If this error persists, it may indicate an internal framework bug.`
29504
28514
  ).build();
29505
28515
  var builderIncompleteError = error("runner.errors.builderIncomplete").format(({ type, builderId, missingFields }) => {
29506
28516
  const typeLabel = type === "hook" ? "Hook" : type === "task-middleware" ? "Task middleware" : "Resource middleware";
29507
28517
  return `${typeLabel} "${builderId}" is incomplete. Missing required: ${missingFields.join(", ")}. Call ${missingFields.map((f) => `.${f}()`).join(" and ")} before .build().`;
29508
- }).build();
29509
- function isCancellationError(err) {
29510
- return cancellationError.is(err);
28518
+ }).remediation(
28519
+ ({ missingFields }) => `Add the missing builder steps: ${missingFields.map((f) => `.${f}()`).join(", ")} before calling .build().`
28520
+ ).build();
28521
+
28522
+ // src/definers/tools.ts
28523
+ function isTask(definition) {
28524
+ return definition && definition[symbolTask];
28525
+ }
28526
+ __name(isTask, "isTask");
28527
+ function isResource(definition) {
28528
+ return definition && definition[symbolResource];
28529
+ }
28530
+ __name(isResource, "isResource");
28531
+ function isResourceWithConfig(definition) {
28532
+ return definition && definition[symbolResourceWithConfig];
28533
+ }
28534
+ __name(isResourceWithConfig, "isResourceWithConfig");
28535
+ function isEvent(definition) {
28536
+ return definition && definition[symbolEvent];
28537
+ }
28538
+ __name(isEvent, "isEvent");
28539
+ function isHook(definition) {
28540
+ return definition && definition[symbolHook];
28541
+ }
28542
+ __name(isHook, "isHook");
28543
+ function isTaskMiddleware(definition) {
28544
+ return definition && definition[symbolTaskMiddleware];
28545
+ }
28546
+ __name(isTaskMiddleware, "isTaskMiddleware");
28547
+ function isResourceMiddleware(definition) {
28548
+ return definition && definition[symbolResourceMiddleware];
28549
+ }
28550
+ __name(isResourceMiddleware, "isResourceMiddleware");
28551
+ function isTag(definition) {
28552
+ return definition && definition[symbolTag];
28553
+ }
28554
+ __name(isTag, "isTag");
28555
+ function isOptional(definition) {
28556
+ return definition && definition[symbolOptionalDependency];
28557
+ }
28558
+ __name(isOptional, "isOptional");
28559
+ function isError(definition) {
28560
+ return Boolean(definition && definition[symbolError]);
28561
+ }
28562
+ __name(isError, "isError");
28563
+ function isAsyncContext(definition) {
28564
+ return Boolean(definition && definition[symbolAsyncContext]);
28565
+ }
28566
+ __name(isAsyncContext, "isAsyncContext");
28567
+
28568
+ // src/tools/throws.ts
28569
+ function invalidThrowsEntryError(owner, item) {
28570
+ const got = item === null ? "null" : Array.isArray(item) ? "array" : typeof item === "object" ? "object" : typeof item;
28571
+ return new Error(
28572
+ `Invalid throws entry for ${owner.kind} ${owner.id}: expected error id string or Error helper, got ${got}`
28573
+ );
28574
+ }
28575
+ __name(invalidThrowsEntryError, "invalidThrowsEntryError");
28576
+ function toErrorIdList(owner, list) {
28577
+ const ids = [];
28578
+ const seen = /* @__PURE__ */ new Set();
28579
+ for (const item of list) {
28580
+ let id2;
28581
+ if (typeof item === "string") {
28582
+ if (item.trim().length === 0) {
28583
+ throw invalidThrowsEntryError(owner, item);
28584
+ }
28585
+ id2 = item;
28586
+ } else if (isError(item)) {
28587
+ id2 = item.id;
28588
+ if (typeof id2 !== "string" || id2.trim().length === 0) {
28589
+ throw invalidThrowsEntryError(owner, item);
28590
+ }
28591
+ } else {
28592
+ throw invalidThrowsEntryError(owner, item);
28593
+ }
28594
+ if (seen.has(id2)) continue;
28595
+ seen.add(id2);
28596
+ ids.push(id2);
28597
+ }
28598
+ return ids;
28599
+ }
28600
+ __name(toErrorIdList, "toErrorIdList");
28601
+ function normalizeThrows(owner, throwsList) {
28602
+ if (throwsList === void 0) return void 0;
28603
+ return toErrorIdList(owner, throwsList);
28604
+ }
28605
+ __name(normalizeThrows, "normalizeThrows");
28606
+
28607
+ // src/definers/defineTask.ts
28608
+ function defineTask(taskConfig) {
28609
+ const filePath = getCallerFile();
28610
+ const id2 = taskConfig.id;
28611
+ return {
28612
+ [symbolTask]: true,
28613
+ [symbolFilePath]: filePath,
28614
+ id: id2,
28615
+ dependencies: taskConfig.dependencies || {},
28616
+ middleware: taskConfig.middleware || [],
28617
+ run: taskConfig.run,
28618
+ inputSchema: taskConfig.inputSchema,
28619
+ resultSchema: taskConfig.resultSchema,
28620
+ meta: taskConfig.meta || {},
28621
+ tags: taskConfig.tags || [],
28622
+ throws: normalizeThrows({ kind: "task", id: id2 }, taskConfig.throws),
28623
+ // autorun,
28624
+ optional() {
28625
+ return {
28626
+ inner: this,
28627
+ [symbolOptionalDependency]: true
28628
+ };
28629
+ }
28630
+ };
29511
28631
  }
29512
- __name(isCancellationError, "isCancellationError");
28632
+ __name(defineTask, "defineTask");
28633
+ defineTask.phantom = (taskConfig) => {
28634
+ const taskDef = defineTask({
28635
+ ...taskConfig,
28636
+ run: /* @__PURE__ */ __name(async (_input) => {
28637
+ phantomTaskNotRoutedError.throw({ taskId: taskConfig.id });
28638
+ }, "run")
28639
+ });
28640
+ taskDef[symbolPhantomTask] = true;
28641
+ return taskDef;
28642
+ };
28643
+
28644
+ // src/definers/defineHook.ts
28645
+ function defineHook(hookDef) {
28646
+ const filePath = getCallerFile();
28647
+ return {
28648
+ [symbolHook]: true,
28649
+ [symbolFilePath]: filePath,
28650
+ id: hookDef.id,
28651
+ dependencies: hookDef.dependencies || {},
28652
+ on: hookDef.on,
28653
+ order: hookDef.order,
28654
+ run: hookDef.run,
28655
+ meta: hookDef.meta || {},
28656
+ tags: hookDef.tags || []
28657
+ };
28658
+ }
28659
+ __name(defineHook, "defineHook");
29513
28660
 
29514
28661
  // src/definers/resourceFork.ts
29515
28662
  function resolveReId(forkId, options) {
@@ -29739,6 +28886,7 @@ function defineResource(constConfig) {
29739
28886
  };
29740
28887
  },
29741
28888
  fork(newId, options) {
28889
+ const forkCallerFilePath = getCallerFile();
29742
28890
  const forkedParts = resolveForkedRegisterAndDependencies({
29743
28891
  register: constConfig.register,
29744
28892
  dependencies: constConfig.dependencies,
@@ -29750,11 +28898,10 @@ function defineResource(constConfig) {
29750
28898
  id: newId,
29751
28899
  register: forkedParts.register,
29752
28900
  dependencies: forkedParts.dependencies,
29753
- [symbolFilePath]: filePath
28901
+ [symbolFilePath]: forkCallerFilePath
29754
28902
  });
29755
- forked[symbolResourceForkedFrom] = {
29756
- fromId: id2,
29757
- forkedAtFilePath: getCallerFile()
28903
+ forked[symbolForkedFrom] = {
28904
+ fromId: id2
29758
28905
  };
29759
28906
  return forked;
29760
28907
  }
@@ -29985,7 +29132,7 @@ __name(defineTag, "defineTag");
29985
29132
 
29986
29133
  // src/globals/middleware/requireContext.middleware.ts
29987
29134
  var requireContextTaskMiddleware = defineTaskMiddleware({
29988
- id: "globals.middleware.requireContext",
29135
+ id: "globals.middleware.task.requireContext",
29989
29136
  async run({ task: task2, next }, _deps, config) {
29990
29137
  if (!config.context) {
29991
29138
  throw new Error(
@@ -30004,12 +29151,6 @@ var SymbolPolicy = /* @__PURE__ */ ((SymbolPolicy2) => {
30004
29151
  SymbolPolicy2["Disabled"] = "Disabled";
30005
29152
  return SymbolPolicy2;
30006
29153
  })(SymbolPolicy || {});
30007
- var SymbolPolicyErrorMessage = /* @__PURE__ */ ((SymbolPolicyErrorMessage2) => {
30008
- SymbolPolicyErrorMessage2["GlobalSymbolsNotAllowed"] = "Global symbols are not allowed";
30009
- SymbolPolicyErrorMessage2["SymbolsNotAllowed"] = "Symbols are not allowed";
30010
- SymbolPolicyErrorMessage2["UnsupportedSymbolPolicy"] = "Unsupported symbol policy";
30011
- return SymbolPolicyErrorMessage2;
30012
- })(SymbolPolicyErrorMessage || {});
30013
29154
 
30014
29155
  // src/serializer/binary-builtins.ts
30015
29156
  var INVALID_PAYLOAD_MESSAGE_PREFIX = "Invalid";
@@ -30517,8 +29658,124 @@ var builtInTypes = [
30517
29658
  ...binaryBuiltInTypes
30518
29659
  ];
30519
29660
 
29661
+ // src/serializer/regexp-validator.ts
29662
+ var isQuantifierAt = /* @__PURE__ */ __name((pattern, index) => {
29663
+ if (index >= pattern.length) {
29664
+ return false;
29665
+ }
29666
+ const char = pattern[index];
29667
+ if (char === "*" || char === "+" || char === "?") {
29668
+ return true;
29669
+ }
29670
+ if (char === "{") {
29671
+ return isBoundedQuantifier(pattern, index);
29672
+ }
29673
+ return false;
29674
+ }, "isQuantifierAt");
29675
+ var isQuantifierChar = /* @__PURE__ */ __name((char, pattern, index) => {
29676
+ if (char === "*" || char === "+") {
29677
+ return true;
29678
+ }
29679
+ if (char === "?") {
29680
+ if (index > 0 && pattern[index - 1] === "(") {
29681
+ return false;
29682
+ }
29683
+ return true;
29684
+ }
29685
+ if (char === "{") {
29686
+ return isBoundedQuantifier(pattern, index);
29687
+ }
29688
+ return false;
29689
+ }, "isQuantifierChar");
29690
+ var isBoundedQuantifier = /* @__PURE__ */ __name((pattern, index) => {
29691
+ let sawDigit = false;
29692
+ let sawComma = false;
29693
+ for (let i = index + 1; i < pattern.length; i += 1) {
29694
+ const char = pattern[i];
29695
+ if (char >= "0" && char <= "9") {
29696
+ sawDigit = true;
29697
+ continue;
29698
+ }
29699
+ if (char === "," && !sawComma) {
29700
+ sawComma = true;
29701
+ continue;
29702
+ }
29703
+ if (char === "}") {
29704
+ return sawDigit;
29705
+ }
29706
+ return false;
29707
+ }
29708
+ return false;
29709
+ }, "isBoundedQuantifier");
29710
+ var isRegExpPatternSafe = /* @__PURE__ */ __name((pattern) => {
29711
+ const groupStack = [];
29712
+ let escaped = false;
29713
+ let inCharClass = false;
29714
+ for (let index = 0; index < pattern.length; index += 1) {
29715
+ const char = pattern[index];
29716
+ if (escaped) {
29717
+ escaped = false;
29718
+ continue;
29719
+ }
29720
+ if (char === "\\") {
29721
+ escaped = true;
29722
+ continue;
29723
+ }
29724
+ if (inCharClass) {
29725
+ if (char === "]") {
29726
+ inCharClass = false;
29727
+ }
29728
+ continue;
29729
+ }
29730
+ if (char === "[") {
29731
+ inCharClass = true;
29732
+ continue;
29733
+ }
29734
+ if (char === "(") {
29735
+ groupStack.push({ hasQuantifier: false });
29736
+ if (pattern[index + 1] === "?") {
29737
+ index += 1;
29738
+ }
29739
+ continue;
29740
+ }
29741
+ if (char === ")") {
29742
+ const group = groupStack.pop();
29743
+ if (group?.hasQuantifier && isQuantifierAt(pattern, index + 1)) {
29744
+ return false;
29745
+ }
29746
+ if (group?.hasQuantifier && groupStack.length > 0) {
29747
+ groupStack[groupStack.length - 1].hasQuantifier = true;
29748
+ }
29749
+ continue;
29750
+ }
29751
+ if (isQuantifierChar(char, pattern, index)) {
29752
+ if (groupStack.length > 0) {
29753
+ groupStack[groupStack.length - 1].hasQuantifier = true;
29754
+ }
29755
+ }
29756
+ }
29757
+ return true;
29758
+ }, "isRegExpPatternSafe");
29759
+ var assertRegExpPayload = /* @__PURE__ */ __name((value, options) => {
29760
+ if (!value || typeof value !== "object") {
29761
+ throw new Error("Invalid RegExp payload");
29762
+ }
29763
+ const record = value;
29764
+ if (typeof record.pattern !== "string" || typeof record.flags !== "string") {
29765
+ throw new Error("Invalid RegExp payload");
29766
+ }
29767
+ if (record.pattern.length > options.maxPatternLength) {
29768
+ throw new Error(
29769
+ `RegExp pattern exceeds limit (${options.maxPatternLength})`
29770
+ );
29771
+ }
29772
+ if (!options.allowUnsafe && !isRegExpPatternSafe(record.pattern)) {
29773
+ throw new Error("Unsafe RegExp pattern");
29774
+ }
29775
+ return { pattern: record.pattern, flags: record.flags };
29776
+ }, "assertRegExpPayload");
29777
+
30520
29778
  // src/serializer/type-registry.ts
30521
- init_regexp_validator();
30522
29779
  var TypeRegistry = class {
30523
29780
  constructor(options) {
30524
29781
  this.typeRegistry = /* @__PURE__ */ new Map();
@@ -31277,29 +30534,25 @@ var Serializer = class {
31277
30534
  * @internal - Exposed for testing RegExp safety validation
31278
30535
  */
31279
30536
  this.isRegExpPatternSafe = /* @__PURE__ */ __name((pattern) => {
31280
- const { isRegExpPatternSafe: check } = (init_regexp_validator(), __toCommonJS(regexp_validator_exports));
31281
- return check(pattern);
30537
+ return isRegExpPatternSafe(pattern);
31282
30538
  }, "isRegExpPatternSafe");
31283
30539
  /**
31284
30540
  * @internal - Exposed for testing quantifier detection
31285
30541
  */
31286
30542
  this.isQuantifierAt = /* @__PURE__ */ __name((pattern, index) => {
31287
- const { isQuantifierAt: check } = (init_regexp_validator(), __toCommonJS(regexp_validator_exports));
31288
- return check(pattern, index);
30543
+ return isQuantifierAt(pattern, index);
31289
30544
  }, "isQuantifierAt");
31290
30545
  /**
31291
30546
  * @internal - Exposed for testing quantifier character detection
31292
30547
  */
31293
30548
  this.isQuantifierChar = /* @__PURE__ */ __name((char, pattern, index) => {
31294
- const { isQuantifierChar: check } = (init_regexp_validator(), __toCommonJS(regexp_validator_exports));
31295
- return check(char, pattern, index);
30549
+ return isQuantifierChar(char, pattern, index);
31296
30550
  }, "isQuantifierChar");
31297
30551
  /**
31298
30552
  * @internal - Exposed for testing bounded quantifier detection
31299
30553
  */
31300
30554
  this.isBoundedQuantifier = /* @__PURE__ */ __name((pattern, index) => {
31301
- const { isBoundedQuantifier: check } = (init_regexp_validator(), __toCommonJS(regexp_validator_exports));
31302
- return check(pattern, index);
30555
+ return isBoundedQuantifier(pattern, index);
31303
30556
  }, "isBoundedQuantifier");
31304
30557
  this.indent = options.pretty ? 2 : void 0;
31305
30558
  this.maxDepth = normalizeMaxDepth(options.maxDepth, DEFAULT_MAX_DEPTH);
@@ -31502,11 +30755,6 @@ function defineAsyncContext(def, filePath) {
31502
30755
  return api;
31503
30756
  }
31504
30757
  __name(defineAsyncContext, "defineAsyncContext");
31505
- function createContext(name) {
31506
- const id2 = name ?? `context.${Math.random().toString(36).slice(2)}.${Date.now()}`;
31507
- return defineAsyncContext({ id: id2 });
31508
- }
31509
- __name(createContext, "createContext");
31510
30758
 
31511
30759
  // src/globals/resources/debug/debug.tag.ts
31512
30760
  var debugTag = defineTag({
@@ -31629,7 +30877,7 @@ var cacheFactoryTask = defineTask({
31629
30877
  });
31630
30878
  var journalKeys = {
31631
30879
  /** Whether the result was served from cache (true) or freshly computed (false) */
31632
- hit: journal.createKey("globals.middleware.cache.hit")
30880
+ hit: journal.createKey("globals.middleware.task.cache.hit")
31633
30881
  };
31634
30882
  var cacheResource = defineResource({
31635
30883
  id: "globals.resources.cache",
@@ -31659,7 +30907,7 @@ var cacheResource = defineResource({
31659
30907
  });
31660
30908
  var defaultKeyBuilder = /* @__PURE__ */ __name((taskId, input) => `${taskId}-${JSON.stringify(input)}`, "defaultKeyBuilder");
31661
30909
  var cacheMiddleware = defineTaskMiddleware({
31662
- id: "globals.middleware.cache",
30910
+ id: "globals.middleware.task.cache",
31663
30911
  dependencies: { cache: cacheResource },
31664
30912
  async run({ task: task2, next, journal: journal2 }, deps, config) {
31665
30913
  const { cache } = deps;
@@ -31710,11 +30958,11 @@ var CircuitBreakerOpenError = class extends Error {
31710
30958
  var journalKeys2 = {
31711
30959
  /** Current state of the circuit breaker (CLOSED, OPEN, or HALF_OPEN) */
31712
30960
  state: journal.createKey(
31713
- "globals.middleware.circuitBreaker.state"
30961
+ "globals.middleware.task.circuitBreaker.state"
31714
30962
  ),
31715
30963
  /** Current failure count */
31716
30964
  failures: journal.createKey(
31717
- "globals.middleware.circuitBreaker.failures"
30965
+ "globals.middleware.task.circuitBreaker.failures"
31718
30966
  )
31719
30967
  };
31720
30968
  var circuitBreakerResource = defineResource({
@@ -31727,7 +30975,7 @@ var circuitBreakerResource = defineResource({
31727
30975
  }, "init")
31728
30976
  });
31729
30977
  var circuitBreakerMiddleware = defineTaskMiddleware({
31730
- id: "globals.middleware.circuitBreaker",
30978
+ id: "globals.middleware.task.circuitBreaker",
31731
30979
  dependencies: { state: circuitBreakerResource },
31732
30980
  async run({ task: task2, next, journal: journal2 }, { state }, config) {
31733
30981
  const taskId = task2.definition.id;
@@ -32307,12 +31555,12 @@ var EventManager = class {
32307
31555
 
32308
31556
  // src/models/Semaphore.ts
32309
31557
  var SemaphoreEvents = {
32310
- queued: defineEvent({ id: "semaphore.queued" }),
32311
- acquired: defineEvent({ id: "semaphore.acquired" }),
32312
- released: defineEvent({ id: "semaphore.released" }),
32313
- timeout: defineEvent({ id: "semaphore.timeout" }),
32314
- aborted: defineEvent({ id: "semaphore.aborted" }),
32315
- disposed: defineEvent({ id: "semaphore.disposed" })
31558
+ queued: defineEvent({ id: "semaphore.events.queued" }),
31559
+ acquired: defineEvent({ id: "semaphore.events.acquired" }),
31560
+ released: defineEvent({ id: "semaphore.events.released" }),
31561
+ timeout: defineEvent({ id: "semaphore.events.timeout" }),
31562
+ aborted: defineEvent({ id: "semaphore.events.aborted" }),
31563
+ disposed: defineEvent({ id: "semaphore.events.disposed" })
32316
31564
  };
32317
31565
  var Semaphore = class {
32318
31566
  constructor(maxPermits) {
@@ -32585,7 +31833,7 @@ var concurrencyResource = defineResource({
32585
31833
  }), "init")
32586
31834
  });
32587
31835
  var concurrencyTaskMiddleware = defineTaskMiddleware({
32588
- id: "globals.middleware.concurrency",
31836
+ id: "globals.middleware.task.concurrency",
32589
31837
  dependencies: { state: concurrencyResource },
32590
31838
  async run({ task: task2, next }, { state }, config) {
32591
31839
  let semaphore = config.semaphore;
@@ -32664,14 +31912,16 @@ var RateLimitError = class extends Error {
32664
31912
  var journalKeys3 = {
32665
31913
  /** Number of remaining requests in the current window */
32666
31914
  remaining: journal.createKey(
32667
- "globals.middleware.rateLimit.remaining"
31915
+ "globals.middleware.task.rateLimit.remaining"
32668
31916
  ),
32669
31917
  /** Timestamp when the current window resets */
32670
31918
  resetTime: journal.createKey(
32671
- "globals.middleware.rateLimit.resetTime"
31919
+ "globals.middleware.task.rateLimit.resetTime"
32672
31920
  ),
32673
31921
  /** Maximum requests allowed per window */
32674
- limit: journal.createKey("globals.middleware.rateLimit.limit")
31922
+ limit: journal.createKey(
31923
+ "globals.middleware.task.rateLimit.limit"
31924
+ )
32675
31925
  };
32676
31926
  var rateLimitResource = defineResource({
32677
31927
  id: "globals.resources.rateLimit",
@@ -32683,7 +31933,7 @@ var rateLimitResource = defineResource({
32683
31933
  }, "init")
32684
31934
  });
32685
31935
  var rateLimitTaskMiddleware = defineTaskMiddleware({
32686
- id: "globals.middleware.rateLimit",
31936
+ id: "globals.middleware.task.rateLimit",
32687
31937
  configSchema: rateLimitConfigSchema,
32688
31938
  dependencies: { state: rateLimitResource },
32689
31939
  async run({ task: task2, next, journal: journal2 }, { state }, config) {
@@ -32731,7 +31981,7 @@ var temporalResource = defineResource({
32731
31981
  }, "init")
32732
31982
  });
32733
31983
  var debounceTaskMiddleware = defineTaskMiddleware({
32734
- id: "globals.middleware.debounce",
31984
+ id: "globals.middleware.task.debounce",
32735
31985
  dependencies: { state: temporalResource },
32736
31986
  async run({ task: task2, next }, { state }, config) {
32737
31987
  const { debounceStates } = state;
@@ -32768,7 +32018,7 @@ var debounceTaskMiddleware = defineTaskMiddleware({
32768
32018
  }
32769
32019
  });
32770
32020
  var throttleTaskMiddleware = defineTaskMiddleware({
32771
- id: "globals.middleware.throttle",
32021
+ id: "globals.middleware.task.throttle",
32772
32022
  dependencies: { state: temporalResource },
32773
32023
  async run({ task: task2, next }, { state }, config) {
32774
32024
  const { throttleStates } = state;
@@ -32840,12 +32090,12 @@ var throttleTaskMiddleware = defineTaskMiddleware({
32840
32090
 
32841
32091
  // src/models/Queue.ts
32842
32092
  var QueueEvents = {
32843
- enqueue: defineEvent({ id: "queue.enqueue" }),
32844
- start: defineEvent({ id: "queue.start" }),
32845
- finish: defineEvent({ id: "queue.finish" }),
32846
- error: defineEvent({ id: "queue.error" }),
32847
- cancel: defineEvent({ id: "queue.cancel" }),
32848
- disposed: defineEvent({ id: "queue.disposed" })
32093
+ enqueue: defineEvent({ id: "queue.events.enqueue" }),
32094
+ start: defineEvent({ id: "queue.events.start" }),
32095
+ finish: defineEvent({ id: "queue.events.finish" }),
32096
+ error: defineEvent({ id: "queue.events.error" }),
32097
+ cancel: defineEvent({ id: "queue.events.cancel" }),
32098
+ disposed: defineEvent({ id: "queue.events.disposed" })
32849
32099
  };
32850
32100
  var Queue = class {
32851
32101
  constructor() {
@@ -32994,11 +32244,218 @@ var queueResource = defineResource({
32994
32244
  }
32995
32245
  });
32996
32246
 
32997
- // src/http-client.ts
32998
- init_protocol();
32999
- init_http_fetch_tunnel_resource();
32247
+ // src/globals/resources/tunnel/protocol.ts
32248
+ var TunnelError = class extends Error {
32249
+ static {
32250
+ __name(this, "TunnelError");
32251
+ }
32252
+ constructor(code, message, details, extras) {
32253
+ super(message);
32254
+ this.name = "TunnelError";
32255
+ this.code = code;
32256
+ this.details = details;
32257
+ this.httpCode = extras?.httpCode;
32258
+ this.id = extras?.id;
32259
+ this.data = extras?.data;
32260
+ }
32261
+ };
32262
+ function toTunnelError(input, fallbackMessage) {
32263
+ if (input instanceof Error) {
32264
+ return new TunnelError("UNKNOWN", input.message);
32265
+ }
32266
+ if (input && typeof input === "object" && "code" in input && "message" in input) {
32267
+ const typed = input;
32268
+ if (typeof typed.message === "string" && typeof typed.code === "string") {
32269
+ const pe = input;
32270
+ const msg = pe.message || fallbackMessage || "Tunnel error";
32271
+ return new TunnelError(pe.code, msg, pe.details, {
32272
+ httpCode: pe.httpCode,
32273
+ id: pe.id,
32274
+ data: pe.data
32275
+ });
32276
+ }
32277
+ }
32278
+ if (input && typeof input === "object" && "message" in input) {
32279
+ const typed = input;
32280
+ if (typeof typed.message === "string") {
32281
+ return new TunnelError("UNKNOWN", typed.message);
32282
+ }
32283
+ }
32284
+ return new TunnelError(
32285
+ "UNKNOWN",
32286
+ typeof input === "string" && input || fallbackMessage || "Tunnel error"
32287
+ );
32288
+ }
32289
+ __name(toTunnelError, "toTunnelError");
32290
+ function assertOkEnvelope(envelope, opts) {
32291
+ if (!envelope || typeof envelope !== "object") {
32292
+ throw new TunnelError(
32293
+ "INVALID_RESPONSE",
32294
+ opts?.fallbackMessage || "Invalid or empty response"
32295
+ );
32296
+ }
32297
+ if (envelope.ok) {
32298
+ return envelope.result;
32299
+ }
32300
+ if (envelope.error) {
32301
+ return (() => {
32302
+ throw toTunnelError(envelope.error, opts?.fallbackMessage);
32303
+ })();
32304
+ }
32305
+ throw new TunnelError("UNKNOWN", opts?.fallbackMessage || "Tunnel error");
32306
+ }
32307
+ __name(assertOkEnvelope, "assertOkEnvelope");
33000
32308
 
33001
- // src/tunnels/buildUniversalManifest.ts
32309
+ // src/http-fetch-tunnel.resource.ts
32310
+ async function postSerialized(options) {
32311
+ const {
32312
+ fetch: fetchFn,
32313
+ url,
32314
+ body,
32315
+ headers,
32316
+ timeoutMs,
32317
+ serializer: serializer3,
32318
+ onRequest,
32319
+ contextHeaderText
32320
+ } = options;
32321
+ const controller = timeoutMs && timeoutMs > 0 ? new AbortController() : void 0;
32322
+ let timeout;
32323
+ try {
32324
+ if (controller) {
32325
+ timeout = setTimeout(() => controller.abort(), timeoutMs);
32326
+ }
32327
+ const reqHeaders = {
32328
+ "content-type": "application/json; charset=utf-8",
32329
+ ...headers
32330
+ };
32331
+ if (contextHeaderText) reqHeaders["x-runner-context"] = contextHeaderText;
32332
+ if (onRequest) await onRequest({ url, headers: reqHeaders });
32333
+ const res = await fetchFn(url, {
32334
+ method: "POST",
32335
+ headers: reqHeaders,
32336
+ body: serializer3.stringify(body),
32337
+ signal: controller?.signal
32338
+ });
32339
+ const text = await res.text();
32340
+ const json2 = text ? serializer3.parse(text) : void 0;
32341
+ return json2;
32342
+ } finally {
32343
+ if (timeout) clearTimeout(timeout);
32344
+ }
32345
+ }
32346
+ __name(postSerialized, "postSerialized");
32347
+ function createExposureFetch(cfg) {
32348
+ const baseUrl = cfg?.baseUrl?.replace(/\/$/, "");
32349
+ if (!baseUrl) throw new Error("createExposureFetch requires baseUrl");
32350
+ const headerName = (cfg?.auth?.header ?? "x-runner-token").toLowerCase();
32351
+ const buildHeaders = /* @__PURE__ */ __name(() => {
32352
+ const headers = {};
32353
+ if (cfg?.auth?.token) headers[headerName] = cfg.auth.token;
32354
+ return headers;
32355
+ }, "buildHeaders");
32356
+ const fetchImpl = cfg.fetchImpl ?? globalThis.fetch;
32357
+ if (typeof fetchImpl !== "function") {
32358
+ throw new Error(
32359
+ "global fetch is not available; provide fetchImpl in config"
32360
+ );
32361
+ }
32362
+ const buildContextHeader = /* @__PURE__ */ __name(() => {
32363
+ if (!cfg.contexts || cfg.contexts.length === 0) return void 0;
32364
+ const map = {};
32365
+ for (const ctx of cfg.contexts) {
32366
+ try {
32367
+ const v = ctx.use();
32368
+ map[ctx.id] = ctx.serialize(v);
32369
+ } catch {
32370
+ }
32371
+ }
32372
+ const keys = Object.keys(map);
32373
+ if (keys.length === 0) return void 0;
32374
+ return cfg.serializer.stringify(map);
32375
+ }, "buildContextHeader");
32376
+ return {
32377
+ async task(id2, input) {
32378
+ const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
32379
+ const r2 = await postSerialized({
32380
+ fetch: fetchImpl,
32381
+ url,
32382
+ body: { input },
32383
+ headers: buildHeaders(),
32384
+ timeoutMs: cfg?.timeoutMs,
32385
+ serializer: cfg.serializer,
32386
+ onRequest: cfg?.onRequest,
32387
+ contextHeaderText: buildContextHeader()
32388
+ });
32389
+ try {
32390
+ return assertOkEnvelope(r2, { fallbackMessage: "Tunnel task error" });
32391
+ } catch (e) {
32392
+ const te = e;
32393
+ if (cfg.errorRegistry && te.id && te.data) {
32394
+ const helper = cfg.errorRegistry.get(String(te.id));
32395
+ if (helper) helper.throw(te.data);
32396
+ }
32397
+ throw e;
32398
+ }
32399
+ },
32400
+ async event(id2, payload) {
32401
+ const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
32402
+ const r2 = await postSerialized({
32403
+ fetch: fetchImpl,
32404
+ url,
32405
+ body: { payload },
32406
+ headers: buildHeaders(),
32407
+ timeoutMs: cfg?.timeoutMs,
32408
+ serializer: cfg.serializer,
32409
+ onRequest: cfg?.onRequest,
32410
+ contextHeaderText: buildContextHeader()
32411
+ });
32412
+ try {
32413
+ assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
32414
+ } catch (e) {
32415
+ const te = e;
32416
+ if (cfg.errorRegistry && te.id && te.data) {
32417
+ const helper = cfg.errorRegistry.get(String(te.id));
32418
+ if (helper) helper.throw(te.data);
32419
+ }
32420
+ throw e;
32421
+ }
32422
+ },
32423
+ async eventWithResult(id2, payload) {
32424
+ const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
32425
+ const r2 = await postSerialized({
32426
+ fetch: fetchImpl,
32427
+ url,
32428
+ body: { payload, returnPayload: true },
32429
+ headers: buildHeaders(),
32430
+ timeoutMs: cfg?.timeoutMs,
32431
+ serializer: cfg.serializer,
32432
+ onRequest: cfg?.onRequest,
32433
+ contextHeaderText: buildContextHeader()
32434
+ });
32435
+ if (r2 && typeof r2 === "object" && r2.ok && !("result" in r2)) {
32436
+ throw new TunnelError(
32437
+ "INVALID_RESPONSE",
32438
+ "Tunnel event returnPayload requested but server did not include result. Upgrade the exposure server."
32439
+ );
32440
+ }
32441
+ try {
32442
+ return assertOkEnvelope(r2, {
32443
+ fallbackMessage: "Tunnel event error"
32444
+ });
32445
+ } catch (e) {
32446
+ const te = e;
32447
+ if (cfg.errorRegistry && te.id && te.data) {
32448
+ const helper = cfg.errorRegistry.get(String(te.id));
32449
+ if (helper) helper.throw(te.data);
32450
+ }
32451
+ throw e;
32452
+ }
32453
+ }
32454
+ };
32455
+ }
32456
+ __name(createExposureFetch, "createExposureFetch");
32457
+
32458
+ // src/tools/buildUniversalManifest.ts
33002
32459
  function buildUniversalManifest(input) {
33003
32460
  const nodeFiles = [];
33004
32461
  const webFiles = [];
@@ -33055,6 +32512,15 @@ function toHeaders(auth) {
33055
32512
  return headers;
33056
32513
  }
33057
32514
  __name(toHeaders, "toHeaders");
32515
+ function rethrowWithRegistry(e, errorRegistry) {
32516
+ const te = e;
32517
+ if (errorRegistry && te.id && te.data) {
32518
+ const helper = errorRegistry.get(String(te.id));
32519
+ if (helper) helper.throw(te.data);
32520
+ }
32521
+ throw e;
32522
+ }
32523
+ __name(rethrowWithRegistry, "rethrowWithRegistry");
33058
32524
  function createHttpClient(cfg) {
33059
32525
  const baseUrl = cfg.baseUrl.replace(/\/$/, "");
33060
32526
  if (!baseUrl) throw new Error("createHttpClient requires baseUrl");
@@ -33121,12 +32587,7 @@ function createHttpClient(cfg) {
33121
32587
  fallbackMessage: "Tunnel task error"
33122
32588
  });
33123
32589
  } catch (e) {
33124
- const te = e;
33125
- if (cfg.errorRegistry && te.id && te.data) {
33126
- const helper = cfg.errorRegistry.get(String(te.id));
33127
- if (helper) helper.throw(te.data);
33128
- }
33129
- throw e;
32590
+ rethrowWithRegistry(e, cfg.errorRegistry);
33130
32591
  }
33131
32592
  }
33132
32593
  if (manifest.nodeFiles.length > 0) {
@@ -33137,24 +32598,14 @@ function createHttpClient(cfg) {
33137
32598
  try {
33138
32599
  return await fetchClient.task(id2, input);
33139
32600
  } catch (e) {
33140
- const te = e;
33141
- if (cfg.errorRegistry && te.id && te.data) {
33142
- const helper = cfg.errorRegistry.get(String(te.id));
33143
- if (helper) helper.throw(te.data);
33144
- }
33145
- throw e;
32601
+ rethrowWithRegistry(e, cfg.errorRegistry);
33146
32602
  }
33147
32603
  },
33148
32604
  async event(id2, payload) {
33149
32605
  try {
33150
32606
  return await fetchClient.event(id2, payload);
33151
32607
  } catch (e) {
33152
- const te = e;
33153
- if (cfg.errorRegistry && te.id && te.data) {
33154
- const helper = cfg.errorRegistry.get(String(te.id));
33155
- if (helper) helper.throw(te.data);
33156
- }
33157
- throw e;
32608
+ rethrowWithRegistry(e, cfg.errorRegistry);
33158
32609
  }
33159
32610
  },
33160
32611
  async eventWithResult(id2, payload) {
@@ -33166,12 +32617,7 @@ function createHttpClient(cfg) {
33166
32617
  }
33167
32618
  return await fetchClient.eventWithResult(id2, payload);
33168
32619
  } catch (e) {
33169
- const te = e;
33170
- if (cfg.errorRegistry && te.id && te.data) {
33171
- const helper = cfg.errorRegistry.get(String(te.id));
33172
- if (helper) helper.throw(te.data);
33173
- }
33174
- throw e;
32620
+ rethrowWithRegistry(e, cfg.errorRegistry);
33175
32621
  }
33176
32622
  }
33177
32623
  };
@@ -33454,13 +32900,15 @@ var retryResourceMiddleware = defineResourceMiddleware({
33454
32900
  var journalKeys6 = {
33455
32901
  /** Whether the fallback path was taken (true) or primary succeeded (false) */
33456
32902
  active: journal.createKey(
33457
- "globals.middleware.fallback.active"
32903
+ "globals.middleware.task.fallback.active"
33458
32904
  ),
33459
32905
  /** The error that triggered the fallback (only set when active is true) */
33460
- error: journal.createKey("globals.middleware.fallback.error")
32906
+ error: journal.createKey(
32907
+ "globals.middleware.task.fallback.error"
32908
+ )
33461
32909
  };
33462
32910
  var fallbackTaskMiddleware = defineTaskMiddleware({
33463
- id: "globals.middleware.fallback",
32911
+ id: "globals.middleware.task.fallback",
33464
32912
  dependencies: {
33465
32913
  taskRunner: globalResources.taskRunner
33466
32914
  },
@@ -34103,6 +33551,34 @@ var Logger = class _Logger {
34103
33551
  }
34104
33552
  };
34105
33553
 
33554
+ // src/models/utils/dependencyStrategies.ts
33555
+ var dependencyStrategies = [
33556
+ {
33557
+ matches: isResource,
33558
+ getStoreMap: /* @__PURE__ */ __name((store2) => store2.resources, "getStoreMap")
33559
+ },
33560
+ {
33561
+ matches: isTask,
33562
+ getStoreMap: /* @__PURE__ */ __name((store2) => store2.tasks, "getStoreMap")
33563
+ },
33564
+ {
33565
+ matches: isEvent,
33566
+ getStoreMap: /* @__PURE__ */ __name((store2) => store2.events, "getStoreMap")
33567
+ },
33568
+ {
33569
+ matches: isError,
33570
+ getStoreMap: /* @__PURE__ */ __name((store2) => store2.errors, "getStoreMap")
33571
+ },
33572
+ {
33573
+ matches: isAsyncContext,
33574
+ getStoreMap: /* @__PURE__ */ __name((store2) => store2.asyncContexts, "getStoreMap")
33575
+ }
33576
+ ];
33577
+ function findDependencyStrategy(item) {
33578
+ return dependencyStrategies.find((s) => s.matches(item));
33579
+ }
33580
+ __name(findDependencyStrategy, "findDependencyStrategy");
33581
+
34106
33582
  // src/models/DependencyProcessor.ts
34107
33583
  var DependencyProcessor = class {
34108
33584
  constructor(store2, eventManager, taskRunner, logger) {
@@ -34210,7 +33686,16 @@ var DependencyProcessor = class {
34210
33686
  }
34211
33687
  throw error2;
34212
33688
  }
34213
- throw new Error(`${prefix}: ${String(error2)}`);
33689
+ const wrapper = new Error(`${prefix}: ${String(error2)}`);
33690
+ Object.defineProperty(wrapper, "resourceId", {
33691
+ value: resourceId,
33692
+ configurable: true
33693
+ });
33694
+ Object.defineProperty(wrapper, "cause", {
33695
+ value: error2,
33696
+ configurable: true
33697
+ });
33698
+ throw wrapper;
34214
33699
  }
34215
33700
  /**
34216
33701
  * Computes and caches dependencies for a resource (if not already computed).
@@ -34353,46 +33838,35 @@ var DependencyProcessor = class {
34353
33838
  return object;
34354
33839
  }
34355
33840
  async extractDependency(object, source) {
34356
- this.logger.trace(`Extracting dependency -> ${source} -> ${object?.id}`);
33841
+ this.logger.trace(
33842
+ `Extracting dependency -> ${source} -> ${object?.id}`
33843
+ );
33844
+ let isOpt = false;
33845
+ let item = object;
34357
33846
  if (isOptional(object)) {
34358
- const inner = object.inner;
34359
- if (isResource(inner)) {
34360
- const exists = this.store.resources.get(inner.id) !== void 0;
34361
- return exists ? this.extractResourceDependency(inner) : void 0;
34362
- } else if (isTask(inner)) {
34363
- const exists = this.store.tasks.get(inner.id) !== void 0;
34364
- return exists ? this.extractTaskDependency(inner) : void 0;
34365
- } else if (isEvent(inner)) {
34366
- const exists = this.store.events.get(inner.id) !== void 0;
34367
- return exists ? this.extractEventDependency(inner, source) : void 0;
34368
- } else if (isError(inner)) {
34369
- const exists = this.store.errors.get(inner.id) !== void 0;
34370
- return exists ? inner : void 0;
34371
- } else if (isAsyncContext(inner)) {
34372
- const exists = this.store.asyncContexts.get(inner.id) !== void 0;
34373
- return exists ? inner : void 0;
34374
- }
34375
- unknownItemTypeError.throw({ item: inner });
34376
- }
34377
- if (isResource(object)) {
34378
- return this.extractResourceDependency(object);
34379
- } else if (isTask(object)) {
34380
- return this.extractTaskDependency(object);
34381
- } else if (isEvent(object)) {
34382
- return this.extractEventDependency(object, source);
34383
- } else if (isError(object)) {
34384
- if (this.store.errors.get(object.id) === void 0) {
34385
- dependencyNotFoundError.throw({ key: `Error ${object.id}` });
34386
- }
34387
- return object;
34388
- } else if (isAsyncContext(object)) {
34389
- if (this.store.asyncContexts.get(object.id) === void 0) {
34390
- dependencyNotFoundError.throw({ key: `AsyncContext ${object.id}` });
34391
- }
34392
- return object;
34393
- } else {
34394
- unknownItemTypeError.throw({ item: object });
33847
+ isOpt = true;
33848
+ item = object.inner;
33849
+ }
33850
+ const itemWithId = item;
33851
+ const strategy = findDependencyStrategy(item);
33852
+ if (!strategy) {
33853
+ return unknownItemTypeError.throw({ item });
34395
33854
  }
33855
+ if (isOpt) {
33856
+ const exists = strategy.getStoreMap(this.store).has(itemWithId.id);
33857
+ if (!exists) return void 0;
33858
+ }
33859
+ if (isResource(item)) return this.extractResourceDependency(item);
33860
+ if (isTask(item)) return this.extractTaskDependency(item);
33861
+ if (isEvent(item)) return this.extractEventDependency(item, source);
33862
+ if (!isOpt) {
33863
+ const exists = strategy.getStoreMap(this.store).has(itemWithId.id);
33864
+ if (!exists) {
33865
+ const label = isError(item) ? "Error" : "AsyncContext";
33866
+ dependencyNotFoundError.throw({ key: `${label} ${itemWithId.id}` });
33867
+ }
33868
+ }
33869
+ return item;
34396
33870
  }
34397
33871
  /**
34398
33872
  * Converts the event into a running functions with real inputs
@@ -34589,19 +34063,246 @@ var StoreValidator = class {
34589
34063
  }
34590
34064
  };
34591
34065
 
34066
+ // src/models/utils/buildDependencyGraph.ts
34067
+ function setupBlankNodes(registry, nodeMap, dependents) {
34068
+ for (const task2 of registry.tasks.values()) {
34069
+ const node = {
34070
+ id: task2.task.id,
34071
+ dependencies: {}
34072
+ };
34073
+ nodeMap.set(task2.task.id, node);
34074
+ dependents.push(node);
34075
+ }
34076
+ for (const middleware of registry.taskMiddlewares.values()) {
34077
+ const node = {
34078
+ id: middleware.middleware.id,
34079
+ dependencies: {}
34080
+ };
34081
+ nodeMap.set(middleware.middleware.id, node);
34082
+ dependents.push(node);
34083
+ }
34084
+ for (const middleware of registry.resourceMiddlewares.values()) {
34085
+ const node = {
34086
+ id: middleware.middleware.id,
34087
+ dependencies: {}
34088
+ };
34089
+ nodeMap.set(middleware.middleware.id, node);
34090
+ dependents.push(node);
34091
+ }
34092
+ for (const resource2 of registry.resources.values()) {
34093
+ const node = {
34094
+ id: resource2.resource.id,
34095
+ dependencies: {}
34096
+ };
34097
+ nodeMap.set(resource2.resource.id, node);
34098
+ dependents.push(node);
34099
+ }
34100
+ for (const hook2 of registry.hooks.values()) {
34101
+ const node = {
34102
+ id: hook2.hook.id,
34103
+ dependencies: {}
34104
+ };
34105
+ nodeMap.set(hook2.hook.id, node);
34106
+ dependents.push(node);
34107
+ }
34108
+ }
34109
+ __name(setupBlankNodes, "setupBlankNodes");
34110
+ function buildDependencyGraph(registry) {
34111
+ const depenedants = [];
34112
+ const nodeMap = /* @__PURE__ */ new Map();
34113
+ setupBlankNodes(registry, nodeMap, depenedants);
34114
+ for (const task2 of registry.tasks.values()) {
34115
+ const node = nodeMap.get(task2.task.id);
34116
+ if (task2.task.dependencies) {
34117
+ for (const [depKey, depItem] of Object.entries(task2.task.dependencies)) {
34118
+ const candidate = isOptional(depItem) ? depItem.inner : depItem;
34119
+ const depNode = nodeMap.get(candidate.id);
34120
+ if (depNode) {
34121
+ node.dependencies[depKey] = depNode;
34122
+ }
34123
+ }
34124
+ }
34125
+ const t = task2.task;
34126
+ for (const middleware of t.middleware) {
34127
+ const middlewareNode = nodeMap.get(middleware.id);
34128
+ if (middlewareNode) {
34129
+ node.dependencies[middleware.id] = middlewareNode;
34130
+ }
34131
+ }
34132
+ }
34133
+ for (const storeTaskMiddleware of registry.taskMiddlewares.values()) {
34134
+ const node = nodeMap.get(storeTaskMiddleware.middleware.id);
34135
+ const { middleware } = storeTaskMiddleware;
34136
+ if (middleware.dependencies) {
34137
+ for (const [depKey, depItem] of Object.entries(middleware.dependencies)) {
34138
+ const candidate = isOptional(depItem) ? depItem.inner : depItem;
34139
+ const depNode = nodeMap.get(candidate.id);
34140
+ if (depNode) {
34141
+ node.dependencies[depKey] = depNode;
34142
+ }
34143
+ }
34144
+ }
34145
+ if (middleware.everywhere) {
34146
+ const filter = typeof middleware.everywhere === "function" ? middleware.everywhere : () => true;
34147
+ for (const task2 of registry.tasks.values()) {
34148
+ if (filter(task2.task)) {
34149
+ const taskNode = nodeMap.get(task2.task.id);
34150
+ taskNode.dependencies[`__middleware.${middleware.id}`] = node;
34151
+ }
34152
+ }
34153
+ }
34154
+ }
34155
+ for (const storeResourceMiddleware of registry.resourceMiddlewares.values()) {
34156
+ const node = nodeMap.get(storeResourceMiddleware.middleware.id);
34157
+ const { middleware } = storeResourceMiddleware;
34158
+ if (middleware.dependencies) {
34159
+ for (const [depKey, depItem] of Object.entries(middleware.dependencies)) {
34160
+ const candidate = isOptional(depItem) ? depItem.inner : depItem;
34161
+ const depNode = nodeMap.get(candidate.id);
34162
+ if (depNode) {
34163
+ node.dependencies[depKey] = depNode;
34164
+ }
34165
+ }
34166
+ }
34167
+ if (middleware.everywhere) {
34168
+ const filter = typeof middleware.everywhere === "function" ? middleware.everywhere : () => true;
34169
+ for (const resource2 of registry.resources.values()) {
34170
+ if (filter(resource2.resource)) {
34171
+ const resourceNode = nodeMap.get(resource2.resource.id);
34172
+ resourceNode.dependencies[`__middleware.${middleware.id}`] = node;
34173
+ }
34174
+ }
34175
+ }
34176
+ }
34177
+ for (const resource2 of registry.resources.values()) {
34178
+ const node = nodeMap.get(resource2.resource.id);
34179
+ if (resource2.resource.dependencies) {
34180
+ for (const [depKey, depItem] of Object.entries(
34181
+ resource2.resource.dependencies
34182
+ )) {
34183
+ const candidate = isOptional(depItem) ? depItem.inner : depItem;
34184
+ const depNode = nodeMap.get(candidate.id);
34185
+ if (depNode) {
34186
+ node.dependencies[depKey] = depNode;
34187
+ }
34188
+ }
34189
+ }
34190
+ for (const middleware of resource2.resource.middleware) {
34191
+ const middlewareNode = nodeMap.get(middleware.id);
34192
+ if (middlewareNode) {
34193
+ node.dependencies[middleware.id] = middlewareNode;
34194
+ }
34195
+ }
34196
+ }
34197
+ for (const hook2 of registry.hooks.values()) {
34198
+ const node = nodeMap.get(hook2.hook.id);
34199
+ if (hook2.hook.dependencies) {
34200
+ for (const [depKey, depItem] of Object.entries(hook2.hook.dependencies)) {
34201
+ const candidate = isOptional(depItem) ? depItem.inner : depItem;
34202
+ const depNode = nodeMap.get(candidate.id);
34203
+ if (depNode) {
34204
+ node.dependencies[depKey] = depNode;
34205
+ }
34206
+ }
34207
+ }
34208
+ }
34209
+ return depenedants;
34210
+ }
34211
+ __name(buildDependencyGraph, "buildDependencyGraph");
34212
+ function buildEventEmissionGraph(registry) {
34213
+ const nodes = /* @__PURE__ */ new Map();
34214
+ for (const e of registry.events.values()) {
34215
+ nodes.set(e.event.id, { id: e.event.id, dependencies: {} });
34216
+ }
34217
+ for (const h of registry.hooks.values()) {
34218
+ const listened = [];
34219
+ const on = h.hook.on;
34220
+ if (on === "*") continue;
34221
+ if (Array.isArray(on))
34222
+ listened.push(...on.map((e) => e.id));
34223
+ else listened.push(on.id);
34224
+ const depEvents = [];
34225
+ const deps = h.hook.dependencies;
34226
+ if (deps) {
34227
+ for (const value of Object.values(deps)) {
34228
+ const candidate = isOptional(value) ? value.inner : value;
34229
+ if (candidate && isEvent(candidate)) {
34230
+ depEvents.push(candidate.id);
34231
+ }
34232
+ }
34233
+ }
34234
+ for (const srcId of listened) {
34235
+ const srcNode = nodes.get(srcId);
34236
+ if (!srcNode) continue;
34237
+ for (const dstId of depEvents) {
34238
+ if (srcId === dstId) continue;
34239
+ const dstNode = nodes.get(dstId);
34240
+ if (dstNode) {
34241
+ srcNode.dependencies[dstId] = dstNode;
34242
+ }
34243
+ }
34244
+ }
34245
+ }
34246
+ return Array.from(nodes.values());
34247
+ }
34248
+ __name(buildEventEmissionGraph, "buildEventEmissionGraph");
34249
+
34250
+ // src/tools/LockableMap.ts
34251
+ var LockableMap = class extends Map {
34252
+ static {
34253
+ __name(this, "LockableMap");
34254
+ }
34255
+ #locked = false;
34256
+ #name;
34257
+ constructor(name) {
34258
+ super();
34259
+ this.#name = name ?? "LockableMap";
34260
+ }
34261
+ /** Whether the map is currently locked. */
34262
+ get locked() {
34263
+ return this.#locked;
34264
+ }
34265
+ /** Permanently lock the map — no further mutations allowed. */
34266
+ lock() {
34267
+ this.#locked = true;
34268
+ }
34269
+ /** @throws if the map is locked */
34270
+ throwIfLocked() {
34271
+ if (this.#locked) {
34272
+ throw new Error(`Cannot modify "${this.#name}" \u2014 the map is locked.`);
34273
+ }
34274
+ }
34275
+ set(key, value) {
34276
+ this.throwIfLocked();
34277
+ return super.set(key, value);
34278
+ }
34279
+ delete(key) {
34280
+ this.throwIfLocked();
34281
+ return super.delete(key);
34282
+ }
34283
+ clear() {
34284
+ this.throwIfLocked();
34285
+ super.clear();
34286
+ }
34287
+ };
34288
+
34592
34289
  // src/models/StoreRegistry.ts
34593
34290
  var StoreRegistry = class {
34594
34291
  constructor(store2) {
34595
34292
  this.store = store2;
34596
- this.tasks = /* @__PURE__ */ new Map();
34597
- this.resources = /* @__PURE__ */ new Map();
34598
- this.events = /* @__PURE__ */ new Map();
34599
- this.taskMiddlewares = /* @__PURE__ */ new Map();
34600
- this.resourceMiddlewares = /* @__PURE__ */ new Map();
34601
- this.hooks = /* @__PURE__ */ new Map();
34602
- this.tags = /* @__PURE__ */ new Map();
34603
- this.asyncContexts = /* @__PURE__ */ new Map();
34604
- this.errors = /* @__PURE__ */ new Map();
34293
+ this.tasks = new LockableMap("tasks");
34294
+ this.resources = new LockableMap(
34295
+ "resources"
34296
+ );
34297
+ this.events = new LockableMap("events");
34298
+ this.taskMiddlewares = new LockableMap("taskMiddlewares");
34299
+ this.resourceMiddlewares = new LockableMap("resourceMiddlewares");
34300
+ this.hooks = new LockableMap("hooks");
34301
+ this.tags = new LockableMap("tags");
34302
+ this.asyncContexts = new LockableMap(
34303
+ "asyncContexts"
34304
+ );
34305
+ this.errors = new LockableMap("errors");
34605
34306
  this.validator = new StoreValidator(this);
34606
34307
  }
34607
34308
  static {
@@ -34610,6 +34311,18 @@ var StoreRegistry = class {
34610
34311
  getValidator() {
34611
34312
  return this.validator;
34612
34313
  }
34314
+ /** Lock every map in the registry, preventing further mutations. */
34315
+ lockAll() {
34316
+ this.tasks.lock();
34317
+ this.resources.lock();
34318
+ this.events.lock();
34319
+ this.taskMiddlewares.lock();
34320
+ this.resourceMiddlewares.lock();
34321
+ this.hooks.lock();
34322
+ this.tags.lock();
34323
+ this.asyncContexts.lock();
34324
+ this.errors.lock();
34325
+ }
34613
34326
  storeGenericItem(item) {
34614
34327
  if (isTask(item)) {
34615
34328
  this.storeTask(item);
@@ -34746,195 +34459,14 @@ var StoreRegistry = class {
34746
34459
  }
34747
34460
  // Feels like a dependencyProcessor task?
34748
34461
  getDependentNodes() {
34749
- const depenedants = [];
34750
- const nodeMap = /* @__PURE__ */ new Map();
34751
- this.setupBlankNodes(nodeMap, depenedants);
34752
- for (const task2 of this.tasks.values()) {
34753
- const node = nodeMap.get(task2.task.id);
34754
- if (task2.task.dependencies) {
34755
- for (const [depKey, depItem] of Object.entries(
34756
- task2.task.dependencies
34757
- )) {
34758
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34759
- const depNode = nodeMap.get(candidate.id);
34760
- if (depNode) {
34761
- node.dependencies[depKey] = depNode;
34762
- }
34763
- }
34764
- }
34765
- const t = task2.task;
34766
- for (const middleware of t.middleware) {
34767
- const middlewareNode = nodeMap.get(middleware.id);
34768
- if (middlewareNode) {
34769
- node.dependencies[middleware.id] = middlewareNode;
34770
- }
34771
- }
34772
- }
34773
- for (const storeTaskMiddleware of this.taskMiddlewares.values()) {
34774
- const node = nodeMap.get(storeTaskMiddleware.middleware.id);
34775
- const { middleware } = storeTaskMiddleware;
34776
- if (middleware.dependencies) {
34777
- for (const [depKey, depItem] of Object.entries(
34778
- middleware.dependencies
34779
- )) {
34780
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34781
- const depNode = nodeMap.get(candidate.id);
34782
- if (depNode) {
34783
- node.dependencies[depKey] = depNode;
34784
- }
34785
- }
34786
- }
34787
- if (middleware.everywhere) {
34788
- const filter = typeof middleware.everywhere === "function" ? middleware.everywhere : () => true;
34789
- for (const task2 of this.tasks.values()) {
34790
- if (filter(task2.task)) {
34791
- const taskNode = nodeMap.get(task2.task.id);
34792
- taskNode.dependencies[`__middleware.${middleware.id}`] = node;
34793
- }
34794
- }
34795
- }
34796
- }
34797
- for (const storeResourceMiddleware of this.resourceMiddlewares.values()) {
34798
- const node = nodeMap.get(storeResourceMiddleware.middleware.id);
34799
- const { middleware } = storeResourceMiddleware;
34800
- if (middleware.dependencies) {
34801
- for (const [depKey, depItem] of Object.entries(
34802
- middleware.dependencies
34803
- )) {
34804
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34805
- const depNode = nodeMap.get(candidate.id);
34806
- if (depNode) {
34807
- node.dependencies[depKey] = depNode;
34808
- }
34809
- }
34810
- }
34811
- if (middleware.everywhere) {
34812
- const filter = typeof middleware.everywhere === "function" ? middleware.everywhere : () => true;
34813
- for (const resource2 of this.resources.values()) {
34814
- if (filter(resource2.resource)) {
34815
- const resourceNode = nodeMap.get(resource2.resource.id);
34816
- resourceNode.dependencies[`__middleware.${middleware.id}`] = node;
34817
- }
34818
- }
34819
- }
34820
- }
34821
- for (const resource2 of this.resources.values()) {
34822
- const node = nodeMap.get(resource2.resource.id);
34823
- if (resource2.resource.dependencies) {
34824
- for (const [depKey, depItem] of Object.entries(
34825
- resource2.resource.dependencies
34826
- )) {
34827
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34828
- const depNode = nodeMap.get(candidate.id);
34829
- if (depNode) {
34830
- node.dependencies[depKey] = depNode;
34831
- }
34832
- }
34833
- }
34834
- for (const middleware of resource2.resource.middleware) {
34835
- const middlewareNode = nodeMap.get(middleware.id);
34836
- if (middlewareNode) {
34837
- node.dependencies[middleware.id] = middlewareNode;
34838
- }
34839
- }
34840
- }
34841
- for (const hook2 of this.hooks.values()) {
34842
- const node = nodeMap.get(hook2.hook.id);
34843
- if (hook2.hook.dependencies) {
34844
- for (const [depKey, depItem] of Object.entries(
34845
- hook2.hook.dependencies
34846
- )) {
34847
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34848
- const depNode = nodeMap.get(candidate.id);
34849
- if (depNode) {
34850
- node.dependencies[depKey] = depNode;
34851
- }
34852
- }
34853
- }
34854
- }
34855
- return depenedants;
34462
+ return buildDependencyGraph(this);
34856
34463
  }
34857
34464
  /**
34858
34465
  * Builds a directed graph of event emissions based on hooks listening to events
34859
34466
  * and their dependencies on events (emission capability). Ignores wildcard hooks by default.
34860
34467
  */
34861
34468
  buildEventEmissionGraph() {
34862
- const nodes = /* @__PURE__ */ new Map();
34863
- for (const e of this.events.values()) {
34864
- nodes.set(e.event.id, { id: e.event.id, dependencies: {} });
34865
- }
34866
- for (const h of this.hooks.values()) {
34867
- const listened = [];
34868
- const on = h.hook.on;
34869
- if (on === "*") continue;
34870
- if (Array.isArray(on))
34871
- listened.push(...on.map((e) => e.id));
34872
- else listened.push(on.id);
34873
- const depEvents = [];
34874
- const deps = h.hook.dependencies;
34875
- if (deps) {
34876
- for (const value of Object.values(deps)) {
34877
- const candidate = isOptional(value) ? value.inner : value;
34878
- if (candidate && isEvent(candidate)) {
34879
- depEvents.push(candidate.id);
34880
- }
34881
- }
34882
- }
34883
- for (const srcId of listened) {
34884
- const srcNode = nodes.get(srcId);
34885
- if (!srcNode) continue;
34886
- for (const dstId of depEvents) {
34887
- if (srcId === dstId) continue;
34888
- const dstNode = nodes.get(dstId);
34889
- if (dstNode) {
34890
- srcNode.dependencies[dstId] = dstNode;
34891
- }
34892
- }
34893
- }
34894
- }
34895
- return Array.from(nodes.values());
34896
- }
34897
- setupBlankNodes(nodeMap, depenedants) {
34898
- for (const task2 of this.tasks.values()) {
34899
- const node = {
34900
- id: task2.task.id,
34901
- dependencies: {}
34902
- };
34903
- nodeMap.set(task2.task.id, node);
34904
- depenedants.push(node);
34905
- }
34906
- for (const middleware of this.taskMiddlewares.values()) {
34907
- const node = {
34908
- id: middleware.middleware.id,
34909
- dependencies: {}
34910
- };
34911
- nodeMap.set(middleware.middleware.id, node);
34912
- depenedants.push(node);
34913
- }
34914
- for (const middleware of this.resourceMiddlewares.values()) {
34915
- const node = {
34916
- id: middleware.middleware.id,
34917
- dependencies: {}
34918
- };
34919
- nodeMap.set(middleware.middleware.id, node);
34920
- depenedants.push(node);
34921
- }
34922
- for (const resource2 of this.resources.values()) {
34923
- const node = {
34924
- id: resource2.resource.id,
34925
- dependencies: {}
34926
- };
34927
- nodeMap.set(resource2.resource.id, node);
34928
- depenedants.push(node);
34929
- }
34930
- for (const hook2 of this.hooks.values()) {
34931
- const node = {
34932
- id: hook2.hook.id,
34933
- dependencies: {}
34934
- };
34935
- nodeMap.set(hook2.hook.id, node);
34936
- depenedants.push(node);
34937
- }
34469
+ return buildEventEmissionGraph(this);
34938
34470
  }
34939
34471
  getTasksWithTag(tag2) {
34940
34472
  const tagId = typeof tag2 === "string" ? tag2 : tag2.id;
@@ -35868,6 +35400,63 @@ function detectRunnerMode(explicitMode) {
35868
35400
  }
35869
35401
  __name(detectRunnerMode, "detectRunnerMode");
35870
35402
 
35403
+ // src/models/utils/disposeOrder.ts
35404
+ function getResourcesInDisposeOrder(resources, initializedResourceIds) {
35405
+ const initializedResources = Array.from(resources.values()).filter(
35406
+ (r2) => r2.isInitialized
35407
+ );
35408
+ const initOrderHasAllInitialized = initializedResourceIds.length === initializedResources.length && initializedResources.every(
35409
+ (r2) => initializedResourceIds.includes(r2.resource.id)
35410
+ );
35411
+ if (initOrderHasAllInitialized) {
35412
+ const byId = new Map(
35413
+ initializedResources.map((r2) => [r2.resource.id, r2])
35414
+ );
35415
+ return initializedResourceIds.slice().reverse().map((id2) => byId.get(id2)).filter((r2) => Boolean(r2));
35416
+ }
35417
+ const visitState = /* @__PURE__ */ new Map();
35418
+ const initOrder = [];
35419
+ let cycleDetected = false;
35420
+ const getDependencyIds = /* @__PURE__ */ __name((resource2) => {
35421
+ const raw = resource2.resource.dependencies;
35422
+ if (!raw) return [];
35423
+ const deps = raw;
35424
+ if (!deps || typeof deps !== "object") return [];
35425
+ const out = [];
35426
+ const collect = /* @__PURE__ */ __name((value) => {
35427
+ if (isOptional(value)) {
35428
+ collect(value.inner);
35429
+ return;
35430
+ }
35431
+ if (isResource(value)) {
35432
+ out.push(value.id);
35433
+ }
35434
+ }, "collect");
35435
+ Object.values(deps).forEach(collect);
35436
+ return out;
35437
+ }, "getDependencyIds");
35438
+ const visit = /* @__PURE__ */ __name((resourceId) => {
35439
+ const state = visitState.get(resourceId);
35440
+ if (state === "visited") return;
35441
+ if (state === "visiting") {
35442
+ cycleDetected = true;
35443
+ return;
35444
+ }
35445
+ const resource2 = resources.get(resourceId);
35446
+ if (!resource2) return;
35447
+ visitState.set(resourceId, "visiting");
35448
+ getDependencyIds(resource2).forEach(visit);
35449
+ visitState.set(resourceId, "visited");
35450
+ initOrder.push(resource2);
35451
+ }, "visit");
35452
+ initializedResources.forEach((r2) => visit(r2.resource.id));
35453
+ if (cycleDetected) {
35454
+ return initializedResources.slice().reverse();
35455
+ }
35456
+ return initOrder.reverse();
35457
+ }
35458
+ __name(getResourcesInDisposeOrder, "getResourcesInDisposeOrder");
35459
+
35871
35460
  // src/models/Store.ts
35872
35461
  var Store = class {
35873
35462
  constructor(eventManager, logger, onUnhandledError, mode) {
@@ -35932,6 +35521,7 @@ var Store = class {
35932
35521
  }
35933
35522
  lock() {
35934
35523
  this.#isLocked = true;
35524
+ this.registry.lockAll();
35935
35525
  }
35936
35526
  checkLock() {
35937
35527
  if (this.#isLocked) {
@@ -36073,58 +35663,7 @@ var Store = class {
36073
35663
  this.initializedResourceIds.push(resourceId);
36074
35664
  }
36075
35665
  getResourcesInDisposeOrder() {
36076
- const initializedResources = Array.from(this.resources.values()).filter(
36077
- (r2) => r2.isInitialized
36078
- );
36079
- const initOrderHasAllInitialized = this.initializedResourceIds.length === initializedResources.length && initializedResources.every(
36080
- (r2) => this.initializedResourceIds.includes(r2.resource.id)
36081
- );
36082
- if (initOrderHasAllInitialized) {
36083
- const byId = new Map(
36084
- initializedResources.map((r2) => [r2.resource.id, r2])
36085
- );
36086
- return this.initializedResourceIds.slice().reverse().map((id2) => byId.get(id2)).filter((r2) => Boolean(r2));
36087
- }
36088
- const visitState = /* @__PURE__ */ new Map();
36089
- const initOrder = [];
36090
- let cycleDetected = false;
36091
- const getDependencyIds = /* @__PURE__ */ __name((resource2) => {
36092
- const raw = resource2.resource.dependencies;
36093
- if (!raw) return [];
36094
- const deps = raw;
36095
- if (!deps || typeof deps !== "object") return [];
36096
- const out = [];
36097
- const collect = /* @__PURE__ */ __name((value) => {
36098
- if (isOptional(value)) {
36099
- collect(value.inner);
36100
- return;
36101
- }
36102
- if (isResource(value)) {
36103
- out.push(value.id);
36104
- }
36105
- }, "collect");
36106
- Object.values(deps).forEach(collect);
36107
- return out;
36108
- }, "getDependencyIds");
36109
- const visit = /* @__PURE__ */ __name((resourceId) => {
36110
- const state = visitState.get(resourceId);
36111
- if (state === "visited") return;
36112
- if (state === "visiting") {
36113
- cycleDetected = true;
36114
- return;
36115
- }
36116
- const resource2 = this.resources.get(resourceId);
36117
- if (!resource2) return;
36118
- visitState.set(resourceId, "visiting");
36119
- getDependencyIds(resource2).forEach(visit);
36120
- visitState.set(resourceId, "visited");
36121
- initOrder.push(resource2);
36122
- }, "visit");
36123
- initializedResources.forEach((r2) => visit(r2.resource.id));
36124
- if (cycleDetected) {
36125
- return initializedResources.slice().reverse();
36126
- }
36127
- return initOrder.reverse();
35666
+ return getResourcesInDisposeOrder(this.resources, this.initializedResourceIds);
36128
35667
  }
36129
35668
  /**
36130
35669
  * Internal, avoid using this method directly.
@@ -36140,21 +35679,11 @@ var Store = class {
36140
35679
  storeGenericItem(item) {
36141
35680
  return this.registry.storeGenericItem(item);
36142
35681
  }
36143
- /**
36144
- * Returns all tasks with the given tag.
36145
- * @param tag - The tag to filter by.
36146
- * @returns The tasks with the given tag.
36147
- */
36148
35682
  getTasksWithTag(tag2) {
36149
- return this.registry.getTasksWithTag(tag2);
35683
+ return typeof tag2 === "string" ? this.registry.getTasksWithTag(tag2) : this.registry.getTasksWithTag(tag2);
36150
35684
  }
36151
- /**
36152
- * Returns all resources with the given tag.
36153
- * @param tag - The tag to filter by.
36154
- * @returns The resources with the given tag.
36155
- */
36156
35685
  getResourcesWithTag(tag2) {
36157
- return this.registry.getResourcesWithTag(tag2);
35686
+ return typeof tag2 === "string" ? this.registry.getResourcesWithTag(tag2) : this.registry.getResourcesWithTag(tag2);
36158
35687
  }
36159
35688
  };
36160
35689
 
@@ -36417,7 +35946,7 @@ var debugResource = defineResource({
36417
35946
  tags: [globalTags.system]
36418
35947
  });
36419
35948
 
36420
- // src/processHooks.ts
35949
+ // src/tools/processShutdownHooks.ts
36421
35950
  var platform2 = getPlatform();
36422
35951
  var activeErrorHandlers = /* @__PURE__ */ new Set();
36423
35952
  var processSafetyNetsInstalled = false;
@@ -36506,13 +36035,6 @@ function bindProcessErrorHandler(handler) {
36506
36035
  };
36507
36036
  }
36508
36037
  __name(bindProcessErrorHandler, "bindProcessErrorHandler");
36509
- async function safeReportUnhandledError(handler, info) {
36510
- try {
36511
- await handler(info);
36512
- } catch {
36513
- }
36514
- }
36515
- __name(safeReportUnhandledError, "safeReportUnhandledError");
36516
36038
 
36517
36039
  // src/models/RunResult.ts
36518
36040
  var RunResult = class {
@@ -36711,7 +36233,6 @@ function extractResourceAndConfig(resourceOrResourceWithConfig) {
36711
36233
  __name(extractResourceAndConfig, "extractResourceAndConfig");
36712
36234
 
36713
36235
  // src/globals/tunnels/index.ts
36714
- init_http_fetch_tunnel_resource();
36715
36236
  var http = Object.freeze({
36716
36237
  createClient(cfg) {
36717
36238
  const { url, ...rest } = cfg;
@@ -36722,39 +36243,15 @@ var tunnels = Object.freeze({
36722
36243
  http
36723
36244
  });
36724
36245
 
36725
- // src/testing.ts
36726
- var testResourceCounter = 0;
36727
- function createTestResource(root, options) {
36728
- return defineResource({
36729
- id: `testing.${root.id}.${++testResourceCounter}`,
36730
- register: [root],
36731
- overrides: options?.overrides || [],
36732
- dependencies: {
36733
- taskRunner: globalResources.taskRunner,
36734
- store: globalResources.store,
36735
- logger: globalResources.logger,
36736
- eventManager: globalResources.eventManager
36737
- },
36738
- async init(_, deps) {
36739
- return buildTestFacade(deps);
36740
- }
36741
- });
36742
- }
36743
- __name(createTestResource, "createTestResource");
36744
- function buildTestFacade(deps) {
36745
- return {
36746
- // Run a task within the fully initialized ecosystem
36747
- runTask: /* @__PURE__ */ __name((task2, ...args) => deps.taskRunner.run(task2, ...args), "runTask"),
36748
- // Access a resource value by id (string or symbol)
36749
- getResource: /* @__PURE__ */ __name((id2) => deps.store.resources.get(id2)?.value, "getResource"),
36750
- // Expose internals when needed in tests (not recommended for app usage)
36751
- taskRunner: deps.taskRunner,
36752
- store: deps.store,
36753
- logger: deps.logger,
36754
- eventManager: deps.eventManager
36755
- };
36246
+ // src/definers/builders/shared/mergeUtils.ts
36247
+ function mergeArray(existing, addition, override2) {
36248
+ const toArray = [...addition];
36249
+ if (override2 || !existing) {
36250
+ return toArray;
36251
+ }
36252
+ return [...existing, ...toArray];
36756
36253
  }
36757
- __name(buildTestFacade, "buildTestFacade");
36254
+ __name(mergeArray, "mergeArray");
36758
36255
 
36759
36256
  // src/definers/builders/resource/utils.ts
36760
36257
  function clone2(s, patch) {
@@ -36800,14 +36297,6 @@ function mergeRegister(existing, addition, override2) {
36800
36297
  ];
36801
36298
  }
36802
36299
  __name(mergeRegister, "mergeRegister");
36803
- function mergeArray(existing, addition, override2) {
36804
- const toArray = [...addition];
36805
- if (override2 || !existing) {
36806
- return toArray;
36807
- }
36808
- return [...existing, ...toArray];
36809
- }
36810
- __name(mergeArray, "mergeArray");
36811
36300
  function mergeDependencies(existing, addition, override2) {
36812
36301
  const isFnExisting = typeof existing === "function";
36813
36302
  const isFnAddition = typeof addition === "function";
@@ -36971,14 +36460,6 @@ function clone3(s, patch) {
36971
36460
  });
36972
36461
  }
36973
36462
  __name(clone3, "clone");
36974
- function mergeArray2(existing, addition, override2) {
36975
- const toArray = [...addition];
36976
- if (override2 || !existing) {
36977
- return toArray;
36978
- }
36979
- return [...existing, ...toArray];
36980
- }
36981
- __name(mergeArray2, "mergeArray");
36982
36463
  function mergeDependencies2(existing, addition, override2) {
36983
36464
  const isFnExisting = typeof existing === "function";
36984
36465
  const isFnAddition = typeof addition === "function";
@@ -37034,14 +36515,14 @@ function makeTaskBuilder(state) {
37034
36515
  middleware(mw, options) {
37035
36516
  const override2 = options?.override ?? false;
37036
36517
  const next = clone3(state, {
37037
- middleware: mergeArray2(state.middleware, mw, override2)
36518
+ middleware: mergeArray(state.middleware, mw, override2)
37038
36519
  });
37039
36520
  return makeTaskBuilder(next);
37040
36521
  },
37041
36522
  tags(t, options) {
37042
36523
  const override2 = options?.override ?? false;
37043
36524
  const next = clone3(state, {
37044
- tags: mergeArray2(state.tags, t, override2)
36525
+ tags: mergeArray(state.tags, t, override2)
37045
36526
  });
37046
36527
  return makeTaskBuilder(next);
37047
36528
  },
@@ -37117,14 +36598,14 @@ function makePhantomTaskBuilder(state) {
37117
36598
  middleware(mw, options) {
37118
36599
  const override2 = options?.override ?? false;
37119
36600
  const next = clone3(state, {
37120
- middleware: mergeArray2(state.middleware, mw, override2)
36601
+ middleware: mergeArray(state.middleware, mw, override2)
37121
36602
  });
37122
36603
  return makePhantomTaskBuilder(next);
37123
36604
  },
37124
36605
  tags(t, options) {
37125
36606
  const override2 = options?.override ?? false;
37126
36607
  const next = clone3(state, {
37127
- tags: mergeArray2(state.tags, t, override2)
36608
+ tags: mergeArray(state.tags, t, override2)
37128
36609
  });
37129
36610
  return makePhantomTaskBuilder(
37130
36611
  next
@@ -37213,14 +36694,6 @@ function clone4(s, patch) {
37213
36694
  });
37214
36695
  }
37215
36696
  __name(clone4, "clone");
37216
- function mergeArray3(existing, addition, override2) {
37217
- const toArray = [...addition];
37218
- if (override2 || !existing) {
37219
- return toArray;
37220
- }
37221
- return [...existing, ...toArray];
37222
- }
37223
- __name(mergeArray3, "mergeArray");
37224
36697
 
37225
36698
  // src/definers/builders/event/fluent-builder.ts
37226
36699
  function makeEventBuilder(state) {
@@ -37235,7 +36708,7 @@ function makeEventBuilder(state) {
37235
36708
  tags(t, options) {
37236
36709
  const override2 = options?.override ?? false;
37237
36710
  const next = clone4(state, {
37238
- tags: mergeArray3(state.tags, t, override2)
36711
+ tags: mergeArray(state.tags, t, override2)
37239
36712
  });
37240
36713
  return makeEventBuilder(next);
37241
36714
  },
@@ -37283,14 +36756,6 @@ function clone5(s, patch) {
37283
36756
  });
37284
36757
  }
37285
36758
  __name(clone5, "clone");
37286
- function mergeArray4(existing, addition, override2) {
37287
- const toArray = [...addition];
37288
- if (override2 || !existing) {
37289
- return toArray;
37290
- }
37291
- return [...existing, ...toArray];
37292
- }
37293
- __name(mergeArray4, "mergeArray");
37294
36759
  function mergeDependencies3(existing, addition, override2) {
37295
36760
  const isFnExisting = typeof existing === "function";
37296
36761
  const isFnAddition = typeof addition === "function";
@@ -37364,7 +36829,7 @@ function makeHookBuilder(state) {
37364
36829
  tags(t, options) {
37365
36830
  const override2 = options?.override ?? false;
37366
36831
  const next = clone5(state, {
37367
- tags: mergeArray4(state.tags, t, override2)
36832
+ tags: mergeArray(state.tags, t, override2)
37368
36833
  });
37369
36834
  return makeHookBuilder(next);
37370
36835
  },
@@ -37441,14 +36906,6 @@ function cloneRes(s, patch) {
37441
36906
  });
37442
36907
  }
37443
36908
  __name(cloneRes, "cloneRes");
37444
- function mergeArray5(existing, addition, override2) {
37445
- const toArray = [...addition];
37446
- if (override2 || !existing) {
37447
- return toArray;
37448
- }
37449
- return [...existing, ...toArray];
37450
- }
37451
- __name(mergeArray5, "mergeArray");
37452
36909
  function mergeDependencies4(existing, addition, override2) {
37453
36910
  const isFnExisting = typeof existing === "function";
37454
36911
  const isFnAddition = typeof addition === "function";
@@ -37529,7 +36986,7 @@ function makeTaskMiddlewareBuilder(state) {
37529
36986
  tags(t, options) {
37530
36987
  const override2 = options?.override ?? false;
37531
36988
  const next = cloneTask(state, {
37532
- tags: mergeArray5(state.tags, t, override2)
36989
+ tags: mergeArray(state.tags, t, override2)
37533
36990
  });
37534
36991
  return makeTaskMiddlewareBuilder(next);
37535
36992
  },
@@ -37601,7 +37058,7 @@ function makeResourceMiddlewareBuilder(state) {
37601
37058
  tags(t, options) {
37602
37059
  const override2 = options?.override ?? false;
37603
37060
  const next = cloneRes(state, {
37604
- tags: mergeArray5(state.tags, t, override2)
37061
+ tags: mergeArray(state.tags, t, override2)
37605
37062
  });
37606
37063
  return makeResourceMiddlewareBuilder(next);
37607
37064
  },
@@ -37812,7 +37269,7 @@ function makeHookOverrideBuilder(base, state) {
37812
37269
  tags(t, options) {
37813
37270
  const override2 = options?.override ?? false;
37814
37271
  const next = cloneHookState(state, {
37815
- tags: mergeArray4(state.tags, t, override2)
37272
+ tags: mergeArray(state.tags, t, override2)
37816
37273
  });
37817
37274
  return makeHookOverrideBuilder(base, next);
37818
37275
  },
@@ -38017,7 +37474,7 @@ function makeResourceMiddlewareOverrideBuilder(base, state) {
38017
37474
  tags(t, options) {
38018
37475
  const override2 = options?.override ?? false;
38019
37476
  const next = cloneResourceMiddlewareState(state, {
38020
- tags: mergeArray5(state.tags, t, override2)
37477
+ tags: mergeArray(state.tags, t, override2)
38021
37478
  });
38022
37479
  return makeResourceMiddlewareOverrideBuilder(base, next);
38023
37480
  },
@@ -38077,14 +37534,14 @@ function makeTaskOverrideBuilder(base, state) {
38077
37534
  middleware(mw, options) {
38078
37535
  const override2 = options?.override ?? false;
38079
37536
  const next = cloneTaskState(state, {
38080
- middleware: mergeArray2(state.middleware, mw, override2)
37537
+ middleware: mergeArray(state.middleware, mw, override2)
38081
37538
  });
38082
37539
  return makeTaskOverrideBuilder(base, next);
38083
37540
  },
38084
37541
  tags(t, options) {
38085
37542
  const override2 = options?.override ?? false;
38086
37543
  const next = cloneTaskState(state, {
38087
- tags: mergeArray2(state.tags, t, override2)
37544
+ tags: mergeArray(state.tags, t, override2)
38088
37545
  });
38089
37546
  return makeTaskOverrideBuilder(base, next);
38090
37547
  },
@@ -38193,7 +37650,7 @@ function makeTaskMiddlewareOverrideBuilder(base, state) {
38193
37650
  tags(t, options) {
38194
37651
  const override2 = options?.override ?? false;
38195
37652
  const next = cloneTaskMiddlewareState(state, {
38196
- tags: mergeArray5(state.tags, t, override2)
37653
+ tags: mergeArray(state.tags, t, override2)
38197
37654
  });
38198
37655
  return makeTaskMiddlewareOverrideBuilder(base, next);
38199
37656
  },
@@ -38245,7 +37702,6 @@ function override(base) {
38245
37702
  __name(override, "override");
38246
37703
 
38247
37704
  // src/public.ts
38248
- init_http_fetch_tunnel_resource();
38249
37705
  var globals = {
38250
37706
  events: globalEvents,
38251
37707
  resources: globalResources,
@@ -38254,7 +37710,6 @@ var globals = {
38254
37710
  tunnels,
38255
37711
  debug
38256
37712
  };
38257
- var createContext2 = createContext;
38258
37713
  var r = Object.freeze({
38259
37714
  resource,
38260
37715
  task,
@@ -39391,6 +38846,7 @@ var UNSAFE_ERROR_FIELDS = /* @__PURE__ */ new Set([
39391
38846
  var isRecord2 = /* @__PURE__ */ __name((value) => !!value && typeof value === "object", "isRecord");
39392
38847
  var isJsonBody = /* @__PURE__ */ __name((value) => isRecord2(value) && typeof value.ok === "boolean", "isJsonBody");
39393
38848
  var toErrorRecord = /* @__PURE__ */ __name((value) => isRecord2(value) ? value : void 0, "toErrorRecord");
38849
+ var isValidHttpCode3 = /* @__PURE__ */ __name((value) => typeof value === "number" && Number.isInteger(value) && value >= 100 && value <= 599, "isValidHttpCode");
39394
38850
  var sanitizeErrorResponse = /* @__PURE__ */ __name((response) => {
39395
38851
  const asRecord = isRecord2(response) ? response : void 0;
39396
38852
  const statusRaw = asRecord?.status ?? asRecord?.statusCode;
@@ -39432,6 +38888,9 @@ var sanitizeErrorResponse = /* @__PURE__ */ __name((response) => {
39432
38888
  if (bodyError.data !== void 0) {
39433
38889
  safeError.data = bodyError.data;
39434
38890
  }
38891
+ if (isValidHttpCode3(bodyError.httpCode)) {
38892
+ safeError.httpCode = bodyError.httpCode;
38893
+ }
39435
38894
  return {
39436
38895
  ok: false,
39437
38896
  error: safeError
@@ -39453,11 +38912,19 @@ var resolveAppErrorExtra = /* @__PURE__ */ __name((store2, error2) => {
39453
38912
  try {
39454
38913
  for (const helper of store2.errors.values()) {
39455
38914
  if (helper.is(error2)) {
39456
- if (!isRecord2(error2)) return { id: void 0, data: void 0 };
38915
+ if (!isRecord2(error2)) {
38916
+ return {
38917
+ id: void 0,
38918
+ data: void 0,
38919
+ httpCode: isValidHttpCode3(helper.httpCode) ? helper.httpCode : void 0
38920
+ };
38921
+ }
39457
38922
  const name = error2["name" /* Name */];
39458
38923
  const id2 = typeof name === "string" ? name : void 0;
39459
38924
  const data = error2["data" /* Data */];
39460
- return { id: id2, data };
38925
+ const runtimeHttpCode = error2["httpCode" /* HttpCode */];
38926
+ const httpCode = isValidHttpCode3(runtimeHttpCode) ? runtimeHttpCode : isValidHttpCode3(helper.httpCode) ? helper.httpCode : void 0;
38927
+ return { id: id2, data, httpCode };
39461
38928
  }
39462
38929
  }
39463
38930
  } catch {
@@ -39467,6 +38934,7 @@ var resolveAppErrorExtra = /* @__PURE__ */ __name((store2, error2) => {
39467
38934
  var handleRequestError = /* @__PURE__ */ __name((options) => {
39468
38935
  const { error: error2, req, res, store: store2, logger, cors, serializer: serializer3, logKey } = options;
39469
38936
  const appErrorExtra = resolveAppErrorExtra(store2, error2);
38937
+ const responseStatus = appErrorExtra?.httpCode ?? 500;
39470
38938
  const displayMessage = appErrorExtra && error2 instanceof Error && error2.message ? error2.message : "Internal Error" /* InternalError */;
39471
38939
  safeLogError(logger, logKey, { error: errorMessage(error2) });
39472
38940
  applyCorsActual(req, res, cors);
@@ -39474,7 +38942,7 @@ var handleRequestError = /* @__PURE__ */ __name((options) => {
39474
38942
  res,
39475
38943
  sanitizeErrorResponse(
39476
38944
  jsonErrorResponse(
39477
- 500,
38945
+ responseStatus,
39478
38946
  displayMessage,
39479
38947
  "INTERNAL_ERROR" /* InternalError */,
39480
38948
  appErrorExtra
@@ -39486,7 +38954,7 @@ var handleRequestError = /* @__PURE__ */ __name((options) => {
39486
38954
 
39487
38955
  // src/node/exposure/requestContext.ts
39488
38956
  var ExposureRequestContext = defineAsyncContext({
39489
- id: "platform.node.exposure.request"
38957
+ id: "platform.node.ctx.exposureRequest"
39490
38958
  });
39491
38959
  function useExposureContext() {
39492
38960
  return ExposureRequestContext.use();
@@ -39527,7 +38995,7 @@ var withExposureContext = /* @__PURE__ */ __name((req, res, controller, deps, fn
39527
38995
  } catch {
39528
38996
  }
39529
38997
  }
39530
- const run3 = /* @__PURE__ */ __name(() => ExposureRequestContext.provide(
38998
+ const run2 = /* @__PURE__ */ __name(() => ExposureRequestContext.provide(
39531
38999
  {
39532
39000
  req,
39533
39001
  res,
@@ -39539,7 +39007,7 @@ var withExposureContext = /* @__PURE__ */ __name((req, res, controller, deps, fn
39539
39007
  },
39540
39008
  userWrapped
39541
39009
  ), "run");
39542
- return Promise.resolve(run3());
39010
+ return Promise.resolve(run2());
39543
39011
  }, "withExposureContext");
39544
39012
  var withUserContexts = /* @__PURE__ */ __name((req, deps, fn) => {
39545
39013
  const { store: store2, serializer: serializer3 } = deps;
@@ -39735,7 +39203,7 @@ var createTaskHandler = /* @__PURE__ */ __name((deps) => {
39735
39203
  applyCorsActual(req, res, cors);
39736
39204
  respondJson(res, jsonOkResponse({ result }), serializer3);
39737
39205
  } catch (error2) {
39738
- if (isCancellationError(error2)) {
39206
+ if (cancellationError.is(error2)) {
39739
39207
  if (!res.writableEnded && !res.headersSent) {
39740
39208
  applyCorsActual(req, res, cors);
39741
39209
  respondJson(
@@ -39844,7 +39312,7 @@ var createEventHandler = /* @__PURE__ */ __name((deps) => {
39844
39312
  serializer3
39845
39313
  );
39846
39314
  } catch (error2) {
39847
- if (isCancellationError(error2)) {
39315
+ if (cancellationError.is(error2)) {
39848
39316
  if (!res.writableEnded && !res.headersSent) {
39849
39317
  applyCorsActual(req, res, cors);
39850
39318
  respondJson(
@@ -39947,190 +39415,650 @@ function createRequestHandlers(deps) {
39947
39415
  events: Array.from(list.eventIds)
39948
39416
  }
39949
39417
  }
39950
- }),
39951
- serializer3
39952
- );
39953
- }, "handleDiscovery");
39954
- const handleRequest = /* @__PURE__ */ __name(async (req, res) => {
39955
- const url = requestUrl(req);
39956
- const target = router.extract(url.pathname);
39957
- if (!target) {
39958
- if (!router.isUnderBase(url.pathname)) {
39959
- return false;
39960
- }
39961
- if (handleCorsPreflight(req, res, cors)) return true;
39962
- applyCorsActual(req, res, cors);
39963
- respondJson(res, NOT_FOUND_RESPONSE, serializer3);
39964
- return true;
39965
- }
39966
- if (target.kind === "task") {
39967
- if (handleCorsPreflight(req, res, cors)) return true;
39968
- await processTaskRequest(req, res, target.id);
39969
- } else if (target.kind === "event") {
39970
- if (handleCorsPreflight(req, res, cors)) return true;
39971
- await processEventRequest(req, res, target.id);
39972
- } else if (target.kind === "discovery") {
39973
- if (handleCorsPreflight(req, res, cors)) return true;
39974
- await handleDiscovery(req, res);
39418
+ }),
39419
+ serializer3
39420
+ );
39421
+ }, "handleDiscovery");
39422
+ const handleRequest = /* @__PURE__ */ __name(async (req, res) => {
39423
+ const url = requestUrl(req);
39424
+ const target = router.extract(url.pathname);
39425
+ if (!target) {
39426
+ if (!router.isUnderBase(url.pathname)) {
39427
+ return false;
39428
+ }
39429
+ if (handleCorsPreflight(req, res, cors)) return true;
39430
+ applyCorsActual(req, res, cors);
39431
+ respondJson(res, NOT_FOUND_RESPONSE, serializer3);
39432
+ return true;
39433
+ }
39434
+ if (target.kind === "task") {
39435
+ if (handleCorsPreflight(req, res, cors)) return true;
39436
+ await processTaskRequest(req, res, target.id);
39437
+ } else if (target.kind === "event") {
39438
+ if (handleCorsPreflight(req, res, cors)) return true;
39439
+ await processEventRequest(req, res, target.id);
39440
+ } else if (target.kind === "discovery") {
39441
+ if (handleCorsPreflight(req, res, cors)) return true;
39442
+ await handleDiscovery(req, res);
39443
+ }
39444
+ return true;
39445
+ }, "handleRequest");
39446
+ return { handleTask, handleEvent, handleDiscovery, handleRequest };
39447
+ }
39448
+ __name(createRequestHandlers, "createRequestHandlers");
39449
+
39450
+ // src/node/exposure/createNodeExposure.ts
39451
+ async function createNodeExposure(cfg, deps) {
39452
+ const { store: store2, taskRunner, eventManager, logger, serializer: serializer3 } = deps;
39453
+ const httpConfig = cfg?.http;
39454
+ const basePath = resolveBasePath(httpConfig?.basePath);
39455
+ const router = createRouter(basePath);
39456
+ const allowList = createAllowListGuard(
39457
+ store2,
39458
+ !!httpConfig?.dangerouslyAllowOpenExposure
39459
+ );
39460
+ const validatorTasks = store2.getTasksWithTag(
39461
+ globalTags.authValidator
39462
+ );
39463
+ const authenticator = createAuthenticator(
39464
+ httpConfig?.auth,
39465
+ taskRunner,
39466
+ validatorTasks
39467
+ );
39468
+ const { handleTask, handleEvent, handleDiscovery, handleRequest } = createRequestHandlers({
39469
+ store: store2,
39470
+ taskRunner,
39471
+ eventManager,
39472
+ logger,
39473
+ authenticator,
39474
+ allowList,
39475
+ router,
39476
+ cors: httpConfig?.cors,
39477
+ serializer: serializer3,
39478
+ limits: httpConfig?.limits
39479
+ });
39480
+ const serverControls = await createExposureServer({
39481
+ httpConfig,
39482
+ handler: handleRequest,
39483
+ logger,
39484
+ basePath
39485
+ });
39486
+ return {
39487
+ handleRequest,
39488
+ handleTask,
39489
+ handleEvent,
39490
+ handleDiscovery,
39491
+ createRequestListener: serverControls.createRequestListener,
39492
+ createServer: serverControls.createServer,
39493
+ attachTo: serverControls.attachTo,
39494
+ server: serverControls.server,
39495
+ basePath,
39496
+ close: serverControls.close
39497
+ };
39498
+ }
39499
+ __name(createNodeExposure, "createNodeExposure");
39500
+
39501
+ // src/node/exposure/resource.ts
39502
+ var nodeExposure = defineResource({
39503
+ id: "platform.node.resources.exposure",
39504
+ meta: {
39505
+ title: "Node Exposure (HTTP)",
39506
+ description: "Exposes Runner tasks and events over HTTP so a tunnel client can invoke them."
39507
+ },
39508
+ dependencies: {
39509
+ store: globalResources.store,
39510
+ taskRunner: globalResources.taskRunner,
39511
+ eventManager: globalResources.eventManager,
39512
+ logger: globalResources.logger,
39513
+ serializer: globalResources.serializer
39514
+ },
39515
+ async init(cfg, deps) {
39516
+ return createNodeExposure(cfg, deps);
39517
+ },
39518
+ async dispose(value) {
39519
+ if (value?.close) {
39520
+ await value.close();
39521
+ }
39522
+ }
39523
+ });
39524
+
39525
+ // src/node/files/createNodeFile.ts
39526
+ function createNodeFile(meta, source, id2 = "F1") {
39527
+ return {
39528
+ $runnerFile: "File",
39529
+ id: id2,
39530
+ meta,
39531
+ _node: source
39532
+ };
39533
+ }
39534
+ __name(createNodeFile, "createNodeFile");
39535
+ async function readInputFileToBuffer(file) {
39536
+ const { stream } = await file.resolve();
39537
+ const chunks = [];
39538
+ await new Promise((resolve, reject) => {
39539
+ stream.on("data", (chunk) => {
39540
+ if (Buffer.isBuffer(chunk)) {
39541
+ chunks.push(chunk);
39542
+ } else if (typeof chunk === "string") {
39543
+ chunks.push(Buffer.from(chunk));
39544
+ } else if (chunk !== void 0 && chunk !== null) {
39545
+ chunks.push(Buffer.from(String(chunk)));
39546
+ }
39547
+ });
39548
+ stream.on("end", () => resolve());
39549
+ stream.on("error", (err) => reject(err));
39550
+ });
39551
+ return Buffer.concat(chunks);
39552
+ }
39553
+ __name(readInputFileToBuffer, "readInputFileToBuffer");
39554
+ async function writeInputFileToPath(file, targetPath) {
39555
+ const { stream } = await file.resolve();
39556
+ await fs3.promises.mkdir(path3.dirname(targetPath), {
39557
+ recursive: true
39558
+ });
39559
+ const write = fs3.createWriteStream(targetPath);
39560
+ let bytesWritten = 0;
39561
+ const normalize = new Transform({
39562
+ writableObjectMode: true,
39563
+ transform(chunk, _enc, cb) {
39564
+ const out = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
39565
+ bytesWritten += out.length;
39566
+ cb(null, out);
39567
+ }
39568
+ });
39569
+ await new Promise((resolve, reject) => {
39570
+ pipeline(
39571
+ stream,
39572
+ normalize,
39573
+ write,
39574
+ (err) => err ? reject(err) : resolve()
39575
+ );
39576
+ });
39577
+ return { bytesWritten };
39578
+ }
39579
+ __name(writeInputFileToPath, "writeInputFileToPath");
39580
+
39581
+ // src/node/upload/manifest.ts
39582
+ function buildNodeManifest(input) {
39583
+ const files = [];
39584
+ function visit(value) {
39585
+ if (!value || typeof value !== "object") return value;
39586
+ const potentialFile = value;
39587
+ if (potentialFile.$runnerFile === "File" && typeof potentialFile.id === "string") {
39588
+ const id2 = potentialFile.id;
39589
+ const meta = potentialFile.meta;
39590
+ const local = potentialFile._node;
39591
+ if (local?.buffer) {
39592
+ files.push({
39593
+ id: id2,
39594
+ meta,
39595
+ source: { type: "buffer", buffer: local.buffer }
39596
+ });
39597
+ } else if (local?.stream) {
39598
+ files.push({
39599
+ id: id2,
39600
+ meta,
39601
+ source: { type: "stream", stream: local.stream }
39602
+ });
39603
+ }
39604
+ const copy = { $runnerFile: "File", id: id2, meta };
39605
+ return copy;
39606
+ }
39607
+ if (Array.isArray(value)) {
39608
+ return value.map((x) => visit(x));
39609
+ }
39610
+ const out = {};
39611
+ const obj = value;
39612
+ for (const k of Object.keys(obj)) {
39613
+ out[k] = visit(obj[k]);
39614
+ }
39615
+ return out;
39616
+ }
39617
+ __name(visit, "visit");
39618
+ const cloned = visit(input);
39619
+ return { input: cloned, files };
39620
+ }
39621
+ __name(buildNodeManifest, "buildNodeManifest");
39622
+
39623
+ // src/node/http/http-smart-client.model.ts
39624
+ function isReadable(value) {
39625
+ return !!value && typeof value.pipe === "function";
39626
+ }
39627
+ __name(isReadable, "isReadable");
39628
+ function hasNodeFile(value) {
39629
+ const isNodeFileSentinel = /* @__PURE__ */ __name((v) => {
39630
+ if (!v || typeof v !== "object") return false;
39631
+ const rec = v;
39632
+ if (rec.$runnerFile !== "File") return false;
39633
+ if (typeof rec.id !== "string") return false;
39634
+ const node = rec._node;
39635
+ if (!node || typeof node !== "object") return false;
39636
+ const n = node;
39637
+ return Boolean(n.stream || n.buffer);
39638
+ }, "isNodeFileSentinel");
39639
+ const visit = /* @__PURE__ */ __name((v) => {
39640
+ if (isNodeFileSentinel(v)) return true;
39641
+ if (!v || typeof v !== "object") return false;
39642
+ if (Array.isArray(v)) return v.some(visit);
39643
+ for (const k of Object.keys(v)) {
39644
+ if (visit(v[k])) return true;
39645
+ }
39646
+ return false;
39647
+ }, "visit");
39648
+ return visit(value);
39649
+ }
39650
+ __name(hasNodeFile, "hasNodeFile");
39651
+ function toHeaders2(auth) {
39652
+ const headers = {};
39653
+ if (auth?.token)
39654
+ headers[(auth.header ?? "x-runner-token").toLowerCase()] = auth.token;
39655
+ return headers;
39656
+ }
39657
+ __name(toHeaders2, "toHeaders");
39658
+ function requestLib(url) {
39659
+ return url.protocol === "https:" ? https : http2;
39660
+ }
39661
+ __name(requestLib, "requestLib");
39662
+ async function postJson(cfg, url, body) {
39663
+ const serializer3 = cfg.serializer;
39664
+ const parsed = new URL(url);
39665
+ const lib = requestLib(parsed);
39666
+ const headers = {
39667
+ "content-type": "application/json; charset=utf-8",
39668
+ ...toHeaders2(cfg.auth)
39669
+ };
39670
+ if (cfg.contexts && cfg.contexts.length > 0) {
39671
+ const map = {};
39672
+ for (const ctx of cfg.contexts) {
39673
+ try {
39674
+ const v = ctx.use();
39675
+ map[ctx.id] = ctx.serialize(v);
39676
+ } catch {
39677
+ }
39678
+ }
39679
+ if (Object.keys(map).length > 0) {
39680
+ headers["x-runner-context"] = cfg.serializer.stringify(map);
39681
+ }
39682
+ }
39683
+ if (cfg.onRequest) await cfg.onRequest({ url, headers });
39684
+ return await new Promise((resolve, reject) => {
39685
+ const req = lib.request(
39686
+ {
39687
+ method: "POST",
39688
+ protocol: parsed.protocol,
39689
+ hostname: parsed.hostname,
39690
+ port: parsed.port,
39691
+ path: parsed.pathname + parsed.search,
39692
+ headers,
39693
+ timeout: cfg.timeoutMs
39694
+ },
39695
+ (res) => {
39696
+ const chunks = [];
39697
+ res.on("data", (c) => {
39698
+ chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(String(c)));
39699
+ });
39700
+ res.on("end", () => {
39701
+ const text = Buffer.concat(chunks).toString(
39702
+ "utf8"
39703
+ );
39704
+ const json2 = text ? serializer3.parse(text) : void 0;
39705
+ resolve(json2);
39706
+ });
39707
+ }
39708
+ );
39709
+ req.on("error", reject);
39710
+ req.write(serializer3.stringify(body));
39711
+ req.end();
39712
+ });
39713
+ }
39714
+ __name(postJson, "postJson");
39715
+ function escapeHeaderValue(value) {
39716
+ return value.replace(/"/g, '\\"');
39717
+ }
39718
+ __name(escapeHeaderValue, "escapeHeaderValue");
39719
+ function encodeMultipart(manifestText, files, boundary) {
39720
+ async function* gen() {
39721
+ const CRLF = "\r\n";
39722
+ const boundaryLine = `--${boundary}`;
39723
+ const partHeader = /* @__PURE__ */ __name((name, options) => {
39724
+ const h = [boundaryLine + CRLF];
39725
+ const cd = [
39726
+ `Content-Disposition: form-data; name="${escapeHeaderValue(name)}"`
39727
+ ];
39728
+ if (options?.filename) {
39729
+ cd.push(`; filename="${escapeHeaderValue(options.filename)}"`);
39730
+ }
39731
+ h.push(cd.join("") + CRLF);
39732
+ if (options?.headers) {
39733
+ for (const k of Object.keys(options.headers)) {
39734
+ h.push(`${k}: ${options.headers[k]}` + CRLF);
39735
+ }
39736
+ }
39737
+ h.push(CRLF);
39738
+ return Buffer.from(h.join(""), "utf8");
39739
+ }, "partHeader");
39740
+ yield partHeader("__manifest");
39741
+ yield Buffer.from(manifestText, "utf8");
39742
+ yield Buffer.from(CRLF, "utf8");
39743
+ for (const entry of files) {
39744
+ const filename = entry.meta?.name ?? "upload";
39745
+ const contentType = entry.meta?.type ?? "application/octet-stream";
39746
+ const headers = {
39747
+ "Content-Type": contentType
39748
+ };
39749
+ yield partHeader(`file:${entry.id}`, { headers, filename });
39750
+ if (entry.source.type === "buffer") {
39751
+ yield entry.source.buffer;
39752
+ } else {
39753
+ for await (const chunk of entry.source.stream) {
39754
+ yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
39755
+ }
39756
+ }
39757
+ yield Buffer.from(CRLF, "utf8");
39758
+ }
39759
+ yield Buffer.from(boundaryLine + "--" + CRLF, "utf8");
39760
+ }
39761
+ __name(gen, "gen");
39762
+ return Readable.from(gen());
39763
+ }
39764
+ __name(encodeMultipart, "encodeMultipart");
39765
+ async function postMultipart(cfg, url, manifestText, files) {
39766
+ const parsed = new URL(url);
39767
+ const lib = requestLib(parsed);
39768
+ const boundary = `runner-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
39769
+ const body = encodeMultipart(manifestText, files, boundary);
39770
+ const headers = {
39771
+ "content-type": `multipart/form-data; boundary=${boundary}`,
39772
+ ...toHeaders2(cfg.auth)
39773
+ };
39774
+ if (cfg.contexts && cfg.contexts.length > 0) {
39775
+ const map = {};
39776
+ for (const ctx of cfg.contexts) {
39777
+ try {
39778
+ const v = ctx.use();
39779
+ map[ctx.id] = ctx.serialize(v);
39780
+ } catch {
39781
+ }
39782
+ }
39783
+ if (Object.keys(map).length > 0) {
39784
+ headers["x-runner-context"] = cfg.serializer.stringify(map);
39785
+ }
39786
+ }
39787
+ if (cfg.onRequest) await cfg.onRequest({ url, headers });
39788
+ return await new Promise(
39789
+ (resolve, reject) => {
39790
+ const req = lib.request(
39791
+ {
39792
+ method: "POST",
39793
+ protocol: parsed.protocol,
39794
+ hostname: parsed.hostname,
39795
+ port: parsed.port,
39796
+ path: parsed.pathname + parsed.search,
39797
+ headers,
39798
+ timeout: cfg.timeoutMs
39799
+ },
39800
+ (res) => resolve({ stream: res, res })
39801
+ );
39802
+ req.on("error", reject);
39803
+ body.on("error", (e) => req.destroy(e));
39804
+ body.pipe(req);
39805
+ }
39806
+ );
39807
+ }
39808
+ __name(postMultipart, "postMultipart");
39809
+ async function postOctetStream(cfg, url, stream) {
39810
+ const parsed = new URL(url);
39811
+ const lib = requestLib(parsed);
39812
+ const headers = {
39813
+ "content-type": "application/octet-stream",
39814
+ ...toHeaders2(cfg.auth)
39815
+ };
39816
+ if (cfg.contexts && cfg.contexts.length > 0) {
39817
+ const map = {};
39818
+ for (const ctx of cfg.contexts) {
39819
+ try {
39820
+ const v = ctx.use();
39821
+ map[ctx.id] = ctx.serialize(v);
39822
+ } catch {
39823
+ }
39824
+ }
39825
+ if (Object.keys(map).length > 0) {
39826
+ headers["x-runner-context"] = cfg.serializer.stringify(map);
39827
+ }
39828
+ }
39829
+ if (cfg.onRequest) await cfg.onRequest({ url, headers });
39830
+ return await new Promise(
39831
+ (resolve, reject) => {
39832
+ let settled = false;
39833
+ const cleanup = [];
39834
+ const resolveOnce = /* @__PURE__ */ __name((value) => {
39835
+ settled = true;
39836
+ cleanup.forEach((fn) => fn());
39837
+ resolve(value);
39838
+ }, "resolveOnce");
39839
+ const rejectOnce = /* @__PURE__ */ __name((error2) => {
39840
+ settled = true;
39841
+ cleanup.forEach((fn) => fn());
39842
+ reject(error2 instanceof Error ? error2 : new Error(String(error2)));
39843
+ }, "rejectOnce");
39844
+ const req = lib.request(
39845
+ {
39846
+ method: "POST",
39847
+ protocol: parsed.protocol,
39848
+ hostname: parsed.hostname,
39849
+ port: parsed.port,
39850
+ path: parsed.pathname + parsed.search,
39851
+ headers,
39852
+ timeout: cfg.timeoutMs
39853
+ },
39854
+ (res) => {
39855
+ setImmediate(() => {
39856
+ if (!settled)
39857
+ resolveOnce({ stream: res, res });
39858
+ });
39859
+ }
39860
+ );
39861
+ const onReqError = /* @__PURE__ */ __name((e) => rejectOnce(e), "onReqError");
39862
+ req.on("error", onReqError);
39863
+ cleanup.push(() => req.removeListener("error", onReqError));
39864
+ const onPipelineDone = /* @__PURE__ */ __name((err) => {
39865
+ if (err) rejectOnce(err);
39866
+ }, "onPipelineDone");
39867
+ pipeline(stream, req, onPipelineDone);
39975
39868
  }
39976
- return true;
39977
- }, "handleRequest");
39978
- return { handleTask, handleEvent, handleDiscovery, handleRequest };
39979
- }
39980
- __name(createRequestHandlers, "createRequestHandlers");
39981
-
39982
- // src/node/exposure/createNodeExposure.ts
39983
- async function createNodeExposure(cfg, deps) {
39984
- const { store: store2, taskRunner, eventManager, logger, serializer: serializer3 } = deps;
39985
- const httpConfig = cfg?.http;
39986
- const basePath = resolveBasePath(httpConfig?.basePath);
39987
- const router = createRouter(basePath);
39988
- const allowList = createAllowListGuard(
39989
- store2,
39990
- !!httpConfig?.dangerouslyAllowOpenExposure
39991
- );
39992
- const validatorTasks = store2.getTasksWithTag(
39993
- globalTags.authValidator
39994
- );
39995
- const authenticator = createAuthenticator(
39996
- httpConfig?.auth,
39997
- taskRunner,
39998
- validatorTasks
39999
39869
  );
40000
- const { handleTask, handleEvent, handleDiscovery, handleRequest } = createRequestHandlers({
40001
- store: store2,
40002
- taskRunner,
40003
- eventManager,
40004
- logger,
40005
- authenticator,
40006
- allowList,
40007
- router,
40008
- cors: httpConfig?.cors,
40009
- serializer: serializer3,
40010
- limits: httpConfig?.limits
40011
- });
40012
- const serverControls = await createExposureServer({
40013
- httpConfig,
40014
- handler: handleRequest,
40015
- logger,
40016
- basePath
40017
- });
40018
- return {
40019
- handleRequest,
40020
- handleTask,
40021
- handleEvent,
40022
- handleDiscovery,
40023
- createRequestListener: serverControls.createRequestListener,
40024
- createServer: serverControls.createServer,
40025
- attachTo: serverControls.attachTo,
40026
- server: serverControls.server,
40027
- basePath,
40028
- close: serverControls.close
40029
- };
40030
39870
  }
40031
- __name(createNodeExposure, "createNodeExposure");
40032
-
40033
- // src/node/exposure/resource.ts
40034
- var nodeExposure = defineResource({
40035
- id: "platform.node.resources.exposure",
40036
- meta: {
40037
- title: "Node Exposure (HTTP)",
40038
- description: "Exposes Runner tasks and events over HTTP so a tunnel client can invoke them."
40039
- },
40040
- dependencies: {
40041
- store: globalResources.store,
40042
- taskRunner: globalResources.taskRunner,
40043
- eventManager: globalResources.eventManager,
40044
- logger: globalResources.logger,
40045
- serializer: globalResources.serializer
40046
- },
40047
- async init(cfg, deps) {
40048
- return createNodeExposure(cfg, deps);
40049
- },
40050
- async dispose(value) {
40051
- if (value?.close) {
40052
- await value.close();
39871
+ __name(postOctetStream, "postOctetStream");
39872
+ function parseMaybeJsonResponse(res, serializer3) {
39873
+ const contentType = String(res.headers["content-type"]);
39874
+ if (/^application\/json/i.test(contentType)) {
39875
+ const chunks = [];
39876
+ return new Promise((resolve, reject) => {
39877
+ res.on("data", (c) => {
39878
+ chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(String(c)));
39879
+ });
39880
+ res.on("end", () => {
39881
+ try {
39882
+ const text = Buffer.concat(chunks).toString(
39883
+ "utf8"
39884
+ );
39885
+ const json2 = text ? serializer3.parse(text) : void 0;
39886
+ resolve(json2);
39887
+ } catch (e) {
39888
+ reject(e);
39889
+ }
39890
+ });
39891
+ res.on("error", reject);
39892
+ });
39893
+ }
39894
+ return Promise.resolve(res);
39895
+ }
39896
+ __name(parseMaybeJsonResponse, "parseMaybeJsonResponse");
39897
+ function rethrowTyped(registry, error2) {
39898
+ if (registry && error2 && typeof error2 === "object") {
39899
+ const err = error2;
39900
+ if (err.id && err.data) {
39901
+ const helper = registry.get(String(err.id));
39902
+ if (helper) helper.throw(err.data);
40053
39903
  }
40054
39904
  }
40055
- });
40056
-
40057
- // src/node/files/createNodeFile.ts
40058
- function createNodeFile(meta, source, id2 = "F1") {
39905
+ throw error2;
39906
+ }
39907
+ __name(rethrowTyped, "rethrowTyped");
39908
+ function createHttpSmartClient(cfg) {
39909
+ const baseUrl = cfg.baseUrl.replace(/\/$/, "");
39910
+ if (!baseUrl) throw new Error("createHttpSmartClient requires baseUrl");
39911
+ const serializer3 = cfg.serializer;
40059
39912
  return {
40060
- $runnerFile: "File",
40061
- id: id2,
40062
- meta,
40063
- _node: source
39913
+ async task(id2, input) {
39914
+ const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
39915
+ if (isReadable(input)) {
39916
+ const { res } = await postOctetStream(cfg, url, input);
39917
+ return res;
39918
+ }
39919
+ if (hasNodeFile(input)) {
39920
+ const manifest = buildNodeManifest(input);
39921
+ const manifestText = serializer3.stringify({
39922
+ input: manifest.input
39923
+ });
39924
+ try {
39925
+ const { res } = await postMultipart(
39926
+ cfg,
39927
+ url,
39928
+ manifestText,
39929
+ manifest.files
39930
+ );
39931
+ const maybe = await parseMaybeJsonResponse(
39932
+ res,
39933
+ serializer3
39934
+ );
39935
+ if (isReadable(maybe)) return maybe;
39936
+ return assertOkEnvelope(maybe, {
39937
+ fallbackMessage: "Tunnel task error"
39938
+ });
39939
+ } catch (error2) {
39940
+ rethrowTyped(cfg.errorRegistry, error2);
39941
+ }
39942
+ }
39943
+ try {
39944
+ const r2 = await postJson(cfg, url, { input });
39945
+ return assertOkEnvelope(r2, {
39946
+ fallbackMessage: "Tunnel task error"
39947
+ });
39948
+ } catch (error2) {
39949
+ rethrowTyped(cfg.errorRegistry, error2);
39950
+ }
39951
+ },
39952
+ async event(id2, payload) {
39953
+ const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
39954
+ try {
39955
+ const r2 = await postJson(cfg, url, { payload });
39956
+ assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
39957
+ } catch (error2) {
39958
+ rethrowTyped(cfg.errorRegistry, error2);
39959
+ }
39960
+ },
39961
+ async eventWithResult(id2, payload) {
39962
+ const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
39963
+ try {
39964
+ const r2 = await postJson(cfg, url, {
39965
+ payload,
39966
+ returnPayload: true
39967
+ });
39968
+ if (r2 && typeof r2 === "object" && r2.ok && !("result" in r2)) {
39969
+ throw new TunnelError(
39970
+ "INVALID_RESPONSE",
39971
+ "Tunnel event returnPayload requested but server did not include result. Upgrade the exposure server."
39972
+ );
39973
+ }
39974
+ return assertOkEnvelope(r2, {
39975
+ fallbackMessage: "Tunnel event error"
39976
+ });
39977
+ } catch (error2) {
39978
+ rethrowTyped(cfg.errorRegistry, error2);
39979
+ }
39980
+ }
40064
39981
  };
40065
39982
  }
40066
- __name(createNodeFile, "createNodeFile");
40067
- async function readInputFileToBuffer(file) {
40068
- const { stream } = await file.resolve();
40069
- const chunks = [];
40070
- await new Promise((resolve, reject) => {
40071
- stream.on("data", (chunk) => {
40072
- if (Buffer.isBuffer(chunk)) {
40073
- chunks.push(chunk);
40074
- } else if (typeof chunk === "string") {
40075
- chunks.push(Buffer.from(chunk));
40076
- } else if (chunk !== void 0 && chunk !== null) {
40077
- chunks.push(Buffer.from(String(chunk)));
40078
- }
40079
- });
40080
- stream.on("end", () => resolve());
40081
- stream.on("error", (err) => reject(err));
40082
- });
40083
- return Buffer.concat(chunks);
39983
+ __name(createHttpSmartClient, "createHttpSmartClient");
39984
+
39985
+ // src/node/http/http-mixed-client.ts
39986
+ function isReadable2(value) {
39987
+ return !!value && typeof value.pipe === "function";
40084
39988
  }
40085
- __name(readInputFileToBuffer, "readInputFileToBuffer");
40086
- async function writeInputFileToPath(file, targetPath) {
40087
- const { stream } = await file.resolve();
40088
- await fs3.promises.mkdir(path3.dirname(targetPath), {
40089
- recursive: true
40090
- });
40091
- const write = fs3.createWriteStream(targetPath);
40092
- let bytesWritten = 0;
40093
- const normalize = new Transform({
40094
- writableObjectMode: true,
40095
- transform(chunk, _enc, cb) {
40096
- const out = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
40097
- bytesWritten += out.length;
40098
- cb(null, out);
39989
+ __name(isReadable2, "isReadable");
39990
+ function hasNodeFile2(value) {
39991
+ const isNodeFileSentinel = /* @__PURE__ */ __name((v) => {
39992
+ if (!v || typeof v !== "object") return false;
39993
+ const rec = v;
39994
+ if (rec.$runnerFile !== "File") return false;
39995
+ if (typeof rec.id !== "string") return false;
39996
+ const node = rec._node;
39997
+ if (!node || typeof node !== "object") return false;
39998
+ const n = node;
39999
+ return Boolean(n.stream || n.buffer);
40000
+ }, "isNodeFileSentinel");
40001
+ const visit = /* @__PURE__ */ __name((v) => {
40002
+ if (isNodeFileSentinel(v)) return true;
40003
+ if (!v || typeof v !== "object") return false;
40004
+ if (Array.isArray(v)) return v.some(visit);
40005
+ for (const k of Object.keys(v)) {
40006
+ if (visit(v[k])) return true;
40099
40007
  }
40008
+ return false;
40009
+ }, "visit");
40010
+ return visit(value);
40011
+ }
40012
+ __name(hasNodeFile2, "hasNodeFile");
40013
+ async function shouldForceSmart(cfg, id2, input) {
40014
+ if (!cfg.forceSmart) return false;
40015
+ if (cfg.forceSmart === true) return true;
40016
+ return await cfg.forceSmart({ id: id2, input });
40017
+ }
40018
+ __name(shouldForceSmart, "shouldForceSmart");
40019
+ function createHttpMixedClient(cfg) {
40020
+ const baseUrl = cfg.baseUrl?.replace(/\/$/, "");
40021
+ if (!baseUrl) throw new Error("createMixedHttpClient requires baseUrl");
40022
+ const fetchClient = createExposureFetch({
40023
+ baseUrl,
40024
+ auth: cfg.auth,
40025
+ timeoutMs: cfg.timeoutMs,
40026
+ fetchImpl: cfg.fetchImpl,
40027
+ serializer: cfg.serializer,
40028
+ onRequest: cfg.onRequest,
40029
+ contexts: cfg.contexts,
40030
+ errorRegistry: cfg.errorRegistry
40100
40031
  });
40101
- await new Promise((resolve, reject) => {
40102
- pipeline(
40103
- stream,
40104
- normalize,
40105
- write,
40106
- (err) => err ? reject(err) : resolve()
40107
- );
40032
+ const smartClient = createHttpSmartClient({
40033
+ baseUrl,
40034
+ auth: cfg.auth,
40035
+ timeoutMs: cfg.timeoutMs,
40036
+ serializer: cfg.serializer,
40037
+ onRequest: cfg.onRequest,
40038
+ contexts: cfg.contexts,
40039
+ errorRegistry: cfg.errorRegistry
40108
40040
  });
40109
- return { bytesWritten };
40041
+ return {
40042
+ async task(id2, input) {
40043
+ if (isReadable2(input) || hasNodeFile2(input) || await shouldForceSmart(cfg, id2, input)) {
40044
+ return await smartClient.task(id2, input);
40045
+ }
40046
+ return await fetchClient.task(id2, input);
40047
+ },
40048
+ async event(id2, payload) {
40049
+ return await fetchClient.event(id2, payload);
40050
+ },
40051
+ async eventWithResult(id2, payload) {
40052
+ if (!fetchClient.eventWithResult) {
40053
+ throw new Error(
40054
+ "createHttpMixedClient: eventWithResult not available on underlying tunnel client."
40055
+ );
40056
+ }
40057
+ return await fetchClient.eventWithResult(id2, payload);
40058
+ }
40059
+ };
40110
40060
  }
40111
- __name(writeInputFileToPath, "writeInputFileToPath");
40112
-
40113
- // src/node/http/index.ts
40114
- init_http_smart_client_model();
40115
- init_http_mixed_client();
40116
-
40117
- // src/node/http/http-smart-client.factory.resource.ts
40118
- var httpSmartClientFactory = defineResource({
40119
- id: "globals.resources.httpSmartClientFactory",
40120
- meta: {
40121
- title: "HTTP Smart Client Factory (Node)",
40122
- description: "Factory placeholder for Node Smart HTTP clients. Value is supplied at runtime by the Node run() wrapper to auto-inject serializer, error registry, and async contexts."
40123
- }
40124
- });
40125
-
40126
- // src/node/http/http-mixed-client.factory.resource.ts
40127
- var httpMixedClientFactory = defineResource({
40128
- id: "globals.resources.httpMixedClientFactory",
40129
- meta: {
40130
- title: "HTTP Mixed Client Factory (Node)",
40131
- description: "Factory placeholder for Node Mixed HTTP clients. Value is supplied at runtime by the Node run() wrapper to auto-inject serializer, error registry, and async contexts."
40132
- }
40133
- });
40061
+ __name(createHttpMixedClient, "createHttpMixedClient");
40134
40062
 
40135
40063
  // src/node/durable/core/types.ts
40136
40064
  var ExecutionStatus = {
@@ -40433,6 +40361,15 @@ async function recordFlowShape(descriptor) {
40433
40361
  }
40434
40362
  __name(recordFlowShape, "recordFlowShape");
40435
40363
 
40364
+ // src/node/durable/tags/durableWorkflow.tag.ts
40365
+ var durableWorkflowTag = defineTag({
40366
+ id: "globals.tags.durableWorkflow",
40367
+ meta: {
40368
+ title: "Durable Workflow",
40369
+ description: "Marks tasks intended to run as durable workflows so they can be discovered at runtime."
40370
+ }
40371
+ });
40372
+
40436
40373
  // src/node/durable/core/DurableResource.ts
40437
40374
  var DurableResource = class _DurableResource {
40438
40375
  constructor(service, contextStorage, store2, runnerStore) {
@@ -40484,11 +40421,20 @@ var DurableResource = class _DurableResource {
40484
40421
  );
40485
40422
  }
40486
40423
  const deps = storeTask.computedDependencies;
40424
+ const resolvedInput = this.resolveDescribeInput(effectiveTask, input);
40487
40425
  return await recordFlowShape(async (ctx) => {
40488
40426
  const depsWithRecorder = this.injectRecorderIntoDurableDeps(deps, ctx);
40489
- await effectiveTask.run(input, depsWithRecorder);
40427
+ await effectiveTask.run(resolvedInput, depsWithRecorder);
40490
40428
  });
40491
40429
  }
40430
+ getWorkflows() {
40431
+ if (!this.runnerStore) {
40432
+ throw new Error(
40433
+ "Durable workflow discovery is not available: runner store was not provided to DurableResource. Use a Runner durable resource (durableResource/memoryDurableResource/redisDurableResource) instead of manually constructing DurableResource."
40434
+ );
40435
+ }
40436
+ return this.runnerStore.getTasksWithTag(durableWorkflowTag);
40437
+ }
40492
40438
  injectRecorderIntoDurableDeps(deps, ctx) {
40493
40439
  const next = { ...deps };
40494
40440
  for (const [key, value] of Object.entries(deps)) {
@@ -40506,8 +40452,28 @@ var DurableResource = class _DurableResource {
40506
40452
  }
40507
40453
  return next;
40508
40454
  }
40509
- startExecution(task2, input, options) {
40510
- return this.service.startExecution(task2, input, options);
40455
+ resolveDescribeInput(task2, input) {
40456
+ if (input !== void 0) {
40457
+ return input;
40458
+ }
40459
+ const tagConfig = durableWorkflowTag.extract(task2.tags);
40460
+ if (!tagConfig?.defaults) {
40461
+ return void 0;
40462
+ }
40463
+ try {
40464
+ return structuredClone(tagConfig.defaults);
40465
+ } catch (error2) {
40466
+ const originalMessage = error2 instanceof Error ? error2.message : String(error2);
40467
+ throw new Error(
40468
+ `Cannot describe task "${task2.id}": durableWorkflowTag.defaults could not be cloned. Ensure defaults contain only structured-cloneable values. Original error: ${originalMessage}`
40469
+ );
40470
+ }
40471
+ }
40472
+ start(task2, input, options) {
40473
+ if (typeof task2 === "string") {
40474
+ return this.service.start(task2, input, options);
40475
+ }
40476
+ return this.service.start(task2, input, options);
40511
40477
  }
40512
40478
  cancelExecution(executionId, reason) {
40513
40479
  return this.service.cancelExecution(executionId, reason);
@@ -40515,16 +40481,22 @@ var DurableResource = class _DurableResource {
40515
40481
  wait(executionId, options) {
40516
40482
  return this.service.wait(executionId, options);
40517
40483
  }
40518
- execute(task2, input, options) {
40519
- return this.service.execute(task2, input, options);
40520
- }
40521
- executeStrict(task2, input, options) {
40522
- return this.service.executeStrict(task2, input, options);
40484
+ startAndWait(task2, input, options) {
40485
+ if (typeof task2 === "string") {
40486
+ return this.service.startAndWait(task2, input, options);
40487
+ }
40488
+ return this.service.startAndWait(task2, input, options);
40523
40489
  }
40524
40490
  schedule(task2, input, options) {
40491
+ if (typeof task2 === "string") {
40492
+ return this.service.schedule(task2, input, options);
40493
+ }
40525
40494
  return this.service.schedule(task2, input, options);
40526
40495
  }
40527
40496
  ensureSchedule(task2, input, options) {
40497
+ if (typeof task2 === "string") {
40498
+ return this.service.ensureSchedule(task2, input, options);
40499
+ }
40528
40500
  return this.service.ensureSchedule(task2, input, options);
40529
40501
  }
40530
40502
  pauseSchedule(scheduleId) {
@@ -41047,10 +41019,11 @@ var ScheduleManager = class {
41047
41019
  static {
41048
41020
  __name(this, "ScheduleManager");
41049
41021
  }
41050
- async ensureSchedule(task2, input, options) {
41022
+ async ensureSchedule(taskRef, input, options) {
41051
41023
  if (!options.cron && options.interval === void 0) {
41052
41024
  throw new Error("ensureSchedule() requires cron or interval");
41053
41025
  }
41026
+ const task2 = this.resolveTaskReference(taskRef, "ensureSchedule");
41054
41027
  this.taskRegistry.register(task2);
41055
41028
  const scheduleId = options.id;
41056
41029
  const lockTtlMs = 1e4;
@@ -41113,7 +41086,8 @@ var ScheduleManager = class {
41113
41086
  }
41114
41087
  }
41115
41088
  }
41116
- async schedule(task2, input, options) {
41089
+ async schedule(taskRef, input, options) {
41090
+ const task2 = this.resolveTaskReference(taskRef, "schedule");
41117
41091
  this.taskRegistry.register(task2);
41118
41092
  const id2 = options.id ?? createExecutionId();
41119
41093
  if (options.cron || options.interval !== void 0) {
@@ -41196,6 +41170,18 @@ var ScheduleManager = class {
41196
41170
  async remove(id2) {
41197
41171
  await this.store.deleteSchedule(id2);
41198
41172
  }
41173
+ resolveTaskReference(taskRef, apiMethod) {
41174
+ if (typeof taskRef !== "string") {
41175
+ return taskRef;
41176
+ }
41177
+ const resolved = this.taskRegistry.find(taskRef);
41178
+ if (!resolved) {
41179
+ throw new Error(
41180
+ `DurableService.${apiMethod}() could not resolve task id "${taskRef}". Ensure the task is registered in the runtime store.`
41181
+ );
41182
+ }
41183
+ return resolved;
41184
+ }
41199
41185
  };
41200
41186
 
41201
41187
  // src/node/durable/core/managers/SignalHandler.ts
@@ -42086,99 +42072,117 @@ var ExecutionManager = class {
42086
42072
  static {
42087
42073
  __name(this, "ExecutionManager");
42088
42074
  }
42089
- async startExecution(task2, input, options) {
42075
+ async start(taskRef, input, options) {
42076
+ const task2 = this.resolveTaskReference(taskRef, "start");
42090
42077
  this.taskRegistry.register(task2);
42078
+ this.assertCanExecute();
42079
+ if (options?.idempotencyKey) {
42080
+ return this.startWithIdempotencyKey(
42081
+ task2,
42082
+ input,
42083
+ options.idempotencyKey,
42084
+ options
42085
+ );
42086
+ }
42087
+ const executionId = await this.persistNewExecution(task2, input, options);
42088
+ await this.kickoffWithFailsafe(executionId);
42089
+ return executionId;
42090
+ }
42091
+ // ─── Idempotent start ──────────────────────────────────────────────────────
42092
+ /**
42093
+ * Start a workflow with deduplication: if the same (taskId, idempotencyKey)
42094
+ * was already started, returns the existing executionId instead of creating
42095
+ * a duplicate. Uses a distributed lock to prevent concurrent races.
42096
+ */
42097
+ async startWithIdempotencyKey(task2, input, idempotencyKey, options) {
42098
+ this.assertStoreSupportsIdempotency();
42099
+ return this.withIdempotencyLock(task2.id, idempotencyKey, async () => {
42100
+ const existingId = await this.config.store.getExecutionIdByIdempotencyKey({
42101
+ taskId: task2.id,
42102
+ idempotencyKey
42103
+ });
42104
+ if (existingId) return existingId;
42105
+ const executionId = createExecutionId();
42106
+ const claimed = await this.config.store.setExecutionIdByIdempotencyKey({
42107
+ taskId: task2.id,
42108
+ idempotencyKey,
42109
+ executionId
42110
+ });
42111
+ if (!claimed) {
42112
+ return this.resolveRacedIdempotencyKey(task2.id, idempotencyKey);
42113
+ }
42114
+ await this.persistNewExecution(task2, input, options, executionId);
42115
+ await this.kickoffExecution(executionId);
42116
+ return executionId;
42117
+ });
42118
+ }
42119
+ assertCanExecute() {
42091
42120
  if (!this.config.queue && !this.config.taskExecutor) {
42092
42121
  throw new Error(
42093
42122
  "DurableService requires `taskExecutor` to execute Runner tasks (when no queue is configured). Use `durableResource.fork(...).with(...)` in a Runner runtime, or provide a custom executor in config."
42094
42123
  );
42095
42124
  }
42096
- const idempotencyKey = options?.idempotencyKey;
42097
- if (idempotencyKey) {
42098
- if (!this.config.store.getExecutionIdByIdempotencyKey || !this.config.store.setExecutionIdByIdempotencyKey) {
42099
- throw new Error(
42100
- "Durable store does not support execution idempotency keys. Implement getExecutionIdByIdempotencyKey/setExecutionIdByIdempotencyKey on the store to use ExecuteOptions.idempotencyKey."
42101
- );
42102
- }
42103
- const lockTtlMs = 1e4;
42104
- const lockResource = `idempotency:${task2.id}:${idempotencyKey}`;
42105
- const canLock = !!this.config.store.acquireLock && !!this.config.store.releaseLock;
42106
- let lockId = null;
42107
- if (canLock) {
42108
- const maxAttempts = 50;
42109
- for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
42110
- lockId = await this.config.store.acquireLock(
42111
- lockResource,
42112
- lockTtlMs
42113
- );
42114
- if (lockId !== null) break;
42115
- await sleepMs(5);
42116
- }
42117
- if (lockId === null) {
42118
- throw new Error(
42119
- `Failed to acquire idempotency lock for '${task2.id}:${idempotencyKey}'`
42120
- );
42121
- }
42122
- }
42125
+ }
42126
+ assertStoreSupportsIdempotency() {
42127
+ if (!this.config.store.getExecutionIdByIdempotencyKey || !this.config.store.setExecutionIdByIdempotencyKey) {
42128
+ throw new Error(
42129
+ "Durable store does not support execution idempotency keys. Implement getExecutionIdByIdempotencyKey/setExecutionIdByIdempotencyKey on the store to use ExecuteOptions.idempotencyKey."
42130
+ );
42131
+ }
42132
+ }
42133
+ /**
42134
+ * Acquires a distributed lock around the idempotency check-and-set,
42135
+ * falling back to lock-free operation when the store has no locking support.
42136
+ */
42137
+ async withIdempotencyLock(taskId, idempotencyKey, fn) {
42138
+ const canLock = !!this.config.store.acquireLock && !!this.config.store.releaseLock;
42139
+ if (!canLock) return fn();
42140
+ const lockResource = `idempotency:${taskId}:${idempotencyKey}`;
42141
+ const lockTtlMs = 1e4;
42142
+ const maxAttempts = 50;
42143
+ let lockId = null;
42144
+ for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
42145
+ lockId = await this.config.store.acquireLock(lockResource, lockTtlMs);
42146
+ if (lockId !== null) break;
42147
+ await sleepMs(5);
42148
+ }
42149
+ if (lockId === null) {
42150
+ throw new Error(
42151
+ `Failed to acquire idempotency lock for '${taskId}:${idempotencyKey}'`
42152
+ );
42153
+ }
42154
+ try {
42155
+ return await fn();
42156
+ } finally {
42123
42157
  try {
42124
- const existing = await this.config.store.getExecutionIdByIdempotencyKey(
42125
- {
42126
- taskId: task2.id,
42127
- idempotencyKey
42128
- }
42129
- );
42130
- if (existing) return existing;
42131
- const executionId2 = createExecutionId();
42132
- const setOk = await this.config.store.setExecutionIdByIdempotencyKey({
42133
- taskId: task2.id,
42134
- idempotencyKey,
42135
- executionId: executionId2
42136
- });
42137
- if (!setOk) {
42138
- const raced = await this.config.store.getExecutionIdByIdempotencyKey({
42139
- taskId: task2.id,
42140
- idempotencyKey
42141
- });
42142
- if (raced) return raced;
42143
- throw new Error(
42144
- "Failed to set idempotency mapping but no existing mapping found."
42145
- );
42146
- }
42147
- const execution2 = {
42148
- id: executionId2,
42149
- taskId: task2.id,
42150
- input,
42151
- status: ExecutionStatus.Pending,
42152
- attempt: 1,
42153
- maxAttempts: this.config.execution?.maxAttempts ?? 3,
42154
- timeout: options?.timeout ?? this.config.execution?.timeout,
42155
- createdAt: /* @__PURE__ */ new Date(),
42156
- updatedAt: /* @__PURE__ */ new Date()
42157
- };
42158
- await this.config.store.saveExecution(execution2);
42159
- await this.auditLogger.log({
42160
- kind: DurableAuditEntryKind.ExecutionStatusChanged,
42161
- executionId: executionId2,
42162
- taskId: task2.id,
42163
- attempt: execution2.attempt,
42164
- from: null,
42165
- to: ExecutionStatus.Pending,
42166
- reason: "created"
42167
- });
42168
- await this.kickoffExecution(executionId2);
42169
- return executionId2;
42170
- } finally {
42171
- if (canLock && lockId !== null) {
42172
- try {
42173
- await this.config.store.releaseLock(lockResource, lockId);
42174
- } catch {
42175
- }
42176
- }
42158
+ await this.config.store.releaseLock(lockResource, lockId);
42159
+ } catch {
42177
42160
  }
42178
42161
  }
42179
- const executionId = createExecutionId();
42162
+ }
42163
+ /**
42164
+ * Recovery path: `setExecutionIdByIdempotencyKey` returned false (another
42165
+ * writer won the race), so we re-read the mapping to get their executionId.
42166
+ */
42167
+ async resolveRacedIdempotencyKey(taskId, idempotencyKey) {
42168
+ const racedId = await this.config.store.getExecutionIdByIdempotencyKey({
42169
+ taskId,
42170
+ idempotencyKey
42171
+ });
42172
+ if (racedId) return racedId;
42173
+ throw new Error(
42174
+ "Failed to set idempotency mapping but no existing mapping found."
42175
+ );
42176
+ }
42177
+ // ─── Execution persistence ─────────────────────────────────────────────────
42178
+ /**
42179
+ * Creates a new execution record, persists it to the store, and logs an
42180
+ * audit entry. Returns the executionId.
42181
+ */
42182
+ async persistNewExecution(task2, input, options, executionId) {
42183
+ const id2 = executionId ?? createExecutionId();
42180
42184
  const execution = {
42181
- id: executionId,
42185
+ id: id2,
42182
42186
  taskId: task2.id,
42183
42187
  input,
42184
42188
  status: ExecutionStatus.Pending,
@@ -42191,37 +42195,40 @@ var ExecutionManager = class {
42191
42195
  await this.config.store.saveExecution(execution);
42192
42196
  await this.auditLogger.log({
42193
42197
  kind: DurableAuditEntryKind.ExecutionStatusChanged,
42194
- executionId,
42198
+ executionId: id2,
42195
42199
  taskId: task2.id,
42196
42200
  attempt: execution.attempt,
42197
42201
  from: null,
42198
42202
  to: ExecutionStatus.Pending,
42199
42203
  reason: "created"
42200
42204
  });
42201
- const kickoffTimerId = `kickoff:${executionId}`;
42202
- const kickoffFailsafeDelayMs = this.config.execution?.kickoffFailsafeDelayMs ?? 1e4;
42203
- const shouldArmKickoffFailsafe = Boolean(this.config.queue) && kickoffFailsafeDelayMs > 0;
42204
- if (shouldArmKickoffFailsafe) {
42205
+ return id2;
42206
+ }
42207
+ /**
42208
+ * Kicks off an execution with a failsafe timer for queue mode.
42209
+ * If the queue enqueue succeeds, the timer is cleaned up immediately.
42210
+ * If enqueue fails, the timer remains so the polling loop can retry later.
42211
+ */
42212
+ async kickoffWithFailsafe(executionId) {
42213
+ const failsafeDelayMs = this.config.execution?.kickoffFailsafeDelayMs ?? 1e4;
42214
+ const shouldArmFailsafe = Boolean(this.config.queue) && failsafeDelayMs > 0;
42215
+ if (shouldArmFailsafe) {
42216
+ const timerId = `kickoff:${executionId}`;
42205
42217
  await this.config.store.createTimer({
42206
- id: kickoffTimerId,
42218
+ id: timerId,
42207
42219
  executionId,
42208
42220
  type: TimerType.Retry,
42209
- fireAt: new Date(Date.now() + kickoffFailsafeDelayMs),
42221
+ fireAt: new Date(Date.now() + failsafeDelayMs),
42210
42222
  status: TimerStatus.Pending
42211
42223
  });
42212
- }
42213
- try {
42214
42224
  await this.kickoffExecution(executionId);
42215
- if (shouldArmKickoffFailsafe) {
42216
- try {
42217
- await this.config.store.deleteTimer(kickoffTimerId);
42218
- } catch {
42219
- }
42225
+ try {
42226
+ await this.config.store.deleteTimer(timerId);
42227
+ } catch {
42220
42228
  }
42221
- } catch (error2) {
42222
- throw error2;
42229
+ return;
42223
42230
  }
42224
- return executionId;
42231
+ await this.kickoffExecution(executionId);
42225
42232
  }
42226
42233
  async cancelExecution(executionId, reason) {
42227
42234
  const execution = await this.config.store.getExecution(executionId);
@@ -42252,16 +42259,16 @@ var ExecutionManager = class {
42252
42259
  timestamp: /* @__PURE__ */ new Date()
42253
42260
  });
42254
42261
  }
42255
- async execute(task2, input, options) {
42256
- const executionId = await this.startExecution(task2, input, options);
42257
- return await this.waitManager.waitForResult(executionId, {
42262
+ async startAndWait(taskRef, input, options) {
42263
+ const executionId = await this.start(taskRef, input, options);
42264
+ const data = await this.waitManager.waitForResult(executionId, {
42258
42265
  timeout: options?.timeout,
42259
42266
  waitPollIntervalMs: options?.waitPollIntervalMs
42260
42267
  });
42261
- }
42262
- async executeStrict(task2, input, options) {
42263
- const actualTask = task2;
42264
- return await this.execute(actualTask, input, options);
42268
+ return {
42269
+ durable: { executionId },
42270
+ data
42271
+ };
42265
42272
  }
42266
42273
  async processExecution(executionId) {
42267
42274
  const execution = await this.config.store.getExecution(executionId);
@@ -42470,6 +42477,18 @@ var ExecutionManager = class {
42470
42477
  });
42471
42478
  }
42472
42479
  }
42480
+ resolveTaskReference(taskRef, apiMethod) {
42481
+ if (typeof taskRef !== "string") {
42482
+ return taskRef;
42483
+ }
42484
+ const resolved = this.taskRegistry.find(taskRef);
42485
+ if (!resolved) {
42486
+ throw new Error(
42487
+ `DurableService.${apiMethod}() could not resolve task id "${taskRef}". Ensure the task is registered in the runtime store.`
42488
+ );
42489
+ }
42490
+ return resolved;
42491
+ }
42473
42492
  };
42474
42493
  var PollingManager = class {
42475
42494
  constructor(workerId, config, store2, queue, maxAttempts, defaultTimeout, taskRegistry, auditLogger, scheduleManager, callbacks) {
@@ -42664,16 +42683,26 @@ var DurableService = class {
42664
42683
  this.config = config;
42665
42684
  this.workerId = config.workerId ?? createExecutionId();
42666
42685
  this.taskRegistry = new TaskRegistry(config.taskResolver);
42667
- if (config.schedules) {
42668
- for (const schedule of config.schedules) {
42669
- this.taskRegistry.register(schedule.task);
42670
- }
42671
- }
42672
42686
  if (config.tasks) {
42673
42687
  for (const task2 of config.tasks) {
42674
42688
  this.taskRegistry.register(task2);
42675
42689
  }
42676
42690
  }
42691
+ if (config.schedules) {
42692
+ for (const schedule of config.schedules) {
42693
+ if (typeof schedule.task === "string") {
42694
+ const resolved = this.taskRegistry.find(schedule.task);
42695
+ if (!resolved) {
42696
+ throw new Error(
42697
+ `Cannot initialize durable schedule "${schedule.id}": task "${schedule.task}" is not registered.`
42698
+ );
42699
+ }
42700
+ this.taskRegistry.register(resolved);
42701
+ continue;
42702
+ }
42703
+ this.taskRegistry.register(schedule.task);
42704
+ }
42705
+ }
42677
42706
  this.auditLogger = new AuditLogger(
42678
42707
  { enabled: config.audit?.enabled, emitter: config.audit?.emitter },
42679
42708
  config.store
@@ -42733,17 +42762,18 @@ var DurableService = class {
42733
42762
  findTask(taskId) {
42734
42763
  return this.taskRegistry.find(taskId);
42735
42764
  }
42736
- async startExecution(task2, input, options) {
42737
- return this.executionManager.startExecution(task2, input, options);
42765
+ start(task2, input, options) {
42766
+ if (task2 === void 0) {
42767
+ this.pollingManager.start();
42768
+ return;
42769
+ }
42770
+ return this.executionManager.start(task2, input, options);
42738
42771
  }
42739
42772
  async cancelExecution(executionId, reason) {
42740
42773
  await this.executionManager.cancelExecution(executionId, reason);
42741
42774
  }
42742
- async execute(task2, input, options) {
42743
- return this.executionManager.execute(task2, input, options);
42744
- }
42745
- async executeStrict(task2, input, options) {
42746
- return this.executionManager.executeStrict(task2, input, options);
42775
+ async startAndWait(task2, input, options) {
42776
+ return this.executionManager.startAndWait(task2, input, options);
42747
42777
  }
42748
42778
  wait(executionId, options) {
42749
42779
  return this.waitManager.waitForResult(executionId, options);
@@ -42762,9 +42792,6 @@ var DurableService = class {
42762
42792
  }
42763
42793
  }
42764
42794
  }
42765
- start() {
42766
- this.pollingManager.start();
42767
- }
42768
42795
  async stop() {
42769
42796
  await this.pollingManager.stop();
42770
42797
  }
@@ -42900,10 +42927,7 @@ async function createRunnerDurableRuntime(config, deps) {
42900
42927
  },
42901
42928
  taskExecutor: {
42902
42929
  run: /* @__PURE__ */ __name(async (task2, input) => {
42903
- const outputPromise = await deps.taskRunner.run(
42904
- task2,
42905
- input
42906
- );
42930
+ const outputPromise = await deps.taskRunner.run(task2, input);
42907
42931
  if (outputPromise === void 0) {
42908
42932
  throw new Error(
42909
42933
  `Durable task '${task2.id}' completed without a result promise.`
@@ -42931,7 +42955,7 @@ async function createRunnerDurableRuntime(config, deps) {
42931
42955
  __name(createRunnerDurableRuntime, "createRunnerDurableRuntime");
42932
42956
 
42933
42957
  // src/node/durable/core/resource.ts
42934
- var durableResource = r.resource("base.durable").register(durableEventsArray).dependencies({
42958
+ var durableResource = r.resource("base.durable").register([durableWorkflowTag, ...durableEventsArray]).dependencies({
42935
42959
  taskRunner: globals.resources.taskRunner,
42936
42960
  eventManager: globals.resources.eventManager,
42937
42961
  runnerStore: globals.resources.store
@@ -44073,7 +44097,7 @@ async function waitUntil(predicate, options) {
44073
44097
  __name(waitUntil, "waitUntil");
44074
44098
 
44075
44099
  // src/node/durable/resources/memoryDurableResource.ts
44076
- var memoryDurableResource = r.resource("base.durable.memory").register(durableEventsArray).dependencies({
44100
+ var memoryDurableResource = r.resource("base.durable.memory").register([durableWorkflowTag, ...durableEventsArray]).dependencies({
44077
44101
  taskRunner: globals.resources.taskRunner,
44078
44102
  eventManager: globals.resources.eventManager,
44079
44103
  runnerStore: globals.resources.store
@@ -44132,7 +44156,7 @@ function deriveDurableIsolation(params) {
44132
44156
  __name(deriveDurableIsolation, "deriveDurableIsolation");
44133
44157
 
44134
44158
  // src/node/durable/resources/redisDurableResource.ts
44135
- var redisDurableResource = r.resource("base.durable.redis").register(durableEventsArray).dependencies({
44159
+ var redisDurableResource = r.resource("base.durable.redis").register([durableWorkflowTag, ...durableEventsArray]).dependencies({
44136
44160
  taskRunner: globals.resources.taskRunner,
44137
44161
  eventManager: globals.resources.eventManager,
44138
44162
  runnerStore: globals.resources.store
@@ -44179,50 +44203,6 @@ var redisDurableResource = r.resource("base.durable.redis").register(durableEven
44179
44203
  if (!ctx.runtimeConfig) return;
44180
44204
  await disposeDurableService(durable.service, ctx.runtimeConfig);
44181
44205
  }).build();
44182
-
44183
- // src/node/node.ts
44184
- var globals2 = {
44185
- ...globals,
44186
- resources: {
44187
- ...globals.resources,
44188
- httpSmartClientFactory,
44189
- httpMixedClientFactory
44190
- }
44191
- };
44192
- async function run2(root, config) {
44193
- const rt = await run(root, config);
44194
- const store2 = await rt.getResourceValue(globals.resources.store);
44195
- store2.storeGenericItem(httpSmartClientFactory);
44196
- store2.storeGenericItem(httpMixedClientFactory);
44197
- const serializer3 = await rt.getResourceValue(
44198
- globals.resources.serializer
44199
- );
44200
- const errorRegistry = /* @__PURE__ */ new Map();
44201
- for (const [id2, helper] of store2.errors) errorRegistry.set(id2, helper);
44202
- const contexts = Array.from(store2.asyncContexts.values());
44203
- const smartEntry = store2.resources.get(httpSmartClientFactory.id);
44204
- if (smartEntry && !smartEntry.isInitialized) {
44205
- smartEntry.value = (cfg) => (init_http_smart_client_model(), __toCommonJS(http_smart_client_model_exports)).createHttpSmartClient({
44206
- ...cfg,
44207
- serializer: serializer3,
44208
- contexts,
44209
- errorRegistry
44210
- });
44211
- smartEntry.isInitialized = true;
44212
- }
44213
- const mixedEntry = store2.resources.get(httpMixedClientFactory.id);
44214
- if (mixedEntry && !mixedEntry.isInitialized) {
44215
- mixedEntry.value = (cfg) => (init_http_mixed_client(), __toCommonJS(http_mixed_client_exports)).createHttpMixedClient({
44216
- ...cfg,
44217
- serializer: serializer3,
44218
- contexts,
44219
- errorRegistry
44220
- });
44221
- mixedEntry.isInitialized = true;
44222
- }
44223
- return rt;
44224
- }
44225
- __name(run2, "run");
44226
44206
  /*! Bundled license information:
44227
44207
 
44228
44208
  depd/index.js:
@@ -44510,6 +44490,6 @@ serve-static/index.js:
44510
44490
  *)
44511
44491
  */
44512
44492
 
44513
- export { DependencyProcessor, DurableAuditEntryKind, DurableContext, DurableExecutionError, DurableOperator, DurableResource, DurableService, DurableWorker, errors_exports as Errors, EventManager, ExecutionStatus, LogPrinter, Logger, MemoryEventBus, MemoryQueue, MemoryStore, MiddlewareManager, NodeInputFile, NoopEventBus, PlatformAdapter, Queue, RabbitMQQueue, RedisEventBus, RedisStore, ResourceInitializer, RunResult, ScheduleStatus, ScheduleType, Semaphore, Serializer, StepBuilder, Store, SuspensionSignal, SymbolPolicy, SymbolPolicyErrorMessage, TaskRunner, TimerStatus, TimerType, allFalse, defineAsyncContext as asyncContext, bindProcessErrorHandler, createContext2 as createContext, createDashboardMiddleware, createDefaultUnhandledError, createDurableAuditEntryId, createDurableRunnerAuditEmitter, createDurableStepId, createDurableTestSetup, createExposureFetch, createHttpClient, createHttpMixedClient, createHttpSmartClient, createNodeFile, createRunnerDurableRuntime, createTestResource, debug, debugLevels, defs_exports as definitions, disposeDurableService, durableEvents, durableEventsArray, durableResource, defineEvent as event, getConfig, globals2 as globals, hasExposureContext, defineHook as hook, initDurableService, initDurableWorker, isDurableInternalStepId, journal, levelNormal, levelVerbose, memoryDurableResource, nodeExposure, normalizeError, defineOverride as override, r, readInputFileToBuffer, redisDurableResource, defineResource as resource, defineResourceMiddleware as resourceMiddleware, run2 as run, safeReportUnhandledError, setPlatform, defineTag as tag, defineTask as task, defineTaskMiddleware as taskMiddleware, useExposureContext, waitUntil, writeInputFileToPath };
44493
+ export { DurableAuditEntryKind, DurableContext, DurableExecutionError, DurableOperator, DurableResource, DurableService, DurableWorker, ExecutionStatus, MemoryEventBus, MemoryQueue, MemoryStore, NodeInputFile, NoopEventBus, RabbitMQQueue, RedisEventBus, RedisStore, ScheduleStatus, ScheduleType, StepBuilder, SuspensionSignal, TimerStatus, TimerType, createDashboardMiddleware, createDurableAuditEntryId, createDurableRunnerAuditEmitter, createDurableStepId, createDurableTestSetup, createHttpMixedClient, createHttpSmartClient, createNodeFile, createRunnerDurableRuntime, disposeDurableService, durableEvents, durableEventsArray, durableResource, durableWorkflowTag, globals, hasExposureContext, initDurableService, initDurableWorker, isDurableInternalStepId, memoryDurableResource, nodeExposure, readInputFileToBuffer, redisDurableResource, run, useExposureContext, waitUntil, writeInputFileToPath };
44514
44494
  //# sourceMappingURL=node.mjs.map
44515
44495
  //# sourceMappingURL=node.mjs.map