@trigger.dev/sdk 3.2.2 → 3.3.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.
- package/dist/commonjs/v3/batch.d.ts +28 -0
- package/dist/commonjs/v3/batch.js +52 -0
- package/dist/commonjs/v3/batch.js.map +1 -0
- package/dist/commonjs/v3/index.d.ts +2 -1
- package/dist/commonjs/v3/index.js +1 -0
- package/dist/commonjs/v3/index.js.map +1 -1
- package/dist/commonjs/v3/runs.d.ts +102 -12
- package/dist/commonjs/v3/runs.js +93 -0
- package/dist/commonjs/v3/runs.js.map +1 -1
- package/dist/commonjs/v3/shared.d.ts +300 -8
- package/dist/commonjs/v3/shared.js +624 -98
- package/dist/commonjs/v3/shared.js.map +1 -1
- package/dist/commonjs/v3/tasks.d.ts +2 -2
- package/dist/commonjs/v3/tasks.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/v3/batch.d.ts +28 -0
- package/dist/esm/v3/batch.js +49 -0
- package/dist/esm/v3/batch.js.map +1 -0
- package/dist/esm/v3/index.d.ts +2 -1
- package/dist/esm/v3/index.js +1 -0
- package/dist/esm/v3/index.js.map +1 -1
- package/dist/esm/v3/runs.d.ts +102 -12
- package/dist/esm/v3/runs.js +93 -0
- package/dist/esm/v3/runs.js.map +1 -1
- package/dist/esm/v3/shared.d.ts +300 -8
- package/dist/esm/v3/shared.js +621 -99
- package/dist/esm/v3/shared.js.map +1 -1
- package/dist/esm/v3/tasks.d.ts +2 -2
- package/dist/esm/v3/tasks.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +2 -2
package/dist/esm/v3/shared.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SpanKind } from "@opentelemetry/api";
|
|
2
|
-
import {
|
|
3
|
-
import { accessoryAttributes, apiClientManager, conditionallyImportPacket, convertToolParametersToSchema, createErrorTaskError, defaultRetryOptions, getSchemaParseFn, logger, makeIdempotencyKey, parsePacket, runtime, SemanticInternalAttributes, stringifyIO, SubtaskUnwrapError, taskCatalog, taskContext, TaskRunPromise, } from "@trigger.dev/core/v3";
|
|
2
|
+
import { accessoryAttributes, apiClientManager, conditionallyImportPacket, convertToolParametersToSchema, createErrorTaskError, defaultRetryOptions, getSchemaParseFn, makeIdempotencyKey, parsePacket, runtime, SemanticInternalAttributes, stringifyIO, SubtaskUnwrapError, taskCatalog, taskContext, TaskRunPromise, } from "@trigger.dev/core/v3";
|
|
4
3
|
import { runs } from "./runs.js";
|
|
5
4
|
import { tracer } from "./tracer.js";
|
|
6
5
|
export { SubtaskUnwrapError, TaskRunPromise };
|
|
@@ -26,11 +25,11 @@ export function createTask(params) {
|
|
|
26
25
|
...options,
|
|
27
26
|
});
|
|
28
27
|
},
|
|
29
|
-
batchTrigger: async (items) => {
|
|
28
|
+
batchTrigger: async (items, options) => {
|
|
30
29
|
const taskMetadata = taskCatalog.getTaskManifest(params.id);
|
|
31
30
|
return await batchTrigger_internal(taskMetadata && taskMetadata.exportName
|
|
32
31
|
? `${taskMetadata.exportName}.batchTrigger()`
|
|
33
|
-
: `batchTrigger()`, params.id, items, undefined, undefined, customQueue);
|
|
32
|
+
: `batchTrigger()`, params.id, items, options, undefined, undefined, customQueue);
|
|
34
33
|
},
|
|
35
34
|
triggerAndWait: (payload, options) => {
|
|
36
35
|
const taskMetadata = taskCatalog.getTaskManifest(params.id);
|
|
@@ -117,11 +116,11 @@ export function createSchemaTask(params) {
|
|
|
117
116
|
...options,
|
|
118
117
|
}, requestOptions);
|
|
119
118
|
},
|
|
120
|
-
batchTrigger: async (items, requestOptions) => {
|
|
119
|
+
batchTrigger: async (items, options, requestOptions) => {
|
|
121
120
|
const taskMetadata = taskCatalog.getTaskManifest(params.id);
|
|
122
121
|
return await batchTrigger_internal(taskMetadata && taskMetadata.exportName
|
|
123
122
|
? `${taskMetadata.exportName}.batchTrigger()`
|
|
124
|
-
: `batchTrigger()`, params.id, items, parsePayload, requestOptions, customQueue);
|
|
123
|
+
: `batchTrigger()`, params.id, items, options, parsePayload, requestOptions, customQueue);
|
|
125
124
|
},
|
|
126
125
|
triggerAndWait: (payload, options) => {
|
|
127
126
|
const taskMetadata = taskCatalog.getTaskManifest(params.id);
|
|
@@ -264,8 +263,546 @@ export async function triggerAndPoll(id, payload, options, requestOptions) {
|
|
|
264
263
|
const handle = await trigger(id, payload, options, requestOptions);
|
|
265
264
|
return runs.poll(handle, options, requestOptions);
|
|
266
265
|
}
|
|
267
|
-
export async function batchTrigger(id, items, requestOptions) {
|
|
268
|
-
return await batchTrigger_internal("tasks.batchTrigger()", id, items, undefined, requestOptions);
|
|
266
|
+
export async function batchTrigger(id, items, options, requestOptions) {
|
|
267
|
+
return await batchTrigger_internal("tasks.batchTrigger()", id, items, options, undefined, requestOptions);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Triggers multiple runs of different tasks with specified payloads and options.
|
|
271
|
+
*
|
|
272
|
+
* @template TTask - The type of task(s) to be triggered, extends AnyTask
|
|
273
|
+
*
|
|
274
|
+
* @param {Array<BatchByIdItem<InferRunTypes<TTask>>>} items - Array of task items to trigger
|
|
275
|
+
* @param {BatchTriggerOptions} [options] - Optional batch-level trigger options
|
|
276
|
+
* @param {TriggerApiRequestOptions} [requestOptions] - Optional API request configuration
|
|
277
|
+
*
|
|
278
|
+
* @returns {Promise<BatchRunHandleFromTypes<InferRunTypes<TTask>>>} A promise that resolves with the batch run handle
|
|
279
|
+
* containing batch ID, cached status, idempotency info, runs, and public access token
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```ts
|
|
283
|
+
* import { batch } from "@trigger.dev/sdk/v3";
|
|
284
|
+
* import type { myTask1, myTask2 } from "~/trigger/myTasks";
|
|
285
|
+
*
|
|
286
|
+
* // Trigger multiple tasks with different payloads
|
|
287
|
+
* const result = await batch.trigger<typeof myTask1 | typeof myTask2>([
|
|
288
|
+
* {
|
|
289
|
+
* id: "my-task-1",
|
|
290
|
+
* payload: { some: "data" },
|
|
291
|
+
* options: {
|
|
292
|
+
* queue: "default",
|
|
293
|
+
* concurrencyKey: "key",
|
|
294
|
+
* idempotencyKey: "unique-key",
|
|
295
|
+
* delay: "5m",
|
|
296
|
+
* tags: ["tag1", "tag2"]
|
|
297
|
+
* }
|
|
298
|
+
* },
|
|
299
|
+
* {
|
|
300
|
+
* id: "my-task-2",
|
|
301
|
+
* payload: { other: "data" }
|
|
302
|
+
* }
|
|
303
|
+
* ]);
|
|
304
|
+
* ```
|
|
305
|
+
*
|
|
306
|
+
* @description
|
|
307
|
+
* Each task item in the array can include:
|
|
308
|
+
* - `id`: The unique identifier of the task
|
|
309
|
+
* - `payload`: The data to pass to the task
|
|
310
|
+
* - `options`: Optional task-specific settings including:
|
|
311
|
+
* - `queue`: Specify a queue for the task
|
|
312
|
+
* - `concurrencyKey`: Control concurrent execution
|
|
313
|
+
* - `idempotencyKey`: Prevent duplicate runs
|
|
314
|
+
* - `idempotencyKeyTTL`: Time-to-live for idempotency key
|
|
315
|
+
* - `delay`: Delay before task execution
|
|
316
|
+
* - `ttl`: Time-to-live for the task
|
|
317
|
+
* - `tags`: Array of tags for the task
|
|
318
|
+
* - `maxAttempts`: Maximum retry attempts
|
|
319
|
+
* - `metadata`: Additional metadata
|
|
320
|
+
* - `maxDuration`: Maximum execution duration
|
|
321
|
+
*/
|
|
322
|
+
export async function batchTriggerById(items, options, requestOptions) {
|
|
323
|
+
const apiClient = apiClientManager.clientOrThrow();
|
|
324
|
+
const response = await apiClient.batchTriggerV2({
|
|
325
|
+
items: await Promise.all(items.map(async (item) => {
|
|
326
|
+
const taskMetadata = taskCatalog.getTask(item.id);
|
|
327
|
+
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
328
|
+
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
329
|
+
: item.payload;
|
|
330
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
331
|
+
return {
|
|
332
|
+
task: item.id,
|
|
333
|
+
payload: payloadPacket.data,
|
|
334
|
+
options: {
|
|
335
|
+
queue: item.options?.queue,
|
|
336
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
337
|
+
test: taskContext.ctx?.run.isTest,
|
|
338
|
+
payloadType: payloadPacket.dataType,
|
|
339
|
+
idempotencyKey: await makeIdempotencyKey(item.options?.idempotencyKey),
|
|
340
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL,
|
|
341
|
+
delay: item.options?.delay,
|
|
342
|
+
ttl: item.options?.ttl,
|
|
343
|
+
tags: item.options?.tags,
|
|
344
|
+
maxAttempts: item.options?.maxAttempts,
|
|
345
|
+
parentAttempt: taskContext.ctx?.attempt.id,
|
|
346
|
+
metadata: item.options?.metadata,
|
|
347
|
+
maxDuration: item.options?.maxDuration,
|
|
348
|
+
},
|
|
349
|
+
};
|
|
350
|
+
})),
|
|
351
|
+
}, {
|
|
352
|
+
spanParentAsLink: true,
|
|
353
|
+
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
354
|
+
idempotencyKeyTTL: options?.idempotencyKeyTTL,
|
|
355
|
+
}, {
|
|
356
|
+
name: "batch.trigger()",
|
|
357
|
+
tracer,
|
|
358
|
+
icon: "trigger",
|
|
359
|
+
onResponseBody(body, span) {
|
|
360
|
+
if (body && typeof body === "object" && !Array.isArray(body)) {
|
|
361
|
+
if ("id" in body && typeof body.id === "string") {
|
|
362
|
+
span.setAttribute("batchId", body.id);
|
|
363
|
+
}
|
|
364
|
+
if ("runs" in body && Array.isArray(body.runs)) {
|
|
365
|
+
span.setAttribute("runCount", body.runs.length);
|
|
366
|
+
}
|
|
367
|
+
if ("isCached" in body && typeof body.isCached === "boolean") {
|
|
368
|
+
if (body.isCached) {
|
|
369
|
+
console.warn(`Result is a cached response because the request was idempotent.`);
|
|
370
|
+
}
|
|
371
|
+
span.setAttribute("isCached", body.isCached);
|
|
372
|
+
}
|
|
373
|
+
if ("idempotencyKey" in body && typeof body.idempotencyKey === "string") {
|
|
374
|
+
span.setAttribute("idempotencyKey", body.idempotencyKey);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
...requestOptions,
|
|
379
|
+
});
|
|
380
|
+
const handle = {
|
|
381
|
+
batchId: response.id,
|
|
382
|
+
isCached: response.isCached,
|
|
383
|
+
idempotencyKey: response.idempotencyKey,
|
|
384
|
+
runs: response.runs,
|
|
385
|
+
publicAccessToken: response.publicAccessToken,
|
|
386
|
+
};
|
|
387
|
+
return handle;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Triggers multiple tasks and waits for all of them to complete before returning their results.
|
|
391
|
+
* This function must be called from within a task.run() context.
|
|
392
|
+
*
|
|
393
|
+
* @template TTask - Union type of tasks to be triggered, extends AnyTask
|
|
394
|
+
*
|
|
395
|
+
* @param {Array<BatchByIdAndWaitItem<InferRunTypes<TTask>>>} items - Array of task items to trigger
|
|
396
|
+
* @param {TriggerApiRequestOptions} [requestOptions] - Optional API request configuration
|
|
397
|
+
*
|
|
398
|
+
* @returns {Promise<BatchByIdResult<TTask>>} A promise that resolves with the batch results, including
|
|
399
|
+
* success/failure status and strongly-typed outputs for each task
|
|
400
|
+
*
|
|
401
|
+
* @throws {Error} If called outside of a task.run() context
|
|
402
|
+
* @throws {Error} If no API client is configured
|
|
403
|
+
*
|
|
404
|
+
* @example
|
|
405
|
+
* ```ts
|
|
406
|
+
* import { batch, task } from "@trigger.dev/sdk/v3";
|
|
407
|
+
*
|
|
408
|
+
* export const parentTask = task({
|
|
409
|
+
* id: "parent-task",
|
|
410
|
+
* run: async (payload: string) => {
|
|
411
|
+
* const results = await batch.triggerAndWait<typeof childTask1 | typeof childTask2>([
|
|
412
|
+
* {
|
|
413
|
+
* id: "child-task-1",
|
|
414
|
+
* payload: { foo: "World" },
|
|
415
|
+
* options: {
|
|
416
|
+
* queue: "default",
|
|
417
|
+
* delay: "5m",
|
|
418
|
+
* tags: ["batch", "child1"]
|
|
419
|
+
* }
|
|
420
|
+
* },
|
|
421
|
+
* {
|
|
422
|
+
* id: "child-task-2",
|
|
423
|
+
* payload: { bar: 42 }
|
|
424
|
+
* }
|
|
425
|
+
* ]);
|
|
426
|
+
*
|
|
427
|
+
* // Type-safe result handling
|
|
428
|
+
* for (const result of results) {
|
|
429
|
+
* if (result.ok) {
|
|
430
|
+
* switch (result.taskIdentifier) {
|
|
431
|
+
* case "child-task-1":
|
|
432
|
+
* console.log("Child task 1 output:", result.output); // string type
|
|
433
|
+
* break;
|
|
434
|
+
* case "child-task-2":
|
|
435
|
+
* console.log("Child task 2 output:", result.output); // number type
|
|
436
|
+
* break;
|
|
437
|
+
* }
|
|
438
|
+
* } else {
|
|
439
|
+
* console.error("Task failed:", result.error);
|
|
440
|
+
* }
|
|
441
|
+
* }
|
|
442
|
+
* }
|
|
443
|
+
* });
|
|
444
|
+
* ```
|
|
445
|
+
*
|
|
446
|
+
* @description
|
|
447
|
+
* Each task item in the array can include:
|
|
448
|
+
* - `id`: The task identifier (must match one of the tasks in the union type)
|
|
449
|
+
* - `payload`: Strongly-typed payload matching the task's input type
|
|
450
|
+
* - `options`: Optional task-specific settings including:
|
|
451
|
+
* - `queue`: Specify a queue for the task
|
|
452
|
+
* - `concurrencyKey`: Control concurrent execution
|
|
453
|
+
* - `delay`: Delay before task execution
|
|
454
|
+
* - `ttl`: Time-to-live for the task
|
|
455
|
+
* - `tags`: Array of tags for the task
|
|
456
|
+
* - `maxAttempts`: Maximum retry attempts
|
|
457
|
+
* - `metadata`: Additional metadata
|
|
458
|
+
* - `maxDuration`: Maximum execution duration
|
|
459
|
+
*
|
|
460
|
+
* The function provides full type safety for:
|
|
461
|
+
* - Task IDs
|
|
462
|
+
* - Payload types
|
|
463
|
+
* - Return value types
|
|
464
|
+
* - Error handling
|
|
465
|
+
*/
|
|
466
|
+
export async function batchTriggerByIdAndWait(items, requestOptions) {
|
|
467
|
+
const ctx = taskContext.ctx;
|
|
468
|
+
if (!ctx) {
|
|
469
|
+
throw new Error("batchTriggerAndWait can only be used from inside a task.run()");
|
|
470
|
+
}
|
|
471
|
+
const apiClient = apiClientManager.clientOrThrow();
|
|
472
|
+
return await tracer.startActiveSpan("batch.triggerAndWait()", async (span) => {
|
|
473
|
+
const response = await apiClient.batchTriggerV2({
|
|
474
|
+
items: await Promise.all(items.map(async (item) => {
|
|
475
|
+
const taskMetadata = taskCatalog.getTask(item.id);
|
|
476
|
+
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
477
|
+
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
478
|
+
: item.payload;
|
|
479
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
480
|
+
return {
|
|
481
|
+
task: item.id,
|
|
482
|
+
payload: payloadPacket.data,
|
|
483
|
+
options: {
|
|
484
|
+
lockToVersion: taskContext.worker?.version,
|
|
485
|
+
queue: item.options?.queue,
|
|
486
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
487
|
+
test: taskContext.ctx?.run.isTest,
|
|
488
|
+
payloadType: payloadPacket.dataType,
|
|
489
|
+
delay: item.options?.delay,
|
|
490
|
+
ttl: item.options?.ttl,
|
|
491
|
+
tags: item.options?.tags,
|
|
492
|
+
maxAttempts: item.options?.maxAttempts,
|
|
493
|
+
metadata: item.options?.metadata,
|
|
494
|
+
maxDuration: item.options?.maxDuration,
|
|
495
|
+
},
|
|
496
|
+
};
|
|
497
|
+
})),
|
|
498
|
+
dependentAttempt: ctx.attempt.id,
|
|
499
|
+
}, {}, requestOptions);
|
|
500
|
+
span.setAttribute("batchId", response.id);
|
|
501
|
+
span.setAttribute("runCount", response.runs.length);
|
|
502
|
+
span.setAttribute("isCached", response.isCached);
|
|
503
|
+
if (response.isCached) {
|
|
504
|
+
console.warn(`Result is a cached response because the request was idempotent.`);
|
|
505
|
+
}
|
|
506
|
+
if (response.idempotencyKey) {
|
|
507
|
+
span.setAttribute("idempotencyKey", response.idempotencyKey);
|
|
508
|
+
}
|
|
509
|
+
const result = await runtime.waitForBatch({
|
|
510
|
+
id: response.id,
|
|
511
|
+
runs: response.runs.map((run) => run.id),
|
|
512
|
+
ctx,
|
|
513
|
+
});
|
|
514
|
+
const runs = await handleBatchTaskRunExecutionResultV2(result.items);
|
|
515
|
+
return {
|
|
516
|
+
id: result.id,
|
|
517
|
+
runs,
|
|
518
|
+
};
|
|
519
|
+
}, {
|
|
520
|
+
kind: SpanKind.PRODUCER,
|
|
521
|
+
attributes: {
|
|
522
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
523
|
+
},
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Triggers multiple tasks and waits for all of them to complete before returning their results.
|
|
528
|
+
* This function must be called from within a task.run() context.
|
|
529
|
+
*
|
|
530
|
+
* @template TTask - Union type of tasks to be triggered, extends AnyTask
|
|
531
|
+
*
|
|
532
|
+
* @param {Array<BatchByIdAndWaitItem<InferRunTypes<TTask>>>} items - Array of task items to trigger
|
|
533
|
+
* @param {TriggerApiRequestOptions} [requestOptions] - Optional API request configuration
|
|
534
|
+
*
|
|
535
|
+
* @returns {Promise<BatchByIdResult<TTask>>} A promise that resolves with the batch results, including
|
|
536
|
+
* success/failure status and strongly-typed outputs for each task
|
|
537
|
+
*
|
|
538
|
+
* @throws {Error} If called outside of a task.run() context
|
|
539
|
+
* @throws {Error} If no API client is configured
|
|
540
|
+
*
|
|
541
|
+
* @example
|
|
542
|
+
* ```ts
|
|
543
|
+
* import { batch, task } from "@trigger.dev/sdk/v3";
|
|
544
|
+
*
|
|
545
|
+
* export const parentTask = task({
|
|
546
|
+
* id: "parent-task",
|
|
547
|
+
* run: async (payload: string) => {
|
|
548
|
+
* const results = await batch.triggerAndWait<typeof childTask1 | typeof childTask2>([
|
|
549
|
+
* {
|
|
550
|
+
* id: "child-task-1",
|
|
551
|
+
* payload: { foo: "World" },
|
|
552
|
+
* options: {
|
|
553
|
+
* queue: "default",
|
|
554
|
+
* delay: "5m",
|
|
555
|
+
* tags: ["batch", "child1"]
|
|
556
|
+
* }
|
|
557
|
+
* },
|
|
558
|
+
* {
|
|
559
|
+
* id: "child-task-2",
|
|
560
|
+
* payload: { bar: 42 }
|
|
561
|
+
* }
|
|
562
|
+
* ]);
|
|
563
|
+
*
|
|
564
|
+
* // Type-safe result handling
|
|
565
|
+
* for (const result of results) {
|
|
566
|
+
* if (result.ok) {
|
|
567
|
+
* switch (result.taskIdentifier) {
|
|
568
|
+
* case "child-task-1":
|
|
569
|
+
* console.log("Child task 1 output:", result.output); // string type
|
|
570
|
+
* break;
|
|
571
|
+
* case "child-task-2":
|
|
572
|
+
* console.log("Child task 2 output:", result.output); // number type
|
|
573
|
+
* break;
|
|
574
|
+
* }
|
|
575
|
+
* } else {
|
|
576
|
+
* console.error("Task failed:", result.error);
|
|
577
|
+
* }
|
|
578
|
+
* }
|
|
579
|
+
* }
|
|
580
|
+
* });
|
|
581
|
+
* ```
|
|
582
|
+
*
|
|
583
|
+
* @description
|
|
584
|
+
* Each task item in the array can include:
|
|
585
|
+
* - `id`: The task identifier (must match one of the tasks in the union type)
|
|
586
|
+
* - `payload`: Strongly-typed payload matching the task's input type
|
|
587
|
+
* - `options`: Optional task-specific settings including:
|
|
588
|
+
* - `queue`: Specify a queue for the task
|
|
589
|
+
* - `concurrencyKey`: Control concurrent execution
|
|
590
|
+
* - `delay`: Delay before task execution
|
|
591
|
+
* - `ttl`: Time-to-live for the task
|
|
592
|
+
* - `tags`: Array of tags for the task
|
|
593
|
+
* - `maxAttempts`: Maximum retry attempts
|
|
594
|
+
* - `metadata`: Additional metadata
|
|
595
|
+
* - `maxDuration`: Maximum execution duration
|
|
596
|
+
*
|
|
597
|
+
* The function provides full type safety for:
|
|
598
|
+
* - Task IDs
|
|
599
|
+
* - Payload types
|
|
600
|
+
* - Return value types
|
|
601
|
+
* - Error handling
|
|
602
|
+
*/
|
|
603
|
+
export async function batchTriggerTasks(items, options, requestOptions) {
|
|
604
|
+
const apiClient = apiClientManager.clientOrThrow();
|
|
605
|
+
const response = await apiClient.batchTriggerV2({
|
|
606
|
+
items: await Promise.all(items.map(async (item) => {
|
|
607
|
+
const taskMetadata = taskCatalog.getTask(item.task.id);
|
|
608
|
+
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
609
|
+
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
610
|
+
: item.payload;
|
|
611
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
612
|
+
return {
|
|
613
|
+
task: item.task.id,
|
|
614
|
+
payload: payloadPacket.data,
|
|
615
|
+
options: {
|
|
616
|
+
queue: item.options?.queue,
|
|
617
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
618
|
+
test: taskContext.ctx?.run.isTest,
|
|
619
|
+
payloadType: payloadPacket.dataType,
|
|
620
|
+
idempotencyKey: await makeIdempotencyKey(item.options?.idempotencyKey),
|
|
621
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL,
|
|
622
|
+
delay: item.options?.delay,
|
|
623
|
+
ttl: item.options?.ttl,
|
|
624
|
+
tags: item.options?.tags,
|
|
625
|
+
maxAttempts: item.options?.maxAttempts,
|
|
626
|
+
parentAttempt: taskContext.ctx?.attempt.id,
|
|
627
|
+
metadata: item.options?.metadata,
|
|
628
|
+
maxDuration: item.options?.maxDuration,
|
|
629
|
+
},
|
|
630
|
+
};
|
|
631
|
+
})),
|
|
632
|
+
}, {
|
|
633
|
+
spanParentAsLink: true,
|
|
634
|
+
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
635
|
+
idempotencyKeyTTL: options?.idempotencyKeyTTL,
|
|
636
|
+
}, {
|
|
637
|
+
name: "batch.triggerByTask()",
|
|
638
|
+
tracer,
|
|
639
|
+
icon: "trigger",
|
|
640
|
+
onResponseBody(body, span) {
|
|
641
|
+
if (body && typeof body === "object" && !Array.isArray(body)) {
|
|
642
|
+
if ("id" in body && typeof body.id === "string") {
|
|
643
|
+
span.setAttribute("batchId", body.id);
|
|
644
|
+
}
|
|
645
|
+
if ("runs" in body && Array.isArray(body.runs)) {
|
|
646
|
+
span.setAttribute("runCount", body.runs.length);
|
|
647
|
+
}
|
|
648
|
+
if ("isCached" in body && typeof body.isCached === "boolean") {
|
|
649
|
+
if (body.isCached) {
|
|
650
|
+
console.warn(`Result is a cached response because the request was idempotent.`);
|
|
651
|
+
}
|
|
652
|
+
span.setAttribute("isCached", body.isCached);
|
|
653
|
+
}
|
|
654
|
+
if ("idempotencyKey" in body && typeof body.idempotencyKey === "string") {
|
|
655
|
+
span.setAttribute("idempotencyKey", body.idempotencyKey);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
},
|
|
659
|
+
...requestOptions,
|
|
660
|
+
});
|
|
661
|
+
const handle = {
|
|
662
|
+
batchId: response.id,
|
|
663
|
+
isCached: response.isCached,
|
|
664
|
+
idempotencyKey: response.idempotencyKey,
|
|
665
|
+
runs: response.runs,
|
|
666
|
+
publicAccessToken: response.publicAccessToken,
|
|
667
|
+
};
|
|
668
|
+
return handle;
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Triggers multiple tasks and waits for all of them to complete before returning their results.
|
|
672
|
+
* This function must be called from within a task.run() context.
|
|
673
|
+
*
|
|
674
|
+
* @template TTask - Union type of tasks to be triggered, extends AnyTask
|
|
675
|
+
*
|
|
676
|
+
* @param {Array<BatchByIdAndWaitItem<InferRunTypes<TTask>>>} items - Array of task items to trigger
|
|
677
|
+
* @param {TriggerApiRequestOptions} [requestOptions] - Optional API request configuration
|
|
678
|
+
*
|
|
679
|
+
* @returns {Promise<BatchByIdResult<TTask>>} A promise that resolves with the batch results, including
|
|
680
|
+
* success/failure status and strongly-typed outputs for each task
|
|
681
|
+
*
|
|
682
|
+
* @throws {Error} If called outside of a task.run() context
|
|
683
|
+
* @throws {Error} If no API client is configured
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* ```ts
|
|
687
|
+
* import { batch, task } from "@trigger.dev/sdk/v3";
|
|
688
|
+
*
|
|
689
|
+
* export const parentTask = task({
|
|
690
|
+
* id: "parent-task",
|
|
691
|
+
* run: async (payload: string) => {
|
|
692
|
+
* const results = await batch.triggerAndWait<typeof childTask1 | typeof childTask2>([
|
|
693
|
+
* {
|
|
694
|
+
* id: "child-task-1",
|
|
695
|
+
* payload: { foo: "World" },
|
|
696
|
+
* options: {
|
|
697
|
+
* queue: "default",
|
|
698
|
+
* delay: "5m",
|
|
699
|
+
* tags: ["batch", "child1"]
|
|
700
|
+
* }
|
|
701
|
+
* },
|
|
702
|
+
* {
|
|
703
|
+
* id: "child-task-2",
|
|
704
|
+
* payload: { bar: 42 }
|
|
705
|
+
* }
|
|
706
|
+
* ]);
|
|
707
|
+
*
|
|
708
|
+
* // Type-safe result handling
|
|
709
|
+
* for (const result of results) {
|
|
710
|
+
* if (result.ok) {
|
|
711
|
+
* switch (result.taskIdentifier) {
|
|
712
|
+
* case "child-task-1":
|
|
713
|
+
* console.log("Child task 1 output:", result.output); // string type
|
|
714
|
+
* break;
|
|
715
|
+
* case "child-task-2":
|
|
716
|
+
* console.log("Child task 2 output:", result.output); // number type
|
|
717
|
+
* break;
|
|
718
|
+
* }
|
|
719
|
+
* } else {
|
|
720
|
+
* console.error("Task failed:", result.error);
|
|
721
|
+
* }
|
|
722
|
+
* }
|
|
723
|
+
* }
|
|
724
|
+
* });
|
|
725
|
+
* ```
|
|
726
|
+
*
|
|
727
|
+
* @description
|
|
728
|
+
* Each task item in the array can include:
|
|
729
|
+
* - `id`: The task identifier (must match one of the tasks in the union type)
|
|
730
|
+
* - `payload`: Strongly-typed payload matching the task's input type
|
|
731
|
+
* - `options`: Optional task-specific settings including:
|
|
732
|
+
* - `queue`: Specify a queue for the task
|
|
733
|
+
* - `concurrencyKey`: Control concurrent execution
|
|
734
|
+
* - `delay`: Delay before task execution
|
|
735
|
+
* - `ttl`: Time-to-live for the task
|
|
736
|
+
* - `tags`: Array of tags for the task
|
|
737
|
+
* - `maxAttempts`: Maximum retry attempts
|
|
738
|
+
* - `metadata`: Additional metadata
|
|
739
|
+
* - `maxDuration`: Maximum execution duration
|
|
740
|
+
*
|
|
741
|
+
* The function provides full type safety for:
|
|
742
|
+
* - Task IDs
|
|
743
|
+
* - Payload types
|
|
744
|
+
* - Return value types
|
|
745
|
+
* - Error handling
|
|
746
|
+
*/
|
|
747
|
+
export async function batchTriggerAndWaitTasks(items, requestOptions) {
|
|
748
|
+
const ctx = taskContext.ctx;
|
|
749
|
+
if (!ctx) {
|
|
750
|
+
throw new Error("batchTriggerAndWait can only be used from inside a task.run()");
|
|
751
|
+
}
|
|
752
|
+
const apiClient = apiClientManager.clientOrThrow();
|
|
753
|
+
return await tracer.startActiveSpan("batch.triggerByTaskAndWait()", async (span) => {
|
|
754
|
+
const response = await apiClient.batchTriggerV2({
|
|
755
|
+
items: await Promise.all(items.map(async (item) => {
|
|
756
|
+
const taskMetadata = taskCatalog.getTask(item.task.id);
|
|
757
|
+
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
758
|
+
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
759
|
+
: item.payload;
|
|
760
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
761
|
+
return {
|
|
762
|
+
task: item.task.id,
|
|
763
|
+
payload: payloadPacket.data,
|
|
764
|
+
options: {
|
|
765
|
+
lockToVersion: taskContext.worker?.version,
|
|
766
|
+
queue: item.options?.queue,
|
|
767
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
768
|
+
test: taskContext.ctx?.run.isTest,
|
|
769
|
+
payloadType: payloadPacket.dataType,
|
|
770
|
+
delay: item.options?.delay,
|
|
771
|
+
ttl: item.options?.ttl,
|
|
772
|
+
tags: item.options?.tags,
|
|
773
|
+
maxAttempts: item.options?.maxAttempts,
|
|
774
|
+
metadata: item.options?.metadata,
|
|
775
|
+
maxDuration: item.options?.maxDuration,
|
|
776
|
+
},
|
|
777
|
+
};
|
|
778
|
+
})),
|
|
779
|
+
dependentAttempt: ctx.attempt.id,
|
|
780
|
+
}, {}, requestOptions);
|
|
781
|
+
span.setAttribute("batchId", response.id);
|
|
782
|
+
span.setAttribute("runCount", response.runs.length);
|
|
783
|
+
span.setAttribute("isCached", response.isCached);
|
|
784
|
+
if (response.isCached) {
|
|
785
|
+
console.warn(`Result is a cached response because the request was idempotent.`);
|
|
786
|
+
}
|
|
787
|
+
if (response.idempotencyKey) {
|
|
788
|
+
span.setAttribute("idempotencyKey", response.idempotencyKey);
|
|
789
|
+
}
|
|
790
|
+
const result = await runtime.waitForBatch({
|
|
791
|
+
id: response.id,
|
|
792
|
+
runs: response.runs.map((run) => run.id),
|
|
793
|
+
ctx,
|
|
794
|
+
});
|
|
795
|
+
const runs = await handleBatchTaskRunExecutionResultV2(result.items);
|
|
796
|
+
return {
|
|
797
|
+
id: result.id,
|
|
798
|
+
runs,
|
|
799
|
+
};
|
|
800
|
+
}, {
|
|
801
|
+
kind: SpanKind.PRODUCER,
|
|
802
|
+
attributes: {
|
|
803
|
+
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
804
|
+
},
|
|
805
|
+
});
|
|
269
806
|
}
|
|
270
807
|
async function trigger_internal(name, id, payload, parsePayload, options, requestOptions) {
|
|
271
808
|
const apiClient = apiClientManager.clientOrThrow();
|
|
@@ -279,6 +816,7 @@ async function trigger_internal(name, id, payload, parsePayload, options, reques
|
|
|
279
816
|
test: taskContext.ctx?.run.isTest,
|
|
280
817
|
payloadType: payloadPacket.dataType,
|
|
281
818
|
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
819
|
+
idempotencyKeyTTL: options?.idempotencyKeyTTL,
|
|
282
820
|
delay: options?.delay,
|
|
283
821
|
ttl: options?.ttl,
|
|
284
822
|
tags: options?.tags,
|
|
@@ -293,30 +831,25 @@ async function trigger_internal(name, id, payload, parsePayload, options, reques
|
|
|
293
831
|
name,
|
|
294
832
|
tracer,
|
|
295
833
|
icon: "trigger",
|
|
296
|
-
attributes: {
|
|
297
|
-
[SEMATTRS_MESSAGING_OPERATION]: "publish",
|
|
298
|
-
["messaging.client_id"]: taskContext.worker?.id,
|
|
299
|
-
[SEMATTRS_MESSAGING_SYSTEM]: "trigger.dev",
|
|
300
|
-
},
|
|
301
834
|
onResponseBody: (body, span) => {
|
|
302
|
-
body &&
|
|
303
|
-
typeof body === "
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
span.setAttribute("messaging.message.id", body.id);
|
|
835
|
+
if (body && typeof body === "object" && !Array.isArray(body)) {
|
|
836
|
+
if ("id" in body && typeof body.id === "string") {
|
|
837
|
+
span.setAttribute("runId", body.id);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
308
840
|
},
|
|
309
841
|
...requestOptions,
|
|
310
842
|
});
|
|
311
843
|
return handle;
|
|
312
844
|
}
|
|
313
|
-
async function batchTrigger_internal(name,
|
|
845
|
+
async function batchTrigger_internal(name, taskIdentifier, items, options, parsePayload, requestOptions, queue) {
|
|
314
846
|
const apiClient = apiClientManager.clientOrThrow();
|
|
315
|
-
const response = await apiClient.
|
|
847
|
+
const response = await apiClient.batchTriggerV2({
|
|
316
848
|
items: await Promise.all(items.map(async (item) => {
|
|
317
849
|
const parsedPayload = parsePayload ? await parsePayload(item.payload) : item.payload;
|
|
318
850
|
const payloadPacket = await stringifyIO(parsedPayload);
|
|
319
851
|
return {
|
|
852
|
+
task: taskIdentifier,
|
|
320
853
|
payload: payloadPacket.data,
|
|
321
854
|
options: {
|
|
322
855
|
queue: item.options?.queue ?? queue,
|
|
@@ -324,6 +857,7 @@ async function batchTrigger_internal(name, id, items, parsePayload, requestOptio
|
|
|
324
857
|
test: taskContext.ctx?.run.isTest,
|
|
325
858
|
payloadType: payloadPacket.dataType,
|
|
326
859
|
idempotencyKey: await makeIdempotencyKey(item.options?.idempotencyKey),
|
|
860
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL,
|
|
327
861
|
delay: item.options?.delay,
|
|
328
862
|
ttl: item.options?.ttl,
|
|
329
863
|
tags: item.options?.tags,
|
|
@@ -334,20 +868,40 @@ async function batchTrigger_internal(name, id, items, parsePayload, requestOptio
|
|
|
334
868
|
},
|
|
335
869
|
};
|
|
336
870
|
})),
|
|
337
|
-
}, {
|
|
871
|
+
}, {
|
|
872
|
+
spanParentAsLink: true,
|
|
873
|
+
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
874
|
+
idempotencyKeyTTL: options?.idempotencyKeyTTL,
|
|
875
|
+
}, {
|
|
338
876
|
name,
|
|
339
877
|
tracer,
|
|
340
878
|
icon: "trigger",
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
879
|
+
onResponseBody(body, span) {
|
|
880
|
+
if (body && typeof body === "object" && !Array.isArray(body)) {
|
|
881
|
+
if ("id" in body && typeof body.id === "string") {
|
|
882
|
+
span.setAttribute("batchId", body.id);
|
|
883
|
+
}
|
|
884
|
+
if ("runs" in body && Array.isArray(body.runs)) {
|
|
885
|
+
span.setAttribute("runCount", body.runs.length);
|
|
886
|
+
}
|
|
887
|
+
if ("isCached" in body && typeof body.isCached === "boolean") {
|
|
888
|
+
if (body.isCached) {
|
|
889
|
+
console.warn(`Result is a cached response because the request was idempotent.`);
|
|
890
|
+
}
|
|
891
|
+
span.setAttribute("isCached", body.isCached);
|
|
892
|
+
}
|
|
893
|
+
if ("idempotencyKey" in body && typeof body.idempotencyKey === "string") {
|
|
894
|
+
span.setAttribute("idempotencyKey", body.idempotencyKey);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
345
897
|
},
|
|
346
898
|
...requestOptions,
|
|
347
899
|
});
|
|
348
900
|
const handle = {
|
|
349
|
-
batchId: response.
|
|
350
|
-
|
|
901
|
+
batchId: response.id,
|
|
902
|
+
isCached: response.isCached,
|
|
903
|
+
idempotencyKey: response.idempotencyKey,
|
|
904
|
+
runs: response.runs,
|
|
351
905
|
publicAccessToken: response.publicAccessToken,
|
|
352
906
|
};
|
|
353
907
|
return handle;
|
|
@@ -370,7 +924,6 @@ async function triggerAndWait_internal(name, id, payload, parsePayload, options,
|
|
|
370
924
|
concurrencyKey: options?.concurrencyKey,
|
|
371
925
|
test: taskContext.ctx?.run.isTest,
|
|
372
926
|
payloadType: payloadPacket.dataType,
|
|
373
|
-
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
374
927
|
delay: options?.delay,
|
|
375
928
|
ttl: options?.ttl,
|
|
376
929
|
tags: options?.tags,
|
|
@@ -379,31 +932,16 @@ async function triggerAndWait_internal(name, id, payload, parsePayload, options,
|
|
|
379
932
|
maxDuration: options?.maxDuration,
|
|
380
933
|
},
|
|
381
934
|
}, {}, requestOptions);
|
|
382
|
-
span.setAttribute("
|
|
383
|
-
if (options?.idempotencyKey) {
|
|
384
|
-
// If an idempotency key is provided, we can check if the result is already available
|
|
385
|
-
const result = await apiClient.getRunResult(response.id);
|
|
386
|
-
if (result) {
|
|
387
|
-
logger.log(`Result reused from previous task run with idempotency key '${options.idempotencyKey}'.`, {
|
|
388
|
-
runId: response.id,
|
|
389
|
-
idempotencyKey: options.idempotencyKey,
|
|
390
|
-
});
|
|
391
|
-
return await handleTaskRunExecutionResult(result);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
935
|
+
span.setAttribute("runId", response.id);
|
|
394
936
|
const result = await runtime.waitForTask({
|
|
395
937
|
id: response.id,
|
|
396
938
|
ctx,
|
|
397
939
|
});
|
|
398
|
-
return await handleTaskRunExecutionResult(result);
|
|
940
|
+
return await handleTaskRunExecutionResult(result, id);
|
|
399
941
|
}, {
|
|
400
942
|
kind: SpanKind.PRODUCER,
|
|
401
943
|
attributes: {
|
|
402
944
|
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
403
|
-
[SEMATTRS_MESSAGING_OPERATION]: "publish",
|
|
404
|
-
["messaging.client_id"]: taskContext.worker?.id,
|
|
405
|
-
[SEMATTRS_MESSAGING_DESTINATION]: id,
|
|
406
|
-
[SEMATTRS_MESSAGING_SYSTEM]: "trigger.dev",
|
|
407
945
|
...accessoryAttributes({
|
|
408
946
|
items: [
|
|
409
947
|
{
|
|
@@ -423,11 +961,12 @@ async function batchTriggerAndWait_internal(name, id, items, parsePayload, reque
|
|
|
423
961
|
}
|
|
424
962
|
const apiClient = apiClientManager.clientOrThrow();
|
|
425
963
|
return await tracer.startActiveSpan(name, async (span) => {
|
|
426
|
-
const response = await apiClient.
|
|
964
|
+
const response = await apiClient.batchTriggerV2({
|
|
427
965
|
items: await Promise.all(items.map(async (item) => {
|
|
428
966
|
const parsedPayload = parsePayload ? await parsePayload(item.payload) : item.payload;
|
|
429
967
|
const payloadPacket = await stringifyIO(parsedPayload);
|
|
430
968
|
return {
|
|
969
|
+
task: id,
|
|
431
970
|
payload: payloadPacket.data,
|
|
432
971
|
options: {
|
|
433
972
|
lockToVersion: taskContext.worker?.version,
|
|
@@ -435,7 +974,6 @@ async function batchTriggerAndWait_internal(name, id, items, parsePayload, reque
|
|
|
435
974
|
concurrencyKey: item.options?.concurrencyKey,
|
|
436
975
|
test: taskContext.ctx?.run.isTest,
|
|
437
976
|
payloadType: payloadPacket.dataType,
|
|
438
|
-
idempotencyKey: await makeIdempotencyKey(item.options?.idempotencyKey),
|
|
439
977
|
delay: item.options?.delay,
|
|
440
978
|
ttl: item.options?.ttl,
|
|
441
979
|
tags: item.options?.tags,
|
|
@@ -447,52 +985,21 @@ async function batchTriggerAndWait_internal(name, id, items, parsePayload, reque
|
|
|
447
985
|
})),
|
|
448
986
|
dependentAttempt: ctx.attempt.id,
|
|
449
987
|
}, {}, requestOptions);
|
|
450
|
-
span.setAttribute("
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
return {
|
|
461
|
-
id: response.batchId,
|
|
462
|
-
items: [],
|
|
463
|
-
};
|
|
464
|
-
};
|
|
465
|
-
const existingResults = await getBatchResults();
|
|
466
|
-
const incompleteRuns = response.runs.filter((runId) => !existingResults.items.some((item) => item.id === runId));
|
|
467
|
-
if (incompleteRuns.length === 0) {
|
|
468
|
-
logger.log(`Results reused from previous task runs because of the provided idempotency keys.`);
|
|
469
|
-
// All runs are already completed
|
|
470
|
-
const runs = await handleBatchTaskRunExecutionResult(existingResults.items);
|
|
471
|
-
return {
|
|
472
|
-
id: existingResults.id,
|
|
473
|
-
runs,
|
|
474
|
-
};
|
|
988
|
+
span.setAttribute("batchId", response.id);
|
|
989
|
+
span.setAttribute("runCount", response.runs.length);
|
|
990
|
+
span.setAttribute("isCached", response.isCached);
|
|
991
|
+
if (response.isCached) {
|
|
992
|
+
console.warn(`Result is a cached response because the request was idempotent.`);
|
|
993
|
+
}
|
|
994
|
+
if (response.idempotencyKey) {
|
|
995
|
+
span.setAttribute("idempotencyKey", response.idempotencyKey);
|
|
475
996
|
}
|
|
476
997
|
const result = await runtime.waitForBatch({
|
|
477
|
-
id: response.
|
|
478
|
-
runs:
|
|
998
|
+
id: response.id,
|
|
999
|
+
runs: response.runs.map((run) => run.id),
|
|
479
1000
|
ctx,
|
|
480
1001
|
});
|
|
481
|
-
|
|
482
|
-
const combinedItems = [];
|
|
483
|
-
for (const runId of response.runs) {
|
|
484
|
-
const existingItem = existingResults.items.find((item) => item.id === runId);
|
|
485
|
-
if (existingItem) {
|
|
486
|
-
combinedItems.push(existingItem);
|
|
487
|
-
}
|
|
488
|
-
else {
|
|
489
|
-
const newItem = result.items.find((item) => item.id === runId);
|
|
490
|
-
if (newItem) {
|
|
491
|
-
combinedItems.push(newItem);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
const runs = await handleBatchTaskRunExecutionResult(combinedItems);
|
|
1002
|
+
const runs = await handleBatchTaskRunExecutionResult(result.items, id);
|
|
496
1003
|
return {
|
|
497
1004
|
id: result.id,
|
|
498
1005
|
runs,
|
|
@@ -501,11 +1008,6 @@ async function batchTriggerAndWait_internal(name, id, items, parsePayload, reque
|
|
|
501
1008
|
kind: SpanKind.PRODUCER,
|
|
502
1009
|
attributes: {
|
|
503
1010
|
[SemanticInternalAttributes.STYLE_ICON]: "trigger",
|
|
504
|
-
["messaging.batch.message_count"]: items.length,
|
|
505
|
-
[SEMATTRS_MESSAGING_OPERATION]: "publish",
|
|
506
|
-
["messaging.client_id"]: taskContext.worker?.id,
|
|
507
|
-
[SEMATTRS_MESSAGING_DESTINATION]: id,
|
|
508
|
-
[SEMATTRS_MESSAGING_SYSTEM]: "trigger.dev",
|
|
509
1011
|
...accessoryAttributes({
|
|
510
1012
|
items: [
|
|
511
1013
|
{
|
|
@@ -518,17 +1020,35 @@ async function batchTriggerAndWait_internal(name, id, items, parsePayload, reque
|
|
|
518
1020
|
},
|
|
519
1021
|
});
|
|
520
1022
|
}
|
|
521
|
-
async function handleBatchTaskRunExecutionResult(items) {
|
|
1023
|
+
async function handleBatchTaskRunExecutionResult(items, taskIdentifier) {
|
|
1024
|
+
const someObjectStoreOutputs = items.some((item) => item.ok && item.outputType === "application/store");
|
|
1025
|
+
if (!someObjectStoreOutputs) {
|
|
1026
|
+
const results = await Promise.all(items.map(async (item) => {
|
|
1027
|
+
return await handleTaskRunExecutionResult(item, taskIdentifier);
|
|
1028
|
+
}));
|
|
1029
|
+
return results;
|
|
1030
|
+
}
|
|
1031
|
+
return await tracer.startActiveSpan("store.downloadPayloads", async (span) => {
|
|
1032
|
+
const results = await Promise.all(items.map(async (item) => {
|
|
1033
|
+
return await handleTaskRunExecutionResult(item, taskIdentifier);
|
|
1034
|
+
}));
|
|
1035
|
+
return results;
|
|
1036
|
+
}, {
|
|
1037
|
+
kind: SpanKind.INTERNAL,
|
|
1038
|
+
[SemanticInternalAttributes.STYLE_ICON]: "cloud-download",
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
1041
|
+
async function handleBatchTaskRunExecutionResultV2(items) {
|
|
522
1042
|
const someObjectStoreOutputs = items.some((item) => item.ok && item.outputType === "application/store");
|
|
523
1043
|
if (!someObjectStoreOutputs) {
|
|
524
1044
|
const results = await Promise.all(items.map(async (item) => {
|
|
525
|
-
return await handleTaskRunExecutionResult(item);
|
|
1045
|
+
return await handleTaskRunExecutionResult(item, item.taskIdentifier ?? "unknown");
|
|
526
1046
|
}));
|
|
527
1047
|
return results;
|
|
528
1048
|
}
|
|
529
1049
|
return await tracer.startActiveSpan("store.downloadPayloads", async (span) => {
|
|
530
1050
|
const results = await Promise.all(items.map(async (item) => {
|
|
531
|
-
return await handleTaskRunExecutionResult(item);
|
|
1051
|
+
return await handleTaskRunExecutionResult(item, item.taskIdentifier ?? "unknown");
|
|
532
1052
|
}));
|
|
533
1053
|
return results;
|
|
534
1054
|
}, {
|
|
@@ -536,13 +1056,14 @@ async function handleBatchTaskRunExecutionResult(items) {
|
|
|
536
1056
|
[SemanticInternalAttributes.STYLE_ICON]: "cloud-download",
|
|
537
1057
|
});
|
|
538
1058
|
}
|
|
539
|
-
async function handleTaskRunExecutionResult(execution) {
|
|
1059
|
+
async function handleTaskRunExecutionResult(execution, taskIdentifier) {
|
|
540
1060
|
if (execution.ok) {
|
|
541
1061
|
const outputPacket = { data: execution.output, dataType: execution.outputType };
|
|
542
1062
|
const importedPacket = await conditionallyImportPacket(outputPacket, tracer);
|
|
543
1063
|
return {
|
|
544
1064
|
ok: true,
|
|
545
1065
|
id: execution.id,
|
|
1066
|
+
taskIdentifier: (execution.taskIdentifier ?? taskIdentifier),
|
|
546
1067
|
output: await parsePacket(importedPacket),
|
|
547
1068
|
};
|
|
548
1069
|
}
|
|
@@ -550,6 +1071,7 @@ async function handleTaskRunExecutionResult(execution) {
|
|
|
550
1071
|
return {
|
|
551
1072
|
ok: false,
|
|
552
1073
|
id: execution.id,
|
|
1074
|
+
taskIdentifier: (execution.taskIdentifier ?? taskIdentifier),
|
|
553
1075
|
error: createErrorTaskError(execution.error),
|
|
554
1076
|
};
|
|
555
1077
|
}
|