@bluelibs/runner 4.8.0 → 4.8.2

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.
@@ -0,0 +1,17 @@
1
+ import type { MixedHttpClient } from "../http-mixed-client";
2
+ export interface HttpMixedClientFactoryConfig {
3
+ baseUrl: string;
4
+ auth?: {
5
+ header?: string;
6
+ token: string;
7
+ };
8
+ timeoutMs?: number;
9
+ fetchImpl?: typeof fetch;
10
+ onRequest?: (ctx: {
11
+ url: string;
12
+ headers: Record<string, string>;
13
+ }) => void | Promise<void>;
14
+ }
15
+ export type HttpMixedClientFactory = (config: HttpMixedClientFactoryConfig) => MixedHttpClient;
16
+ export declare const httpMixedClientFactory: import("..").IResource<void, Promise<HttpMixedClientFactory>, {}, any, any, import("..").TagType[], import("..").ResourceMiddlewareAttachmentType[]>;
17
+ export type { MixedHttpClient };
@@ -0,0 +1,16 @@
1
+ import type { HttpSmartClient } from "../http-smart-client.model";
2
+ export interface HttpSmartClientFactoryConfig {
3
+ baseUrl: string;
4
+ auth?: {
5
+ header?: string;
6
+ token: string;
7
+ };
8
+ timeoutMs?: number;
9
+ onRequest?: (ctx: {
10
+ url: string;
11
+ headers: Record<string, string>;
12
+ }) => void | Promise<void>;
13
+ }
14
+ export type HttpSmartClientFactory = (config: HttpSmartClientFactoryConfig) => HttpSmartClient;
15
+ export declare const httpSmartClientFactory: import("..").IResource<void, Promise<HttpSmartClientFactory>, {}, any, any, import("..").TagType[], import("..").ResourceMiddlewareAttachmentType[]>;
16
+ export type { HttpSmartClient };
@@ -362,7 +362,7 @@ var error = errorBuilder;
362
362
 
363
363
  // src/platform/adapters/node-als.ts
364
364
  async function loadAsyncLocalStorageClass() {
365
- const mod = await import('async_hooks');
365
+ const mod = __require("async_hooks");
366
366
  return mod.AsyncLocalStorage;
367
367
  }
368
368
  __name(loadAsyncLocalStorageClass, "loadAsyncLocalStorageClass");
@@ -1248,7 +1248,7 @@ function defineAsyncContext(def) {
1248
1248
  map.set(ctxId, value);
1249
1249
  return storage.run(map, fn);
1250
1250
  }, "provide");
1251
- const serializer = getDefaultSerializer();
1251
+ const serializer2 = getDefaultSerializer();
1252
1252
  const api = {
1253
1253
  id: ctxId,
1254
1254
  [symbolAsyncContext]: true,
@@ -1264,9 +1264,9 @@ function defineAsyncContext(def) {
1264
1264
  });
1265
1265
  },
1266
1266
  /* istanbul ignore next */
1267
- serialize: def.serialize || ((data) => serializer.stringify(data)),
1267
+ serialize: def.serialize || ((data) => serializer2.stringify(data)),
1268
1268
  /* istanbul ignore next */
