@requence/service 1.0.0-alpha.5 → 1.0.0-alpha.50

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 (99) hide show
  1. package/CHANGELOG.md +270 -0
  2. package/build/{chunk-0x9092n4.js → chunk-6w7td62p.js} +5 -44
  3. package/build/chunk-6w7td62p.js.map +10 -0
  4. package/build/cli.js +123 -25
  5. package/build/cli.js.map +3 -3
  6. package/build/index.js +979 -840
  7. package/build/index.js.map +18 -16
  8. package/build/types/helpers/src/files/RequenceFile.d.ts +40 -0
  9. package/build/types/helpers/src/files/RequenceFile.d.ts.map +1 -0
  10. package/build/types/helpers/src/files/RequenceStream.d.ts +32 -0
  11. package/build/types/helpers/src/files/RequenceStream.d.ts.map +1 -0
  12. package/build/types/helpers/src/files/fileObject.d.ts +16 -0
  13. package/build/types/helpers/src/files/fileObject.d.ts.map +1 -0
  14. package/build/types/helpers/src/files/index.d.ts +7 -0
  15. package/build/types/helpers/src/files/index.d.ts.map +1 -0
  16. package/build/types/helpers/src/files/isValidMimeType.d.ts +5 -0
  17. package/build/types/helpers/src/files/isValidMimeType.d.ts.map +1 -0
  18. package/build/types/helpers/src/files/mapOutput.d.ts +10 -0
  19. package/build/types/helpers/src/files/mapOutput.d.ts.map +1 -0
  20. package/build/types/helpers/src/files/streamObject.d.ts +14 -0
  21. package/build/types/helpers/src/files/streamObject.d.ts.map +1 -0
  22. package/build/types/helpers/src/files/types.d.ts +4 -0
  23. package/build/types/helpers/src/files/types.d.ts.map +1 -0
  24. package/build/types/helpers/src/index.d.ts +12 -6
  25. package/build/types/helpers/src/index.d.ts.map +1 -1
  26. package/build/types/helpers/src/jsonschema/mapSchema.d.ts +20 -0
  27. package/build/types/helpers/src/jsonschema/mapSchema.d.ts.map +1 -0
  28. package/build/types/helpers/src/jsonschema/types.d.ts +13 -0
  29. package/build/types/helpers/src/jsonschema/types.d.ts.map +1 -0
  30. package/build/types/helpers/src/jsonschema/validate.d.ts +32 -0
  31. package/build/types/helpers/src/jsonschema/validate.d.ts.map +1 -0
  32. package/build/types/helpers/src/jsonschema/zod.d.ts +17 -0
  33. package/build/types/helpers/src/jsonschema/zod.d.ts.map +1 -0
  34. package/build/types/helpers/src/protocol/NodeTree.d.ts +496 -0
  35. package/build/types/helpers/src/protocol/NodeTree.d.ts.map +1 -0
  36. package/build/types/helpers/src/protocol/command.d.ts +481 -0
  37. package/build/types/helpers/src/protocol/command.d.ts.map +1 -0
  38. package/build/types/helpers/src/protocol/helpers.d.ts +7 -0
  39. package/build/types/helpers/src/protocol/helpers.d.ts.map +1 -0
  40. package/build/types/helpers/src/protocol/index.d.ts +8 -0
  41. package/build/types/helpers/src/protocol/index.d.ts.map +1 -0
  42. package/build/types/helpers/src/protocol/nodeType.d.ts +171 -0
  43. package/build/types/helpers/src/protocol/nodeType.d.ts.map +1 -0
  44. package/build/types/helpers/src/protocol/taskOptions.d.ts +20 -0
  45. package/build/types/helpers/src/protocol/taskOptions.d.ts.map +1 -0
  46. package/build/types/helpers/src/protocol/templateNodeTypes.d.ts +267 -0
  47. package/build/types/helpers/src/protocol/templateNodeTypes.d.ts.map +1 -0
  48. package/build/types/helpers/src/protocol/treeNodes.d.ts +836 -0
  49. package/build/types/helpers/src/protocol/treeNodes.d.ts.map +1 -0
  50. package/build/types/helpers/src/protocol/update.d.ts +381 -0
  51. package/build/types/helpers/src/protocol/update.d.ts.map +1 -0
  52. package/build/types/helpers/src/utils/callbackToAsyncIterator.d.ts +3 -0
  53. package/build/types/helpers/src/utils/callbackToAsyncIterator.d.ts.map +1 -0
  54. package/build/types/helpers/src/utils/clone.d.ts +3 -0
  55. package/build/types/helpers/src/utils/clone.d.ts.map +1 -0
  56. package/build/types/helpers/src/utils/createObjectProxy.d.ts +2 -0
  57. package/build/types/helpers/src/utils/createObjectProxy.d.ts.map +1 -0
  58. package/build/types/helpers/src/utils/debounce.d.ts +4 -0
  59. package/build/types/helpers/src/utils/debounce.d.ts.map +1 -0
  60. package/build/types/helpers/src/utils/guards.d.ts +3 -0
  61. package/build/types/helpers/src/utils/guards.d.ts.map +1 -0
  62. package/build/types/helpers/src/utils/mapData.d.ts +18 -0
  63. package/build/types/helpers/src/utils/mapData.d.ts.map +1 -0
  64. package/build/types/helpers/src/{utils.d.ts → utils/matchSchema.d.ts} +2 -2
  65. package/build/types/helpers/src/utils/matchSchema.d.ts.map +1 -0
  66. package/build/types/helpers/src/utils/obfuscate.d.ts.map +1 -0
  67. package/build/types/helpers/src/utils/obj.d.ts +4 -0
  68. package/build/types/helpers/src/utils/obj.d.ts.map +1 -0
  69. package/build/types/helpers/src/utils/requenceCallback.d.ts +17 -0
  70. package/build/types/helpers/src/utils/requenceCallback.d.ts.map +1 -0
  71. package/build/types/helpers/src/utils/resolveRequenceTypes.d.ts +8 -0
  72. package/build/types/helpers/src/utils/resolveRequenceTypes.d.ts.map +1 -0
  73. package/build/types/helpers/src/utils/types.d.ts +7 -0
  74. package/build/types/helpers/src/utils/types.d.ts.map +1 -0
  75. package/build/types/service/src/createAmqpConnection.d.ts +29 -27
  76. package/build/types/service/src/createAmqpConnection.d.ts.map +1 -1
  77. package/build/types/service/src/errors.d.ts +3 -0
  78. package/build/types/service/src/errors.d.ts.map +1 -0
  79. package/build/types/service/src/helpers.d.ts +72 -90
  80. package/build/types/service/src/helpers.d.ts.map +1 -1
  81. package/build/types/service/src/index.d.ts +11 -4
  82. package/build/types/service/src/index.d.ts.map +1 -1
  83. package/build/types/service/src/macro.d.ts +2 -0
  84. package/build/types/service/src/macro.d.ts.map +1 -0
  85. package/build/types/service/src/mapInput.d.ts +2 -0
  86. package/build/types/service/src/mapInput.d.ts.map +1 -0
  87. package/build/types/service/src/utils.d.ts +6 -0
  88. package/build/types/service/src/utils.d.ts.map +1 -0
  89. package/package.json +10 -7
  90. package/build/chunk-0x9092n4.js.map +0 -12
  91. package/build/types/helpers/src/clone.d.ts +0 -3
  92. package/build/types/helpers/src/clone.d.ts.map +0 -1
  93. package/build/types/helpers/src/createObjectProxy.d.ts +0 -2
  94. package/build/types/helpers/src/createObjectProxy.d.ts.map +0 -1
  95. package/build/types/helpers/src/createRemotePromise.d.ts +0 -7
  96. package/build/types/helpers/src/createRemotePromise.d.ts.map +0 -1
  97. package/build/types/helpers/src/obfuscate.d.ts.map +0 -1
  98. package/build/types/helpers/src/utils.d.ts.map +0 -1
  99. /package/build/types/helpers/src/{obfuscate.d.ts → utils/obfuscate.d.ts} +0 -0
package/build/index.js CHANGED
@@ -1,611 +1,418 @@
1
1
  import {
2
- clone,
3
- createObjectProxy,
4
2
  deobfuscate,
5
3
  obfuscate
6
- } from "./chunk-0x9092n4.js";
4
+ } from "./chunk-6w7td62p.js";
7
5
 
8
6
  // src/index.ts
9
- import { readFileSync } from "node:fs";
10
- import { z as z8 } from "zod";
7
+ import fs from "node:fs";
11
8
 
12
- // ../helpers/src/context/context.ts
13
- import { z } from "zod";
14
- var contextSchema = z.object({
15
- input: z.any(),
16
- meta: z.any(),
17
- tenant: z.object({ name: z.string() }),
18
- data: z.record(z.string(), z.any()),
19
- errors: z.record(z.string(), z.string()),
20
- dates: z.record(z.string(), z.string().datetime())
21
- });
22
- var internalKey = Symbol.for("internal");
23
- // ../helpers/src/protocol/command.ts
24
- import { z as z5 } from "zod";
25
-
26
- // ../helpers/src/protocol/nodes.ts
27
- import { ZodError, z as z4 } from "zod";
9
+ // ../helpers/src/utils/guards.ts
10
+ import { z } from "zod/v4";
11
+ var recordSchema = z.record(z.string(), z.unknown());
12
+ function isRecord(data) {
13
+ return recordSchema.safeParse(data).success;
14
+ }
15
+ var uuidSchema = z.uuid();
28
16
 
