@requence/service 0.7.1

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 (91) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +330 -0
  3. package/build/chunk-6w7td62p.js +56 -0
  4. package/build/chunk-6w7td62p.js.map +10 -0
  5. package/build/cli.js +166 -0
  6. package/build/cli.js.map +10 -0
  7. package/build/index.js +1229 -0
  8. package/build/index.js.map +24 -0
  9. package/build/types/helpers/src/files/RequenceFile.d.ts +40 -0
  10. package/build/types/helpers/src/files/RequenceFile.d.ts.map +1 -0
  11. package/build/types/helpers/src/files/RequenceStream.d.ts +32 -0
  12. package/build/types/helpers/src/files/RequenceStream.d.ts.map +1 -0
  13. package/build/types/helpers/src/files/fileObject.d.ts +16 -0
  14. package/build/types/helpers/src/files/fileObject.d.ts.map +1 -0
  15. package/build/types/helpers/src/files/index.d.ts +7 -0
  16. package/build/types/helpers/src/files/index.d.ts.map +1 -0
  17. package/build/types/helpers/src/files/isValidMimeType.d.ts +5 -0
  18. package/build/types/helpers/src/files/isValidMimeType.d.ts.map +1 -0
  19. package/build/types/helpers/src/files/mapOutput.d.ts +10 -0
  20. package/build/types/helpers/src/files/mapOutput.d.ts.map +1 -0
  21. package/build/types/helpers/src/files/streamObject.d.ts +14 -0
  22. package/build/types/helpers/src/files/streamObject.d.ts.map +1 -0
  23. package/build/types/helpers/src/files/types.d.ts +4 -0
  24. package/build/types/helpers/src/files/types.d.ts.map +1 -0
  25. package/build/types/helpers/src/index.d.ts +13 -0
  26. package/build/types/helpers/src/index.d.ts.map +1 -0
  27. package/build/types/helpers/src/jsonschema/mapSchema.d.ts +20 -0
  28. package/build/types/helpers/src/jsonschema/mapSchema.d.ts.map +1 -0
  29. package/build/types/helpers/src/jsonschema/types.d.ts +13 -0
  30. package/build/types/helpers/src/jsonschema/types.d.ts.map +1 -0
  31. package/build/types/helpers/src/jsonschema/validate.d.ts +32 -0
  32. package/build/types/helpers/src/jsonschema/validate.d.ts.map +1 -0
  33. package/build/types/helpers/src/jsonschema/zod.d.ts +17 -0
  34. package/build/types/helpers/src/jsonschema/zod.d.ts.map +1 -0
  35. package/build/types/helpers/src/protocol/NodeTree.d.ts +510 -0
  36. package/build/types/helpers/src/protocol/NodeTree.d.ts.map +1 -0
  37. package/build/types/helpers/src/protocol/command.d.ts +507 -0
  38. package/build/types/helpers/src/protocol/command.d.ts.map +1 -0
  39. package/build/types/helpers/src/protocol/helpers.d.ts +7 -0
  40. package/build/types/helpers/src/protocol/helpers.d.ts.map +1 -0
  41. package/build/types/helpers/src/protocol/index.d.ts +8 -0
  42. package/build/types/helpers/src/protocol/index.d.ts.map +1 -0
  43. package/build/types/helpers/src/protocol/nodeType.d.ts +187 -0
  44. package/build/types/helpers/src/protocol/nodeType.d.ts.map +1 -0
  45. package/build/types/helpers/src/protocol/taskOptions.d.ts +23 -0
  46. package/build/types/helpers/src/protocol/taskOptions.d.ts.map +1 -0
  47. package/build/types/helpers/src/protocol/templateNodeTypes.d.ts +267 -0
  48. package/build/types/helpers/src/protocol/templateNodeTypes.d.ts.map +1 -0
  49. package/build/types/helpers/src/protocol/treeNodes.d.ts +874 -0
  50. package/build/types/helpers/src/protocol/treeNodes.d.ts.map +1 -0
  51. package/build/types/helpers/src/protocol/update.d.ts +406 -0
  52. package/build/types/helpers/src/protocol/update.d.ts.map +1 -0
  53. package/build/types/helpers/src/utils/callbackToAsyncIterator.d.ts +3 -0
  54. package/build/types/helpers/src/utils/callbackToAsyncIterator.d.ts.map +1 -0
  55. package/build/types/helpers/src/utils/clone.d.ts +3 -0
  56. package/build/types/helpers/src/utils/clone.d.ts.map +1 -0
  57. package/build/types/helpers/src/utils/createObjectProxy.d.ts +2 -0
  58. package/build/types/helpers/src/utils/createObjectProxy.d.ts.map +1 -0
  59. package/build/types/helpers/src/utils/debounce.d.ts +4 -0
  60. package/build/types/helpers/src/utils/debounce.d.ts.map +1 -0
  61. package/build/types/helpers/src/utils/guards.d.ts +3 -0
  62. package/build/types/helpers/src/utils/guards.d.ts.map +1 -0
  63. package/build/types/helpers/src/utils/mapData.d.ts +18 -0
  64. package/build/types/helpers/src/utils/mapData.d.ts.map +1 -0
  65. package/build/types/helpers/src/utils/matchSchema.d.ts +4 -0
  66. package/build/types/helpers/src/utils/matchSchema.d.ts.map +1 -0
  67. package/build/types/helpers/src/utils/obfuscate.d.ts +4 -0
  68. package/build/types/helpers/src/utils/obfuscate.d.ts.map +1 -0
  69. package/build/types/helpers/src/utils/obj.d.ts +4 -0
  70. package/build/types/helpers/src/utils/obj.d.ts.map +1 -0
  71. package/build/types/helpers/src/utils/requenceCallback.d.ts +17 -0
  72. package/build/types/helpers/src/utils/requenceCallback.d.ts.map +1 -0
  73. package/build/types/helpers/src/utils/resolveRequenceTypes.d.ts +8 -0
  74. package/build/types/helpers/src/utils/resolveRequenceTypes.d.ts.map +1 -0
  75. package/build/types/helpers/src/utils/types.d.ts +7 -0
  76. package/build/types/helpers/src/utils/types.d.ts.map +1 -0
  77. package/build/types/service/src/createAmqpConnection.d.ts +44 -0
  78. package/build/types/service/src/createAmqpConnection.d.ts.map +1 -0
  79. package/build/types/service/src/errors.d.ts +3 -0
  80. package/build/types/service/src/errors.d.ts.map +1 -0
  81. package/build/types/service/src/helpers.d.ts +98 -0
  82. package/build/types/service/src/helpers.d.ts.map +1 -0
  83. package/build/types/service/src/index.d.ts +20 -0
  84. package/build/types/service/src/index.d.ts.map +1 -0
  85. package/build/types/service/src/macro.d.ts +2 -0
  86. package/build/types/service/src/macro.d.ts.map +1 -0
  87. package/build/types/service/src/mapInput.d.ts +2 -0
  88. package/build/types/service/src/mapInput.d.ts.map +1 -0
  89. package/build/types/service/src/utils.d.ts +6 -0
  90. package/build/types/service/src/utils.d.ts.map +1 -0
  91. package/package.json +38 -0
