@trigger.dev/sdk 4.5.0-rc.6 → 4.5.0-rc.7
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/ai.d.ts +171 -5
- package/dist/commonjs/v3/ai.js +309 -22
- package/dist/commonjs/v3/ai.js.map +1 -1
- package/dist/commonjs/v3/chat-server.d.ts +8 -0
- package/dist/commonjs/v3/chat-server.js +32 -10
- package/dist/commonjs/v3/chat-server.js.map +1 -1
- package/dist/commonjs/v3/chat-server.test.js +51 -0
- package/dist/commonjs/v3/chat-server.test.js.map +1 -1
- package/dist/commonjs/v3/createStartSessionAction.test.js +30 -0
- package/dist/commonjs/v3/createStartSessionAction.test.js.map +1 -1
- package/dist/commonjs/v3/sessions.d.ts +3 -2
- package/dist/commonjs/v3/sessions.js +3 -2
- package/dist/commonjs/v3/sessions.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/v3/ai.d.ts +171 -5
- package/dist/esm/v3/ai.js +309 -22
- package/dist/esm/v3/ai.js.map +1 -1
- package/dist/esm/v3/chat-server.d.ts +8 -0
- package/dist/esm/v3/chat-server.js +32 -10
- package/dist/esm/v3/chat-server.js.map +1 -1
- package/dist/esm/v3/chat-server.test.js +51 -0
- package/dist/esm/v3/chat-server.test.js.map +1 -1
- package/dist/esm/v3/createStartSessionAction.test.js +30 -0
- package/dist/esm/v3/createStartSessionAction.test.js.map +1 -1
- package/dist/esm/v3/sessions.d.ts +3 -2
- package/dist/esm/v3/sessions.js +3 -2
- package/dist/esm/v3/sessions.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/docs/ai/prompts.mdx +430 -0
- package/docs/ai-chat/actions.mdx +115 -0
- package/docs/ai-chat/anatomy.mdx +71 -0
- package/docs/ai-chat/backend.mdx +817 -0
- package/docs/ai-chat/background-injection.mdx +221 -0
- package/docs/ai-chat/changelog.mdx +850 -0
- package/docs/ai-chat/chat-local.mdx +174 -0
- package/docs/ai-chat/client-protocol.mdx +1081 -0
- package/docs/ai-chat/compaction.mdx +411 -0
- package/docs/ai-chat/custom-agents.mdx +364 -0
- package/docs/ai-chat/error-handling.mdx +415 -0
- package/docs/ai-chat/fast-starts.mdx +672 -0
- package/docs/ai-chat/frontend.mdx +580 -0
- package/docs/ai-chat/how-it-works.mdx +230 -0
- package/docs/ai-chat/lifecycle-hooks.mdx +530 -0
- package/docs/ai-chat/mcp.mdx +101 -0
- package/docs/ai-chat/overview.mdx +90 -0
- package/docs/ai-chat/patterns/branching-conversations.mdx +284 -0
- package/docs/ai-chat/patterns/code-sandbox.mdx +126 -0
- package/docs/ai-chat/patterns/database-persistence.mdx +414 -0
- package/docs/ai-chat/patterns/human-in-the-loop.mdx +275 -0
- package/docs/ai-chat/patterns/large-payloads.mdx +169 -0
- package/docs/ai-chat/patterns/oom-resilience.mdx +120 -0
- package/docs/ai-chat/patterns/persistence-and-replay.mdx +211 -0
- package/docs/ai-chat/patterns/recovery-boot.mdx +230 -0
- package/docs/ai-chat/patterns/skills.mdx +221 -0
- package/docs/ai-chat/patterns/sub-agents.mdx +383 -0
- package/docs/ai-chat/patterns/tool-result-auditing.mdx +148 -0
- package/docs/ai-chat/patterns/trusted-edge-signals.mdx +337 -0
- package/docs/ai-chat/patterns/version-upgrades.mdx +172 -0
- package/docs/ai-chat/pending-messages.mdx +343 -0
- package/docs/ai-chat/prompt-caching.mdx +206 -0
- package/docs/ai-chat/quick-start.mdx +161 -0
- package/docs/ai-chat/reference.mdx +909 -0
- package/docs/ai-chat/server-chat.mdx +263 -0
- package/docs/ai-chat/sessions.mdx +333 -0
- package/docs/ai-chat/testing.mdx +682 -0
- package/docs/ai-chat/tools.mdx +191 -0
- package/docs/ai-chat/types.mdx +242 -0
- package/docs/ai-chat/upgrade-guide.mdx +515 -0
- package/docs/apikeys.mdx +54 -0
- package/docs/building-with-ai.mdx +261 -0
- package/docs/bulk-actions.mdx +49 -0
- package/docs/changelog.mdx +6 -0
- package/docs/cli-deploy-commands.mdx +9 -0
- package/docs/cli-dev-commands.mdx +9 -0
- package/docs/cli-dev.mdx +8 -0
- package/docs/cli-init-commands.mdx +58 -0
- package/docs/cli-introduction.mdx +25 -0
- package/docs/cli-list-profiles-commands.mdx +42 -0
- package/docs/cli-login-commands.mdx +33 -0
- package/docs/cli-logout-commands.mdx +33 -0
- package/docs/cli-preview-archive.mdx +59 -0
- package/docs/cli-promote-commands.mdx +9 -0
- package/docs/cli-switch.mdx +43 -0
- package/docs/cli-update-commands.mdx +42 -0
- package/docs/cli-whoami-commands.mdx +33 -0
- package/docs/community.mdx +6 -0
- package/docs/config/config-file.mdx +602 -0
- package/docs/config/extensions/additionalFiles.mdx +38 -0
- package/docs/config/extensions/additionalPackages.mdx +40 -0
- package/docs/config/extensions/aptGet.mdx +34 -0
- package/docs/config/extensions/audioWaveform.mdx +20 -0
- package/docs/config/extensions/custom.mdx +380 -0
- package/docs/config/extensions/emitDecoratorMetadata.mdx +29 -0
- package/docs/config/extensions/esbuildPlugin.mdx +31 -0
- package/docs/config/extensions/ffmpeg.mdx +45 -0
- package/docs/config/extensions/lightpanda.mdx +56 -0
- package/docs/config/extensions/overview.mdx +67 -0
- package/docs/config/extensions/playwright.mdx +195 -0
- package/docs/config/extensions/prismaExtension.mdx +1014 -0
- package/docs/config/extensions/puppeteer.mdx +30 -0
- package/docs/config/extensions/pythonExtension.mdx +182 -0
- package/docs/config/extensions/syncEnvVars.mdx +291 -0
- package/docs/context.mdx +235 -0
- package/docs/database-connections.mdx +213 -0
- package/docs/deploy-environment-variables.mdx +435 -0
- package/docs/deployment/atomic-deployment.mdx +172 -0
- package/docs/deployment/overview.mdx +257 -0
- package/docs/deployment/preview-branches.mdx +224 -0
- package/docs/errors-retrying.mdx +379 -0
- package/docs/github-actions.mdx +222 -0
- package/docs/github-integration.mdx +136 -0
- package/docs/github-repo.mdx +8 -0
- package/docs/help-email.mdx +6 -0
- package/docs/help-slack.mdx +11 -0
- package/docs/hidden-tasks.mdx +56 -0
- package/docs/how-it-works.mdx +454 -0
- package/docs/how-to-reduce-your-spend.mdx +217 -0
- package/docs/idempotency.mdx +504 -0
- package/docs/introduction.mdx +223 -0
- package/docs/limits.mdx +241 -0
- package/docs/logging.mdx +195 -0
- package/docs/machines.mdx +952 -0
- package/docs/manual-setup.mdx +632 -0
- package/docs/mcp-agent-rules.mdx +41 -0
- package/docs/mcp-introduction.mdx +385 -0
- package/docs/mcp-tools.mdx +273 -0
- package/docs/migrating-from-v3.mdx +334 -0
- package/docs/observability/dashboards.mdx +102 -0
- package/docs/observability/query.mdx +585 -0
- package/docs/open-source-contributing.mdx +16 -0
- package/docs/open-source-self-hosting.mdx +541 -0
- package/docs/private-networking/aws-console-setup.mdx +304 -0
- package/docs/private-networking/overview.mdx +144 -0
- package/docs/private-networking/troubleshooting.mdx +78 -0
- package/docs/queue-concurrency.mdx +354 -0
- package/docs/quick-start.mdx +97 -0
- package/docs/realtime/auth.mdx +208 -0
- package/docs/realtime/backend/overview.mdx +45 -0
- package/docs/realtime/backend/streams.mdx +418 -0
- package/docs/realtime/backend/subscribe.mdx +225 -0
- package/docs/realtime/how-it-works.mdx +94 -0
- package/docs/realtime/overview.mdx +63 -0
- package/docs/realtime/react-hooks/overview.mdx +73 -0
- package/docs/realtime/react-hooks/streams.mdx +449 -0
- package/docs/realtime/react-hooks/subscribe.mdx +674 -0
- package/docs/realtime/react-hooks/swr.mdx +87 -0
- package/docs/realtime/react-hooks/triggering.mdx +194 -0
- package/docs/realtime/react-hooks/use-wait-token.mdx +34 -0
- package/docs/realtime/run-object.mdx +174 -0
- package/docs/replaying.mdx +72 -0
- package/docs/request-feature.mdx +6 -0
- package/docs/roadmap.mdx +6 -0
- package/docs/run-tests.mdx +20 -0
- package/docs/run-usage.mdx +113 -0
- package/docs/runs/heartbeats.mdx +38 -0
- package/docs/runs/max-duration.mdx +139 -0
- package/docs/runs/metadata.mdx +734 -0
- package/docs/runs/priority.mdx +31 -0
- package/docs/runs.mdx +396 -0
- package/docs/self-hosting/docker.mdx +458 -0
- package/docs/self-hosting/env/supervisor.mdx +74 -0
- package/docs/self-hosting/env/webapp.mdx +276 -0
- package/docs/self-hosting/kubernetes.mdx +601 -0
- package/docs/self-hosting/overview.mdx +108 -0
- package/docs/skills.mdx +85 -0
- package/docs/tags.mdx +120 -0
- package/docs/tasks/overview.mdx +697 -0
- package/docs/tasks/scheduled.mdx +382 -0
- package/docs/tasks/schemaTask.mdx +413 -0
- package/docs/tasks/streams.mdx +884 -0
- package/docs/triggering.mdx +1320 -0
- package/docs/troubleshooting-alerts.mdx +385 -0
- package/docs/troubleshooting-debugging-in-vscode.mdx +8 -0
- package/docs/troubleshooting-github-issues.mdx +6 -0
- package/docs/troubleshooting-uptime-status.mdx +6 -0
- package/docs/troubleshooting.mdx +398 -0
- package/docs/upgrading-packages.mdx +80 -0
- package/docs/vercel-integration.mdx +207 -0
- package/docs/versioning.mdx +56 -0
- package/docs/video-walkthrough.mdx +23 -0
- package/docs/wait-for-token.mdx +540 -0
- package/docs/wait-for.mdx +42 -0
- package/docs/wait-until.mdx +53 -0
- package/docs/wait.mdx +18 -0
- package/docs/writing-tasks-introduction.mdx +33 -0
- package/package.json +8 -5
- package/skills/trigger-authoring-chat-agent/SKILL.md +296 -0
- package/skills/trigger-authoring-tasks/SKILL.md +254 -0
- package/skills/trigger-chat-agent-advanced/SKILL.md +368 -0
- package/skills/trigger-cost-savings/SKILL.md +116 -0
- package/skills/trigger-realtime-and-frontend/SKILL.md +276 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "GitHub integration"
|
|
3
|
+
description: "Automatically deploy your tasks on every push to your GitHub repository."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## How it works
|
|
7
|
+
|
|
8
|
+
Once you connect a GitHub repository to your project, you can configure tracking branches for the production and staging environments.
|
|
9
|
+
Every push to a tracked branch creates a deployment in the corresponding environment. Preview branch deployments are also supported for pull requests.
|
|
10
|
+
|
|
11
|
+
This eliminates the need to manually run the `trigger.dev deploy` command or set up custom CI/CD workflows.
|
|
12
|
+
|
|
13
|
+
## Setup
|
|
14
|
+
|
|
15
|
+
<Steps>
|
|
16
|
+
|
|
17
|
+
<Step title="Install our GitHub app">
|
|
18
|
+
Go to your project's settings page and click `Install GitHub app`.
|
|
19
|
+
This will take you to GitHub to authorize the Trigger.dev app for your organization or personal account.
|
|
20
|
+
</Step>
|
|
21
|
+
|
|
22
|
+
<Step title="Connect your repository">
|
|
23
|
+
Select a repository to connect to your project.
|
|
24
|
+
</Step>
|
|
25
|
+
|
|
26
|
+
<Step title="Configure branch tracking">
|
|
27
|
+
Choose which branches should trigger automatic deployments:
|
|
28
|
+
|
|
29
|
+
- **Production**: The branch that deploys to your production environment, e.g., `main`.
|
|
30
|
+
- **Staging**: The branch that deploys to your staging environment.
|
|
31
|
+
- **Preview**: Toggle to enable preview deployments for pull requests
|
|
32
|
+
</Step>
|
|
33
|
+
|
|
34
|
+
<Step title="Customize build settings (optional)">
|
|
35
|
+
Configure how your project is built:
|
|
36
|
+
|
|
37
|
+
- **Trigger config file**: Path to your `trigger.config.ts` file. By default, we look for it in the root of your repository. The path should be relative to the root of your repository and contain the config file name, e.g., `apps/tasks/trigger.config.ts`.
|
|
38
|
+
- **Install command**: Auto-detected by default, but you can override it if necessary. The command will be run from the root of your repository.
|
|
39
|
+
- **Pre-build command**: Run any commands before building and deploying your project, e.g., `pnpm run prisma:generate`. The command will be run from the root of your repository.
|
|
40
|
+
</Step>
|
|
41
|
+
|
|
42
|
+
</Steps>
|
|
43
|
+
|
|
44
|
+
## Branch tracking
|
|
45
|
+
|
|
46
|
+
Our GitHub integration uses branch tracking to determine when and where to deploy your code.
|
|
47
|
+
|
|
48
|
+

