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