package/build/index.js ADDED
@@ -0,0 +1,1229 @@
1
+ import {
2
+ deobfuscate,
3
+ obfuscate
4
+ } from "./chunk-6w7td62p.js";
5
+
6
+ // src/index.ts
7
+ import fs from "node:fs";
8
+
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();
16
+
17
+ // ../helpers/src/utils/mapData.ts
18
+ function resolve(value, onResolve) {
19
+ if (value instanceof Promise) {
20
+ return Promise.resolve().then(() => value).then(onResolve);
21
+ }
22
+ return onResolve(value);
23
+ }
24
+ function notUndefined(value, fallback) {
25
+ return resolve(value, (resolvedValue) => typeof resolvedValue === "undefined" ? fallback : resolvedValue);
26
+ }
27
+
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;
35
+ }
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
+ });
48
+ }
49
+ if (data2 === null) {
50
+ return notUndefined(visitors.Null?.(data2, path), data2);
51
+ }
52
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(data2)) {
53
+ return notUndefined(visitors.Buffer?.(data2, path), data2);
54
+ }
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;
93
+ }
94
+ };
95
+ return traverseData(data, []);
96
+ }
97
+ mapData.abort = () => {
98
+ throw new AbortMapData;
99
+ };
100
+
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;
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"
138
+ };
139
+ }
140
+ function isFileObject(data) {
141
+ return fileObjectSchema.safeParse(data).success;
142
+ }
143
+
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);
150
+ }
151
+ static fromFileObject(file) {
152
+ const instance = new this([], { type: "x/x" });
153
+ instance.#file = file;
154
+ return instance;
155
+ }
156
+ get fileObject() {
157
+ return this.#file;
158
+ }
159
+ get size() {
160
+ return this.#file?.size ?? this.#data.size;
161
+ }
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());
174
+ }
175
+ return this.#data.text();
176
+ }
177
+ async json() {
178
+ if (this.#file) {
179
+ return fetch(this.#file.url).then((response) => response.json());
180
+ }
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());
186
+ }
187
+ return this.#data;
188
+ }
189
+ async arrayBuffer() {
190
+ if (this.#file) {
191
+ return fetch(this.#file.url).then((response) => response.arrayBuffer());
192
+ }
193
+ return this.#data.arrayBuffer();
194
+ }
195
+ toString() {
196
+ return `RequenceFile<${this.mimeType}>`;
197
+ }
198
+ toJSON() {
199
+ return `RequenceFile<${this.mimeType}>`;
200
+ }
201
+ }
202
+
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;
211
+ }
212
+ static fromStreamObject(stream) {
213
+ const instance = new this(null, {
214
+ type: "x/x"
215
+ });
216
+ instance.#stream = stream;
217
+ return instance;
218
+ }
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();
241
+ return {
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
+ }
254
+ };
255
+ }
256
+ toString() {
257
+ return `RequenceStream<${this.mimeType}>`;
258
+ }
259
+ toJSON() {
260
+ return `RequenceStream<${this.mimeType}>`;
261
+ }
262
+ }
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")
270
+ });
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
+ }
280
+
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");
294
+ }
295
+ return toFileObject(data);
296
+ }
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");
303
+ }
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");
314
+ }
315
+ const { mime, url } = data;
316
+ await dataPromise;
317
+ const done = fetch(url, {
318
+ method: "POST",
319
+ signal,
320
+ duplex: "half",
321
+ body: dataStream
322
+ });
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
+ }
352
+ }
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
+ }
380
+ }
381
+ }
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);
393
+ }
394
+ if (isStreamObject(obj)) {
395
+ return RequenceStream.fromStreamObject(obj);
396
+ }
397
+ if (isCallbackObject(obj)) {
398
+ return (arg) => {
399
+ onCallback?.({ ...obj, arg });
400
+ };
401
+ }
402
+ }
403
+ });
404
+ }
405
+
406
+ // src/createAmqpConnection.ts
407
+ import { connect } from "amqp-connection-manager";
408
+ import { z as z5 } from "zod/v4";
409
+
410
+ // src/errors.ts
411
+ class RequenceConnectionError extends Error {
412
+ }
413
+
414
+ // src/helpers.ts
415
+ import { AsyncLocalStorage } from "node:async_hooks";
416
+ class RetryError extends Error {
417
+ delay;
418
+ constructor(delay) {
419
+ super();
420
+ this.delay = delay;
421
+ }
422
+ }
423
+
424
+ class SkipError extends Error {
425
+ }
426
+
427
+ class AbortError extends Error {
428
+ }
429
+ var OUTPUT_VALUE = Symbol("output_value");
430
+ function isOutputValue(value) {
431
+ return value !== null && typeof value === "object" && OUTPUT_VALUE in value;
432
+ }
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
+ });
448
+ }
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
+ };
461
+ }
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
+ };
472
+ }
473
+ function createContextHelper(options) {
474
+ const terminatePromise = Promise.withResolvers();
475
+ const abortController = new AbortController;
476
+ terminatePromise.promise.then(() => abortController.abort());
477
+ const terminated = Object.assign(terminatePromise.promise, {
478
+ signal: abortController.signal
479
+ });
480
+ return [
481
+ {
482
+ taskId: options.taskId,
483
+ input: resolveRequenceTypes(options.input, options.onCallback),
484
+ configuration: resolveRequenceTypes(options.configuration, () => {
485
+ throw new Error("configuration may not have callbacks");
486
+ }),
487
+ toOutput(name, value) {
488
+ return {
489
+ [OUTPUT_VALUE]: name,
490
+ value
491
+ };
492
+ },
493
+ defer: options.onDefer,
494
+ debug: {
495
+ log(...data) {
496
+ options.onLog("log", data);
497
+ },
498
+ info(...data) {
499
+ options.onLog("info", data);
500
+ },
501
+ warn(...data) {
502
+ options.onLog("warn", data);
503
+ },
504
+ error(...data) {
505
+ options.onLog("error", data);
506
+ }
507
+ },
508
+ retry(delay) {
509
+ throw new RetryError(delay);
510
+ },
511
+ abort(reason) {
512
+ throw new AbortError(reason);
513
+ },
514
+ skip() {
515
+ throw new SkipError;
516
+ },
517
+ terminated
518
+ },
519
+ terminatePromise
520
+ ];
521
+ }
522
+ var handlerStorage = new AsyncLocalStorage;
523
+
524
+ // src/mapInput.ts
525
+ function mapInput(data) {
526
+ return mapData(data, {
527
+ Object(obj) {
528
+ if (isFileObject(obj)) {
529
+ return RequenceFile.fromFileObject(obj);
530
+ }
531
+ if (isStreamObject(obj)) {
532
+ return RequenceStream.fromStreamObject(obj);
533
+ }
534
+ }
535
+ });
536
+ }
537
+
538
+ // src/createAmqpConnection.ts
539
+ var messageKeySchema = z5.string().transform((str) => deobfuscate(str)).pipe(z5.tuple([z5.uuid(), z5.uuid()]).rest(z5.string())).transform((arr) => ({
540
+ taskId: arr[0],
541
+ messageId: arr[1],
542
+ uploadUrl: arr[2] || undefined,
543
+ streamUrl: arr[3] || undefined
544
+ }));
545
+ var headerSchema = z5.object({
546
+ properties: z5.object({
547
+ correlationId: z5.uuid(),
548
+ headers: z5.object({
549
+ taskId: z5.uuid(),
550
+ mode: z5.enum(["LINEAR", "CONTINUOUS"]).default("LINEAR")
551
+ })
552
+ })
553
+ }).transform((msg) => ({
554
+ messageId: msg.properties.correlationId,
555
+ taskId: msg.properties.headers.taskId,
556
+ mode: msg.properties.headers.mode
557
+ }));
558
+ var payloadSchema = z5.object({ content: z5.instanceof(Buffer) }).transform((msg) => JSON.parse(msg.content.toString())).pipe(z5.object({
559
+ input: z5.unknown(),
560
+ configuration: z5.unknown(),
561
+ options: z5.object({
562
+ uploadUrl: z5.url().optional(),
563
+ streamUrl: z5.url().optional()
564
+ })
565
+ }));
566
+ var backchannelMessageSchema = z5.object({
567
+ content: z5.instanceof(Buffer).transform((content) => JSON.parse(content.toString())).pipe(z5.discriminatedUnion("type", [
568
+ z5.object({
569
+ type: z5.literal("stop")
570
+ }),
571
+ z5.object({
572
+ type: z5.literal("callback"),
573
+ callbackId: z5.uuid(),
574
+ arg: z5.any()
575
+ })
576
+ ])),
577
+ properties: z5.object({
578
+ correlationId: z5.string()
579
+ })
580
+ }).transform((message) => ({
581
+ payload: message.content,
582
+ messageId: message.properties.correlationId
583
+ }));
584
+ var abortSymbol = Symbol();
585
+ var connectionOptionsSchema = z5.object({
586
+ url: z5.union([
587
+ z5.string().regex(/^amqps?:\/\/(.+):(.+)@(.+)$/).transform((str) => new URL(str)),
588
+ z5.instanceof(URL).refine((url) => url.protocol.match(/^amqps?:/), "Wrong protocol")
589
+ ]),
590
+ version: z5.string(),
591
+ devOverlay: z5.string().optional(),
592
+ silent: z5.boolean().optional(),
593
+ prefetch: z5.number().int().optional(),
594
+ connectionTimeout: z5.number().positive().default(3000),
595
+ connectionOptions: z5.any().optional()
596
+ });
597
+ function isMessageHandlerGenerator(handler) {
598
+ return handler.constructor.name === "GeneratorFunction" || handler.constructor.name === "AsyncGeneratorFunction";
599
+ }
600
+ var activeMessages = new Map;
601
+ function createConnection({
602
+ url,
603
+ version,
604
+ prefetch = 1,
605
+ silent = false,
606
+ connectionTimeout,
607
+ connectionOptions,
608
+ devOverlay = ""
609
+ }, messageHandler) {
610
+ const baseQueue = `${url.username}@${version}`;
611
+ const queue = devOverlay ? `${baseQueue}-dev-overlay-${devOverlay}` : baseQueue;
612
+ const exchange = url.username;
613
+ const connection = connect(url.toString(), { connectionOptions });
614
+ const connectedPromise = new Promise((resolve2, reject) => {
615
+ const unsubscribe = () => {
616
+ clearTimeout(timeout);
617
+ connection.removeListener("connect", handleConnect);
618
+ connection.removeListener("connectFailed", handleConnectFailed);
619
+ };
620
+ const timeout = setTimeout(() => {
621
+ handleConnectFailed({
622
+ err: new RequenceConnectionError("Requence connection timeout")
623
+ });
624
+ }, connectionTimeout);
625
+ const handleConnect = () => {
626
+ unsubscribe();
627
+ resolve2();
628
+ };
629
+ const handleConnectFailed = ({ err }) => {
630
+ unsubscribe();
631
+ if (err.message.startsWith("Handshake terminated by server: 403 (ACCESS-REFUSED)")) {
632
+ reject(new RequenceConnectionError("Invalid service credentials"));
633
+ } else {
634
+ reject(err);
635
+ }
636
+ };
637
+ connection.addListener("connect", handleConnect);
638
+ connection.addListener("connectFailed", handleConnectFailed);
639
+ });
640
+ const connectionId = crypto.randomUUID();
641
+ const backchannelQueue = `${baseQueue}-backchannel-${connectionId}`;
642
+ const generatorTerminators = new Map;
643
+ const callbacks = new Map;
644
+ const channelWrapper = connection.createChannel({
645
+ async setup(channel) {
646
+ if (devOverlay) {
647
+ await channel.assertQueue(queue);
648
+ await channel.bindQueue(queue, "service", queue);
649
+ }
650
+ await channel.checkExchange(exchange);
651
+ await channel.checkExchange(`${exchange}-retry`);
652
+ await channel.checkQueue(queue);
653
+ await channel.prefetch(prefetch);
654
+ await channel.assertQueue(backchannelQueue, {
655
+ exclusive: true
656
+ });
657
+ await channel.bindQueue(backchannelQueue, "service", backchannelQueue);
658
+ await channel.consume(backchannelQueue, async (message) => {
659
+ const result = backchannelMessageSchema.safeParse(message);
660
+ if (!result.success) {
661
+ return;
662
+ }
663
+ const backchannelMessage = result.data;
664
+ switch (backchannelMessage.payload.type) {
665
+ case "stop": {
666
+ generatorTerminators.get(backchannelMessage.messageId)?.("task stopped");
667
+ break;
668
+ }
669
+ case "callback": {
670
+ callbacks.get(backchannelMessage.payload.callbackId)?.(backchannelMessage.payload.arg);
671
+ break;
672
+ }
673
+ }
674
+ }, {
675
+ noAck: true
676
+ });
677
+ }
678
+ });
679
+ const publish = ({
680
+ data,
681
+ outputName,
682
+ messageId,
683
+ priority,
684
+ ...headers
685
+ }) => channelWrapper.publish(exchange, "", Buffer.from(JSON.stringify(data ?? null)), {
686
+ correlationId: messageId,
687
+ contentType: "application/json",
688
+ persistent: true,
689
+ priority,
690
+ headers: {
691
+ outputName: outputName ?? null,
692
+ connectionId,
693
+ libVersion: "javascript@0.7.1",
694
+ ...headers
695
+ }
696
+ });
697
+ channelWrapper.addSetup(async (channel) => {
698
+ channel.consume(queue, async (message) => {
699
+ if (!message) {
700
+ return;
701
+ }
702
+ let publishIndex = 0;
703
+ let acked = false;
704
+ let terminated = false;
705
+ const donePromises = [];
706
+ const registeredCallbackIds = new Set;
707
+ let resolveActiveMessage = () => {};
708
+ const { messageId, taskId, mode } = headerSchema.parse(message);
709
+ try {
710
+ let deferred = false;
711
+ let deferredReason = null;
712
+ const messageExecution = Promise.withResolvers();
713
+ activeMessages.set(messageId, messageExecution.promise);
714
+ messageExecution.promise.then(() => {
715
+ activeMessages.delete(messageId);
716
+ });
717
+ resolveActiveMessage = () => {
718
+ messageExecution.resolve();
719
+ };
720
+ const payload = payloadSchema.parse(message);
721
+ const [extendedContext, terminatePromise] = createContextHelper({
722
+ taskId,
723
+ input: mapInput(payload.input),
724
+ configuration: mapInput(payload.configuration),
725
+ onLog(debugMethod, data) {
726
+ publish({
727
+ index: publishIndex++,
728
+ version,
729
+ messageId,
730
+ taskId,
731
+ data,
732
+ debugMethod,
733
+ priority: message.properties.priority,
734
+ debug: true
735
+ });
736
+ },
737
+ onDefer(reason) {
738
+ deferred = true;
739
+ deferredReason = reason || null;
740
+ return obfuscate(taskId, messageId, payload.options.uploadUrl ?? "", payload.options.streamUrl ?? "");
741
+ },
742
+ onCallback(params) {
743
+ publish({
744
+ index: 0,
745
+ version,
746
+ taskId,
747
+ messageId,
748
+ data: params.arg,
749
+ outputName: params.outputName,
750
+ connectionId: params.sourceId,
751
+ callbackId: params.callbackId,
752
+ propertyPath: params.propertyPath
753
+ });
754
+ }
755
+ });
756
+ await publish({
757
+ index: publishIndex++,
758
+ version,
759
+ messageId,
760
+ taskId,
761
+ priority: message.properties.priority,
762
+ begin: true
763
+ });
764
+ if (isMessageHandlerGenerator(messageHandler) && mode === "CONTINUOUS") {
765
+ channel.ack(message);
766
+ acked = true;
767
+ const generator = messageHandler(extendedContext);
768
+ const terminationPromise = Promise.withResolvers();
769
+ generatorTerminators.set(messageId, (reason) => {
770
+ terminated = true;
771
+ generator.return().catch((error) => {
772
+ if (terminated && error instanceof Error && error.name === "AbortError" && !(error instanceof AbortError)) {
773
+ return;
774
+ }
775
+ throw error;
776
+ });
777
+ terminationPromise.resolve(abortSymbol);
778
+ terminatePromise.resolve(reason);
779
+ });
780
+ await handlerStorage.run(extendedContext, async () => {
781
+ while (true) {
782
+ const nextPromise = Promise.resolve(generator.next()).then((r) => r, (error) => {
783
+ if (terminated && error instanceof Error && error.name === "AbortError" && !(error instanceof AbortError)) {
784
+ return { value: undefined, done: true };
785
+ }
786
+ throw error;
787
+ });
788
+ const next = await Promise.race([
789
+ terminationPromise.promise,
790
+ nextPromise
791
+ ]);
792
+ if (next === abortSymbol) {
793
+ break;
794
+ }
795
+ const { value: result, done } = next;
796
+ if (deferred) {
797
+ deferred = false;
798
+ console.warn("returning a value in a deferred message resets the deferred status");
799
+ }
800
+ const donePromise = Promise.withResolvers();
801
+ donePromises.push(donePromise.promise);
802
+ const { value, outputName } = await unwrapResult({
803
+ result,
804
+ options: payload.options,
805
+ onDone: donePromise.resolve,
806
+ onCallback: (callback) => {
807
+ const callbackId = crypto.randomUUID();
808
+ registeredCallbackIds.add(callbackId);
809
+ callbacks.set(callbackId, callback);
810
+ return {
811
+ sourceId: connectionId,
812
+ callbackId
813
+ };
814
+ }
815
+ });
816
+ if (!done || typeof value !== "undefined") {
817
+ publish({
818
+ index: publishIndex++,
819
+ version,
820
+ messageId,
821
+ taskId,
822
+ data: value,
823
+ priority: message.properties.priority,
824
+ outputName
825
+ });
826
+ }
827
+ if (done) {
828
+ break;
829
+ }
830
+ }
831
+ });
832
+ } else {
833
+ const result = await handlerStorage.run(extendedContext, () => messageHandler(extendedContext));
834
+ const donePromise = Promise.withResolvers();
835
+ donePromises.push(donePromise.promise);
836
+ const { value, outputName } = await unwrapResult({
837
+ result,
838
+ options: payload.options,
839
+ onDone: donePromise.resolve,
840
+ onCallback: () => {
841
+ throw new Error("callbacks can only be used in generator functions");
842
+ }
843
+ });
844
+ if (deferred && value) {
845
+ console.warn("returning a value in a deferred message resets the deferred status");
846
+ deferred = false;
847
+ }
848
+ if (!deferred || value) {
849
+ publish({
850
+ index: publishIndex++,
851
+ version,
852
+ messageId,
853
+ taskId,
854
+ data: value,
855
+ priority: message.properties.priority,
856
+ outputName
857
+ });
858
+ }
859
+ }
860
+ await new Promise((resolve2) => {
861
+ setImmediate(async () => {
862
+ if (!deferred) {
863
+ await Promise.allSettled(donePromises);
864
+ }
865
+ await publish({
866
+ index: publishIndex++,
867
+ version,
868
+ messageId,
869
+ taskId,
870
+ data: deferredReason,
871
+ priority: message.properties.priority,
872
+ deferred,
873
+ done: !deferred
874
+ });
875
+ if (!acked) {
876
+ channel.ack(message);
877
+ }
878
+ resolve2();
879
+ });
880
+ });
881
+ } catch (error) {
882
+ if (error instanceof SkipError) {
883
+ if (!acked) {
884
+ channel.nack(message);
885
+ }
886
+ return;
887
+ }
888
+ if (error instanceof RetryError) {
889
+ if (!acked) {
890
+ channel.ack(message);
891
+ }
892
+ const properties = {
893
+ ...message.properties,
894
+ expiration: error.delay || 1000
895
+ };
896
+ channel.publish(`${exchange}-retry`, version, message.content, properties);
897
+ return;
898
+ }
899
+ if (error instanceof AbortError && error.message.length > 0) {
900
+ if (!acked) {
901
+ channelWrapper.ack(message);
902
+ }
903
+ channelWrapper.publish(`${exchange}-retry`, "operator", error.message, {
904
+ ...message.properties,
905
+ contentType: "text/plain",
906
+ headers: {
907
+ ...message.properties.headers,
908
+ index: publishIndex++,
909
+ libVersion: "javascript@0.7.1",
910
+ abort: true
911
+ }
912
+ });
913
+ return;
914
+ }
915
+ if (terminated && error instanceof Error && error.name === "AbortError" && !(error instanceof AbortError)) {
916
+ if (!acked) {
917
+ channel.ack(message);
918
+ }
919
+ return;
920
+ }
921
+ if (error instanceof Error) {
922
+ if (!silent) {
923
+ console.error("Encountered an error inside service handler:");
924
+ console.error(error);
925
+ }
926
+ if (!acked) {
927
+ channel.ack(message);
928
+ }
929
+ channel.publish(`${exchange}-retry`, "operator", message.content, {
930
+ ...message.properties,
931
+ headers: {
932
+ ...message.properties.headers,
933
+ version,
934
+ exception: true,
935
+ index: publishIndex++,
936
+ libVersion: "javascript@0.7.1",
937
+ "error-message": error.message || "error in service handler"
938
+ }
939
+ });
940
+ return;
941
+ }
942
+ } finally {
943
+ generatorTerminators.delete(messageId);
944
+ registeredCallbackIds.forEach((id) => callbacks.delete(id));
945
+ resolveActiveMessage();
946
+ }
947
+ });
948
+ });
949
+ const activeMessageKeys = new Set;
950
+ const api = {
951
+ close: async () => {
952
+ await channelWrapper.close();
953
+ await connection.close();
954
+ },
955
+ open: () => connectedPromise.then(() => api),
956
+ async act(messageKey, actor) {
957
+ if (activeMessageKeys.has(messageKey)) {
958
+ throw new Error("a defer key can only be used once");
959
+ }
960
+ activeMessageKeys.add(messageKey);
961
+ let publishIndex = 0;
962
+ const { taskId, messageId, ...options } = messageKeySchema.parse(messageKey);
963
+ const activeMessage = async () => {
964
+ if (activeMessages.has(messageId)) {
965
+ await activeMessages.get(messageId);
966
+ }
967
+ };
968
+ const registeredCallbackIds = new Set;
969
+ const donePromises = [];
970
+ const sendApi = {
971
+ async sendToOutput(outputName, data) {
972
+ await activeMessage();
973
+ const donePromise = Promise.withResolvers();
974
+ donePromises.push(donePromise.promise);
975
+ donePromises.push(publish({
976
+ index: publishIndex++,
977
+ version,
978
+ messageId,
979
+ taskId,
980
+ data: await processData({
981
+ outputName,
982
+ data,
983
+ options,
984
+ onDone: donePromise.resolve,
985
+ onCallback: (callback) => {
986
+ const callbackId = crypto.randomUUID();
987
+ registeredCallbackIds.add(callbackId);
988
+ callbacks.set(callbackId, callback);
989
+ return {
990
+ sourceId: connectionId,
991
+ callbackId
992
+ };
993
+ }
994
+ }),
995
+ outputName
996
+ }));
997
+ },
998
+ async send(data) {
999
+ await activeMessage();
1000
+ const donePromise = Promise.withResolvers();
1001
+ donePromises.push(donePromise.promise);
1002
+ donePromises.push(publish({
1003
+ index: publishIndex++,
1004
+ version,
1005
+ messageId,
1006
+ taskId,
1007
+ data: await processData({
1008
+ outputName: null,
1009
+ data,
1010
+ options,
1011
+ onDone: donePromise.resolve,
1012
+ onCallback: (callback) => {
1013
+ const callbackId = crypto.randomUUID();
1014
+ registeredCallbackIds.add(callbackId);
1015
+ callbacks.set(callbackId, callback);
1016
+ return {
1017
+ sourceId: connectionId,
1018
+ callbackId
1019
+ };
1020
+ }
1021
+ })
1022
+ }));
1023
+ },
1024
+ async abort(error) {
1025
+ await activeMessage();
1026
+ channelWrapper.publish(`${exchange}-retry`, "operator", error instanceof Error ? error.message : error, {
1027
+ persistent: true,
1028
+ correlationId: messageId,
1029
+ expiration: 0,
1030
+ priority: 0,
1031
+ contentType: "text/plain",
1032
+ headers: {
1033
+ taskId,
1034
+ libVersion: "javascript@0.7.1",
1035
+ index: publishIndex++,
1036
+ abort: true
1037
+ }
1038
+ });
1039
+ }
1040
+ };
1041
+ const result = await actor(sendApi);
1042
+ if (result != null && typeof result === "object" && ((Symbol.asyncIterator in result) || (Symbol.iterator in result))) {
1043
+ const iterable = result;
1044
+ for await (const value of iterable) {
1045
+ if (value !== undefined) {
1046
+ await sendApi.send(value);
1047
+ }
1048
+ }
1049
+ } else if (result !== undefined) {
1050
+ await sendApi.send(result);
1051
+ }
1052
+ await new Promise((resolve2) => setImmediate(resolve2));
1053
+ await activeMessage();
1054
+ while (true) {
1055
+ const promiseCount = donePromises.length;
1056
+ await Promise.allSettled(donePromises);
1057
+ if (promiseCount === donePromises.length) {
1058
+ break;
1059
+ }
1060
+ }
1061
+ registeredCallbackIds.forEach((id) => callbacks.delete(id));
1062
+ await publish({
1063
+ index: publishIndex++,
1064
+ version,
1065
+ messageId,
1066
+ taskId,
1067
+ done: true
1068
+ });
1069
+ activeMessageKeys.delete(messageKey);
1070
+ }
1071
+ };
1072
+ return api;
1073
+ }
1074
+ // src/utils.ts
1075
+ function isAsyncIterable(iterable) {
1076
+ return typeof iterable[Symbol.asyncIterator] === "function";
1077
+ }
1078
+ function wrapIterable(iterable) {
1079
+ const context = handlerStorage.getStore();
1080
+ if (!context) {
1081
+ return iterable;
1082
+ }
1083
+ let terminated = false;
1084
+ context.terminated.then(() => {
1085
+ terminated = true;
1086
+ });
1087
+ if (isAsyncIterable(iterable)) {
1088
+ return {
1089
+ [Symbol.asyncIterator]() {
1090
+ const iterator = iterable[Symbol.asyncIterator]();
1091
+ return {
1092
+ async next() {
1093
+ const result = await Promise.race([
1094
+ context.terminated,
1095
+ iterator.next()
1096
+ ]);
1097
+ if (terminated) {
1098
+ return { done: true, value: undefined };
1099
+ }
1100
+ return result;
1101
+ }
1102
+ };
1103
+ }
1104
+ };
1105
+ }
1106
+ return {
1107
+ [Symbol.iterator]() {
1108
+ const iterator = iterable[Symbol.iterator]();
1109
+ return {
1110
+ next() {
1111
+ if (terminated) {
1112
+ return { done: true, value: undefined };
1113
+ }
1114
+ const result = iterator.next();
1115
+ return result;
1116
+ }
1117
+ };
1118
+ }
1119
+ };
1120
+ }
1121
+ function asyncEventEmitter(initial = []) {
1122
+ const context = handlerStorage.getStore();
1123
+ let terminated = false;
1124
+ context?.terminated.then(() => {
1125
+ terminated = true;
1126
+ });
1127
+ let resolve2;
1128
+ const initialValues = structuredClone(initial);
1129
+ return {
1130
+ push: (value) => {
1131
+ if (resolve2) {
1132
+ resolve2(value);
1133
+ } else {
1134
+ initialValues.push(value);
1135
+ }
1136
+ },
1137
+ [Symbol.asyncIterator]() {
1138
+ return {
1139
+ async next() {
1140
+ if (initialValues.length > 0) {
1141
+ return { value: initialValues.shift(), done: false };
1142
+ }
1143
+ const defer = Promise.withResolvers();
1144
+ resolve2 = defer.resolve;
1145
+ if (context) {
1146
+ const value = await Promise.race([
1147
+ defer.promise,
1148
+ context.terminated
1149
+ ]);
1150
+ return terminated ? { done: true, value: undefined } : { done: false, value };
1151
+ }
1152
+ return { value: await defer.promise, done: false };
1153
+ }
1154
+ };
1155
+ }
1156
+ };
1157
+ }
1158
+
1159
+ // src/index.ts
1160
+ var pkgJson;
1161
+ function loadPkgJson() {
1162
+ if (!pkgJson) {
1163
+ pkgJson = JSON.parse(fs.readFileSync("package.json", "utf-8"));
1164
+ }
1165
+ return pkgJson;
1166
+ }
1167
+ function createService(optionsOrVersion, optionalMessageHandler) {
1168
+ let options;
1169
+ let messageHandler;
1170
+ if (typeof optionsOrVersion === "string") {
1171
+ options = {
1172
+ version: optionsOrVersion
1173
+ };
1174
+ messageHandler = optionalMessageHandler;
1175
+ } else {
1176
+ options = optionsOrVersion;
1177
+ messageHandler = optionalMessageHandler;
1178
+ }
1179
+ let token = options.accessToken ?? process.env.REQUENCE_SERVICE_ACCESS_TOKEN ?? process.env.REQUENCE_ACCESS_TOKEN;
1180
+ if (!token) {
1181
+ try {
1182
+ const pkgJson2 = loadPkgJson();
1183
+ token = pkgJson2.requence?.service?.accessToken ?? pkgJson2.requence?.accessToken;
1184
+ } catch {}
1185
+ }
1186
+ let devToken = options.devToken ?? process.env.REQUENCE_SERVICE_DEV_TOKEN ?? process.env.REQUENCE_DEV_TOKEN;
1187
+ if (!devToken) {
1188
+ try {
1189
+ const pkgJson2 = loadPkgJson();
1190
+ devToken = pkgJson2.requence?.service?.devToken ?? pkgJson2.requence?.devToken;
1191
+ } catch {}
1192
+ }
1193
+ if (!token) {
1194
+ throw new Error("no access token provided");
1195
+ }
1196
+ const parts = deobfuscate(token);
1197
+ if (parts.length < 2 || parts[0] !== "service") {
1198
+ throw new Error("invalid access token");
1199
+ }
1200
+ const url = parts[1];
1201
+ let devOverlay;
1202
+ if (devToken) {
1203
+ const devParts = deobfuscate(devToken);
1204
+ if (devParts[0] !== "api") {
1205
+ throw new Error("invalid dev token: please provide a personal access token");
1206
+ }
1207
+ if (devParts[2] !== parts[2]) {
1208
+ throw new Error("invalid dev token: access token and dev token belong to different requence instances");
1209
+ }
1210
+ devOverlay = devParts[1];
1211
+ }
1212
+ return createConnection(connectionOptionsSchema.parse({
1213
+ ...options,
1214
+ url,
1215
+ devOverlay
1216
+ }), messageHandler);
1217
+ }
1218
+ export {
1219
+ wrapIterable,
1220
+ createService,
1221
+ createCallback,
1222
+ asyncEventEmitter,
1223
+ RequenceStream,
1224
+ RequenceFile,
1225
+ RequenceConnectionError
1226
+ };
1227
+
1228
+ //# debugId=DF5C6A6E1370BBD564756E2164756E21
1229
+ //# sourceMappingURL=index.js.map