1269
- parse: def.parse || ((data) => serializer.parse(data)),
1269
+ parse: def.parse || ((data) => serializer2.parse(data)),
1270
1270
  optional() {
1271
1271
  return {
1272
1272
  inner: api,
@@ -1427,6 +1427,352 @@ var queueResource = defineResource({
1427
1427
  }
1428
1428
  });
1429
1429
 
1430
+ // src/globals/resources/tunnel/protocol.ts
1431
+ var TunnelError = class extends Error {
1432
+ static {
1433
+ __name(this, "TunnelError");
1434
+ }
1435
+ constructor(code, message, details, extras) {
1436
+ super(message);
1437
+ this.name = "TunnelError";
1438
+ this.code = code;
1439
+ this.details = details;
1440
+ this.id = extras?.id;
1441
+ this.data = extras?.data;
1442
+ }
1443
+ };
1444
+ function toTunnelError(input, fallbackMessage) {
1445
+ if (input instanceof Error) {
1446
+ return new TunnelError("UNKNOWN", input.message);
1447
+ }
1448
+ if (input && typeof input === "object" && "code" in input && "message" in input && typeof input.message === "string" && typeof input.code === "string") {
1449
+ const pe = input;
1450
+ const msg = pe.message || fallbackMessage || "Tunnel error";
1451
+ return new TunnelError(pe.code, msg, pe.details, {
1452
+ id: pe.id,
1453
+ data: pe.data
1454
+ });
1455
+ }
1456
+ if (input && typeof input === "object" && "message" in input && typeof input.message === "string") {
1457
+ return new TunnelError("UNKNOWN", input.message);
1458
+ }
1459
+ return new TunnelError(
1460
+ "UNKNOWN",
1461
+ typeof input === "string" && input || fallbackMessage || "Tunnel error"
1462
+ );
1463
+ }
1464
+ __name(toTunnelError, "toTunnelError");
1465
+ function assertOkEnvelope(envelope, opts) {
1466
+ if (!envelope || typeof envelope !== "object") {
1467
+ throw new TunnelError(
1468
+ "INVALID_RESPONSE",
1469
+ opts?.fallbackMessage || "Invalid or empty response"
1470
+ );
1471
+ }
1472
+ if (envelope.ok) {
1473
+ return envelope.result;
1474
+ }
1475
+ if (envelope.error) {
1476
+ return (() => {
1477
+ throw toTunnelError(envelope.error, opts?.fallbackMessage);
1478
+ })();
1479
+ }
1480
+ throw new TunnelError("UNKNOWN", opts?.fallbackMessage || "Tunnel error");
1481
+ }
1482
+ __name(assertOkEnvelope, "assertOkEnvelope");
1483
+
1484
+ // src/http-fetch-tunnel.resource.ts
1485
+ async function postSerialized(fetchFn, url, body, headers, timeoutMs, serializer2, onRequest, contextHeaderText) {
1486
+ const controller = timeoutMs && timeoutMs > 0 ? new AbortController() : void 0;
1487
+ let timeout;
1488
+ try {
1489
+ if (controller) {
1490
+ timeout = setTimeout(() => controller.abort(), timeoutMs);
1491
+ }
1492
+ const reqHeaders = {
1493
+ "content-type": "application/json; charset=utf-8",
1494
+ ...headers
1495
+ };
1496
+ if (contextHeaderText) reqHeaders["x-runner-context"] = contextHeaderText;
1497
+ if (onRequest) await onRequest({ url, headers: reqHeaders });
1498
+ const res = await fetchFn(url, {
1499
+ method: "POST",
1500
+ headers: reqHeaders,
1501
+ body: serializer2.stringify(body),
1502
+ signal: controller?.signal
1503
+ });
1504
+ const text = await res.text();
1505
+ const json = text ? serializer2.parse(text) : void 0;
1506
+ return json;
1507
+ } finally {
1508
+ if (timeout) clearTimeout(timeout);
1509
+ }
1510
+ }
1511
+ __name(postSerialized, "postSerialized");
1512
+ function createExposureFetch(cfg) {
1513
+ const baseUrl = (cfg?.baseUrl).replace(/\/$/, "");
1514
+ if (!baseUrl) throw new Error("createExposureFetch requires baseUrl");
1515
+ const headerName = (cfg?.auth?.header ?? "x-runner-token").toLowerCase();
1516
+ const buildHeaders = /* @__PURE__ */ __name(() => {
1517
+ const headers = {};
1518
+ if (cfg?.auth?.token) headers[headerName] = cfg.auth.token;
1519
+ return headers;
1520
+ }, "buildHeaders");
1521
+ const fetchImpl = cfg.fetchImpl ?? globalThis.fetch;
1522
+ if (typeof fetchImpl !== "function") {
1523
+ throw new Error(
1524
+ "global fetch is not available; provide fetchImpl in config"
1525
+ );
1526
+ }
1527
+ const buildContextHeader = /* @__PURE__ */ __name(() => {
1528
+ if (!cfg.contexts || cfg.contexts.length === 0) return void 0;
1529
+ const map = {};
1530
+ for (const ctx of cfg.contexts) {
1531
+ try {
1532
+ const v = ctx.use();
1533
+ map[ctx.id] = ctx.serialize(v);
1534
+ } catch {
1535
+ }
1536
+ }
1537
+ const keys = Object.keys(map);
1538
+ if (keys.length === 0) return void 0;
1539
+ return cfg.serializer.stringify(map);
1540
+ }, "buildContextHeader");
1541
+ return {
1542
+ async task(id2, input) {
1543
+ const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
1544
+ const r2 = await postSerialized(
1545
+ fetchImpl,
1546
+ url,
1547
+ { input },
1548
+ buildHeaders(),
1549
+ cfg?.timeoutMs,
1550
+ cfg.serializer,
1551
+ cfg?.onRequest,
1552
+ buildContextHeader()
1553
+ );
1554
+ try {
1555
+ return assertOkEnvelope(r2, { fallbackMessage: "Tunnel task error" });
1556
+ } catch (e) {
1557
+ const te = e;
1558
+ if (te && cfg.errorRegistry && te.id && te.data) {
1559
+ const helper = cfg.errorRegistry.get(String(te.id));
1560
+ if (helper) helper.throw(te.data);
1561
+ }
1562
+ throw e;
1563
+ }
1564
+ },
1565
+ async event(id2, payload) {
1566
+ const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
1567
+ const r2 = await postSerialized(
1568
+ fetchImpl,
1569
+ url,
1570
+ { payload },
1571
+ buildHeaders(),
1572
+ cfg?.timeoutMs,
1573
+ cfg.serializer,
1574
+ cfg?.onRequest,
1575
+ buildContextHeader()
1576
+ );
1577
+ try {
1578
+ assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
1579
+ } catch (e) {
1580
+ const te = e;
1581
+ if (te && cfg.errorRegistry && te.id && te.data) {
1582
+ const helper = cfg.errorRegistry.get(String(te.id));
1583
+ if (helper) helper.throw(te.data);
1584
+ }
1585
+ throw e;
1586
+ }
1587
+ }
1588
+ };
1589
+ }
1590
+ __name(createExposureFetch, "createExposureFetch");
1591
+
1592
+ // src/tunnels/buildUniversalManifest.ts
1593
+ function buildUniversalManifest(input) {
1594
+ const nodeFiles = [];
1595
+ const webFiles = [];
1596
+ function visit(value) {
1597
+ if (!value || typeof value !== "object") return value;
1598
+ if (value.$ejson === "File" && typeof value.id === "string") {
1599
+ const v = value;
1600
+ const id2 = v.id;
1601
+ const meta = v.meta;
1602
+ const node = v._node;
1603
+ const web = v._web;
1604
+ if (node?.buffer) {
1605
+ nodeFiles.push({
1606
+ id: id2,
1607
+ meta,
1608
+ source: { type: "buffer", buffer: node.buffer }
1609
+ });
1610
+ } else if (node?.stream) {
1611
+ nodeFiles.push({
1612
+ id: id2,
1613
+ meta,
1614
+ source: { type: "stream", stream: node.stream }
1615
+ });
1616
+ } else if (web?.blob) {
1617
+ webFiles.push({ id: id2, meta, blob: web.blob });
1618
+ }
1619
+ const copy = { $ejson: "File", id: id2, meta };
1620
+ return copy;
1621
+ }
1622
+ if (Array.isArray(value)) {
1623
+ return value.map((x) => visit(x));
1624
+ }
1625
+ const out = {};
1626
+ for (const k of Object.keys(value)) {
1627
+ out[k] = visit(value[k]);
1628
+ }
1629
+ return out;
1630
+ }
1631
+ __name(visit, "visit");
1632
+ const cloned = visit(input);
1633
+ return {
1634
+ input: cloned,
1635
+ nodeFiles,
1636
+ webFiles
1637
+ };
1638
+ }
1639
+ __name(buildUniversalManifest, "buildUniversalManifest");
1640
+
1641
+ // src/http-client.ts
1642
+ function toHeaders(auth) {
1643
+ const headers = {};
1644
+ if (auth?.token)
1645
+ headers[(auth.header ?? "x-runner-token").toLowerCase()] = auth.token;
1646
+ return headers;
1647
+ }
1648
+ __name(toHeaders, "toHeaders");
1649
+ function createHttpClient(cfg) {
1650
+ const baseUrl = cfg.baseUrl.replace(/\/$/, "");
1651
+ if (!baseUrl) throw new Error("createHttpClient requires baseUrl");
1652
+ const fetchClient = createExposureFetch({
1653
+ baseUrl,
1654
+ auth: cfg.auth,
1655
+ timeoutMs: cfg.timeoutMs,
1656
+ fetchImpl: cfg.fetchImpl,
1657
+ serializer: cfg.serializer,
1658
+ onRequest: cfg.onRequest,
1659
+ contexts: cfg.contexts,
1660
+ errorRegistry: cfg.errorRegistry
1661
+ });
1662
+ async function postMultipartBrowser(url, manifestText, files) {
1663
+ const fd = new FormData();
1664
+ fd.append("__manifest", manifestText);
1665
+ for (const f of files) {
1666
+ const filename = f.meta?.name ?? "upload";
1667
+ fd.append(`file:${f.id}`, f.blob, filename);
1668
+ }
1669
+ const headers = toHeaders(cfg.auth);
1670
+ if (cfg.contexts && cfg.contexts.length > 0) {
1671
+ const map = {};
1672
+ for (const ctx of cfg.contexts) {
1673
+ try {
1674
+ const v = ctx.use();
1675
+ map[ctx.id] = ctx.serialize(v);
1676
+ } catch {
1677
+ }
1678
+ }
1679
+ if (Object.keys(map).length > 0) {
1680
+ headers["x-runner-context"] = cfg.serializer.stringify(map);
1681
+ }
1682
+ }
1683
+ if (cfg.onRequest) await cfg.onRequest({ url, headers });
1684
+ const fetchImpl = cfg.fetchImpl ?? globalThis.fetch;
1685
+ const res = await fetchImpl(url, { method: "POST", body: fd, headers });
1686
+ const text = await res.text();
1687
+ const json = text ? cfg.serializer.parse(text) : void 0;
1688
+ return json;
1689
+ }
1690
+ __name(postMultipartBrowser, "postMultipartBrowser");
1691
+ return {
1692
+ async task(id2, input) {
1693
+ const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
1694
+ if (input && typeof input.pipe === "function") {
1695
+ throw new Error(
1696
+ "createHttpClient (universal) cannot send a Node stream. Use @bluelibs/runner/node createHttpSmartClient or createHttpMixedClient for duplex/streaming."
1697
+ );
1698
+ }
1699
+ const manifest = buildUniversalManifest(input);
1700
+ if (manifest.webFiles.length > 0) {
1701
+ const manifestText = cfg.serializer.stringify({ input: manifest.input });
1702
+ const r2 = await postMultipartBrowser(url, manifestText, manifest.webFiles);
1703
+ try {
1704
+ return assertOkEnvelope(r2, {
1705
+ fallbackMessage: "Tunnel task error"
1706
+ });
1707
+ } catch (e) {
1708
+ const te = e;
1709
+ if (te && cfg.errorRegistry && te.id && te.data) {
1710
+ const helper = cfg.errorRegistry.get(String(te.id));
1711
+ if (helper) helper.throw(te.data);
1712
+ }
1713
+ throw e;
1714
+ }
1715
+ }
1716
+ if (manifest.nodeFiles.length > 0) {
1717
+ throw new Error(
1718
+ "createHttpClient (universal) detected Node file input. Use @bluelibs/runner/node createHttpSmartClient or createHttpMixedClient for Node streaming/multipart."
1719
+ );
1720
+ }
1721
+ try {
1722
+ return await fetchClient.task(id2, input);
1723
+ } catch (e) {
1724
+ const te = e;
1725
+ if (te && cfg.errorRegistry && te.id && te.data) {
1726
+ const helper = cfg.errorRegistry.get(String(te.id));
1727
+ if (helper) helper.throw(te.data);
1728
+ }
1729
+ throw e;
1730
+ }
1731
+ },
1732
+ async event(id2, payload) {
1733
+ try {
1734
+ return await fetchClient.event(id2, payload);
1735
+ } catch (e) {
1736
+ const te = e;
1737
+ if (te && cfg.errorRegistry && te.id && te.data) {
1738
+ const helper = cfg.errorRegistry.get(String(te.id));
1739
+ if (helper) helper.throw(te.data);
1740
+ }
1741
+ throw e;
1742
+ }
1743
+ }
1744
+ };
1745
+ }
1746
+ __name(createHttpClient, "createHttpClient");
1747
+
1748
+ // src/globals/resources/httpClientFactory.resource.ts
1749
+ var httpClientFactory = defineResource({
1750
+ id: "globals.resources.httpClientFactory",
1751
+ meta: {
1752
+ title: "HTTP Client Factory",
1753
+ description: "Factory for creating HTTP clients with automatic injection of serializer, error registry, and async contexts from the store."
1754
+ },
1755
+ // Use it as a function to avoid circular dependencies, and undefined
1756
+ dependencies: /* @__PURE__ */ __name(() => ({
1757
+ serializer,
1758
+ store
1759
+ }), "dependencies"),
1760
+ init: /* @__PURE__ */ __name(async (_, { serializer: serializer2, store: store2 }) => {
1761
+ const errorRegistry = /* @__PURE__ */ new Map();
1762
+ for (const [id2, helper] of store2.errors) {
1763
+ errorRegistry.set(id2, helper);
1764
+ }
1765
+ const contexts = Array.from(store2.asyncContexts.values());
1766
+ const create = /* @__PURE__ */ __name((config) => createHttpClient({
1767
+ ...config,
1768
+ serializer: serializer2,
1769
+ errorRegistry,
1770
+ contexts
1771
+ }), "create");
1772
+ return create;
1773
+ }, "init")
1774
+ });
1775
+
1430
1776
  // src/globals/globalResources.ts
1431
1777
  var systemTag2 = globalTags.system;
1432
1778
  var store = defineResource({
@@ -1437,6 +1783,14 @@ var store = defineResource({
1437
1783
  },
1438
1784
  tags: [systemTag2]
1439
1785
  });
1786
+ var serializer = defineResource({
1787
+ id: "globals.resources.serializer",
1788
+ meta: {
1789
+ title: "Serializer",
1790
+ description: "Serializes and deserializes data. Provides EJSON-compatible stringify/parse and custom type registration via addType."
1791
+ },
1792
+ tags: [systemTag2]
1793
+ });
1440
1794
  var globalResources = {
1441
1795
  store,
1442
1796
  middlewareManager: defineResource({
@@ -1472,16 +1826,10 @@ var globalResources = {
1472
1826
  },
1473
1827
  tags: [systemTag2]
1474
1828
  }),
1475
- serializer: defineResource({
1476
- id: "globals.resources.serializer",
1477
- meta: {
1478
- title: "Serializer",
1479
- description: "Serializes and deserializes data. Provides EJSON-compatible stringify/parse and custom type registration via addType."
1480
- },
1481
- tags: [systemTag2]
1482
- }),
1829
+ serializer,
1483
1830
  cache: cacheResource,
1484
- queue: queueResource
1831
+ queue: queueResource,
1832
+ httpClientFactory
1485
1833
  };
1486
1834
 
1487
1835
  // src/globals/middleware/retry.middleware.ts
@@ -4043,6 +4391,7 @@ var Store = class {
4043
4391
  this.middlewareManager
4044
4392
  );
4045
4393
  this.registry.storeGenericItem(globalResources.queue);
4394
+ this.registry.storeGenericItem(globalResources.httpClientFactory);
4046
4395
  for (const [resource2, value] of builtInResourcesMap.entries()) {
4047
4396
  this.registry.storeGenericItem(resource2);
4048
4397
  const entry = this.resources.get(resource2.id);
@@ -4708,168 +5057,6 @@ function extractResourceAndConfig(resourceOrResourceWithConfig) {
4708
5057
  }
4709
5058
  __name(extractResourceAndConfig, "extractResourceAndConfig");
4710
5059
 
4711
- // src/globals/resources/tunnel/protocol.ts
4712
- var TunnelError = class extends Error {
4713
- static {
4714
- __name(this, "TunnelError");
4715
- }
4716
- constructor(code, message, details, extras) {
4717
- super(message);
4718
- this.name = "TunnelError";
4719
- this.code = code;
4720
- this.details = details;
4721
- this.id = extras?.id;
4722
- this.data = extras?.data;
4723
- }
4724
- };
4725
- function toTunnelError(input, fallbackMessage) {
4726
- if (input instanceof Error) {
4727
- return new TunnelError("UNKNOWN", input.message);
4728
- }
4729
- if (input && typeof input === "object" && "code" in input && "message" in input && typeof input.message === "string" && typeof input.code === "string") {
4730
- const pe = input;
4731
- const msg = pe.message || fallbackMessage || "Tunnel error";
4732
- return new TunnelError(pe.code, msg, pe.details, {
4733
- id: pe.id,
4734
- data: pe.data
4735
- });
4736
- }
4737
- if (input && typeof input === "object" && "message" in input && typeof input.message === "string") {
4738
- return new TunnelError("UNKNOWN", input.message);
4739
- }
4740
- return new TunnelError(
4741
- "UNKNOWN",
4742
- typeof input === "string" && input || fallbackMessage || "Tunnel error"
4743
- );
4744
- }
4745
- __name(toTunnelError, "toTunnelError");
4746
- function assertOkEnvelope(envelope, opts) {
4747
- if (!envelope || typeof envelope !== "object") {
4748
- throw new TunnelError(
4749
- "INVALID_RESPONSE",
4750
- opts?.fallbackMessage || "Invalid or empty response"
4751
- );
4752
- }
4753
- if (envelope.ok) {
4754
- return envelope.result;
4755
- }
4756
- if (envelope.error) {
4757
- return (() => {
4758
- throw toTunnelError(envelope.error, opts?.fallbackMessage);
4759
- })();
4760
- }
4761
- throw new TunnelError("UNKNOWN", opts?.fallbackMessage || "Tunnel error");
4762
- }
4763
- __name(assertOkEnvelope, "assertOkEnvelope");
4764
-
4765
- // src/http-fetch-tunnel.resource.ts
4766
- async function postSerialized(fetchFn, url, body, headers, timeoutMs, serializer, onRequest, contextHeaderText) {
4767
- const controller = timeoutMs && timeoutMs > 0 ? new AbortController() : void 0;
4768
- let timeout;
4769
- try {
4770
- if (controller) {
4771
- timeout = setTimeout(() => controller.abort(), timeoutMs);
4772
- }
4773
- const reqHeaders = {
4774
- "content-type": "application/json; charset=utf-8",
4775
- ...headers
4776
- };
4777
- if (contextHeaderText) reqHeaders["x-runner-context"] = contextHeaderText;
4778
- if (onRequest) await onRequest({ url, headers: reqHeaders });
4779
- const res = await fetchFn(url, {
4780
- method: "POST",
4781
- headers: reqHeaders,
4782
- body: serializer.stringify(body),
4783
- signal: controller?.signal
4784
- });
4785
- const text = await res.text();
4786
- const json = text ? serializer.parse(text) : void 0;
4787
- return json;
4788
- } finally {
4789
- if (timeout) clearTimeout(timeout);
4790
- }
4791
- }
4792
- __name(postSerialized, "postSerialized");
4793
- function createExposureFetch(cfg) {
4794
- const baseUrl = (cfg?.baseUrl).replace(/\/$/, "");
4795
- if (!baseUrl) throw new Error("createExposureFetch requires baseUrl");
4796
- const headerName = (cfg?.auth?.header ?? "x-runner-token").toLowerCase();
4797
- const buildHeaders = /* @__PURE__ */ __name(() => {
4798
- const headers = {};
4799
- if (cfg?.auth?.token) headers[headerName] = cfg.auth.token;
4800
- return headers;
4801
- }, "buildHeaders");
4802
- const fetchImpl = cfg.fetchImpl ?? globalThis.fetch;
4803
- if (typeof fetchImpl !== "function") {
4804
- throw new Error(
4805
- "global fetch is not available; provide fetchImpl in config"
4806
- );
4807
- }
4808
- const buildContextHeader = /* @__PURE__ */ __name(() => {
4809
- if (!cfg.contexts || cfg.contexts.length === 0) return void 0;
4810
- const map = {};
4811
- for (const ctx of cfg.contexts) {
4812
- try {
4813
- const v = ctx.use();
4814
- map[ctx.id] = ctx.serialize(v);
4815
- } catch {
4816
- }
4817
- }
4818
- const keys = Object.keys(map);
4819
- if (keys.length === 0) return void 0;
4820
- return cfg.serializer.stringify(map);
4821
- }, "buildContextHeader");
4822
- return {
4823
- async task(id2, input) {
4824
- const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
4825
- const r2 = await postSerialized(
4826
- fetchImpl,
4827
- url,
4828
- { input },
4829
- buildHeaders(),
4830
- cfg?.timeoutMs,
4831
- cfg.serializer,
4832
- cfg?.onRequest,
4833
- buildContextHeader()
4834
- );
4835
- try {
4836
- return assertOkEnvelope(r2, { fallbackMessage: "Tunnel task error" });
4837
- } catch (e) {
4838
- const te = e;
4839
- if (te && cfg.errorRegistry && te.id && te.data) {
4840
- const helper = cfg.errorRegistry.get(String(te.id));
4841
- if (helper) helper.throw(te.data);
4842
- }
4843
- throw e;
4844
- }
4845
- },
4846
- async event(id2, payload) {
4847
- const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
4848
- const r2 = await postSerialized(
4849
- fetchImpl,
4850
- url,
4851
- { payload },
4852
- buildHeaders(),
4853
- cfg?.timeoutMs,
4854
- cfg.serializer,
4855
- cfg?.onRequest,
4856
- buildContextHeader()
4857
- );
4858
- try {
4859
- assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
4860
- } catch (e) {
4861
- const te = e;
4862
- if (te && cfg.errorRegistry && te.id && te.data) {
4863
- const helper = cfg.errorRegistry.get(String(te.id));
4864
- if (helper) helper.throw(te.data);
4865
- }
4866
- throw e;
4867
- }
4868
- }
4869
- };
4870
- }
4871
- __name(createExposureFetch, "createExposureFetch");
4872
-
4873
5060
  // src/globals/tunnels/index.ts
4874
5061
  var http = Object.freeze({
4875
5062
  createClient(cfg) {