diff --git a/.changeset/breezy-turtles-talk.md b/.changeset/breezy-turtles-talk.md new file mode 100644 index 00000000000..da208cb2c8f --- /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 7224a9a85d1..3ce4c2db29e 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 25d12a1ed47..b53337ecb02 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 aa134d782c7..9905fc9efca 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 8dbd39f189d..fac274c9002 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 3a749293662..40f97bb421d 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 260d9861f49..b3ed907610e 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 c860adb1c88..3b4240bd37d 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 269bf6d4219..69c51e2fb5c 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 3c037608537..15cdfe9c1e8 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 56d8f89b7e8..f3e4015ef08 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 b789b0d023a..3ca5184c752 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 3b62f654499..6cb26e2c70f 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 057952409b7..4635e176476 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 d72311dcf85..80646e60a09 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 00000000000..3c94426fa03 --- /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 00000000000..ccbc1d9a4da --- /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 00000000000..650f9be396a --- /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 db1d165220e..ba5101a143e 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 5cb860910ba..e5d89f20dd3 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 ? (