|
|
49
|
+
|
|
50
|
+
### Production and staging branches
|
|
51
|
+
|
|
52
|
+
When you connect a repository, the default branch of your repository will be used as the production tracking branch, by default.
|
|
53
|
+
|
|
54
|
+
When you configure a production or staging branch, every push to that branch will trigger a deployment.
|
|
55
|
+
Our build server will install the project dependencies, build your project, and deploy it to the corresponding environment.
|
|
56
|
+
|
|
57
|
+
If there are multiple consecutive pushes to a tracked branch, the later deployments will be queued until the previous deployment completes.
|
|
58
|
+
|
|
59
|
+
<Note>
|
|
60
|
+
When you connect a repository, the default branch of your repository will be used as the production tracking branch by default.
|
|
61
|
+
You can change this in the git settings of your project.
|
|
62
|
+
</Note>
|
|
63
|
+
|
|
64
|
+
### Pull requests
|
|
65
|
+
|
|
66
|
+
By default, pull requests will be deployed to preview branch environments, enabling you to test changes before merging.
|
|
67
|
+
When the pull request is merged or closed, the preview branch is automatically archived.
|
|
68
|
+
|
|
69
|
+
The name of the preview branch matches the branch name of the pull request.
|
|
70
|
+
|
|
71
|
+
<Note>
|
|
72
|
+
Preview branch deployments require the preview environment to be enabled on your project. Learn more about [preview branches](/deployment/preview-branches).
|
|
73
|
+
</Note>
|
|
74
|
+
|
|
75
|
+
## Disconnecting a repository
|
|
76
|
+
|
|
77
|
+
You can disconnect a repository at any time from your project git settings. This will stop automatic deployments triggered from GitHub.
|
|
78
|
+
|
|
79
|
+
## Managing repository access
|
|
80
|
+
|
|
81
|
+
To add or remove repository access for the Trigger.dev GitHub app, follow the link in the `Connect GitHub repository` modal:
|
|
82
|
+
|
|
83
|
+

