@trigger.dev/sdk 3.0.0-beta.3 → 3.0.0-beta.30

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/v3/index.mjs CHANGED
@@ -1,523 +1,146 @@
1
- import { SpanKind, trace, context, SpanStatusCode } from '@opentelemetry/api';
1
+ import { TriggerTracer, SemanticInternalAttributes, runtime, accessoryAttributes, apiClientManager, taskCatalog, defaultRetryOptions, calculateNextRetryDelay, defaultFetchRetryOptions, calculateResetAt, eventFilterMatches, flattenAttributes, stringifyIO, taskContext, logger, conditionallyImportPacket, parsePacket, createErrorTaskError } from '@trigger.dev/core/v3';
2
+ export { APIError, AuthenticationError, BadRequestError, ConflictError, InternalServerError, NotFoundError, PermissionDeniedError, RateLimitError, UnprocessableEntityError, logger } from '@trigger.dev/core/v3';
3
+ import { trace, context, SpanStatusCode, SpanKind } from '@opentelemetry/api';
2
4
  import { SEMATTRS_HTTP_STATUS_CODE, SEMATTRS_HTTP_METHOD, SEMATTRS_HTTP_URL, SEMATTRS_HTTP_HOST, SEMATTRS_HTTP_SCHEME, SEMATTRS_HTTP_RESPONSE_CONTENT_LENGTH, SEMATTRS_MESSAGING_OPERATION, SEMATTRS_MESSAGING_DESTINATION, SEMATTRS_MESSAGING_SYSTEM } from '@opentelemetry/semantic-conventions';
3
- import { TriggerTracer, runtime, SemanticInternalAttributes, accessoryAttributes, defaultRetryOptions, conditionallyImportPacket, parsePacket, createErrorTaskError, apiClientManager, calculateNextRetryDelay, defaultFetchRetryOptions, calculateResetAt, eventFilterMatches, flattenAttributes, taskContextManager } from '@trigger.dev/core/v3';
4
- export { logger } from '@trigger.dev/core/v3';
5
5
  import { AsyncLocalStorage } from 'node:async_hooks';
6
6
 
7
7
  var __defProp = Object.defineProperty;
8
8
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
9
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
10
+ var __export = (target, all) => {
11
+ for (var name in all)
12
+ __defProp(target, name, { get: all[name], enumerable: true });
13
+ };
10
14
  var __publicField = (obj, key, value) => {
11
15
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
12
16
  return value;
13
17
  };
14
18
 
15
19
  // package.json
16
- var version = "3.0.0-beta.3";
20
+ var version = "3.0.0-beta.30";
21
+
22
+ // src/v3/tracer.ts
17
23
  var tracer = new TriggerTracer({
18
24
  name: "@trigger.dev/sdk",
19
25
  version
20
26
  });
21
27
 