29
- // ../helpers/src/protocol/getNodeOutputs.ts
30
- function getNodeOutputs(node, outputName) {
31
- const outputs = !outputName ? node.output : outputName === "__default__" ? node.output.filter((o) => o.default) : node.output.filter((o) => ("name" in o) && o.name === outputName);
32
- const outputTargets = new Set;
33
- for (const output of outputs) {
34
- if (output.exit) {
35
- outputTargets.add("__exit__");
36
- } else {
37
- outputTargets.add(output.target);
38
- }
17
+ // ../helpers/src/utils/mapData.ts
18
+ function resolve(value, onResolve) {
19
+ if (value instanceof Promise) {
20
+ return Promise.resolve().then(() => value).then(onResolve);
39
21
  }
40
- return Array.from(outputTargets);
22
+ return onResolve(value);
23
+ }
24
+ function notUndefined(value, fallback) {
25
+ return resolve(value, (resolvedValue) => typeof resolvedValue === "undefined" ? fallback : resolvedValue);
41
26
  }
42
27
 
43
- // ../helpers/src/protocol/createNodeMaps.ts
44
- function createNodeMaps(nodes) {
45
- const nodesByIdMap = new Map;
46
- const nodesByNameOrAlias = new Map;
47
- const inputsNodeMap = new Map([
48
- ["__exit__", []]
49
- ]);
50
- for (const node of nodes) {
51
- nodesByIdMap.set(node.id, node);
52
- if ("alias" in node && node.alias) {
53
- nodesByNameOrAlias.set(node.alias, node);
54
- }
55
- if ("name" in node && node.name) {
56
- nodesByNameOrAlias.set(node.name, node);
28
+ class AbortMapData extends Error {
29
+ }
30
+ function mapData(data, visitors) {
31
+ let aborted = false;
32
+ const traverseData = (data2, path) => {
33
+ if (aborted) {
34
+ return data2;
57
35
  }
58
- }
59
- for (const node of nodes) {
60
- for (const outputNodeId of getNodeOutputs(node)) {
61
- if (!inputsNodeMap.has(outputNodeId)) {
62
- inputsNodeMap.set(outputNodeId, []);
36
+ try {
37
+ if (Array.isArray(data2)) {
38
+ return resolve(visitors.Array?.(data2, path), (resolvedData) => {
39
+ if (resolvedData) {
40
+ return resolvedData;
41
+ }
42
+ const items = data2.map((item, index) => traverseData(item, [...path, index]));
43
+ if (items.some((item) => item instanceof Promise)) {
44
+ return Promise.all(items);
45
+ }
46
+ return items;
47
+ });
63
48
  }
64
- inputsNodeMap.get(outputNodeId).push(node);
65
- }
66
- }
67
- return {
68
- getInputs(node) {
69
- if (typeof node === "string") {
70
- return inputsNodeMap.get(node) ?? [];
49
+ if (data2 === null) {
50
+ return notUndefined(visitors.Null?.(data2, path), data2);
71
51
  }
72
- if (node.type === "catch" || node.type === "entry") {
73
- return [];
52
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(data2)) {
53
+ return notUndefined(visitors.Buffer?.(data2, path), data2);
74
54
  }
75
- return inputsNodeMap.get(node.id) ?? [];
76
- },
77
- getNode(nodeId) {
78
- return nodesByIdMap.get(nodeId);
79
- },
80
- lookupNode(nameOrAlias) {
81
- return nodesByNameOrAlias.get(nameOrAlias);
55
+ if (typeof data2 === "string") {
56
+ return notUndefined(visitors.String?.(data2, path), data2);
57
+ }
58
+ if (typeof data2 === "number") {
59
+ return notUndefined(visitors.Number?.(data2, path), data2);
60
+ }
61
+ if (typeof data2 === "symbol") {
62
+ return notUndefined(visitors.Symbol?.(data2, path), data2);
63
+ }
64
+ if (typeof data2 === "function") {
65
+ return notUndefined(visitors.Function?.(data2, path), data2);
66
+ }
67
+ if (isRecord(data2)) {
68
+ return resolve(visitors.Object?.(structuredClone(data2), path), (resolvedData) => {
69
+ const nextData = resolvedData ?? data2;
70
+ if (!isRecord(nextData)) {
71
+ return nextData;
72
+ }
73
+ const entries = Object.entries(nextData).map(([key, value]) => [
74
+ key,
75
+ traverseData(value, [...path, key])
76
+ ]);
77
+ if (entries.some(([, value]) => value instanceof Promise)) {
78
+ return Promise.all(entries.map(([key, value]) => Promise.resolve().then(() => value).then((resolvedValue) => [key, resolvedValue]))).then((entries2) => Object.fromEntries(entries2));
79
+ }
80
+ return Object.fromEntries(entries);
81
+ });
82
+ }
83
+ if (typeof data2 === "object" && data2) {
84
+ return notUndefined(visitors.Object?.(data2, path), data2);
85
+ }
86
+ return data2;
87
+ } catch (error) {
88
+ if (error instanceof AbortMapData) {
89
+ aborted = true;
90
+ return data2;
91
+ }
92
+ throw error;
82
93
  }
83
94
  };
95
+ return traverseData(data, []);
84
96
  }
97
+ mapData.abort = () => {
98
+ throw new AbortMapData;
99
+ };
85
100
 
86
- // ../helpers/src/protocol/getPossiblePaths.ts
87
- function getPossiblePaths({
88
- getInputs,
89
- getNode,
90
- onMissingInputs
91
- }) {
92
- const sets = new Set;
93
- const followPath = (nodeId, set2) => {
94
- if (nodeId === "__entry__") {
95
- return;
96
- }
97
- const node = nodeId !== "__exit__" ? getNode(nodeId) : null;
98
- const isOrNode = node?.type === "or";
99
- const inputNodes = getInputs(nodeId);
100
- if (node && node.type !== "catch" && inputNodes.length === 0) {
101
- onMissingInputs?.(node, Array.from(set2).toReversed());
102
- }
103
- for (const inputNode of inputNodes) {
104
- let usedSet = set2;
105
- if (isOrNode) {
106
- usedSet = new Set(set2);
107
- sets.add(usedSet);
108
- }
109
- const inputNodeId = inputNode.id;
110
- if (inputNode.type !== "or") {
111
- if (usedSet.has(inputNodeId)) {
112
- return;
113
- }
114
- usedSet.add(inputNodeId);
115
- }
116
- followPath(inputNodeId, usedSet);
117
- }
118
- if (isOrNode) {
119
- sets.delete(set2);
101
+ // ../helpers/src/utils/requenceCallback.ts
102
+ import { z as z2 } from "zod/v4";
103
+ var callbackObjectSchema = z2.object({
104
+ sourceId: z2.string(),
105
+ outputName: z2.string().nullable(),
106
+ propertyPath: z2.array(z2.union([z2.string(), z2.int()])),
107
+ callbackId: z2.uuid(),
108
+ __REQUENCE_type: z2.literal("RequenceCallback")
109
+ });
110
+ function isCallbackObject(data) {
111
+ return callbackObjectSchema.safeParse(data).success;
112
+ }
113
+ function createCallback(callback) {
114
+ const { promise, resolve: resolve2 } = Promise.withResolvers();
115
+ const executor = (arg) => {
116
+ resolve2(arg);
117
+ callback?.(arg);
118
+ };
119
+ return Object.assign(executor, {
120
+ response() {
121
+ return promise;
120
122
  }
123
+ });
124
+ }
125
+
126
+ // ../helpers/src/files/fileObject.ts
127
+ import { z as z3 } from "zod/v4";
128
+ var fileObjectSchema = z3.object({
129
+ size: z3.int().positive(),
130
+ mime: z3.string(),
131
+ url: z3.url(),
132
+ __REQUENCE_type: z3.literal("RequenceFile")
133
+ });
134
+ function toFileObject(fileInfo) {
135
+ return {
136
+ ...fileInfo,
137
+ __REQUENCE_type: "RequenceFile"
121
138
  };
122
- const set = new Set(["__exit__"]);
123
- sets.add(set);
124
- followPath("__exit__", set);
125
- return Array.from(sets, (set2) => Array.from(set2).toReversed());
139
+ }
140
+ function isFileObject(data) {
141
+ return fileObjectSchema.safeParse(data).success;
126
142
  }
127
143
 
128
- // ../helpers/src/protocol/identifyNode.ts
129
- function identifyNode(nodeId, getNode) {
130
- if (nodeId === "__entry__") {
131
- return "ENTRY";
144
+ // ../helpers/src/files/RequenceFile.ts
145
+ class RequenceFile {
146
+ #data;
147
+ #file = null;
148
+ constructor(blobParts, options) {
149
+ this.#data = new Blob(blobParts, options);
132
150
  }
133
- if (nodeId === "__exit__") {
134
- return "EXIT";
151
+ static fromFileObject(file) {
152
+ const instance = new this([], { type: "x/x" });
153
+ instance.#file = file;
154
+ return instance;
135
155
  }
136
- if (typeof nodeId === "symbol") {
137
- return String(nodeId);
156
+ get fileObject() {
157
+ return this.#file;
138
158
  }
139
- const node = getNode(nodeId);
140
- if (!node) {
141
- return `Unknown[${nodeId}]`;
159
+ get size() {
160
+ return this.#file?.size ?? this.#data.size;
142
161
  }
143
- switch (node.type) {
144
- case "service": {
145
- return `Service[${node.alias || node.name}]`;
146
- }
147
- case "catch": {
148
- return `Catch[${identifyNode(node.subject, getNode)}]`;
162
+ get mimeType() {
163
+ return this.#file?.mime ?? this.#data.type;
164
+ }
165
+ get mainMimeType() {
166
+ return this.mimeType.split("/")[0];
167
+ }
168
+ get subMimeType() {
169
+ return this.mimeType.split("/")[1];
170
+ }
171
+ async text() {
172
+ if (this.#file) {
173
+ return fetch(this.#file.url).then((response) => response.text());
149
174
  }
150
- case "logic": {
151
- return `Logic[${node.alias || node.id}]`;
175
+ return this.#data.text();
176
+ }
177
+ async json() {
178
+ if (this.#file) {
179
+ return fetch(this.#file.url).then((response) => response.json());
152
180
  }
153
- case "entry": {
154
- return "ENTRY";
181
+ return JSON.parse(await this.text());
182
+ }
183
+ async blob() {
184
+ if (this.#file) {
185
+ return fetch(this.#file.url).then((response) => response.blob());
155
186
  }
156
- case "or": {
157
- return `OR[${node.alias || node.id}]`;
187
+ return this.#data;
188
+ }
189
+ async arrayBuffer() {
190
+ if (this.#file) {
191
+ return fetch(this.#file.url).then((response) => response.arrayBuffer());
158
192
  }
193
+ return this.#data.arrayBuffer();
194
+ }
195
+ toString() {
196
+ return `RequenceFile<${this.mimeType}>`;
197
+ }
198
+ toJSON() {
199
+ return `RequenceFile<${this.mimeType}>`;
159
200
  }
160
201
  }
161
202
 
162
- // ../helpers/src/protocol/node.ts
163
- import { z as z3 } from "zod";
164
-
165
- // ../helpers/src/protocol/jsonSchema.ts
166
- import { z as z2 } from "zod";
167
- var jsonSchema7Schema = z2.lazy(() => z2.object({
168
- $id: z2.string().optional(),
169
- $schema: z2.string().optional(),
170
- $ref: z2.string().optional(),
171
- title: z2.string().optional(),
172
- description: z2.string().optional(),
173
- type: z2.union([
174
- z2.literal("string"),
175
- z2.literal("number"),
176
- z2.literal("integer"),
177
- z2.literal("boolean"),
178
- z2.literal("object"),
179
- z2.literal("array"),
180
- z2.literal("null")
181
- ]).optional(),
182
- enum: z2.array(z2.union([z2.string(), z2.number(), z2.boolean(), z2.null()])).optional(),
183
- const: z2.union([z2.string(), z2.number(), z2.boolean(), z2.null()]).optional(),
184
- multipleOf: z2.number().positive().optional(),
185
- maximum: z2.number().optional(),
186
- exclusiveMaximum: z2.number().optional(),
187
- minimum: z2.number().optional(),
188
- exclusiveMinimum: z2.number().optional(),
189
- maxLength: z2.number().int().nonnegative().optional(),
190
- minLength: z2.number().int().nonnegative().optional(),
191
- pattern: z2.string().optional(),
192
- additionalItems: z2.boolean().optional(),
193
- items: z2.union([z2.lazy(() => jsonSchema7Schema), z2.array(jsonSchema7Schema)]).optional(),
194
- maxItems: z2.number().int().nonnegative().optional(),
195
- minItems: z2.number().int().nonnegative().optional(),
196
- uniqueItems: z2.boolean().optional(),
197
- contains: z2.lazy(() => jsonSchema7Schema).optional(),
198
- maxProperties: z2.number().int().nonnegative().optional(),
199
- minProperties: z2.number().int().nonnegative().optional(),
200
- required: z2.array(z2.string()).optional(),
201
- properties: z2.record(jsonSchema7Schema).optional(),
202
- patternProperties: z2.record(jsonSchema7Schema).optional(),
203
- additionalProperties: z2.union([z2.boolean(), z2.lazy(() => jsonSchema7Schema)]).optional(),
204
- dependencies: z2.record(z2.union([z2.array(z2.string()), jsonSchema7Schema])).optional(),
205
- propertyNames: z2.lazy(() => jsonSchema7Schema).optional(),
206
- if: z2.lazy(() => jsonSchema7Schema).optional(),
207
- then: z2.lazy(() => jsonSchema7Schema).optional(),
208
- else: z2.lazy(() => jsonSchema7Schema).optional(),
209
- allOf: z2.array(jsonSchema7Schema).optional(),
210
- anyOf: z2.array(jsonSchema7Schema).optional(),
211
- oneOf: z2.array(jsonSchema7Schema).optional(),
212
- not: z2.lazy(() => jsonSchema7Schema).optional(),
213
- definitions: z2.record(jsonSchema7Schema).optional(),
214
- format: z2.string().optional(),
215
- contentMediaType: z2.string().optional(),
216
- contentEncoding: z2.string().optional()
217
- }).transform((obj) => {
218
- if (obj.type === "object" && typeof obj.additionalProperties === "undefined") {
219
- return {
220
- ...obj,
221
- additionalProperties: false
222
- };
203
+ // ../helpers/src/files/RequenceStream.ts
204
+ class RequenceStream {
205
+ #data;
206
+ #stream = null;
207
+ #options;
208
+ constructor(stream, options) {
209
+ this.#data = stream;
210
+ this.#options = options;
223
211
  }
224
- return obj;
225
- }));
226
- var jsonSchema7ObjectSchema = z2.object({
227
- type: z2.literal("object"),
228
- properties: z2.record(jsonSchema7Schema),
229
- required: z2.array(z2.string()).optional(),
230
- description: z2.string().optional(),
231
- maxProperties: z2.number().int().nonnegative().optional(),
232
- minProperties: z2.number().int().nonnegative().optional(),
233
- additionalProperties: z2.boolean().default(false)
234
- });
235
- var jsonSchema7NullSchema = z2.object({
236
- type: z2.literal("null")
237
- });
238
-
239
- // ../helpers/src/protocol/node.ts
240
- var outputDefinitionSchema = z3.object({
241
- schema: jsonSchema7Schema.nullable().optional()
242
- }).and(z3.union([
243
- z3.object({
244
- default: z3.literal(false).default(false),
245
- name: z3.string().min(1)
246
- }),
247
- z3.object({
248
- default: z3.literal(true).default(true)
249
- })
250
- ])).and(z3.union([
251
- z3.object({
252
- exit: z3.literal(false).default(false),
253
- target: z3.string().min(1)
254
- }),
255
- z3.object({ exit: z3.literal(true) })
256
- ]));
257
- var defaultOutputSchema = z3.union([
258
- z3.string().min(1),
259
- z3.object({ default: z3.literal(true).default(true), exit: z3.literal(true) }),
260
- z3.object({
261
- default: z3.literal(true).default(true),
262
- exit: z3.literal(false).default(false),
263
- target: z3.string().min(1)
264
- })
265
- ]).transform((output) => {
266
- if (typeof output === "string") {
267
- return {
268
- default: true,
269
- exit: false,
270
- target: output
271
- };
212
+ static fromStreamObject(stream) {
213
+ const instance = new this(null, {
214
+ type: "x/x"
215
+ });
216
+ instance.#stream = stream;
217
+ return instance;
272
218
  }
273
- return output;
274
- });
275
- var outputSchema = z3.union([z3.string().min(1), outputDefinitionSchema]).transform((output) => {
276
- if (typeof output === "string") {
219
+ get streamObject() {
220
+ return this.#stream;
221
+ }
222
+ get mimeType() {
223
+ return this.#stream?.mime ?? this.#options.type;
224
+ }
225
+ get mainMimeType() {
226
+ return this.mimeType.split("/")[0];
227
+ }
228
+ get subMimeType() {
229
+ return this.mimeType.split("/")[1];
230
+ }
231
+ stream() {
232
+ if (this.#stream) {
233
+ const { readable, writable } = new TransformStream;
234
+ fetch(this.#stream.url).then((response) => response.body?.pipeTo(writable));
235
+ return readable;
236
+ }
237
+ return this.#data;
238
+ }
239
+ asyncIterable() {
240
+ const reader = this.stream().getReader();
277
241
  return {
278
- default: true,
279
- exit: false,
280
- target: output
242
+ [Symbol.asyncIterator]() {
243
+ return {
244
+ async next() {
245
+ return reader.read();
246
+ },
247
+ async return() {
248
+ reader.cancel();
249
+ reader.releaseLock();
250
+ return { done: true, value: null };
251
+ }
252
+ };
253
+ }
281
254
  };
282
255
  }
283
- return output;
284
- });
285
- function validateOutputs(outputs, ctx) {
286
- const exitOutputs = new Set(outputs.filter((output) => output.exit).map((output) => output.default ? "__default__" : output.name));
287
- outputs.filter((output) => !output.exit).forEach((output) => {
288
- const name = output.default ? "__default__" : output.name;
289
- if (exitOutputs.has(name)) {
290
- ctx.addIssue({
291
- code: "custom",
292
- message: output.default ? `default exit output cannot be mixed with target output "${output.target}"` : `named exit output "${name}" cannot be mixed with target output "${output.target}"`
293
- });
294
- }
295
- });
296
- const targets = new Map;
297
- outputs.forEach((output) => {
298
- const name = output.default ? "__default__" : output.name;
299
- const target = output.exit ? "__exit__" : output.target;
300
- if (!targets.has(name)) {
301
- targets.set(name, new Set);
302
- }
303
- const knownTargets = targets.get(name);
304
- if (knownTargets.has(target)) {
305
- ctx.addIssue({
306
- code: "custom",
307
- message: [
308
- output.default ? "duplicate default output" : `duplicate named output "${name}"`,
309
- output.exit ? "for exit" : `for target "${target}"`
310
- ].join(" ")
311
- });
312
- }
313
- knownTargets.add(target);
314
- });
256
+ toString() {
257
+ return `RequenceStream<${this.mimeType}>`;
258
+ }
259
+ toJSON() {
260
+ return `RequenceStream<${this.mimeType}>`;
261
+ }
315
262
  }
316
- var defaultOutputsSchema = z3.array(defaultOutputSchema).default([]).superRefine(validateOutputs);
317
- var outputsSchema = z3.array(outputSchema).default([]).superRefine(validateOutputs);
318
- var idSchema = z3.string().uuid().default(() => crypto.randomUUID());
319
- var metaSchema = z3.record(z3.any()).optional();
320
- var entryNodeSchema = z3.object({
321
- type: z3.literal("entry"),
322
- id: z3.literal("__entry__").default("__entry__"),
323
- output: defaultOutputsSchema,
324
- inputSchema: jsonSchema7Schema.default({ type: "null" }),
325
- metaSchema: jsonSchema7Schema.default({ type: "null" }),
326
- meta: metaSchema
327
- });
328
- var serviceNodeSchema = z3.object({
329
- type: z3.literal("service"),
330
- output: outputsSchema,
331
- inputSchema: z3.union([jsonSchema7ObjectSchema, jsonSchema7NullSchema]).default({ type: "null" }),
332
- id: idSchema,
333
- name: z3.string(),
334
- version: z3.string(),
335
- configuration: z3.any().optional(),
336
- configurationSchema: jsonSchema7Schema.default({ type: "null" }),
337
- alias: z3.string().optional(),
338
- ttl: z3.number().int().min(1).optional(),
339
- retry: z3.number().int().min(1).optional(),
340
- retryDelay: z3.number().int().min(100).optional(),
341
- meta: metaSchema
342
- });
343
- var catchNodeSchema = z3.object({
344
- type: z3.literal("catch"),
345
- output: outputsSchema,
346
- id: idSchema,
347
- subject: z3.string(),
348
- meta: metaSchema
349
- });
350
- var logicNodeSchema = z3.object({
351
- type: z3.literal("logic"),
352
- alias: z3.string().optional(),
353
- output: outputsSchema,
354
- id: idSchema,
355
- script: z3.string(),
356
- concurrency: z3.boolean().default(true),
357
- language: z3.enum(["javascript", "python", "typescript"]).default("javascript"),
358
- maxExecutionTime: z3.number().int().min(0).default(200),
359
- meta: metaSchema
360
- });
361
- var orNodeSchema = z3.object({
362
- id: idSchema,
363
- type: z3.literal("or"),
364
- alias: z3.string().optional(),
365
- output: outputsSchema,
366
- meta: metaSchema
263
+
264
+ // ../helpers/src/files/streamObject.ts
265
+ import { z as z4 } from "zod/v4";
266
+ var streamObjectSchema = z4.object({
267
+ mime: z4.string(),
268
+ url: z4.string().url(),
269
+ __REQUENCE_type: z4.literal("RequenceStream")
367
270
  });
368
- var nodeSchema = z3.discriminatedUnion("type", [
369
- entryNodeSchema,
370
- serviceNodeSchema,
371
- catchNodeSchema,
372
- logicNodeSchema,
373
- orNodeSchema
374
- ]);
271
+ function isStreamObject(data) {
272
+ return streamObjectSchema.safeParse(data).success;
273
+ }
274
+ function toStreamObject(streamInfo) {
275
+ return {
276
+ ...streamInfo,
277
+ __REQUENCE_type: "RequenceStream"
278
+ };
279
+ }
375
280
 
376
- // ../helpers/src/protocol/nodes.ts
377
- class NodesError extends ZodError {
378
- constructor(message, params, path = []) {
379
- super([
380
- {
381
- code: z4.ZodIssueCode.custom,
382
- message,
383
- path,
384
- params
385
- }
386
- ]);
281
+ // ../helpers/src/files/mapOutput.ts
282
+ async function upload(uploadUrl, body, signal, contentType) {
283
+ const uploadResponse = await fetch(uploadUrl, {
284
+ method: "POST",
285
+ signal,
286
+ headers: contentType ? {
287
+ "Content-Type": contentType
288
+ } : {},
289
+ body
290
+ });
291
+ const data = await uploadResponse.json();
292
+ if (!data || typeof data !== "object") {
293
+ throw new Error("invalid upload response");
387
294
  }
295
+ return toFileObject(data);
388
296
  }
389
- var nodesSchema = z4.array(nodeSchema).transform((nodes) => {
390
- const aliases = new Map;
391
- const names = new Map;
392
- let entryNode = null;
393
- let firstNodeId = null;
394
- for (const node of nodes) {
395
- if (node.type === "entry") {
396
- entryNode = node;
397
- }
398
- if ((node.type === "service" || node.type === "logic") && !firstNodeId) {
399
- firstNodeId = node.id;
297
+ async function stream(streamUrl, stream2, signal, contentType) {
298
+ const [testStream, dataStream] = stream2.tee();
299
+ const reader = testStream.getReader();
300
+ const dataPromise = reader.read().then(({ done: done2 }) => {
301
+ if (done2) {
302
+ throw new Error("No streaming date received");
400
303
  }
401
- if ("alias" in node && node.alias) {
402
- if (!aliases.has(node.alias)) {
403
- aliases.set(node.alias, []);
404
- }
405
- aliases.get(node.alias).push(node.id);
406
- }
407
- if ("name" in node && node.name) {
408
- if (!names.has(node.name)) {
409
- names.set(node.name, []);
410
- }
411
- names.get(node.name).push(node.id);
412
- }
413
- }
414
- if (!entryNode && firstNodeId) {
415
- nodes.unshift({
416
- type: "entry",
417
- id: "__entry__",
418
- inputSchema: { type: "null" },
419
- metaSchema: { type: "null" },
420
- output: [{ default: true, exit: false, target: firstNodeId }]
421
- });
304
+ reader.cancel();
305
+ });
306
+ const streamResponse = await fetch(streamUrl, {
307
+ method: "POST",
308
+ signal,
309
+ headers: contentType ? { "Content-Type": contentType } : {}
310
+ });
311
+ const data = await streamResponse.json();
312
+ if (!data || typeof data !== "object") {
313
+ throw new Error("invalid stream response");
422
314
  }
423
- const resolveOutput = (identifier) => {
424
- if (aliases.get(identifier)?.length === 1) {
425
- return aliases.get(identifier)[0];
426
- }
427
- if (names.get(identifier)?.length === 1) {
428
- return names.get(identifier)[0];
429
- }
430
- return identifier;
431
- };
432
- return nodes.map((node) => {
433
- node.output = node.output.map((output) => ("target" in output) ? {
434
- ...output,
435
- target: resolveOutput(output.target)
436
- } : output);
437
- if ("subject" in node) {
438
- node.subject = resolveOutput(node.subject);
439
- }
440
- return node;
315
+ const { mime, url } = data;
316
+ await dataPromise;
317
+ const done = fetch(url, {
318
+ method: "POST",
319
+ signal,
320
+ duplex: "half",
321
+ body: dataStream
441
322
  });
442
- }).transform((nodes) => {
443
- const { getInputs, getNode } = createNodeMaps(nodes);
444
- const nodeAliases = new Set;
445
- const nodeIds = new Set;
446
- const catchSubjects = new Map;
447
- const identify = (nodeId) => identifyNode(nodeId, getNode);
448
- for (const node of nodes) {
449
- if (nodeIds.has(node.id)) {
450
- throw new NodesError("id is not unique", {
451
- id: node.id
452
- });
453
- }
454
- nodeIds.add(node.id);
455
- if ("alias" in node && node.alias) {
456
- if (nodeAliases.has(node.alias)) {
457
- throw new NodesError("alias is not unique", {
458
- alias: node.alias
459
- });
323
+ return [toStreamObject({ mime, url }), done];
324
+ }
325
+ async function mapOutput(params) {
326
+ const streamPromises = [];
327
+ const mapped = await mapData(params.value, {
328
+ async Object(obj) {
329
+ if (obj instanceof Blob || obj instanceof RequenceFile) {
330
+ if (obj instanceof RequenceFile && obj.fileObject) {
331
+ return obj.fileObject;
332
+ }
333
+ if (params.options.uploadUrl) {
334
+ try {
335
+ if (obj instanceof Blob) {
336
+ return await upload(params.options.uploadUrl, obj, params.signal, obj.type);
337
+ }
338
+ if (obj instanceof RequenceFile) {
339
+ return await upload(params.options.uploadUrl, await obj.blob(), params.signal, obj.mimeType);
340
+ }
341
+ } catch (error) {
342
+ if (!(error instanceof Error)) {
343
+ throw error;
344
+ }
345
+ params.onFail?.(error);
346
+ return null;
347
+ }
348
+ } else {
349
+ params.onSkip?.();
350
+ return null;
351
+ }
460
352
  }
461
- nodeAliases.add(node.alias);
462
- }
463
- if (node.type === "catch") {
464
- if (catchSubjects.has(node.subject)) {
465
- throw new NodesError("only one catch node per service allowed", {
466
- id: node.subject
467
- });
353
+ if (obj instanceof Response || obj instanceof RequenceStream) {
354
+ if (obj instanceof RequenceStream && obj.streamObject) {
355
+ return obj.streamObject;
356
+ }
357
+ if (params.options.streamUrl) {
358
+ try {
359
+ if (obj instanceof Response && obj.body) {
360
+ const [streamObject, streamPromise] = await stream(params.options.streamUrl, obj.body, params.signal, obj.headers.get("Content-Type"));
361
+ streamPromises.push(streamPromise);
362
+ return streamObject;
363
+ }
364
+ if (obj instanceof RequenceStream) {
365
+ const [streamObject, streamPromise] = await stream(params.options.streamUrl, obj.stream(), params.signal, obj.mimeType);
366
+ streamPromises.push(streamPromise);
367
+ return streamObject;
368
+ }
369
+ } catch (error) {
370
+ if (!(error instanceof Error)) {
371
+ throw error;
372
+ }
373
+ params.onFail?.(error);
374
+ return null;
375
+ }
376
+ } else {
377
+ params.onSkip?.();
378
+ return null;
379
+ }
468
380
  }
469
- catchSubjects.set(node.subject, node);
470
- }
471
- }
472
- if (!getNode("__entry__")) {
473
- throw new NodesError("missing entry node");
474
- }
475
- if (getInputs("__exit__").length === 0) {
476
- throw new NodesError("no path leads to exit");
477
- }
478
- for (const catchNode of nodes.filter((node) => node.type === "catch")) {
479
- if (!getNode(catchNode.subject)) {
480
- throw new NodesError("catch node has invalid subject", {
481
- id: catchNode.subject
482
- });
483
381
  }
484
- }
485
- for (const node of nodes) {
486
- if (node.type === "or") {
487
- const inputs = getInputs(node);
488
- if (!inputs || inputs.length < 2) {
489
- throw new NodesError("or nodes need at least 2 inputs");
382
+ });
383
+ Promise.allSettled(streamPromises).then(() => params.onDone?.());
384
+ return mapped;
385
+ }
386
+
387
+ // ../helpers/src/utils/resolveRequenceTypes.ts
388
+ function resolveRequenceTypes(data, onCallback) {
389
+ return mapData(data, {
390
+ Object(obj) {
391
+ if (isFileObject(obj)) {
392
+ return RequenceFile.fromFileObject(obj);
490
393
  }
491
- }
492
- for (const targetNodeId of getNodeOutputs(node)) {
493
- if (targetNodeId !== "__exit__" && !getNode(targetNodeId)) {
494
- throw new NodesError("missing node", {
495
- id: targetNodeId
496
- });
394
+ if (isStreamObject(obj)) {
395
+ return RequenceStream.fromStreamObject(obj);
497
396
  }
498
- }
499
- }
500
- const possiblePaths = getPossiblePaths({
501
- getInputs,
502
- getNode,
503
- onMissingInputs: (_node, path) => {
504
- throw new NodesError("no path from entry to node", {
505
- path: path.map(identify)
506
- });
507
- }
508
- });
509
- if (possiblePaths.every((possiblePath) => !possiblePath.includes("__entry__"))) {
510
- throw new NodesError("no path from entry to exit");
511
- }
512
- for (const possiblePath of possiblePaths) {
513
- for (const pathSegment of possiblePath) {
514
- const node = pathSegment === "__exit__" ? null : getNode(pathSegment);
515
- if (node?.type === "catch" && possiblePath.includes(node.subject)) {
516
- throw new NodesError("Unresolvable, inputs needs both catch and subject", {
517
- path: possiblePath.map(identify)
518
- });
397
+ if (isCallbackObject(obj)) {
398
+ return (arg) => {
399
+ onCallback?.({ ...obj, arg });
400
+ };
519
401
  }
520
402
  }
521
- }
522
- return nodes;
523
- });
403
+ });
404
+ }
524
405
 
525
- // ../helpers/src/protocol/command.ts
526
- var abortSchema = z5.object({
527
- type: z5.literal("ABORT"),
528
- reason: z5.string().optional()
529
- });
530
- var nodeOptionsSchema = z5.object({
531
- maxExecutions: z5.number().int().min(0).optional().default(10)
532
- });
533
- var createNodesSchema = z5.object({
534
- type: z5.literal("CREATE_NODES"),
535
- nodes: nodesSchema,
536
- input: z5.any(),
537
- meta: z5.any(),
538
- options: nodeOptionsSchema
539
- });
540
- var commandSchema = z5.union([abortSchema, createNodesSchema]);
541
- // ../helpers/src/protocol/update.ts
542
- import { z as z6 } from "zod";
543
- var baseUpdateSchema = z6.object({
544
- timestamp: z6.number().int().transform((int) => new Date(int))
545
- });
546
- var baseNodeUpdateSchema = baseUpdateSchema.extend({
547
- nodeId: z6.string().uuid()
548
- });
549
- var nodeStartUpdateSchema = baseNodeUpdateSchema.extend({
550
- type: z6.literal("NODE_START"),
551
- context: contextSchema
552
- });
553
- var nodeErrorUpdateSchema = baseNodeUpdateSchema.extend({
554
- type: z6.literal("NODE_ERROR"),
555
- error: z6.string(),
556
- context: contextSchema
557
- });
558
- var nodeUpdateSchema = baseNodeUpdateSchema.extend({
559
- type: z6.literal("NODE_UPDATE"),
560
- output: z6.string(),
561
- data: z6.unknown(),
562
- context: contextSchema
563
- });
564
- var nodeFinishedUpdateSchema = baseNodeUpdateSchema.extend({
565
- type: z6.literal("NODE_FINISHED"),
566
- context: contextSchema
567
- });
568
- var nodeDebugUpdateSchema = baseNodeUpdateSchema.extend({
569
- type: z6.literal("NODE_DEBUG"),
570
- severity: z6.enum(["log", "info", "warn", "error"]),
571
- data: z6.unknown(),
572
- context: contextSchema
573
- });
574
- var nodeDeferUpdateSchema = baseNodeUpdateSchema.extend({
575
- type: z6.literal("NODE_DEFER"),
576
- data: z6.unknown(),
577
- context: contextSchema
578
- });
579
- var taskStartUpdateSchema = baseUpdateSchema.extend({
580
- type: z6.literal("TASK_START"),
581
- nodes: nodesSchema,
582
- context: contextSchema
583
- });
584
- var taskErrorUpdateSchema = baseUpdateSchema.extend({
585
- type: z6.literal("TASK_ERROR"),
586
- reason: z6.string().optional(),
587
- context: contextSchema
588
- });
589
- var taskFinishedUpdateSchema = baseUpdateSchema.extend({
590
- type: z6.literal("TASK_FINISHED"),
591
- context: contextSchema
592
- });
593
- var updateSchema = z6.discriminatedUnion("type", [
594
- nodeStartUpdateSchema,
595
- nodeErrorUpdateSchema,
596
- nodeUpdateSchema,
597
- nodeFinishedUpdateSchema,
598
- nodeDebugUpdateSchema,
599
- nodeDeferUpdateSchema,
600
- taskStartUpdateSchema,
601
- taskErrorUpdateSchema,
602
- taskFinishedUpdateSchema
603
- ]);
604
406
  // src/createAmqpConnection.ts
605
407
  import { connect } from "amqp-connection-manager";
606
- import { z as z7 } from "zod";
408
+ import { z as z5 } from "zod/v4";
409
+
410
+ // src/errors.ts
411
+ class RequenceConnectionError extends Error {
412
+ }
607
413
 
608
414
  // src/helpers.ts
415
+ import { AsyncLocalStorage } from "node:async_hooks";
609
416
  class RetryError extends Error {
610
417
  delay;
611
418
  constructor(delay) {
@@ -614,400 +421,701 @@ class RetryError extends Error {
614
421
  }
615
422
  }
616
423
 
424
+ class SkipError extends Error {
425
+ }
426
+
617
427
  class AbortError extends Error {
618
428
  }
619
429
  var OUTPUT_VALUE = Symbol("output_value");
620
430
  function isOutputValue(value) {
621
431
  return value !== null && typeof value === "object" && OUTPUT_VALUE in value;
622
432
  }
623
- function isRecord(data) {
624
- return typeof data === "object" && data !== null && !Array.isArray(data);
433
+ function processData(params) {
434
+ return mapOutput({
435
+ value: mapData(params.data, {
436
+ Function(data, path) {
437
+ return {
438
+ ...params.onCallback(data),
439
+ outputName: params.outputName,
440
+ propertyPath: path,
441
+ __REQUENCE_type: "RequenceCallback"
442
+ };
443
+ }
444
+ }),
445
+ options: params.options,
446
+ onDone: params.onDone
447
+ });
625
448
  }
626
- function unwrapResult(result) {
627
- if (isOutputValue(result)) {
628
- return { value: result.value, outputName: result[OUTPUT_VALUE] };
449
+ async function unwrapResult(params) {
450
+ if (isOutputValue(params.result)) {
451
+ return {
452
+ value: await processData({
453
+ outputName: params.result[OUTPUT_VALUE],
454
+ data: params.result.value,
455
+ options: params.options,
456
+ onDone: params.onDone,
457
+ onCallback: params.onCallback
458
+ }),
459
+ outputName: params.result[OUTPUT_VALUE]
460
+ };
629
461
  }
630
- return { value: result, outputName: null };
462
+ return {
463
+ value: await processData({
464
+ outputName: null,
465
+ data: params.result,
466
+ options: params.options,
467
+ onDone: params.onDone,
468
+ onCallback: params.onCallback
469
+ }),
470
+ outputName: null
471
+ };
631
472
  }
632
473
  function createContextHelper(options) {
633
- const nodes2 = new Map(options.nodes.map((node2) => [
634
- node2.id,
635
- Object.assign(node2, {
636
- executionDate: node2.id in options.context.dates ? new Date(options.context.dates[node2.id]) : null,
637
- data: options.context.data[node2.id] ?? null,
638
- error: options.context.errors[node2.id] ?? null
639
- })
640
- ]));
641
- return {
642
- taskId: options.taskId,
643
- getInput() {
644
- return options.context.input;
645
- },
646
- getMeta() {
647
- return options.context.meta;
648
- },
649
- getData() {
650
- return Array.from(nodes2.values()).filter((result) => result.executionDate && isRecord(result.data)).toSorted((a, b) => a.executionDate.getTime() - b.executionDate.getTime()).reduce((acc, result) => ({
651
- ...acc,
652
- ...result.data
653
- }), isRecord(options.context.input) ? { ...options.context.input } : {});
654
- },
655
- toOutput(name, value) {
656
- return {
657
- [OUTPUT_VALUE]: name,
658
- value
659
- };
660
- },
661
- defer: options.onDefer,
662
- getConfiguration() {
663
- const result = nodes2.get(options.serviceId);
664
- if (result?.type === "service") {
665
- return result.configuration ?? null;
666
- }
667
- return null;
668
- },
669
- getNode() {
670
- return nodes2.get(options.serviceId);
671
- },
672
- getNodes() {
673
- return Array.from(nodes2.values());
674
- },
675
- state: createObjectProxy(options.state, options.onStateChange),
676
- debug: {
677
- log(...data) {
678
- options.onLog("log", data);
474
+ const terminatePromise = Promise.withResolvers();
475
+ return [
476
+ {
477
+ taskId: options.taskId,
478
+ input: resolveRequenceTypes(options.input, options.onCallback),
479
+ configuration: resolveRequenceTypes(options.configuration, () => {
480
+ throw new Error("configuration may not have callbacks");
481
+ }),
482
+ toOutput(name, value) {
483
+ return {
484
+ [OUTPUT_VALUE]: name,
485
+ value
486
+ };
679
487
  },
680
- info(...data) {
681
- options.onLog("info", data);
488
+ defer: options.onDefer,
489
+ debug: {
490
+ log(...data) {
491
+ options.onLog("log", data);
492
+ },
493
+ info(...data) {
494
+ options.onLog("info", data);
495
+ },
496
+ warn(...data) {
497
+ options.onLog("warn", data);
498
+ },
499
+ error(...data) {
500
+ options.onLog("error", data);
501
+ }
682
502
  },
683
- warn(...data) {
684
- options.onLog("warn", data);
503
+ retry(delay) {
504
+ throw new RetryError(delay);
685
505
  },
686
- error(...data) {
687
- options.onLog("error", data);
688
- }
689
- },
690
- retry(delay) {
691
- throw new RetryError(delay);
506
+ abort(reason) {
507
+ throw new AbortError(reason);
508
+ },
509
+ skip() {
510
+ throw new SkipError;
511
+ },
512
+ terminated: terminatePromise.promise
692
513
  },
693
- abort(reason) {
694
- throw new AbortError(reason);
514
+ terminatePromise
515
+ ];
516
+ }
517
+ var handlerStorage = new AsyncLocalStorage;
518
+
519
+ // src/mapInput.ts
520
+ function mapInput(data) {
521
+ return mapData(data, {
522
+ Object(obj) {
523
+ if (isFileObject(obj)) {
524
+ return RequenceFile.fromFileObject(obj);
525
+ }
526
+ if (isStreamObject(obj)) {
527
+ return RequenceStream.fromStreamObject(obj);
528
+ }
695
529
  }
696
- };
530
+ });
697
531
  }
698
532
 
699
533
  // src/createAmqpConnection.ts
700
- var messageKeySchema = z7.string().transform((str) => deobfuscate(str)).pipe(z7.array(z7.string().uuid()).length(3)).transform((arr) => ({
534
+ var messageKeySchema = z5.string().transform((str) => deobfuscate(str)).pipe(z5.tuple([z5.uuid(), z5.uuid()]).rest(z5.string())).transform((arr) => ({
701
535
  taskId: arr[0],
702
- serviceId: arr[1],
703
- messageId: arr[2]
536
+ messageId: arr[1],
537
+ uploadUrl: arr[2] || undefined,
538
+ streamUrl: arr[3] || undefined
704
539
  }));
705
- var headerSchema = z7.object({
706
- properties: z7.object({
707
- correlationId: z7.string().uuid(),
708
- headers: z7.object({
709
- version: z7.string(),
710
- taskId: z7.string().uuid(),
711
- serviceId: z7.string().uuid()
540
+ var headerSchema = z5.object({
541
+ properties: z5.object({
542
+ correlationId: z5.uuid(),
543
+ headers: z5.object({
544
+ taskId: z5.uuid()
712
545
  })
713
546
  })
714
547
  }).transform((msg) => ({
715
- version: msg.properties.headers.version,
716
548
  messageId: msg.properties.correlationId,
717
- taskId: msg.properties.headers.taskId,
718
- serviceId: msg.properties.headers.serviceId
549
+ taskId: msg.properties.headers.taskId
719
550
  }));
720
- var payloadSchema = z7.object({ content: z7.instanceof(Buffer) }).transform((msg) => JSON.parse(msg.content.toString())).pipe(z7.object({
721
- context: contextSchema,
722
- meta: z7.object({
723
- nodes: nodesSchema,
724
- state: z7.record(z7.any())
551
+ var payloadSchema = z5.object({ content: z5.instanceof(Buffer) }).transform((msg) => JSON.parse(msg.content.toString())).pipe(z5.object({
552
+ input: z5.unknown(),
553
+ configuration: z5.unknown(),
554
+ options: z5.object({
555
+ uploadUrl: z5.url().optional(),
556
+ streamUrl: z5.url().optional()
725
557
  })
726
558
  }));
559
+ var backchannelMessageSchema = z5.object({
560
+ content: z5.instanceof(Buffer).transform((content) => JSON.parse(content.toString())).pipe(z5.discriminatedUnion("type", [
561
+ z5.object({
562
+ type: z5.literal("stop")
563
+ }),
564
+ z5.object({
565
+ type: z5.literal("callback"),
566
+ callbackId: z5.uuid(),
567
+ arg: z5.any()
568
+ })
569
+ ])),
570
+ properties: z5.object({
571
+ correlationId: z5.string()
572
+ })
573
+ }).transform((message) => ({
574
+ payload: message.content,
575
+ messageId: message.properties.correlationId
576
+ }));
577
+ var abortSymbol = Symbol();
578
+ var connectionOptionsSchema = z5.object({
579
+ url: z5.union([
580
+ z5.string().regex(/^amqps?:\/\/(.+):(.+)@(.+)$/).transform((str) => new URL(str)),
581
+ z5.instanceof(URL).refine((url) => url.protocol.match(/^amqps?:/), "Wrong protocol")
582
+ ]),
583
+ version: z5.string(),
584
+ devOverlay: z5.string().optional(),
585
+ silent: z5.boolean().optional(),
586
+ prefetch: z5.number().int().optional(),
587
+ connectionTimeout: z5.number().positive().default(3000),
588
+ connectionOptions: z5.any()
589
+ });
727
590
  function isMessageHandlerGenerator(handler) {
728
591
  return handler.constructor.name === "GeneratorFunction" || handler.constructor.name === "AsyncGeneratorFunction";
729
592
  }
730
- var activeMessages = new Set;
593
+ var activeMessages = new Map;
731
594
  function createConnection({
732
595
  url,
733
596
  version,
734
597
  prefetch = 1,
735
598
  silent = false,
736
- connectionTimeout
599
+ connectionTimeout,
600
+ connectionOptions,
601
+ devOverlay = ""
737
602
  }, messageHandler) {
738
- const queue = `${url.username}@${version}`;
603
+ const baseQueue = `${url.username}@${version}`;
604
+ const queue = devOverlay ? `${baseQueue}-dev-overlay-${devOverlay}` : baseQueue;
739
605
  const exchange = url.username;
740
- const connection = connect(url.toString());
741
- const connectedPromise = new Promise((resolve, reject) => {
606
+ const connection = connect(url.toString(), { connectionOptions });
607
+ const connectedPromise = new Promise((resolve2, reject) => {
742
608
  const unsubscribe = () => {
743
609
  clearTimeout(timeout);
744
610
  connection.removeListener("connect", handleConnect);
745
611
  connection.removeListener("connectFailed", handleConnectFailed);
746
612
  };
747
613
  const timeout = setTimeout(() => {
748
- handleConnectFailed({ err: "Connection timeout" });
614
+ handleConnectFailed({
615
+ err: new RequenceConnectionError("Requence connection timeout")
616
+ });
749
617
  }, connectionTimeout);
750
618
  const handleConnect = () => {
751
619
  unsubscribe();
752
- resolve();
620
+ resolve2();
753
621
  };
754
622
  const handleConnectFailed = ({ err }) => {
755
623
  unsubscribe();
756
- reject(new Error(err));
624
+ if (err.message.startsWith("Handshake terminated by server: 403 (ACCESS-REFUSED)")) {
625
+ reject(new RequenceConnectionError("Invalid service credentials"));
626
+ } else {
627
+ reject(err);
628
+ }
757
629
  };
758
630
  connection.addListener("connect", handleConnect);
759
631
  connection.addListener("connectFailed", handleConnectFailed);
760
632
  });
761
- const channel = connection.createChannel({
762
- async setup(channel2) {
763
- await channel2.checkExchange(exchange);
764
- await channel2.checkExchange(`${exchange}-retry`);
765
- await channel2.checkQueue(queue);
766
- await channel2.prefetch(prefetch);
633
+ const connectionId = crypto.randomUUID();
634
+ const backchannelQueue = `${baseQueue}-backchannel-${connectionId}`;
635
+ const channelWrapper = connection.createChannel({
636
+ async setup(channel) {
637
+ if (devOverlay) {
638
+ await channel.assertQueue(queue);
639
+ await channel.bindQueue(queue, "service", queue);
640
+ }
641
+ await channel.checkExchange(exchange);
642
+ await channel.checkExchange(`${exchange}-retry`);
643
+ await channel.checkQueue(queue);
644
+ await channel.prefetch(prefetch);
767
645
  }
768
646
  });
769
647
  const publish = ({
770
648
  data,
771
649
  outputName,
772
650
  messageId,
651
+ priority,
773
652
  ...headers
774
- }) => {
775
- channel.publish(exchange, "", Buffer.from(JSON.stringify(data ?? null)), {
776
- correlationId: messageId,
777
- contentType: "application/json",
778
- headers: {
779
- outputName: outputName ?? null,
780
- ...headers
781
- }
782
- });
783
- };
784
- channel.consume(queue, async (message) => {
785
- if (message.properties.headers?.abort || message.properties.headers?.exception) {
786
- channel.nack(message, false, false);
787
- return;
653
+ }) => channelWrapper.publish(exchange, "", Buffer.from(JSON.stringify(data ?? null)), {
654
+ correlationId: messageId,
655
+ contentType: "application/json",
656
+ persistent: true,
657
+ priority,
658
+ headers: {
659
+ outputName: outputName ?? null,
660
+ connectionId,
661
+ libVersion: "javascript@1.0.0-alpha.50",
662
+ ...headers
788
663
  }
789
- let removeActiveMessage = () => {
790
- };
791
- try {
792
- let deferred = false;
793
- let deferredReason = null;
794
- const { messageId, serviceId, taskId } = headerSchema.parse(message);
795
- activeMessages.add(messageId);
796
- removeActiveMessage = () => activeMessages.delete(messageId);
797
- const payload = payloadSchema.parse(message);
798
- let acked = false;
799
- const ack = () => {
800
- if (!acked) {
801
- acked = true;
802
- channel.ack(message);
664
+ });
665
+ const generatorTerminators = new Map;
666
+ const callbacks = new Map;
667
+ channelWrapper.addSetup(async (channel) => {
668
+ await channel.assertQueue(backchannelQueue, {
669
+ exclusive: true
670
+ });
671
+ await channel.bindQueue(backchannelQueue, "service", backchannelQueue);
672
+ await channel.consume(backchannelQueue, async (message) => {
673
+ const result = backchannelMessageSchema.safeParse(message);
674
+ if (!result.success) {
675
+ return;
676
+ }
677
+ const backchannelMessage = result.data;
678
+ switch (backchannelMessage.payload.type) {
679
+ case "stop": {
680
+ generatorTerminators.get(backchannelMessage.messageId)?.("task stopped");
681
+ break;
803
682
  }
804
- };
805
- let immediateUpdateState;
806
- const extendedContext = createContextHelper({
807
- serviceId,
808
- context: payload.context,
809
- nodes: payload.meta.nodes,
810
- taskId,
811
- state: payload.meta.state,
812
- onStateChange(newState) {
813
- clearImmediate(immediateUpdateState);
814
- immediateUpdateState = setImmediate(() => {
683
+ case "callback": {
684
+ callbacks.get(backchannelMessage.payload.callbackId)?.(backchannelMessage.payload.arg);
685
+ break;
686
+ }
687
+ }
688
+ }, {
689
+ noAck: true
690
+ });
691
+ });
692
+ channelWrapper.addSetup(async (channel) => {
693
+ channel.consume(queue, async (message) => {
694
+ if (!message) {
695
+ return;
696
+ }
697
+ let publishIndex = 0;
698
+ const donePromises = [];
699
+ const registeredCallbackIds = new Set;
700
+ let resolveActiveMessage = () => {};
701
+ const { messageId, taskId } = headerSchema.parse(message);
702
+ try {
703
+ let deferred = false;
704
+ let deferredReason = null;
705
+ const messageExecution = Promise.withResolvers();
706
+ activeMessages.set(messageId, messageExecution.promise);
707
+ messageExecution.promise.then(() => {
708
+ activeMessages.delete(messageId);
709
+ });
710
+ resolveActiveMessage = () => {
711
+ messageExecution.resolve();
712
+ };
713
+ const payload = payloadSchema.parse(message);
714
+ const [extendedContext, terminatePromise] = createContextHelper({
715
+ taskId,
716
+ input: mapInput(payload.input),
717
+ configuration: mapInput(payload.configuration),
718
+ onLog(debugMethod, data) {
815
719
  publish({
720
+ index: publishIndex++,
721
+ version,
816
722
  messageId,
817
723
  taskId,
818
- serviceId,
819
- data: clone(newState),
820
- state: true
724
+ data,
725
+ debugMethod,
726
+ priority: message.properties.priority,
727
+ debug: true
821
728
  });
729
+ },
730
+ onDefer(reason) {
731
+ deferred = true;
732
+ deferredReason = reason || null;
733
+ return obfuscate(taskId, messageId, payload.options.uploadUrl ?? "", payload.options.streamUrl ?? "");
734
+ },
735
+ onCallback(params) {
736
+ publish({
737
+ index: 0,
738
+ version,
739
+ taskId,
740
+ messageId,
741
+ data: params.arg,
742
+ outputName: params.outputName,
743
+ connectionId: params.sourceId,
744
+ callbackId: params.callbackId,
745
+ propertyPath: params.propertyPath
746
+ });
747
+ }
748
+ });
749
+ await publish({
750
+ index: publishIndex++,
751
+ version,
752
+ messageId,
753
+ taskId,
754
+ priority: message.properties.priority,
755
+ begin: true
756
+ });
757
+ if (isMessageHandlerGenerator(messageHandler)) {
758
+ const generator = messageHandler(extendedContext);
759
+ const terminationPromise = Promise.withResolvers();
760
+ generatorTerminators.set(messageId, (reason) => {
761
+ generator.return();
762
+ terminationPromise.resolve(abortSymbol);
763
+ terminatePromise.resolve(reason);
822
764
  });
823
- },
824
- onLog(debugMethod, data) {
825
- publish({
826
- messageId,
827
- taskId,
828
- serviceId,
829
- data,
830
- debugMethod,
831
- debug: true
765
+ await handlerStorage.run(extendedContext, async () => {
766
+ while (true) {
767
+ const next = await Promise.race([
768
+ terminationPromise.promise,
769
+ generator.next()
770
+ ]);
771
+ if (next === abortSymbol) {
772
+ break;
773
+ }
774
+ const { value: result, done } = next;
775
+ if (deferred) {
776
+ deferred = false;
777
+ console.warn("returning a value in a deferred message resets the deferred status");
778
+ }
779
+ const donePromise = Promise.withResolvers();
780
+ donePromises.push(donePromise.promise);
781
+ const { value, outputName } = await unwrapResult({
782
+ result,
783
+ options: payload.options,
784
+ onDone: donePromise.resolve,
785
+ onCallback: (callback) => {
786
+ const callbackId = crypto.randomUUID();
787
+ registeredCallbackIds.add(callbackId);
788
+ callbacks.set(callbackId, callback);
789
+ return {
790
+ sourceId: connectionId,
791
+ callbackId
792
+ };
793
+ }
794
+ });
795
+ if (!done || typeof value !== "undefined") {
796
+ publish({
797
+ index: publishIndex++,
798
+ version,
799
+ messageId,
800
+ taskId,
801
+ data: value,
802
+ priority: message.properties.priority,
803
+ outputName
804
+ });
805
+ }
806
+ if (done) {
807
+ break;
808
+ }
809
+ }
832
810
  });
833
- },
834
- onDefer(reason) {
835
- deferred = true;
836
- deferredReason = reason || null;
837
- ack();
838
- return obfuscate(taskId, serviceId, messageId);
839
- }
840
- });
841
- if (isMessageHandlerGenerator(messageHandler)) {
842
- const generator = messageHandler(extendedContext);
843
- while (true) {
844
- const { value: result, done } = await generator.next();
845
- ack();
846
- if (deferred) {
847
- deferred = false;
811
+ } else {
812
+ const result = await handlerStorage.run(extendedContext, () => messageHandler(extendedContext));
813
+ const donePromise = Promise.withResolvers();
814
+ donePromises.push(donePromise.promise);
815
+ const { value, outputName } = await unwrapResult({
816
+ result,
817
+ options: payload.options,
818
+ onDone: donePromise.resolve,
819
+ onCallback: () => {
820
+ throw new Error("callbacks can only be used in generator functions");
821
+ }
822
+ });
823
+ if (deferred && value) {
848
824
  console.warn("returning a value in a deferred message resets the deferred status");
825
+ deferred = false;
849
826
  }
850
- const { value, outputName } = unwrapResult(result);
851
- if (!done || typeof value !== "undefined") {
827
+ if (!deferred || value) {
852
828
  publish({
829
+ index: publishIndex++,
830
+ version,
853
831
  messageId,
854
832
  taskId,
855
- serviceId,
856
833
  data: value,
834
+ priority: message.properties.priority,
857
835
  outputName
858
836
  });
859
837
  }
860
- if (done) {
861
- break;
862
- }
863
838
  }
864
- } else {
865
- const result = await messageHandler(extendedContext);
866
- ack();
867
- const { value, outputName } = unwrapResult(result);
868
- if (deferred && value) {
869
- console.warn("returning a value in a deferred message resets the deferred status");
870
- deferred = false;
839
+ await new Promise((resolve2) => {
840
+ setImmediate(async () => {
841
+ if (!deferred) {
842
+ await Promise.allSettled(donePromises);
843
+ }
844
+ await publish({
845
+ index: publishIndex++,
846
+ version,
847
+ messageId,
848
+ taskId,
849
+ data: deferredReason,
850
+ priority: message.properties.priority,
851
+ deferred,
852
+ done: !deferred
853
+ });
854
+ channel.ack(message);
855
+ resolve2();
856
+ });
857
+ });
858
+ } catch (error) {
859
+ if (error instanceof SkipError) {
860
+ channel.nack(message);
861
+ return;
871
862
  }
872
- if (!deferred || value) {
873
- publish({
874
- messageId,
875
- taskId,
876
- serviceId,
877
- data: value,
878
- outputName
863
+ if (error instanceof RetryError) {
864
+ channel.ack(message);
865
+ const properties = {
866
+ ...message.properties,
867
+ expiration: error.delay || 1000
868
+ };
869
+ channel.publish(`${exchange}-retry`, version, message.content, properties);
870
+ return;
871
+ }
872
+ if (error instanceof AbortError && error.message.length > 0) {
873
+ channelWrapper.ack(message);
874
+ channelWrapper.publish(`${exchange}-retry`, "operator", error.message, {
875
+ ...message.properties,
876
+ contentType: "text/plain",
877
+ headers: {
878
+ ...message.properties.headers,
879
+ index: publishIndex++,
880
+ libVersion: "javascript@1.0.0-alpha.50",
881
+ abort: true
882
+ }
879
883
  });
884
+ return;
880
885
  }
881
- }
882
- setImmediate(() => publish({
883
- messageId,
884
- taskId,
885
- serviceId,
886
- data: deferredReason,
887
- deferred,
888
- done: !deferred
889
- }));
890
- } catch (error) {
891
- if (error instanceof RetryError) {
892
- const properties = {
893
- ...message.properties,
894
- expiration: error.delay || 1000
895
- };
896
- channel.publish(`${exchange}-retry`, "retry", message.content, properties);
897
- channel.ack(message);
898
- return;
899
- }
900
- if (error instanceof AbortError && error.message.length > 0) {
901
- channel.publish(`${exchange}-retry`, "requeue", error.message, {
902
- ...message.properties,
903
- expiration: 0,
904
- priority: 0,
905
- contentType: "text/plain",
906
- headers: {
907
- ...message.properties.headers,
908
- abort: true
886
+ if (error instanceof Error) {
887
+ if (!silent) {
888
+ console.error("Encountered an error inside service handler:");
889
+ console.error(error);
909
890
  }
910
- });
911
- channel.ack(message);
912
- return;
913
- }
914
- if (error instanceof Error) {
915
- if (!silent) {
916
- console.error(`Encountered an error inside service handler:`);
917
- console.error(error);
891
+ channel.ack(message);
892
+ channel.publish(`${exchange}-retry`, "operator", message.content, {
893
+ ...message.properties,
894
+ headers: {
895
+ ...message.properties.headers,
896
+ version,
897
+ exception: true,
898
+ index: publishIndex++,
899
+ libVersion: "javascript@1.0.0-alpha.50",
900
+ "error-message": error.message || "error in service handler"
901
+ }
902
+ });
903
+ return;
918
904
  }
919
- channel.publish(`${exchange}-retry`, "requeue", message.content, {
920
- ...message.properties,
921
- expiration: 0,
922
- priority: 0,
923
- headers: {
924
- ...message.properties.headers,
925
- exception: true,
926
- "error-message": error.message || "error in service handler"
927
- }
928
- });
929
- channel.ack(message);
930
- return;
905
+ } finally {
906
+ generatorTerminators.delete(messageId);
907
+ registeredCallbackIds.forEach((id) => callbacks.delete(id));
908
+ resolveActiveMessage();
931
909
  }
932
- channel.nack(message, false, false);
933
- } finally {
934
- removeActiveMessage();
935
- }
910
+ });
936
911
  });
912
+ const activeMessageKeys = new Set;
937
913
  const api = {
938
914
  close: async () => {
939
- await channel.close();
915
+ await channelWrapper.close();
940
916
  await connection.close();
941
917
  },
942
918
  open: () => connectedPromise.then(() => api),
943
919
  async act(messageKey, actor) {
920
+ if (activeMessageKeys.has(messageKey)) {
921
+ throw new Error("a defer key can only be used once");
922
+ }
923
+ activeMessageKeys.add(messageKey);
924
+ let publishIndex = 0;
925
+ const { taskId, messageId, ...options } = messageKeySchema.parse(messageKey);
926
+ const activeMessage = async () => {
927
+ if (activeMessages.has(messageId)) {
928
+ await activeMessages.get(messageId);
929
+ }
930
+ };
931
+ const registeredCallbackIds = new Set;
932
+ const donePromises = [];
944
933
  await actor({
945
- sendToOutput(outputName, data) {
946
- const { taskId: taskId2, serviceId: serviceId2, messageId: messageId2 } = messageKeySchema.parse(messageKey);
947
- if (activeMessages.has(messageId2)) {
948
- throw new Error("Cannot send deferred message while callback handler is still running");
949
- }
950
- publish({
951
- messageId: messageId2,
952
- taskId: taskId2,
953
- serviceId: serviceId2,
954
- data,
934
+ async sendToOutput(outputName, data) {
935
+ await activeMessage();
936
+ const donePromise = Promise.withResolvers();
937
+ donePromises.push(donePromise.promise);
938
+ donePromises.push(publish({
939
+ index: publishIndex++,
940
+ version,
941
+ messageId,
942
+ taskId,
943
+ data: await processData({
944
+ outputName,
945
+ data,
946
+ options,
947
+ onDone: donePromise.resolve,
948
+ onCallback: (callback) => {
949
+ const callbackId = crypto.randomUUID();
950
+ registeredCallbackIds.add(callbackId);
951
+ callbacks.set(callbackId, callback);
952
+ return {
953
+ sourceId: connectionId,
954
+ callbackId
955
+ };
956
+ }
957
+ }),
955
958
  outputName
956
- });
959
+ }));
957
960
  },
958
- send(data) {
959
- const { taskId: taskId2, serviceId: serviceId2, messageId: messageId2 } = messageKeySchema.parse(messageKey);
960
- if (activeMessages.has(messageId2)) {
961
- throw new Error("Cannot send deferred message while callback handler is still running");
962
- }
963
- publish({
964
- messageId: messageId2,
965
- taskId: taskId2,
966
- serviceId: serviceId2,
967
- data
968
- });
961
+ async send(data) {
962
+ await activeMessage();
963
+ const donePromise = Promise.withResolvers();
964
+ donePromises.push(donePromise.promise);
965
+ donePromises.push(publish({
966
+ index: publishIndex++,
967
+ version,
968
+ messageId,
969
+ taskId,
970
+ data: await processData({
971
+ outputName: null,
972
+ data,
973
+ options,
974
+ onDone: donePromise.resolve,
975
+ onCallback: (callback) => {
976
+ const callbackId = crypto.randomUUID();
977
+ registeredCallbackIds.add(callbackId);
978
+ callbacks.set(callbackId, callback);
979
+ return {
980
+ sourceId: connectionId,
981
+ callbackId
982
+ };
983
+ }
984
+ })
985
+ }));
969
986
  },
970
- abort(error) {
971
- const { taskId: taskId2, serviceId: serviceId2, messageId: messageId2 } = messageKeySchema.parse(messageKey);
972
- if (activeMessages.has(messageId2)) {
973
- throw new Error("Cannot send deferred message while callback handler is still running");
974
- }
975
- channel.publish(`${exchange}-retry`, "requeue", error instanceof Error ? error.message : error, {
976
- correlationId: messageId2,
987
+ async abort(error) {
988
+ await activeMessage();
989
+ channelWrapper.publish(`${exchange}-retry`, "operator", error instanceof Error ? error.message : error, {
990
+ persistent: true,
991
+ correlationId: messageId,
977
992
  expiration: 0,
978
993
  priority: 0,
979
994
  contentType: "text/plain",
980
995
  headers: {
981
- taskId: taskId2,
982
- serviceId: serviceId2,
996
+ taskId,
997
+ libVersion: "javascript@1.0.0-alpha.50",
998
+ index: publishIndex++,
983
999
  abort: true
984
1000
  }
985
1001
  });
986
1002
  }
987
1003
  });
988
- const { taskId, serviceId, messageId } = messageKeySchema.parse(messageKey);
989
- setImmediate(() => publish({
1004
+ await new Promise((resolve2) => setImmediate(resolve2));
1005
+ await activeMessage();
1006
+ while (true) {
1007
+ const promiseCount = donePromises.length;
1008
+ await Promise.allSettled(donePromises);
1009
+ if (promiseCount === donePromises.length) {
1010
+ break;
1011
+ }
1012
+ }
1013
+ registeredCallbackIds.forEach((id) => callbacks.delete(id));
1014
+ await publish({
1015
+ index: publishIndex++,
1016
+ version,
990
1017
  messageId,
991
1018
  taskId,
992
- serviceId,
993
1019
  done: true
994
- }));
1020
+ });
1021
+ activeMessageKeys.delete(messageKey);
995
1022
  }
996
1023
  };
997
1024
  return api;
998
1025
  }
1026
+ // src/utils.ts
1027
+ function isAsyncIterable(iterable) {
1028
+ return typeof iterable[Symbol.asyncIterator] === "function";
1029
+ }
1030
+ function wrapIterable(iterable) {
1031
+ const context = handlerStorage.getStore();
1032
+ if (!context) {
1033
+ return iterable;
1034
+ }
1035
+ let terminated = false;
1036
+ context.terminated.then(() => {
1037
+ terminated = true;
1038
+ });
1039
+ if (isAsyncIterable(iterable)) {
1040
+ return {
1041
+ [Symbol.asyncIterator]() {
1042
+ const iterator = iterable[Symbol.asyncIterator]();
1043
+ return {
1044
+ async next() {
1045
+ const result = await Promise.race([
1046
+ context.terminated,
1047
+ iterator.next()
1048
+ ]);
1049
+ if (terminated) {
1050
+ return { done: true, value: undefined };
1051
+ }
1052
+ return result;
1053
+ }
1054
+ };
1055
+ }
1056
+ };
1057
+ }
1058
+ return {
1059
+ [Symbol.iterator]() {
1060
+ const iterator = iterable[Symbol.iterator]();
1061
+ return {
1062
+ next() {
1063
+ if (terminated) {
1064
+ return { done: true, value: undefined };
1065
+ }
1066
+ const result = iterator.next();
1067
+ return result;
1068
+ }
1069
+ };
1070
+ }
1071
+ };
1072
+ }
1073
+ function asyncEventEmitter(initial = []) {
1074
+ const context = handlerStorage.getStore();
1075
+ let terminated = false;
1076
+ context?.terminated.then(() => {
1077
+ terminated = true;
1078
+ });
1079
+ let resolve2;
1080
+ const initialValues = structuredClone(initial);
1081
+ return {
1082
+ push: (value) => {
1083
+ if (resolve2) {
1084
+ resolve2(value);
1085
+ } else {
1086
+ initialValues.push(value);
1087
+ }
1088
+ },
1089
+ [Symbol.asyncIterator]() {
1090
+ return {
1091
+ async next() {
1092
+ if (initialValues.length > 0) {
1093
+ return { value: initialValues.shift(), done: false };
1094
+ }
1095
+ const defer = Promise.withResolvers();
1096
+ resolve2 = defer.resolve;
1097
+ if (context) {
1098
+ const value = await Promise.race([
1099
+ defer.promise,
1100
+ context.terminated
1101
+ ]);
1102
+ return terminated ? { done: true, value: undefined } : { done: false, value };
1103
+ }
1104
+ return { value: await defer.promise, done: false };
1105
+ }
1106
+ };
1107
+ }
1108
+ };
1109
+ }
999
1110
 
1000
1111
  // src/index.ts
1001
- var connectionOptionsSchema = z8.object({
1002
- url: z8.union([
1003
- z8.string().regex(/^amqps?:\/\/(.+):(.+)@(.+)$/).transform((str) => new URL(str)),
1004
- z8.instanceof(URL).refine((url) => url.protocol.match(/^amqps?:/), "Wrong protocol")
1005
- ]),
1006
- version: z8.string(),
1007
- silent: z8.boolean().optional(),
1008
- prefetch: z8.number().int().optional(),
1009
- connectionTimeout: z8.number().positive().default(3000)
1010
- });
1112
+ var pkgJson;
1113
+ function loadPkgJson() {
1114
+ if (!pkgJson) {
1115
+ pkgJson = JSON.parse(fs.readFileSync("package.json", "utf-8"));
1116
+ }
1117
+ return pkgJson;
1118
+ }
1011
1119
  function createService(optionsOrVersion, optionalMessageHandler) {
1012
1120
  let options;
1013
1121
  let messageHandler;
@@ -1020,23 +1128,54 @@ function createService(optionsOrVersion, optionalMessageHandler) {
1020
1128
  options = optionsOrVersion;
1021
1129
  messageHandler = optionalMessageHandler;
1022
1130
  }
1023
- const token = options.accessToken ?? process.env.REQUENCE_ACCESS_TOKEN ?? JSON.parse(readFileSync("package.json", "utf-8")).requence?.accessToken;
1131
+ let token = options.accessToken ?? process.env.REQUENCE_SERVICE_ACCESS_TOKEN ?? process.env.REQUENCE_ACCESS_TOKEN;
1024
1132
  if (!token) {
1025
- throw new Error("No service key found");
1133
+ try {
1134
+ const pkgJson2 = loadPkgJson();
1135
+ token = pkgJson2.requence?.service?.accessToken ?? pkgJson2.requence?.accessToken;
1136
+ } catch {}
1137
+ }
1138
+ let devToken = options.devToken ?? process.env.REQUENCE_SERVICE_DEV_TOKEN ?? process.env.REQUENCE_DEV_TOKEN;
1139
+ if (!devToken) {
1140
+ try {
1141
+ const pkgJson2 = loadPkgJson();
1142
+ devToken = pkgJson2.requence?.service?.devToken ?? pkgJson2.requence?.devToken;
1143
+ } catch {}
1144
+ }
1145
+ if (!token) {
1146
+ throw new Error("no access token provided");
1026
1147
  }
1027
1148
  const parts = deobfuscate(token);
1028
1149
  if (parts.length < 2 || parts[0] !== "service") {
1029
- throw new Error("Invalid service key");
1150
+ throw new Error("invalid access token");
1030
1151
  }
1031
- const connectionOptions = {
1152
+ const url = parts[1];
1153
+ let devOverlay;
1154
+ if (devToken) {
1155
+ const devParts = deobfuscate(devToken);
1156
+ if (devParts[0] !== "api") {
1157
+ throw new Error("invalid dev token: please provide a personal access token");
1158
+ }
1159
+ if (devParts[2] !== parts[2]) {
1160
+ throw new Error("invalid dev token: access token and dev token belong to different requence instances");
1161
+ }
1162
+ devOverlay = devParts[1];
1163
+ }
1164
+ return createConnection(connectionOptionsSchema.parse({
1032
1165
  ...options,
1033
- url: parts[1]
1034
- };
1035
- return createConnection(connectionOptionsSchema.parse(connectionOptions), messageHandler);
1166
+ url,
1167
+ devOverlay
1168
+ }), messageHandler);
1036
1169
  }
1037
1170
  export {
1038
- createService
1171
+ wrapIterable,
1172
+ createService,
1173
+ createCallback,
1174
+ asyncEventEmitter,
1175
+ RequenceStream,
1176
+ RequenceFile,
1177
+ RequenceConnectionError
1039
1178
  };
1040
1179
 
1041
- //# debugId=41D15659E9341B8064756E2164756E21
1180
+ //# debugId=57C0C865BD4C680C64756E2164756E21
1042
1181
  //# sourceMappingURL=index.js.map