diff --git a/.changeset/breezy-turtles-talk.md b/.changeset/breezy-turtles-talk.md new file mode 100644 index 000000000..da208cb2c --- /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 7224a9a85..3ce4c2db2 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 25d12a1ed..b53337ecb 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 aa134d782..9905fc9ef 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 8dbd39f18..fac274c90 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 3a7492936..40f97bb42 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 260d9861f..b3ed90761 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 c860adb1c..3b4240bd3 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 269bf6d42..69c51e2fb 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 3c0376085..15cdfe9c1 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 56d8f89b7..f3e4015ef 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 b789b0d02..3ca5184c7 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 3b62f6544..6cb26e2c7 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 057952409..4635e1764 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 d72311dcf..80646e60a 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 000000000..3c94426fa --- /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 000000000..ccbc1d9a4 --- /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 000000000..650f9be39 --- /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 db1d16522..ba5101a14 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 5cb860910..e5d89f20d 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 ? (