iii-sdk 0.19.3 → 0.19.4-alpha.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.
Files changed (85) hide show
  1. package/dist/channel.cjs +5 -0
  2. package/dist/channel.d.cts +2 -0
  3. package/dist/channel.d.mts +2 -0
  4. package/dist/channel.mjs +3 -0
  5. package/dist/{utils-DXL7JI0q.mjs → channels-BFs4n1g6.mjs} +2 -107
  6. package/dist/channels-BFs4n1g6.mjs.map +1 -0
  7. package/dist/{utils-CuS1Knym.cjs → channels-huduKJ-b.cjs} +2 -165
  8. package/dist/channels-huduKJ-b.cjs.map +1 -0
  9. package/dist/engine.cjs +5 -0
  10. package/dist/engine.d.cts +3 -0
  11. package/dist/engine.d.mts +3 -0
  12. package/dist/engine.mjs +3 -0
  13. package/dist/errors.cjs +33 -0
  14. package/dist/errors.cjs.map +1 -0
  15. package/dist/errors.d.cts +52 -0
  16. package/dist/errors.d.cts.map +1 -0
  17. package/dist/errors.d.mts +52 -0
  18. package/dist/errors.d.mts.map +1 -0
  19. package/dist/errors.mjs +29 -0
  20. package/dist/errors.mjs.map +1 -0
  21. package/dist/helpers.cjs +4 -3
  22. package/dist/helpers.cjs.map +1 -1
  23. package/dist/helpers.d.cts +19 -1
  24. package/dist/helpers.d.cts.map +1 -1
  25. package/dist/helpers.d.mts +19 -1
  26. package/dist/helpers.d.mts.map +1 -1
  27. package/dist/helpers.mjs +2 -1
  28. package/dist/helpers.mjs.map +1 -1
  29. package/dist/iii-constants-Baptl8nm.d.mts +47 -0
  30. package/dist/iii-constants-Baptl8nm.d.mts.map +1 -0
  31. package/dist/iii-constants-BqXp8xSN.d.cts +47 -0
  32. package/dist/iii-constants-BqXp8xSN.d.cts.map +1 -0
  33. package/dist/iii-constants-Br94RUNi.cjs +67 -0
  34. package/dist/iii-constants-Br94RUNi.cjs.map +1 -0
  35. package/dist/iii-constants-_k3SoHry.mjs +43 -0
  36. package/dist/iii-constants-_k3SoHry.mjs.map +1 -0
  37. package/dist/iii-types-6aHBgy7l.cjs +24 -0
  38. package/dist/iii-types-6aHBgy7l.cjs.map +1 -0
  39. package/dist/iii-types-CRx2qAjB.mjs +18 -0
  40. package/dist/iii-types-CRx2qAjB.mjs.map +1 -0
  41. package/dist/index.cjs +56 -133
  42. package/dist/index.cjs.map +1 -1
  43. package/dist/index.d.cts +8 -76
  44. package/dist/index.d.cts.map +1 -1
  45. package/dist/index.d.mts +8 -76
  46. package/dist/index.d.mts.map +1 -1
  47. package/dist/index.mjs +13 -88
  48. package/dist/index.mjs.map +1 -1
  49. package/dist/internal.cjs +0 -0
  50. package/dist/internal.d.cts +2 -0
  51. package/dist/internal.d.mts +2 -0
  52. package/dist/internal.mjs +1 -0
  53. package/dist/protocol.cjs +4 -0
  54. package/dist/protocol.d.cts +2 -0
  55. package/dist/protocol.d.mts +2 -0
  56. package/dist/protocol.mjs +3 -0
  57. package/dist/runtime.cjs +0 -0
  58. package/dist/runtime.d.cts +3 -0
  59. package/dist/runtime.d.mts +3 -0
  60. package/dist/runtime.mjs +1 -0
  61. package/dist/state.cjs.map +1 -1
  62. package/dist/state.d.cts +1 -1
  63. package/dist/state.d.mts +1 -1
  64. package/dist/state.mjs.map +1 -1
  65. package/dist/stream.d.cts +4 -245
  66. package/dist/stream.d.cts.map +1 -1
  67. package/dist/stream.d.mts +4 -245
  68. package/dist/stream.d.mts.map +1 -1
  69. package/dist/trigger.cjs +0 -0
  70. package/dist/trigger.d.cts +2 -0
  71. package/dist/trigger.d.mts +2 -0
  72. package/dist/trigger.mjs +1 -0
  73. package/dist/{utils-BnRzIUCy.d.cts → types-DduY0ha2.d.mts} +18 -203
  74. package/dist/types-DduY0ha2.d.mts.map +1 -0
  75. package/dist/{utils-e84Qph-9.d.mts → types-gwm9j9oD.d.cts} +18 -203
  76. package/dist/types-gwm9j9oD.d.cts.map +1 -0
  77. package/dist/utils-BtEFReHq.cjs +121 -0
  78. package/dist/utils-BtEFReHq.cjs.map +1 -0
  79. package/dist/utils-Cuv_ksKp.mjs +69 -0
  80. package/dist/utils-Cuv_ksKp.mjs.map +1 -0
  81. package/package.json +38 -2
  82. package/dist/utils-BnRzIUCy.d.cts.map +0 -1
  83. package/dist/utils-CuS1Knym.cjs.map +0 -1
  84. package/dist/utils-DXL7JI0q.mjs.map +0 -1
  85. package/dist/utils-e84Qph-9.d.mts.map +0 -1
