@bluelibs/runner 5.3.0 → 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 (60) hide show
  1. package/dist/browser/index.cjs +829 -742
  2. package/dist/browser/index.cjs.map +1 -1
  3. package/dist/browser/index.mjs +828 -743
  4. package/dist/browser/index.mjs.map +1 -1
  5. package/dist/edge/index.cjs +829 -742
  6. package/dist/edge/index.cjs.map +1 -1
  7. package/dist/edge/index.mjs +828 -743
  8. package/dist/edge/index.mjs.map +1 -1
  9. package/dist/node/node.cjs +1462 -1706
  10. package/dist/node/node.cjs.map +1 -1
  11. package/dist/node/node.mjs +1459 -1659
  12. package/dist/node/node.mjs.map +1 -1
  13. package/dist/types/definers/builders/event/utils.d.ts +1 -4
  14. package/dist/types/definers/builders/hook/utils.d.ts +1 -4
  15. package/dist/types/definers/builders/middleware/utils.d.ts +1 -4
  16. package/dist/types/definers/builders/resource/utils.d.ts +1 -4
  17. package/dist/types/definers/builders/shared/mergeUtils.d.ts +5 -0
  18. package/dist/types/definers/builders/task/utils.d.ts +1 -4
  19. package/dist/types/definers/builders/utils.d.ts +1 -1
  20. package/dist/types/errors.d.ts +20 -21
  21. package/dist/types/models/DependencyProcessor.d.ts +1 -1
  22. package/dist/types/models/MiddlewareManager.d.ts +2 -2
  23. package/dist/types/models/RunResult.d.ts +1 -1
  24. package/dist/types/models/Store.d.ts +10 -10
  25. package/dist/types/models/StoreRegistry.d.ts +14 -13
  26. package/dist/types/models/middleware/ResourceMiddlewareComposer.d.ts +2 -2
  27. package/dist/types/models/utils/buildDependencyGraph.d.ts +12 -0
  28. package/dist/types/models/utils/dependencyStrategies.d.ts +15 -0
  29. package/dist/types/models/utils/disposeOrder.d.ts +7 -0
  30. package/dist/types/node/durable/core/DurableResource.d.ts +1 -0
  31. package/dist/types/node/durable/core/resource.d.ts +5 -5
  32. package/dist/types/node/durable/resources/memoryDurableResource.d.ts +5 -5
  33. package/dist/types/node/durable/resources/redisDurableResource.d.ts +5 -5
  34. package/dist/types/node/durable/tags/durableWorkflow.tag.d.ts +6 -1
  35. package/dist/types/node/exposure/requestContext.d.ts +1 -1
  36. package/dist/types/node/exposure/resource.d.ts +7 -7
  37. package/dist/types/node/http/http-mixed-client.factory.resource.d.ts +1 -1
  38. package/dist/types/node/http/http-smart-client.factory.resource.d.ts +1 -1
  39. package/dist/types/node/node.d.ts +1 -184
  40. package/dist/types/platform/adapters/edge.d.ts +17 -0
  41. package/dist/types/platform/adapters/universal-generic.d.ts +3 -0
  42. package/dist/types/platform/index.d.ts +1 -0
  43. package/dist/types/platform/types.d.ts +7 -1
  44. package/dist/types/public.d.ts +2 -0
  45. package/dist/types/tools/LockableMap.d.ts +20 -0
  46. package/dist/types/types/symbols.d.ts +1 -1
  47. package/dist/types/types/task.d.ts +1 -1
  48. package/dist/ui/assets/index-Bo7Gi6Vq.js +141 -0
  49. package/dist/ui/assets/index-Y_9aLumt.css +1 -0
  50. package/dist/ui/index.html +2 -3
  51. package/dist/universal/index.cjs +829 -742
  52. package/dist/universal/index.cjs.map +1 -1
  53. package/dist/universal/index.mjs +828 -743
  54. package/dist/universal/index.mjs.map +1 -1
  55. package/package.json +1 -2
  56. package/readmes/AI.md +34 -3
  57. package/dist/ui/assets/index-2cb8f39f.js +0 -141
  58. package/dist/ui/assets/index-b1f988bf.css +0 -1
  59. /package/dist/types/{tunnels → tools}/buildUniversalManifest.d.ts +0 -0
  60. /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,875 +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
