@trigger.dev/sdk 3.2.2 → 3.3.0
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 +618 -100
- 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 +615 -101
- 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,540 @@ 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
|
+
});
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Triggers multiple tasks and waits for all of them to complete before returning their results.
|
|
525
|
+
* This function must be called from within a task.run() context.
|
|
526
|
+
*
|
|
527
|
+
* @template TTask - Union type of tasks to be triggered, extends AnyTask
|
|
528
|
+
*
|
|
529
|
+
* @param {Array<BatchByIdAndWaitItem<InferRunTypes<TTask>>>} items - Array of task items to trigger
|
|
530
|
+
* @param {TriggerApiRequestOptions} [requestOptions] - Optional API request configuration
|
|
531
|
+
*
|
|
532
|
+
* @returns {Promise<BatchByIdResult<TTask>>} A promise that resolves with the batch results, including
|
|
533
|
+
* success/failure status and strongly-typed outputs for each task
|
|
534
|
+
*
|
|
535
|
+
* @throws {Error} If called outside of a task.run() context
|
|
536
|
+
* @throws {Error} If no API client is configured
|
|
537
|
+
*
|
|
538
|
+
* @example
|
|
539
|
+
* ```ts
|
|
540
|
+
* import { batch, task } from "@trigger.dev/sdk/v3";
|
|
541
|
+
*
|
|
542
|
+
* export const parentTask = task({
|
|
543
|
+
* id: "parent-task",
|
|
544
|
+
* run: async (payload: string) => {
|
|
545
|
+
* const results = await batch.triggerAndWait<typeof childTask1 | typeof childTask2>([
|
|
546
|
+
* {
|
|
547
|
+
* id: "child-task-1",
|
|
548
|
+
* payload: { foo: "World" },
|
|
549
|
+
* options: {
|
|
550
|
+
* queue: "default",
|
|
551
|
+
* delay: "5m",
|
|
552
|
+
* tags: ["batch", "child1"]
|
|
553
|
+
* }
|
|
554
|
+
* },
|
|
555
|
+
* {
|
|
556
|
+
* id: "child-task-2",
|
|
557
|
+
* payload: { bar: 42 }
|
|
558
|
+
* }
|
|
559
|
+
* ]);
|
|
560
|
+
*
|
|
561
|
+
* // Type-safe result handling
|
|
562
|
+
* for (const result of results) {
|
|
563
|
+
* if (result.ok) {
|
|
564
|
+
* switch (result.taskIdentifier) {
|
|
565
|
+
* case "child-task-1":
|
|
566
|
+
* console.log("Child task 1 output:", result.output); // string type
|
|
567
|
+
* break;
|
|
568
|
+
* case "child-task-2":
|
|
569
|
+
* console.log("Child task 2 output:", result.output); // number type
|
|
570
|
+
* break;
|
|
571
|
+
* }
|
|
572
|
+
* } else {
|
|
573
|
+
* console.error("Task failed:", result.error);
|
|
574
|
+
* }
|
|
575
|
+
* }
|
|
576
|
+
* }
|
|
577
|
+
* });
|
|
578
|
+
* ```
|
|
579
|
+
*
|
|
580
|
+
* @description
|
|
581
|
+
* Each task item in the array can include:
|
|
582
|
+
* - `id`: The task identifier (must match one of the tasks in the union type)
|
|
583
|
+
* - `payload`: Strongly-typed payload matching the task's input type
|
|
584
|
+
* - `options`: Optional task-specific settings including:
|
|
585
|
+
* - `queue`: Specify a queue for the task
|
|
586
|
+
* - `concurrencyKey`: Control concurrent execution
|
|
587
|
+
* - `delay`: Delay before task execution
|
|
588
|
+
* - `ttl`: Time-to-live for the task
|
|
589
|
+
* - `tags`: Array of tags for the task
|
|
590
|
+
* - `maxAttempts`: Maximum retry attempts
|
|
591
|
+
* - `metadata`: Additional metadata
|
|
592
|
+
* - `maxDuration`: Maximum execution duration
|
|
593
|
+
*
|
|
594
|
+
* The function provides full type safety for:
|
|
595
|
+
* - Task IDs
|
|
596
|
+
* - Payload types
|
|
597
|
+
* - Return value types
|
|
598
|
+
* - Error handling
|
|
599
|
+
*/
|
|
600
|
+
export async function batchTriggerTasks(items, options, requestOptions) {
|
|
601
|
+
const apiClient = apiClientManager.clientOrThrow();
|
|
602
|
+
const response = await apiClient.batchTriggerV2({
|
|
603
|
+
items: await Promise.all(items.map(async (item) => {
|
|
604
|
+
const taskMetadata = taskCatalog.getTask(item.task.id);
|
|
605
|
+
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
606
|
+
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
607
|
+
: item.payload;
|
|
608
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
609
|
+
return {
|
|
610
|
+
task: item.task.id,
|
|
611
|
+
payload: payloadPacket.data,
|
|
612
|
+
options: {
|
|
613
|
+
queue: item.options?.queue,
|
|
614
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
615
|
+
test: taskContext.ctx?.run.isTest,
|
|
616
|
+
payloadType: payloadPacket.dataType,
|
|
617
|
+
idempotencyKey: await makeIdempotencyKey(item.options?.idempotencyKey),
|
|
618
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL,
|
|
619
|
+
delay: item.options?.delay,
|
|
620
|
+
ttl: item.options?.ttl,
|
|
621
|
+
tags: item.options?.tags,
|
|
622
|
+
maxAttempts: item.options?.maxAttempts,
|
|
623
|
+
parentAttempt: taskContext.ctx?.attempt.id,
|
|
624
|
+
metadata: item.options?.metadata,
|
|
625
|
+
maxDuration: item.options?.maxDuration,
|
|
626
|
+
},
|
|
627
|
+
};
|
|
628
|
+
})),
|
|
629
|
+
}, {
|
|
630
|
+
spanParentAsLink: true,
|
|
631
|
+
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
632
|
+
idempotencyKeyTTL: options?.idempotencyKeyTTL,
|
|
633
|
+
}, {
|
|
634
|
+
name: "batch.triggerByTask()",
|
|
635
|
+
tracer,
|
|
636
|
+
icon: "trigger",
|
|
637
|
+
onResponseBody(body, span) {
|
|
638
|
+
if (body && typeof body === "object" && !Array.isArray(body)) {
|
|
639
|
+
if ("id" in body && typeof body.id === "string") {
|
|
640
|
+
span.setAttribute("batchId", body.id);
|
|
641
|
+
}
|
|
642
|
+
if ("runs" in body && Array.isArray(body.runs)) {
|
|
643
|
+
span.setAttribute("runCount", body.runs.length);
|
|
644
|
+
}
|
|
645
|
+
if ("isCached" in body && typeof body.isCached === "boolean") {
|
|
646
|
+
if (body.isCached) {
|
|
647
|
+
console.warn(`Result is a cached response because the request was idempotent.`);
|
|
648
|
+
}
|
|
649
|
+
span.setAttribute("isCached", body.isCached);
|
|
650
|
+
}
|
|
651
|
+
if ("idempotencyKey" in body && typeof body.idempotencyKey === "string") {
|
|
652
|
+
span.setAttribute("idempotencyKey", body.idempotencyKey);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
},
|
|
656
|
+
...requestOptions,
|
|
657
|
+
});
|
|
658
|
+
const handle = {
|
|
659
|
+
batchId: response.id,
|
|
660
|
+
isCached: response.isCached,
|
|
661
|
+
idempotencyKey: response.idempotencyKey,
|
|
662
|
+
runs: response.runs,
|
|
663
|
+
publicAccessToken: response.publicAccessToken,
|
|
664
|
+
};
|
|
665
|
+
return handle;
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Triggers multiple tasks and waits for all of them to complete before returning their results.
|
|
669
|
+
* This function must be called from within a task.run() context.
|
|
670
|
+
*
|
|
671
|
+
* @template TTask - Union type of tasks to be triggered, extends AnyTask
|
|
672
|
+
*
|
|
673
|
+
* @param {Array<BatchByIdAndWaitItem<InferRunTypes<TTask>>>} items - Array of task items to trigger
|
|
674
|
+
* @param {TriggerApiRequestOptions} [requestOptions] - Optional API request configuration
|
|
675
|
+
*
|
|
676
|
+
* @returns {Promise<BatchByIdResult<TTask>>} A promise that resolves with the batch results, including
|
|
677
|
+
* success/failure status and strongly-typed outputs for each task
|
|
678
|
+
*
|
|
679
|
+
* @throws {Error} If called outside of a task.run() context
|
|
680
|
+
* @throws {Error} If no API client is configured
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* ```ts
|
|
684
|
+
* import { batch, task } from "@trigger.dev/sdk/v3";
|
|
685
|
+
*
|
|
686
|
+
* export const parentTask = task({
|
|
687
|
+
* id: "parent-task",
|
|
688
|
+
* run: async (payload: string) => {
|
|
689
|
+
* const results = await batch.triggerAndWait<typeof childTask1 | typeof childTask2>([
|
|
690
|
+
* {
|
|
691
|
+
* id: "child-task-1",
|
|
692
|
+
* payload: { foo: "World" },
|
|
693
|
+
* options: {
|
|
694
|
+
* queue: "default",
|
|
695
|
+
* delay: "5m",
|
|
696
|
+
* tags: ["batch", "child1"]
|
|
697
|
+
* }
|
|
698
|
+
* },
|
|
699
|
+
* {
|
|
700
|
+
* id: "child-task-2",
|
|
701
|
+
* payload: { bar: 42 }
|
|
702
|
+
* }
|
|
703
|
+
* ]);
|
|
704
|
+
*
|
|
705
|
+
* // Type-safe result handling
|
|
706
|
+
* for (const result of results) {
|
|
707
|
+
* if (result.ok) {
|
|
708
|
+
* switch (result.taskIdentifier) {
|
|
709
|
+
* case "child-task-1":
|
|
710
|
+
* console.log("Child task 1 output:", result.output); // string type
|
|
711
|
+
* break;
|
|
712
|
+
* case "child-task-2":
|
|
713
|
+
* console.log("Child task 2 output:", result.output); // number type
|
|
714
|
+
* break;
|
|
715
|
+
* }
|
|
716
|
+
* } else {
|
|
717
|
+
* console.error("Task failed:", result.error);
|
|
718
|
+
* }
|
|
719
|
+
* }
|
|
720
|
+
* }
|
|
721
|
+
* });
|
|
722
|
+
* ```
|
|
723
|
+
*
|
|
724
|
+
* @description
|
|
725
|
+
* Each task item in the array can include:
|
|
726
|
+
* - `id`: The task identifier (must match one of the tasks in the union type)
|
|
727
|
+
* - `payload`: Strongly-typed payload matching the task's input type
|
|
728
|
+
* - `options`: Optional task-specific settings including:
|
|
729
|
+
* - `queue`: Specify a queue for the task
|
|
730
|
+
* - `concurrencyKey`: Control concurrent execution
|
|
731
|
+
* - `delay`: Delay before task execution
|
|
732
|
+
* - `ttl`: Time-to-live for the task
|
|
733
|
+
* - `tags`: Array of tags for the task
|
|
734
|
+
* - `maxAttempts`: Maximum retry attempts
|
|
735
|
+
* - `metadata`: Additional metadata
|
|
736
|
+
* - `maxDuration`: Maximum execution duration
|
|
737
|
+
*
|
|
738
|
+
* The function provides full type safety for:
|
|
739
|
+
* - Task IDs
|
|
740
|
+
* - Payload types
|
|
741
|
+
* - Return value types
|
|
742
|
+
* - Error handling
|
|
743
|
+
*/
|
|
744
|
+
export async function batchTriggerAndWaitTasks(items, requestOptions) {
|
|
745
|
+
const ctx = taskContext.ctx;
|
|
746
|
+
if (!ctx) {
|
|
747
|
+
throw new Error("batchTriggerAndWait can only be used from inside a task.run()");
|
|
748
|
+
}
|
|
749
|
+
const apiClient = apiClientManager.clientOrThrow();
|
|
750
|
+
return await tracer.startActiveSpan("batch.triggerByTaskAndWait()", async (span) => {
|
|
751
|
+
const response = await apiClient.batchTriggerV2({
|
|
752
|
+
items: await Promise.all(items.map(async (item) => {
|
|
753
|
+
const taskMetadata = taskCatalog.getTask(item.task.id);
|
|
754
|
+
const parsedPayload = taskMetadata?.fns.parsePayload
|
|
755
|
+
? await taskMetadata?.fns.parsePayload(item.payload)
|
|
756
|
+
: item.payload;
|
|
757
|
+
const payloadPacket = await stringifyIO(parsedPayload);
|
|
758
|
+
return {
|
|
759
|
+
task: item.task.id,
|
|
760
|
+
payload: payloadPacket.data,
|
|
761
|
+
options: {
|
|
762
|
+
lockToVersion: taskContext.worker?.version,
|
|
763
|
+
queue: item.options?.queue,
|
|
764
|
+
concurrencyKey: item.options?.concurrencyKey,
|
|
765
|
+
test: taskContext.ctx?.run.isTest,
|
|
766
|
+
payloadType: payloadPacket.dataType,
|
|
767
|
+
delay: item.options?.delay,
|
|
768
|
+
ttl: item.options?.ttl,
|
|
769
|
+
tags: item.options?.tags,
|
|
770
|
+
maxAttempts: item.options?.maxAttempts,
|
|
771
|
+
metadata: item.options?.metadata,
|
|
772
|
+
maxDuration: item.options?.maxDuration,
|
|
773
|
+
},
|
|
774
|
+
};
|
|
775
|
+
})),
|
|
776
|
+
dependentAttempt: ctx.attempt.id,
|
|
777
|
+
}, {}, requestOptions);
|
|
778
|
+
span.setAttribute("batchId", response.id);
|
|
779
|
+
span.setAttribute("runCount", response.runs.length);
|
|
780
|
+
span.setAttribute("isCached", response.isCached);
|
|
781
|
+
if (response.isCached) {
|
|
782
|
+
console.warn(`Result is a cached response because the request was idempotent.`);
|
|
783
|
+
}
|
|
784
|
+
if (response.idempotencyKey) {
|
|
785
|
+
span.setAttribute("idempotencyKey", response.idempotencyKey);
|
|
786
|
+
}
|
|
787
|
+
const result = await runtime.waitForBatch({
|
|
788
|
+
id: response.id,
|
|
789
|
+
runs: response.runs.map((run) => run.id),
|
|
790
|
+
ctx,
|
|
791
|
+
});
|
|
792
|
+
const runs = await handleBatchTaskRunExecutionResultV2(result.items);
|
|
793
|
+
return {
|
|
794
|
+
id: result.id,
|
|
795
|
+
runs,
|
|
796
|
+
};
|
|
797
|
+
}, {
|
|
798
|
+
kind: SpanKind.PRODUCER,
|
|
799
|
+
});
|
|
269
800
|
}
|
|
270
801
|
async function trigger_internal(name, id, payload, parsePayload, options, requestOptions) {
|
|
271
802
|
const apiClient = apiClientManager.clientOrThrow();
|
|
@@ -279,6 +810,7 @@ async function trigger_internal(name, id, payload, parsePayload, options, reques
|
|
|
279
810
|
test: taskContext.ctx?.run.isTest,
|
|
280
811
|
payloadType: payloadPacket.dataType,
|
|
281
812
|
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
813
|
+
idempotencyKeyTTL: options?.idempotencyKeyTTL,
|
|
282
814
|
delay: options?.delay,
|
|
283
815
|
ttl: options?.ttl,
|
|
284
816
|
tags: options?.tags,
|
|
@@ -293,30 +825,25 @@ async function trigger_internal(name, id, payload, parsePayload, options, reques
|
|
|
293
825
|
name,
|
|
294
826
|
tracer,
|
|
295
827
|
icon: "trigger",
|
|
296
|
-
attributes: {
|
|
297
|
-
[SEMATTRS_MESSAGING_OPERATION]: "publish",
|
|
298
|
-
["messaging.client_id"]: taskContext.worker?.id,
|
|
299
|
-
[SEMATTRS_MESSAGING_SYSTEM]: "trigger.dev",
|
|
300
|
-
},
|
|
301
828
|
onResponseBody: (body, span) => {
|
|
302
|
-
body &&
|
|
303
|
-
typeof body === "
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
span.setAttribute("messaging.message.id", body.id);
|
|
829
|
+
if (body && typeof body === "object" && !Array.isArray(body)) {
|
|
830
|
+
if ("id" in body && typeof body.id === "string") {
|
|
831
|
+
span.setAttribute("runId", body.id);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
308
834
|
},
|
|
309
835
|
...requestOptions,
|
|
310
836
|
});
|
|
311
837
|
return handle;
|
|
312
838
|
}
|
|
313
|
-
async function batchTrigger_internal(name,
|
|
839
|
+
async function batchTrigger_internal(name, taskIdentifier, items, options, parsePayload, requestOptions, queue) {
|
|
314
840
|
const apiClient = apiClientManager.clientOrThrow();
|
|
315
|
-
const response = await apiClient.
|
|
841
|
+
const response = await apiClient.batchTriggerV2({
|
|
316
842
|
items: await Promise.all(items.map(async (item) => {
|
|
317
843
|
const parsedPayload = parsePayload ? await parsePayload(item.payload) : item.payload;
|
|
318
844
|
const payloadPacket = await stringifyIO(parsedPayload);
|
|
319
845
|
return {
|
|
846
|
+
task: taskIdentifier,
|
|
320
847
|
payload: payloadPacket.data,
|
|
321
848
|
options: {
|
|
322
849
|
queue: item.options?.queue ?? queue,
|
|
@@ -324,6 +851,7 @@ async function batchTrigger_internal(name, id, items, parsePayload, requestOptio
|
|
|
324
851
|
test: taskContext.ctx?.run.isTest,
|
|
325
852
|
payloadType: payloadPacket.dataType,
|
|
326
853
|
idempotencyKey: await makeIdempotencyKey(item.options?.idempotencyKey),
|
|
854
|
+
idempotencyKeyTTL: item.options?.idempotencyKeyTTL,
|
|
327
855
|
delay: item.options?.delay,
|
|
328
856
|
ttl: item.options?.ttl,
|
|
329
857
|
tags: item.options?.tags,
|
|
@@ -334,20 +862,40 @@ async function batchTrigger_internal(name, id, items, parsePayload, requestOptio
|
|
|
334
862
|
},
|
|
335
863
|
};
|
|
336
864
|
})),
|
|
337
|
-
}, {
|
|
865
|
+
}, {
|
|
866
|
+
spanParentAsLink: true,
|
|
867
|
+
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
868
|
+
idempotencyKeyTTL: options?.idempotencyKeyTTL,
|
|
869
|
+
}, {
|
|
338
870
|
name,
|
|
339
871
|
tracer,
|
|
340
872
|
icon: "trigger",
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
873
|
+
onResponseBody(body, span) {
|
|
874
|
+
if (body && typeof body === "object" && !Array.isArray(body)) {
|
|
875
|
+
if ("id" in body && typeof body.id === "string") {
|
|
876
|
+
span.setAttribute("batchId", body.id);
|
|
877
|
+
}
|
|
878
|
+
if ("runs" in body && Array.isArray(body.runs)) {
|
|
879
|
+
span.setAttribute("runCount", body.runs.length);
|
|
880
|
+
}
|
|
881
|
+
if ("isCached" in body && typeof body.isCached === "boolean") {
|
|
882
|
+
if (body.isCached) {
|
|
883
|
+
console.warn(`Result is a cached response because the request was idempotent.`);
|
|
884
|
+
}
|
|
885
|
+
span.setAttribute("isCached", body.isCached);
|
|
886
|
+
}
|
|
887
|
+
if ("idempotencyKey" in body && typeof body.idempotencyKey === "string") {
|
|
888
|
+
span.setAttribute("idempotencyKey", body.idempotencyKey);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
345
891
|
},
|
|
346
892
|
...requestOptions,
|
|
347
893
|
});
|
|
348
894
|
const handle = {
|
|
349
|
-
batchId: response.
|
|
350
|
-
|
|
895
|
+
batchId: response.id,
|
|
896
|
+
isCached: response.isCached,
|
|
897
|
+
idempotencyKey: response.idempotencyKey,
|
|
898
|
+
runs: response.runs,
|
|
351
899
|
publicAccessToken: response.publicAccessToken,
|
|
352
900
|
};
|
|
353
901
|
return handle;
|
|
@@ -370,7 +918,6 @@ async function triggerAndWait_internal(name, id, payload, parsePayload, options,
|
|
|
370
918
|
concurrencyKey: options?.concurrencyKey,
|
|
371
919
|
test: taskContext.ctx?.run.isTest,
|
|
372
920
|
payloadType: payloadPacket.dataType,
|
|
373
|
-
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
|
|
374
921
|
delay: options?.delay,
|
|
375
922
|
ttl: options?.ttl,
|
|
376
923
|
tags: options?.tags,
|
|
@@ -379,31 +926,15 @@ async function triggerAndWait_internal(name, id, payload, parsePayload, options,
|
|
|
379
926
|
maxDuration: options?.maxDuration,
|
|
380
927
|
},
|
|
381
928
|
}, {}, 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
|
-
}
|
|
929
|
+
span.setAttribute("runId", response.id);
|
|
394
930
|
const result = await runtime.waitForTask({
|
|
395
931
|
id: response.id,
|
|
396
932
|
ctx,
|
|
397
933
|
});
|
|
398
|
-
return await handleTaskRunExecutionResult(result);
|
|
934
|
+
return await handleTaskRunExecutionResult(result, id);
|
|
399
935
|
}, {
|
|
400
936
|
kind: SpanKind.PRODUCER,
|
|
401
937
|
attributes: {
|
|
402
|
-
[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
938
|
...accessoryAttributes({
|
|
408
939
|
items: [
|
|
409
940
|
{
|
|
@@ -423,11 +954,12 @@ async function batchTriggerAndWait_internal(name, id, items, parsePayload, reque
|
|
|
423
954
|
}
|
|
424
955
|
const apiClient = apiClientManager.clientOrThrow();
|
|
425
956
|
return await tracer.startActiveSpan(name, async (span) => {
|
|
426
|
-
const response = await apiClient.
|
|
957
|
+
const response = await apiClient.batchTriggerV2({
|
|
427
958
|
items: await Promise.all(items.map(async (item) => {
|
|
428
959
|
const parsedPayload = parsePayload ? await parsePayload(item.payload) : item.payload;
|
|
429
960
|
const payloadPacket = await stringifyIO(parsedPayload);
|
|
430
961
|
return {
|
|
962
|
+
task: id,
|
|
431
963
|
payload: payloadPacket.data,
|
|
432
964
|
options: {
|
|
433
965
|
lockToVersion: taskContext.worker?.version,
|
|
@@ -435,7 +967,6 @@ async function batchTriggerAndWait_internal(name, id, items, parsePayload, reque
|
|
|
435
967
|
concurrencyKey: item.options?.concurrencyKey,
|
|
436
968
|
test: taskContext.ctx?.run.isTest,
|
|
437
969
|
payloadType: payloadPacket.dataType,
|
|
438
|
-
idempotencyKey: await makeIdempotencyKey(item.options?.idempotencyKey),
|
|
439
970
|
delay: item.options?.delay,
|
|
440
971
|
ttl: item.options?.ttl,
|
|
441
972
|
tags: item.options?.tags,
|
|
@@ -447,52 +978,21 @@ async function batchTriggerAndWait_internal(name, id, items, parsePayload, reque
|
|
|
447
978
|
})),
|
|
448
979
|
dependentAttempt: ctx.attempt.id,
|
|
449
980
|
}, {}, 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
|
-
};
|
|
981
|
+
span.setAttribute("batchId", response.id);
|
|
982
|
+
span.setAttribute("runCount", response.runs.length);
|
|
983
|
+
span.setAttribute("isCached", response.isCached);
|
|
984
|
+
if (response.isCached) {
|
|
985
|
+
console.warn(`Result is a cached response because the request was idempotent.`);
|
|
986
|
+
}
|
|
987
|
+
if (response.idempotencyKey) {
|
|
988
|
+
span.setAttribute("idempotencyKey", response.idempotencyKey);
|
|
475
989
|
}
|
|
476
990
|
const result = await runtime.waitForBatch({
|
|
477
|
-
id: response.
|
|
478
|
-
runs:
|
|
991
|
+
id: response.id,
|
|
992
|
+
runs: response.runs.map((run) => run.id),
|
|
479
993
|
ctx,
|
|
480
994
|
});
|
|
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);
|
|
995
|
+
const runs = await handleBatchTaskRunExecutionResult(result.items, id);
|
|
496
996
|
return {
|
|
497
997
|
id: result.id,
|
|
498
998
|
runs,
|
|
@@ -500,12 +1000,6 @@ async function batchTriggerAndWait_internal(name, id, items, parsePayload, reque
|
|
|
500
1000
|
}, {
|
|
501
1001
|
kind: SpanKind.PRODUCER,
|
|
502
1002
|
attributes: {
|
|
503
|
-
[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
1003
|
...accessoryAttributes({
|
|
510
1004
|
items: [
|
|
511
1005
|
{
|
|
@@ -518,17 +1012,35 @@ async function batchTriggerAndWait_internal(name, id, items, parsePayload, reque
|
|
|
518
1012
|
},
|
|
519
1013
|
});
|
|
520
1014
|
}
|
|
521
|
-
async function handleBatchTaskRunExecutionResult(items) {
|
|
1015
|
+
async function handleBatchTaskRunExecutionResult(items, taskIdentifier) {
|
|
1016
|
+
const someObjectStoreOutputs = items.some((item) => item.ok && item.outputType === "application/store");
|
|
1017
|
+
if (!someObjectStoreOutputs) {
|
|
1018
|
+
const results = await Promise.all(items.map(async (item) => {
|
|
1019
|
+
return await handleTaskRunExecutionResult(item, taskIdentifier);
|
|
1020
|
+
}));
|
|
1021
|
+
return results;
|
|
1022
|
+
}
|
|
1023
|
+
return await tracer.startActiveSpan("store.downloadPayloads", async (span) => {
|
|
1024
|
+
const results = await Promise.all(items.map(async (item) => {
|
|
1025
|
+
return await handleTaskRunExecutionResult(item, taskIdentifier);
|
|
1026
|
+
}));
|
|
1027
|
+
return results;
|
|
1028
|
+
}, {
|
|
1029
|
+
kind: SpanKind.INTERNAL,
|
|
1030
|
+
[SemanticInternalAttributes.STYLE_ICON]: "cloud-download",
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
async function handleBatchTaskRunExecutionResultV2(items) {
|
|
522
1034
|
const someObjectStoreOutputs = items.some((item) => item.ok && item.outputType === "application/store");
|
|
523
1035
|
if (!someObjectStoreOutputs) {
|
|
524
1036
|
const results = await Promise.all(items.map(async (item) => {
|
|
525
|
-
return await handleTaskRunExecutionResult(item);
|
|
1037
|
+
return await handleTaskRunExecutionResult(item, item.taskIdentifier ?? "unknown");
|
|
526
1038
|
}));
|
|
527
1039
|
return results;
|
|
528
1040
|
}
|
|
529
1041
|
return await tracer.startActiveSpan("store.downloadPayloads", async (span) => {
|
|
530
1042
|
const results = await Promise.all(items.map(async (item) => {
|
|
531
|
-
return await handleTaskRunExecutionResult(item);
|
|
1043
|
+
return await handleTaskRunExecutionResult(item, item.taskIdentifier ?? "unknown");
|
|
532
1044
|
}));
|
|
533
1045
|
return results;
|
|
534
1046
|
}, {
|
|
@@ -536,13 +1048,14 @@ async function handleBatchTaskRunExecutionResult(items) {
|
|
|
536
1048
|
[SemanticInternalAttributes.STYLE_ICON]: "cloud-download",
|
|
537
1049
|
});
|
|
538
1050
|
}
|
|
539
|
-
async function handleTaskRunExecutionResult(execution) {
|
|
1051
|
+
async function handleTaskRunExecutionResult(execution, taskIdentifier) {
|
|
540
1052
|
if (execution.ok) {
|
|
541
1053
|
const outputPacket = { data: execution.output, dataType: execution.outputType };
|
|
542
1054
|
const importedPacket = await conditionallyImportPacket(outputPacket, tracer);
|
|
543
1055
|
return {
|
|
544
1056
|
ok: true,
|
|
545
1057
|
id: execution.id,
|
|
1058
|
+
taskIdentifier: (execution.taskIdentifier ?? taskIdentifier),
|
|
546
1059
|
output: await parsePacket(importedPacket),
|
|
547
1060
|
};
|
|
548
1061
|
}
|
|
@@ -550,6 +1063,7 @@ async function handleTaskRunExecutionResult(execution) {
|
|
|
550
1063
|
return {
|
|
551
1064
|
ok: false,
|
|
552
1065
|
id: execution.id,
|
|
1066
|
+
taskIdentifier: (execution.taskIdentifier ?? taskIdentifier),
|
|
553
1067
|
error: createErrorTaskError(execution.error),
|
|
554
1068
|
};
|
|
555
1069
|
}
|