@@ -0,0 +1,121 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) {
13
+ __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ }
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+
27
+ //#endregion
28
+ let node_fs = require("node:fs");
29
+ node_fs = __toESM(node_fs);
30
+ let node_path = require("node:path");
31
+ node_path = __toESM(node_path);
32
+
33
+ //#region src/utils.ts
34
+ /**
35
+ * Returns a project identifier for telemetry, derived from the current working
36
+ * directory. Reads `package.json` `name` if present at `cwd`; otherwise falls
37
+ * back to the basename of `cwd`. Returns `undefined` only when both signals
38
+ * are unavailable (e.g. cwd is the filesystem root).
39
+ *
40
+ * No directory walking — only inspects `cwd` itself, so the SDK never reads
41
+ * files outside the user's explicit working directory.
42
+ */
43
+ function detectProjectName(cwd = process.cwd()) {
44
+ try {
45
+ const manifest = node_path.join(cwd, "package.json");
46
+ if (node_fs.existsSync(manifest)) {
47
+ const parsed = JSON.parse(node_fs.readFileSync(manifest, "utf8"));
48
+ if (typeof parsed.name === "string") {
49
+ const trimmed = parsed.name.trim();
50
+ if (trimmed) return trimmed;
51
+ }
52
+ }
53
+ } catch {}
54
+ return node_path.basename(cwd).trim() || void 0;
55
+ }
56
+ /**
57
+ * Type guard that checks if a value is a {@link StreamChannelRef}.
58
+ *
59
+ * @param value - Value to check.
60
+ * @returns `true` if the value is a valid `StreamChannelRef`.
61
+ */
62
+ const isChannelRef = (value) => {
63
+ if (typeof value !== "object" || value === null) return false;
64
+ const maybe = value;
65
+ return typeof maybe.channel_id === "string" && typeof maybe.access_key === "string" && (maybe.direction === "read" || maybe.direction === "write");
66
+ };
67
+ /**
68
+ * Recursively extract all {@link StreamChannelRef} values from a JSON-like
69
+ * input, returning each match paired with its dotted/bracketed path. Mirrors
70
+ * the Rust SDK's `extract_channel_refs`.
71
+ *
72
+ * @param data - Arbitrary JSON-like value.
73
+ * @returns Array of `[path, ref]` tuples. Empty when no refs are found.
74
+ */
75
+ const extractChannelRefs = (data) => {
76
+ const refs = [];
77
+ extractRefsRecursive(data, "", refs);
78
+ return refs;
79
+ };
80
+ const extractRefsRecursive = (data, prefix, refs) => {
81
+ if (isChannelRef(data)) {
82
+ refs.push([prefix, data]);
83
+ return;
84
+ }
85
+ if (Array.isArray(data)) {
86
+ for (let i = 0; i < data.length; i++) {
87
+ const path = prefix === "" ? `[${i}]` : `${prefix}[${i}]`;
88
+ extractRefsRecursive(data[i], path, refs);
89
+ }
90
+ return;
91
+ }
92
+ if (typeof data !== "object" || data === null) return;
93
+ for (const [key, value] of Object.entries(data)) extractRefsRecursive(value, prefix === "" ? key : `${prefix}.${key}`, refs);
94
+ };
95
+
96
+ //#endregion
97
+ Object.defineProperty(exports, '__toESM', {
98
+ enumerable: true,
99
+ get: function () {
100
+ return __toESM;
101
+ }
102
+ });
103
+ Object.defineProperty(exports, 'detectProjectName', {
104
+ enumerable: true,
105
+ get: function () {
106
+ return detectProjectName;
107
+ }
108
+ });
109
+ Object.defineProperty(exports, 'extractChannelRefs', {
110
+ enumerable: true,
111
+ get: function () {
112
+ return extractChannelRefs;
113
+ }
114
+ });
115
+ Object.defineProperty(exports, 'isChannelRef', {
116
+ enumerable: true,
117
+ get: function () {
118
+ return isChannelRef;
119
+ }
120
+ });
121
+ //# sourceMappingURL=utils-BtEFReHq.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils-BtEFReHq.cjs","names":["path","fs"],"sources":["../src/utils.ts"],"sourcesContent":["import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport type { StreamChannelRef } from './iii-types'\n\n/**\n * Returns a project identifier for telemetry, derived from the current working\n * directory. Reads `package.json` `name` if present at `cwd`; otherwise falls\n * back to the basename of `cwd`. Returns `undefined` only when both signals\n * are unavailable (e.g. cwd is the filesystem root).\n *\n * No directory walking — only inspects `cwd` itself, so the SDK never reads\n * files outside the user's explicit working directory.\n */\nexport function detectProjectName(cwd: string = process.cwd()): string | undefined {\n try {\n const manifest = path.join(cwd, 'package.json')\n if (fs.existsSync(manifest)) {\n const parsed = JSON.parse(fs.readFileSync(manifest, 'utf8')) as { name?: unknown }\n if (typeof parsed.name === 'string') {\n const trimmed = parsed.name.trim()\n if (trimmed) return trimmed\n }\n }\n } catch {\n // fall through to directory-name fallback\n }\n\n const base = path.basename(cwd).trim()\n return base || undefined\n}\n\n/**\n * Type guard that checks if a value is a {@link StreamChannelRef}.\n *\n * @param value - Value to check.\n * @returns `true` if the value is a valid `StreamChannelRef`.\n */\nexport const isChannelRef = (value: unknown): value is StreamChannelRef => {\n if (typeof value !== 'object' || value === null) return false\n const maybe = value as Partial<StreamChannelRef>\n return (\n typeof maybe.channel_id === 'string' &&\n typeof maybe.access_key === 'string' &&\n (maybe.direction === 'read' || maybe.direction === 'write')\n )\n}\n\n/**\n * Recursively extract all {@link StreamChannelRef} values from a JSON-like\n * input, returning each match paired with its dotted/bracketed path. Mirrors\n * the Rust SDK's `extract_channel_refs`.\n *\n * @param data - Arbitrary JSON-like value.\n * @returns Array of `[path, ref]` tuples. Empty when no refs are found.\n */\nexport const extractChannelRefs = (data: unknown): Array<[string, StreamChannelRef]> => {\n const refs: Array<[string, StreamChannelRef]> = []\n extractRefsRecursive(data, '', refs)\n return refs\n}\n\nconst extractRefsRecursive = (\n data: unknown,\n prefix: string,\n refs: Array<[string, StreamChannelRef]>,\n): void => {\n if (isChannelRef(data)) {\n refs.push([prefix, data])\n return\n }\n if (Array.isArray(data)) {\n for (let i = 0; i < data.length; i++) {\n const path = prefix === '' ? `[${i}]` : `${prefix}[${i}]`\n extractRefsRecursive(data[i], path, refs)\n }\n return\n }\n if (typeof data !== 'object' || data === null) return\n\n for (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n const path = prefix === '' ? key : `${prefix}.${key}`\n extractRefsRecursive(value, path, refs)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,SAAgB,kBAAkB,MAAc,QAAQ,KAAK,EAAsB;AACjF,KAAI;EACF,MAAM,WAAWA,UAAK,KAAK,KAAK,eAAe;AAC/C,MAAIC,QAAG,WAAW,SAAS,EAAE;GAC3B,MAAM,SAAS,KAAK,MAAMA,QAAG,aAAa,UAAU,OAAO,CAAC;AAC5D,OAAI,OAAO,OAAO,SAAS,UAAU;IACnC,MAAM,UAAU,OAAO,KAAK,MAAM;AAClC,QAAI,QAAS,QAAO;;;SAGlB;AAKR,QADaD,UAAK,SAAS,IAAI,CAAC,MAAM,IACvB;;;;;;;;AASjB,MAAa,gBAAgB,UAA8C;AACzE,KAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;CACxD,MAAM,QAAQ;AACd,QACE,OAAO,MAAM,eAAe,YAC5B,OAAO,MAAM,eAAe,aAC3B,MAAM,cAAc,UAAU,MAAM,cAAc;;;;;;;;;;AAYvD,MAAa,sBAAsB,SAAqD;CACtF,MAAM,OAA0C,EAAE;AAClD,sBAAqB,MAAM,IAAI,KAAK;AACpC,QAAO;;AAGT,MAAM,wBACJ,MACA,QACA,SACS;AACT,KAAI,aAAa,KAAK,EAAE;AACtB,OAAK,KAAK,CAAC,QAAQ,KAAK,CAAC;AACzB;;AAEF,KAAI,MAAM,QAAQ,KAAK,EAAE;AACvB,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;GACpC,MAAM,OAAO,WAAW,KAAK,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,EAAE;AACvD,wBAAqB,KAAK,IAAI,MAAM,KAAK;;AAE3C;;AAEF,KAAI,OAAO,SAAS,YAAY,SAAS,KAAM;AAE/C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAgC,CAExE,sBAAqB,OADR,WAAW,KAAK,MAAM,GAAG,OAAO,GAAG,OACd,KAAK"}
@@ -0,0 +1,69 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+
4
+ //#region src/utils.ts
5
+ /**
6
+ * Returns a project identifier for telemetry, derived from the current working
7
+ * directory. Reads `package.json` `name` if present at `cwd`; otherwise falls
8
+ * back to the basename of `cwd`. Returns `undefined` only when both signals
9
+ * are unavailable (e.g. cwd is the filesystem root).
10
+ *
11
+ * No directory walking — only inspects `cwd` itself, so the SDK never reads
12
+ * files outside the user's explicit working directory.
13
+ */
14
+ function detectProjectName(cwd = process.cwd()) {
15
+ try {
16
+ const manifest = path.join(cwd, "package.json");
17
+ if (fs.existsSync(manifest)) {
18
+ const parsed = JSON.parse(fs.readFileSync(manifest, "utf8"));
19
+ if (typeof parsed.name === "string") {
20
+ const trimmed = parsed.name.trim();
21
+ if (trimmed) return trimmed;
22
+ }
23
+ }
24
+ } catch {}
25
+ return path.basename(cwd).trim() || void 0;
26
+ }
27
+ /**
28
+ * Type guard that checks if a value is a {@link StreamChannelRef}.
29
+ *
30
+ * @param value - Value to check.
31
+ * @returns `true` if the value is a valid `StreamChannelRef`.
32
+ */
33
+ const isChannelRef = (value) => {
34
+ if (typeof value !== "object" || value === null) return false;
35
+ const maybe = value;
36
+ return typeof maybe.channel_id === "string" && typeof maybe.access_key === "string" && (maybe.direction === "read" || maybe.direction === "write");
37
+ };
38
+ /**
39
+ * Recursively extract all {@link StreamChannelRef} values from a JSON-like
40
+ * input, returning each match paired with its dotted/bracketed path. Mirrors
41
+ * the Rust SDK's `extract_channel_refs`.
42
+ *
43
+ * @param data - Arbitrary JSON-like value.
44
+ * @returns Array of `[path, ref]` tuples. Empty when no refs are found.
45
+ */
46
+ const extractChannelRefs = (data) => {
47
+ const refs = [];
48
+ extractRefsRecursive(data, "", refs);
49
+ return refs;
50
+ };
51
+ const extractRefsRecursive = (data, prefix, refs) => {
52
+ if (isChannelRef(data)) {
53
+ refs.push([prefix, data]);
54
+ return;
55
+ }
56
+ if (Array.isArray(data)) {
57
+ for (let i = 0; i < data.length; i++) {
58
+ const path = prefix === "" ? `[${i}]` : `${prefix}[${i}]`;
59
+ extractRefsRecursive(data[i], path, refs);
60
+ }
61
+ return;
62
+ }
63
+ if (typeof data !== "object" || data === null) return;
64
+ for (const [key, value] of Object.entries(data)) extractRefsRecursive(value, prefix === "" ? key : `${prefix}.${key}`, refs);
65
+ };
66
+
67
+ //#endregion
68
+ export { extractChannelRefs as n, isChannelRef as r, detectProjectName as t };
69
+ //# sourceMappingURL=utils-Cuv_ksKp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils-Cuv_ksKp.mjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport type { StreamChannelRef } from './iii-types'\n\n/**\n * Returns a project identifier for telemetry, derived from the current working\n * directory. Reads `package.json` `name` if present at `cwd`; otherwise falls\n * back to the basename of `cwd`. Returns `undefined` only when both signals\n * are unavailable (e.g. cwd is the filesystem root).\n *\n * No directory walking — only inspects `cwd` itself, so the SDK never reads\n * files outside the user's explicit working directory.\n */\nexport function detectProjectName(cwd: string = process.cwd()): string | undefined {\n try {\n const manifest = path.join(cwd, 'package.json')\n if (fs.existsSync(manifest)) {\n const parsed = JSON.parse(fs.readFileSync(manifest, 'utf8')) as { name?: unknown }\n if (typeof parsed.name === 'string') {\n const trimmed = parsed.name.trim()\n if (trimmed) return trimmed\n }\n }\n } catch {\n // fall through to directory-name fallback\n }\n\n const base = path.basename(cwd).trim()\n return base || undefined\n}\n\n/**\n * Type guard that checks if a value is a {@link StreamChannelRef}.\n *\n * @param value - Value to check.\n * @returns `true` if the value is a valid `StreamChannelRef`.\n */\nexport const isChannelRef = (value: unknown): value is StreamChannelRef => {\n if (typeof value !== 'object' || value === null) return false\n const maybe = value as Partial<StreamChannelRef>\n return (\n typeof maybe.channel_id === 'string' &&\n typeof maybe.access_key === 'string' &&\n (maybe.direction === 'read' || maybe.direction === 'write')\n )\n}\n\n/**\n * Recursively extract all {@link StreamChannelRef} values from a JSON-like\n * input, returning each match paired with its dotted/bracketed path. Mirrors\n * the Rust SDK's `extract_channel_refs`.\n *\n * @param data - Arbitrary JSON-like value.\n * @returns Array of `[path, ref]` tuples. Empty when no refs are found.\n */\nexport const extractChannelRefs = (data: unknown): Array<[string, StreamChannelRef]> => {\n const refs: Array<[string, StreamChannelRef]> = []\n extractRefsRecursive(data, '', refs)\n return refs\n}\n\nconst extractRefsRecursive = (\n data: unknown,\n prefix: string,\n refs: Array<[string, StreamChannelRef]>,\n): void => {\n if (isChannelRef(data)) {\n refs.push([prefix, data])\n return\n }\n if (Array.isArray(data)) {\n for (let i = 0; i < data.length; i++) {\n const path = prefix === '' ? `[${i}]` : `${prefix}[${i}]`\n extractRefsRecursive(data[i], path, refs)\n }\n return\n }\n if (typeof data !== 'object' || data === null) return\n\n for (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n const path = prefix === '' ? key : `${prefix}.${key}`\n extractRefsRecursive(value, path, refs)\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,SAAgB,kBAAkB,MAAc,QAAQ,KAAK,EAAsB;AACjF,KAAI;EACF,MAAM,WAAW,KAAK,KAAK,KAAK,eAAe;AAC/C,MAAI,GAAG,WAAW,SAAS,EAAE;GAC3B,MAAM,SAAS,KAAK,MAAM,GAAG,aAAa,UAAU,OAAO,CAAC;AAC5D,OAAI,OAAO,OAAO,SAAS,UAAU;IACnC,MAAM,UAAU,OAAO,KAAK,MAAM;AAClC,QAAI,QAAS,QAAO;;;SAGlB;AAKR,QADa,KAAK,SAAS,IAAI,CAAC,MAAM,IACvB;;;;;;;;AASjB,MAAa,gBAAgB,UAA8C;AACzE,KAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;CACxD,MAAM,QAAQ;AACd,QACE,OAAO,MAAM,eAAe,YAC5B,OAAO,MAAM,eAAe,aAC3B,MAAM,cAAc,UAAU,MAAM,cAAc;;;;;;;;;;AAYvD,MAAa,sBAAsB,SAAqD;CACtF,MAAM,OAA0C,EAAE;AAClD,sBAAqB,MAAM,IAAI,KAAK;AACpC,QAAO;;AAGT,MAAM,wBACJ,MACA,QACA,SACS;AACT,KAAI,aAAa,KAAK,EAAE;AACtB,OAAK,KAAK,CAAC,QAAQ,KAAK,CAAC;AACzB;;AAEF,KAAI,MAAM,QAAQ,KAAK,EAAE;AACvB,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;GACpC,MAAM,OAAO,WAAW,KAAK,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,EAAE;AACvD,wBAAqB,KAAK,IAAI,MAAM,KAAK;;AAE3C;;AAEF,KAAI,OAAO,SAAS,YAAY,SAAS,KAAM;AAE/C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAgC,CAExE,sBAAqB,OADR,WAAW,KAAK,MAAM,GAAG,OAAO,GAAG,OACd,KAAK"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iii-sdk",
3
- "version": "0.19.3",
3
+ "version": "0.19.4-alpha.2",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -34,12 +34,48 @@
34
34
  "types": "./dist/helpers.d.ts",