|
|
84
|
+
|
|
85
|
+
Alternatively, you can follow these steps on GitHub:
|
|
86
|
+
|
|
87
|
+
1. Go to your GitHub account settings
|
|
88
|
+
2. Navigate to **Settings** → **Applications** → **Installed GitHub Apps**
|
|
89
|
+
3. Click **Configure** next to `Trigger.dev App`
|
|
90
|
+
4. Update repository access under `Repository access`
|
|
91
|
+
|
|
92
|
+
Changes to repository access will be reflected immediately in your Trigger.dev project settings.
|
|
93
|
+
|
|
94
|
+
## Environment variables at build time
|
|
95
|
+
|
|
96
|
+
You can expose environment variables during the build and deployment process by prefixing them with `TRIGGER_BUILD_`.
|
|
97
|
+
In the build server, the `TRIGGER_BUILD_` prefix is stripped from the variable name, i.e., `TRIGGER_BUILD_MY_TOKEN` is exposed as `MY_TOKEN`.
|
|
98
|
+
|
|
99
|
+
Build extensions will also have access to these variables.
|
|
100
|
+
|
|
101
|
+
<Note>
|
|
102
|
+
Build environment variables only apply to deployments in the environment you set them in.
|
|
103
|
+
</Note>
|
|
104
|
+
|
|
105
|
+
Learn more about managing [environment variables](/deploy-environment-variables).
|
|
106
|
+
|
|
107
|
+
## Using a private npm registry
|
|
108
|
+
|
|
109
|
+
If your project uses packages from a private npm registry, you can provide authentication by setting a `TRIGGER_BUILD_NPM_RC` environment variable.
|
|
110
|
+
|
|
111
|
+
The value should be the contents of your `.npmrc` file including any token credentials, encoded to base64.
|
|
112
|
+
|
|
113
|
+
### Example
|
|
114
|
+
|
|
115
|
+
Example `.npmrc` file containing credentials for a private npm registry and a GitHub package registry:
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
//registry.npmjs.org/:_authToken=<YOUR_NPM_TOKEN>
|
|
119
|
+
@<YOUR_NAMESPACE>:registry=https://npm.pkg.github.com
|
|
120
|
+
//npm.pkg.github.com/:always-auth=true
|
|
121
|
+
//npm.pkg.github.com/:_authToken=<YOUR_GITHUB_TOKEN>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Encode it to base64:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Encode your .npmrc file
|
|
128
|
+
cat .npmrc | base64
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Then, set the `TRIGGER_BUILD_NPM_RC` environment variable in your project settings with the encoded value.
|
|
132
|
+
|
|
133
|
+
<Note>
|
|
134
|
+
The build server will automatically create a `.npmrc` file in the installation directory based on the content of the `TRIGGER_BUILD_NPM_RC` environment variable.
|
|
135
|
+
This enables the build server to authenticate to your private npm registry.
|
|
136
|
+
</Note>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "GitHub repo"
|
|
3
|
+
url: "https://github.com/triggerdotdev/trigger.dev"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Trigger.dev is [Open Source on GitHub](https://github.com/triggerdotdev/trigger.dev). You can contribute to the project by submitting issues, pull requests, or simply by using it and providing feedback.
|
|
7
|
+
|
|
8
|
+
You can also [self-host](/open-source-self-hosting) the project if you want to run it on your own infrastructure.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Slack support"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
If you're on the Trigger.dev Pro plan, you can request a private Slack Connect channel.
|
|
6
|
+
|
|
7
|
+
To do this:
|
|
8
|
+
|
|
9
|
+
1. Login to the [Trigger.dev web app](https://cloud.trigger.dev).
|
|
10
|
+
2. Subscribe to a paid plan if you haven't already.
|
|
11
|
+
3. In the bottom-left corner click "Join our Slack".
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Hidden tasks"
|
|
3
|
+
description: "Create tasks that are not exported from your trigger files but can still be executed."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Hidden tasks are tasks that are not exported from your trigger files but can still be executed. These tasks are only accessible to other tasks within the same file or module where they're defined.
|
|
7
|
+
|
|
8
|
+
```ts trigger/my-task.ts
|
|
9
|
+
import { task } from "@trigger.dev/sdk";
|
|
10
|
+
|
|
11
|
+
// This is a hidden task - not exported
|
|
12
|
+
const internalTask = task({
|
|
13
|
+
id: "internal-processing",
|
|
14
|
+
run: async (payload: any, { ctx }) => {
|
|
15
|
+
// Internal processing logic
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Hidden tasks are useful for creating internal workflows that should only be triggered by other tasks in the same file:
|
|
21
|
+
|
|
22
|
+
```ts trigger/my-workflow.ts
|
|
23
|
+
import { task } from "@trigger.dev/sdk";
|
|
24
|
+
|
|
25
|
+
// Hidden task for internal use
|
|
26
|
+
const processData = task({
|
|
27
|
+
id: "process-data",
|
|
28
|
+
run: async (payload: { data: string }, { ctx }) => {
|
|
29
|
+
// Process the data
|
|
30
|
+
return { processed: payload.data.toUpperCase() };
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Public task that uses the hidden task
|
|
35
|
+
export const mainWorkflow = task({
|
|
36
|
+
id: "main-workflow",
|
|
37
|
+
run: async (payload: any, { ctx }) => {
|
|
38
|
+
const result = await processData.trigger({ data: payload.input });
|
|
39
|
+
return result;
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
You can also create packages of reusable tasks that can be imported and used without needing to re-export them:
|
|
45
|
+
|
|
46
|
+
```ts trigger/my-task.ts
|
|
47
|
+
import { task } from "@trigger.dev/sdk";
|
|
48
|
+
import { sendToSlack } from "@repo/tasks"; // Hidden task from another package
|
|
49
|
+
|
|
50
|
+
export const notificationTask = task({
|
|
51
|
+
id: "send-notification",
|
|
52
|
+
run: async (payload: any, { ctx }) => {
|
|
53
|
+
await sendToSlack.trigger(payload);
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
```
|
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "How it works"
|
|
3
|
+
sidebarTitle: "How it works"
|
|
4
|
+
description: "Understand how Trigger.dev works and how it can help you."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Introduction
|
|
8
|
+
|
|
9
|
+
Trigger.dev v3 allows you to integrate long-running async tasks into your application and run them in the background. This allows you to offload tasks that take a long time to complete, such as sending multi-day email campaigns, processing videos, or running long chains of AI tasks.
|
|
10
|
+
|
|
11
|
+
For example, the below task processes a video with `ffmpeg` and sends the results to an s3 bucket, then updates a database with the results and sends an email to the user.
|
|
12
|
+
|
|
13
|
+
```ts /trigger/video.ts
|
|
14
|
+
import { logger, task } from "@trigger.dev/sdk";
|
|
15
|
+
import { updateVideoUrl } from "../db.js";
|
|
16
|
+
import ffmpeg from "fluent-ffmpeg";
|
|
17
|
+
import { Readable } from "node:stream";
|
|
18
|
+
import type { ReadableStream } from "node:stream/web";
|
|
19
|
+
import * as fs from "node:fs/promises";
|
|
20
|
+
import * as path from "node:path";
|
|
21
|
+
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
|
|
22
|
+
import { sendEmail } from "../email.js";
|
|
23
|
+
import { getVideo } from "../db.js";
|
|
24
|
+
|
|
25
|
+
// Initialize S3 client
|
|
26
|
+
const s3Client = new S3Client({
|
|
27
|
+
region: process.env.AWS_REGION,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export const convertVideo = task({
|
|
31
|
+
id: "convert-video",
|
|
32
|
+
retry: {
|
|
33
|
+
maxAttempts: 5,
|
|
34
|
+
minTimeoutInMs: 1000,
|
|
35
|
+
maxTimeoutInMs: 10000,
|
|
36
|
+
factor: 2,
|
|
37
|
+
},
|
|
38
|
+
run: async ({ videoId }: { videoId: string }) => {
|
|
39
|
+
const { url, userId } = await getVideo(videoId);
|
|
40
|
+
|
|
41
|
+
const outputPath = path.join("/tmp", `output_${videoId}.mp4`);
|
|
42
|
+
|
|
43
|
+
const response = await fetch(url);
|
|
44
|
+
|
|
45
|
+
await new Promise((resolve, reject) => {
|
|
46
|
+
ffmpeg(Readable.fromWeb(response.body as ReadableStream))
|
|
47
|
+
.videoFilters("scale=iw/2:ih/2")
|
|
48
|
+
.output(outputPath)
|
|
49
|
+
.on("end", resolve)
|
|
50
|
+
.on("error", reject)
|
|
51
|
+
.run();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const processedContent = await fs.readFile(outputPath);
|
|
55
|
+
|
|
56
|
+
// Upload to S3
|
|
57
|
+
const s3Key = `processed-videos/output_${videoId}.mp4`;
|
|
58
|
+
|
|
59
|
+
const uploadParams = {
|
|
60
|
+
Bucket: process.env.S3_BUCKET,
|
|
61
|
+
Key: s3Key,
|
|
62
|
+
Body: processedContent,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
await s3Client.send(new PutObjectCommand(uploadParams));
|
|
66
|
+
const s3Url = `https://${process.env.S3_BUCKET}.s3.amazonaws.com/${s3Key}`;
|
|
67
|
+
|
|
68
|
+
logger.info("Video converted", { videoId, s3Url });
|
|
69
|
+
|
|
70
|
+
// Update database
|
|
71
|
+
await updateVideoUrl(videoId, s3Url);
|
|
72
|
+
|
|
73
|
+
await sendEmail(
|
|
74
|
+
userId,
|
|
75
|
+
"Video Processing Complete",
|
|
76
|
+
`Your video has been processed and is available at: ${s3Url}`
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
return { success: true, s3Url };
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Now in your application, you can trigger this task by calling:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { NextResponse } from "next/server";
|
|
88
|
+
import { tasks } from "@trigger.dev/sdk";
|
|
89
|
+
import type { convertVideo } from "./trigger/video";
|
|
90
|
+
// 👆 **type-only** import
|
|
91
|
+
|
|
92
|
+
export async function POST(request: Request) {
|
|
93
|
+
const body = await request.json();
|
|
94
|
+
|
|
95
|
+
// Trigger the task, this will return before the task is completed
|
|
96
|
+
const handle = await tasks.trigger<typeof convertVideo>("convert-video", body);
|
|
97
|
+
|
|
98
|
+
return NextResponse.json(handle);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
This will schedule the task to run in the background and return a handle that you can use to check the status of the task. This allows your backend application to respond quickly to the user and offload the long-running task to Trigger.dev.
|
|
103
|
+
|
|
104
|
+
## The CLI
|
|
105
|
+
|
|
106
|
+
Trigger.dev comes with a CLI that allows you to initialize Trigger.dev into your project, deploy your tasks, and run your tasks locally. You can run it via `npx` like so:
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
npx trigger.dev@latest login # Log in to your Trigger.dev account
|
|
110
|
+
npx trigger.dev@latest init # Initialize Trigger.dev in your project
|
|
111
|
+
npx trigger.dev@latest dev # Run your tasks locally
|
|
112
|
+
npx trigger.dev@latest deploy # Deploy your tasks to the Trigger.dev instance
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
All these commands work with the Trigger.dev cloud and/or your self-hosted instance. It supports multiple profiles so you can easily switch between different accounts or instances.
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
npx trigger.dev@latest login --profile <profile> -a https://trigger.example.com # Log in to a specific profile into a self-hosted instance
|
|
119
|
+
npx trigger.dev@latest dev --profile <profile> # Initialize Trigger.dev in your project
|
|
120
|
+
npx trigger.dev@latest deploy --profile <profile> # Deploy your tasks to the Trigger.dev instance
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Trigger.dev architecture
|
|
124
|
+
|
|
125
|
+
Trigger.dev implements a serverless architecture (without timeouts!) that allows you to run your tasks in a scalable and reliable way. When you run `npx trigger.dev@latest deploy`, we build and deploy your task code to your Trigger.dev instance. Then, when you trigger a task from your application, it's run in a secure, isolated environment with the resources you need to complete the task. A simplified diagram for a task execution looks like this:
|
|
126
|
+
|
|
127
|
+
```mermaid
|
|
128
|
+
sequenceDiagram
|
|
129
|
+
participant App
|
|
130
|
+
participant Trigger.dev
|
|
131
|
+
participant Task Worker
|
|
132
|
+
|
|
133
|
+
App->>Trigger.dev: Trigger task
|
|
134
|
+
Trigger.dev-->>App: Task handle
|
|
135
|
+
Trigger.dev->>Task Worker: Run task
|
|
136
|
+
Task Worker-->>Trigger.dev: Task completed
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
In reality there are many more components involved, such as the task queue, the task scheduler, and the task worker pool, logging (etc.), but this diagram gives you a high-level overview of how Trigger.dev works.
|
|
140
|
+
|
|
141
|
+
## The Checkpoint-Resume System
|
|
142
|
+
|
|
143
|
+
Trigger.dev implements a powerful Checkpoint-Resume System that enables efficient execution of long-running background tasks in a serverless-like environment. This system allows tasks to pause, checkpoint their state, and resume seamlessly, optimizing resource usage and enabling complex workflows.
|
|
144
|
+
|
|
145
|
+
Here's how the Checkpoint-Resume System works:
|
|
146
|
+
|
|
147
|
+
1. **Task Execution**: When a task is triggered, it runs in an isolated environment with all necessary resources.
|
|
148
|
+
|
|
149
|
+
2. **Subtask Handling**: If a task needs to trigger a subtask, it can do so and wait for its completion using `triggerAndWait`
|
|
150
|
+
|
|
151
|
+
3. **State Checkpointing**: While waiting for a subtask or during a programmed pause (e.g., `wait.for({ seconds: 30 })`), the system uses CRIU (Checkpoint/Restore In Userspace) to create a checkpoint of the task's entire state, including memory, CPU registers, and open file descriptors.
|
|
152
|
+
|
|
153
|
+
4. **Resource Release**: After checkpointing, the parent task's resources are released, freeing up the execution environment.
|
|
154
|
+
|
|
155
|
+
5. **Efficient Storage**: The checkpoint is efficiently compressed and stored on disk, ready to be restored when needed.
|
|
156
|
+
|
|
157
|
+
6. **Event-Driven Resumption**: When a subtask completes or a wait period ends, Trigger.dev's event system triggers the restoration process.
|
|
158
|
+
|
|
159
|
+
7. **State Restoration**: The checkpoint is loaded back into a new execution environment, restoring the task to its exact state before suspension.
|
|
160
|
+
|
|
161
|
+
8. **Seamless Continuation**: The task resumes execution from where it left off, with any subtask results or updated state seamlessly integrated.
|
|
162
|
+
|
|
163
|
+
This approach allows Trigger.dev to manage resources efficiently, handle complex task dependencies, and provide a virtually limitless execution time for your tasks, all while maintaining the simplicity and scalability of a serverless architecture.
|
|
164
|
+
|
|
165
|
+
Example of a parent and child task using the Checkpoint-Resume System:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import { task, wait } from "@trigger.dev/sdk";
|
|
169
|
+
|
|
170
|
+
export const parentTask = task({
|
|
171
|
+
id: "parent-task",
|
|
172
|
+
run: async () => {
|
|
173
|
+
console.log("Starting parent task");
|
|
174
|
+
|
|
175
|
+
// This will cause the parent task to be checkpointed and suspended
|
|
176
|
+
const result = await childTask.triggerAndWait({ data: "some data" });
|
|
177
|
+
|
|
178
|
+
console.log("Child task result:", result);
|
|
179
|
+
|
|
180
|
+
// This will also cause the task to be checkpointed and suspended
|
|
181
|
+
await wait.for({ seconds: 30 });
|
|
182
|
+
|
|
183
|
+
console.log("Resumed after 30 seconds");
|
|
184
|
+
|
|
185
|
+
return "Parent task completed";
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
export const childTask = task({
|
|
190
|
+
id: "child-task",
|
|
191
|
+
run: async (payload: { data: string }) => {
|
|
192
|
+
console.log("Starting child task with data:", payload.data);
|
|
193
|
+
|
|
194
|
+
// Simulate some work
|
|
195
|
+
await sleep(5);
|
|
196
|
+
|
|
197
|
+
return "Child task result";
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The diagram below illustrates the flow of the parent and child tasks using the Checkpoint-Resume System:
|
|
203
|
+
|
|
204
|
+
```mermaid
|
|
205
|
+
sequenceDiagram
|
|
206
|
+
participant App
|
|
207
|
+
participant Trigger.dev
|
|
208
|
+
participant Parent Task
|
|
209
|
+
participant Child Task
|
|
210
|
+
participant CR System
|
|
211
|
+
participant Storage
|
|
212
|
+
|
|
213
|
+
App->>Trigger.dev: Trigger parent task
|
|
214
|
+
Trigger.dev->>Parent Task: Start execution
|
|
215
|
+
Parent Task->>Child Task: Trigger child task
|
|
216
|
+
Parent Task->>CR System: Request snapshot
|
|
217
|
+
CR System->>Storage: Store snapshot
|
|
218
|
+
CR System-->>Parent Task: Confirm snapshot stored
|
|
219
|
+
Parent Task->>Trigger.dev: Release resources
|
|
220
|
+
|
|
221
|
+
Child Task->>Trigger.dev: Complete execution
|
|
222
|
+
Trigger.dev->>CR System: Request parent task restoration
|
|
223
|
+
CR System->>Storage: Retrieve snapshot
|
|
224
|
+
CR System->>Parent Task: Restore state
|
|
225
|
+
Parent Task->>Trigger.dev: Resume execution
|
|
226
|
+
Parent Task->>Trigger.dev: Complete execution
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
<Note>
|
|
230
|
+
This is why, in the Trigger.dev Cloud, we don't charge for the time waiting for subtasks or the
|
|
231
|
+
time spent in a paused state.
|
|
232
|
+
</Note>
|
|
233
|
+
|
|
234
|
+
## Durable execution
|
|
235
|
+
|
|
236
|
+
Trigger.dev's Checkpoint-Resume System, combined with idempotency keys, enables durable execution of complex workflows. This approach allows for efficient retries and caching of results, ensuring that work is not unnecessarily repeated in case of failures.
|
|
237
|
+
|
|
238
|
+
### How it works
|
|
239
|
+
|
|
240
|
+
1. **Task breakdown**: Complex workflows are broken down into smaller, independent subtasks.
|
|
241
|
+
2. **Idempotency keys**: Each subtask is assigned a unique idempotency key.
|
|
242
|
+
3. **Result caching**: The output of each subtask is cached based on its idempotency key.
|
|
243
|
+
4. **Intelligent retries**: If a failure occurs, only the failed subtask and subsequent tasks are retried.
|
|
244
|
+
|
|
245
|
+
### Example: Video processing workflow
|
|
246
|
+
|
|
247
|
+
Let's rewrite the `convert-video` task above to be more durable:
|
|
248
|
+
|
|
249
|
+
<CodeGroup>
|
|
250
|
+
|
|
251
|
+
```ts /trigger/video.ts
|
|
252
|
+
import { idempotencyKeys, logger, task } from "@trigger.dev/sdk";
|
|
253
|
+
import { processVideo, sendUserEmail, uploadToS3 } from "./tasks.js";
|
|
254
|
+
import { updateVideoUrl } from "../db.js";
|
|
255
|
+
|
|
256
|
+
export const convertVideo = task({
|
|
257
|
+
id: "convert-video",
|
|
258
|
+
retry: {
|
|
259
|
+
maxAttempts: 5,
|
|
260
|
+
minTimeoutInMs: 1000,
|
|
261
|
+
maxTimeoutInMs: 10000,
|
|
262
|
+
factor: 2,
|
|
263
|
+
},
|
|
264
|
+
run: async ({ videoId }: { videoId: string }) => {
|
|
265
|
+
// Automatically scope the idempotency key to this run, across retries
|
|
266
|
+
const idempotencyKey = await idempotencyKeys.create(videoId);
|
|
267
|
+
|
|
268
|
+
// Process video
|
|
269
|
+
const { processedContent } = await processVideo
|
|
270
|
+
.triggerAndWait({ videoId }, { idempotencyKey })
|
|
271
|
+
.unwrap(); // Calling unwrap will return the output of the subtask, or throw an error if the subtask failed
|
|
272
|
+
|
|
273
|
+
// Upload to S3
|
|
274
|
+
const { s3Url } = await uploadToS3
|
|
275
|
+
.triggerAndWait({ processedContent, videoId }, { idempotencyKey })
|
|
276
|
+
.unwrap();
|
|
277
|
+
|
|
278
|
+
// Update database
|
|
279
|
+
await updateVideoUrl(videoId, s3Url);
|
|
280
|
+
|
|
281
|
+
// Send email, we don't need to wait for this to finish
|
|
282
|
+
await sendUserEmail.trigger({ videoId, s3Url }, { idempotencyKey });
|
|
283
|
+
|
|
284
|
+
return { success: true, s3Url };
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
```ts /trigger/tasks.ts
|
|
290
|
+
import { task, logger } from "@trigger.dev/sdk";
|
|
291
|
+
import ffmpeg from "fluent-ffmpeg";
|
|
292
|
+
import { Readable } from "node:stream";
|
|
293
|
+
import type { ReadableStream } from "node:stream/web";
|
|
294
|
+
import * as fs from "node:fs/promises";
|
|
295
|
+
import * as path from "node:path";
|
|
296
|
+
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
|
|
297
|
+
import { sendEmail } from "../email.js";
|
|
298
|
+
import { getVideo } from "../db.js";
|
|
299
|
+
|
|
300
|
+
// Initialize S3 client
|
|
301
|
+
const s3Client = new S3Client({
|
|
302
|
+
region: process.env.AWS_REGION,
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
export const processVideo = task({
|
|
306
|
+
id: "process-video",
|
|
307
|
+
run: async ({ videoId }: { videoId: string }) => {
|
|
308
|
+
const { url } = await getVideo(videoId);
|
|
309
|
+
|
|
310
|
+
const outputPath = path.join("/tmp", `output_${videoId}.mp4`);
|
|
311
|
+
const response = await fetch(url);
|
|
312
|
+
|
|
313
|
+
await logger.trace("ffmpeg", async (span) => {
|
|
314
|
+
await new Promise((resolve, reject) => {
|
|
315
|
+
ffmpeg(Readable.fromWeb(response.body as ReadableStream))
|
|
316
|
+
.videoFilters("scale=iw/2:ih/2")
|
|
317
|
+
.output(outputPath)
|
|
318
|
+
.on("end", resolve)
|
|
319
|
+
.on("error", reject)
|
|
320
|
+
.run();
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
const processedContent = await fs.readFile(outputPath);
|
|
325
|
+
|
|
326
|
+
await fs.unlink(outputPath);
|
|
327
|
+
|
|
328
|
+
return { processedContent: processedContent.toString("base64") };
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
export const uploadToS3 = task({
|
|
333
|
+
id: "upload-to-s3",
|
|
334
|
+
run: async (payload: { processedContent: string; videoId: string }) => {
|
|
335
|
+
const { processedContent, videoId } = payload;
|
|
336
|
+
|
|
337
|
+
const s3Key = `processed-videos/output_${videoId}.mp4`;
|
|
338
|
+
|
|
339
|
+
const uploadParams = {
|
|
340
|
+
Bucket: process.env.S3_BUCKET,
|
|
341
|
+
Key: s3Key,
|
|
342
|
+
Body: Buffer.from(processedContent, "base64"),
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
await s3Client.send(new PutObjectCommand(uploadParams));
|
|
346
|
+
const s3Url = `https://${process.env.S3_BUCKET}.s3.amazonaws.com/${s3Key}`;
|
|
347
|
+
|
|
348
|
+
return { s3Url };
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
export const sendUserEmail = task({
|
|
353
|
+
id: "send-user-email",
|
|
354
|
+
run: async ({ videoId, s3Url }: { videoId: string; s3Url: string }) => {
|
|
355
|
+
const { userId } = await getVideo(videoId);
|
|
356
|
+
|
|
357
|
+
return await sendEmail(
|
|
358
|
+
userId,
|
|
359
|
+
"Video Processing Complete",
|
|
360
|
+
`Your video has been processed and is available at: ${s3Url}`
|
|
361
|
+
);
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
</CodeGroup>
|
|
367
|
+
|
|
368
|
+
### How retries work
|
|
369
|
+
|
|
370
|
+
Let's say the email sending fails in our video processing workflow. Here's how the retry process works:
|
|
371
|
+
|
|
372
|
+
1. The main task throws an error and is scheduled for retry.
|
|
373
|
+
2. When retried, it starts from the beginning, but leverages cached results for completed subtasks.
|
|
374
|
+
|
|
375
|
+
Here's a sequence diagram illustrating this process:
|
|
376
|
+
|
|
377
|
+
```mermaid
|
|
378
|
+
sequenceDiagram
|
|
379
|
+
participant Main as Main Task
|
|
380
|
+
participant Process as Process Video
|
|
381
|
+
participant Upload as Upload to S3
|
|
382
|
+
participant DB as Update Database
|
|
383
|
+
participant Email as Send Email
|
|
384
|
+
|
|
385
|
+
Main->>Process: triggerAndWait (1st attempt)
|
|
386
|
+
Process-->>Main: Return result
|
|
387
|
+
Main->>Upload: triggerAndWait (1st attempt)
|
|
388
|
+
Upload-->>Main: Return result
|
|
389
|
+
Main->>DB: Update
|
|
390
|
+
Main->>Email: triggerAndWait (1st attempt)
|
|
391
|
+
Email--xMain: Fail
|
|
392
|
+
Main-->>Main: Schedule retry
|
|
393
|
+
|
|
394
|
+
Main->>Process: triggerAndWait (2nd attempt)
|
|
395
|
+
Process-->>Main: Return cached result
|
|
396
|
+
Main->>Upload: triggerAndWait (2nd attempt)
|
|
397
|
+
Upload-->>Main: Return cached result
|
|
398
|
+
Main->>DB: Update (idempotent)
|
|
399
|
+
Main->>Email: triggerAndWait (2nd attempt)
|
|
400
|
+
Email-->>Main: Success
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## The build system
|
|
404
|
+
|
|
405
|
+
When you run `npx trigger.dev@latest deploy` or `npx trigger.dev@latest dev`, we build your task code using our build system, which is powered by [esbuild](https://esbuild.github.io/). When deploying, the code is packaged up into a Docker image and deployed to your Trigger.dev instance. When running in dev mode, the code is built and run locally on your machine. Some features of our build system include:
|
|
406
|
+
|
|
407
|
+
- **Bundled by default**: Code + dependencies are bundled and tree-shaked by default.
|
|
408
|
+
- **Build extensions**: Use and write custom build extensions to transform your code or the resulting docker image.
|
|
409
|
+
- **ESM ouput**: We output to ESM, which allows tree-shaking and better performance.
|
|
410
|
+
|
|
411
|
+
You can review the build output by running deploy with the `--dry-run` flag, which will output the Containerfile and the build output.
|
|
412
|
+
|
|
413
|
+
Learn more about working with our build system in the [configuration docs](/config/config-file).
|
|
414
|
+
|
|
415
|
+
## Dev mode
|
|
416
|
+
|
|
417
|
+
When you run `npx trigger.dev@latest dev`, we run your task code locally on your machine. All scheduling is still done in the Trigger.dev server instance, but the task code is run locally. This allows you to develop and test your tasks locally before deploying them to the cloud, and is especially useful for debugging and testing.
|
|
418
|
+
|
|
419
|
+
- The same build system is used in dev mode, so you can be sure that your code will run the same locally as it does in the cloud.
|
|
420
|
+
- Changes are automatically detected and a new version is spun up when you save your code.
|
|
421
|
+
- Add debuggers and breakpoints to your code and debug it locally.
|
|
422
|
+
- Each task is run in a separate process, so you can run multiple tasks in parallel.
|
|
423
|
+
- Auto-cancels tasks when you stop the dev server.
|
|
424
|
+
|
|
425
|
+
<Note>
|
|
426
|
+
Trigger.dev currently does not support "offline" dev mode, where you can run tasks without an
|
|
427
|
+
internet connection. [Please let us know](https://feedback.trigger.dev/) if this is a feature you
|
|
428
|
+
want/need.
|
|
429
|
+
</Note>
|
|
430
|
+
|
|
431
|
+
## Staging and production environments
|
|
432
|
+
|
|
433
|
+
Trigger.dev supports deploying to `prod` and `staging` environments. This allows you to test your tasks in a staging environment before deploying them to production. You can deploy to a different environment by running `npx trigger.dev@latest deploy --env <env>`, where `<env>` is either `prod` or `staging`. Each environment has its own API Key, which you can use to trigger tasks in that environment.
|
|
434
|
+
|
|
435
|
+
For additional isolated environments, you can use [preview branches](/deployment/preview-branches), which allow you to create separate environments for each branch of your code.
|
|
436
|
+
|
|
437
|
+
## OpenTelemetry
|
|
438
|
+
|
|
439
|
+
The Trigger.dev logging and task dashboard is powered by OpenTelemetry traces and logs, which allows you to trace your tasks and auto-instrument your code. We also auto-correlate logs from subtasks and parent tasks, making it easy view the entire trace of a task execution. A single run of the video processing task above looks like this in the dashboard:
|
|
440
|
+
|
|
441
|
+

|
|
442
|
+
|
|
443
|
+
Because we use standard OpenTelemetry, you can instrument your code and OpenTelemetry compatible libraries to get detailed traces and logs of your tasks. The above trace instruments both Prisma and the AWS SDK:
|
|
444
|
+
|
|
445
|
+
```ts trigger.config.ts
|
|
446
|
+
import { defineConfig } from "@trigger.dev/sdk";
|
|
447
|
+
import { PrismaInstrumentation } from "@prisma/instrumentation";
|
|
448
|
+
import { AwsInstrumentation } from "@opentelemetry/instrumentation-aws-sdk";
|
|
449
|
+
|
|
450
|
+
export default defineConfig({
|
|
451
|
+
project: "<your-project-ref>",
|
|
452
|
+
instrumentations: [new PrismaInstrumentation(), new AwsInstrumentation()],
|
|
453
|
+
});
|
|
454
|
+
```
|