@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,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var http2 = require('http');
4
- var https = require('https');
5
- var stream = require('stream');
6
3
  var lruCache = require('lru-cache');
7
4
  var crypto = require('crypto');
5
+ var http2 = require('http');
6
+ var stream = require('stream');
8
7
  var Busboy = require('busboy');
9
8
  var fs3 = require('fs');
10
9
  var os = require('os');
11
10
  var path3 = require('path');
11
+ var https = require('https');
12
12
  var timers = require('timers');
13
13
  var module$1 = require('module');
14
14
  var async_hooks = require('async_hooks');
@@ -31,13 +31,13 @@ function _interopNamespace(e) {
31
31
  return Object.freeze(n);
32
32
  }
33
33
 
34
- var http2__namespace = /*#__PURE__*/_interopNamespace(http2);
35
- var https__namespace = /*#__PURE__*/_interopNamespace(https);
36
34
  var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
35
+ var http2__namespace = /*#__PURE__*/_interopNamespace(http2);
37
36
  var Busboy__namespace = /*#__PURE__*/_interopNamespace(Busboy);
38
37
  var fs3__namespace = /*#__PURE__*/_interopNamespace(fs3);
39
38
  var os__namespace = /*#__PURE__*/_interopNamespace(os);
40
39
  var path3__namespace = /*#__PURE__*/_interopNamespace(path3);
40
+ var https__namespace = /*#__PURE__*/_interopNamespace(https);
41
41
 
42
42
  var __create = Object.create;
43
43
  var __defProp = Object.defineProperty;
@@ -52,16 +52,9 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
52
52
  if (typeof require !== "undefined") return require.apply(this, arguments);
53
53
  throw Error('Dynamic require of "' + x + '" is not supported');
54
54
  });
55
- var __esm = (fn, res) => function __init() {
56
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
57
- };
58
55
  var __commonJS = (cb, mod) => function __require2() {
59
56
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
60
57
  };
61
- var __export = (target, all) => {
62
- for (var name in all)
63
- __defProp(target, name, { get: all[name], enumerable: true });
64
- };
65
58
  var __copyProps = (to, from, except, desc) => {
66
59
  if (from && typeof from === "object" || typeof from === "function") {
67
60
  for (let key of __getOwnPropNames(from))
@@ -78,875 +71,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
78
71
  __defProp(target, "default", { value: mod, enumerable: true }) ,
79
72
  mod
80
73
  ));