35
35
  "import": "./dist/helpers.mjs",
36
36
  "require": "./dist/helpers.cjs"
37
+ },
38
+ "./channel": {
39
+ "types": "./dist/channel.d.ts",
40
+ "import": "./dist/channel.mjs",
41
+ "require": "./dist/channel.cjs"
42
+ },
43
+ "./trigger": {
44
+ "types": "./dist/trigger.d.ts",
45
+ "import": "./dist/trigger.mjs",
46
+ "require": "./dist/trigger.cjs"
47
+ },
48
+ "./runtime": {
49
+ "types": "./dist/runtime.d.ts",
50
+ "import": "./dist/runtime.mjs",
51
+ "require": "./dist/runtime.cjs"
52
+ },
53
+ "./errors": {
54
+ "types": "./dist/errors.d.ts",
55
+ "import": "./dist/errors.mjs",
56
+ "require": "./dist/errors.cjs"
57
+ },
58
+ "./internal": {
59
+ "types": "./dist/internal.d.ts",
60
+ "import": "./dist/internal.mjs",
61
+ "require": "./dist/internal.cjs"
62
+ },
63
+ "./engine": {
64
+ "types": "./dist/engine.d.ts",
65
+ "import": "./dist/engine.mjs",
66
+ "require": "./dist/engine.cjs"
67
+ },
68
+ "./protocol": {
69
+ "types": "./dist/protocol.d.ts",
70
+ "import": "./dist/protocol.mjs",
71
+ "require": "./dist/protocol.cjs"
37
72
  }