- httpCode: pe.httpCode,
198
- id: pe.id,
199
- data: pe.data
200
- });
201
- }
202
- }
203
- if (input && typeof input === "object" && "message" in input) {
204
- const typed = input;
205
- if (typeof typed.message === "string") {
206
- return new TunnelError("UNKNOWN", typed.message);
207
- }
208
- }
209
- return new TunnelError(
210
- "UNKNOWN",
211
- typeof input === "string" && input || fallbackMessage || "Tunnel error"
212
- );
213
- }
214
- function assertOkEnvelope(envelope, opts) {
215
- if (!envelope || typeof envelope !== "object") {
216
- throw new TunnelError(
217
- "INVALID_RESPONSE",
218
- opts?.fallbackMessage || "Invalid or empty response"
219
- );
220
- }
221
- if (envelope.ok) {
222
- return envelope.result;
223
- }
224
- if (envelope.error) {
225
- return (() => {
226
- throw toTunnelError(envelope.error, opts?.fallbackMessage);
227
- })();
228
- }
229
- throw new TunnelError("UNKNOWN", opts?.fallbackMessage || "Tunnel error");
230
- }
231
- var TunnelError;
232
- var init_protocol = __esm({
233
- "src/globals/resources/tunnel/protocol.ts"() {
234
- TunnelError = class extends Error {
235
- static {
236
- __name(this, "TunnelError");
237
- }
238
- constructor(code, message, details, extras) {
239
- super(message);
240
- this.name = "TunnelError";
241
- this.code = code;
242
- this.details = details;
243
- this.httpCode = extras?.httpCode;
244
- this.id = extras?.id;
245
- this.data = extras?.data;
246
- }
247
- };
248
- __name(toTunnelError, "toTunnelError");
249
- __name(assertOkEnvelope, "assertOkEnvelope");
250
- }
251
- });
252
-
253
- // src/globals/resources/tunnel/error-utils.ts
254
- function normalizeError(input) {
255
- return input instanceof Error ? input : new Error(String(input));
256
- }
257
- var init_error_utils = __esm({
258
- "src/globals/resources/tunnel/error-utils.ts"() {
259
- __name(normalizeError, "normalizeError");
260
- }
261
- });
262
-
263
- // src/http-fetch-tunnel.resource.ts
264
- async function postSerialized(options) {
265
- const {
266
- fetch: fetchFn,
267
- url,
268
- body,
269
- headers,
270
- timeoutMs,
271
- serializer: serializer3,
272
- onRequest,
273
- contextHeaderText
274
- } = options;
275
- const controller = timeoutMs && timeoutMs > 0 ? new AbortController() : void 0;
276
- let timeout;
277
- try {
278
- if (controller) {
279
- timeout = setTimeout(() => controller.abort(), timeoutMs);
280
- }
281
- const reqHeaders = {
282
- "content-type": "application/json; charset=utf-8",
283
- ...headers
284
- };
285
- if (contextHeaderText) reqHeaders["x-runner-context"] = contextHeaderText;
286
- if (onRequest) await onRequest({ url, headers: reqHeaders });
287
- const res = await fetchFn(url, {
288
- method: "POST",
289
- headers: reqHeaders,
290
- body: serializer3.stringify(body),
291
- signal: controller?.signal
292
- });
293
- const text = await res.text();
294
- const json2 = text ? serializer3.parse(text) : void 0;
295
- return json2;
296
- } finally {
297
- if (timeout) clearTimeout(timeout);
298
- }
299
- }
300
- function createExposureFetch(cfg) {
301
- const baseUrl = cfg?.baseUrl?.replace(/\/$/, "");
302
- if (!baseUrl) throw new Error("createExposureFetch requires baseUrl");
303
- const headerName = (cfg?.auth?.header ?? "x-runner-token").toLowerCase();
304
- const buildHeaders = /* @__PURE__ */ __name(() => {
305
- const headers = {};
306
- if (cfg?.auth?.token) headers[headerName] = cfg.auth.token;
307
- return headers;
308
- }, "buildHeaders");
309
- const fetchImpl = cfg.fetchImpl ?? globalThis.fetch;
310
- if (typeof fetchImpl !== "function") {
311
- throw new Error(
312
- "global fetch is not available; provide fetchImpl in config"
313
- );
314
- }
315
- const buildContextHeader = /* @__PURE__ */ __name(() => {
316
- if (!cfg.contexts || cfg.contexts.length === 0) return void 0;
317
- const map = {};
318
- for (const ctx of cfg.contexts) {
319
- try {
320
- const v = ctx.use();
321
- map[ctx.id] = ctx.serialize(v);
322
- } catch {
323
- }
324
- }
325
- const keys = Object.keys(map);
326
- if (keys.length === 0) return void 0;
327
- return cfg.serializer.stringify(map);
328
- }, "buildContextHeader");
329
- return {
330
- async task(id2, input) {
331
- const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
332
- const r2 = await postSerialized({
333
- fetch: fetchImpl,
334
- url,
335
- body: { input },
336
- headers: buildHeaders(),
337
- timeoutMs: cfg?.timeoutMs,
338
- serializer: cfg.serializer,
339
- onRequest: cfg?.onRequest,
340
- contextHeaderText: buildContextHeader()
341
- });
342
- try {
343
- return assertOkEnvelope(r2, { fallbackMessage: "Tunnel task error" });
344
- } catch (e) {
345
- const te = e;
346
- if (cfg.errorRegistry && te.id && te.data) {
347
- const helper = cfg.errorRegistry.get(String(te.id));
348
- if (helper) helper.throw(te.data);
349
- }
350
- throw e;
351
- }
352
- },
353
- async event(id2, payload) {
354
- const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
355
- const r2 = await postSerialized({
356
- fetch: fetchImpl,
357
- url,
358
- body: { payload },
359
- headers: buildHeaders(),
360
- timeoutMs: cfg?.timeoutMs,
361
- serializer: cfg.serializer,
362
- onRequest: cfg?.onRequest,
363
- contextHeaderText: buildContextHeader()
364
- });
365
- try {
366
- assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
367
- } catch (e) {
368
- const te = e;
369
- if (cfg.errorRegistry && te.id && te.data) {
370
- const helper = cfg.errorRegistry.get(String(te.id));
371
- if (helper) helper.throw(te.data);
372
- }
373
- throw e;
374
- }
375
- },
376
- async eventWithResult(id2, payload) {
377
- const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
378
- const r2 = await postSerialized({
379
- fetch: fetchImpl,
380
- url,
381
- body: { payload, returnPayload: true },
382
- headers: buildHeaders(),
383
- timeoutMs: cfg?.timeoutMs,
384
- serializer: cfg.serializer,
385
- onRequest: cfg?.onRequest,
386
- contextHeaderText: buildContextHeader()
387
- });
388
- if (r2 && typeof r2 === "object" && r2.ok && !("result" in r2)) {
389
- throw new TunnelError(
390
- "INVALID_RESPONSE",
391
- "Tunnel event returnPayload requested but server did not include result. Upgrade the exposure server."
392
- );
393
- }
394
- try {
395
- return assertOkEnvelope(r2, {
396
- fallbackMessage: "Tunnel event error"
397
- });
398
- } catch (e) {
399
- const te = e;
400
- if (cfg.errorRegistry && te.id && te.data) {
401
- const helper = cfg.errorRegistry.get(String(te.id));
402
- if (helper) helper.throw(te.data);
403
- }
404
- throw e;
405
- }
406
- }
407
- };
408
- }
409
- var init_http_fetch_tunnel_resource = __esm({
410
- "src/http-fetch-tunnel.resource.ts"() {
411
- init_protocol();
412
- init_error_utils();
413
- __name(postSerialized, "postSerialized");
414
- __name(createExposureFetch, "createExposureFetch");
415
- }
416
- });
417
-
418
- // src/node/upload/manifest.ts
419
- function buildNodeManifest(input) {
420
- const files = [];
421
- function visit(value) {
422
- if (!value || typeof value !== "object") return value;
423
- const potentialFile = value;
424
- if (potentialFile.$runnerFile === "File" && typeof potentialFile.id === "string") {
425
- const id2 = potentialFile.id;
426
- const meta = potentialFile.meta;
427
- const local = potentialFile._node;
428
- if (local?.buffer) {
429
- files.push({
430
- id: id2,
431
- meta,
432
- source: { type: "buffer", buffer: local.buffer }
433
- });
434
- } else if (local?.stream) {
435
- files.push({
436
- id: id2,
437
- meta,
438
- source: { type: "stream", stream: local.stream }
439
- });
440
- }
441
- const copy = { $runnerFile: "File", id: id2, meta };
442
- return copy;
443
- }
444
- if (Array.isArray(value)) {
445
- return value.map((x) => visit(x));
446
- }
447
- const out = {};
448
- const obj = value;
449
- for (const k of Object.keys(obj)) {
450
- out[k] = visit(obj[k]);
451
- }
452
- return out;
453
- }
454
- __name(visit, "visit");
455
- const cloned = visit(input);
456
- return { input: cloned, files };
457
- }
458
- var init_manifest = __esm({
459
- "src/node/upload/manifest.ts"() {
460
- __name(buildNodeManifest, "buildNodeManifest");
461
- }
462
- });
463
-
464
- // src/node/http/http-smart-client.model.ts
465
- var http_smart_client_model_exports = {};
466
- __export(http_smart_client_model_exports, {
467
- createHttpSmartClient: () => createHttpSmartClient
468
- });
469
- function isReadable(value) {
470
- return !!value && typeof value.pipe === "function";
471
- }
472
- function hasNodeFile(value) {
473
- const isNodeFileSentinel = /* @__PURE__ */ __name((v) => {
474
- if (!v || typeof v !== "object") return false;
475
- const rec = v;
476
- if (rec.$runnerFile !== "File") return false;
477
- if (typeof rec.id !== "string") return false;
478
- const node = rec._node;
479
- if (!node || typeof node !== "object") return false;
480
- const n = node;
481
- return Boolean(n.stream || n.buffer);
482
- }, "isNodeFileSentinel");
483
- const visit = /* @__PURE__ */ __name((v) => {
484
- if (isNodeFileSentinel(v)) return true;
485
- if (!v || typeof v !== "object") return false;
486
- if (Array.isArray(v)) return v.some(visit);
487
- for (const k of Object.keys(v)) {
488
- if (visit(v[k])) return true;
489
- }
490
- return false;
491
- }, "visit");
492
- return visit(value);
493
- }
494
- function toHeaders2(auth) {
495
- const headers = {};
496
- if (auth?.token)
497
- headers[(auth.header ?? "x-runner-token").toLowerCase()] = auth.token;
498
- return headers;
499
- }
500
- function requestLib(url) {
501
- return url.protocol === "https:" ? https : http2;
502
- }
503
- async function postJson(cfg, url, body) {
504
- const serializer3 = cfg.serializer;
505
- const parsed = new URL(url);
506
- const lib = requestLib(parsed);
507
- const headers = {
508
- "content-type": "application/json; charset=utf-8",
509
- ...toHeaders2(cfg.auth)
510
- };
511
- if (cfg.contexts && cfg.contexts.length > 0) {
512
- const map = {};
513
- for (const ctx of cfg.contexts) {
514
- try {
515
- const v = ctx.use();
516
- map[ctx.id] = ctx.serialize(v);
517
- } catch {
518
- }
519
- }
520
- if (Object.keys(map).length > 0) {
521
- headers["x-runner-context"] = cfg.serializer.stringify(map);
522
- }
523
- }
524
- if (cfg.onRequest) await cfg.onRequest({ url, headers });
525
- return await new Promise((resolve, reject) => {
526
- const req = lib.request(
527
- {
528
- method: "POST",
529
- protocol: parsed.protocol,
530
- hostname: parsed.hostname,
531
- port: parsed.port,
532
- path: parsed.pathname + parsed.search,
533
- headers,
534
- timeout: cfg.timeoutMs
535
- },
536
- (res) => {
537
- const chunks = [];
538
- res.on("data", (c) => {
539
- chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(String(c)));
540
- });
541
- res.on("end", () => {
542
- const text = Buffer.concat(chunks).toString(
543
- "utf8"
544
- );
545
- const json2 = text ? serializer3.parse(text) : void 0;
546
- resolve(json2);
547
- });
548
- }
549
- );
550
- req.on("error", reject);
551
- req.write(serializer3.stringify(body));
552
- req.end();
553
- });
554
- }
555
- function escapeHeaderValue(value) {
556
- return value.replace(/"/g, '\\"');
557
- }
558
- function encodeMultipart(manifestText, files, boundary) {
559
- async function* gen() {
560
- const CRLF = "\r\n";
561
- const boundaryLine = `--${boundary}`;
562
- const partHeader = /* @__PURE__ */ __name((name, options) => {
563
- const h = [boundaryLine + CRLF];
564
- const cd = [
565
- `Content-Disposition: form-data; name="${escapeHeaderValue(name)}"`
566
- ];
567
- if (options?.filename) {
568
- cd.push(`; filename="${escapeHeaderValue(options.filename)}"`);
569
- }
570
- h.push(cd.join("") + CRLF);
571
- if (options?.headers) {
572
- for (const k of Object.keys(options.headers)) {
573
- h.push(`${k}: ${options.headers[k]}` + CRLF);
574
- }
575
- }
576
- h.push(CRLF);
577
- return Buffer.from(h.join(""), "utf8");
578
- }, "partHeader");
579
- yield partHeader("__manifest");
580
- yield Buffer.from(manifestText, "utf8");
581
- yield Buffer.from(CRLF, "utf8");
582
- for (const entry of files) {
583
- const filename = entry.meta?.name ?? "upload";
584
- const contentType = entry.meta?.type ?? "application/octet-stream";
585
- const headers = {
586
- "Content-Type": contentType
587
- };
588
- yield partHeader(`file:${entry.id}`, { headers, filename });
589
- if (entry.source.type === "buffer") {
590
- yield entry.source.buffer;
591
- } else {
592
- for await (const chunk of entry.source.stream) {
593
- yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
594
- }
595
- }
596
- yield Buffer.from(CRLF, "utf8");
597
- }
598
- yield Buffer.from(boundaryLine + "--" + CRLF, "utf8");
599
- }
600
- __name(gen, "gen");
601
- return Readable.from(gen());
602
- }
603
- async function postMultipart(cfg, url, manifestText, files) {
604
- const parsed = new URL(url);
605
- const lib = requestLib(parsed);
606
- const boundary = `runner-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
607
- const body = encodeMultipart(manifestText, files, boundary);
608
- const headers = {
609
- "content-type": `multipart/form-data; boundary=${boundary}`,
610
- ...toHeaders2(cfg.auth)
611
- };
612
- if (cfg.contexts && cfg.contexts.length > 0) {
613
- const map = {};
614
- for (const ctx of cfg.contexts) {
615
- try {
616
- const v = ctx.use();
617
- map[ctx.id] = ctx.serialize(v);
618
- } catch {
619
- }
620
- }
621
- if (Object.keys(map).length > 0) {
622
- headers["x-runner-context"] = cfg.serializer.stringify(map);
623
- }
624
- }
625
- if (cfg.onRequest) await cfg.onRequest({ url, headers });
626
- return await new Promise(
627
- (resolve, reject) => {
628
- const req = lib.request(
629
- {
630
- method: "POST",
631
- protocol: parsed.protocol,
632
- hostname: parsed.hostname,
633
- port: parsed.port,
634
- path: parsed.pathname + parsed.search,
635
- headers,
636
- timeout: cfg.timeoutMs
637
- },
638
- (res) => resolve({ stream: res, res })
639
- );
640
- req.on("error", reject);
641
- body.on("error", (e) => req.destroy(e));
642
- body.pipe(req);
643
- }
644
- );
645
- }
646
- async function postOctetStream(cfg, url, stream) {
647
- const parsed = new URL(url);
648
- const lib = requestLib(parsed);
649
- const headers = {
650
- "content-type": "application/octet-stream",
651
- ...toHeaders2(cfg.auth)
652
- };
653
- if (cfg.contexts && cfg.contexts.length > 0) {
654
- const map = {};
655
- for (const ctx of cfg.contexts) {
656
- try {
657
- const v = ctx.use();
658
- map[ctx.id] = ctx.serialize(v);
659
- } catch {
660
- }
661
- }
662
- if (Object.keys(map).length > 0) {
663
- headers["x-runner-context"] = cfg.serializer.stringify(map);
664
- }
665
- }
666
- if (cfg.onRequest) await cfg.onRequest({ url, headers });
667
- return await new Promise(
668
- (resolve, reject) => {
669
- let settled = false;
670
- const cleanup = [];
671
- const resolveOnce = /* @__PURE__ */ __name((value) => {
672
- settled = true;
673
- cleanup.forEach((fn) => fn());
674
- resolve(value);
675
- }, "resolveOnce");
676
- const rejectOnce = /* @__PURE__ */ __name((error2) => {
677
- settled = true;
678
- cleanup.forEach((fn) => fn());
679
- reject(error2 instanceof Error ? error2 : new Error(String(error2)));
680
- }, "rejectOnce");
681
- const req = lib.request(
682
- {
683
- method: "POST",
684
- protocol: parsed.protocol,
685
- hostname: parsed.hostname,
686
- port: parsed.port,
687
- path: parsed.pathname + parsed.search,
688
- headers,
689
- timeout: cfg.timeoutMs
690
- },
691
- (res) => {
692
- setImmediate(() => {
693
- if (!settled)
694
- resolveOnce({ stream: res, res });
695
- });
696
- }
697
- );
698
- const onReqError = /* @__PURE__ */ __name((e) => rejectOnce(e), "onReqError");
699
- req.on("error", onReqError);
700
- cleanup.push(() => req.removeListener("error", onReqError));
701
- const onPipelineDone = /* @__PURE__ */ __name((err) => {
702
- if (err) rejectOnce(err);
703
- }, "onPipelineDone");
704
- pipeline(stream, req, onPipelineDone);
705
- }
706
- );
707
- }
708
- function parseMaybeJsonResponse(res, serializer3) {
709
- const contentType = String(res.headers["content-type"]);
710
- if (/^application\/json/i.test(contentType)) {
711
- const chunks = [];
712
- return new Promise((resolve, reject) => {
713
- res.on("data", (c) => {
714
- chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(String(c)));
715
- });
716
- res.on("end", () => {
717
- try {
718
- const text = Buffer.concat(chunks).toString(
719
- "utf8"
720
- );
721
- const json2 = text ? serializer3.parse(text) : void 0;
722
- resolve(json2);
723
- } catch (e) {
724
- reject(e);
725
- }
726
- });
727
- res.on("error", reject);
728
- });
729
- }
730
- return Promise.resolve(res);
731
- }
732
- function rethrowTyped(registry, error2) {
733
- if (registry && error2 && typeof error2 === "object") {
734
- const err = error2;
735
- if (err.id && err.data) {
736
- const helper = registry.get(String(err.id));
737
- if (helper) helper.throw(err.data);
738
- }
739
- }
740
- throw error2;
741
- }
742
- function createHttpSmartClient(cfg) {
743
- const baseUrl = cfg.baseUrl.replace(/\/$/, "");
744
- if (!baseUrl) throw new Error("createHttpSmartClient requires baseUrl");
745
- const serializer3 = cfg.serializer;
746
- return {
747
- async task(id2, input) {
748
- const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
749
- if (isReadable(input)) {
750
- const { res } = await postOctetStream(cfg, url, input);
751
- return res;
752
- }
753
- if (hasNodeFile(input)) {
754
- const manifest = buildNodeManifest(input);
755
- const manifestText = serializer3.stringify({
756
- input: manifest.input
757
- });
758
- try {
759
- const { res } = await postMultipart(
760
- cfg,
761
- url,
762
- manifestText,
763
- manifest.files
764
- );
765
- const maybe = await parseMaybeJsonResponse(
766
- res,
767
- serializer3
768
- );
769
- if (isReadable(maybe)) return maybe;
770
- return assertOkEnvelope(maybe, {
771
- fallbackMessage: "Tunnel task error"
772
- });
773
- } catch (error2) {
774
- rethrowTyped(cfg.errorRegistry, error2);
775
- }
776
- }
777
- try {
778
- const r2 = await postJson(cfg, url, { input });
779
- return assertOkEnvelope(r2, {
780
- fallbackMessage: "Tunnel task error"
781
- });
782
- } catch (error2) {
783
- rethrowTyped(cfg.errorRegistry, error2);
784
- }
785
- },
786
- async event(id2, payload) {
787
- const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
788
- try {
789
- const r2 = await postJson(cfg, url, { payload });
790
- assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
791
- } catch (error2) {
792
- rethrowTyped(cfg.errorRegistry, error2);
793
- }
794
- },
795
- async eventWithResult(id2, payload) {
796
- const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
797
- try {
798
- const r2 = await postJson(cfg, url, {
799
- payload,
800
- returnPayload: true
801
- });
802
- if (r2 && typeof r2 === "object" && r2.ok && !("result" in r2)) {
803
- throw new TunnelError(
804
- "INVALID_RESPONSE",
805
- "Tunnel event returnPayload requested but server did not include result. Upgrade the exposure server."
806
- );
807
- }
808
- return assertOkEnvelope(r2, {
809
- fallbackMessage: "Tunnel event error"
810
- });
811
- } catch (error2) {
812
- rethrowTyped(cfg.errorRegistry, error2);
813
- }
814
- }
815
- };
816
- }
817
- var init_http_smart_client_model = __esm({
818
- "src/node/http/http-smart-client.model.ts"() {
819
- init_protocol();
820
- init_manifest();
821
- __name(isReadable, "isReadable");
822
- __name(hasNodeFile, "hasNodeFile");
823
- __name(toHeaders2, "toHeaders");
824
- __name(requestLib, "requestLib");
825
- __name(postJson, "postJson");
826
- __name(escapeHeaderValue, "escapeHeaderValue");
827
- __name(encodeMultipart, "encodeMultipart");
828
- __name(postMultipart, "postMultipart");
829
- __name(postOctetStream, "postOctetStream");
830
- __name(parseMaybeJsonResponse, "parseMaybeJsonResponse");
831
- __name(rethrowTyped, "rethrowTyped");
832
- __name(createHttpSmartClient, "createHttpSmartClient");
833
- }
834
- });
835
-
836
- // src/node/http/http-mixed-client.ts
837
- var http_mixed_client_exports = {};
838
- __export(http_mixed_client_exports, {
839
- createHttpMixedClient: () => createHttpMixedClient
840
- });
841
- function isReadable2(value) {
842
- return !!value && typeof value.pipe === "function";
843
- }
844
- function hasNodeFile2(value) {
845
- const isNodeFileSentinel = /* @__PURE__ */ __name((v) => {
846
- if (!v || typeof v !== "object") return false;
847
- const rec = v;
848
- if (rec.$runnerFile !== "File") return false;
849
- if (typeof rec.id !== "string") return false;
850
- const node = rec._node;
851
- if (!node || typeof node !== "object") return false;
852
- const n = node;
853
- return Boolean(n.stream || n.buffer);
854
- }, "isNodeFileSentinel");
855
- const visit = /* @__PURE__ */ __name((v) => {
856
- if (isNodeFileSentinel(v)) return true;
857
- if (!v || typeof v !== "object") return false;
858
- if (Array.isArray(v)) return v.some(visit);
859
- for (const k of Object.keys(v)) {
860
- if (visit(v[k])) return true;
861
- }
862
- return false;
863
- }, "visit");
864
- return visit(value);
865
- }
866
- async function shouldForceSmart(cfg, id2, input) {
867
- if (!cfg.forceSmart) return false;
868
- if (cfg.forceSmart === true) return true;
869
- return await cfg.forceSmart({ id: id2, input });
870
- }
871
- function createHttpMixedClient(cfg) {
872
- const baseUrl = cfg.baseUrl?.replace(/\/$/, "");
873
- if (!baseUrl) throw new Error("createMixedHttpClient requires baseUrl");
874
- const fetchClient = createExposureFetch({
875
- baseUrl,
876
- auth: cfg.auth,
877
- timeoutMs: cfg.timeoutMs,
878
- fetchImpl: cfg.fetchImpl,
879
- serializer: cfg.serializer,
880
- onRequest: cfg.onRequest,
881
- contexts: cfg.contexts,
882
- errorRegistry: cfg.errorRegistry
883
- });
884
- const smartClient = createHttpSmartClient({
885
- baseUrl,
886
- auth: cfg.auth,
887
- timeoutMs: cfg.timeoutMs,
888
- serializer: cfg.serializer,
889
- onRequest: cfg.onRequest,
890
- contexts: cfg.contexts,
891
- errorRegistry: cfg.errorRegistry
892
- });
893
- return {
894
- async task(id2, input) {
895
- if (isReadable2(input) || hasNodeFile2(input) || await shouldForceSmart(cfg, id2, input)) {
896
- return await smartClient.task(id2, input);
897
- }
898
- return await fetchClient.task(id2, input);
899
- },
900
- async event(id2, payload) {
901
- return await fetchClient.event(id2, payload);
902
- },
903
- async eventWithResult(id2, payload) {
904
- if (!fetchClient.eventWithResult) {
905
- throw new Error(
906
- "createHttpMixedClient: eventWithResult not available on underlying tunnel client."
907
- );
908
- }
909
- return await fetchClient.eventWithResult(id2, payload);
910
- }
911
- };
912
- }
913
- var init_http_mixed_client = __esm({
914
- "src/node/http/http-mixed-client.ts"() {
915
- init_http_fetch_tunnel_resource();
916
- init_http_smart_client_model();
917
- __name(isReadable2, "isReadable");
918
- __name(hasNodeFile2, "hasNodeFile");
919
- __name(shouldForceSmart, "shouldForceSmart");
920
- __name(createHttpMixedClient, "createHttpMixedClient");
921
- }
922
- });
923
47
 
924
48
  // node_modules/ms/index.js
925
49
  var require_ms = __commonJS({
@@ -28596,7 +27720,6 @@ var symbolResourceWithConfig = Symbol.for(
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,228 +27768,6 @@ 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
- symbolForkedFrom: () => symbolForkedFrom,
28661
- symbolHook: () => symbolHook,
28662
- symbolMiddleware: () => symbolMiddleware,
28663
- symbolMiddlewareConfigured: () => symbolMiddlewareConfigured,
28664
- symbolOptionalDependency: () => symbolOptionalDependency,
28665
- symbolPhantomTask: () => symbolPhantomTask,
28666
- symbolResource: () => symbolResource,
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
28871
27772
  var isValidHttpCode = /* @__PURE__ */ __name((value) => Number.isInteger(value) && value >= 100 && value <= 599, "isValidHttpCode");
28872
27773
  var assertHttpCode = /* @__PURE__ */ __name((value) => {
@@ -29204,20 +28105,67 @@ var EdgePlatformAdapter = class extends BrowserPlatformAdapter {
29204
28105
  constructor() {
29205
28106
  super(...arguments);
29206
28107
  this.id = "edge";
28108
+ this.alsClass = null;
28109
+ this.alsProbed = false;
29207
28110
  }
29208
28111
  static {
29209
28112
  __name(this, "EdgePlatformAdapter");
29210
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
+ }
29211
28146
  onShutdownSignal(_handler) {
29212
28147
  return () => {
29213
28148
  };
29214
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
+ }
29215
28161
  };
29216
28162
 
29217
28163
  // src/platform/adapters/universal-generic.ts
29218
28164
  var GenericUniversalPlatformAdapter = class {
29219
28165
  constructor() {
29220
28166
  this.id = "universal";
28167
+ this.alsClass = null;
28168
+ this.alsProbed = false;
29221
28169
  this.setTimeout = globalThis.setTimeout;
29222
28170
  this.clearTimeout = globalThis.clearTimeout;
29223
28171
  }
@@ -29226,6 +28174,23 @@ var GenericUniversalPlatformAdapter = class {
29226
28174
  }
29227
28175
  async init() {
29228
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
+ }
29229
28194
  onUncaughtException(handler) {
29230
28195
  const tgt = globalThis;
29231
28196
  if (tgt.addEventListener) {
@@ -29280,9 +28245,14 @@ var GenericUniversalPlatformAdapter = class {
29280
28245
  return void 0;
29281
28246
  }
29282
28247
  hasAsyncLocalStorage() {
29283
- return false;
28248
+ this.probeAsyncLocalStorage();
28249
+ return this.alsClass !== null;
29284
28250
  }
29285
28251
  createAsyncLocalStorage() {
28252
+ this.probeAsyncLocalStorage();
28253
+ if (this.alsClass) {
28254
+ return new this.alsClass();
28255
+ }
29286
28256
  return {
29287
28257
  getStore: /* @__PURE__ */ __name(() => {
29288
28258
  platformUnsupportedFunctionError.throw({
@@ -29340,6 +28310,10 @@ var UniversalPlatformAdapter = class {
29340
28310
  if (this.inner) return;
29341
28311
  const kind = detectEnvironment();
29342
28312
  const global2 = globalThis;
28313
+ if (typeof global2.Deno !== "undefined") {
28314
+ this.inner = new GenericUniversalPlatformAdapter();
28315
+ return;
28316
+ }
29343
28317
  if (typeof global2.document !== "undefined" || typeof global2.addEventListener === "function") {
29344
28318
  this.inner = new BrowserPlatformAdapter();
29345
28319
  } else {
@@ -29408,63 +28382,6 @@ function getPlatform() {
29408
28382
  return platformInstance;
29409
28383
  }
29410
28384
  __name(getPlatform, "getPlatform");
29411
- function setPlatform(adapter) {
29412
- platformInstance = adapter;
29413
- adapter.id;
29414
- }
29415
- __name(setPlatform, "setPlatform");
29416
- var PlatformAdapter = class {
29417
- static {
29418
- __name(this, "PlatformAdapter");
29419
- }
29420
- constructor(env) {
29421
- const kind = env ?? detectEnvironment();
29422
- this.env = kind;
29423
- switch (kind) {
29424
- case "node":
29425
- this.inner = new NodePlatformAdapter();
29426
- break;
29427
- case "browser":
29428
- this.inner = new BrowserPlatformAdapter();
29429
- break;
29430
- case "edge":
29431
- this.inner = new EdgePlatformAdapter();
29432
- break;
29433
- case "universal":
29434
- this.inner = new GenericUniversalPlatformAdapter();
29435
- break;
29436
- default:
29437
- this.inner = new UniversalPlatformAdapter();
29438
- }
29439
- this.id = this.inner.id;
29440
- this.setTimeout = this.inner.setTimeout;
29441
- this.clearTimeout = this.inner.clearTimeout;
29442
- }
29443
- async init() {
29444
- return this.inner.init();
29445
- }
29446
- onUncaughtException(handler) {
29447
- return this.inner.onUncaughtException(handler);
29448
- }
29449
- onUnhandledRejection(handler) {
29450
- return this.inner.onUnhandledRejection(handler);
29451
- }
29452
- onShutdownSignal(handler) {
29453
- return this.inner.onShutdownSignal(handler);
29454
- }
29455
- exit(code) {
29456
- return this.inner.exit(code);
29457
- }
29458
- getEnv(key) {
29459
- return this.inner.getEnv(key);
29460
- }
29461
- hasAsyncLocalStorage() {
29462
- return this.inner.hasAsyncLocalStorage();
29463
- }
29464
- createAsyncLocalStorage() {
29465
- return this.inner.createAsyncLocalStorage();
29466
- }
29467
- };
29468
28385
 
29469
28386
  // src/errors.ts
29470
28387
  var duplicateRegistrationError = error("runner.errors.duplicateRegistration").format(
@@ -29513,7 +28430,7 @@ var eventNotFoundError = error(
29513
28430
  ).remediation(
29514
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().`
29515
28432
  ).build();
29516
- var resourceNotFoundError = error(
28433
+ error(
29517
28434
  "runner.errors.resourceNotFound"
29518
28435
  ).format(
29519
28436
  ({ id: id2 }) => `Resource "${id2.toString()}" not found. Did you forget to register it or are you using the correct id?`
@@ -29601,10 +28518,145 @@ var builderIncompleteError = error("runner.errors.builderIncomplete").format(({
29601
28518
  }).remediation(
29602
28519
  ({ missingFields }) => `Add the missing builder steps: ${missingFields.map((f) => `.${f}()`).join(", ")} before calling .build().`
29603
28520
  ).build();
29604
- function isCancellationError(err) {
29605
- return cancellationError.is(err);
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
+ };
28631
+ }
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
+ };
29606
28658
  }
29607
- __name(isCancellationError, "isCancellationError");
28659
+ __name(defineHook, "defineHook");
29608
28660
 
29609
28661
  // src/definers/resourceFork.ts
29610
28662
  function resolveReId(forkId, options) {
@@ -30099,12 +29151,6 @@ var SymbolPolicy = /* @__PURE__ */ ((SymbolPolicy2) => {
30099
29151
  SymbolPolicy2["Disabled"] = "Disabled";
30100
29152
  return SymbolPolicy2;
30101
29153
  })(SymbolPolicy || {});
30102
- var SymbolPolicyErrorMessage = /* @__PURE__ */ ((SymbolPolicyErrorMessage2) => {
30103
- SymbolPolicyErrorMessage2["GlobalSymbolsNotAllowed"] = "Global symbols are not allowed";
30104
- SymbolPolicyErrorMessage2["SymbolsNotAllowed"] = "Symbols are not allowed";
30105
- SymbolPolicyErrorMessage2["UnsupportedSymbolPolicy"] = "Unsupported symbol policy";
30106
- return SymbolPolicyErrorMessage2;
30107
- })(SymbolPolicyErrorMessage || {});
30108
29154
 
30109
29155
  // src/serializer/binary-builtins.ts
30110
29156
  var INVALID_PAYLOAD_MESSAGE_PREFIX = "Invalid";
@@ -30612,8 +29658,124 @@ var builtInTypes = [
30612
29658
  ...binaryBuiltInTypes
30613
29659
  ];
30614
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
+
30615
29778
  // src/serializer/type-registry.ts
30616
- init_regexp_validator();
30617
29779
  var TypeRegistry = class {
30618
29780
  constructor(options) {
30619
29781
  this.typeRegistry = /* @__PURE__ */ new Map();
@@ -31372,29 +30534,25 @@ var Serializer = class {
31372
30534
  * @internal - Exposed for testing RegExp safety validation
31373
30535
  */
31374
30536
  this.isRegExpPatternSafe = /* @__PURE__ */ __name((pattern) => {
31375
- const { isRegExpPatternSafe: check } = (init_regexp_validator(), __toCommonJS(regexp_validator_exports));
31376
- return check(pattern);
30537
+ return isRegExpPatternSafe(pattern);
31377
30538
  }, "isRegExpPatternSafe");
31378
30539
  /**
31379
30540
  * @internal - Exposed for testing quantifier detection
31380
30541
  */
31381
30542
  this.isQuantifierAt = /* @__PURE__ */ __name((pattern, index) => {
31382
- const { isQuantifierAt: check } = (init_regexp_validator(), __toCommonJS(regexp_validator_exports));
31383
- return check(pattern, index);
30543
+ return isQuantifierAt(pattern, index);
31384
30544
  }, "isQuantifierAt");
31385
30545
  /**
31386
30546
  * @internal - Exposed for testing quantifier character detection
31387
30547
  */
31388
30548
  this.isQuantifierChar = /* @__PURE__ */ __name((char, pattern, index) => {
31389
- const { isQuantifierChar: check } = (init_regexp_validator(), __toCommonJS(regexp_validator_exports));
31390
- return check(char, pattern, index);
30549
+ return isQuantifierChar(char, pattern, index);
31391
30550
  }, "isQuantifierChar");
31392
30551
  /**
31393
30552
  * @internal - Exposed for testing bounded quantifier detection
31394
30553
  */
31395
30554
  this.isBoundedQuantifier = /* @__PURE__ */ __name((pattern, index) => {
31396
- const { isBoundedQuantifier: check } = (init_regexp_validator(), __toCommonJS(regexp_validator_exports));
31397
- return check(pattern, index);
30555
+ return isBoundedQuantifier(pattern, index);
31398
30556
  }, "isBoundedQuantifier");
31399
30557
  this.indent = options.pretty ? 2 : void 0;
31400
30558
  this.maxDepth = normalizeMaxDepth(options.maxDepth, DEFAULT_MAX_DEPTH);
@@ -31597,11 +30755,6 @@ function defineAsyncContext(def, filePath) {
31597
30755
  return api;
31598
30756
  }
31599
30757
  __name(defineAsyncContext, "defineAsyncContext");
31600
- function createContext(name) {
31601
- const id2 = name ?? `context.${Math.random().toString(36).slice(2)}.${Date.now()}`;
31602
- return defineAsyncContext({ id: id2 });
31603
- }
31604
- __name(createContext, "createContext");
31605
30758
 
31606
30759
  // src/globals/resources/debug/debug.tag.ts
31607
30760
  var debugTag = defineTag({
@@ -33091,11 +32244,218 @@ var queueResource = defineResource({
33091
32244
  }
33092
32245
  });
33093
32246
 
33094
- // src/http-client.ts
33095
- init_protocol();
33096
- 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");
33097
32308
 
33098
- // 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
33099
32459
  function buildUniversalManifest(input) {
33100
32460
  const nodeFiles = [];
33101
32461
  const webFiles = [];
@@ -33152,6 +32512,15 @@ function toHeaders(auth) {
33152
32512
  return headers;
33153
32513
  }
33154
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");
33155
32524
  function createHttpClient(cfg) {
33156
32525
  const baseUrl = cfg.baseUrl.replace(/\/$/, "");
33157
32526
  if (!baseUrl) throw new Error("createHttpClient requires baseUrl");
@@ -33218,12 +32587,7 @@ function createHttpClient(cfg) {
33218
32587
  fallbackMessage: "Tunnel task error"
33219
32588
  });
33220
32589
  } catch (e) {
33221
- const te = e;
33222
- if (cfg.errorRegistry && te.id && te.data) {
33223
- const helper = cfg.errorRegistry.get(String(te.id));
33224
- if (helper) helper.throw(te.data);
33225
- }
33226
- throw e;
32590
+ rethrowWithRegistry(e, cfg.errorRegistry);
33227
32591
  }
33228
32592
  }
33229
32593
  if (manifest.nodeFiles.length > 0) {
@@ -33234,24 +32598,14 @@ function createHttpClient(cfg) {
33234
32598
  try {
33235
32599
  return await fetchClient.task(id2, input);
33236
32600
  } catch (e) {
33237
- const te = e;
33238
- if (cfg.errorRegistry && te.id && te.data) {
33239
- const helper = cfg.errorRegistry.get(String(te.id));
33240
- if (helper) helper.throw(te.data);
33241
- }
33242
- throw e;
32601
+ rethrowWithRegistry(e, cfg.errorRegistry);
33243
32602
  }
33244
32603
  },
33245
32604
  async event(id2, payload) {
33246
32605
  try {
33247
32606
  return await fetchClient.event(id2, payload);
33248
32607
  } catch (e) {
33249
- const te = e;
33250
- if (cfg.errorRegistry && te.id && te.data) {
33251
- const helper = cfg.errorRegistry.get(String(te.id));
33252
- if (helper) helper.throw(te.data);
33253
- }
33254
- throw e;
32608
+ rethrowWithRegistry(e, cfg.errorRegistry);
33255
32609
  }
33256
32610
  },
33257
32611
  async eventWithResult(id2, payload) {
@@ -33263,12 +32617,7 @@ function createHttpClient(cfg) {
33263
32617
  }
33264
32618
  return await fetchClient.eventWithResult(id2, payload);
33265
32619
  } catch (e) {
33266
- const te = e;
33267
- if (cfg.errorRegistry && te.id && te.data) {
33268
- const helper = cfg.errorRegistry.get(String(te.id));
33269
- if (helper) helper.throw(te.data);
33270
- }
33271
- throw e;
32620
+ rethrowWithRegistry(e, cfg.errorRegistry);
33272
32621
  }
33273
32622
  }
33274
32623
  };
@@ -34202,6 +33551,34 @@ var Logger = class _Logger {
34202
33551
  }
34203
33552
  };
34204
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
+
34205
33582
  // src/models/DependencyProcessor.ts
34206
33583
  var DependencyProcessor = class {
34207
33584
  constructor(store2, eventManager, taskRunner, logger) {
@@ -34309,7 +33686,16 @@ var DependencyProcessor = class {
34309
33686
  }
34310
33687
  throw error2;
34311
33688
  }
34312
- 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;
34313
33699
  }
34314
33700
  /**
34315
33701
  * Computes and caches dependencies for a resource (if not already computed).
@@ -34452,46 +33838,35 @@ var DependencyProcessor = class {
34452
33838
  return object;
34453
33839
  }
34454
33840
  async extractDependency(object, source) {
34455
- 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;
34456
33846
  if (isOptional(object)) {
34457
- const inner = object.inner;
34458
- if (isResource(inner)) {
34459
- const exists = this.store.resources.get(inner.id) !== void 0;
34460
- return exists ? this.extractResourceDependency(inner) : void 0;
34461
- } else if (isTask(inner)) {
34462
- const exists = this.store.tasks.get(inner.id) !== void 0;
34463
- return exists ? this.extractTaskDependency(inner) : void 0;
34464
- } else if (isEvent(inner)) {
34465
- const exists = this.store.events.get(inner.id) !== void 0;
34466
- return exists ? this.extractEventDependency(inner, source) : void 0;
34467
- } else if (isError(inner)) {
34468
- const exists = this.store.errors.get(inner.id) !== void 0;
34469
- return exists ? inner : void 0;
34470
- } else if (isAsyncContext(inner)) {
34471
- const exists = this.store.asyncContexts.get(inner.id) !== void 0;
34472
- return exists ? inner : void 0;
34473
- }
34474
- unknownItemTypeError.throw({ item: inner });
34475
- }
34476
- if (isResource(object)) {
34477
- return this.extractResourceDependency(object);
34478
- } else if (isTask(object)) {
34479
- return this.extractTaskDependency(object);
34480
- } else if (isEvent(object)) {
34481
- return this.extractEventDependency(object, source);
34482
- } else if (isError(object)) {
34483
- if (this.store.errors.get(object.id) === void 0) {
34484
- dependencyNotFoundError.throw({ key: `Error ${object.id}` });
34485
- }
34486
- return object;
34487
- } else if (isAsyncContext(object)) {
34488
- if (this.store.asyncContexts.get(object.id) === void 0) {
34489
- dependencyNotFoundError.throw({ key: `AsyncContext ${object.id}` });
34490
- }
34491
- return object;
34492
- } else {
34493
- 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 });
34494
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;
34495
33870
  }
34496
33871
  /**
34497
33872
  * Converts the event into a running functions with real inputs
@@ -34688,19 +34063,246 @@ var StoreValidator = class {
34688
34063
  }
34689
34064
  };
34690
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
+
34691
34289
  // src/models/StoreRegistry.ts
34692
34290
  var StoreRegistry = class {
34693
34291
  constructor(store2) {
34694
34292
  this.store = store2;
34695
- this.tasks = /* @__PURE__ */ new Map();
34696
- this.resources = /* @__PURE__ */ new Map();
34697
- this.events = /* @__PURE__ */ new Map();
34698
- this.taskMiddlewares = /* @__PURE__ */ new Map();
34699
- this.resourceMiddlewares = /* @__PURE__ */ new Map();
34700
- this.hooks = /* @__PURE__ */ new Map();
34701
- this.tags = /* @__PURE__ */ new Map();
34702
- this.asyncContexts = /* @__PURE__ */ new Map();
34703
- 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");
34704
34306
  this.validator = new StoreValidator(this);
34705
34307
  }
34706
34308
  static {
@@ -34709,6 +34311,18 @@ var StoreRegistry = class {
34709
34311
  getValidator() {
34710
34312
  return this.validator;
34711
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
+ }
34712
34326
  storeGenericItem(item) {
34713
34327
  if (isTask(item)) {
34714
34328
  this.storeTask(item);
@@ -34845,195 +34459,14 @@ var StoreRegistry = class {
34845
34459
  }
34846
34460
  // Feels like a dependencyProcessor task?
34847
34461
  getDependentNodes() {
34848
- const depenedants = [];
34849
- const nodeMap = /* @__PURE__ */ new Map();
34850
- this.setupBlankNodes(nodeMap, depenedants);
34851
- for (const task2 of this.tasks.values()) {
34852
- const node = nodeMap.get(task2.task.id);
34853
- if (task2.task.dependencies) {
34854
- for (const [depKey, depItem] of Object.entries(
34855
- task2.task.dependencies
34856
- )) {
34857
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34858
- const depNode = nodeMap.get(candidate.id);
34859
- if (depNode) {
34860
- node.dependencies[depKey] = depNode;
34861
- }
34862
- }
34863
- }
34864
- const t = task2.task;
34865
- for (const middleware of t.middleware) {
34866
- const middlewareNode = nodeMap.get(middleware.id);
34867
- if (middlewareNode) {
34868
- node.dependencies[middleware.id] = middlewareNode;
34869
- }
34870
- }
34871
- }
34872
- for (const storeTaskMiddleware of this.taskMiddlewares.values()) {
34873
- const node = nodeMap.get(storeTaskMiddleware.middleware.id);
34874
- const { middleware } = storeTaskMiddleware;
34875
- if (middleware.dependencies) {
34876
- for (const [depKey, depItem] of Object.entries(
34877
- middleware.dependencies
34878
- )) {
34879
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34880
- const depNode = nodeMap.get(candidate.id);
34881
- if (depNode) {
34882
- node.dependencies[depKey] = depNode;
34883
- }
34884
- }
34885
- }
34886
- if (middleware.everywhere) {
34887
- const filter = typeof middleware.everywhere === "function" ? middleware.everywhere : () => true;
34888
- for (const task2 of this.tasks.values()) {
34889
- if (filter(task2.task)) {
34890
- const taskNode = nodeMap.get(task2.task.id);
34891
- taskNode.dependencies[`__middleware.${middleware.id}`] = node;
34892
- }
34893
- }
34894
- }
34895
- }
34896
- for (const storeResourceMiddleware of this.resourceMiddlewares.values()) {
34897
- const node = nodeMap.get(storeResourceMiddleware.middleware.id);
34898
- const { middleware } = storeResourceMiddleware;
34899
- if (middleware.dependencies) {
34900
- for (const [depKey, depItem] of Object.entries(
34901
- middleware.dependencies
34902
- )) {
34903
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34904
- const depNode = nodeMap.get(candidate.id);
34905
- if (depNode) {
34906
- node.dependencies[depKey] = depNode;
34907
- }
34908
- }
34909
- }
34910
- if (middleware.everywhere) {
34911
- const filter = typeof middleware.everywhere === "function" ? middleware.everywhere : () => true;
34912
- for (const resource2 of this.resources.values()) {
34913
- if (filter(resource2.resource)) {
34914
- const resourceNode = nodeMap.get(resource2.resource.id);
34915
- resourceNode.dependencies[`__middleware.${middleware.id}`] = node;
34916
- }
34917
- }
34918
- }
34919
- }
34920
- for (const resource2 of this.resources.values()) {
34921
- const node = nodeMap.get(resource2.resource.id);
34922
- if (resource2.resource.dependencies) {
34923
- for (const [depKey, depItem] of Object.entries(
34924
- resource2.resource.dependencies
34925
- )) {
34926
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34927
- const depNode = nodeMap.get(candidate.id);
34928
- if (depNode) {
34929
- node.dependencies[depKey] = depNode;
34930
- }
34931
- }
34932
- }
34933
- for (const middleware of resource2.resource.middleware) {
34934
- const middlewareNode = nodeMap.get(middleware.id);
34935
- if (middlewareNode) {
34936
- node.dependencies[middleware.id] = middlewareNode;
34937
- }
34938
- }
34939
- }
34940
- for (const hook2 of this.hooks.values()) {
34941
- const node = nodeMap.get(hook2.hook.id);
34942
- if (hook2.hook.dependencies) {
34943
- for (const [depKey, depItem] of Object.entries(
34944
- hook2.hook.dependencies
34945
- )) {
34946
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34947
- const depNode = nodeMap.get(candidate.id);
34948
- if (depNode) {
34949
- node.dependencies[depKey] = depNode;
34950
- }
34951
- }
34952
- }
34953
- }
34954
- return depenedants;
34462
+ return buildDependencyGraph(this);
34955
34463
  }
34956
34464
  /**
34957
34465
  * Builds a directed graph of event emissions based on hooks listening to events
34958
34466
  * and their dependencies on events (emission capability). Ignores wildcard hooks by default.
34959
34467
  */
34960
34468
  buildEventEmissionGraph() {
34961
- const nodes = /* @__PURE__ */ new Map();
34962
- for (const e of this.events.values()) {
34963
- nodes.set(e.event.id, { id: e.event.id, dependencies: {} });
34964
- }
34965
- for (const h of this.hooks.values()) {
34966
- const listened = [];
34967
- const on = h.hook.on;
34968
- if (on === "*") continue;
34969
- if (Array.isArray(on))
34970
- listened.push(...on.map((e) => e.id));
34971
- else listened.push(on.id);
34972
- const depEvents = [];
34973
- const deps = h.hook.dependencies;
34974
- if (deps) {
34975
- for (const value of Object.values(deps)) {
34976
- const candidate = isOptional(value) ? value.inner : value;
34977
- if (candidate && isEvent(candidate)) {
34978
- depEvents.push(candidate.id);
34979
- }
34980
- }
34981
- }
34982
- for (const srcId of listened) {
34983
- const srcNode = nodes.get(srcId);
34984
- if (!srcNode) continue;
34985
- for (const dstId of depEvents) {
34986
- if (srcId === dstId) continue;
34987
- const dstNode = nodes.get(dstId);
34988
- if (dstNode) {
34989
- srcNode.dependencies[dstId] = dstNode;
34990
- }
34991
- }
34992
- }
34993
- }
34994
- return Array.from(nodes.values());
34995
- }
34996
- setupBlankNodes(nodeMap, depenedants) {
34997
- for (const task2 of this.tasks.values()) {
34998
- const node = {
34999
- id: task2.task.id,
35000
- dependencies: {}
35001
- };
35002
- nodeMap.set(task2.task.id, node);
35003
- depenedants.push(node);
35004
- }
35005
- for (const middleware of this.taskMiddlewares.values()) {
35006
- const node = {
35007
- id: middleware.middleware.id,
35008
- dependencies: {}
35009
- };
35010
- nodeMap.set(middleware.middleware.id, node);
35011
- depenedants.push(node);
35012
- }
35013
- for (const middleware of this.resourceMiddlewares.values()) {
35014
- const node = {
35015
- id: middleware.middleware.id,
35016
- dependencies: {}
35017
- };
35018
- nodeMap.set(middleware.middleware.id, node);
35019
- depenedants.push(node);
35020
- }
35021
- for (const resource2 of this.resources.values()) {
35022
- const node = {
35023
- id: resource2.resource.id,
35024
- dependencies: {}
35025
- };
35026
- nodeMap.set(resource2.resource.id, node);
35027
- depenedants.push(node);
35028
- }
35029
- for (const hook2 of this.hooks.values()) {
35030
- const node = {
35031
- id: hook2.hook.id,
35032
- dependencies: {}
35033
- };
35034
- nodeMap.set(hook2.hook.id, node);
35035
- depenedants.push(node);
35036
- }
34469
+ return buildEventEmissionGraph(this);
35037
34470
  }
35038
34471
  getTasksWithTag(tag2) {
35039
34472
  const tagId = typeof tag2 === "string" ? tag2 : tag2.id;
@@ -35967,6 +35400,63 @@ function detectRunnerMode(explicitMode) {
35967
35400
  }
35968
35401
  __name(detectRunnerMode, "detectRunnerMode");
35969
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
+
35970
35460
  // src/models/Store.ts
35971
35461
  var Store = class {
35972
35462
  constructor(eventManager, logger, onUnhandledError, mode) {
@@ -36031,6 +35521,7 @@ var Store = class {
36031
35521
  }
36032
35522
  lock() {
36033
35523
  this.#isLocked = true;
35524
+ this.registry.lockAll();
36034
35525
  }
36035
35526
  checkLock() {
36036
35527
  if (this.#isLocked) {
@@ -36172,58 +35663,7 @@ var Store = class {
36172
35663
  this.initializedResourceIds.push(resourceId);
36173
35664
  }
36174
35665
  getResourcesInDisposeOrder() {
36175
- const initializedResources = Array.from(this.resources.values()).filter(
36176
- (r2) => r2.isInitialized
36177
- );
36178
- const initOrderHasAllInitialized = this.initializedResourceIds.length === initializedResources.length && initializedResources.every(
36179
- (r2) => this.initializedResourceIds.includes(r2.resource.id)
36180
- );
36181
- if (initOrderHasAllInitialized) {
36182
- const byId = new Map(
36183
- initializedResources.map((r2) => [r2.resource.id, r2])
36184
- );
36185
- return this.initializedResourceIds.slice().reverse().map((id2) => byId.get(id2)).filter((r2) => Boolean(r2));
36186
- }
36187
- const visitState = /* @__PURE__ */ new Map();
36188
- const initOrder = [];
36189
- let cycleDetected = false;
36190
- const getDependencyIds = /* @__PURE__ */ __name((resource2) => {
36191
- const raw = resource2.resource.dependencies;
36192
- if (!raw) return [];
36193
- const deps = raw;
36194
- if (!deps || typeof deps !== "object") return [];
36195
- const out = [];
36196
- const collect = /* @__PURE__ */ __name((value) => {
36197
- if (isOptional(value)) {
36198
- collect(value.inner);
36199
- return;
36200
- }
36201
- if (isResource(value)) {
36202
- out.push(value.id);
36203
- }
36204
- }, "collect");
36205
- Object.values(deps).forEach(collect);
36206
- return out;
36207
- }, "getDependencyIds");
36208
- const visit = /* @__PURE__ */ __name((resourceId) => {
36209
- const state = visitState.get(resourceId);
36210
- if (state === "visited") return;
36211
- if (state === "visiting") {
36212
- cycleDetected = true;
36213
- return;
36214
- }
36215
- const resource2 = this.resources.get(resourceId);
36216
- if (!resource2) return;
36217
- visitState.set(resourceId, "visiting");
36218
- getDependencyIds(resource2).forEach(visit);
36219
- visitState.set(resourceId, "visited");
36220
- initOrder.push(resource2);
36221
- }, "visit");
36222
- initializedResources.forEach((r2) => visit(r2.resource.id));
36223
- if (cycleDetected) {
36224
- return initializedResources.slice().reverse();
36225
- }
36226
- return initOrder.reverse();
35666
+ return getResourcesInDisposeOrder(this.resources, this.initializedResourceIds);
36227
35667
  }
36228
35668
  /**
36229
35669
  * Internal, avoid using this method directly.
@@ -36506,7 +35946,7 @@ var debugResource = defineResource({
36506
35946
  tags: [globalTags.system]
36507
35947
  });
36508
35948
 
36509
- // src/processHooks.ts
35949
+ // src/tools/processShutdownHooks.ts
36510
35950
  var platform2 = getPlatform();
36511
35951
  var activeErrorHandlers = /* @__PURE__ */ new Set();
36512
35952
  var processSafetyNetsInstalled = false;
@@ -36595,13 +36035,6 @@ function bindProcessErrorHandler(handler) {
36595
36035
  };
36596
36036
  }
36597
36037
  __name(bindProcessErrorHandler, "bindProcessErrorHandler");
36598
- async function safeReportUnhandledError(handler, info) {
36599
- try {
36600
- await handler(info);
36601
- } catch {
36602
- }
36603
- }
36604
- __name(safeReportUnhandledError, "safeReportUnhandledError");
36605
36038
 
36606
36039
  // src/models/RunResult.ts
36607
36040
  var RunResult = class {
@@ -36800,7 +36233,6 @@ function extractResourceAndConfig(resourceOrResourceWithConfig) {
36800
36233
  __name(extractResourceAndConfig, "extractResourceAndConfig");
36801
36234
 
36802
36235
  // src/globals/tunnels/index.ts
36803
- init_http_fetch_tunnel_resource();
36804
36236
  var http = Object.freeze({
36805
36237
  createClient(cfg) {
36806
36238
  const { url, ...rest } = cfg;
@@ -36811,39 +36243,15 @@ var tunnels = Object.freeze({
36811
36243
  http
36812
36244
  });
36813
36245
 
36814
- // src/testing.ts
36815
- var testResourceCounter = 0;
36816
- function createTestResource(root, options) {
36817
- return defineResource({
36818
- id: `testing.${root.id}.${++testResourceCounter}`,
36819
- register: [root],
36820
- overrides: options?.overrides || [],
36821
- dependencies: {
36822
- taskRunner: globalResources.taskRunner,
36823
- store: globalResources.store,
36824
- logger: globalResources.logger,
36825
- eventManager: globalResources.eventManager
36826
- },
36827
- async init(_, deps) {
36828
- return buildTestFacade(deps);
36829
- }
36830
- });
36831
- }
36832
- __name(createTestResource, "createTestResource");
36833
- function buildTestFacade(deps) {
36834
- return {
36835
- // Run a task within the fully initialized ecosystem
36836
- runTask: /* @__PURE__ */ __name((task2, ...args) => deps.taskRunner.run(task2, ...args), "runTask"),
36837
- // Access a resource value by id (string or symbol)
36838
- getResource: /* @__PURE__ */ __name((id2) => deps.store.resources.get(id2)?.value, "getResource"),
36839
- // Expose internals when needed in tests (not recommended for app usage)
36840
- taskRunner: deps.taskRunner,
36841
- store: deps.store,
36842
- logger: deps.logger,
36843
- eventManager: deps.eventManager
36844
- };
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];
36845
36253
  }
36846
- __name(buildTestFacade, "buildTestFacade");
36254
+ __name(mergeArray, "mergeArray");
36847
36255
 
36848
36256
  // src/definers/builders/resource/utils.ts
36849
36257
  function clone2(s, patch) {
@@ -36889,14 +36297,6 @@ function mergeRegister(existing, addition, override2) {
36889
36297
  ];
36890
36298
  }
36891
36299
  __name(mergeRegister, "mergeRegister");
36892
- function mergeArray(existing, addition, override2) {
36893
- const toArray = [...addition];
36894
- if (override2 || !existing) {
36895
- return toArray;
36896
- }
36897
- return [...existing, ...toArray];
36898
- }
36899
- __name(mergeArray, "mergeArray");
36900
36300
  function mergeDependencies(existing, addition, override2) {
36901
36301
  const isFnExisting = typeof existing === "function";
36902
36302
  const isFnAddition = typeof addition === "function";
@@ -37060,14 +36460,6 @@ function clone3(s, patch) {
37060
36460
  });
37061
36461
  }
37062
36462
  __name(clone3, "clone");
37063
- function mergeArray2(existing, addition, override2) {
37064
- const toArray = [...addition];
37065
- if (override2 || !existing) {
37066
- return toArray;
37067
- }
37068
- return [...existing, ...toArray];
37069
- }
37070
- __name(mergeArray2, "mergeArray");
37071
36463
  function mergeDependencies2(existing, addition, override2) {
37072
36464
  const isFnExisting = typeof existing === "function";
37073
36465
  const isFnAddition = typeof addition === "function";
@@ -37123,14 +36515,14 @@ function makeTaskBuilder(state) {
37123
36515
  middleware(mw, options) {
37124
36516
  const override2 = options?.override ?? false;
37125
36517
  const next = clone3(state, {
37126
- middleware: mergeArray2(state.middleware, mw, override2)
36518
+ middleware: mergeArray(state.middleware, mw, override2)
37127
36519
  });
37128
36520
  return makeTaskBuilder(next);
37129
36521
  },
37130
36522
  tags(t, options) {
37131
36523
  const override2 = options?.override ?? false;
37132
36524
  const next = clone3(state, {
37133
- tags: mergeArray2(state.tags, t, override2)
36525
+ tags: mergeArray(state.tags, t, override2)
37134
36526
  });
37135
36527
  return makeTaskBuilder(next);
37136
36528
  },
@@ -37206,14 +36598,14 @@ function makePhantomTaskBuilder(state) {
37206
36598
  middleware(mw, options) {
37207
36599
  const override2 = options?.override ?? false;
37208
36600
  const next = clone3(state, {
37209
- middleware: mergeArray2(state.middleware, mw, override2)
36601
+ middleware: mergeArray(state.middleware, mw, override2)
37210
36602
  });
37211
36603
  return makePhantomTaskBuilder(next);
37212
36604
  },
37213
36605
  tags(t, options) {
37214
36606
  const override2 = options?.override ?? false;
37215
36607
  const next = clone3(state, {
37216
- tags: mergeArray2(state.tags, t, override2)
36608
+ tags: mergeArray(state.tags, t, override2)
37217
36609
  });
37218
36610
  return makePhantomTaskBuilder(
37219
36611
  next
@@ -37302,14 +36694,6 @@ function clone4(s, patch) {
37302
36694
  });
37303
36695
  }
37304
36696
  __name(clone4, "clone");
37305
- function mergeArray3(existing, addition, override2) {
37306
- const toArray = [...addition];
37307
- if (override2 || !existing) {
37308
- return toArray;
37309
- }
37310
- return [...existing, ...toArray];
37311
- }
37312
- __name(mergeArray3, "mergeArray");
37313
36697
 
37314
36698
  // src/definers/builders/event/fluent-builder.ts
37315
36699
  function makeEventBuilder(state) {
@@ -37324,7 +36708,7 @@ function makeEventBuilder(state) {
37324
36708
  tags(t, options) {
37325
36709
  const override2 = options?.override ?? false;
37326
36710
  const next = clone4(state, {
37327
- tags: mergeArray3(state.tags, t, override2)
36711
+ tags: mergeArray(state.tags, t, override2)
37328
36712
  });
37329
36713
  return makeEventBuilder(next);
37330
36714
  },
@@ -37372,14 +36756,6 @@ function clone5(s, patch) {
37372
36756
  });
37373
36757
  }
37374
36758
  __name(clone5, "clone");
37375
- function mergeArray4(existing, addition, override2) {
37376
- const toArray = [...addition];
37377
- if (override2 || !existing) {
37378
- return toArray;
37379
- }
37380
- return [...existing, ...toArray];
37381
- }
37382
- __name(mergeArray4, "mergeArray");
37383
36759
  function mergeDependencies3(existing, addition, override2) {
37384
36760
  const isFnExisting = typeof existing === "function";
37385
36761
  const isFnAddition = typeof addition === "function";
@@ -37453,7 +36829,7 @@ function makeHookBuilder(state) {
37453
36829
  tags(t, options) {
37454
36830
  const override2 = options?.override ?? false;
37455
36831
  const next = clone5(state, {
37456
- tags: mergeArray4(state.tags, t, override2)
36832
+ tags: mergeArray(state.tags, t, override2)
37457
36833
  });
37458
36834
  return makeHookBuilder(next);
37459
36835
  },
@@ -37530,14 +36906,6 @@ function cloneRes(s, patch) {
37530
36906
  });
37531
36907
  }
37532
36908
  __name(cloneRes, "cloneRes");
37533
- function mergeArray5(existing, addition, override2) {
37534
- const toArray = [...addition];
37535
- if (override2 || !existing) {
37536
- return toArray;
37537
- }
37538
- return [...existing, ...toArray];
37539
- }
37540
- __name(mergeArray5, "mergeArray");
37541
36909
  function mergeDependencies4(existing, addition, override2) {
37542
36910
  const isFnExisting = typeof existing === "function";
37543
36911
  const isFnAddition = typeof addition === "function";
@@ -37618,7 +36986,7 @@ function makeTaskMiddlewareBuilder(state) {
37618
36986
  tags(t, options) {
37619
36987
  const override2 = options?.override ?? false;
37620
36988
  const next = cloneTask(state, {
37621
- tags: mergeArray5(state.tags, t, override2)
36989
+ tags: mergeArray(state.tags, t, override2)
37622
36990
  });
37623
36991
  return makeTaskMiddlewareBuilder(next);
37624
36992
  },
@@ -37690,7 +37058,7 @@ function makeResourceMiddlewareBuilder(state) {
37690
37058
  tags(t, options) {
37691
37059
  const override2 = options?.override ?? false;
37692
37060
  const next = cloneRes(state, {
37693
- tags: mergeArray5(state.tags, t, override2)
37061
+ tags: mergeArray(state.tags, t, override2)
37694
37062
  });
37695
37063
  return makeResourceMiddlewareBuilder(next);
37696
37064
  },
@@ -37901,7 +37269,7 @@ function makeHookOverrideBuilder(base, state) {
37901
37269
  tags(t, options) {
37902
37270
  const override2 = options?.override ?? false;
37903
37271
  const next = cloneHookState(state, {
37904
- tags: mergeArray4(state.tags, t, override2)
37272
+ tags: mergeArray(state.tags, t, override2)
37905
37273
  });
37906
37274
  return makeHookOverrideBuilder(base, next);
37907
37275
  },
@@ -38106,7 +37474,7 @@ function makeResourceMiddlewareOverrideBuilder(base, state) {
38106
37474
  tags(t, options) {
38107
37475
  const override2 = options?.override ?? false;
38108
37476
  const next = cloneResourceMiddlewareState(state, {
38109
- tags: mergeArray5(state.tags, t, override2)
37477
+ tags: mergeArray(state.tags, t, override2)
38110
37478
  });
38111
37479
  return makeResourceMiddlewareOverrideBuilder(base, next);
38112
37480
  },
@@ -38166,14 +37534,14 @@ function makeTaskOverrideBuilder(base, state) {
38166
37534
  middleware(mw, options) {
38167
37535
  const override2 = options?.override ?? false;
38168
37536
  const next = cloneTaskState(state, {
38169
- middleware: mergeArray2(state.middleware, mw, override2)
37537
+ middleware: mergeArray(state.middleware, mw, override2)
38170
37538
  });
38171
37539
  return makeTaskOverrideBuilder(base, next);
38172
37540
  },
38173
37541
  tags(t, options) {
38174
37542
  const override2 = options?.override ?? false;
38175
37543
  const next = cloneTaskState(state, {
38176
- tags: mergeArray2(state.tags, t, override2)
37544
+ tags: mergeArray(state.tags, t, override2)
38177
37545
  });
38178
37546
  return makeTaskOverrideBuilder(base, next);
38179
37547
  },
@@ -38282,7 +37650,7 @@ function makeTaskMiddlewareOverrideBuilder(base, state) {
38282
37650
  tags(t, options) {
38283
37651
  const override2 = options?.override ?? false;
38284
37652
  const next = cloneTaskMiddlewareState(state, {
38285
- tags: mergeArray5(state.tags, t, override2)
37653
+ tags: mergeArray(state.tags, t, override2)
38286
37654
  });
38287
37655
  return makeTaskMiddlewareOverrideBuilder(base, next);
38288
37656
  },
@@ -38334,7 +37702,6 @@ function override(base) {
38334
37702
  __name(override, "override");
38335
37703
 
38336
37704
  // src/public.ts
38337
- init_http_fetch_tunnel_resource();
38338
37705
  var globals = {
38339
37706
  events: globalEvents,
38340
37707
  resources: globalResources,
@@ -38343,7 +37710,6 @@ var globals = {
38343
37710
  tunnels,
38344
37711
  debug
38345
37712
  };
38346
- var createContext2 = createContext;
38347
37713
  var r = Object.freeze({
38348
37714
  resource,
38349
37715
  task,
@@ -39629,7 +38995,7 @@ var withExposureContext = /* @__PURE__ */ __name((req, res, controller, deps, fn
39629
38995
  } catch {
39630
38996
  }
39631
38997
  }
39632
- const run3 = /* @__PURE__ */ __name(() => ExposureRequestContext.provide(
38998
+ const run2 = /* @__PURE__ */ __name(() => ExposureRequestContext.provide(
39633
38999
  {
39634
39000
  req,
39635
39001
  res,
@@ -39641,7 +39007,7 @@ var withExposureContext = /* @__PURE__ */ __name((req, res, controller, deps, fn
39641
39007
  },
39642
39008
  userWrapped
39643
39009
  ), "run");
39644
- return Promise.resolve(run3());
39010
+ return Promise.resolve(run2());
39645
39011
  }, "withExposureContext");
39646
39012
  var withUserContexts = /* @__PURE__ */ __name((req, deps, fn) => {
39647
39013
  const { store: store2, serializer: serializer3 } = deps;
@@ -39837,7 +39203,7 @@ var createTaskHandler = /* @__PURE__ */ __name((deps) => {
39837
39203
  applyCorsActual(req, res, cors);
39838
39204
  respondJson(res, jsonOkResponse({ result }), serializer3);
39839
39205
  } catch (error2) {
39840
- if (isCancellationError(error2)) {
39206
+ if (cancellationError.is(error2)) {
39841
39207
  if (!res.writableEnded && !res.headersSent) {
39842
39208
  applyCorsActual(req, res, cors);
39843
39209
  respondJson(
@@ -39946,7 +39312,7 @@ var createEventHandler = /* @__PURE__ */ __name((deps) => {
39946
39312
  serializer3
39947
39313
  );
39948
39314
  } catch (error2) {
39949
- if (isCancellationError(error2)) {
39315
+ if (cancellationError.is(error2)) {
39950
39316
  if (!res.writableEnded && !res.headersSent) {
39951
39317
  applyCorsActual(req, res, cors);
39952
39318
  respondJson(
@@ -40212,27 +39578,487 @@ async function writeInputFileToPath(file, targetPath) {
40212
39578
  }
40213
39579
  __name(writeInputFileToPath, "writeInputFileToPath");
40214
39580
 
40215
- // src/node/http/index.ts
40216
- init_http_smart_client_model();
40217
- init_http_mixed_client();
40218
-
40219
- // src/node/http/http-smart-client.factory.resource.ts
40220
- var httpSmartClientFactory = defineResource({
40221
- id: "globals.resources.httpSmartClientFactory",
40222
- meta: {
40223
- title: "HTTP Smart Client Factory (Node)",
40224
- 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."
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;
40225
39616
  }
40226
- });
39617
+ __name(visit, "visit");
39618
+ const cloned = visit(input);
39619
+ return { input: cloned, files };
39620
+ }
39621
+ __name(buildNodeManifest, "buildNodeManifest");
40227
39622
 
40228
- // src/node/http/http-mixed-client.factory.resource.ts
40229
- var httpMixedClientFactory = defineResource({
40230
- id: "globals.resources.httpMixedClientFactory",
40231
- meta: {
40232
- title: "HTTP Mixed Client Factory (Node)",
40233
- 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."
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
+ }
40234
39682
  }
40235
- });
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);
39868
+ }
39869
+ );
39870
+ }
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);
39903
+ }
39904
+ }
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;
39912
+ return {
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
+ }
39981
+ };
39982
+ }
39983
+ __name(createHttpSmartClient, "createHttpSmartClient");
39984
+
39985
+ // src/node/http/http-mixed-client.ts
39986
+ function isReadable2(value) {
39987
+ return !!value && typeof value.pipe === "function";
39988
+ }
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;
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
40031
+ });
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
40040
+ });
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
+ };
40060
+ }
40061
+ __name(createHttpMixedClient, "createHttpMixedClient");
40236
40062
 
40237
40063
  // src/node/durable/core/types.ts
40238
40064
  var ExecutionStatus = {
@@ -40595,9 +40421,10 @@ var DurableResource = class _DurableResource {
40595
40421
  );
40596
40422
  }
40597
40423
  const deps = storeTask.computedDependencies;
40424
+ const resolvedInput = this.resolveDescribeInput(effectiveTask, input);
40598
40425
  return await recordFlowShape(async (ctx) => {
40599
40426
  const depsWithRecorder = this.injectRecorderIntoDurableDeps(deps, ctx);
40600
- await effectiveTask.run(input, depsWithRecorder);
40427
+ await effectiveTask.run(resolvedInput, depsWithRecorder);
40601
40428
  });
40602
40429
  }
40603
40430
  getWorkflows() {
@@ -40625,6 +40452,23 @@ var DurableResource = class _DurableResource {
40625
40452
  }
40626
40453
  return next;
40627
40454
  }
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
+ }
40628
40472
  start(task2, input, options) {
40629
40473
  if (typeof task2 === "string") {
40630
40474
  return this.service.start(task2, input, options);
@@ -44359,50 +44203,6 @@ var redisDurableResource = r.resource("base.durable.redis").register([durableWor
44359
44203
  if (!ctx.runtimeConfig) return;
44360
44204
  await disposeDurableService(durable.service, ctx.runtimeConfig);
44361
44205
  }).build();
44362
-
44363
- // src/node/node.ts
44364
- var globals2 = {
44365
- ...globals,
44366
- resources: {
44367
- ...globals.resources,
44368
- httpSmartClientFactory,
44369
- httpMixedClientFactory
44370
- }
44371
- };
44372
- async function run2(root, config) {
44373
- const rt = await run(root, config);
44374
- const store2 = await rt.getResourceValue(globals.resources.store);
44375
- store2.storeGenericItem(httpSmartClientFactory);
44376
- store2.storeGenericItem(httpMixedClientFactory);
44377
- const serializer3 = await rt.getResourceValue(
44378
- globals.resources.serializer
44379
- );
44380
- const errorRegistry = /* @__PURE__ */ new Map();
44381
- for (const [id2, helper] of store2.errors) errorRegistry.set(id2, helper);
44382
- const contexts = Array.from(store2.asyncContexts.values());
44383
- const smartEntry = store2.resources.get(httpSmartClientFactory.id);
44384
- if (smartEntry && !smartEntry.isInitialized) {
44385
- smartEntry.value = (cfg) => (init_http_smart_client_model(), __toCommonJS(http_smart_client_model_exports)).createHttpSmartClient({
44386
- ...cfg,
44387
- serializer: serializer3,
44388
- contexts,
44389
- errorRegistry
44390
- });
44391
- smartEntry.isInitialized = true;
44392
- }
44393
- const mixedEntry = store2.resources.get(httpMixedClientFactory.id);
44394
- if (mixedEntry && !mixedEntry.isInitialized) {
44395
- mixedEntry.value = (cfg) => (init_http_mixed_client(), __toCommonJS(http_mixed_client_exports)).createHttpMixedClient({
44396
- ...cfg,
44397
- serializer: serializer3,
44398
- contexts,
44399
- errorRegistry
44400
- });
44401
- mixedEntry.isInitialized = true;
44402
- }
44403
- return rt;
44404
- }
44405
- __name(run2, "run");
44406
44206
  /*! Bundled license information:
44407
44207
 
44408
44208
  depd/index.js:
@@ -44690,6 +44490,6 @@ serve-static/index.js:
44690
44490
  *)
44691
44491
  */
44692
44492
 
44693
- 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, RunnerError, 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, durableWorkflowTag, 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 };
44694
44494
  //# sourceMappingURL=node.mjs.map
44695
44495
  //# sourceMappingURL=node.mjs.map