22
- // src/v3/shared.ts
23
- function createTask(params) {
24
- const task2 = {
25
- trigger: async ({ payload, options }) => {
26
- const apiClient = apiClientManager.client;
27
- if (!apiClient) {
28
- throw apiClientMissingError();
28
+ // src/v3/cache.ts
29
+ var _InMemoryCache = class _InMemoryCache {
30
+ constructor() {
31
+ __publicField(this, "_cache", /* @__PURE__ */ new Map());
32
+ }
33
+ get(key) {
34
+ return this._cache.get(key);
35
+ }
36
+ set(key, value) {
37
+ this._cache.set(key, value);
38
+ return void 0;
39
+ }
40
+ delete(key) {
41
+ this._cache.delete(key);
42
+ return void 0;
43
+ }
44
+ };
45
+ __name(_InMemoryCache, "InMemoryCache");
46
+ var InMemoryCache = _InMemoryCache;
47
+ function createCache(store) {
48
+ return /* @__PURE__ */ __name(function cache(cacheKey, fn) {
49
+ return tracer.startActiveSpan("cache", async (span) => {
50
+ span.setAttribute("cache.key", cacheKey);
51
+ span.setAttribute(SemanticInternalAttributes.STYLE_ICON, "device-sd-card");
52
+ const cacheEntry = await store.get(cacheKey);
53
+ if (cacheEntry) {
54
+ span.updateName(`cache.hit ${cacheKey}`);
55
+ return cacheEntry.value;
29
56
  }
30
- const taskMetadata = runtime.getTaskMetadata(params.id);
31
- const handle = await tracer.startActiveSpan(taskMetadata ? "Trigger" : `${params.id} trigger()`, async (span) => {
32
- const response = await apiClient.triggerTask(params.id, {
33
- payload,
34
- options: {
35
- queue: params.queue,
36
- concurrencyKey: options?.concurrencyKey,
37
- test: taskContextManager.ctx?.run.isTest
38
- }
39
- }, {
40
- spanParentAsLink: true
41
- });
42
- if (!response.ok) {
43
- throw new Error(response.error);
44
- }
45
- span.setAttribute("messaging.message.id", response.data.id);
46
- return response.data;
57
+ span.updateName(`cache.miss ${cacheKey}`);
58
+ const value = await tracer.startActiveSpan("cache.getFreshValue", async (span2) => {
59
+ return await fn();
47
60
  }, {
48
- kind: SpanKind.PRODUCER,
49
61
  attributes: {
50
- [SEMATTRS_MESSAGING_OPERATION]: "publish",
51
- [SemanticInternalAttributes.STYLE_ICON]: "trigger",
52
- ["messaging.client_id"]: taskContextManager.worker?.id,
53
- [SEMATTRS_MESSAGING_DESTINATION]: params.queue?.name ?? params.id,
54
- ["messaging.message.body.size"]: JSON.stringify(payload).length,
55
- [SEMATTRS_MESSAGING_SYSTEM]: "trigger.dev",
56
- ...taskMetadata ? accessoryAttributes({
57
- items: [
58
- {
59
- text: `${taskMetadata.exportName}.trigger()`,
60
- variant: "normal"
61
- }
62
- ],
63
- style: "codepath"
64
- }) : {}
62
+ "cache.key": cacheKey,
63
+ [SemanticInternalAttributes.STYLE_ICON]: "device-sd-card"
65
64
  }
66
65
  });
67
- return handle;
68
- },
69
- batchTrigger: async ({ items }) => {
70
- const apiClient = apiClientManager.client;
71
- if (!apiClient) {
72
- throw apiClientMissingError();
73
- }
74
- const taskMetadata = runtime.getTaskMetadata(params.id);
75
- const response = await tracer.startActiveSpan(taskMetadata ? "Batch trigger" : `${params.id} batchTrigger()`, async (span) => {
76
- const response2 = await apiClient.batchTriggerTask(params.id, {
77
- items: items.map((item) => ({
78
- payload: item.payload,
79
- options: {
80
- queue: item.options?.queue ?? params.queue,
81
- concurrencyKey: item.options?.concurrencyKey,
82
- test: taskContextManager.ctx?.run.isTest
83
- }
84
- }))
85
- }, {
86
- spanParentAsLink: true
66
+ await tracer.startActiveSpan("cache.set", async (span2) => {
67
+ await store.set(cacheKey, {
68
+ value,
69
+ metadata: {
70
+ createdTime: Date.now()
71
+ }
87
72
  });
88
- if (!response2.ok) {
89
- throw new Error(response2.error);
90
- }
91
- span.setAttribute("messaging.message.id", response2.data.batchId);
92
- return response2.data;
93
73
  }, {
94
- kind: SpanKind.PRODUCER,
95
74
  attributes: {
96
- [SEMATTRS_MESSAGING_OPERATION]: "publish",
97
- ["messaging.batch.message_count"]: items.length,
98
- ["messaging.client_id"]: taskContextManager.worker?.id,
99
- [SEMATTRS_MESSAGING_DESTINATION]: params.queue?.name ?? params.id,
100
- ["messaging.message.body.size"]: items.map((item) => JSON.stringify(item.payload)).join("").length,
101
- [SEMATTRS_MESSAGING_SYSTEM]: "trigger.dev",
102
- [SemanticInternalAttributes.STYLE_ICON]: "trigger",
103
- ...taskMetadata ? accessoryAttributes({
104
- items: [
105
- {
106
- text: `${taskMetadata.exportName}.batchTrigger()`,
107
- variant: "normal"
108
- }
109
- ],
110
- style: "codepath"
111
- }) : {}
75
+ "cache.key": cacheKey,
76
+ [SemanticInternalAttributes.STYLE_ICON]: "device-sd-card"
112
77
  }
113
78
  });
114
- return response;
115
- },
116
- triggerAndWait: async ({ payload, options }) => {
117
- const ctx = taskContextManager.ctx;
118
- if (!ctx) {
119
- throw new Error("triggerAndWait can only be used from inside a task.run()");
120
- }
121
- const apiClient = apiClientManager.client;
122
- if (!apiClient) {
123
- throw apiClientMissingError();
124
- }
125
- const taskMetadata = runtime.getTaskMetadata(params.id);
126
- return await tracer.startActiveSpan(taskMetadata ? "Trigger" : `${params.id} triggerAndWait()`, async (span) => {
127
- const response = await apiClient.triggerTask(params.id, {
128
- payload,
129
- options: {
130
- dependentAttempt: ctx.attempt.id,
131
- lockToVersion: taskContextManager.worker?.version,
132
- queue: params.queue,
133
- concurrencyKey: options?.concurrencyKey,
134
- test: taskContextManager.ctx?.run.isTest
135
- }
136
- });
137
- if (!response.ok) {
138
- throw new Error(response.error);
139
- }
140
- span.setAttribute("messaging.message.id", response.data.id);
141
- const result = await runtime.waitForTask({
142
- id: response.data.id,
143
- ctx
144
- });
145
- const runResult = await handleTaskRunExecutionResult(result);
146
- if (!runResult.ok) {
147
- throw runResult.error;
148
- }
149
- return runResult.output;
150
- }, {
151
- kind: SpanKind.PRODUCER,
79
+ return value;
80
+ });
81
+ }, "cache");
82
+ }
83
+ __name(createCache, "createCache");
84
+ function onThrow(fn, options) {
85
+ const opts = {
86
+ ...defaultRetryOptions,
87
+ ...options
88
+ };
89
+ return tracer.startActiveSpan(`retry.onThrow()`, async (span) => {
90
+ let attempt = 1;
91
+ while (attempt <= opts.maxAttempts) {
92
+ const innerSpan = tracer.startSpan("retry.fn()", {
152
93
  attributes: {
153
- [SemanticInternalAttributes.STYLE_ICON]: "trigger",
154
- [SEMATTRS_MESSAGING_OPERATION]: "publish",
155
- ["messaging.client_id"]: taskContextManager.worker?.id,
156
- [SEMATTRS_MESSAGING_DESTINATION]: params.queue?.name ?? params.id,
157
- [SEMATTRS_MESSAGING_SYSTEM]: "trigger.dev",
158
- ...taskMetadata ? accessoryAttributes({
94
+ [SemanticInternalAttributes.STYLE_ICON]: "function",
95
+ ...accessoryAttributes({
159
96
  items: [
160
97
  {
161
- text: `${taskMetadata.exportName}.triggerAndWait()`,
98
+ text: `${attempt}/${opts.maxAttempts}`,
162
99
  variant: "normal"
163
100
  }
164
101
  ],
165
102
  style: "codepath"
166
- }) : {}
103
+ })
167
104
  }
168
105
  });
169
- },
170
- batchTriggerAndWait: async ({ items }) => {
171
- const ctx = taskContextManager.ctx;
172
- if (!ctx) {
173
- throw new Error("batchTriggerAndWait can only be used from inside a task.run()");
174
- }
175
- const apiClient = apiClientManager.client;
176
- if (!apiClient) {
177
- throw apiClientMissingError();
178
- }
179
- const taskMetadata = runtime.getTaskMetadata(params.id);
180
- return await tracer.startActiveSpan(taskMetadata ? "Batch trigger" : `${params.id} batchTriggerAndWait()`, async (span) => {
181
- const response = await apiClient.batchTriggerTask(params.id, {
182
- items: items.map((item) => ({
183
- payload: item.payload,
184
- options: {
185
- lockToVersion: taskContextManager.worker?.version,
186
- queue: item.options?.queue ?? params.queue,
187
- concurrencyKey: item.options?.concurrencyKey,
188
- test: taskContextManager.ctx?.run.isTest
189
- }
190
- })),
191
- dependentAttempt: ctx.attempt.id
106
+ const contextWithSpanSet = trace.setSpan(context.active(), innerSpan);
107
+ try {
108
+ const result = await context.with(contextWithSpanSet, async () => {
109
+ return fn({
110
+ attempt,
111
+ maxAttempts: opts.maxAttempts
112
+ });
192
113
  });
193
- if (!response.ok) {
194
- throw new Error(response.error);
114
+ innerSpan.end();
115
+ return result;
116
+ } catch (e) {
117
+ if (e instanceof Error || typeof e === "string") {
118
+ innerSpan.recordException(e);
119
+ } else {
120
+ innerSpan.recordException(String(e));
195
121
  }
196
- span.setAttribute("messaging.message.id", response.data.batchId);
197
- const result = await runtime.waitForBatch({
198
- id: response.data.batchId,
199
- runs: response.data.runs,
200
- ctx
122
+ innerSpan.setStatus({
123
+ code: SpanStatusCode.ERROR
201
124
  });
202
- const runs = await handleBatchTaskRunExecutionResult(result.items);
203
- return {
204
- id: result.id,
205
- runs
206
- };
207
- }, {
208
- kind: SpanKind.PRODUCER,
209
- attributes: {
210
- [SEMATTRS_MESSAGING_OPERATION]: "publish",
211
- ["messaging.batch.message_count"]: items.length,
212
- ["messaging.client_id"]: taskContextManager.worker?.id,
213
- [SEMATTRS_MESSAGING_DESTINATION]: params.queue?.name ?? params.id,
214
- ["messaging.message.body.size"]: items.map((item) => JSON.stringify(item.payload)).join("").length,
215
- [SEMATTRS_MESSAGING_SYSTEM]: "trigger.dev",
216
- [SemanticInternalAttributes.STYLE_ICON]: "trigger",
217
- ...taskMetadata ? accessoryAttributes({
218
- items: [
219
- {
220
- text: `${taskMetadata.exportName}.batchTriggerAndWait()`,
221
- variant: "normal"
222
- }
223
- ],
224
- style: "codepath"
225
- }) : {}
125
+ const nextRetryDelay = calculateNextRetryDelay(opts, attempt);
126
+ if (!nextRetryDelay) {
127
+ innerSpan.end();
128
+ throw e;
226
129
  }
227
- });
228
- }
229
- };
230
- Object.defineProperty(task2, "__trigger", {
231
- value: {
232
- id: params.id,
233
- packageVersion: version,
234
- queue: params.queue,
235
- retry: params.retry ? {
236
- ...defaultRetryOptions,
237
- ...params.retry
238
- } : void 0,
239
- machine: params.machine,
240
- fns: {
241
- run: params.run,
242
- init: params.init,
243
- cleanup: params.cleanup,
244
- middleware: params.middleware,
245
- handleError: params.handleError
130
+ innerSpan.setAttribute(SemanticInternalAttributes.RETRY_AT, new Date(Date.now() + nextRetryDelay).toISOString());
131
+ innerSpan.setAttribute(SemanticInternalAttributes.RETRY_COUNT, attempt);
132
+ innerSpan.setAttribute(SemanticInternalAttributes.RETRY_DELAY, `${nextRetryDelay}ms`);
133
+ innerSpan.end();
134
+ await runtime.waitForDuration(nextRetryDelay);
135
+ } finally {
136
+ attempt++;
246
137
  }
247
- },
248
- enumerable: false
249
- });
250
- return task2;
251
- }
252
- __name(createTask, "createTask");
253
- async function handleBatchTaskRunExecutionResult(items) {
254
- const someObjectStoreOutputs = items.some((item) => item.ok && item.outputType === "application/store");
255
- if (!someObjectStoreOutputs) {
256
- const results = await Promise.all(items.map(async (item) => {
257
- return await handleTaskRunExecutionResult(item);
258
- }));
259
- return results;
260
- }
261
- return await tracer.startActiveSpan("store.downloadPayloads", async (span) => {
262
- const results = await Promise.all(items.map(async (item) => {
263
- return await handleTaskRunExecutionResult(item);
264
- }));
265
- return results;
138
+ }
139
+ throw new Error("Max attempts reached");
266
140
  }, {
267
- kind: SpanKind.INTERNAL,
268
- [SemanticInternalAttributes.STYLE_ICON]: "cloud-download"
269
- });
270
- }
271
- __name(handleBatchTaskRunExecutionResult, "handleBatchTaskRunExecutionResult");
272
- async function handleTaskRunExecutionResult(execution) {
273
- if (execution.ok) {
274
- const outputPacket = {
275
- data: execution.output,
276
- dataType: execution.outputType
277
- };
278
- const importedPacket = await conditionallyImportPacket(outputPacket, tracer);
279
- return {
280
- ok: true,
281
- id: execution.id,
282
- output: await parsePacket(importedPacket)
283
- };
284
- } else {
285
- return {
286
- ok: false,
287
- id: execution.id,
288
- error: createErrorTaskError(execution.error)
289
- };
290
- }
291
- }
292
- __name(handleTaskRunExecutionResult, "handleTaskRunExecutionResult");
293
- function apiClientMissingError() {
294
- const hasBaseUrl = !!apiClientManager.baseURL;
295
- const hasAccessToken = !!apiClientManager.accessToken;
296
- if (!hasBaseUrl && !hasAccessToken) {
297
- return `You need to set the TRIGGER_API_URL and TRIGGER_SECRET_KEY environment variables.`;
298
- } else if (!hasBaseUrl) {
299
- return `You need to set the TRIGGER_API_URL environment variable.`;
300
- } else if (!hasAccessToken) {
301
- return `You need to set the TRIGGER_SECRET_KEY environment variable.`;
302
- }
303
- return `Unknown error`;
304
- }
305
- __name(apiClientMissingError, "apiClientMissingError");
306
-
307
- // src/v3/tasks.ts
308
- function task(options) {
309
- return createTask(options);
310
- }
311
- __name(task, "task");
312
- var wait = {
313
- for: async (options) => {
314
- return tracer.startActiveSpan(`wait.for()`, async (span) => {
315
- const durationInMs = calculateDurationInMs(options);
316
- await runtime.waitForDuration(durationInMs);
317
- }, {
318
- attributes: {
319
- [SemanticInternalAttributes.STYLE_ICON]: "wait",
320
- ...accessoryAttributes({
321
- items: [
322
- {
323
- text: nameForWaitOptions(options),
324
- variant: "normal"
325
- }
326
- ],
327
- style: "codepath"
328
- })
329
- }
330
- });
331
- },
332
- until: async (options) => {
333
- return tracer.startActiveSpan(`wait.until()`, async (span) => {
334
- const start = Date.now();
335
- if (options.throwIfInThePast && options.date < /* @__PURE__ */ new Date()) {
336
- throw new Error("Date is in the past");
337
- }
338
- const durationInMs = options.date.getTime() - start;
339
- await runtime.waitForDuration(durationInMs);
340
- }, {
341
- attributes: {
342
- [SemanticInternalAttributes.STYLE_ICON]: "wait",
343
- ...accessoryAttributes({
344
- items: [
345
- {
346
- text: options.date.toISOString(),
347
- variant: "normal"
348
- }
349
- ],
350
- style: "codepath"
351
- })
352
- }
353
- });
354
- }
355
- };
356
- function nameForWaitOptions(options) {
357
- if ("seconds" in options) {
358
- return options.seconds === 1 ? `1 second` : `${options.seconds} seconds`;
359
- }
360
- if ("minutes" in options) {
361
- return options.minutes === 1 ? `1 minute` : `${options.minutes} minutes`;
362
- }
363
- if ("hours" in options) {
364
- return options.hours === 1 ? `1 hour` : `${options.hours} hours`;
365
- }
366
- if ("days" in options) {
367
- return options.days === 1 ? `1 day` : `${options.days} days`;
368
- }
369
- if ("weeks" in options) {
370
- return options.weeks === 1 ? `1 week` : `${options.weeks} weeks`;
371
- }
372
- if ("months" in options) {
373
- return options.months === 1 ? `1 month` : `${options.months} months`;
374
- }
375
- if ("years" in options) {
376
- return options.years === 1 ? `1 year` : `${options.years} years`;
377
- }
378
- return "NaN";
379
- }
380
- __name(nameForWaitOptions, "nameForWaitOptions");
381
- function calculateDurationInMs(options) {
382
- if ("seconds" in options) {
383
- return options.seconds * 1e3;
384
- }
385
- if ("minutes" in options) {
386
- return options.minutes * 1e3 * 60;
387
- }
388
- if ("hours" in options) {
389
- return options.hours * 1e3 * 60 * 60;
390
- }
391
- if ("days" in options) {
392
- return options.days * 1e3 * 60 * 60 * 24;
393
- }
394
- if ("weeks" in options) {
395
- return options.weeks * 1e3 * 60 * 60 * 24 * 7;
396
- }
397
- if ("months" in options) {
398
- return options.months * 1e3 * 60 * 60 * 24 * 30;
399
- }
400
- if ("years" in options) {
401
- return options.years * 1e3 * 60 * 60 * 24 * 365;
402
- }
403
- throw new Error("Invalid options");
404
- }
405
- __name(calculateDurationInMs, "calculateDurationInMs");
406
- var _InMemoryCache = class _InMemoryCache {
407
- constructor() {
408
- __publicField(this, "_cache", /* @__PURE__ */ new Map());
409
- }
410
- get(key) {
411
- return this._cache.get(key);
412
- }
413
- set(key, value) {
414
- this._cache.set(key, value);
415
- return void 0;
416
- }
417
- delete(key) {
418
- this._cache.delete(key);
419
- return void 0;
420
- }
421
- };
422
- __name(_InMemoryCache, "InMemoryCache");
423
- var InMemoryCache = _InMemoryCache;
424
- function createCache(store) {
425
- return /* @__PURE__ */ __name(function cache(cacheKey, fn) {
426
- return tracer.startActiveSpan("cache", async (span) => {
427
- span.setAttribute("cache.key", cacheKey);
428
- span.setAttribute(SemanticInternalAttributes.STYLE_ICON, "device-sd-card");
429
- const cacheEntry = await store.get(cacheKey);
430
- if (cacheEntry) {
431
- span.updateName(`cache.hit ${cacheKey}`);
432
- return cacheEntry.value;
433
- }
434
- span.updateName(`cache.miss ${cacheKey}`);
435
- const value = await tracer.startActiveSpan("cache.getFreshValue", async (span2) => {
436
- return await fn();
437
- }, {
438
- attributes: {
439
- "cache.key": cacheKey,
440
- [SemanticInternalAttributes.STYLE_ICON]: "device-sd-card"
441
- }
442
- });
443
- await tracer.startActiveSpan("cache.set", async (span2) => {
444
- await store.set(cacheKey, {
445
- value,
446
- metadata: {
447
- createdTime: Date.now()
448
- }
449
- });
450
- }, {
451
- attributes: {
452
- "cache.key": cacheKey,
453
- [SemanticInternalAttributes.STYLE_ICON]: "device-sd-card"
454
- }
455
- });
456
- return value;
457
- });
458
- }, "cache");
459
- }
460
- __name(createCache, "createCache");
461
- function onThrow(fn, options) {
462
- const opts = {
463
- ...defaultRetryOptions,
464
- ...options
465
- };
466
- return tracer.startActiveSpan(`retry.onThrow()`, async (span) => {
467
- let attempt = 1;
468
- while (attempt <= opts.maxAttempts) {
469
- const innerSpan = tracer.startSpan("retry.fn()", {
470
- attributes: {
471
- [SemanticInternalAttributes.STYLE_ICON]: "function",
472
- ...accessoryAttributes({
473
- items: [
474
- {
475
- text: `${attempt}/${opts.maxAttempts}`,
476
- variant: "normal"
477
- }
478
- ],
479
- style: "codepath"
480
- })
481
- }
482
- });
483
- const contextWithSpanSet = trace.setSpan(context.active(), innerSpan);
484
- try {
485
- const result = await context.with(contextWithSpanSet, async () => {
486
- return fn({
487
- attempt,
488
- maxAttempts: opts.maxAttempts
489
- });
490
- });
491
- innerSpan.end();
492
- return result;
493
- } catch (e) {
494
- if (e instanceof Error || typeof e === "string") {
495
- innerSpan.recordException(e);
496
- } else {
497
- innerSpan.recordException(String(e));
498
- }
499
- innerSpan.setStatus({
500
- code: SpanStatusCode.ERROR
501
- });
502
- const nextRetryDelay = calculateNextRetryDelay(opts, attempt);
503
- if (!nextRetryDelay) {
504
- innerSpan.end();
505
- throw e;
506
- }
507
- innerSpan.setAttribute(SemanticInternalAttributes.RETRY_AT, new Date(Date.now() + nextRetryDelay).toISOString());
508
- innerSpan.setAttribute(SemanticInternalAttributes.RETRY_COUNT, attempt);
509
- innerSpan.setAttribute(SemanticInternalAttributes.RETRY_DELAY, `${nextRetryDelay}ms`);
510
- innerSpan.end();
511
- await runtime.waitForDuration(nextRetryDelay);
512
- } finally {
513
- attempt++;
514
- }
515
- }
516
- throw new Error("Max attempts reached");
517
- }, {
518
- attributes: {
519
- [SemanticInternalAttributes.STYLE_ICON]: "arrow-capsule"
520
- }
141
+ attributes: {
142
+ [SemanticInternalAttributes.STYLE_ICON]: "arrow-capsule"
143
+ }
521
144
  });
522
145
  }
523
146
  __name(onThrow, "onThrow");
@@ -877,7 +500,549 @@ var retry = {
877
500
  fetch: retryFetch,
878
501
  interceptFetch
879
502
  };
503
+ function queue(options) {
504
+ return options;
505
+ }
506
+ __name(queue, "queue");
507
+ function createTask(params) {
508
+ const task3 = {
509
+ id: params.id,
510
+ trigger: async (payload, options) => {
511
+ const apiClient = apiClientManager.client;
512
+ if (!apiClient) {
513
+ throw apiClientMissingError();
514
+ }
515
+ const taskMetadata = taskCatalog.getTaskMetadata(params.id);
516
+ const payloadPacket = await stringifyIO(payload);
517
+ const handle = await tracer.startActiveSpan(taskMetadata ? "Trigger" : `${params.id} trigger()`, async (span) => {
518
+ const response = await apiClient.triggerTask(params.id, {
519
+ payload: payloadPacket.data,
520
+ options: {
521
+ queue: params.queue,
522
+ concurrencyKey: options?.concurrencyKey,
523
+ test: taskContext.ctx?.run.isTest,
524
+ payloadType: payloadPacket.dataType,
525
+ idempotencyKey: options?.idempotencyKey
526
+ }
527
+ }, {
528
+ spanParentAsLink: true
529
+ });
530
+ span.setAttribute("messaging.message.id", response.id);
531
+ return response;
532
+ }, {
533
+ kind: SpanKind.PRODUCER,
534
+ attributes: {
535
+ [SEMATTRS_MESSAGING_OPERATION]: "publish",
536
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
537
+ ["messaging.client_id"]: taskContext.worker?.id,
538
+ [SEMATTRS_MESSAGING_DESTINATION]: params.queue?.name ?? params.id,
539
+ [SEMATTRS_MESSAGING_SYSTEM]: "trigger.dev",
540
+ ...taskMetadata ? accessoryAttributes({
541
+ items: [
542
+ {
543
+ text: `${taskMetadata.exportName}.trigger()`,
544
+ variant: "normal"
545
+ }
546
+ ],
547
+ style: "codepath"
548
+ }) : {}
549
+ }
550
+ });
551
+ return handle;
552
+ },
553
+ batchTrigger: async (items) => {
554
+ const apiClient = apiClientManager.client;
555
+ if (!apiClient) {
556
+ throw apiClientMissingError();
557
+ }
558
+ const taskMetadata = taskCatalog.getTaskMetadata(params.id);
559
+ const response = await tracer.startActiveSpan(taskMetadata ? "Batch trigger" : `${params.id} batchTrigger()`, async (span) => {
560
+ const response2 = await apiClient.batchTriggerTask(params.id, {
561
+ items: await Promise.all(items.map(async (item) => {
562
+ const payloadPacket = await stringifyIO(item.payload);
563
+ return {
564
+ payload: payloadPacket.data,
565
+ options: {
566
+ queue: item.options?.queue ?? params.queue,
567
+ concurrencyKey: item.options?.concurrencyKey,
568
+ test: taskContext.ctx?.run.isTest,
569
+ payloadType: payloadPacket.dataType,
570
+ idempotencyKey: item.options?.idempotencyKey
571
+ }
572
+ };
573
+ }))
574
+ }, {
575
+ spanParentAsLink: true
576
+ });
577
+ span.setAttribute("messaging.message.id", response2.batchId);
578
+ return response2;
579
+ }, {
580
+ kind: SpanKind.PRODUCER,
581
+ attributes: {
582
+ [SEMATTRS_MESSAGING_OPERATION]: "publish",
583
+ ["messaging.batch.message_count"]: items.length,
584
+ ["messaging.client_id"]: taskContext.worker?.id,
585
+ [SEMATTRS_MESSAGING_DESTINATION]: params.queue?.name ?? params.id,
586
+ [SEMATTRS_MESSAGING_SYSTEM]: "trigger.dev",
587
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
588
+ ...taskMetadata ? accessoryAttributes({
589
+ items: [
590
+ {
591
+ text: `${taskMetadata.exportName}.batchTrigger()`,
592
+ variant: "normal"
593
+ }
594
+ ],
595
+ style: "codepath"
596
+ }) : {}
597
+ }
598
+ });
599
+ return response;
600
+ },
601
+ triggerAndWait: async (payload, options) => {
602
+ const ctx = taskContext.ctx;
603
+ if (!ctx) {
604
+ throw new Error("triggerAndWait can only be used from inside a task.run()");
605
+ }
606
+ const apiClient = apiClientManager.client;
607
+ if (!apiClient) {
608
+ throw apiClientMissingError();
609
+ }
610
+ const taskMetadata = taskCatalog.getTaskMetadata(params.id);
611
+ const payloadPacket = await stringifyIO(payload);
612
+ return await tracer.startActiveSpan(taskMetadata ? "Trigger" : `${params.id} triggerAndWait()`, async (span) => {
613
+ const response = await apiClient.triggerTask(params.id, {
614
+ payload: payloadPacket.data,
615
+ options: {
616
+ dependentAttempt: ctx.attempt.id,
617
+ lockToVersion: taskContext.worker?.version,
618
+ queue: params.queue,
619
+ concurrencyKey: options?.concurrencyKey,
620
+ test: taskContext.ctx?.run.isTest,
621
+ payloadType: payloadPacket.dataType,
622
+ idempotencyKey: options?.idempotencyKey
623
+ }
624
+ });
625
+ span.setAttribute("messaging.message.id", response.id);
626
+ if (options?.idempotencyKey) {
627
+ const result2 = await apiClient.getRunResult(response.id);
628
+ if (result2) {
629
+ logger.log(`Result reused from previous task run with idempotency key '${options.idempotencyKey}'.`, {
630
+ runId: response.id,
631
+ idempotencyKey: options.idempotencyKey
632
+ });
633
+ return await handleTaskRunExecutionResult(result2);
634
+ }
635
+ }
636
+ const result = await runtime.waitForTask({
637
+ id: response.id,
638
+ ctx
639
+ });
640
+ return await handleTaskRunExecutionResult(result);
641
+ }, {
642
+ kind: SpanKind.PRODUCER,
643
+ attributes: {
644
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
645
+ [SEMATTRS_MESSAGING_OPERATION]: "publish",
646
+ ["messaging.client_id"]: taskContext.worker?.id,
647
+ [SEMATTRS_MESSAGING_DESTINATION]: params.queue?.name ?? params.id,
648
+ [SEMATTRS_MESSAGING_SYSTEM]: "trigger.dev",
649
+ ...taskMetadata ? accessoryAttributes({
650
+ items: [
651
+ {
652
+ text: `${taskMetadata.exportName}.triggerAndWait()`,
653
+ variant: "normal"
654
+ }
655
+ ],
656
+ style: "codepath"
657
+ }) : {}
658
+ }
659
+ });
660
+ },
661
+ batchTriggerAndWait: async (items) => {
662
+ const ctx = taskContext.ctx;
663
+ if (!ctx) {
664
+ throw new Error("batchTriggerAndWait can only be used from inside a task.run()");
665
+ }
666
+ const apiClient = apiClientManager.client;
667
+ if (!apiClient) {
668
+ throw apiClientMissingError();
669
+ }
670
+ const taskMetadata = taskCatalog.getTaskMetadata(params.id);
671
+ return await tracer.startActiveSpan(taskMetadata ? "Batch trigger" : `${params.id} batchTriggerAndWait()`, async (span) => {
672
+ const response = await apiClient.batchTriggerTask(params.id, {
673
+ items: await Promise.all(items.map(async (item) => {
674
+ const payloadPacket = await stringifyIO(item.payload);
675
+ return {
676
+ payload: payloadPacket.data,
677
+ options: {
678
+ lockToVersion: taskContext.worker?.version,
679
+ queue: item.options?.queue ?? params.queue,
680
+ concurrencyKey: item.options?.concurrencyKey,
681
+ test: taskContext.ctx?.run.isTest,
682
+ payloadType: payloadPacket.dataType,
683
+ idempotencyKey: item.options?.idempotencyKey
684
+ }
685
+ };
686
+ })),
687
+ dependentAttempt: ctx.attempt.id
688
+ });
689
+ span.setAttribute("messaging.message.id", response.batchId);
690
+ const getBatchResults = /* @__PURE__ */ __name(async () => {
691
+ const hasIdempotencyKey = items.some((item) => item.options?.idempotencyKey);
692
+ if (hasIdempotencyKey) {
693
+ const results = await apiClient.getBatchResults(response.batchId);
694
+ if (results) {
695
+ return results;
696
+ }
697
+ }
698
+ return {
699
+ id: response.batchId,
700
+ items: []
701
+ };
702
+ }, "getBatchResults");
703
+ const existingResults = await getBatchResults();
704
+ const incompleteRuns = response.runs.filter((runId) => !existingResults.items.some((item) => item.id === runId));
705
+ if (incompleteRuns.length === 0) {
706
+ logger.log(`Results reused from previous task runs because of the provided idempotency keys.`);
707
+ const runs3 = await handleBatchTaskRunExecutionResult(existingResults.items);
708
+ return {
709
+ id: existingResults.id,
710
+ runs: runs3
711
+ };
712
+ }
713
+ const result = await runtime.waitForBatch({
714
+ id: response.batchId,
715
+ runs: incompleteRuns,
716
+ ctx
717
+ });
718
+ const combinedItems = [];
719
+ for (const runId of response.runs) {
720
+ const existingItem = existingResults.items.find((item) => item.id === runId);
721
+ if (existingItem) {
722
+ combinedItems.push(existingItem);
723
+ } else {
724
+ const newItem = result.items.find((item) => item.id === runId);
725
+ if (newItem) {
726
+ combinedItems.push(newItem);
727
+ }
728
+ }
729
+ }
730
+ const runs2 = await handleBatchTaskRunExecutionResult(combinedItems);
731
+ return {
732
+ id: result.id,
733
+ runs: runs2
734
+ };
735
+ }, {
736
+ kind: SpanKind.PRODUCER,
737
+ attributes: {
738
+ [SEMATTRS_MESSAGING_OPERATION]: "publish",
739
+ ["messaging.batch.message_count"]: items.length,
740
+ ["messaging.client_id"]: taskContext.worker?.id,
741
+ [SEMATTRS_MESSAGING_DESTINATION]: params.queue?.name ?? params.id,
742
+ [SEMATTRS_MESSAGING_SYSTEM]: "trigger.dev",
743
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
744
+ ...taskMetadata ? accessoryAttributes({
745
+ items: [
746
+ {
747
+ text: `${taskMetadata.exportName}.batchTriggerAndWait()`,
748
+ variant: "normal"
749
+ }
750
+ ],
751
+ style: "codepath"
752
+ }) : {}
753
+ }
754
+ });
755
+ }
756
+ };
757
+ taskCatalog.registerTaskMetadata({
758
+ id: params.id,
759
+ packageVersion: version,
760
+ queue: params.queue,
761
+ retry: params.retry ? {
762
+ ...defaultRetryOptions,
763
+ ...params.retry
764
+ } : void 0,
765
+ machine: params.machine,
766
+ fns: {
767
+ run: params.run,
768
+ init: params.init,
769
+ cleanup: params.cleanup,
770
+ middleware: params.middleware,
771
+ handleError: params.handleError,
772
+ onSuccess: params.onSuccess,
773
+ onFailure: params.onFailure,
774
+ onStart: params.onStart
775
+ }
776
+ });
777
+ return task3;
778
+ }
779
+ __name(createTask, "createTask");
780
+ async function handleBatchTaskRunExecutionResult(items) {
781
+ const someObjectStoreOutputs = items.some((item) => item.ok && item.outputType === "application/store");
782
+ if (!someObjectStoreOutputs) {
783
+ const results = await Promise.all(items.map(async (item) => {
784
+ return await handleTaskRunExecutionResult(item);
785
+ }));
786
+ return results;
787
+ }
788
+ return await tracer.startActiveSpan("store.downloadPayloads", async (span) => {
789
+ const results = await Promise.all(items.map(async (item) => {
790
+ return await handleTaskRunExecutionResult(item);
791
+ }));
792
+ return results;
793
+ }, {
794
+ kind: SpanKind.INTERNAL,
795
+ [SemanticInternalAttributes.STYLE_ICON]: "cloud-download"
796
+ });
797
+ }
798
+ __name(handleBatchTaskRunExecutionResult, "handleBatchTaskRunExecutionResult");
799
+ async function handleTaskRunExecutionResult(execution) {
800
+ if (execution.ok) {
801
+ const outputPacket = {
802
+ data: execution.output,
803
+ dataType: execution.outputType
804
+ };
805
+ const importedPacket = await conditionallyImportPacket(outputPacket, tracer);
806
+ return {
807
+ ok: true,
808
+ id: execution.id,
809
+ output: await parsePacket(importedPacket)
810
+ };
811
+ } else {
812
+ return {
813
+ ok: false,
814
+ id: execution.id,
815
+ error: createErrorTaskError(execution.error)
816
+ };
817
+ }
818
+ }
819
+ __name(handleTaskRunExecutionResult, "handleTaskRunExecutionResult");
820
+ function apiClientMissingError() {
821
+ const hasBaseUrl = !!apiClientManager.baseURL;
822
+ const hasAccessToken = !!apiClientManager.accessToken;
823
+ if (!hasBaseUrl && !hasAccessToken) {
824
+ return `You need to set the TRIGGER_API_URL and TRIGGER_SECRET_KEY environment variables.`;
825
+ } else if (!hasBaseUrl) {
826
+ return `You need to set the TRIGGER_API_URL environment variable.`;
827
+ } else if (!hasAccessToken) {
828
+ return `You need to set the TRIGGER_SECRET_KEY environment variable.`;
829
+ }
830
+ return `Unknown error`;
831
+ }
832
+ __name(apiClientMissingError, "apiClientMissingError");
833
+
834
+ // src/v3/tasks.ts
835
+ function task(options) {
836
+ return createTask(options);
837
+ }
838
+ __name(task, "task");
839
+ var wait = {
840
+ for: async (options) => {
841
+ return tracer.startActiveSpan(`wait.for()`, async (span) => {
842
+ const durationInMs = calculateDurationInMs(options);
843
+ await runtime.waitForDuration(durationInMs);
844
+ }, {
845
+ attributes: {
846
+ [SemanticInternalAttributes.STYLE_ICON]: "wait",
847
+ ...accessoryAttributes({
848
+ items: [
849
+ {
850
+ text: nameForWaitOptions(options),
851
+ variant: "normal"
852
+ }
853
+ ],
854
+ style: "codepath"
855
+ })
856
+ }
857
+ });
858
+ },
859
+ until: async (options) => {
860
+ return tracer.startActiveSpan(`wait.until()`, async (span) => {
861
+ const start = Date.now();
862
+ if (options.throwIfInThePast && options.date < /* @__PURE__ */ new Date()) {
863
+ throw new Error("Date is in the past");
864
+ }
865
+ const durationInMs = options.date.getTime() - start;
866
+ await runtime.waitForDuration(durationInMs);
867
+ }, {
868
+ attributes: {
869
+ [SemanticInternalAttributes.STYLE_ICON]: "wait",
870
+ ...accessoryAttributes({
871
+ items: [
872
+ {
873
+ text: options.date.toISOString(),
874
+ variant: "normal"
875
+ }
876
+ ],
877
+ style: "codepath"
878
+ })
879
+ }
880
+ });
881
+ }
882
+ };
883
+ function nameForWaitOptions(options) {
884
+ if ("seconds" in options) {
885
+ return options.seconds === 1 ? `1 second` : `${options.seconds} seconds`;
886
+ }
887
+ if ("minutes" in options) {
888
+ return options.minutes === 1 ? `1 minute` : `${options.minutes} minutes`;
889
+ }
890
+ if ("hours" in options) {
891
+ return options.hours === 1 ? `1 hour` : `${options.hours} hours`;
892
+ }
893
+ if ("days" in options) {
894
+ return options.days === 1 ? `1 day` : `${options.days} days`;
895
+ }
896
+ if ("weeks" in options) {
897
+ return options.weeks === 1 ? `1 week` : `${options.weeks} weeks`;
898
+ }
899
+ if ("months" in options) {
900
+ return options.months === 1 ? `1 month` : `${options.months} months`;
901
+ }
902
+ if ("years" in options) {
903
+ return options.years === 1 ? `1 year` : `${options.years} years`;
904
+ }
905
+ return "NaN";
906
+ }
907
+ __name(nameForWaitOptions, "nameForWaitOptions");
908
+ function calculateDurationInMs(options) {
909
+ if ("seconds" in options) {
910
+ return options.seconds * 1e3;
911
+ }
912
+ if ("minutes" in options) {
913
+ return options.minutes * 1e3 * 60;
914
+ }
915
+ if ("hours" in options) {
916
+ return options.hours * 1e3 * 60 * 60;
917
+ }
918
+ if ("days" in options) {
919
+ return options.days * 1e3 * 60 * 60 * 24;
920
+ }
921
+ if ("weeks" in options) {
922
+ return options.weeks * 1e3 * 60 * 60 * 24 * 7;
923
+ }
924
+ if ("months" in options) {
925
+ return options.months * 1e3 * 60 * 60 * 24 * 30;
926
+ }
927
+ if ("years" in options) {
928
+ return options.years * 1e3 * 60 * 60 * 24 * 365;
929
+ }
930
+ throw new Error("Invalid options");
931
+ }
932
+ __name(calculateDurationInMs, "calculateDurationInMs");
933
+ var runs = {
934
+ replay: replayRun,
935
+ cancel: cancelRun,
936
+ retrieve: retrieveRun
937
+ };
938
+ async function retrieveRun(runId) {
939
+ const apiClient = apiClientManager.client;
940
+ if (!apiClient) {
941
+ throw apiClientMissingError();
942
+ }
943
+ return await apiClient.retrieveRun(runId);
944
+ }
945
+ __name(retrieveRun, "retrieveRun");
946
+ async function replayRun(runId) {
947
+ const apiClient = apiClientManager.client;
948
+ if (!apiClient) {
949
+ throw apiClientMissingError();
950
+ }
951
+ return await apiClient.replayRun(runId);
952
+ }
953
+ __name(replayRun, "replayRun");
954
+ async function cancelRun(runId) {
955
+ const apiClient = apiClientManager.client;
956
+ if (!apiClient) {
957
+ throw apiClientMissingError();
958
+ }
959
+ return await apiClient.cancelRun(runId);
960
+ }
961
+ __name(cancelRun, "cancelRun");
962
+
963
+ // src/v3/schedules/index.ts
964
+ var schedules_exports = {};
965
+ __export(schedules_exports, {
966
+ activate: () => activate,
967
+ create: () => create,
968
+ deactivate: () => deactivate,
969
+ del: () => del,
970
+ list: () => list,
971
+ retrieve: () => retrieve,
972
+ task: () => task2,
973
+ update: () => update
974
+ });
975
+ function task2(params) {
976
+ const task3 = createTask(params);
977
+ taskCatalog.updateTaskMetadata(task3.id, {
978
+ triggerSource: "schedule"
979
+ });
980
+ return task3;
981
+ }
982
+ __name(task2, "task");
983
+ async function create(options) {
984
+ const apiClient = apiClientManager.client;
985
+ if (!apiClient) {
986
+ throw apiClientMissingError();
987
+ }
988
+ return apiClient.createSchedule(options);
989
+ }
990
+ __name(create, "create");
991
+ async function retrieve(scheduleId) {
992
+ const apiClient = apiClientManager.client;
993
+ if (!apiClient) {
994
+ throw apiClientMissingError();
995
+ }
996
+ return apiClient.retrieveSchedule(scheduleId);
997
+ }
998
+ __name(retrieve, "retrieve");
999
+ async function update(scheduleId, options) {
1000
+ const apiClient = apiClientManager.client;
1001
+ if (!apiClient) {
1002
+ throw apiClientMissingError();
1003
+ }
1004
+ return apiClient.updateSchedule(scheduleId, options);
1005
+ }
1006
+ __name(update, "update");
1007
+ async function del(scheduleId) {
1008
+ const apiClient = apiClientManager.client;
1009
+ if (!apiClient) {
1010
+ throw apiClientMissingError();
1011
+ }
1012
+ return apiClient.deleteSchedule(scheduleId);
1013
+ }
1014
+ __name(del, "del");
1015
+ async function deactivate(scheduleId) {
1016
+ const apiClient = apiClientManager.client;
1017
+ if (!apiClient) {
1018
+ throw apiClientMissingError();
1019
+ }
1020
+ return apiClient.deactivateSchedule(scheduleId);
1021
+ }
1022
+ __name(deactivate, "deactivate");
1023
+ async function activate(scheduleId) {
1024
+ const apiClient = apiClientManager.client;
1025
+ if (!apiClient) {
1026
+ throw apiClientMissingError();
1027
+ }
1028
+ return apiClient.activateSchedule(scheduleId);
1029
+ }
1030
+ __name(activate, "activate");
1031
+ async function list(options) {
1032
+ const apiClient = apiClientManager.client;
1033
+ if (!apiClient) {
1034
+ throw apiClientMissingError();
1035
+ }
1036
+ return apiClient.listSchedules(options);
1037
+ }
1038
+ __name(list, "list");
1039
+
1040
+ // src/v3/index.ts
1041
+ function configure(options) {
1042
+ apiClientManager.setGlobalAPIClientConfiguration(options);
1043
+ }
1044
+ __name(configure, "configure");
880
1045
 
881
- export { InMemoryCache, createCache, retry, task, wait };
1046
+ export { InMemoryCache, configure, createCache, queue, retry, runs, schedules_exports as schedules, task, wait };
882
1047
  //# sourceMappingURL=out.js.map
883
1048
  //# sourceMappingURL=index.mjs.map