diff --git a/.changeset/breezy-turtles-talk.md b/.changeset/breezy-turtles-talk.md new file mode 100644 index 0000000000..da208cb2c8 --- /dev/null +++ b/.changeset/breezy-turtles-talk.md @@ -0,0 +1,10 @@ +--- +"@trigger.dev/react-hooks": patch +"@trigger.dev/sdk": patch +"trigger.dev": patch +"@trigger.dev/build": patch +"@trigger.dev/core": patch +"@trigger.dev/rsc": patch +--- + +Run Engine 2.0 (alpha) diff --git a/.configs/tsconfig.base.json b/.configs/tsconfig.base.json index 7224a9a85d..3ce4c2db29 100644 --- a/.configs/tsconfig.base.json +++ b/.configs/tsconfig.base.json @@ -1,7 +1,7 @@ { "compilerOptions": { "target": "es2022", - "lib": ["ES2022", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable", "DOM.AsyncIterable"], "module": "NodeNext", "moduleResolution": "NodeNext", "moduleDetection": "force", diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 25d12a1ed4..b53337ecb0 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -38,6 +38,9 @@ jobs: - name: 📥 Download deps run: pnpm install --frozen-lockfile --filter trigger.dev... + - name: 📀 Generate Prisma Client + run: pnpm run generate + - name: 🔧 Build v3 cli monorepo dependencies run: pnpm run build --filter trigger.dev^... diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index aa134d782c..9905fc9efc 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -24,6 +24,13 @@ jobs: node-version: 20.11.1 cache: "pnpm" + # ..to avoid rate limits when pulling images + - name: 🐳 Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: 📥 Download deps run: pnpm install --frozen-lockfile diff --git a/.npmrc b/.npmrc index 8dbd39f189..fac274c900 100644 --- a/.npmrc +++ b/.npmrc @@ -1,3 +1,4 @@ link-workspace-packages=false public-hoist-pattern[]=*prisma* -prefer-workspace-packages=true \ No newline at end of file +prefer-workspace-packages=true +update-notifier=false \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 3a74929366..40f97bb421 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -133,6 +133,14 @@ "command": "pnpm exec trigger dev", "cwd": "${workspaceFolder}/references/hello-world", "sourceMaps": true + }, + { + "type": "node-terminal", + "request": "launch", + "name": "Debug RunEngine tests", + "command": "pnpm run test --filter @internal/run-engine", + "cwd": "${workspaceFolder}", + "sourceMaps": true } ] } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 260d9861f4..b3ed907610 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -230,13 +230,21 @@ pnpm run db:studio cd packages/database ``` -3. Create and apply the migrations +3. Create a migration ``` - pnpm run db:migrate:dev + pnpm run db:migrate:dev:create ``` - This creates a migration file and executes the migrations against your database and applies changes to the database schema(s) + This creates a migration file. Check the migration file does only what you want. If you're adding any database indexes they must use `CONCURRENTLY`, otherwise they'll lock the table when executed. + +4. Run the migration. + + ``` + pnpm run db:migrate:deploy + pnpm run generate + ``` + This executes the migrations against your database and applies changes to the database schema(s), and then regenerates the Prisma client. 4. Commit generated migrations as well as changes to the schema.prisma file 5. If you're using VSCode you may need to restart the Typescript server in the webapp to get updated type inference. Open a TypeScript file, then open the Command Palette (View > Command Palette) and run `TypeScript: Restart TS server`. diff --git a/apps/coordinator/package.json b/apps/coordinator/package.json index c860adb1c8..3b4240bd37 100644 --- a/apps/coordinator/package.json +++ b/apps/coordinator/package.json @@ -23,10 +23,8 @@ "tinyexec": "^0.3.0" }, "devDependencies": { - "@types/node": "^18", "dotenv": "^16.4.2", "esbuild": "^0.19.11", - "tsx": "^4.7.0", - "typescript": "^5.3.3" + "tsx": "^4.7.0" } } \ No newline at end of file diff --git a/apps/coordinator/src/checkpointer.ts b/apps/coordinator/src/checkpointer.ts index 269bf6d421..69c51e2fb5 100644 --- a/apps/coordinator/src/checkpointer.ts +++ b/apps/coordinator/src/checkpointer.ts @@ -1,5 +1,5 @@ import { ExponentialBackoff } from "@trigger.dev/core/v3/apps"; -import { testDockerCheckpoint } from "@trigger.dev/core/v3/apps"; +import { testDockerCheckpoint } from "@trigger.dev/core/v3/checkpoints"; import { nanoid } from "nanoid"; import fs from "node:fs/promises"; import { ChaosMonkey } from "./chaosMonkey"; diff --git a/apps/coordinator/tsconfig.json b/apps/coordinator/tsconfig.json index 3c03760853..15cdfe9c1e 100644 --- a/apps/coordinator/tsconfig.json +++ b/apps/coordinator/tsconfig.json @@ -1,8 +1,6 @@ { - "include": ["./src/**/*.ts"], - "exclude": ["node_modules"], "compilerOptions": { - "target": "es2016", + "target": "es2018", "module": "commonjs", "esModuleInterop": true, "resolveJsonModule": true, diff --git a/apps/docker-provider/package.json b/apps/docker-provider/package.json index 56d8f89b7e..f3e4015ef0 100644 --- a/apps/docker-provider/package.json +++ b/apps/docker-provider/package.json @@ -20,10 +20,8 @@ "execa": "^8.0.1" }, "devDependencies": { - "@types/node": "^18.19.8", "dotenv": "^16.4.2", "esbuild": "^0.19.11", - "tsx": "^4.7.0", - "typescript": "^5.3.3" + "tsx": "^4.7.0" } } \ No newline at end of file diff --git a/apps/docker-provider/src/index.ts b/apps/docker-provider/src/index.ts index b789b0d023..3ca5184c75 100644 --- a/apps/docker-provider/src/index.ts +++ b/apps/docker-provider/src/index.ts @@ -7,7 +7,8 @@ import { TaskOperationsRestoreOptions, } from "@trigger.dev/core/v3/apps"; import { SimpleLogger } from "@trigger.dev/core/v3/apps"; -import { isExecaChildProcess, testDockerCheckpoint } from "@trigger.dev/core/v3/apps"; +import { isExecaChildProcess } from "@trigger.dev/core/v3/apps"; +import { testDockerCheckpoint } from "@trigger.dev/core/v3/checkpoints"; import { setTimeout } from "node:timers/promises"; import { PostStartCauses, PreStopCauses } from "@trigger.dev/core/v3"; diff --git a/apps/kubernetes-provider/package.json b/apps/kubernetes-provider/package.json index 3b62f65449..6cb26e2c70 100644 --- a/apps/kubernetes-provider/package.json +++ b/apps/kubernetes-provider/package.json @@ -23,7 +23,6 @@ "devDependencies": { "dotenv": "^16.4.2", "esbuild": "^0.19.11", - "tsx": "^4.7.0", - "typescript": "^5.3.3" + "tsx": "^4.7.0" } } \ No newline at end of file diff --git a/apps/kubernetes-provider/tsconfig.json b/apps/kubernetes-provider/tsconfig.json index 057952409b..4635e17647 100644 --- a/apps/kubernetes-provider/tsconfig.json +++ b/apps/kubernetes-provider/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es2016", + "target": "es2018", "module": "commonjs", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, diff --git a/apps/proxy/package.json b/apps/proxy/package.json index d72311dcf8..80646e60a0 100644 --- a/apps/proxy/package.json +++ b/apps/proxy/package.json @@ -9,7 +9,6 @@ }, "devDependencies": { "@cloudflare/workers-types": "^4.20240512.0", - "typescript": "^5.0.4", "wrangler": "^3.57.1" }, "dependencies": { diff --git a/apps/webapp/app/assets/icons/AnimatedHourglassIcon.tsx b/apps/webapp/app/assets/icons/AnimatedHourglassIcon.tsx new file mode 100644 index 0000000000..3c94426fa0 --- /dev/null +++ b/apps/webapp/app/assets/icons/AnimatedHourglassIcon.tsx @@ -0,0 +1,27 @@ +import { useAnimate } from "framer-motion"; +import { HourglassIcon } from "lucide-react"; +import { useEffect } from "react"; + +export function AnimatedHourglassIcon({ + className, + delay, +}: { + className?: string; + delay?: number; +}) { + const [scope, animate] = useAnimate(); + + useEffect(() => { + animate( + [ + [scope.current, { rotate: 0 }, { duration: 0.7 }], + [scope.current, { rotate: 180 }, { duration: 0.3 }], + [scope.current, { rotate: 180 }, { duration: 0.7 }], + [scope.current, { rotate: 360 }, { duration: 0.3 }], + ], + { repeat: Infinity, delay } + ); + }, []); + + return ; +} diff --git a/apps/webapp/app/assets/icons/PauseIcon.tsx b/apps/webapp/app/assets/icons/PauseIcon.tsx new file mode 100644 index 0000000000..ccbc1d9a4d --- /dev/null +++ b/apps/webapp/app/assets/icons/PauseIcon.tsx @@ -0,0 +1,12 @@ +export function PauseIcon({ className }: { className?: string }) { + return ( + + + + ); +} diff --git a/apps/webapp/app/assets/icons/TaskCachedIcon.tsx b/apps/webapp/app/assets/icons/TaskCachedIcon.tsx new file mode 100644 index 0000000000..650f9be396 --- /dev/null +++ b/apps/webapp/app/assets/icons/TaskCachedIcon.tsx @@ -0,0 +1,49 @@ +export function TaskCachedIcon({ className }: { className?: string }) { + return ( + + + + + + + + + + + + + + + + + + + ); +} diff --git a/apps/webapp/app/components/code/CodeBlock.tsx b/apps/webapp/app/components/code/CodeBlock.tsx index db1d165220..ba5101a143 100644 --- a/apps/webapp/app/components/code/CodeBlock.tsx +++ b/apps/webapp/app/components/code/CodeBlock.tsx @@ -53,7 +53,7 @@ type CodeBlockProps = { fileName?: string; /** title text for the Title row */ - rowTitle?: string; + rowTitle?: ReactNode; /** Whether to show the open in modal button */ showOpenInModal?: boolean; diff --git a/apps/webapp/app/components/primitives/Switch.tsx b/apps/webapp/app/components/primitives/Switch.tsx index 5cb860910b..e5d89f20dd 100644 --- a/apps/webapp/app/components/primitives/Switch.tsx +++ b/apps/webapp/app/components/primitives/Switch.tsx @@ -3,6 +3,7 @@ import * as React from "react"; import * as SwitchPrimitives from "@radix-ui/react-switch"; import { cn } from "~/utils/cn"; +import { ShortcutDefinition, useShortcutKeys } from "~/hooks/useShortcutKeys"; const variations = { large: { @@ -23,14 +24,34 @@ const variations = { type SwitchProps = React.ComponentPropsWithoutRef & { label?: React.ReactNode; variant: keyof typeof variations; + shortcut?: ShortcutDefinition; }; export const Switch = React.forwardRef, SwitchProps>( ({ className, variant, label, ...props }, ref) => { + const innerRef = React.useRef(null); + React.useImperativeHandle(ref, () => innerRef.current as HTMLButtonElement); + const { container, root, thumb, text } = variations[variant]; + if (props.shortcut) { + useShortcutKeys({ + shortcut: props.shortcut, + action: () => { + if (innerRef.current) { + innerRef.current.click(); + } + }, + disabled: props.disabled, + }); + } + return ( - + {label ? (