81
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
82
-
83
- // src/serializer/regexp-validator.ts
84
- var regexp_validator_exports = {};
85
- __export(regexp_validator_exports, {
86
- assertRegExpPayload: () => assertRegExpPayload,
87
- isBoundedQuantifier: () => isBoundedQuantifier,
88
- isQuantifierAt: () => isQuantifierAt,
89
- isQuantifierChar: () => isQuantifierChar,
90
- isRegExpPatternSafe: () => isRegExpPatternSafe
91
- });
92
- var isQuantifierAt, isQuantifierChar, isBoundedQuantifier, isRegExpPatternSafe, assertRegExpPayload;
93
- var init_regexp_validator = __esm({
94
- "src/serializer/regexp-validator.ts"() {
95
- isQuantifierAt = /* @__PURE__ */ __name((pattern, index) => {
96
- if (index >= pattern.length) {
97
- return false;
98
- }
99
- const char = pattern[index];
100
- if (char === "*" || char === "+" || char === "?") {
101
- return true;
102
- }
103
- if (char === "{") {
104
- return isBoundedQuantifier(pattern, index);
105
- }
106
- return false;
107
- }, "isQuantifierAt");
108
- isQuantifierChar = /* @__PURE__ */ __name((char, pattern, index) => {
109
- if (char === "*" || char === "+") {
110
- return true;
111
- }
112
- if (char === "?") {
113
- if (index > 0 && pattern[index - 1] === "(") {
114
- return false;
115
- }
116
- return true;
117
- }
118
- if (char === "{") {
119
- return isBoundedQuantifier(pattern, index);
120
- }
121
- return false;
122
- }, "isQuantifierChar");
123
- isBoundedQuantifier = /* @__PURE__ */ __name((pattern, index) => {
124
- let sawDigit = false;
125
- let sawComma = false;
126
- for (let i = index + 1; i < pattern.length; i += 1) {
127
- const char = pattern[i];
128
- if (char >= "0" && char <= "9") {
129
- sawDigit = true;
130
- continue;
131
- }
132
- if (char === "," && !sawComma) {
133
- sawComma = true;
134
- continue;
135
- }
136
- if (char === "}") {
137
- return sawDigit;
138
- }
139
- return false;
140
- }
141
- return false;
142
- }, "isBoundedQuantifier");
143
- isRegExpPatternSafe = /* @__PURE__ */ __name((pattern) => {
144
- const groupStack = [];
145
- let escaped = false;
146
- let inCharClass = false;
147
- for (let index = 0; index < pattern.length; index += 1) {
148
- const char = pattern[index];
149
- if (escaped) {
150
- escaped = false;
151
- continue;
152
- }
153
- if (char === "\\") {
154
- escaped = true;
155
- continue;
156
- }
157
- if (inCharClass) {
158
- if (char === "]") {
159
- inCharClass = false;
160
- }
161
- continue;
162
- }
163
- if (char === "[") {
164
- inCharClass = true;
165
- continue;
166
- }
167
- if (char === "(") {
168
- groupStack.push({ hasQuantifier: false });
169
- if (pattern[index + 1] === "?") {
170
- index += 1;
171
- }
172
- continue;
173
- }
174
- if (char === ")") {
175
- const group = groupStack.pop();
176
- if (group?.hasQuantifier && isQuantifierAt(pattern, index + 1)) {
177
- return false;
178
- }
179
- if (group?.hasQuantifier && groupStack.length > 0) {
180
- groupStack[groupStack.length - 1].hasQuantifier = true;
181
- }
182
- continue;
183
- }
184
- if (isQuantifierChar(char, pattern, index)) {
185
- if (groupStack.length > 0) {
186
- groupStack[groupStack.length - 1].hasQuantifier = true;
187
- }
188
- }
189
- }
190
- return true;
191
- }, "isRegExpPatternSafe");
192
- assertRegExpPayload = /* @__PURE__ */ __name((value, options) => {
193
- if (!value || typeof value !== "object") {
194
- throw new Error("Invalid RegExp payload");
195
- }
196
- const record = value;
197
- if (typeof record.pattern !== "string" || typeof record.flags !== "string") {
198
- throw new Error("Invalid RegExp payload");
199
- }
200
- if (record.pattern.length > options.maxPatternLength) {
201
- throw new Error(
202
- `RegExp pattern exceeds limit (${options.maxPatternLength})`
203
- );
204
- }
205
- if (!options.allowUnsafe && !isRegExpPatternSafe(record.pattern)) {
206
- throw new Error("Unsafe RegExp pattern");
207
- }
208
- return { pattern: record.pattern, flags: record.flags };
209
- }, "assertRegExpPayload");
210
- }
211
- });
212
-
213
- // src/globals/resources/tunnel/protocol.ts
214
- function toTunnelError(input, fallbackMessage) {
215
- if (input instanceof Error) {
216
- return new TunnelError("UNKNOWN", input.message);
217
- }
218
- if (input && typeof input === "object" && "code" in input && "message" in input) {
219
- const typed = input;
220
- if (typeof typed.message === "string" && typeof typed.code === "string") {
221
- const pe = input;
222
- const msg = pe.message || fallbackMessage || "Tunnel error";
223
- return new TunnelError(pe.code, msg, pe.details, {
224
- httpCode: pe.httpCode,
225
- id: pe.id,
226
- data: pe.data
227
- });
228
- }
229
- }
230
- if (input && typeof input === "object" && "message" in input) {
231
- const typed = input;
232
- if (typeof typed.message === "string") {
233
- return new TunnelError("UNKNOWN", typed.message);
234
- }
235
- }
236
- return new TunnelError(
237
- "UNKNOWN",
238
- typeof input === "string" && input || fallbackMessage || "Tunnel error"
239
- );
240
- }
241
- function assertOkEnvelope(envelope, opts) {
242
- if (!envelope || typeof envelope !== "object") {
243
- throw new TunnelError(
244
- "INVALID_RESPONSE",
245
- opts?.fallbackMessage || "Invalid or empty response"
246
- );
247
- }
248
- if (envelope.ok) {
249
- return envelope.result;
250
- }
251
- if (envelope.error) {
252
- return (() => {
253
- throw toTunnelError(envelope.error, opts?.fallbackMessage);
254
- })();
255
- }
256
- throw new TunnelError("UNKNOWN", opts?.fallbackMessage || "Tunnel error");
257
- }
258
- var TunnelError;
259
- var init_protocol = __esm({
260
- "src/globals/resources/tunnel/protocol.ts"() {
261
- TunnelError = class extends Error {
262
- static {
263
- __name(this, "TunnelError");
264
- }
265
- constructor(code, message, details, extras) {
266
- super(message);
267
- this.name = "TunnelError";
268
- this.code = code;
269
- this.details = details;
270
- this.httpCode = extras?.httpCode;
271
- this.id = extras?.id;
272
- this.data = extras?.data;
273
- }
274
- };
275
- __name(toTunnelError, "toTunnelError");
276
- __name(assertOkEnvelope, "assertOkEnvelope");
277
- }
278
- });
279
-
280
- // src/globals/resources/tunnel/error-utils.ts
281
- function normalizeError(input) {
282
- return input instanceof Error ? input : new Error(String(input));
283
- }
284
- var init_error_utils = __esm({
285
- "src/globals/resources/tunnel/error-utils.ts"() {
286
- __name(normalizeError, "normalizeError");
287
- }
288
- });
289
-
290
- // src/http-fetch-tunnel.resource.ts
291
- async function postSerialized(options) {
292
- const {
293
- fetch: fetchFn,
294
- url,
295
- body,
296
- headers,
297
- timeoutMs,
298
- serializer: serializer3,
299
- onRequest,
300
- contextHeaderText
301
- } = options;
302
- const controller = timeoutMs && timeoutMs > 0 ? new AbortController() : void 0;
303
- let timeout;
304
- try {
305
- if (controller) {
306
- timeout = setTimeout(() => controller.abort(), timeoutMs);
307
- }
308
- const reqHeaders = {
309
- "content-type": "application/json; charset=utf-8",
310
- ...headers
311
- };
312
- if (contextHeaderText) reqHeaders["x-runner-context"] = contextHeaderText;
313
- if (onRequest) await onRequest({ url, headers: reqHeaders });
314
- const res = await fetchFn(url, {
315
- method: "POST",
316
- headers: reqHeaders,
317
- body: serializer3.stringify(body),
318
- signal: controller?.signal
319
- });
320
- const text = await res.text();
321
- const json2 = text ? serializer3.parse(text) : void 0;
322
- return json2;
323
- } finally {
324
- if (timeout) clearTimeout(timeout);
325
- }
326
- }
327
- function createExposureFetch(cfg) {
328
- const baseUrl = cfg?.baseUrl?.replace(/\/$/, "");
329
- if (!baseUrl) throw new Error("createExposureFetch requires baseUrl");
330
- const headerName = (cfg?.auth?.header ?? "x-runner-token").toLowerCase();
331
- const buildHeaders = /* @__PURE__ */ __name(() => {
332
- const headers = {};
333
- if (cfg?.auth?.token) headers[headerName] = cfg.auth.token;
334
- return headers;
335
- }, "buildHeaders");
336
- const fetchImpl = cfg.fetchImpl ?? globalThis.fetch;
337
- if (typeof fetchImpl !== "function") {
338
- throw new Error(
339
- "global fetch is not available; provide fetchImpl in config"
340
- );
341
- }
342
- const buildContextHeader = /* @__PURE__ */ __name(() => {
343
- if (!cfg.contexts || cfg.contexts.length === 0) return void 0;
344
- const map = {};
345
- for (const ctx of cfg.contexts) {
346
- try {
347
- const v = ctx.use();
348
- map[ctx.id] = ctx.serialize(v);
349
- } catch {
350
- }
351
- }
352
- const keys = Object.keys(map);
353
- if (keys.length === 0) return void 0;
354
- return cfg.serializer.stringify(map);
355
- }, "buildContextHeader");
356
- return {
357
- async task(id2, input) {
358
- const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
359
- const r2 = await postSerialized({
360
- fetch: fetchImpl,
361
- url,
362
- body: { input },
363
- headers: buildHeaders(),
364
- timeoutMs: cfg?.timeoutMs,
365
- serializer: cfg.serializer,
366
- onRequest: cfg?.onRequest,
367
- contextHeaderText: buildContextHeader()
368
- });
369
- try {
370
- return assertOkEnvelope(r2, { fallbackMessage: "Tunnel task error" });
371
- } catch (e) {
372
- const te = e;
373
- if (cfg.errorRegistry && te.id && te.data) {
374
- const helper = cfg.errorRegistry.get(String(te.id));
375
- if (helper) helper.throw(te.data);
376
- }
377
- throw e;
378
- }
379
- },
380
- async event(id2, payload) {
381
- const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
382
- const r2 = await postSerialized({
383
- fetch: fetchImpl,
384
- url,
385
- body: { payload },
386
- headers: buildHeaders(),
387
- timeoutMs: cfg?.timeoutMs,
388
- serializer: cfg.serializer,
389
- onRequest: cfg?.onRequest,
390
- contextHeaderText: buildContextHeader()
391
- });
392
- try {
393
- assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
394
- } catch (e) {
395
- const te = e;
396
- if (cfg.errorRegistry && te.id && te.data) {
397
- const helper = cfg.errorRegistry.get(String(te.id));
398
- if (helper) helper.throw(te.data);
399
- }
400
- throw e;
401
- }
402
- },
403
- async eventWithResult(id2, payload) {
404
- const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
405
- const r2 = await postSerialized({
406
- fetch: fetchImpl,
407
- url,
408
- body: { payload, returnPayload: true },
409
- headers: buildHeaders(),
410
- timeoutMs: cfg?.timeoutMs,
411
- serializer: cfg.serializer,
412
- onRequest: cfg?.onRequest,
413
- contextHeaderText: buildContextHeader()
414
- });
415
- if (r2 && typeof r2 === "object" && r2.ok && !("result" in r2)) {
416
- throw new TunnelError(
417
- "INVALID_RESPONSE",
418
- "Tunnel event returnPayload requested but server did not include result. Upgrade the exposure server."
419
- );
420
- }
421
- try {
422
- return assertOkEnvelope(r2, {
423
- fallbackMessage: "Tunnel event error"
424
- });
425
- } catch (e) {
426
- const te = e;
427
- if (cfg.errorRegistry && te.id && te.data) {
428
- const helper = cfg.errorRegistry.get(String(te.id));
429
- if (helper) helper.throw(te.data);
430
- }
431
- throw e;
432
- }
433
- }
434
- };
435
- }
436
- var init_http_fetch_tunnel_resource = __esm({
437
- "src/http-fetch-tunnel.resource.ts"() {
438
- init_protocol();
439
- init_error_utils();
440
- __name(postSerialized, "postSerialized");
441
- __name(createExposureFetch, "createExposureFetch");
442
- }
443
- });
444
-
445
- // src/node/upload/manifest.ts
446
- function buildNodeManifest(input) {
447
- const files = [];
448
- function visit(value) {
449
- if (!value || typeof value !== "object") return value;
450
- const potentialFile = value;
451
- if (potentialFile.$runnerFile === "File" && typeof potentialFile.id === "string") {
452
- const id2 = potentialFile.id;
453
- const meta = potentialFile.meta;
454
- const local = potentialFile._node;
455
- if (local?.buffer) {
456
- files.push({
457
- id: id2,
458
- meta,
459
- source: { type: "buffer", buffer: local.buffer }
460
- });
461
- } else if (local?.stream) {
462
- files.push({
463
- id: id2,
464
- meta,
465
- source: { type: "stream", stream: local.stream }
466
- });
467
- }
468
- const copy = { $runnerFile: "File", id: id2, meta };
469
- return copy;
470
- }
471
- if (Array.isArray(value)) {
472
- return value.map((x) => visit(x));
473
- }
474
- const out = {};
475
- const obj = value;
476
- for (const k of Object.keys(obj)) {
477
- out[k] = visit(obj[k]);
478
- }
479
- return out;
480
- }
481
- __name(visit, "visit");
482
- const cloned = visit(input);
483
- return { input: cloned, files };
484
- }
485
- var init_manifest = __esm({
486
- "src/node/upload/manifest.ts"() {
487
- __name(buildNodeManifest, "buildNodeManifest");
488
- }
489
- });
490
-
491
- // src/node/http/http-smart-client.model.ts
492
- var http_smart_client_model_exports = {};
493
- __export(http_smart_client_model_exports, {
494
- createHttpSmartClient: () => createHttpSmartClient
495
- });
496
- function isReadable(value) {
497
- return !!value && typeof value.pipe === "function";
498
- }
499
- function hasNodeFile(value) {
500
- const isNodeFileSentinel = /* @__PURE__ */ __name((v) => {
501
- if (!v || typeof v !== "object") return false;
502
- const rec = v;
503
- if (rec.$runnerFile !== "File") return false;
504
- if (typeof rec.id !== "string") return false;
505
- const node = rec._node;
506
- if (!node || typeof node !== "object") return false;
507
- const n = node;
508
- return Boolean(n.stream || n.buffer);
509
- }, "isNodeFileSentinel");
510
- const visit = /* @__PURE__ */ __name((v) => {
511
- if (isNodeFileSentinel(v)) return true;
512
- if (!v || typeof v !== "object") return false;
513
- if (Array.isArray(v)) return v.some(visit);
514
- for (const k of Object.keys(v)) {
515
- if (visit(v[k])) return true;
516
- }
517
- return false;
518
- }, "visit");
519
- return visit(value);
520
- }
521
- function toHeaders2(auth) {
522
- const headers = {};
523
- if (auth?.token)
524
- headers[(auth.header ?? "x-runner-token").toLowerCase()] = auth.token;
525
- return headers;
526
- }
527
- function requestLib(url) {
528
- return url.protocol === "https:" ? https__namespace : http2__namespace;
529
- }
530
- async function postJson(cfg, url, body) {
531
- const serializer3 = cfg.serializer;
532
- const parsed = new URL(url);
533
- const lib = requestLib(parsed);
534
- const headers = {
535
- "content-type": "application/json; charset=utf-8",
536
- ...toHeaders2(cfg.auth)
537
- };
538
- if (cfg.contexts && cfg.contexts.length > 0) {
539
- const map = {};
540
- for (const ctx of cfg.contexts) {
541
- try {
542
- const v = ctx.use();
543
- map[ctx.id] = ctx.serialize(v);
544
- } catch {
545
- }
546
- }
547
- if (Object.keys(map).length > 0) {
548
- headers["x-runner-context"] = cfg.serializer.stringify(map);
549
- }
550
- }
551
- if (cfg.onRequest) await cfg.onRequest({ url, headers });
552
- return await new Promise((resolve, reject) => {
553
- const req = lib.request(
554
- {
555
- method: "POST",
556
- protocol: parsed.protocol,
557
- hostname: parsed.hostname,
558
- port: parsed.port,
559
- path: parsed.pathname + parsed.search,
560
- headers,
561
- timeout: cfg.timeoutMs
562
- },
563
- (res) => {
564
- const chunks = [];
565
- res.on("data", (c) => {
566
- chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(String(c)));
567
- });
568
- res.on("end", () => {
569
- const text = Buffer.concat(chunks).toString(
570
- "utf8"
571
- );
572
- const json2 = text ? serializer3.parse(text) : void 0;
573
- resolve(json2);
574
- });
575
- }
576
- );
577
- req.on("error", reject);
578
- req.write(serializer3.stringify(body));
579
- req.end();
580
- });
581
- }
582
- function escapeHeaderValue(value) {
583
- return value.replace(/"/g, '\\"');
584
- }
585
- function encodeMultipart(manifestText, files, boundary) {
586
- async function* gen() {
587
- const CRLF = "\r\n";
588
- const boundaryLine = `--${boundary}`;
589
- const partHeader = /* @__PURE__ */ __name((name, options) => {
590
- const h = [boundaryLine + CRLF];
591
- const cd = [
592
- `Content-Disposition: form-data; name="${escapeHeaderValue(name)}"`
593
- ];
594
- if (options?.filename) {
595
- cd.push(`; filename="${escapeHeaderValue(options.filename)}"`);
596
- }
597
- h.push(cd.join("") + CRLF);
598
- if (options?.headers) {
599
- for (const k of Object.keys(options.headers)) {
600
- h.push(`${k}: ${options.headers[k]}` + CRLF);
601
- }
602
- }
603
- h.push(CRLF);
604
- return Buffer.from(h.join(""), "utf8");
605
- }, "partHeader");
606
- yield partHeader("__manifest");
607
- yield Buffer.from(manifestText, "utf8");
608
- yield Buffer.from(CRLF, "utf8");
609
- for (const entry of files) {
610
- const filename = entry.meta?.name ?? "upload";
611
- const contentType = entry.meta?.type ?? "application/octet-stream";
612
- const headers = {
613
- "Content-Type": contentType
614
- };
615
- yield partHeader(`file:${entry.id}`, { headers, filename });
616
- if (entry.source.type === "buffer") {
617
- yield entry.source.buffer;
618
- } else {
619
- for await (const chunk of entry.source.stream) {
620
- yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
621
- }
622
- }
623
- yield Buffer.from(CRLF, "utf8");
624
- }
625
- yield Buffer.from(boundaryLine + "--" + CRLF, "utf8");
626
- }
627
- __name(gen, "gen");
628
- return stream.Readable.from(gen());
629
- }
630
- async function postMultipart(cfg, url, manifestText, files) {
631
- const parsed = new URL(url);
632
- const lib = requestLib(parsed);
633
- const boundary = `runner-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
634
- const body = encodeMultipart(manifestText, files, boundary);
635
- const headers = {
636
- "content-type": `multipart/form-data; boundary=${boundary}`,
637
- ...toHeaders2(cfg.auth)
638
- };
639
- if (cfg.contexts && cfg.contexts.length > 0) {
640
- const map = {};
641
- for (const ctx of cfg.contexts) {
642
- try {
643
- const v = ctx.use();
644
- map[ctx.id] = ctx.serialize(v);
645
- } catch {
646
- }
647
- }
648
- if (Object.keys(map).length > 0) {
649
- headers["x-runner-context"] = cfg.serializer.stringify(map);
650
- }
651
- }
652
- if (cfg.onRequest) await cfg.onRequest({ url, headers });
653
- return await new Promise(
654
- (resolve, reject) => {
655
- const req = lib.request(
656
- {
657
- method: "POST",
658
- protocol: parsed.protocol,
659
- hostname: parsed.hostname,
660
- port: parsed.port,
661
- path: parsed.pathname + parsed.search,
662
- headers,
663
- timeout: cfg.timeoutMs
664
- },
665
- (res) => resolve({ stream: res, res })
666
- );
667
- req.on("error", reject);
668
- body.on("error", (e) => req.destroy(e));
669
- body.pipe(req);
670
- }
671
- );
672
- }
673
- async function postOctetStream(cfg, url, stream$1) {
674
- const parsed = new URL(url);
675
- const lib = requestLib(parsed);
676
- const headers = {
677
- "content-type": "application/octet-stream",
678
- ...toHeaders2(cfg.auth)
679
- };
680
- if (cfg.contexts && cfg.contexts.length > 0) {
681
- const map = {};
682
- for (const ctx of cfg.contexts) {
683
- try {
684
- const v = ctx.use();
685
- map[ctx.id] = ctx.serialize(v);
686
- } catch {
687
- }
688
- }
689
- if (Object.keys(map).length > 0) {
690
- headers["x-runner-context"] = cfg.serializer.stringify(map);
691
- }
692
- }
693
- if (cfg.onRequest) await cfg.onRequest({ url, headers });
694
- return await new Promise(
695
- (resolve, reject) => {
696
- let settled = false;
697
- const cleanup = [];
698
- const resolveOnce = /* @__PURE__ */ __name((value) => {
699
- settled = true;
700
- cleanup.forEach((fn) => fn());
701
- resolve(value);
702
- }, "resolveOnce");
703
- const rejectOnce = /* @__PURE__ */ __name((error2) => {
704
- settled = true;
705
- cleanup.forEach((fn) => fn());
706
- reject(error2 instanceof Error ? error2 : new Error(String(error2)));
707
- }, "rejectOnce");
708
- const req = lib.request(
709
- {
710
- method: "POST",
711
- protocol: parsed.protocol,
712
- hostname: parsed.hostname,
713
- port: parsed.port,
714
- path: parsed.pathname + parsed.search,
715
- headers,
716
- timeout: cfg.timeoutMs
717
- },
718
- (res) => {
719
- setImmediate(() => {
720
- if (!settled)
721
- resolveOnce({ stream: res, res });
722
- });
723
- }
724
- );
725
- const onReqError = /* @__PURE__ */ __name((e) => rejectOnce(e), "onReqError");
726
- req.on("error", onReqError);
727
- cleanup.push(() => req.removeListener("error", onReqError));
728
- const onPipelineDone = /* @__PURE__ */ __name((err) => {
729
- if (err) rejectOnce(err);
730
- }, "onPipelineDone");
731
- stream.pipeline(stream$1, req, onPipelineDone);
732
- }
733
- );
734
- }
735
- function parseMaybeJsonResponse(res, serializer3) {
736
- const contentType = String(res.headers["content-type"]);
737
- if (/^application\/json/i.test(contentType)) {
738
- const chunks = [];
739
- return new Promise((resolve, reject) => {
740
- res.on("data", (c) => {
741
- chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(String(c)));
742
- });
743
- res.on("end", () => {
744
- try {
745
- const text = Buffer.concat(chunks).toString(
746
- "utf8"
747
- );
748
- const json2 = text ? serializer3.parse(text) : void 0;
749
- resolve(json2);
750
- } catch (e) {
751
- reject(e);
752
- }
753
- });
754
- res.on("error", reject);
755
- });
756
- }
757
- return Promise.resolve(res);
758
- }
759
- function rethrowTyped(registry, error2) {
760
- if (registry && error2 && typeof error2 === "object") {
761
- const err = error2;
762
- if (err.id && err.data) {
763
- const helper = registry.get(String(err.id));
764
- if (helper) helper.throw(err.data);
765
- }
766
- }
767
- throw error2;
768
- }
769
- function createHttpSmartClient(cfg) {
770
- const baseUrl = cfg.baseUrl.replace(/\/$/, "");
771
- if (!baseUrl) throw new Error("createHttpSmartClient requires baseUrl");
772
- const serializer3 = cfg.serializer;
773
- return {
774
- async task(id2, input) {
775
- const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
776
- if (isReadable(input)) {
777
- const { res } = await postOctetStream(cfg, url, input);
778
- return res;
779
- }
780
- if (hasNodeFile(input)) {
781
- const manifest = buildNodeManifest(input);
782
- const manifestText = serializer3.stringify({
783
- input: manifest.input
784
- });
785
- try {
786
- const { res } = await postMultipart(
787
- cfg,
788
- url,
789
- manifestText,
790
- manifest.files
791
- );
792
- const maybe = await parseMaybeJsonResponse(
793
- res,
794
- serializer3
795
- );
796
- if (isReadable(maybe)) return maybe;
797
- return assertOkEnvelope(maybe, {
798
- fallbackMessage: "Tunnel task error"
799
- });
800
- } catch (error2) {
801
- rethrowTyped(cfg.errorRegistry, error2);
802
- }
803
- }
804
- try {
805
- const r2 = await postJson(cfg, url, { input });
806
- return assertOkEnvelope(r2, {
807
- fallbackMessage: "Tunnel task error"
808
- });
809
- } catch (error2) {
810
- rethrowTyped(cfg.errorRegistry, error2);
811
- }
812
- },
813
- async event(id2, payload) {
814
- const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
815
- try {
816
- const r2 = await postJson(cfg, url, { payload });
817
- assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
818
- } catch (error2) {
819
- rethrowTyped(cfg.errorRegistry, error2);
820
- }
821
- },
822
- async eventWithResult(id2, payload) {
823
- const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
824
- try {
825
- const r2 = await postJson(cfg, url, {
826
- payload,
827
- returnPayload: true
828
- });
829
- if (r2 && typeof r2 === "object" && r2.ok && !("result" in r2)) {
830
- throw new TunnelError(
831
- "INVALID_RESPONSE",
832
- "Tunnel event returnPayload requested but server did not include result. Upgrade the exposure server."
833
- );
834
- }
835
- return assertOkEnvelope(r2, {
836
- fallbackMessage: "Tunnel event error"
837
- });
838
- } catch (error2) {
839
- rethrowTyped(cfg.errorRegistry, error2);
840
- }
841
- }
842
- };
843
- }
844
- var init_http_smart_client_model = __esm({
845
- "src/node/http/http-smart-client.model.ts"() {
846
- init_protocol();
847
- init_manifest();
848
- __name(isReadable, "isReadable");
849
- __name(hasNodeFile, "hasNodeFile");
850
- __name(toHeaders2, "toHeaders");
851
- __name(requestLib, "requestLib");
852
- __name(postJson, "postJson");
853
- __name(escapeHeaderValue, "escapeHeaderValue");
854
- __name(encodeMultipart, "encodeMultipart");
855
- __name(postMultipart, "postMultipart");
856
- __name(postOctetStream, "postOctetStream");
857
- __name(parseMaybeJsonResponse, "parseMaybeJsonResponse");
858
- __name(rethrowTyped, "rethrowTyped");
859
- __name(createHttpSmartClient, "createHttpSmartClient");
860
- }
861
- });
862
-
863
- // src/node/http/http-mixed-client.ts
864
- var http_mixed_client_exports = {};
865
- __export(http_mixed_client_exports, {
866
- createHttpMixedClient: () => createHttpMixedClient
867
- });
868
- function isReadable2(value) {
869
- return !!value && typeof value.pipe === "function";
870
- }
871
- function hasNodeFile2(value) {
872
- const isNodeFileSentinel = /* @__PURE__ */ __name((v) => {
873
- if (!v || typeof v !== "object") return false;
874
- const rec = v;
875
- if (rec.$runnerFile !== "File") return false;
876
- if (typeof rec.id !== "string") return false;
877
- const node = rec._node;
878
- if (!node || typeof node !== "object") return false;
879
- const n = node;
880
- return Boolean(n.stream || n.buffer);
881
- }, "isNodeFileSentinel");
882
- const visit = /* @__PURE__ */ __name((v) => {
883
- if (isNodeFileSentinel(v)) return true;
884
- if (!v || typeof v !== "object") return false;
885
- if (Array.isArray(v)) return v.some(visit);
886
- for (const k of Object.keys(v)) {
887
- if (visit(v[k])) return true;
888
- }
889
- return false;
890
- }, "visit");
891
- return visit(value);
892
- }
893
- async function shouldForceSmart(cfg, id2, input) {
894
- if (!cfg.forceSmart) return false;
895
- if (cfg.forceSmart === true) return true;
896
- return await cfg.forceSmart({ id: id2, input });
897
- }
898
- function createHttpMixedClient(cfg) {
899
- const baseUrl = cfg.baseUrl?.replace(/\/$/, "");
900
- if (!baseUrl) throw new Error("createMixedHttpClient requires baseUrl");
901
- const fetchClient = createExposureFetch({
902
- baseUrl,
903
- auth: cfg.auth,
904
- timeoutMs: cfg.timeoutMs,
905
- fetchImpl: cfg.fetchImpl,
906
- serializer: cfg.serializer,
907
- onRequest: cfg.onRequest,
908
- contexts: cfg.contexts,
909
- errorRegistry: cfg.errorRegistry
910
- });
911
- const smartClient = createHttpSmartClient({
912
- baseUrl,
913
- auth: cfg.auth,
914
- timeoutMs: cfg.timeoutMs,
915
- serializer: cfg.serializer,
916
- onRequest: cfg.onRequest,
917
- contexts: cfg.contexts,
918
- errorRegistry: cfg.errorRegistry
919
- });
920
- return {
921
- async task(id2, input) {
922
- if (isReadable2(input) || hasNodeFile2(input) || await shouldForceSmart(cfg, id2, input)) {
923
- return await smartClient.task(id2, input);
924
- }
925
- return await fetchClient.task(id2, input);
926
- },
927
- async event(id2, payload) {
928
- return await fetchClient.event(id2, payload);
929
- },
930
- async eventWithResult(id2, payload) {
931
- if (!fetchClient.eventWithResult) {
932
- throw new Error(
933
- "createHttpMixedClient: eventWithResult not available on underlying tunnel client."
934
- );
935
- }
936
- return await fetchClient.eventWithResult(id2, payload);
937
- }
938
- };
939
- }
940
- var init_http_mixed_client = __esm({
941
- "src/node/http/http-mixed-client.ts"() {
942
- init_http_fetch_tunnel_resource();
943
- init_http_smart_client_model();
944
- __name(isReadable2, "isReadable");
945
- __name(hasNodeFile2, "hasNodeFile");
946
- __name(shouldForceSmart, "shouldForceSmart");
947
- __name(createHttpMixedClient, "createHttpMixedClient");
948
- }
949
- });
950
74
 
951
75
  // node_modules/ms/index.js
952
76
  var require_ms = __commonJS({
@@ -28623,7 +27747,6 @@ var symbolResourceWithConfig = Symbol.for(
28623
27747
  );
28624
27748
  var symbolEvent = Symbol.for("runner.event");
28625
27749
  var symbolError = Symbol.for("runner.error");
28626
- var symbolMiddleware = Symbol.for("runner.middleware");
28627
27750
  var symbolTaskMiddleware = Symbol.for(
28628
27751
  "runner.taskMiddleware"
28629
27752
  );
@@ -28672,228 +27795,6 @@ function getCallerFile() {
28672
27795
  }
28673
27796
  __name(getCallerFile, "getCallerFile");
28674
27797
 
28675
- // src/defs.ts
28676
- var defs_exports = {};
28677
- __export(defs_exports, {
28678
- CONTRACT: () => CONTRACT,
28679
- HookDependencyState: () => HookDependencyState,
28680
- RunnerMode: () => RunnerMode,
28681
- isOneOf: () => isOneOf,
28682
- onAnyOf: () => onAnyOf,
28683
- symbolAsyncContext: () => symbolAsyncContext,
28684
- symbolError: () => symbolError,
28685
- symbolEvent: () => symbolEvent,
28686
- symbolFilePath: () => symbolFilePath,
28687
- symbolForkedFrom: () => symbolForkedFrom,
28688
- symbolHook: () => symbolHook,
28689
- symbolMiddleware: () => symbolMiddleware,
28690
- symbolMiddlewareConfigured: () => symbolMiddlewareConfigured,
28691
- symbolOptionalDependency: () => symbolOptionalDependency,
28692
- symbolPhantomTask: () => symbolPhantomTask,
28693
- symbolResource: () => symbolResource,
28694
- symbolResourceMiddleware: () => symbolResourceMiddleware,
28695
- symbolResourceWithConfig: () => symbolResourceWithConfig,
28696
- symbolTag: () => symbolTag,
28697
- symbolTagConfigured: () => symbolTagConfigured,
28698
- symbolTask: () => symbolTask,
28699
- symbolTaskMiddleware: () => symbolTaskMiddleware,
28700
- symbolTunneledBy: () => symbolTunneledBy
28701
- });
28702
-
28703
- // src/types/event.ts
28704
- function onAnyOf(...defs) {
28705
- return defs;
28706
- }
28707
- __name(onAnyOf, "onAnyOf");
28708
- function isOneOf(emission, defs) {
28709
- return defs.some((d) => d.id === emission.id);
28710
- }
28711
- __name(isOneOf, "isOneOf");
28712
-
28713
- // src/types/runner.ts
28714
- var RunnerMode = /* @__PURE__ */ ((RunnerMode2) => {
28715
- RunnerMode2["TEST"] = "test";
28716
- RunnerMode2["DEV"] = "dev";
28717
- RunnerMode2["PROD"] = "prod";
28718
- return RunnerMode2;
28719
- })(RunnerMode || {});
28720
-
28721
- // src/types/contracts.ts
28722
- var CONTRACT = Symbol.for("runner.contract");
28723
-
28724
- // src/types/storeTypes.ts
28725
- var HookDependencyState = /* @__PURE__ */ ((HookDependencyState2) => {
28726
- HookDependencyState2["Pending"] = "pending";
28727
- HookDependencyState2["Computing"] = "computing";
28728
- HookDependencyState2["Ready"] = "ready";
28729
- return HookDependencyState2;
28730
- })(HookDependencyState || {});
28731
-
28732
- // src/definers/tools.ts
28733
- function isTask(definition) {
28734
- return definition && definition[symbolTask];
28735
- }
28736
- __name(isTask, "isTask");
28737
- function isResource(definition) {
28738
- return definition && definition[symbolResource];
28739
- }
28740
- __name(isResource, "isResource");
28741
- function isResourceWithConfig(definition) {
28742
- return definition && definition[symbolResourceWithConfig];
28743
- }
28744
- __name(isResourceWithConfig, "isResourceWithConfig");
28745
- function isEvent(definition) {
28746
- return definition && definition[symbolEvent];
28747
- }
28748
- __name(isEvent, "isEvent");
28749
- function isHook(definition) {
28750
- return definition && definition[symbolHook];
28751
- }
28752
- __name(isHook, "isHook");
28753
- function isTaskMiddleware(definition) {
28754
- return definition && definition[symbolTaskMiddleware];
28755
- }
28756
- __name(isTaskMiddleware, "isTaskMiddleware");
28757
- function isResourceMiddleware(definition) {
28758
- return definition && definition[symbolResourceMiddleware];
28759
- }
28760
- __name(isResourceMiddleware, "isResourceMiddleware");
28761
- function isTag(definition) {
28762
- return definition && definition[symbolTag];
28763
- }
28764
- __name(isTag, "isTag");
28765
- function isOptional(definition) {
28766
- return definition && definition[symbolOptionalDependency];
28767
- }
28768
- __name(isOptional, "isOptional");
28769
- function isError(definition) {
28770
- return Boolean(definition && definition[symbolError]);
28771
- }
28772
- __name(isError, "isError");
28773
- function isAsyncContext(definition) {
28774
- return Boolean(definition && definition[symbolAsyncContext]);
28775
- }
28776
- __name(isAsyncContext, "isAsyncContext");
28777
-
28778
- // src/tools/throws.ts
28779
- function invalidThrowsEntryError(owner, item) {
28780
- const got = item === null ? "null" : Array.isArray(item) ? "array" : typeof item === "object" ? "object" : typeof item;
28781
- return new Error(
28782
- `Invalid throws entry for ${owner.kind} ${owner.id}: expected error id string or Error helper, got ${got}`
28783
- );
28784
- }
28785
- __name(invalidThrowsEntryError, "invalidThrowsEntryError");
28786
- function toErrorIdList(owner, list) {
28787
- const ids = [];
28788
- const seen = /* @__PURE__ */ new Set();
28789
- for (const item of list) {
28790
- let id2;
28791
- if (typeof item === "string") {
28792
- if (item.trim().length === 0) {
28793
- throw invalidThrowsEntryError(owner, item);
28794
- }
28795
- id2 = item;
28796
- } else if (isError(item)) {
28797
- id2 = item.id;
28798
- if (typeof id2 !== "string" || id2.trim().length === 0) {
28799
- throw invalidThrowsEntryError(owner, item);
28800
- }
28801
- } else {
28802
- throw invalidThrowsEntryError(owner, item);
28803
- }
28804
- if (seen.has(id2)) continue;
28805
- seen.add(id2);
28806
- ids.push(id2);
28807
- }
28808
- return ids;
28809
- }
28810
- __name(toErrorIdList, "toErrorIdList");
28811
- function normalizeThrows(owner, throwsList) {
28812
- if (throwsList === void 0) return void 0;
28813
- return toErrorIdList(owner, throwsList);
28814
- }
28815
- __name(normalizeThrows, "normalizeThrows");
28816
-
28817
- // src/definers/defineTask.ts
28818
- function defineTask(taskConfig) {
28819
- const filePath = getCallerFile();
28820
- const id2 = taskConfig.id;
28821
- return {
28822
- [symbolTask]: true,
28823
- [symbolFilePath]: filePath,
28824
- id: id2,
28825
- dependencies: taskConfig.dependencies || {},
28826
- middleware: taskConfig.middleware || [],
28827
- run: taskConfig.run,
28828
- inputSchema: taskConfig.inputSchema,
28829
- resultSchema: taskConfig.resultSchema,
28830
- meta: taskConfig.meta || {},
28831
- tags: taskConfig.tags || [],
28832
- throws: normalizeThrows({ kind: "task", id: id2 }, taskConfig.throws),
28833
- // autorun,
28834
- optional() {
28835
- return {
28836
- inner: this,
28837
- [symbolOptionalDependency]: true
28838
- };
28839
- }
28840
- };
28841
- }
28842
- __name(defineTask, "defineTask");
28843
- defineTask.phantom = (taskConfig) => {
28844
- const taskDef = defineTask({
28845
- ...taskConfig,
28846
- run: /* @__PURE__ */ __name(async (_input) => {
28847
- return void 0;
28848
- }, "run")
28849
- });
28850
- taskDef[symbolPhantomTask] = true;
28851
- return taskDef;
28852
- };
28853
-
28854
- // src/definers/defineHook.ts
28855
- function defineHook(hookDef) {
28856
- const filePath = getCallerFile();
28857
- return {
28858
- [symbolHook]: true,
28859
- [symbolFilePath]: filePath,
28860
- id: hookDef.id,
28861
- dependencies: hookDef.dependencies || {},
28862
- on: hookDef.on,
28863
- order: hookDef.order,
28864
- run: hookDef.run,
28865
- meta: hookDef.meta || {},
28866
- tags: hookDef.tags || []
28867
- };
28868
- }
28869
- __name(defineHook, "defineHook");
28870
-
28871
- // src/errors.ts
28872
- var errors_exports = {};
28873
- __export(errors_exports, {
28874
- builderIncompleteError: () => builderIncompleteError,
28875
- cancellationError: () => cancellationError,
28876
- circularDependenciesError: () => circularDependenciesError,
28877
- contextError: () => contextError,
28878
- dependencyNotFoundError: () => dependencyNotFoundError,
28879
- duplicateRegistrationError: () => duplicateRegistrationError,
28880
- eventCycleError: () => eventCycleError,
28881
- eventEmissionCycleError: () => eventEmissionCycleError,
28882
- eventNotFoundError: () => eventNotFoundError,
28883
- isCancellationError: () => isCancellationError,
28884
- lockedError: () => lockedError,
28885
- middlewareNotRegisteredError: () => middlewareNotRegisteredError,
28886
- phantomTaskNotRoutedError: () => phantomTaskNotRoutedError,
28887
- platformUnsupportedFunctionError: () => platformUnsupportedFunctionError,
28888
- resourceNotFoundError: () => resourceNotFoundError,
28889
- storeAlreadyInitializedError: () => storeAlreadyInitializedError,
28890
- tagNotFoundError: () => tagNotFoundError,
28891
- taskNotRegisteredError: () => taskNotRegisteredError,
28892
- tunnelOwnershipConflictError: () => tunnelOwnershipConflictError,
28893
- unknownItemTypeError: () => unknownItemTypeError,
28894
- validationError: () => validationError
28895
- });
28896
-
28897
27798
  // src/definers/defineError.ts
28898
27799
  var isValidHttpCode = /* @__PURE__ */ __name((value) => Number.isInteger(value) && value >= 100 && value <= 599, "isValidHttpCode");
28899
27800
  var assertHttpCode = /* @__PURE__ */ __name((value) => {
@@ -29231,20 +28132,67 @@ var EdgePlatformAdapter = class extends BrowserPlatformAdapter {
29231
28132
  constructor() {
29232
28133
  super(...arguments);
29233
28134
  this.id = "edge";
28135
+ this.alsClass = null;
28136
+ this.alsProbed = false;
29234
28137
  }
29235
28138
  static {
29236
28139
  __name(this, "EdgePlatformAdapter");
29237
28140
  }
28141
+ async init() {
28142
+ await this.probeAsyncLocalStorage();
28143
+ }
28144
+ /**
28145
+ * Attempt to discover AsyncLocalStorage from the runtime.
28146
+ * Checks globalThis first, then tries `import("node:async_hooks")`.
28147
+ */
28148
+ probeGlobalAsyncLocalStorage() {
28149
+ if (this.alsClass) return true;
28150
+ const g = globalThis;
28151
+ if (typeof g.AsyncLocalStorage === "function") {
28152
+ this.alsClass = g.AsyncLocalStorage;
28153
+ return true;
28154
+ }
28155
+ return false;
28156
+ }
28157
+ async probeAsyncLocalStorage() {
28158
+ if (this.alsProbed) return;
28159
+ if (this.probeGlobalAsyncLocalStorage()) {
28160
+ this.alsProbed = true;
28161
+ return;
28162
+ }
28163
+ try {
28164
+ const mod = await import('async_hooks');
28165
+ if (mod?.AsyncLocalStorage) {
28166
+ this.alsClass = mod.AsyncLocalStorage;
28167
+ }
28168
+ } catch {
28169
+ } finally {
28170
+ this.alsProbed = true;
28171
+ }
28172
+ }
29238
28173
  onShutdownSignal(_handler) {
29239
28174
  return () => {
29240
28175
  };
29241
28176
  }
28177
+ hasAsyncLocalStorage() {
28178
+ this.probeGlobalAsyncLocalStorage();
28179
+ return this.alsClass !== null;
28180
+ }
28181
+ createAsyncLocalStorage() {
28182
+ this.probeGlobalAsyncLocalStorage();
28183
+ if (this.alsClass) {
28184
+ return new this.alsClass();
28185
+ }
28186
+ return super.createAsyncLocalStorage();
28187
+ }
29242
28188
  };
29243
28189
 
29244
28190
  // src/platform/adapters/universal-generic.ts
29245
28191
  var GenericUniversalPlatformAdapter = class {
29246
28192
  constructor() {
29247
28193
  this.id = "universal";
28194
+ this.alsClass = null;
28195
+ this.alsProbed = false;
29248
28196
  this.setTimeout = globalThis.setTimeout;
29249
28197
  this.clearTimeout = globalThis.clearTimeout;
29250
28198
  }
@@ -29253,6 +28201,23 @@ var GenericUniversalPlatformAdapter = class {
29253
28201
  }
29254
28202
  async init() {
29255
28203
  }
28204
+ probeAsyncLocalStorage() {
28205
+ if (this.alsProbed) return;
28206
+ this.alsProbed = true;
28207
+ const g = globalThis;
28208
+ if (typeof g.Deno === "undefined") return;
28209
+ if (typeof g.AsyncLocalStorage === "function") {
28210
+ this.alsClass = g.AsyncLocalStorage;
28211
+ return;
28212
+ }
28213
+ try {
28214
+ const mod = __require("async_hooks");
28215
+ if (mod?.AsyncLocalStorage) {
28216
+ this.alsClass = mod.AsyncLocalStorage;
28217
+ }
28218
+ } catch {
28219
+ }
28220
+ }
29256
28221
  onUncaughtException(handler) {
29257
28222
  const tgt = globalThis;
29258
28223
  if (tgt.addEventListener) {
@@ -29307,9 +28272,14 @@ var GenericUniversalPlatformAdapter = class {
29307
28272
  return void 0;
29308
28273
  }
29309
28274
  hasAsyncLocalStorage() {
29310
- return false;
28275
+ this.probeAsyncLocalStorage();
28276
+ return this.alsClass !== null;
29311
28277
  }
29312
28278
  createAsyncLocalStorage() {
28279
+ this.probeAsyncLocalStorage();
28280
+ if (this.alsClass) {
28281
+ return new this.alsClass();
28282
+ }
29313
28283
  return {
29314
28284
  getStore: /* @__PURE__ */ __name(() => {
29315
28285
  platformUnsupportedFunctionError.throw({
@@ -29367,6 +28337,10 @@ var UniversalPlatformAdapter = class {
29367
28337
  if (this.inner) return;
29368
28338
  const kind = detectEnvironment();
29369
28339
  const global2 = globalThis;
28340
+ if (typeof global2.Deno !== "undefined") {
28341
+ this.inner = new GenericUniversalPlatformAdapter();
28342
+ return;
28343
+ }
29370
28344
  if (typeof global2.document !== "undefined" || typeof global2.addEventListener === "function") {
29371
28345
  this.inner = new BrowserPlatformAdapter();
29372
28346
  } else {
@@ -29435,63 +28409,6 @@ function getPlatform() {
29435
28409
  return platformInstance;
29436
28410
  }
29437
28411
  __name(getPlatform, "getPlatform");
29438
- function setPlatform(adapter) {
29439
- platformInstance = adapter;
29440
- adapter.id;
29441
- }
29442
- __name(setPlatform, "setPlatform");
29443
- var PlatformAdapter = class {
29444
- static {
29445
- __name(this, "PlatformAdapter");
29446
- }
29447
- constructor(env) {
29448
- const kind = env ?? detectEnvironment();
29449
- this.env = kind;
29450
- switch (kind) {
29451
- case "node":
29452
- this.inner = new NodePlatformAdapter();
29453
- break;
29454
- case "browser":
29455
- this.inner = new BrowserPlatformAdapter();
29456
- break;
29457
- case "edge":
29458
- this.inner = new EdgePlatformAdapter();
29459
- break;
29460
- case "universal":
29461
- this.inner = new GenericUniversalPlatformAdapter();
29462
- break;
29463
- default:
29464
- this.inner = new UniversalPlatformAdapter();
29465
- }
29466
- this.id = this.inner.id;
29467
- this.setTimeout = this.inner.setTimeout;
29468
- this.clearTimeout = this.inner.clearTimeout;
29469
- }
29470
- async init() {
29471
- return this.inner.init();
29472
- }
29473
- onUncaughtException(handler) {
29474
- return this.inner.onUncaughtException(handler);
29475
- }
29476
- onUnhandledRejection(handler) {
29477
- return this.inner.onUnhandledRejection(handler);
29478
- }
29479
- onShutdownSignal(handler) {
29480
- return this.inner.onShutdownSignal(handler);
29481
- }
29482
- exit(code) {
29483
- return this.inner.exit(code);
29484
- }
29485
- getEnv(key) {
29486
- return this.inner.getEnv(key);
29487
- }
29488
- hasAsyncLocalStorage() {
29489
- return this.inner.hasAsyncLocalStorage();
29490
- }
29491
- createAsyncLocalStorage() {
29492
- return this.inner.createAsyncLocalStorage();
29493
- }
29494
- };
29495
28412
 
29496
28413
  // src/errors.ts
29497
28414
  var duplicateRegistrationError = error("runner.errors.duplicateRegistration").format(
@@ -29540,7 +28457,7 @@ var eventNotFoundError = error(
29540
28457
  ).remediation(
29541
28458
  ({ 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().`
29542
28459
  ).build();
29543
- var resourceNotFoundError = error(
28460
+ error(
29544
28461
  "runner.errors.resourceNotFound"
29545
28462
  ).format(
29546
28463
  ({ id: id2 }) => `Resource "${id2.toString()}" not found. Did you forget to register it or are you using the correct id?`
@@ -29628,10 +28545,145 @@ var builderIncompleteError = error("runner.errors.builderIncomplete").format(({
29628
28545
  }).remediation(
29629
28546
  ({ missingFields }) => `Add the missing builder steps: ${missingFields.map((f) => `.${f}()`).join(", ")} before calling .build().`
29630
28547
  ).build();
29631
- function isCancellationError(err) {
29632
- return cancellationError.is(err);
28548
+
28549
+ // src/definers/tools.ts
28550
+ function isTask(definition) {
28551
+ return definition && definition[symbolTask];
28552
+ }
28553
+ __name(isTask, "isTask");
28554
+ function isResource(definition) {
28555
+ return definition && definition[symbolResource];
28556
+ }
28557
+ __name(isResource, "isResource");
28558
+ function isResourceWithConfig(definition) {
28559
+ return definition && definition[symbolResourceWithConfig];
28560
+ }
28561
+ __name(isResourceWithConfig, "isResourceWithConfig");
28562
+ function isEvent(definition) {
28563
+ return definition && definition[symbolEvent];
28564
+ }
28565
+ __name(isEvent, "isEvent");
28566
+ function isHook(definition) {
28567
+ return definition && definition[symbolHook];
28568
+ }
28569
+ __name(isHook, "isHook");
28570
+ function isTaskMiddleware(definition) {
28571
+ return definition && definition[symbolTaskMiddleware];
28572
+ }
28573
+ __name(isTaskMiddleware, "isTaskMiddleware");
28574
+ function isResourceMiddleware(definition) {
28575
+ return definition && definition[symbolResourceMiddleware];
28576
+ }
28577
+ __name(isResourceMiddleware, "isResourceMiddleware");
28578
+ function isTag(definition) {
28579
+ return definition && definition[symbolTag];
28580
+ }
28581
+ __name(isTag, "isTag");
28582
+ function isOptional(definition) {
28583
+ return definition && definition[symbolOptionalDependency];
28584
+ }
28585
+ __name(isOptional, "isOptional");
28586
+ function isError(definition) {
28587
+ return Boolean(definition && definition[symbolError]);
28588
+ }
28589
+ __name(isError, "isError");
28590
+ function isAsyncContext(definition) {
28591
+ return Boolean(definition && definition[symbolAsyncContext]);
28592
+ }
28593
+ __name(isAsyncContext, "isAsyncContext");
28594
+
28595
+ // src/tools/throws.ts
28596
+ function invalidThrowsEntryError(owner, item) {
28597
+ const got = item === null ? "null" : Array.isArray(item) ? "array" : typeof item === "object" ? "object" : typeof item;
28598
+ return new Error(
28599
+ `Invalid throws entry for ${owner.kind} ${owner.id}: expected error id string or Error helper, got ${got}`
28600
+ );
28601
+ }
28602
+ __name(invalidThrowsEntryError, "invalidThrowsEntryError");
28603
+ function toErrorIdList(owner, list) {
28604
+ const ids = [];
28605
+ const seen = /* @__PURE__ */ new Set();
28606
+ for (const item of list) {
28607
+ let id2;
28608
+ if (typeof item === "string") {
28609
+ if (item.trim().length === 0) {
28610
+ throw invalidThrowsEntryError(owner, item);
28611
+ }
28612
+ id2 = item;
28613
+ } else if (isError(item)) {
28614
+ id2 = item.id;
28615
+ if (typeof id2 !== "string" || id2.trim().length === 0) {
28616
+ throw invalidThrowsEntryError(owner, item);
28617
+ }
28618
+ } else {
28619
+ throw invalidThrowsEntryError(owner, item);
28620
+ }
28621
+ if (seen.has(id2)) continue;
28622
+ seen.add(id2);
28623
+ ids.push(id2);
28624
+ }
28625
+ return ids;
28626
+ }
28627
+ __name(toErrorIdList, "toErrorIdList");
28628
+ function normalizeThrows(owner, throwsList) {
28629
+ if (throwsList === void 0) return void 0;
28630
+ return toErrorIdList(owner, throwsList);
28631
+ }
28632
+ __name(normalizeThrows, "normalizeThrows");
28633
+
28634
+ // src/definers/defineTask.ts
28635
+ function defineTask(taskConfig) {
28636
+ const filePath = getCallerFile();
28637
+ const id2 = taskConfig.id;
28638
+ return {
28639
+ [symbolTask]: true,
28640
+ [symbolFilePath]: filePath,
28641
+ id: id2,
28642
+ dependencies: taskConfig.dependencies || {},
28643
+ middleware: taskConfig.middleware || [],
28644
+ run: taskConfig.run,
28645
+ inputSchema: taskConfig.inputSchema,
28646
+ resultSchema: taskConfig.resultSchema,
28647
+ meta: taskConfig.meta || {},
28648
+ tags: taskConfig.tags || [],
28649
+ throws: normalizeThrows({ kind: "task", id: id2 }, taskConfig.throws),
28650
+ // autorun,
28651
+ optional() {
28652
+ return {
28653
+ inner: this,
28654
+ [symbolOptionalDependency]: true
28655
+ };
28656
+ }
28657
+ };
28658
+ }
28659
+ __name(defineTask, "defineTask");
28660
+ defineTask.phantom = (taskConfig) => {
28661
+ const taskDef = defineTask({
28662
+ ...taskConfig,
28663
+ run: /* @__PURE__ */ __name(async (_input) => {
28664
+ phantomTaskNotRoutedError.throw({ taskId: taskConfig.id });
28665
+ }, "run")
28666
+ });
28667
+ taskDef[symbolPhantomTask] = true;
28668
+ return taskDef;
28669
+ };
28670
+
28671
+ // src/definers/defineHook.ts
28672
+ function defineHook(hookDef) {
28673
+ const filePath = getCallerFile();
28674
+ return {
28675
+ [symbolHook]: true,
28676
+ [symbolFilePath]: filePath,
28677
+ id: hookDef.id,
28678
+ dependencies: hookDef.dependencies || {},
28679
+ on: hookDef.on,
28680
+ order: hookDef.order,
28681
+ run: hookDef.run,
28682
+ meta: hookDef.meta || {},
28683
+ tags: hookDef.tags || []
28684
+ };
29633
28685
  }
29634
- __name(isCancellationError, "isCancellationError");
28686
+ __name(defineHook, "defineHook");
29635
28687
 
29636
28688
  // src/definers/resourceFork.ts
29637
28689
  function resolveReId(forkId, options) {
@@ -30126,12 +29178,6 @@ var SymbolPolicy = /* @__PURE__ */ ((SymbolPolicy2) => {
30126
29178
  SymbolPolicy2["Disabled"] = "Disabled";
30127
29179
  return SymbolPolicy2;
30128
29180
  })(SymbolPolicy || {});
30129
- var SymbolPolicyErrorMessage = /* @__PURE__ */ ((SymbolPolicyErrorMessage2) => {
30130
- SymbolPolicyErrorMessage2["GlobalSymbolsNotAllowed"] = "Global symbols are not allowed";
30131
- SymbolPolicyErrorMessage2["SymbolsNotAllowed"] = "Symbols are not allowed";
30132
- SymbolPolicyErrorMessage2["UnsupportedSymbolPolicy"] = "Unsupported symbol policy";
30133
- return SymbolPolicyErrorMessage2;
30134
- })(SymbolPolicyErrorMessage || {});
30135
29181
 
30136
29182
  // src/serializer/binary-builtins.ts
30137
29183
  var INVALID_PAYLOAD_MESSAGE_PREFIX = "Invalid";
@@ -30639,8 +29685,124 @@ var builtInTypes = [
30639
29685
  ...binaryBuiltInTypes
30640
29686
  ];
30641
29687
 
29688
+ // src/serializer/regexp-validator.ts
29689
+ var isQuantifierAt = /* @__PURE__ */ __name((pattern, index) => {
29690
+ if (index >= pattern.length) {
29691
+ return false;
29692
+ }
29693
+ const char = pattern[index];
29694
+ if (char === "*" || char === "+" || char === "?") {
29695
+ return true;
29696
+ }
29697
+ if (char === "{") {
29698
+ return isBoundedQuantifier(pattern, index);
29699
+ }
29700
+ return false;
29701
+ }, "isQuantifierAt");
29702
+ var isQuantifierChar = /* @__PURE__ */ __name((char, pattern, index) => {
29703
+ if (char === "*" || char === "+") {
29704
+ return true;
29705
+ }
29706
+ if (char === "?") {
29707
+ if (index > 0 && pattern[index - 1] === "(") {
29708
+ return false;
29709
+ }
29710
+ return true;
29711
+ }
29712
+ if (char === "{") {
29713
+ return isBoundedQuantifier(pattern, index);
29714
+ }
29715
+ return false;
29716
+ }, "isQuantifierChar");
29717
+ var isBoundedQuantifier = /* @__PURE__ */ __name((pattern, index) => {
29718
+ let sawDigit = false;
29719
+ let sawComma = false;
29720
+ for (let i = index + 1; i < pattern.length; i += 1) {
29721
+ const char = pattern[i];
29722
+ if (char >= "0" && char <= "9") {
29723
+ sawDigit = true;
29724
+ continue;
29725
+ }
29726
+ if (char === "," && !sawComma) {
29727
+ sawComma = true;
29728
+ continue;
29729
+ }
29730
+ if (char === "}") {
29731
+ return sawDigit;
29732
+ }
29733
+ return false;
29734
+ }
29735
+ return false;
29736
+ }, "isBoundedQuantifier");
29737
+ var isRegExpPatternSafe = /* @__PURE__ */ __name((pattern) => {
29738
+ const groupStack = [];
29739
+ let escaped = false;
29740
+ let inCharClass = false;
29741
+ for (let index = 0; index < pattern.length; index += 1) {
29742
+ const char = pattern[index];
29743
+ if (escaped) {
29744
+ escaped = false;
29745
+ continue;
29746
+ }
29747
+ if (char === "\\") {
29748
+ escaped = true;
29749
+ continue;
29750
+ }
29751
+ if (inCharClass) {
29752
+ if (char === "]") {
29753
+ inCharClass = false;
29754
+ }
29755
+ continue;
29756
+ }
29757
+ if (char === "[") {
29758
+ inCharClass = true;
29759
+ continue;
29760
+ }
29761
+ if (char === "(") {
29762
+ groupStack.push({ hasQuantifier: false });
29763
+ if (pattern[index + 1] === "?") {
29764
+ index += 1;
29765
+ }
29766
+ continue;
29767
+ }
29768
+ if (char === ")") {
29769
+ const group = groupStack.pop();
29770
+ if (group?.hasQuantifier && isQuantifierAt(pattern, index + 1)) {
29771
+ return false;
29772
+ }
29773
+ if (group?.hasQuantifier && groupStack.length > 0) {
29774
+ groupStack[groupStack.length - 1].hasQuantifier = true;
29775
+ }
29776
+ continue;
29777
+ }
29778
+ if (isQuantifierChar(char, pattern, index)) {
29779
+ if (groupStack.length > 0) {
29780
+ groupStack[groupStack.length - 1].hasQuantifier = true;
29781
+ }
29782
+ }
29783
+ }
29784
+ return true;
29785
+ }, "isRegExpPatternSafe");
29786
+ var assertRegExpPayload = /* @__PURE__ */ __name((value, options) => {
29787
+ if (!value || typeof value !== "object") {
29788
+ throw new Error("Invalid RegExp payload");
29789
+ }
29790
+ const record = value;
29791
+ if (typeof record.pattern !== "string" || typeof record.flags !== "string") {
29792
+ throw new Error("Invalid RegExp payload");
29793
+ }
29794
+ if (record.pattern.length > options.maxPatternLength) {
29795
+ throw new Error(
29796
+ `RegExp pattern exceeds limit (${options.maxPatternLength})`
29797
+ );
29798
+ }
29799
+ if (!options.allowUnsafe && !isRegExpPatternSafe(record.pattern)) {
29800
+ throw new Error("Unsafe RegExp pattern");
29801
+ }
29802
+ return { pattern: record.pattern, flags: record.flags };
29803
+ }, "assertRegExpPayload");
29804
+
30642
29805
  // src/serializer/type-registry.ts
30643
- init_regexp_validator();
30644
29806
  var TypeRegistry = class {
30645
29807
  constructor(options) {
30646
29808
  this.typeRegistry = /* @__PURE__ */ new Map();
@@ -31399,29 +30561,25 @@ var Serializer = class {
31399
30561
  * @internal - Exposed for testing RegExp safety validation
31400
30562
  */
31401
30563
  this.isRegExpPatternSafe = /* @__PURE__ */ __name((pattern) => {
31402
- const { isRegExpPatternSafe: check } = (init_regexp_validator(), __toCommonJS(regexp_validator_exports));
31403
- return check(pattern);
30564
+ return isRegExpPatternSafe(pattern);
31404
30565
  }, "isRegExpPatternSafe");
31405
30566
  /**
31406
30567
  * @internal - Exposed for testing quantifier detection
31407
30568
  */
31408
30569
  this.isQuantifierAt = /* @__PURE__ */ __name((pattern, index) => {
31409
- const { isQuantifierAt: check } = (init_regexp_validator(), __toCommonJS(regexp_validator_exports));
31410
- return check(pattern, index);
30570
+ return isQuantifierAt(pattern, index);
31411
30571
  }, "isQuantifierAt");
31412
30572
  /**
31413
30573
  * @internal - Exposed for testing quantifier character detection
31414
30574
  */
31415
30575
  this.isQuantifierChar = /* @__PURE__ */ __name((char, pattern, index) => {
31416
- const { isQuantifierChar: check } = (init_regexp_validator(), __toCommonJS(regexp_validator_exports));
31417
- return check(char, pattern, index);
30576
+ return isQuantifierChar(char, pattern, index);
31418
30577
  }, "isQuantifierChar");
31419
30578
  /**
31420
30579
  * @internal - Exposed for testing bounded quantifier detection
31421
30580
  */
31422
30581
  this.isBoundedQuantifier = /* @__PURE__ */ __name((pattern, index) => {
31423
- const { isBoundedQuantifier: check } = (init_regexp_validator(), __toCommonJS(regexp_validator_exports));
31424
- return check(pattern, index);
30582
+ return isBoundedQuantifier(pattern, index);
31425
30583
  }, "isBoundedQuantifier");
31426
30584
  this.indent = options.pretty ? 2 : void 0;
31427
30585
  this.maxDepth = normalizeMaxDepth(options.maxDepth, DEFAULT_MAX_DEPTH);
@@ -31624,11 +30782,6 @@ function defineAsyncContext(def, filePath) {
31624
30782
  return api;
31625
30783
  }
31626
30784
  __name(defineAsyncContext, "defineAsyncContext");
31627
- function createContext(name) {
31628
- const id2 = name ?? `context.${Math.random().toString(36).slice(2)}.${Date.now()}`;
31629
- return defineAsyncContext({ id: id2 });
31630
- }
31631
- __name(createContext, "createContext");
31632
30785
 
31633
30786
  // src/globals/resources/debug/debug.tag.ts
31634
30787
  var debugTag = defineTag({
@@ -33118,11 +32271,218 @@ var queueResource = defineResource({
33118
32271
  }
33119
32272
  });
33120
32273
 
33121
- // src/http-client.ts
33122
- init_protocol();
33123
- init_http_fetch_tunnel_resource();
32274
+ // src/globals/resources/tunnel/protocol.ts
32275
+ var TunnelError = class extends Error {
32276
+ static {
32277
+ __name(this, "TunnelError");
32278
+ }
32279
+ constructor(code, message, details, extras) {
32280
+ super(message);
32281
+ this.name = "TunnelError";
32282
+ this.code = code;
32283
+ this.details = details;
32284
+ this.httpCode = extras?.httpCode;
32285
+ this.id = extras?.id;
32286
+ this.data = extras?.data;
32287
+ }
32288
+ };
32289
+ function toTunnelError(input, fallbackMessage) {
32290
+ if (input instanceof Error) {
32291
+ return new TunnelError("UNKNOWN", input.message);
32292
+ }
32293
+ if (input && typeof input === "object" && "code" in input && "message" in input) {
32294
+ const typed = input;
32295
+ if (typeof typed.message === "string" && typeof typed.code === "string") {
32296
+ const pe = input;
32297
+ const msg = pe.message || fallbackMessage || "Tunnel error";
32298
+ return new TunnelError(pe.code, msg, pe.details, {
32299
+ httpCode: pe.httpCode,
32300
+ id: pe.id,
32301
+ data: pe.data
32302
+ });
32303
+ }
32304
+ }
32305
+ if (input && typeof input === "object" && "message" in input) {
32306
+ const typed = input;
32307
+ if (typeof typed.message === "string") {
32308
+ return new TunnelError("UNKNOWN", typed.message);
32309
+ }
32310
+ }
32311
+ return new TunnelError(
32312
+ "UNKNOWN",
32313
+ typeof input === "string" && input || fallbackMessage || "Tunnel error"
32314
+ );
32315
+ }
32316
+ __name(toTunnelError, "toTunnelError");
32317
+ function assertOkEnvelope(envelope, opts) {
32318
+ if (!envelope || typeof envelope !== "object") {
32319
+ throw new TunnelError(
32320
+ "INVALID_RESPONSE",
32321
+ opts?.fallbackMessage || "Invalid or empty response"
32322
+ );
32323
+ }
32324
+ if (envelope.ok) {
32325
+ return envelope.result;
32326
+ }
32327
+ if (envelope.error) {
32328
+ return (() => {
32329
+ throw toTunnelError(envelope.error, opts?.fallbackMessage);
32330
+ })();
32331
+ }
32332
+ throw new TunnelError("UNKNOWN", opts?.fallbackMessage || "Tunnel error");
32333
+ }
32334
+ __name(assertOkEnvelope, "assertOkEnvelope");
33124
32335
 
33125
- // src/tunnels/buildUniversalManifest.ts
32336
+ // src/http-fetch-tunnel.resource.ts
32337
+ async function postSerialized(options) {
32338
+ const {
32339
+ fetch: fetchFn,
32340
+ url,
32341
+ body,
32342
+ headers,
32343
+ timeoutMs,
32344
+ serializer: serializer3,
32345
+ onRequest,
32346
+ contextHeaderText
32347
+ } = options;
32348
+ const controller = timeoutMs && timeoutMs > 0 ? new AbortController() : void 0;
32349
+ let timeout;
32350
+ try {
32351
+ if (controller) {
32352
+ timeout = setTimeout(() => controller.abort(), timeoutMs);
32353
+ }
32354
+ const reqHeaders = {
32355
+ "content-type": "application/json; charset=utf-8",
32356
+ ...headers
32357
+ };
32358
+ if (contextHeaderText) reqHeaders["x-runner-context"] = contextHeaderText;
32359
+ if (onRequest) await onRequest({ url, headers: reqHeaders });
32360
+ const res = await fetchFn(url, {
32361
+ method: "POST",
32362
+ headers: reqHeaders,
32363
+ body: serializer3.stringify(body),
32364
+ signal: controller?.signal
32365
+ });
32366
+ const text = await res.text();
32367
+ const json2 = text ? serializer3.parse(text) : void 0;
32368
+ return json2;
32369
+ } finally {
32370
+ if (timeout) clearTimeout(timeout);
32371
+ }
32372
+ }
32373
+ __name(postSerialized, "postSerialized");
32374
+ function createExposureFetch(cfg) {
32375
+ const baseUrl = cfg?.baseUrl?.replace(/\/$/, "");
32376
+ if (!baseUrl) throw new Error("createExposureFetch requires baseUrl");
32377
+ const headerName = (cfg?.auth?.header ?? "x-runner-token").toLowerCase();
32378
+ const buildHeaders = /* @__PURE__ */ __name(() => {
32379
+ const headers = {};
32380
+ if (cfg?.auth?.token) headers[headerName] = cfg.auth.token;
32381
+ return headers;
32382
+ }, "buildHeaders");
32383
+ const fetchImpl = cfg.fetchImpl ?? globalThis.fetch;
32384
+ if (typeof fetchImpl !== "function") {
32385
+ throw new Error(
32386
+ "global fetch is not available; provide fetchImpl in config"
32387
+ );
32388
+ }
32389
+ const buildContextHeader = /* @__PURE__ */ __name(() => {
32390
+ if (!cfg.contexts || cfg.contexts.length === 0) return void 0;
32391
+ const map = {};
32392
+ for (const ctx of cfg.contexts) {
32393
+ try {
32394
+ const v = ctx.use();
32395
+ map[ctx.id] = ctx.serialize(v);
32396
+ } catch {
32397
+ }
32398
+ }
32399
+ const keys = Object.keys(map);
32400
+ if (keys.length === 0) return void 0;
32401
+ return cfg.serializer.stringify(map);
32402
+ }, "buildContextHeader");
32403
+ return {
32404
+ async task(id2, input) {
32405
+ const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
32406
+ const r2 = await postSerialized({
32407
+ fetch: fetchImpl,
32408
+ url,
32409
+ body: { input },
32410
+ headers: buildHeaders(),
32411
+ timeoutMs: cfg?.timeoutMs,
32412
+ serializer: cfg.serializer,
32413
+ onRequest: cfg?.onRequest,
32414
+ contextHeaderText: buildContextHeader()
32415
+ });
32416
+ try {
32417
+ return assertOkEnvelope(r2, { fallbackMessage: "Tunnel task error" });
32418
+ } catch (e) {
32419
+ const te = e;
32420
+ if (cfg.errorRegistry && te.id && te.data) {
32421
+ const helper = cfg.errorRegistry.get(String(te.id));
32422
+ if (helper) helper.throw(te.data);
32423
+ }
32424
+ throw e;
32425
+ }
32426
+ },
32427
+ async event(id2, payload) {
32428
+ const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
32429
+ const r2 = await postSerialized({
32430
+ fetch: fetchImpl,
32431
+ url,
32432
+ body: { payload },
32433
+ headers: buildHeaders(),
32434
+ timeoutMs: cfg?.timeoutMs,
32435
+ serializer: cfg.serializer,
32436
+ onRequest: cfg?.onRequest,
32437
+ contextHeaderText: buildContextHeader()
32438
+ });
32439
+ try {
32440
+ assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
32441
+ } catch (e) {
32442
+ const te = e;
32443
+ if (cfg.errorRegistry && te.id && te.data) {
32444
+ const helper = cfg.errorRegistry.get(String(te.id));
32445
+ if (helper) helper.throw(te.data);
32446
+ }
32447
+ throw e;
32448
+ }
32449
+ },
32450
+ async eventWithResult(id2, payload) {
32451
+ const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
32452
+ const r2 = await postSerialized({
32453
+ fetch: fetchImpl,
32454
+ url,
32455
+ body: { payload, returnPayload: true },
32456
+ headers: buildHeaders(),
32457
+ timeoutMs: cfg?.timeoutMs,
32458
+ serializer: cfg.serializer,
32459
+ onRequest: cfg?.onRequest,
32460
+ contextHeaderText: buildContextHeader()
32461
+ });
32462
+ if (r2 && typeof r2 === "object" && r2.ok && !("result" in r2)) {
32463
+ throw new TunnelError(
32464
+ "INVALID_RESPONSE",
32465
+ "Tunnel event returnPayload requested but server did not include result. Upgrade the exposure server."
32466
+ );
32467
+ }
32468
+ try {
32469
+ return assertOkEnvelope(r2, {
32470
+ fallbackMessage: "Tunnel event error"
32471
+ });
32472
+ } catch (e) {
32473
+ const te = e;
32474
+ if (cfg.errorRegistry && te.id && te.data) {
32475
+ const helper = cfg.errorRegistry.get(String(te.id));
32476
+ if (helper) helper.throw(te.data);
32477
+ }
32478
+ throw e;
32479
+ }
32480
+ }
32481
+ };
32482
+ }
32483
+ __name(createExposureFetch, "createExposureFetch");
32484
+
32485
+ // src/tools/buildUniversalManifest.ts
33126
32486
  function buildUniversalManifest(input) {
33127
32487
  const nodeFiles = [];
33128
32488
  const webFiles = [];
@@ -33179,6 +32539,15 @@ function toHeaders(auth) {
33179
32539
  return headers;
33180
32540
  }
33181
32541
  __name(toHeaders, "toHeaders");
32542
+ function rethrowWithRegistry(e, errorRegistry) {
32543
+ const te = e;
32544
+ if (errorRegistry && te.id && te.data) {
32545
+ const helper = errorRegistry.get(String(te.id));
32546
+ if (helper) helper.throw(te.data);
32547
+ }
32548
+ throw e;
32549
+ }
32550
+ __name(rethrowWithRegistry, "rethrowWithRegistry");
33182
32551
  function createHttpClient(cfg) {
33183
32552
  const baseUrl = cfg.baseUrl.replace(/\/$/, "");
33184
32553
  if (!baseUrl) throw new Error("createHttpClient requires baseUrl");
@@ -33245,12 +32614,7 @@ function createHttpClient(cfg) {
33245
32614
  fallbackMessage: "Tunnel task error"
33246
32615
  });
33247
32616
  } catch (e) {
33248
- const te = e;
33249
- if (cfg.errorRegistry && te.id && te.data) {
33250
- const helper = cfg.errorRegistry.get(String(te.id));
33251
- if (helper) helper.throw(te.data);
33252
- }
33253
- throw e;
32617
+ rethrowWithRegistry(e, cfg.errorRegistry);
33254
32618
  }
33255
32619
  }
33256
32620
  if (manifest.nodeFiles.length > 0) {
@@ -33261,24 +32625,14 @@ function createHttpClient(cfg) {
33261
32625
  try {
33262
32626
  return await fetchClient.task(id2, input);
33263
32627
  } catch (e) {
33264
- const te = e;
33265
- if (cfg.errorRegistry && te.id && te.data) {
33266
- const helper = cfg.errorRegistry.get(String(te.id));
33267
- if (helper) helper.throw(te.data);
33268
- }
33269
- throw e;
32628
+ rethrowWithRegistry(e, cfg.errorRegistry);
33270
32629
  }
33271
32630
  },
33272
32631
  async event(id2, payload) {
33273
32632
  try {
33274
32633
  return await fetchClient.event(id2, payload);
33275
32634
  } catch (e) {
33276
- const te = e;
33277
- if (cfg.errorRegistry && te.id && te.data) {
33278
- const helper = cfg.errorRegistry.get(String(te.id));
33279
- if (helper) helper.throw(te.data);
33280
- }
33281
- throw e;
32635
+ rethrowWithRegistry(e, cfg.errorRegistry);
33282
32636
  }
33283
32637
  },
33284
32638
  async eventWithResult(id2, payload) {
@@ -33290,12 +32644,7 @@ function createHttpClient(cfg) {
33290
32644
  }
33291
32645
  return await fetchClient.eventWithResult(id2, payload);
33292
32646
  } catch (e) {
33293
- const te = e;
33294
- if (cfg.errorRegistry && te.id && te.data) {
33295
- const helper = cfg.errorRegistry.get(String(te.id));
33296
- if (helper) helper.throw(te.data);
33297
- }
33298
- throw e;
32647
+ rethrowWithRegistry(e, cfg.errorRegistry);
33299
32648
  }
33300
32649
  }
33301
32650
  };
@@ -34229,6 +33578,34 @@ var Logger = class _Logger {
34229
33578
  }
34230
33579
  };
34231
33580
 
33581
+ // src/models/utils/dependencyStrategies.ts
33582
+ var dependencyStrategies = [
33583
+ {
33584
+ matches: isResource,
33585
+ getStoreMap: /* @__PURE__ */ __name((store2) => store2.resources, "getStoreMap")
33586
+ },
33587
+ {
33588
+ matches: isTask,
33589
+ getStoreMap: /* @__PURE__ */ __name((store2) => store2.tasks, "getStoreMap")
33590
+ },
33591
+ {
33592
+ matches: isEvent,
33593
+ getStoreMap: /* @__PURE__ */ __name((store2) => store2.events, "getStoreMap")
33594
+ },
33595
+ {
33596
+ matches: isError,
33597
+ getStoreMap: /* @__PURE__ */ __name((store2) => store2.errors, "getStoreMap")
33598
+ },
33599
+ {
33600
+ matches: isAsyncContext,
33601
+ getStoreMap: /* @__PURE__ */ __name((store2) => store2.asyncContexts, "getStoreMap")
33602
+ }
33603
+ ];
33604
+ function findDependencyStrategy(item) {
33605
+ return dependencyStrategies.find((s) => s.matches(item));
33606
+ }
33607
+ __name(findDependencyStrategy, "findDependencyStrategy");
33608
+
34232
33609
  // src/models/DependencyProcessor.ts
34233
33610
  var DependencyProcessor = class {
34234
33611
  constructor(store2, eventManager, taskRunner, logger) {
@@ -34336,7 +33713,16 @@ var DependencyProcessor = class {
34336
33713
  }
34337
33714
  throw error2;
34338
33715
  }
34339
- throw new Error(`${prefix}: ${String(error2)}`);
33716
+ const wrapper = new Error(`${prefix}: ${String(error2)}`);
33717
+ Object.defineProperty(wrapper, "resourceId", {
33718
+ value: resourceId,
33719
+ configurable: true
33720
+ });
33721
+ Object.defineProperty(wrapper, "cause", {
33722
+ value: error2,
33723
+ configurable: true
33724
+ });
33725
+ throw wrapper;
34340
33726
  }
34341
33727
  /**
34342
33728
  * Computes and caches dependencies for a resource (if not already computed).
@@ -34479,46 +33865,35 @@ var DependencyProcessor = class {
34479
33865
  return object;
34480
33866
  }
34481
33867
  async extractDependency(object, source) {
34482
- this.logger.trace(`Extracting dependency -> ${source} -> ${object?.id}`);
33868
+ this.logger.trace(
33869
+ `Extracting dependency -> ${source} -> ${object?.id}`
33870
+ );
33871
+ let isOpt = false;
33872
+ let item = object;
34483
33873
  if (isOptional(object)) {
34484
- const inner = object.inner;
34485
- if (isResource(inner)) {
34486
- const exists = this.store.resources.get(inner.id) !== void 0;
34487
- return exists ? this.extractResourceDependency(inner) : void 0;
34488
- } else if (isTask(inner)) {
34489
- const exists = this.store.tasks.get(inner.id) !== void 0;
34490
- return exists ? this.extractTaskDependency(inner) : void 0;
34491
- } else if (isEvent(inner)) {
34492
- const exists = this.store.events.get(inner.id) !== void 0;
34493
- return exists ? this.extractEventDependency(inner, source) : void 0;
34494
- } else if (isError(inner)) {
34495
- const exists = this.store.errors.get(inner.id) !== void 0;
34496
- return exists ? inner : void 0;
34497
- } else if (isAsyncContext(inner)) {
34498
- const exists = this.store.asyncContexts.get(inner.id) !== void 0;
34499
- return exists ? inner : void 0;
34500
- }
34501
- unknownItemTypeError.throw({ item: inner });
34502
- }
34503
- if (isResource(object)) {
34504
- return this.extractResourceDependency(object);
34505
- } else if (isTask(object)) {
34506
- return this.extractTaskDependency(object);
34507
- } else if (isEvent(object)) {
34508
- return this.extractEventDependency(object, source);
34509
- } else if (isError(object)) {
34510
- if (this.store.errors.get(object.id) === void 0) {
34511
- dependencyNotFoundError.throw({ key: `Error ${object.id}` });
34512
- }
34513
- return object;
34514
- } else if (isAsyncContext(object)) {
34515
- if (this.store.asyncContexts.get(object.id) === void 0) {
34516
- dependencyNotFoundError.throw({ key: `AsyncContext ${object.id}` });
34517
- }
34518
- return object;
34519
- } else {
34520
- unknownItemTypeError.throw({ item: object });
33874
+ isOpt = true;
33875
+ item = object.inner;
33876
+ }
33877
+ const itemWithId = item;
33878
+ const strategy = findDependencyStrategy(item);
33879
+ if (!strategy) {
33880
+ return unknownItemTypeError.throw({ item });
34521
33881
  }
33882
+ if (isOpt) {
33883
+ const exists = strategy.getStoreMap(this.store).has(itemWithId.id);
33884
+ if (!exists) return void 0;
33885
+ }
33886
+ if (isResource(item)) return this.extractResourceDependency(item);
33887
+ if (isTask(item)) return this.extractTaskDependency(item);
33888
+ if (isEvent(item)) return this.extractEventDependency(item, source);
33889
+ if (!isOpt) {
33890
+ const exists = strategy.getStoreMap(this.store).has(itemWithId.id);
33891
+ if (!exists) {
33892
+ const label = isError(item) ? "Error" : "AsyncContext";
33893
+ dependencyNotFoundError.throw({ key: `${label} ${itemWithId.id}` });
33894
+ }
33895
+ }
33896
+ return item;
34522
33897
  }
34523
33898
  /**
34524
33899
  * Converts the event into a running functions with real inputs
@@ -34715,19 +34090,246 @@ var StoreValidator = class {
34715
34090
  }
34716
34091
  };
34717
34092
 
34093
+ // src/models/utils/buildDependencyGraph.ts
34094
+ function setupBlankNodes(registry, nodeMap, dependents) {
34095
+ for (const task2 of registry.tasks.values()) {
34096
+ const node = {
34097
+ id: task2.task.id,
34098
+ dependencies: {}
34099
+ };
34100
+ nodeMap.set(task2.task.id, node);
34101
+ dependents.push(node);
34102
+ }
34103
+ for (const middleware of registry.taskMiddlewares.values()) {
34104
+ const node = {
34105
+ id: middleware.middleware.id,
34106
+ dependencies: {}
34107
+ };
34108
+ nodeMap.set(middleware.middleware.id, node);
34109
+ dependents.push(node);
34110
+ }
34111
+ for (const middleware of registry.resourceMiddlewares.values()) {
34112
+ const node = {
34113
+ id: middleware.middleware.id,
34114
+ dependencies: {}
34115
+ };
34116
+ nodeMap.set(middleware.middleware.id, node);
34117
+ dependents.push(node);
34118
+ }
34119
+ for (const resource2 of registry.resources.values()) {
34120
+ const node = {
34121
+ id: resource2.resource.id,
34122
+ dependencies: {}
34123
+ };
34124
+ nodeMap.set(resource2.resource.id, node);
34125
+ dependents.push(node);
34126
+ }
34127
+ for (const hook2 of registry.hooks.values()) {
34128
+ const node = {
34129
+ id: hook2.hook.id,
34130
+ dependencies: {}
34131
+ };
34132
+ nodeMap.set(hook2.hook.id, node);
34133
+ dependents.push(node);
34134
+ }
34135
+ }
34136
+ __name(setupBlankNodes, "setupBlankNodes");
34137
+ function buildDependencyGraph(registry) {
34138
+ const depenedants = [];
34139
+ const nodeMap = /* @__PURE__ */ new Map();
34140
+ setupBlankNodes(registry, nodeMap, depenedants);
34141
+ for (const task2 of registry.tasks.values()) {
34142
+ const node = nodeMap.get(task2.task.id);
34143
+ if (task2.task.dependencies) {
34144
+ for (const [depKey, depItem] of Object.entries(task2.task.dependencies)) {
34145
+ const candidate = isOptional(depItem) ? depItem.inner : depItem;
34146
+ const depNode = nodeMap.get(candidate.id);
34147
+ if (depNode) {
34148
+ node.dependencies[depKey] = depNode;
34149
+ }
34150
+ }
34151
+ }
34152
+ const t = task2.task;
34153
+ for (const middleware of t.middleware) {
34154
+ const middlewareNode = nodeMap.get(middleware.id);
34155
+ if (middlewareNode) {
34156
+ node.dependencies[middleware.id] = middlewareNode;
34157
+ }
34158
+ }
34159
+ }
34160
+ for (const storeTaskMiddleware of registry.taskMiddlewares.values()) {
34161
+ const node = nodeMap.get(storeTaskMiddleware.middleware.id);
34162
+ const { middleware } = storeTaskMiddleware;
34163
+ if (middleware.dependencies) {
34164
+ for (const [depKey, depItem] of Object.entries(middleware.dependencies)) {
34165
+ const candidate = isOptional(depItem) ? depItem.inner : depItem;
34166
+ const depNode = nodeMap.get(candidate.id);
34167
+ if (depNode) {
34168
+ node.dependencies[depKey] = depNode;
34169
+ }
34170
+ }
34171
+ }
34172
+ if (middleware.everywhere) {
34173
+ const filter = typeof middleware.everywhere === "function" ? middleware.everywhere : () => true;
34174
+ for (const task2 of registry.tasks.values()) {
34175
+ if (filter(task2.task)) {
34176
+ const taskNode = nodeMap.get(task2.task.id);
34177
+ taskNode.dependencies[`__middleware.${middleware.id}`] = node;
34178
+ }
34179
+ }
34180
+ }
34181
+ }
34182
+ for (const storeResourceMiddleware of registry.resourceMiddlewares.values()) {
34183
+ const node = nodeMap.get(storeResourceMiddleware.middleware.id);
34184
+ const { middleware } = storeResourceMiddleware;
34185
+ if (middleware.dependencies) {
34186
+ for (const [depKey, depItem] of Object.entries(middleware.dependencies)) {
34187
+ const candidate = isOptional(depItem) ? depItem.inner : depItem;
34188
+ const depNode = nodeMap.get(candidate.id);
34189
+ if (depNode) {
34190
+ node.dependencies[depKey] = depNode;
34191
+ }
34192
+ }
34193
+ }
34194
+ if (middleware.everywhere) {
34195
+ const filter = typeof middleware.everywhere === "function" ? middleware.everywhere : () => true;
34196
+ for (const resource2 of registry.resources.values()) {
34197
+ if (filter(resource2.resource)) {
34198
+ const resourceNode = nodeMap.get(resource2.resource.id);
34199
+ resourceNode.dependencies[`__middleware.${middleware.id}`] = node;
34200
+ }
34201
+ }
34202
+ }
34203
+ }
34204
+ for (const resource2 of registry.resources.values()) {
34205
+ const node = nodeMap.get(resource2.resource.id);
34206
+ if (resource2.resource.dependencies) {
34207
+ for (const [depKey, depItem] of Object.entries(
34208
+ resource2.resource.dependencies
34209
+ )) {
34210
+ const candidate = isOptional(depItem) ? depItem.inner : depItem;
34211
+ const depNode = nodeMap.get(candidate.id);
34212
+ if (depNode) {
34213
+ node.dependencies[depKey] = depNode;
34214
+ }
34215
+ }
34216
+ }
34217
+ for (const middleware of resource2.resource.middleware) {
34218
+ const middlewareNode = nodeMap.get(middleware.id);
34219
+ if (middlewareNode) {
34220
+ node.dependencies[middleware.id] = middlewareNode;
34221
+ }
34222
+ }
34223
+ }
34224
+ for (const hook2 of registry.hooks.values()) {
34225
+ const node = nodeMap.get(hook2.hook.id);
34226
+ if (hook2.hook.dependencies) {
34227
+ for (const [depKey, depItem] of Object.entries(hook2.hook.dependencies)) {
34228
+ const candidate = isOptional(depItem) ? depItem.inner : depItem;
34229
+ const depNode = nodeMap.get(candidate.id);
34230
+ if (depNode) {
34231
+ node.dependencies[depKey] = depNode;
34232
+ }
34233
+ }
34234
+ }
34235
+ }
34236
+ return depenedants;
34237
+ }
34238
+ __name(buildDependencyGraph, "buildDependencyGraph");
34239
+ function buildEventEmissionGraph(registry) {
34240
+ const nodes = /* @__PURE__ */ new Map();
34241
+ for (const e of registry.events.values()) {
34242
+ nodes.set(e.event.id, { id: e.event.id, dependencies: {} });
34243
+ }
34244
+ for (const h of registry.hooks.values()) {
34245
+ const listened = [];
34246
+ const on = h.hook.on;
34247
+ if (on === "*") continue;
34248
+ if (Array.isArray(on))
34249
+ listened.push(...on.map((e) => e.id));
34250
+ else listened.push(on.id);
34251
+ const depEvents = [];
34252
+ const deps = h.hook.dependencies;
34253
+ if (deps) {
34254
+ for (const value of Object.values(deps)) {
34255
+ const candidate = isOptional(value) ? value.inner : value;
34256
+ if (candidate && isEvent(candidate)) {
34257
+ depEvents.push(candidate.id);
34258
+ }
34259
+ }
34260
+ }
34261
+ for (const srcId of listened) {
34262
+ const srcNode = nodes.get(srcId);
34263
+ if (!srcNode) continue;
34264
+ for (const dstId of depEvents) {
34265
+ if (srcId === dstId) continue;
34266
+ const dstNode = nodes.get(dstId);
34267
+ if (dstNode) {
34268
+ srcNode.dependencies[dstId] = dstNode;
34269
+ }
34270
+ }
34271
+ }
34272
+ }
34273
+ return Array.from(nodes.values());
34274
+ }
34275
+ __name(buildEventEmissionGraph, "buildEventEmissionGraph");
34276
+
34277
+ // src/tools/LockableMap.ts
34278
+ var LockableMap = class extends Map {
34279
+ static {
34280
+ __name(this, "LockableMap");
34281
+ }
34282
+ #locked = false;
34283
+ #name;
34284
+ constructor(name) {
34285
+ super();
34286
+ this.#name = name ?? "LockableMap";
34287
+ }
34288
+ /** Whether the map is currently locked. */
34289
+ get locked() {
34290
+ return this.#locked;
34291
+ }
34292
+ /** Permanently lock the map — no further mutations allowed. */
34293
+ lock() {
34294
+ this.#locked = true;
34295
+ }
34296
+ /** @throws if the map is locked */
34297
+ throwIfLocked() {
34298
+ if (this.#locked) {
34299
+ throw new Error(`Cannot modify "${this.#name}" \u2014 the map is locked.`);
34300
+ }
34301
+ }
34302
+ set(key, value) {
34303
+ this.throwIfLocked();
34304
+ return super.set(key, value);
34305
+ }
34306
+ delete(key) {
34307
+ this.throwIfLocked();
34308
+ return super.delete(key);
34309
+ }
34310
+ clear() {
34311
+ this.throwIfLocked();
34312
+ super.clear();
34313
+ }
34314
+ };
34315
+
34718
34316
  // src/models/StoreRegistry.ts
34719
34317
  var StoreRegistry = class {
34720
34318
  constructor(store2) {
34721
34319
  this.store = store2;
34722
- this.tasks = /* @__PURE__ */ new Map();
34723
- this.resources = /* @__PURE__ */ new Map();
34724
- this.events = /* @__PURE__ */ new Map();
34725
- this.taskMiddlewares = /* @__PURE__ */ new Map();
34726
- this.resourceMiddlewares = /* @__PURE__ */ new Map();
34727
- this.hooks = /* @__PURE__ */ new Map();
34728
- this.tags = /* @__PURE__ */ new Map();
34729
- this.asyncContexts = /* @__PURE__ */ new Map();
34730
- this.errors = /* @__PURE__ */ new Map();
34320
+ this.tasks = new LockableMap("tasks");
34321
+ this.resources = new LockableMap(
34322
+ "resources"
34323
+ );
34324
+ this.events = new LockableMap("events");
34325
+ this.taskMiddlewares = new LockableMap("taskMiddlewares");
34326
+ this.resourceMiddlewares = new LockableMap("resourceMiddlewares");
34327
+ this.hooks = new LockableMap("hooks");
34328
+ this.tags = new LockableMap("tags");
34329
+ this.asyncContexts = new LockableMap(
34330
+ "asyncContexts"
34331
+ );
34332
+ this.errors = new LockableMap("errors");
34731
34333
  this.validator = new StoreValidator(this);
34732
34334
  }
34733
34335
  static {
@@ -34736,6 +34338,18 @@ var StoreRegistry = class {
34736
34338
  getValidator() {
34737
34339
  return this.validator;
34738
34340
  }
34341
+ /** Lock every map in the registry, preventing further mutations. */
34342
+ lockAll() {
34343
+ this.tasks.lock();
34344
+ this.resources.lock();
34345
+ this.events.lock();
34346
+ this.taskMiddlewares.lock();
34347
+ this.resourceMiddlewares.lock();
34348
+ this.hooks.lock();
34349
+ this.tags.lock();
34350
+ this.asyncContexts.lock();
34351
+ this.errors.lock();
34352
+ }
34739
34353
  storeGenericItem(item) {
34740
34354
  if (isTask(item)) {
34741
34355
  this.storeTask(item);
@@ -34872,195 +34486,14 @@ var StoreRegistry = class {
34872
34486
  }
34873
34487
  // Feels like a dependencyProcessor task?
34874
34488
  getDependentNodes() {
34875
- const depenedants = [];
34876
- const nodeMap = /* @__PURE__ */ new Map();
34877
- this.setupBlankNodes(nodeMap, depenedants);
34878
- for (const task2 of this.tasks.values()) {
34879
- const node = nodeMap.get(task2.task.id);
34880
- if (task2.task.dependencies) {
34881
- for (const [depKey, depItem] of Object.entries(
34882
- task2.task.dependencies
34883
- )) {
34884
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34885
- const depNode = nodeMap.get(candidate.id);
34886
- if (depNode) {
34887
- node.dependencies[depKey] = depNode;
34888
- }
34889
- }
34890
- }
34891
- const t = task2.task;
34892
- for (const middleware of t.middleware) {
34893
- const middlewareNode = nodeMap.get(middleware.id);
34894
- if (middlewareNode) {
34895
- node.dependencies[middleware.id] = middlewareNode;
34896
- }
34897
- }
34898
- }
34899
- for (const storeTaskMiddleware of this.taskMiddlewares.values()) {
34900
- const node = nodeMap.get(storeTaskMiddleware.middleware.id);
34901
- const { middleware } = storeTaskMiddleware;
34902
- if (middleware.dependencies) {
34903
- for (const [depKey, depItem] of Object.entries(
34904
- middleware.dependencies
34905
- )) {
34906
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34907
- const depNode = nodeMap.get(candidate.id);
34908
- if (depNode) {
34909
- node.dependencies[depKey] = depNode;
34910
- }
34911
- }
34912
- }
34913
- if (middleware.everywhere) {
34914
- const filter = typeof middleware.everywhere === "function" ? middleware.everywhere : () => true;
34915
- for (const task2 of this.tasks.values()) {
34916
- if (filter(task2.task)) {
34917
- const taskNode = nodeMap.get(task2.task.id);
34918
- taskNode.dependencies[`__middleware.${middleware.id}`] = node;
34919
- }
34920
- }
34921
- }
34922
- }
34923
- for (const storeResourceMiddleware of this.resourceMiddlewares.values()) {
34924
- const node = nodeMap.get(storeResourceMiddleware.middleware.id);
34925
- const { middleware } = storeResourceMiddleware;
34926
- if (middleware.dependencies) {
34927
- for (const [depKey, depItem] of Object.entries(
34928
- middleware.dependencies
34929
- )) {
34930
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34931
- const depNode = nodeMap.get(candidate.id);
34932
- if (depNode) {
34933
- node.dependencies[depKey] = depNode;
34934
- }
34935
- }
34936
- }
34937
- if (middleware.everywhere) {
34938
- const filter = typeof middleware.everywhere === "function" ? middleware.everywhere : () => true;
34939
- for (const resource2 of this.resources.values()) {
34940
- if (filter(resource2.resource)) {
34941
- const resourceNode = nodeMap.get(resource2.resource.id);
34942
- resourceNode.dependencies[`__middleware.${middleware.id}`] = node;
34943
- }
34944
- }
34945
- }
34946
- }
34947
- for (const resource2 of this.resources.values()) {
34948
- const node = nodeMap.get(resource2.resource.id);
34949
- if (resource2.resource.dependencies) {
34950
- for (const [depKey, depItem] of Object.entries(
34951
- resource2.resource.dependencies
34952
- )) {
34953
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34954
- const depNode = nodeMap.get(candidate.id);
34955
- if (depNode) {
34956
- node.dependencies[depKey] = depNode;
34957
- }
34958
- }
34959
- }
34960
- for (const middleware of resource2.resource.middleware) {
34961
- const middlewareNode = nodeMap.get(middleware.id);
34962
- if (middlewareNode) {
34963
- node.dependencies[middleware.id] = middlewareNode;
34964
- }
34965
- }
34966
- }
34967
- for (const hook2 of this.hooks.values()) {
34968
- const node = nodeMap.get(hook2.hook.id);
34969
- if (hook2.hook.dependencies) {
34970
- for (const [depKey, depItem] of Object.entries(
34971
- hook2.hook.dependencies
34972
- )) {
34973
- const candidate = isOptional(depItem) ? depItem.inner : depItem;
34974
- const depNode = nodeMap.get(candidate.id);
34975
- if (depNode) {
34976
- node.dependencies[depKey] = depNode;
34977
- }
34978
- }
34979
- }
34980
- }
34981
- return depenedants;
34489
+ return buildDependencyGraph(this);
34982
34490
  }
34983
34491
  /**
34984
34492
  * Builds a directed graph of event emissions based on hooks listening to events
34985
34493
  * and their dependencies on events (emission capability). Ignores wildcard hooks by default.
34986
34494
  */
34987
34495
  buildEventEmissionGraph() {
34988
- const nodes = /* @__PURE__ */ new Map();
34989
- for (const e of this.events.values()) {
34990
- nodes.set(e.event.id, { id: e.event.id, dependencies: {} });
34991
- }
34992
- for (const h of this.hooks.values()) {
34993
- const listened = [];
34994
- const on = h.hook.on;
34995
- if (on === "*") continue;
34996
- if (Array.isArray(on))
34997
- listened.push(...on.map((e) => e.id));
34998
- else listened.push(on.id);
34999
- const depEvents = [];
35000
- const deps = h.hook.dependencies;
35001
- if (deps) {
35002
- for (const value of Object.values(deps)) {
35003
- const candidate = isOptional(value) ? value.inner : value;
35004
- if (candidate && isEvent(candidate)) {
35005
- depEvents.push(candidate.id);
35006
- }
35007
- }
35008
- }
35009
- for (const srcId of listened) {
35010
- const srcNode = nodes.get(srcId);
35011
- if (!srcNode) continue;
35012
- for (const dstId of depEvents) {
35013
- if (srcId === dstId) continue;
35014
- const dstNode = nodes.get(dstId);
35015
- if (dstNode) {
35016
- srcNode.dependencies[dstId] = dstNode;
35017
- }
35018
- }
35019
- }
35020
- }
35021
- return Array.from(nodes.values());
35022
- }
35023
- setupBlankNodes(nodeMap, depenedants) {
35024
- for (const task2 of this.tasks.values()) {
35025
- const node = {
35026
- id: task2.task.id,
35027
- dependencies: {}
35028
- };
35029
- nodeMap.set(task2.task.id, node);
35030
- depenedants.push(node);
35031
- }
35032
- for (const middleware of this.taskMiddlewares.values()) {
35033
- const node = {
35034
- id: middleware.middleware.id,
35035
- dependencies: {}
35036
- };
35037
- nodeMap.set(middleware.middleware.id, node);
35038
- depenedants.push(node);
35039
- }
35040
- for (const middleware of this.resourceMiddlewares.values()) {
35041
- const node = {
35042
- id: middleware.middleware.id,
35043
- dependencies: {}
35044
- };
35045
- nodeMap.set(middleware.middleware.id, node);
35046
- depenedants.push(node);
35047
- }
35048
- for (const resource2 of this.resources.values()) {
35049
- const node = {
35050
- id: resource2.resource.id,
35051
- dependencies: {}
35052
- };
35053
- nodeMap.set(resource2.resource.id, node);
35054
- depenedants.push(node);
35055
- }
35056
- for (const hook2 of this.hooks.values()) {
35057
- const node = {
35058
- id: hook2.hook.id,
35059
- dependencies: {}
35060
- };
35061
- nodeMap.set(hook2.hook.id, node);
35062
- depenedants.push(node);
35063
- }
34496
+ return buildEventEmissionGraph(this);
35064
34497
  }
35065
34498
  getTasksWithTag(tag2) {
35066
34499
  const tagId = typeof tag2 === "string" ? tag2 : tag2.id;
@@ -35994,6 +35427,63 @@ function detectRunnerMode(explicitMode) {
35994
35427
  }
35995
35428
  __name(detectRunnerMode, "detectRunnerMode");
35996
35429
 
35430
+ // src/models/utils/disposeOrder.ts
35431
+ function getResourcesInDisposeOrder(resources, initializedResourceIds) {
35432
+ const initializedResources = Array.from(resources.values()).filter(
35433
+ (r2) => r2.isInitialized
35434
+ );
35435
+ const initOrderHasAllInitialized = initializedResourceIds.length === initializedResources.length && initializedResources.every(
35436
+ (r2) => initializedResourceIds.includes(r2.resource.id)
35437
+ );
35438
+ if (initOrderHasAllInitialized) {
35439
+ const byId = new Map(
35440
+ initializedResources.map((r2) => [r2.resource.id, r2])
35441
+ );
35442
+ return initializedResourceIds.slice().reverse().map((id2) => byId.get(id2)).filter((r2) => Boolean(r2));
35443
+ }
35444
+ const visitState = /* @__PURE__ */ new Map();
35445
+ const initOrder = [];
35446
+ let cycleDetected = false;
35447
+ const getDependencyIds = /* @__PURE__ */ __name((resource2) => {
35448
+ const raw = resource2.resource.dependencies;
35449
+ if (!raw) return [];
35450
+ const deps = raw;
35451
+ if (!deps || typeof deps !== "object") return [];
35452
+ const out = [];
35453
+ const collect = /* @__PURE__ */ __name((value) => {
35454
+ if (isOptional(value)) {
35455
+ collect(value.inner);
35456
+ return;
35457
+ }
35458
+ if (isResource(value)) {
35459
+ out.push(value.id);
35460
+ }
35461
+ }, "collect");
35462
+ Object.values(deps).forEach(collect);
35463
+ return out;
35464
+ }, "getDependencyIds");
35465
+ const visit = /* @__PURE__ */ __name((resourceId) => {
35466
+ const state = visitState.get(resourceId);
35467
+ if (state === "visited") return;
35468
+ if (state === "visiting") {
35469
+ cycleDetected = true;
35470
+ return;
35471
+ }
35472
+ const resource2 = resources.get(resourceId);
35473
+ if (!resource2) return;
35474
+ visitState.set(resourceId, "visiting");
35475
+ getDependencyIds(resource2).forEach(visit);
35476
+ visitState.set(resourceId, "visited");
35477
+ initOrder.push(resource2);
35478
+ }, "visit");
35479
+ initializedResources.forEach((r2) => visit(r2.resource.id));
35480
+ if (cycleDetected) {
35481
+ return initializedResources.slice().reverse();
35482
+ }
35483
+ return initOrder.reverse();
35484
+ }
35485
+ __name(getResourcesInDisposeOrder, "getResourcesInDisposeOrder");
35486
+
35997
35487
  // src/models/Store.ts
35998
35488
  var Store = class {
35999
35489
  constructor(eventManager, logger, onUnhandledError, mode) {
@@ -36058,6 +35548,7 @@ var Store = class {
36058
35548
  }
36059
35549
  lock() {
36060
35550
  this.#isLocked = true;
35551
+ this.registry.lockAll();
36061
35552
  }
36062
35553
  checkLock() {
36063
35554
  if (this.#isLocked) {
@@ -36199,58 +35690,7 @@ var Store = class {
36199
35690
  this.initializedResourceIds.push(resourceId);
36200
35691
  }
36201
35692
  getResourcesInDisposeOrder() {
36202
- const initializedResources = Array.from(this.resources.values()).filter(
36203
- (r2) => r2.isInitialized
36204
- );
36205
- const initOrderHasAllInitialized = this.initializedResourceIds.length === initializedResources.length && initializedResources.every(
36206
- (r2) => this.initializedResourceIds.includes(r2.resource.id)
36207
- );
36208
- if (initOrderHasAllInitialized) {
36209
- const byId = new Map(
36210
- initializedResources.map((r2) => [r2.resource.id, r2])
36211
- );
36212
- return this.initializedResourceIds.slice().reverse().map((id2) => byId.get(id2)).filter((r2) => Boolean(r2));
36213
- }
36214
- const visitState = /* @__PURE__ */ new Map();
36215
- const initOrder = [];
36216
- let cycleDetected = false;
36217
- const getDependencyIds = /* @__PURE__ */ __name((resource2) => {
36218
- const raw = resource2.resource.dependencies;
36219
- if (!raw) return [];
36220
- const deps = raw;
36221
- if (!deps || typeof deps !== "object") return [];
36222
- const out = [];
36223
- const collect = /* @__PURE__ */ __name((value) => {
36224
- if (isOptional(value)) {
36225
- collect(value.inner);
36226
- return;
36227
- }
36228
- if (isResource(value)) {
36229
- out.push(value.id);
36230
- }
36231
- }, "collect");
36232
- Object.values(deps).forEach(collect);
36233
- return out;
36234
- }, "getDependencyIds");
36235
- const visit = /* @__PURE__ */ __name((resourceId) => {
36236
- const state = visitState.get(resourceId);
36237
- if (state === "visited") return;
36238
- if (state === "visiting") {
36239
- cycleDetected = true;
36240
- return;
36241
- }
36242
- const resource2 = this.resources.get(resourceId);
36243
- if (!resource2) return;
36244
- visitState.set(resourceId, "visiting");
36245
- getDependencyIds(resource2).forEach(visit);
36246
- visitState.set(resourceId, "visited");
36247
- initOrder.push(resource2);
36248
- }, "visit");
36249
- initializedResources.forEach((r2) => visit(r2.resource.id));
36250
- if (cycleDetected) {
36251
- return initializedResources.slice().reverse();
36252
- }
36253
- return initOrder.reverse();
35693
+ return getResourcesInDisposeOrder(this.resources, this.initializedResourceIds);
36254
35694
  }
36255
35695
  /**
36256
35696
  * Internal, avoid using this method directly.
@@ -36533,7 +35973,7 @@ var debugResource = defineResource({
36533
35973
  tags: [globalTags.system]
36534
35974
  });
36535
35975
 
36536
- // src/processHooks.ts
35976
+ // src/tools/processShutdownHooks.ts
36537
35977
  var platform2 = getPlatform();
36538
35978
  var activeErrorHandlers = /* @__PURE__ */ new Set();
36539
35979
  var processSafetyNetsInstalled = false;
@@ -36622,13 +36062,6 @@ function bindProcessErrorHandler(handler) {
36622
36062
  };
36623
36063
  }
36624
36064
  __name(bindProcessErrorHandler, "bindProcessErrorHandler");
36625
- async function safeReportUnhandledError(handler, info) {
36626
- try {
36627
- await handler(info);
36628
- } catch {
36629
- }
36630
- }
36631
- __name(safeReportUnhandledError, "safeReportUnhandledError");
36632
36065
 
36633
36066
  // src/models/RunResult.ts
36634
36067
  var RunResult = class {
@@ -36827,7 +36260,6 @@ function extractResourceAndConfig(resourceOrResourceWithConfig) {
36827
36260
  __name(extractResourceAndConfig, "extractResourceAndConfig");
36828
36261
 
36829
36262
  // src/globals/tunnels/index.ts
36830
- init_http_fetch_tunnel_resource();
36831
36263
  var http = Object.freeze({
36832
36264
  createClient(cfg) {
36833
36265
  const { url, ...rest } = cfg;
@@ -36838,39 +36270,15 @@ var tunnels = Object.freeze({
36838
36270
  http
36839
36271
  });
36840
36272
 
36841
- // src/testing.ts
36842
- var testResourceCounter = 0;
36843
- function createTestResource(root, options) {
36844
- return defineResource({
36845
- id: `testing.${root.id}.${++testResourceCounter}`,
36846
- register: [root],
36847
- overrides: options?.overrides || [],
36848
- dependencies: {
36849
- taskRunner: globalResources.taskRunner,
36850
- store: globalResources.store,
36851
- logger: globalResources.logger,
36852
- eventManager: globalResources.eventManager
36853
- },
36854
- async init(_, deps) {
36855
- return buildTestFacade(deps);
36856
- }
36857
- });
36858
- }
36859
- __name(createTestResource, "createTestResource");
36860
- function buildTestFacade(deps) {
36861
- return {
36862
- // Run a task within the fully initialized ecosystem
36863
- runTask: /* @__PURE__ */ __name((task2, ...args) => deps.taskRunner.run(task2, ...args), "runTask"),
36864
- // Access a resource value by id (string or symbol)
36865
- getResource: /* @__PURE__ */ __name((id2) => deps.store.resources.get(id2)?.value, "getResource"),
36866
- // Expose internals when needed in tests (not recommended for app usage)
36867
- taskRunner: deps.taskRunner,
36868
- store: deps.store,
36869
- logger: deps.logger,
36870
- eventManager: deps.eventManager
36871
- };
36273
+ // src/definers/builders/shared/mergeUtils.ts
36274
+ function mergeArray(existing, addition, override2) {
36275
+ const toArray = [...addition];
36276
+ if (override2 || !existing) {
36277
+ return toArray;
36278
+ }
36279
+ return [...existing, ...toArray];
36872
36280
  }
36873
- __name(buildTestFacade, "buildTestFacade");
36281
+ __name(mergeArray, "mergeArray");
36874
36282
 
36875
36283
  // src/definers/builders/resource/utils.ts
36876
36284
  function clone2(s, patch) {
@@ -36916,14 +36324,6 @@ function mergeRegister(existing, addition, override2) {
36916
36324
  ];
36917
36325
  }
36918
36326
  __name(mergeRegister, "mergeRegister");
36919
- function mergeArray(existing, addition, override2) {
36920
- const toArray = [...addition];
36921
- if (override2 || !existing) {
36922
- return toArray;
36923
- }
36924
- return [...existing, ...toArray];
36925
- }
36926
- __name(mergeArray, "mergeArray");
36927
36327
  function mergeDependencies(existing, addition, override2) {
36928
36328
  const isFnExisting = typeof existing === "function";
36929
36329
  const isFnAddition = typeof addition === "function";
@@ -37087,14 +36487,6 @@ function clone3(s, patch) {
37087
36487
  });
37088
36488
  }
37089
36489
  __name(clone3, "clone");
37090
- function mergeArray2(existing, addition, override2) {
37091
- const toArray = [...addition];
37092
- if (override2 || !existing) {
37093
- return toArray;
37094
- }
37095
- return [...existing, ...toArray];
37096
- }
37097
- __name(mergeArray2, "mergeArray");
37098
36490
  function mergeDependencies2(existing, addition, override2) {
37099
36491
  const isFnExisting = typeof existing === "function";
37100
36492
  const isFnAddition = typeof addition === "function";
@@ -37150,14 +36542,14 @@ function makeTaskBuilder(state) {
37150
36542
  middleware(mw, options) {
37151
36543
  const override2 = options?.override ?? false;
37152
36544
  const next = clone3(state, {
37153
- middleware: mergeArray2(state.middleware, mw, override2)
36545
+ middleware: mergeArray(state.middleware, mw, override2)
37154
36546
  });
37155
36547
  return makeTaskBuilder(next);
37156
36548
  },
37157
36549
  tags(t, options) {
37158
36550
  const override2 = options?.override ?? false;
37159
36551
  const next = clone3(state, {
37160
- tags: mergeArray2(state.tags, t, override2)
36552
+ tags: mergeArray(state.tags, t, override2)
37161
36553
  });
37162
36554
  return makeTaskBuilder(next);
37163
36555
  },
@@ -37233,14 +36625,14 @@ function makePhantomTaskBuilder(state) {
37233
36625
  middleware(mw, options) {
37234
36626
  const override2 = options?.override ?? false;
37235
36627
  const next = clone3(state, {
37236
- middleware: mergeArray2(state.middleware, mw, override2)
36628
+ middleware: mergeArray(state.middleware, mw, override2)
37237
36629
  });
37238
36630
  return makePhantomTaskBuilder(next);
37239
36631
  },
37240
36632
  tags(t, options) {
37241
36633
  const override2 = options?.override ?? false;
37242
36634
  const next = clone3(state, {
37243
- tags: mergeArray2(state.tags, t, override2)
36635
+ tags: mergeArray(state.tags, t, override2)
37244
36636
  });
37245
36637
  return makePhantomTaskBuilder(
37246
36638
  next
@@ -37329,14 +36721,6 @@ function clone4(s, patch) {
37329
36721
  });
37330
36722
  }
37331
36723
  __name(clone4, "clone");
37332
- function mergeArray3(existing, addition, override2) {
37333
- const toArray = [...addition];
37334
- if (override2 || !existing) {
37335
- return toArray;
37336
- }
37337
- return [...existing, ...toArray];
37338
- }
37339
- __name(mergeArray3, "mergeArray");
37340
36724
 
37341
36725
  // src/definers/builders/event/fluent-builder.ts
37342
36726
  function makeEventBuilder(state) {
@@ -37351,7 +36735,7 @@ function makeEventBuilder(state) {
37351
36735
  tags(t, options) {
37352
36736
  const override2 = options?.override ?? false;
37353
36737
  const next = clone4(state, {
37354
- tags: mergeArray3(state.tags, t, override2)
36738
+ tags: mergeArray(state.tags, t, override2)
37355
36739
  });
37356
36740
  return makeEventBuilder(next);
37357
36741
  },
@@ -37399,14 +36783,6 @@ function clone5(s, patch) {
37399
36783
  });
37400
36784
  }
37401
36785
  __name(clone5, "clone");
37402
- function mergeArray4(existing, addition, override2) {
37403
- const toArray = [...addition];
37404
- if (override2 || !existing) {
37405
- return toArray;
37406
- }
37407
- return [...existing, ...toArray];
37408
- }
37409
- __name(mergeArray4, "mergeArray");
37410
36786
  function mergeDependencies3(existing, addition, override2) {
37411
36787
  const isFnExisting = typeof existing === "function";
37412
36788
  const isFnAddition = typeof addition === "function";
@@ -37480,7 +36856,7 @@ function makeHookBuilder(state) {
37480
36856
  tags(t, options) {
37481
36857
  const override2 = options?.override ?? false;
37482
36858
  const next = clone5(state, {
37483
- tags: mergeArray4(state.tags, t, override2)
36859
+ tags: mergeArray(state.tags, t, override2)
37484
36860
  });
37485
36861
  return makeHookBuilder(next);
37486
36862
  },
@@ -37557,14 +36933,6 @@ function cloneRes(s, patch) {
37557
36933
  });
37558
36934
  }
37559
36935
  __name(cloneRes, "cloneRes");
37560
- function mergeArray5(existing, addition, override2) {
37561
- const toArray = [...addition];
37562
- if (override2 || !existing) {
37563
- return toArray;
37564
- }
37565
- return [...existing, ...toArray];
37566
- }
37567
- __name(mergeArray5, "mergeArray");
37568
36936
  function mergeDependencies4(existing, addition, override2) {
37569
36937
  const isFnExisting = typeof existing === "function";
37570
36938
  const isFnAddition = typeof addition === "function";
@@ -37645,7 +37013,7 @@ function makeTaskMiddlewareBuilder(state) {
37645
37013
  tags(t, options) {
37646
37014
  const override2 = options?.override ?? false;
37647
37015
  const next = cloneTask(state, {
37648
- tags: mergeArray5(state.tags, t, override2)
37016
+ tags: mergeArray(state.tags, t, override2)
37649
37017
  });
37650
37018
  return makeTaskMiddlewareBuilder(next);
37651
37019
  },
@@ -37717,7 +37085,7 @@ function makeResourceMiddlewareBuilder(state) {
37717
37085
  tags(t, options) {
37718
37086
  const override2 = options?.override ?? false;
37719
37087
  const next = cloneRes(state, {
37720
- tags: mergeArray5(state.tags, t, override2)
37088
+ tags: mergeArray(state.tags, t, override2)
37721
37089
  });
37722
37090
  return makeResourceMiddlewareBuilder(next);
37723
37091
  },
@@ -37928,7 +37296,7 @@ function makeHookOverrideBuilder(base, state) {
37928
37296
  tags(t, options) {
37929
37297
  const override2 = options?.override ?? false;
37930
37298
  const next = cloneHookState(state, {
37931
- tags: mergeArray4(state.tags, t, override2)
37299
+ tags: mergeArray(state.tags, t, override2)
37932
37300
  });
37933
37301
  return makeHookOverrideBuilder(base, next);
37934
37302
  },
@@ -38133,7 +37501,7 @@ function makeResourceMiddlewareOverrideBuilder(base, state) {
38133
37501
  tags(t, options) {
38134
37502
  const override2 = options?.override ?? false;
38135
37503
  const next = cloneResourceMiddlewareState(state, {
38136
- tags: mergeArray5(state.tags, t, override2)
37504
+ tags: mergeArray(state.tags, t, override2)
38137
37505
  });
38138
37506
  return makeResourceMiddlewareOverrideBuilder(base, next);
38139
37507
  },
@@ -38193,14 +37561,14 @@ function makeTaskOverrideBuilder(base, state) {
38193
37561
  middleware(mw, options) {
38194
37562
  const override2 = options?.override ?? false;
38195
37563
  const next = cloneTaskState(state, {
38196
- middleware: mergeArray2(state.middleware, mw, override2)
37564
+ middleware: mergeArray(state.middleware, mw, override2)
38197
37565
  });
38198
37566
  return makeTaskOverrideBuilder(base, next);
38199
37567
  },
38200
37568
  tags(t, options) {
38201
37569
  const override2 = options?.override ?? false;
38202
37570
  const next = cloneTaskState(state, {
38203
- tags: mergeArray2(state.tags, t, override2)
37571
+ tags: mergeArray(state.tags, t, override2)
38204
37572
  });
38205
37573
  return makeTaskOverrideBuilder(base, next);
38206
37574
  },
@@ -38309,7 +37677,7 @@ function makeTaskMiddlewareOverrideBuilder(base, state) {
38309
37677
  tags(t, options) {
38310
37678
  const override2 = options?.override ?? false;
38311
37679
  const next = cloneTaskMiddlewareState(state, {
38312
- tags: mergeArray5(state.tags, t, override2)
37680
+ tags: mergeArray(state.tags, t, override2)
38313
37681
  });
38314
37682
  return makeTaskMiddlewareOverrideBuilder(base, next);
38315
37683
  },
@@ -38361,7 +37729,6 @@ function override(base) {
38361
37729
  __name(override, "override");
38362
37730
 
38363
37731
  // src/public.ts
38364
- init_http_fetch_tunnel_resource();
38365
37732
  var globals = {
38366
37733
  events: globalEvents,
38367
37734
  resources: globalResources,
@@ -38370,7 +37737,6 @@ var globals = {
38370
37737
  tunnels,
38371
37738
  debug
38372
37739
  };
38373
- var createContext2 = createContext;
38374
37740
  var r = Object.freeze({
38375
37741
  resource,
38376
37742
  task,
@@ -39656,7 +39022,7 @@ var withExposureContext = /* @__PURE__ */ __name((req, res, controller, deps, fn
39656
39022
  } catch {
39657
39023
  }
39658
39024
  }
39659
- const run3 = /* @__PURE__ */ __name(() => ExposureRequestContext.provide(
39025
+ const run2 = /* @__PURE__ */ __name(() => ExposureRequestContext.provide(
39660
39026
  {
39661
39027
  req,
39662
39028
  res,
@@ -39668,7 +39034,7 @@ var withExposureContext = /* @__PURE__ */ __name((req, res, controller, deps, fn
39668
39034
  },
39669
39035
  userWrapped
39670
39036
  ), "run");
39671
- return Promise.resolve(run3());
39037
+ return Promise.resolve(run2());
39672
39038
  }, "withExposureContext");
39673
39039
  var withUserContexts = /* @__PURE__ */ __name((req, deps, fn) => {
39674
39040
  const { store: store2, serializer: serializer3 } = deps;
@@ -39864,7 +39230,7 @@ var createTaskHandler = /* @__PURE__ */ __name((deps) => {
39864
39230
  applyCorsActual(req, res, cors);
39865
39231
  respondJson(res, jsonOkResponse({ result }), serializer3);
39866
39232
  } catch (error2) {
39867
- if (isCancellationError(error2)) {
39233
+ if (cancellationError.is(error2)) {
39868
39234
  if (!res.writableEnded && !res.headersSent) {
39869
39235
  applyCorsActual(req, res, cors);
39870
39236
  respondJson(
@@ -39973,7 +39339,7 @@ var createEventHandler = /* @__PURE__ */ __name((deps) => {
39973
39339
  serializer3
39974
39340
  );
39975
39341
  } catch (error2) {
39976
- if (isCancellationError(error2)) {
39342
+ if (cancellationError.is(error2)) {
39977
39343
  if (!res.writableEnded && !res.headersSent) {
39978
39344
  applyCorsActual(req, res, cors);
39979
39345
  respondJson(
@@ -40239,27 +39605,487 @@ async function writeInputFileToPath(file, targetPath) {
40239
39605
  }
40240
39606
  __name(writeInputFileToPath, "writeInputFileToPath");
40241
39607
 
40242
- // src/node/http/index.ts
40243
- init_http_smart_client_model();
40244
- init_http_mixed_client();
40245
-
40246
- // src/node/http/http-smart-client.factory.resource.ts
40247
- var httpSmartClientFactory = defineResource({
40248
- id: "globals.resources.httpSmartClientFactory",
40249
- meta: {
40250
- title: "HTTP Smart Client Factory (Node)",
40251
- 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."
39608
+ // src/node/upload/manifest.ts
39609
+ function buildNodeManifest(input) {
39610
+ const files = [];
39611
+ function visit(value) {
39612
+ if (!value || typeof value !== "object") return value;
39613
+ const potentialFile = value;
39614
+ if (potentialFile.$runnerFile === "File" && typeof potentialFile.id === "string") {
39615
+ const id2 = potentialFile.id;
39616
+ const meta = potentialFile.meta;
39617
+ const local = potentialFile._node;
39618
+ if (local?.buffer) {
39619
+ files.push({
39620
+ id: id2,
39621
+ meta,
39622
+ source: { type: "buffer", buffer: local.buffer }
39623
+ });
39624
+ } else if (local?.stream) {
39625
+ files.push({
39626
+ id: id2,
39627
+ meta,
39628
+ source: { type: "stream", stream: local.stream }
39629
+ });
39630
+ }
39631
+ const copy = { $runnerFile: "File", id: id2, meta };
39632
+ return copy;
39633
+ }
39634
+ if (Array.isArray(value)) {
39635
+ return value.map((x) => visit(x));
39636
+ }
39637
+ const out = {};
39638
+ const obj = value;
39639
+ for (const k of Object.keys(obj)) {
39640
+ out[k] = visit(obj[k]);
39641
+ }
39642
+ return out;
40252
39643
  }
40253
- });
39644
+ __name(visit, "visit");
39645
+ const cloned = visit(input);
39646
+ return { input: cloned, files };
39647
+ }
39648
+ __name(buildNodeManifest, "buildNodeManifest");
40254
39649
 
40255
- // src/node/http/http-mixed-client.factory.resource.ts
40256
- var httpMixedClientFactory = defineResource({
40257
- id: "globals.resources.httpMixedClientFactory",
40258
- meta: {
40259
- title: "HTTP Mixed Client Factory (Node)",
40260
- 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."
39650
+ // src/node/http/http-smart-client.model.ts
39651
+ function isReadable(value) {
39652
+ return !!value && typeof value.pipe === "function";
39653
+ }
39654
+ __name(isReadable, "isReadable");
39655
+ function hasNodeFile(value) {
39656
+ const isNodeFileSentinel = /* @__PURE__ */ __name((v) => {
39657
+ if (!v || typeof v !== "object") return false;
39658
+ const rec = v;
39659
+ if (rec.$runnerFile !== "File") return false;
39660
+ if (typeof rec.id !== "string") return false;
39661
+ const node = rec._node;
39662
+ if (!node || typeof node !== "object") return false;
39663
+ const n = node;
39664
+ return Boolean(n.stream || n.buffer);
39665
+ }, "isNodeFileSentinel");
39666
+ const visit = /* @__PURE__ */ __name((v) => {
39667
+ if (isNodeFileSentinel(v)) return true;
39668
+ if (!v || typeof v !== "object") return false;
39669
+ if (Array.isArray(v)) return v.some(visit);
39670
+ for (const k of Object.keys(v)) {
39671
+ if (visit(v[k])) return true;
39672
+ }
39673
+ return false;
39674
+ }, "visit");
39675
+ return visit(value);
39676
+ }
39677
+ __name(hasNodeFile, "hasNodeFile");
39678
+ function toHeaders2(auth) {
39679
+ const headers = {};
39680
+ if (auth?.token)
39681
+ headers[(auth.header ?? "x-runner-token").toLowerCase()] = auth.token;
39682
+ return headers;
39683
+ }
39684
+ __name(toHeaders2, "toHeaders");
39685
+ function requestLib(url) {
39686
+ return url.protocol === "https:" ? https__namespace : http2__namespace;
39687
+ }
39688
+ __name(requestLib, "requestLib");
39689
+ async function postJson(cfg, url, body) {
39690
+ const serializer3 = cfg.serializer;
39691
+ const parsed = new URL(url);
39692
+ const lib = requestLib(parsed);
39693
+ const headers = {
39694
+ "content-type": "application/json; charset=utf-8",
39695
+ ...toHeaders2(cfg.auth)
39696
+ };
39697
+ if (cfg.contexts && cfg.contexts.length > 0) {
39698
+ const map = {};
39699
+ for (const ctx of cfg.contexts) {
39700
+ try {
39701
+ const v = ctx.use();
39702
+ map[ctx.id] = ctx.serialize(v);
39703
+ } catch {
39704
+ }
39705
+ }
39706
+ if (Object.keys(map).length > 0) {
39707
+ headers["x-runner-context"] = cfg.serializer.stringify(map);
39708
+ }
40261
39709
  }
40262
- });
39710
+ if (cfg.onRequest) await cfg.onRequest({ url, headers });
39711
+ return await new Promise((resolve, reject) => {
39712
+ const req = lib.request(
39713
+ {
39714
+ method: "POST",
39715
+ protocol: parsed.protocol,
39716
+ hostname: parsed.hostname,
39717
+ port: parsed.port,
39718
+ path: parsed.pathname + parsed.search,
39719
+ headers,
39720
+ timeout: cfg.timeoutMs
39721
+ },
39722
+ (res) => {
39723
+ const chunks = [];
39724
+ res.on("data", (c) => {
39725
+ chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(String(c)));
39726
+ });
39727
+ res.on("end", () => {
39728
+ const text = Buffer.concat(chunks).toString(
39729
+ "utf8"
39730
+ );
39731
+ const json2 = text ? serializer3.parse(text) : void 0;
39732
+ resolve(json2);
39733
+ });
39734
+ }
39735
+ );
39736
+ req.on("error", reject);
39737
+ req.write(serializer3.stringify(body));
39738
+ req.end();
39739
+ });
39740
+ }
39741
+ __name(postJson, "postJson");
39742
+ function escapeHeaderValue(value) {
39743
+ return value.replace(/"/g, '\\"');
39744
+ }
39745
+ __name(escapeHeaderValue, "escapeHeaderValue");
39746
+ function encodeMultipart(manifestText, files, boundary) {
39747
+ async function* gen() {
39748
+ const CRLF = "\r\n";
39749
+ const boundaryLine = `--${boundary}`;
39750
+ const partHeader = /* @__PURE__ */ __name((name, options) => {
39751
+ const h = [boundaryLine + CRLF];
39752
+ const cd = [
39753
+ `Content-Disposition: form-data; name="${escapeHeaderValue(name)}"`
39754
+ ];
39755
+ if (options?.filename) {
39756
+ cd.push(`; filename="${escapeHeaderValue(options.filename)}"`);
39757
+ }
39758
+ h.push(cd.join("") + CRLF);
39759
+ if (options?.headers) {
39760
+ for (const k of Object.keys(options.headers)) {
39761
+ h.push(`${k}: ${options.headers[k]}` + CRLF);
39762
+ }
39763
+ }
39764
+ h.push(CRLF);
39765
+ return Buffer.from(h.join(""), "utf8");
39766
+ }, "partHeader");
39767
+ yield partHeader("__manifest");
39768
+ yield Buffer.from(manifestText, "utf8");
39769
+ yield Buffer.from(CRLF, "utf8");
39770
+ for (const entry of files) {
39771
+ const filename = entry.meta?.name ?? "upload";
39772
+ const contentType = entry.meta?.type ?? "application/octet-stream";
39773
+ const headers = {
39774
+ "Content-Type": contentType
39775
+ };
39776
+ yield partHeader(`file:${entry.id}`, { headers, filename });
39777
+ if (entry.source.type === "buffer") {
39778
+ yield entry.source.buffer;
39779
+ } else {
39780
+ for await (const chunk of entry.source.stream) {
39781
+ yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
39782
+ }
39783
+ }
39784
+ yield Buffer.from(CRLF, "utf8");
39785
+ }
39786
+ yield Buffer.from(boundaryLine + "--" + CRLF, "utf8");
39787
+ }
39788
+ __name(gen, "gen");
39789
+ return stream.Readable.from(gen());
39790
+ }
39791
+ __name(encodeMultipart, "encodeMultipart");
39792
+ async function postMultipart(cfg, url, manifestText, files) {
39793
+ const parsed = new URL(url);
39794
+ const lib = requestLib(parsed);
39795
+ const boundary = `runner-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
39796
+ const body = encodeMultipart(manifestText, files, boundary);
39797
+ const headers = {
39798
+ "content-type": `multipart/form-data; boundary=${boundary}`,
39799
+ ...toHeaders2(cfg.auth)
39800
+ };
39801
+ if (cfg.contexts && cfg.contexts.length > 0) {
39802
+ const map = {};
39803
+ for (const ctx of cfg.contexts) {
39804
+ try {
39805
+ const v = ctx.use();
39806
+ map[ctx.id] = ctx.serialize(v);
39807
+ } catch {
39808
+ }
39809
+ }
39810
+ if (Object.keys(map).length > 0) {
39811
+ headers["x-runner-context"] = cfg.serializer.stringify(map);
39812
+ }
39813
+ }
39814
+ if (cfg.onRequest) await cfg.onRequest({ url, headers });
39815
+ return await new Promise(
39816
+ (resolve, reject) => {
39817
+ const req = lib.request(
39818
+ {
39819
+ method: "POST",
39820
+ protocol: parsed.protocol,
39821
+ hostname: parsed.hostname,
39822
+ port: parsed.port,
39823
+ path: parsed.pathname + parsed.search,
39824
+ headers,
39825
+ timeout: cfg.timeoutMs
39826
+ },
39827
+ (res) => resolve({ stream: res, res })
39828
+ );
39829
+ req.on("error", reject);
39830
+ body.on("error", (e) => req.destroy(e));
39831
+ body.pipe(req);
39832
+ }
39833
+ );
39834
+ }
39835
+ __name(postMultipart, "postMultipart");
39836
+ async function postOctetStream(cfg, url, stream$1) {
39837
+ const parsed = new URL(url);
39838
+ const lib = requestLib(parsed);
39839
+ const headers = {
39840
+ "content-type": "application/octet-stream",
39841
+ ...toHeaders2(cfg.auth)
39842
+ };
39843
+ if (cfg.contexts && cfg.contexts.length > 0) {
39844
+ const map = {};
39845
+ for (const ctx of cfg.contexts) {
39846
+ try {
39847
+ const v = ctx.use();
39848
+ map[ctx.id] = ctx.serialize(v);
39849
+ } catch {
39850
+ }
39851
+ }
39852
+ if (Object.keys(map).length > 0) {
39853
+ headers["x-runner-context"] = cfg.serializer.stringify(map);
39854
+ }
39855
+ }
39856
+ if (cfg.onRequest) await cfg.onRequest({ url, headers });
39857
+ return await new Promise(
39858
+ (resolve, reject) => {
39859
+ let settled = false;
39860
+ const cleanup = [];
39861
+ const resolveOnce = /* @__PURE__ */ __name((value) => {
39862
+ settled = true;
39863
+ cleanup.forEach((fn) => fn());
39864
+ resolve(value);
39865
+ }, "resolveOnce");
39866
+ const rejectOnce = /* @__PURE__ */ __name((error2) => {
39867
+ settled = true;
39868
+ cleanup.forEach((fn) => fn());
39869
+ reject(error2 instanceof Error ? error2 : new Error(String(error2)));
39870
+ }, "rejectOnce");
39871
+ const req = lib.request(
39872
+ {
39873
+ method: "POST",
39874
+ protocol: parsed.protocol,
39875
+ hostname: parsed.hostname,
39876
+ port: parsed.port,
39877
+ path: parsed.pathname + parsed.search,
39878
+ headers,
39879
+ timeout: cfg.timeoutMs
39880
+ },
39881
+ (res) => {
39882
+ setImmediate(() => {
39883
+ if (!settled)
39884
+ resolveOnce({ stream: res, res });
39885
+ });
39886
+ }
39887
+ );
39888
+ const onReqError = /* @__PURE__ */ __name((e) => rejectOnce(e), "onReqError");
39889
+ req.on("error", onReqError);
39890
+ cleanup.push(() => req.removeListener("error", onReqError));
39891
+ const onPipelineDone = /* @__PURE__ */ __name((err) => {
39892
+ if (err) rejectOnce(err);
39893
+ }, "onPipelineDone");
39894
+ stream.pipeline(stream$1, req, onPipelineDone);
39895
+ }
39896
+ );
39897
+ }
39898
+ __name(postOctetStream, "postOctetStream");
39899
+ function parseMaybeJsonResponse(res, serializer3) {
39900
+ const contentType = String(res.headers["content-type"]);
39901
+ if (/^application\/json/i.test(contentType)) {
39902
+ const chunks = [];
39903
+ return new Promise((resolve, reject) => {
39904
+ res.on("data", (c) => {
39905
+ chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(String(c)));
39906
+ });
39907
+ res.on("end", () => {
39908
+ try {
39909
+ const text = Buffer.concat(chunks).toString(
39910
+ "utf8"
39911
+ );
39912
+ const json2 = text ? serializer3.parse(text) : void 0;
39913
+ resolve(json2);
39914
+ } catch (e) {
39915
+ reject(e);
39916
+ }
39917
+ });
39918
+ res.on("error", reject);
39919
+ });
39920
+ }
39921
+ return Promise.resolve(res);
39922
+ }
39923
+ __name(parseMaybeJsonResponse, "parseMaybeJsonResponse");
39924
+ function rethrowTyped(registry, error2) {
39925
+ if (registry && error2 && typeof error2 === "object") {
39926
+ const err = error2;
39927
+ if (err.id && err.data) {
39928
+ const helper = registry.get(String(err.id));
39929
+ if (helper) helper.throw(err.data);
39930
+ }
39931
+ }
39932
+ throw error2;
39933
+ }
39934
+ __name(rethrowTyped, "rethrowTyped");
39935
+ function createHttpSmartClient(cfg) {
39936
+ const baseUrl = cfg.baseUrl.replace(/\/$/, "");
39937
+ if (!baseUrl) throw new Error("createHttpSmartClient requires baseUrl");
39938
+ const serializer3 = cfg.serializer;
39939
+ return {
39940
+ async task(id2, input) {
39941
+ const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
39942
+ if (isReadable(input)) {
39943
+ const { res } = await postOctetStream(cfg, url, input);
39944
+ return res;
39945
+ }
39946
+ if (hasNodeFile(input)) {
39947
+ const manifest = buildNodeManifest(input);
39948
+ const manifestText = serializer3.stringify({
39949
+ input: manifest.input
39950
+ });
39951
+ try {
39952
+ const { res } = await postMultipart(
39953
+ cfg,
39954
+ url,
39955
+ manifestText,
39956
+ manifest.files
39957
+ );
39958
+ const maybe = await parseMaybeJsonResponse(
39959
+ res,
39960
+ serializer3
39961
+ );
39962
+ if (isReadable(maybe)) return maybe;
39963
+ return assertOkEnvelope(maybe, {
39964
+ fallbackMessage: "Tunnel task error"
39965
+ });
39966
+ } catch (error2) {
39967
+ rethrowTyped(cfg.errorRegistry, error2);
39968
+ }
39969
+ }
39970
+ try {
39971
+ const r2 = await postJson(cfg, url, { input });
39972
+ return assertOkEnvelope(r2, {
39973
+ fallbackMessage: "Tunnel task error"
39974
+ });
39975
+ } catch (error2) {
39976
+ rethrowTyped(cfg.errorRegistry, error2);
39977
+ }
39978
+ },
39979
+ async event(id2, payload) {
39980
+ const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
39981
+ try {
39982
+ const r2 = await postJson(cfg, url, { payload });
39983
+ assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
39984
+ } catch (error2) {
39985
+ rethrowTyped(cfg.errorRegistry, error2);
39986
+ }
39987
+ },
39988
+ async eventWithResult(id2, payload) {
39989
+ const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
39990
+ try {
39991
+ const r2 = await postJson(cfg, url, {
39992
+ payload,
39993
+ returnPayload: true
39994
+ });
39995
+ if (r2 && typeof r2 === "object" && r2.ok && !("result" in r2)) {
39996
+ throw new TunnelError(
39997
+ "INVALID_RESPONSE",
39998
+ "Tunnel event returnPayload requested but server did not include result. Upgrade the exposure server."
39999
+ );
40000
+ }
40001
+ return assertOkEnvelope(r2, {
40002
+ fallbackMessage: "Tunnel event error"
40003
+ });
40004
+ } catch (error2) {
40005
+ rethrowTyped(cfg.errorRegistry, error2);
40006
+ }
40007
+ }
40008
+ };
40009
+ }
40010
+ __name(createHttpSmartClient, "createHttpSmartClient");
40011
+
40012
+ // src/node/http/http-mixed-client.ts
40013
+ function isReadable2(value) {
40014
+ return !!value && typeof value.pipe === "function";
40015
+ }
40016
+ __name(isReadable2, "isReadable");
40017
+ function hasNodeFile2(value) {
40018
+ const isNodeFileSentinel = /* @__PURE__ */ __name((v) => {
40019
+ if (!v || typeof v !== "object") return false;
40020
+ const rec = v;
40021
+ if (rec.$runnerFile !== "File") return false;
40022
+ if (typeof rec.id !== "string") return false;
40023
+ const node = rec._node;
40024
+ if (!node || typeof node !== "object") return false;
40025
+ const n = node;
40026
+ return Boolean(n.stream || n.buffer);
40027
+ }, "isNodeFileSentinel");
40028
+ const visit = /* @__PURE__ */ __name((v) => {
40029
+ if (isNodeFileSentinel(v)) return true;
40030
+ if (!v || typeof v !== "object") return false;
40031
+ if (Array.isArray(v)) return v.some(visit);
40032
+ for (const k of Object.keys(v)) {
40033
+ if (visit(v[k])) return true;
40034
+ }
40035
+ return false;
40036
+ }, "visit");
40037
+ return visit(value);
40038
+ }
40039
+ __name(hasNodeFile2, "hasNodeFile");
40040
+ async function shouldForceSmart(cfg, id2, input) {
40041
+ if (!cfg.forceSmart) return false;
40042
+ if (cfg.forceSmart === true) return true;
40043
+ return await cfg.forceSmart({ id: id2, input });
40044
+ }
40045
+ __name(shouldForceSmart, "shouldForceSmart");
40046
+ function createHttpMixedClient(cfg) {
40047
+ const baseUrl = cfg.baseUrl?.replace(/\/$/, "");
40048
+ if (!baseUrl) throw new Error("createMixedHttpClient requires baseUrl");
40049
+ const fetchClient = createExposureFetch({
40050
+ baseUrl,
40051
+ auth: cfg.auth,
40052
+ timeoutMs: cfg.timeoutMs,
40053
+ fetchImpl: cfg.fetchImpl,
40054
+ serializer: cfg.serializer,
40055
+ onRequest: cfg.onRequest,
40056
+ contexts: cfg.contexts,
40057
+ errorRegistry: cfg.errorRegistry
40058
+ });
40059
+ const smartClient = createHttpSmartClient({
40060
+ baseUrl,
40061
+ auth: cfg.auth,
40062
+ timeoutMs: cfg.timeoutMs,
40063
+ serializer: cfg.serializer,
40064
+ onRequest: cfg.onRequest,
40065
+ contexts: cfg.contexts,
40066
+ errorRegistry: cfg.errorRegistry
40067
+ });
40068
+ return {
40069
+ async task(id2, input) {
40070
+ if (isReadable2(input) || hasNodeFile2(input) || await shouldForceSmart(cfg, id2, input)) {
40071
+ return await smartClient.task(id2, input);
40072
+ }
40073
+ return await fetchClient.task(id2, input);
40074
+ },
40075
+ async event(id2, payload) {
40076
+ return await fetchClient.event(id2, payload);
40077
+ },
40078
+ async eventWithResult(id2, payload) {
40079
+ if (!fetchClient.eventWithResult) {
40080
+ throw new Error(
40081
+ "createHttpMixedClient: eventWithResult not available on underlying tunnel client."
40082
+ );
40083
+ }
40084
+ return await fetchClient.eventWithResult(id2, payload);
40085
+ }
40086
+ };
40087
+ }
40088
+ __name(createHttpMixedClient, "createHttpMixedClient");
40263
40089
 
40264
40090
  // src/node/durable/core/types.ts
40265
40091
  var ExecutionStatus = {
@@ -40622,9 +40448,10 @@ var DurableResource = class _DurableResource {
40622
40448
  );
40623
40449
  }
40624
40450
  const deps = storeTask.computedDependencies;
40451
+ const resolvedInput = this.resolveDescribeInput(effectiveTask, input);
40625
40452
  return await recordFlowShape(async (ctx) => {
40626
40453
  const depsWithRecorder = this.injectRecorderIntoDurableDeps(deps, ctx);
40627
- await effectiveTask.run(input, depsWithRecorder);
40454
+ await effectiveTask.run(resolvedInput, depsWithRecorder);
40628
40455
  });
40629
40456
  }
40630
40457
  getWorkflows() {
@@ -40652,6 +40479,23 @@ var DurableResource = class _DurableResource {
40652
40479
  }
40653
40480
  return next;
40654
40481
  }
40482
+ resolveDescribeInput(task2, input) {
40483
+ if (input !== void 0) {
40484
+ return input;
40485
+ }
40486
+ const tagConfig = durableWorkflowTag.extract(task2.tags);
40487
+ if (!tagConfig?.defaults) {
40488
+ return void 0;
40489
+ }
40490
+ try {
40491
+ return structuredClone(tagConfig.defaults);
40492
+ } catch (error2) {
40493
+ const originalMessage = error2 instanceof Error ? error2.message : String(error2);
40494
+ throw new Error(
40495
+ `Cannot describe task "${task2.id}": durableWorkflowTag.defaults could not be cloned. Ensure defaults contain only structured-cloneable values. Original error: ${originalMessage}`
40496
+ );
40497
+ }
40498
+ }
40655
40499
  start(task2, input, options) {
40656
40500
  if (typeof task2 === "string") {
40657
40501
  return this.service.start(task2, input, options);
@@ -44386,50 +44230,6 @@ var redisDurableResource = r.resource("base.durable.redis").register([durableWor
44386
44230
  if (!ctx.runtimeConfig) return;
44387
44231
  await disposeDurableService(durable.service, ctx.runtimeConfig);
44388
44232
  }).build();
44389
-
44390
- // src/node/node.ts
44391
- var globals2 = {
44392
- ...globals,
44393
- resources: {
44394
- ...globals.resources,
44395
- httpSmartClientFactory,
44396
- httpMixedClientFactory
44397
- }
44398
- };
44399
- async function run2(root, config) {
44400
- const rt = await run(root, config);
44401
- const store2 = await rt.getResourceValue(globals.resources.store);
44402
- store2.storeGenericItem(httpSmartClientFactory);
44403
- store2.storeGenericItem(httpMixedClientFactory);
44404
- const serializer3 = await rt.getResourceValue(
44405
- globals.resources.serializer
44406
- );
44407
- const errorRegistry = /* @__PURE__ */ new Map();
44408
- for (const [id2, helper] of store2.errors) errorRegistry.set(id2, helper);
44409
- const contexts = Array.from(store2.asyncContexts.values());
44410
- const smartEntry = store2.resources.get(httpSmartClientFactory.id);
44411
- if (smartEntry && !smartEntry.isInitialized) {
44412
- smartEntry.value = (cfg) => (init_http_smart_client_model(), __toCommonJS(http_smart_client_model_exports)).createHttpSmartClient({
44413
- ...cfg,
44414
- serializer: serializer3,
44415
- contexts,
44416
- errorRegistry
44417
- });
44418
- smartEntry.isInitialized = true;
44419
- }
44420
- const mixedEntry = store2.resources.get(httpMixedClientFactory.id);
44421
- if (mixedEntry && !mixedEntry.isInitialized) {
44422
- mixedEntry.value = (cfg) => (init_http_mixed_client(), __toCommonJS(http_mixed_client_exports)).createHttpMixedClient({
44423
- ...cfg,
44424
- serializer: serializer3,
44425
- contexts,
44426
- errorRegistry
44427
- });
44428
- mixedEntry.isInitialized = true;
44429
- }
44430
- return rt;
44431
- }
44432
- __name(run2, "run");
44433
44233
  /*! Bundled license information:
44434
44234
 
44435
44235
  depd/index.js:
@@ -44717,7 +44517,6 @@ serve-static/index.js:
44717
44517
  *)
44718
44518
  */
44719
44519
 
44720
- exports.DependencyProcessor = DependencyProcessor;
44721
44520
  exports.DurableAuditEntryKind = DurableAuditEntryKind;
44722
44521
  exports.DurableContext = DurableContext;
44723
44522
  exports.DurableExecutionError = DurableExecutionError;
@@ -44725,88 +44524,45 @@ exports.DurableOperator = DurableOperator;
44725
44524
  exports.DurableResource = DurableResource;
44726
44525
  exports.DurableService = DurableService;
44727
44526
  exports.DurableWorker = DurableWorker;
44728
- exports.Errors = errors_exports;
44729
- exports.EventManager = EventManager;
44730
44527
  exports.ExecutionStatus = ExecutionStatus;
44731
- exports.LogPrinter = LogPrinter;
44732
- exports.Logger = Logger;
44733
44528
  exports.MemoryEventBus = MemoryEventBus;
44734
44529
  exports.MemoryQueue = MemoryQueue;
44735
44530
  exports.MemoryStore = MemoryStore;
44736
- exports.MiddlewareManager = MiddlewareManager;
44737
44531
  exports.NodeInputFile = NodeInputFile;
44738
44532
  exports.NoopEventBus = NoopEventBus;
44739
- exports.PlatformAdapter = PlatformAdapter;
44740
- exports.Queue = Queue;
44741
44533
  exports.RabbitMQQueue = RabbitMQQueue;
44742
44534
  exports.RedisEventBus = RedisEventBus;
44743
44535
  exports.RedisStore = RedisStore;
44744
- exports.ResourceInitializer = ResourceInitializer;
44745
- exports.RunResult = RunResult;
44746
- exports.RunnerError = RunnerError;
44747
44536
  exports.ScheduleStatus = ScheduleStatus;
44748
44537
  exports.ScheduleType = ScheduleType;
44749
- exports.Semaphore = Semaphore;
44750
- exports.Serializer = Serializer;
44751
44538
  exports.StepBuilder = StepBuilder;
44752
- exports.Store = Store;
44753
44539
  exports.SuspensionSignal = SuspensionSignal;
44754
- exports.SymbolPolicy = SymbolPolicy;
44755
- exports.SymbolPolicyErrorMessage = SymbolPolicyErrorMessage;
44756
- exports.TaskRunner = TaskRunner;
44757
44540
  exports.TimerStatus = TimerStatus;
44758
44541
  exports.TimerType = TimerType;
44759
- exports.allFalse = allFalse;
44760
- exports.asyncContext = defineAsyncContext;
44761
- exports.bindProcessErrorHandler = bindProcessErrorHandler;
44762
- exports.createContext = createContext2;
44763
44542
  exports.createDashboardMiddleware = createDashboardMiddleware;
44764
- exports.createDefaultUnhandledError = createDefaultUnhandledError;
44765
44543
  exports.createDurableAuditEntryId = createDurableAuditEntryId;
44766
44544
  exports.createDurableRunnerAuditEmitter = createDurableRunnerAuditEmitter;
44767
44545
  exports.createDurableStepId = createDurableStepId;
44768
44546
  exports.createDurableTestSetup = createDurableTestSetup;
44769
- exports.createExposureFetch = createExposureFetch;
44770
- exports.createHttpClient = createHttpClient;
44771
44547
  exports.createHttpMixedClient = createHttpMixedClient;
44772
44548
  exports.createHttpSmartClient = createHttpSmartClient;
44773
44549
  exports.createNodeFile = createNodeFile;
44774
44550
  exports.createRunnerDurableRuntime = createRunnerDurableRuntime;
44775
- exports.createTestResource = createTestResource;
44776
- exports.debug = debug;
44777
- exports.debugLevels = debugLevels;
44778
- exports.definitions = defs_exports;
44779
44551
  exports.disposeDurableService = disposeDurableService;
44780
44552
  exports.durableEvents = durableEvents;
44781
44553
  exports.durableEventsArray = durableEventsArray;
44782
44554
  exports.durableResource = durableResource;
44783
44555
  exports.durableWorkflowTag = durableWorkflowTag;
44784
- exports.event = defineEvent;
44785
- exports.getConfig = getConfig;
44786
- exports.globals = globals2;
44556
+ exports.globals = globals;
44787
44557
  exports.hasExposureContext = hasExposureContext;
44788
- exports.hook = defineHook;
44789
44558
  exports.initDurableService = initDurableService;
44790
44559
  exports.initDurableWorker = initDurableWorker;
44791
44560
  exports.isDurableInternalStepId = isDurableInternalStepId;
44792
- exports.journal = journal;
44793
- exports.levelNormal = levelNormal;
44794
- exports.levelVerbose = levelVerbose;
44795
44561
  exports.memoryDurableResource = memoryDurableResource;
44796
44562
  exports.nodeExposure = nodeExposure;
44797
- exports.normalizeError = normalizeError;
44798
- exports.override = defineOverride;
44799
- exports.r = r;
44800
44563
  exports.readInputFileToBuffer = readInputFileToBuffer;
44801
44564
  exports.redisDurableResource = redisDurableResource;
44802
- exports.resource = defineResource;
44803
- exports.resourceMiddleware = defineResourceMiddleware;
44804
- exports.run = run2;
44805
- exports.safeReportUnhandledError = safeReportUnhandledError;
44806
- exports.setPlatform = setPlatform;
44807
- exports.tag = defineTag;
44808
- exports.task = defineTask;
44809
- exports.taskMiddleware = defineTaskMiddleware;
44565
+ exports.run = run;
44810
44566
  exports.useExposureContext = useExposureContext;
44811
44567
  exports.waitUntil = waitUntil;
44812
44568
  exports.writeInputFileToPath = writeInputFileToPath;