38
73
  },
39
74
  "dependencies": {
40
75
  "@opentelemetry/api": "^1.9.0",
41
76
  "ws": "^8.18.3",
42
- "@iii-dev/observability": "0.19.3"
77
+ "@iii-dev/helpers": "0.19.4-alpha.2",
78
+ "@iii-dev/observability": "0.19.4-alpha.2"
43
79
  },
44
80
  "devDependencies": {
45
81
  "@opentelemetry/context-async-hooks": "^2.7.1",
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-BnRzIUCy.d.cts","names":[],"sources":["../src/iii-types.ts","../src/channels.ts","../src/triggers.ts","../src/types.ts","../src/utils.ts"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-CuS1Knym.cjs","names":["Writable","WebSocket","Readable","path","fs"],"sources":["../src/channels.ts","../src/utils.ts"],"sourcesContent":["import { Readable, Writable } from 'node:stream'\nimport { WebSocket } from 'ws'\nimport type { StreamChannelRef } from './iii-types'\n\n/**\n * Direction of a streaming channel endpoint. Mirrors the Rust SDK's\n * `ChannelDirection` enum and matches the literal values used by\n * {@link StreamChannelRef.direction}.\n */\nexport const ChannelDirection = {\n Read: 'read',\n Write: 'write',\n} as const\nexport type ChannelDirection = (typeof ChannelDirection)[keyof typeof ChannelDirection]\n\n/**\n * Discriminated runtime tag for an item observed on a streaming channel.\n * Mirrors the Rust SDK's `ChannelItem` enum (`Text` / `Binary`). Carrier for\n * factory + type-guard helpers so callers can construct and discriminate\n * channel items without depending on Rust-specific shape.\n */\nexport type ChannelItem =\n | { type: 'text'; value: string }\n | { type: 'binary'; value: Uint8Array }\n\nexport const ChannelItem = {\n /** Construct a text channel item. */\n Text(value: string): ChannelItem {\n return { type: 'text', value }\n },\n /** Construct a binary channel item. */\n Binary(value: Uint8Array): ChannelItem {\n return { type: 'binary', value }\n },\n} as const\n\n/**\n * Write end of a streaming channel. Provides both a Node.js `Writable` stream\n * and a `sendMessage` method for sending structured text messages.\n *\n * @example\n * ```typescript\n * import { createChannel } from 'iii-sdk/helpers'\n * const channel = await createChannel(iii)\n *\n * // Stream binary data\n * channel.writer.stream.write(Buffer.from('hello'))\n * channel.writer.stream.end()\n *\n * // Or send text messages\n * channel.writer.sendMessage(JSON.stringify({ type: 'event', data: 'test' }))\n * channel.writer.close()\n * ```\n */\nexport class ChannelWriter {\n private static readonly FRAME_SIZE = 64 * 1024\n private ws: WebSocket | null = null\n private wsReady = false\n private readonly pendingMessages: {\n data: Buffer | string\n callback: (err?: Error | null) => void\n }[] = []\n /** Node.js Writable stream for binary data. */\n public readonly stream: Writable\n private readonly url: string\n\n constructor(engineWsBase: string, ref: StreamChannelRef) {\n this.url = buildChannelUrl(engineWsBase, ref.channel_id, ref.access_key, 'write')\n\n this.stream = new Writable({\n write: (chunk: Buffer, _encoding, callback) => {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n this.sendChunked(buf, callback)\n },\n final: (callback) => {\n if (!this.ws) {\n callback()\n return\n }\n // Delay the close frame slightly to allow the TCP stack to flush\n // all buffered send() data. Without this, the close frame can arrive\n // at the engine before all data frames, causing data truncation.\n const doClose = () => {\n if (this.ws) {\n this.ws.close(1000, 'stream_complete')\n }\n callback()\n }\n if (this.wsReady) {\n setTimeout(doClose, 10)\n } else {\n this.ws.on('open', () => setTimeout(doClose, 10))\n }\n },\n destroy: (err, callback) => {\n if (this.ws) this.ws.terminate()\n callback(err)\n },\n })\n }\n\n private ensureConnected(): void {\n if (this.ws) return\n this.ws = new WebSocket(this.url)\n\n this.ws.on('open', () => {\n this.wsReady = true\n for (const { data, callback } of this.pendingMessages) {\n this.ws?.send(data, callback)\n }\n this.pendingMessages.length = 0\n })\n\n this.ws.on('error', (err) => {\n this.stream.destroy(err)\n })\n\n this.ws.on('close', () => {\n if (!this.stream.destroyed) {\n this.stream.destroy()\n }\n })\n }\n\n /** Send a text message through the channel. */\n sendMessage(msg: string): void {\n this.ensureConnected()\n this.sendRaw(msg, (err) => {\n if (err) this.stream.destroy(err)\n })\n }\n\n /** Close the channel writer. */\n close(): void {\n if (!this.ws) return\n const doClose = () => {\n if (this.ws) {\n this.ws.close(1000, 'channel_close')\n }\n }\n if (this.wsReady) {\n doClose()\n } else {\n this.ws.on('open', () => doClose())\n }\n }\n\n private sendChunked(data: Buffer, callback: (err?: Error | null) => void): void {\n let offset = 0\n const sendNext = (err?: Error | null): void => {\n if (err) {\n callback(err)\n return\n }\n\n if (offset >= data.length) {\n callback(null)\n return\n }\n\n const end = Math.min(offset + ChannelWriter.FRAME_SIZE, data.length)\n const part = data.subarray(offset, end)\n offset = end\n this.sendRaw(part, sendNext)\n }\n sendNext(null)\n }\n\n private sendRaw(data: Buffer | string, callback: (err?: Error | null) => void): void {\n this.ensureConnected()\n if (this.wsReady && this.ws) {\n this.ws.send(data, (err) => callback(err ?? null))\n } else {\n this.pendingMessages.push({ data, callback })\n }\n }\n}\n\n/**\n * Read end of a streaming channel. Provides both a Node.js `Readable` stream\n * for binary data and an `onMessage` callback for structured text messages.\n *\n * @example\n * ```typescript\n * import { createChannel } from 'iii-sdk/helpers'\n * const channel = await createChannel(iii)\n *\n * // Stream binary data\n * channel.reader.stream.on('data', (chunk) => console.log(chunk))\n *\n * // Or receive text messages\n * channel.reader.onMessage((msg) => console.log('Got:', msg))\n * ```\n */\nexport class ChannelReader {\n private ws: WebSocket | null = null\n private connected = false\n private readonly messageCallbacks: Array<(msg: string) => void> = []\n /** Node.js Readable stream for binary data. */\n public readonly stream: Readable\n private readonly url: string\n\n constructor(engineWsBase: string, ref: StreamChannelRef) {\n this.url = buildChannelUrl(engineWsBase, ref.channel_id, ref.access_key, 'read')\n\n const self = this\n this.stream = new Readable({\n read() {\n self.ensureConnected()\n if (self.ws) self.ws.resume()\n },\n destroy(err, callback) {\n if (self.ws && self.ws.readyState !== WebSocket.CLOSED) {\n self.ws.terminate()\n }\n self.ws = null\n callback(err)\n },\n })\n }\n\n private ensureConnected(): void {\n if (this.connected) return\n this.connected = true\n this.ws = new WebSocket(this.url)\n\n this.ws.on('open', () => {\n ;(this.ws as unknown as { binaryType: string }).binaryType = 'nodebuffer'\n })\n\n this.ws.on('message', (data: Buffer, isBinary: boolean) => {\n if (isBinary) {\n if (!this.stream.push(data)) {\n this.ws?.pause()\n }\n } else {\n const msg = data.toString('utf-8')\n for (const cb of this.messageCallbacks) {\n cb(msg)\n }\n }\n })\n\n this.ws.on('close', () => {\n this.ws = null\n if (!this.stream.destroyed) this.stream.push(null)\n })\n\n this.ws.on('error', (err) => {\n this.stream.destroy(err)\n })\n }\n\n /** Register a callback to receive text messages from the channel. */\n onMessage(callback: (msg: string) => void): void {\n this.messageCallbacks.push(callback)\n }\n\n async readAll(): Promise<Buffer> {\n this.ensureConnected()\n const chunks: Buffer[] = []\n\n for await (const chunk of this.stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))\n }\n\n return Buffer.concat(chunks)\n }\n\n close(): void {\n if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {\n this.ws.close(1000, 'channel_close')\n }\n }\n}\n\nfunction buildChannelUrl(\n engineWsBase: string,\n channelId: string,\n accessKey: string,\n direction: 'read' | 'write',\n): string {\n const base = engineWsBase.replace(/\\/$/, '')\n return `${base}/ws/channels/${channelId}?key=${encodeURIComponent(accessKey)}&dir=${direction}`\n}\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport type { StreamChannelRef } from './iii-types'\nimport type { ApiResponse, HttpRequest, HttpResponse, InternalHttpRequest } from './types'\n\n/**\n * Returns a project identifier for telemetry, derived from the current working\n * directory. Reads `package.json` `name` if present at `cwd`; otherwise falls\n * back to the basename of `cwd`. Returns `undefined` only when both signals\n * are unavailable (e.g. cwd is the filesystem root).\n *\n * No directory walking — only inspects `cwd` itself, so the SDK never reads\n * files outside the user's explicit working directory.\n */\nexport function detectProjectName(cwd: string = process.cwd()): string | undefined {\n try {\n const manifest = path.join(cwd, 'package.json')\n if (fs.existsSync(manifest)) {\n const parsed = JSON.parse(fs.readFileSync(manifest, 'utf8')) as { name?: unknown }\n if (typeof parsed.name === 'string') {\n const trimmed = parsed.name.trim()\n if (trimmed) return trimmed\n }\n }\n } catch {\n // fall through to directory-name fallback\n }\n\n const base = path.basename(cwd).trim()\n return base || undefined\n}\n\n/**\n * Helper that wraps an HTTP-style handler (with separate `req`/`res` arguments)\n * into the function handler format expected by the SDK.\n *\n * @param callback - Async handler receiving an {@link HttpRequest} and {@link HttpResponse}.\n * @returns A function handler compatible with {@link ISdk.registerFunction}.\n *\n * @example\n * ```typescript\n * import { http } from 'iii-sdk'\n *\n * iii.registerFunction(\n * 'my-api',\n * http(async (req, res) => {\n * res.status(200)\n * res.headers({ 'content-type': 'application/json' })\n * res.stream.end(JSON.stringify({ hello: 'world' }))\n * res.close()\n * }),\n * )\n * ```\n */\nexport const http = (\n // biome-ignore lint/suspicious/noConfusingVoidType: void is necessary here\n callback: (req: HttpRequest, res: HttpResponse) => Promise<void | ApiResponse>,\n) => {\n return async (req: InternalHttpRequest) => {\n const { response, ...request } = req\n\n const httpResponse: HttpResponse = {\n status: (status_code: number) =>\n response.sendMessage(JSON.stringify({ type: 'set_status', status_code })),\n headers: (headers: Record<string, string>) =>\n response.sendMessage(JSON.stringify({ type: 'set_headers', headers })),\n stream: response.stream,\n close: () => response.close(),\n }\n\n return callback(request, httpResponse)\n }\n}\n\n/**\n * Type guard that checks if a value is a {@link StreamChannelRef}.\n *\n * @param value - Value to check.\n * @returns `true` if the value is a valid `StreamChannelRef`.\n */\nexport const isChannelRef = (value: unknown): value is StreamChannelRef => {\n if (typeof value !== 'object' || value === null) return false\n const maybe = value as Partial<StreamChannelRef>\n return (\n typeof maybe.channel_id === 'string' &&\n typeof maybe.access_key === 'string' &&\n (maybe.direction === 'read' || maybe.direction === 'write')\n )\n}\n\n/**\n * Recursively extract all {@link StreamChannelRef} values from a JSON-like\n * input, returning each match paired with its dotted/bracketed path. Mirrors\n * the Rust SDK's `extract_channel_refs`.\n *\n * @param data - Arbitrary JSON-like value.\n * @returns Array of `[path, ref]` tuples. Empty when no refs are found.\n */\nexport const extractChannelRefs = (data: unknown): Array<[string, StreamChannelRef]> => {\n const refs: Array<[string, StreamChannelRef]> = []\n extractRefsRecursive(data, '', refs)\n return refs\n}\n\nconst extractRefsRecursive = (\n data: unknown,\n prefix: string,\n refs: Array<[string, StreamChannelRef]>,\n): void => {\n if (isChannelRef(data)) {\n refs.push([prefix, data])\n return\n }\n if (Array.isArray(data)) {\n for (let i = 0; i < data.length; i++) {\n const path = prefix === '' ? `[${i}]` : `${prefix}[${i}]`\n extractRefsRecursive(data[i], path, refs)\n }\n return\n }\n if (typeof data !== 'object' || data === null) return\n\n for (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n const path = prefix === '' ? key : `${prefix}.${key}`\n extractRefsRecursive(value, path, refs)\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-DXL7JI0q.mjs","names":[],"sources":["../src/channels.ts","../src/utils.ts"],"sourcesContent":["import { Readable, Writable } from 'node:stream'\nimport { WebSocket } from 'ws'\nimport type { StreamChannelRef } from './iii-types'\n\n/**\n * Direction of a streaming channel endpoint. Mirrors the Rust SDK's\n * `ChannelDirection` enum and matches the literal values used by\n * {@link StreamChannelRef.direction}.\n */\nexport const ChannelDirection = {\n Read: 'read',\n Write: 'write',\n} as const\nexport type ChannelDirection = (typeof ChannelDirection)[keyof typeof ChannelDirection]\n\n/**\n * Discriminated runtime tag for an item observed on a streaming channel.\n * Mirrors the Rust SDK's `ChannelItem` enum (`Text` / `Binary`). Carrier for\n * factory + type-guard helpers so callers can construct and discriminate\n * channel items without depending on Rust-specific shape.\n */\nexport type ChannelItem =\n | { type: 'text'; value: string }\n | { type: 'binary'; value: Uint8Array }\n\nexport const ChannelItem = {\n /** Construct a text channel item. */\n Text(value: string): ChannelItem {\n return { type: 'text', value }\n },\n /** Construct a binary channel item. */\n Binary(value: Uint8Array): ChannelItem {\n return { type: 'binary', value }\n },\n} as const\n\n/**\n * Write end of a streaming channel. Provides both a Node.js `Writable` stream\n * and a `sendMessage` method for sending structured text messages.\n *\n * @example\n * ```typescript\n * import { createChannel } from 'iii-sdk/helpers'\n * const channel = await createChannel(iii)\n *\n * // Stream binary data\n * channel.writer.stream.write(Buffer.from('hello'))\n * channel.writer.stream.end()\n *\n * // Or send text messages\n * channel.writer.sendMessage(JSON.stringify({ type: 'event', data: 'test' }))\n * channel.writer.close()\n * ```\n */\nexport class ChannelWriter {\n private static readonly FRAME_SIZE = 64 * 1024\n private ws: WebSocket | null = null\n private wsReady = false\n private readonly pendingMessages: {\n data: Buffer | string\n callback: (err?: Error | null) => void\n }[] = []\n /** Node.js Writable stream for binary data. */\n public readonly stream: Writable\n private readonly url: string\n\n constructor(engineWsBase: string, ref: StreamChannelRef) {\n this.url = buildChannelUrl(engineWsBase, ref.channel_id, ref.access_key, 'write')\n\n this.stream = new Writable({\n write: (chunk: Buffer, _encoding, callback) => {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n this.sendChunked(buf, callback)\n },\n final: (callback) => {\n if (!this.ws) {\n callback()\n return\n }\n // Delay the close frame slightly to allow the TCP stack to flush\n // all buffered send() data. Without this, the close frame can arrive\n // at the engine before all data frames, causing data truncation.\n const doClose = () => {\n if (this.ws) {\n this.ws.close(1000, 'stream_complete')\n }\n callback()\n }\n if (this.wsReady) {\n setTimeout(doClose, 10)\n } else {\n this.ws.on('open', () => setTimeout(doClose, 10))\n }\n },\n destroy: (err, callback) => {\n if (this.ws) this.ws.terminate()\n callback(err)\n },\n })\n }\n\n private ensureConnected(): void {\n if (this.ws) return\n this.ws = new WebSocket(this.url)\n\n this.ws.on('open', () => {\n this.wsReady = true\n for (const { data, callback } of this.pendingMessages) {\n this.ws?.send(data, callback)\n }\n this.pendingMessages.length = 0\n })\n\n this.ws.on('error', (err) => {\n this.stream.destroy(err)\n })\n\n this.ws.on('close', () => {\n if (!this.stream.destroyed) {\n this.stream.destroy()\n }\n })\n }\n\n /** Send a text message through the channel. */\n sendMessage(msg: string): void {\n this.ensureConnected()\n this.sendRaw(msg, (err) => {\n if (err) this.stream.destroy(err)\n })\n }\n\n /** Close the channel writer. */\n close(): void {\n if (!this.ws) return\n const doClose = () => {\n if (this.ws) {\n this.ws.close(1000, 'channel_close')\n }\n }\n if (this.wsReady) {\n doClose()\n } else {\n this.ws.on('open', () => doClose())\n }\n }\n\n private sendChunked(data: Buffer, callback: (err?: Error | null) => void): void {\n let offset = 0\n const sendNext = (err?: Error | null): void => {\n if (err) {\n callback(err)\n return\n }\n\n if (offset >= data.length) {\n callback(null)\n return\n }\n\n const end = Math.min(offset + ChannelWriter.FRAME_SIZE, data.length)\n const part = data.subarray(offset, end)\n offset = end\n this.sendRaw(part, sendNext)\n }\n sendNext(null)\n }\n\n private sendRaw(data: Buffer | string, callback: (err?: Error | null) => void): void {\n this.ensureConnected()\n if (this.wsReady && this.ws) {\n this.ws.send(data, (err) => callback(err ?? null))\n } else {\n this.pendingMessages.push({ data, callback })\n }\n }\n}\n\n/**\n * Read end of a streaming channel. Provides both a Node.js `Readable` stream\n * for binary data and an `onMessage` callback for structured text messages.\n *\n * @example\n * ```typescript\n * import { createChannel } from 'iii-sdk/helpers'\n * const channel = await createChannel(iii)\n *\n * // Stream binary data\n * channel.reader.stream.on('data', (chunk) => console.log(chunk))\n *\n * // Or receive text messages\n * channel.reader.onMessage((msg) => console.log('Got:', msg))\n * ```\n */\nexport class ChannelReader {\n private ws: WebSocket | null = null\n private connected = false\n private readonly messageCallbacks: Array<(msg: string) => void> = []\n /** Node.js Readable stream for binary data. */\n public readonly stream: Readable\n private readonly url: string\n\n constructor(engineWsBase: string, ref: StreamChannelRef) {\n this.url = buildChannelUrl(engineWsBase, ref.channel_id, ref.access_key, 'read')\n\n const self = this\n this.stream = new Readable({\n read() {\n self.ensureConnected()\n if (self.ws) self.ws.resume()\n },\n destroy(err, callback) {\n if (self.ws && self.ws.readyState !== WebSocket.CLOSED) {\n self.ws.terminate()\n }\n self.ws = null\n callback(err)\n },\n })\n }\n\n private ensureConnected(): void {\n if (this.connected) return\n this.connected = true\n this.ws = new WebSocket(this.url)\n\n this.ws.on('open', () => {\n ;(this.ws as unknown as { binaryType: string }).binaryType = 'nodebuffer'\n })\n\n this.ws.on('message', (data: Buffer, isBinary: boolean) => {\n if (isBinary) {\n if (!this.stream.push(data)) {\n this.ws?.pause()\n }\n } else {\n const msg = data.toString('utf-8')\n for (const cb of this.messageCallbacks) {\n cb(msg)\n }\n }\n })\n\n this.ws.on('close', () => {\n this.ws = null\n if (!this.stream.destroyed) this.stream.push(null)\n })\n\n this.ws.on('error', (err) => {\n this.stream.destroy(err)\n })\n }\n\n /** Register a callback to receive text messages from the channel. */\n onMessage(callback: (msg: string) => void): void {\n this.messageCallbacks.push(callback)\n }\n\n async readAll(): Promise<Buffer> {\n this.ensureConnected()\n const chunks: Buffer[] = []\n\n for await (const chunk of this.stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))\n }\n\n return Buffer.concat(chunks)\n }\n\n close(): void {\n if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {\n this.ws.close(1000, 'channel_close')\n }\n }\n}\n\nfunction buildChannelUrl(\n engineWsBase: string,\n channelId: string,\n accessKey: string,\n direction: 'read' | 'write',\n): string {\n const base = engineWsBase.replace(/\\/$/, '')\n return `${base}/ws/channels/${channelId}?key=${encodeURIComponent(accessKey)}&dir=${direction}`\n}\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport type { StreamChannelRef } from './iii-types'\nimport type { ApiResponse, HttpRequest, HttpResponse, InternalHttpRequest } from './types'\n\n/**\n * Returns a project identifier for telemetry, derived from the current working\n * directory. Reads `package.json` `name` if present at `cwd`; otherwise falls\n * back to the basename of `cwd`. Returns `undefined` only when both signals\n * are unavailable (e.g. cwd is the filesystem root).\n *\n * No directory walking — only inspects `cwd` itself, so the SDK never reads\n * files outside the user's explicit working directory.\n */\nexport function detectProjectName(cwd: string = process.cwd()): string | undefined {\n try {\n const manifest = path.join(cwd, 'package.json')\n if (fs.existsSync(manifest)) {\n const parsed = JSON.parse(fs.readFileSync(manifest, 'utf8')) as { name?: unknown }\n if (typeof parsed.name === 'string') {\n const trimmed = parsed.name.trim()\n if (trimmed) return trimmed\n }\n }\n } catch {\n // fall through to directory-name fallback\n }\n\n const base = path.basename(cwd).trim()\n return base || undefined\n}\n\n/**\n * Helper that wraps an HTTP-style handler (with separate `req`/`res` arguments)\n * into the function handler format expected by the SDK.\n *\n * @param callback - Async handler receiving an {@link HttpRequest} and {@link HttpResponse}.\n * @returns A function handler compatible with {@link ISdk.registerFunction}.\n *\n * @example\n * ```typescript\n * import { http } from 'iii-sdk'\n *\n * iii.registerFunction(\n * 'my-api',\n * http(async (req, res) => {\n * res.status(200)\n * res.headers({ 'content-type': 'application/json' })\n * res.stream.end(JSON.stringify({ hello: 'world' }))\n * res.close()\n * }),\n * )\n * ```\n */\nexport const http = (\n // biome-ignore lint/suspicious/noConfusingVoidType: void is necessary here\n callback: (req: HttpRequest, res: HttpResponse) => Promise<void | ApiResponse>,\n) => {\n return async (req: InternalHttpRequest) => {\n const { response, ...request } = req\n\n const httpResponse: HttpResponse = {\n status: (status_code: number) =>\n response.sendMessage(JSON.stringify({ type: 'set_status', status_code })),\n headers: (headers: Record<string, string>) =>\n response.sendMessage(JSON.stringify({ type: 'set_headers', headers })),\n stream: response.stream,\n close: () => response.close(),\n }\n\n return callback(request, httpResponse)\n }\n}\n\n/**\n * Type guard that checks if a value is a {@link StreamChannelRef}.\n *\n * @param value - Value to check.\n * @returns `true` if the value is a valid `StreamChannelRef`.\n */\nexport const isChannelRef = (value: unknown): value is StreamChannelRef => {\n if (typeof value !== 'object' || value === null) return false\n const maybe = value as Partial<StreamChannelRef>\n return (\n typeof maybe.channel_id === 'string' &&\n typeof maybe.access_key === 'string' &&\n (maybe.direction === 'read' || maybe.direction === 'write')\n )\n}\n\n/**\n * Recursively extract all {@link StreamChannelRef} values from a JSON-like\n * input, returning each match paired with its dotted/bracketed path. Mirrors\n * the Rust SDK's `extract_channel_refs`.\n *\n * @param data - Arbitrary JSON-like value.\n * @returns Array of `[path, ref]` tuples. Empty when no refs are found.\n */\nexport const extractChannelRefs = (data: unknown): Array<[string, StreamChannelRef]> => {\n const refs: Array<[string, StreamChannelRef]> = []\n extractRefsRecursive(data, '', refs)\n return refs\n}\n\nconst extractRefsRecursive = (\n data: unknown,\n prefix: string,\n refs: Array<[string, StreamChannelRef]>,\n): void => {\n if (isChannelRef(data)) {\n refs.push([prefix, data])\n return\n }\n if (Array.isArray(data)) {\n for (let i = 0; i < data.length; i++) {\n const path = prefix === '' ? `[${i}]` : `${prefix}[${i}]`\n extractRefsRecursive(data[i], path, refs)\n }\n return\n }\n if (typeof data !== 'object' || data === null) return\n\n for (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n const path = prefix === '' ? key : `${prefix}.${key}`\n extractRefsRecursive(value, path, refs)\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-e84Qph-9.d.mts","names":[],"sources":["../src/iii-types.ts","../src/channels.ts","../src/triggers.ts","../src/types.ts","../src/utils.ts"],"mappings":"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"}