### Define Workflow with Parameters Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/workflows.mdx This example demonstrates how to define a workflow and access its parameters: input, step API, version, and run metadata. Use this to start building your workflow logic. ```typescript defineWorkflow({ name: "example" }, async ({ input, step, version, run }) => { console.log("Input:", input); console.log("Version:", version); console.log("Run ID:", run.id); await step.run({ name: "my-step" }, async () => { // step logic }); }); ``` -------------------------------- ### Install OpenWorkflow and PostgreSQL Driver Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/configuration.mdx Install the necessary packages for using the PostgreSQL backend with npm, pnpm, or bun. ```bash npm i openworkflow postgres ``` ```bash pnpm add openworkflow postgres ``` ```bash bun add openworkflow postgres ``` -------------------------------- ### Full OpenWorkflow Configuration Example Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/configuration.mdx A comprehensive example demonstrating PostgreSQL backend, multiple directories, ignore patterns, and worker concurrency. ```typescript import { defineConfig } from "@openworkflow/cli"; import { BackendPostgres } from "openworkflow/postgres"; export default defineConfig({ // PostgreSQL for production, with namespace backend: await BackendPostgres.connect( process.env.OPENWORKFLOW_POSTGRES_URL!, { namespaceId: process.env.OPENWORKFLOW_NAMESPACE_ID || "default", }, ), // Scan multiple directories dirs: ["./openworkflow", "./src/workflows"], // Ignore test files ignorePatterns: ["**/*.test.*", "**/*.spec.*"], // Worker configuration worker: { concurrency: 8, }, }); ``` -------------------------------- ### Initialize OpenWorkflow CLI Source: https://github.com/openworkflowdev/openworkflow/blob/main/README.md Commands to initialize a new OpenWorkflow project using different package managers (npm, pnpm, bun). The CLI will guide you through the setup process. ```bash # npm npx @openworkflow/cli init # pnpm pnpx @openworkflow/cli init # bun bunx @openworkflow/cli init ``` -------------------------------- ### Setup SQLite Backend Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/sqlite.mdx Import necessary classes and connect to a SQLite database file. This setup is synchronous and ideal for local development. ```typescript import { OpenWorkflow } from "openworkflow"; import { BackendSqlite } from "openworkflow/sqlite"; const backend = BackendSqlite.connect("./openworkflow/backend.db"); const ow = new OpenWorkflow({ backend }); ``` -------------------------------- ### Install OpenWorkflow CLI Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/cli.mdx Install the OpenWorkflow CLI as a development dependency using npm, pnpm, or bun. ```bash npm install -D @openworkflow/cli ``` ```bash pnpm add -D @openworkflow/cli ``` ```bash bun add -D @openworkflow/cli ``` -------------------------------- ### Start Dashboard with npm Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/dashboard.mdx Starts the OpenWorkflow dashboard using npm. The dashboard will be accessible at http://localhost:3000 by default. ```bash npx @openworkflow/cli dashboard ``` -------------------------------- ### Start a Worker with Concurrency via npm Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/workers.mdx Start a worker and specify the concurrency level directly from the command line using npm. ```bash npx @openworkflow/cli worker start --concurrency 10 ``` -------------------------------- ### Start a Worker with Concurrency via bun Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/workers.mdx Start a worker and specify the concurrency level directly from the command line using bun. ```bash bunx @openworkflow/cli worker start --concurrency 10 ``` -------------------------------- ### Run First Workflow Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/quickstart.mdx Trigger the example 'hello-world' workflow to create a new run. This script enqueues the workflow for the worker to process. ```bash npx tsx openworkflow/hello-world.run.ts ``` ```bash pnpx tsx openworkflow/hello-world.run.ts ``` ```bash bun openworkflow/hello-world.run.ts ``` -------------------------------- ### Start a Worker using npm Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/workers.mdx Use this command to start a worker process with npm. It loads configuration, discovers workflows, and begins polling for work. ```bash npx @openworkflow/cli worker start ``` -------------------------------- ### Start Dashboard with bun Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/dashboard.mdx Starts the OpenWorkflow dashboard using bun. The dashboard will be accessible at http://localhost:3000 by default. ```bash bunx @openworkflow/cli dashboard ``` -------------------------------- ### Configure PostgreSQL and SQLite Backends Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/configuration.mdx Examples of connecting to PostgreSQL for production and SQLite for development environments. ```typescript // PostgreSQL (production) backend: await BackendPostgres.connect(process.env.OPENWORKFLOW_POSTGRES_URL!), // SQLite (development) backend: BackendSqlite.connect("./openworkflow/backend.db"), ``` -------------------------------- ### Start a Worker with Concurrency via pnpm Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/workers.mdx Start a worker and specify the concurrency level directly from the command line using pnpm. ```bash pnpx @openworkflow/cli worker start --concurrency 10 ``` -------------------------------- ### Start a Worker using bun Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/workers.mdx Use this command to start a worker process with bun. It loads configuration, discovers workflows, and begins polling for work. ```bash bunx @openworkflow/cli worker start ``` -------------------------------- ### Examples of Good vs. Bad Step Granularity Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/steps.mdx Illustrates the difference between well-defined steps representing single logical operations and steps that are too granular or too coarse. Use these examples to guide your step definition for optimal workflow management. ```typescript // Good - each step is a meaningful operation await step.run({ name: "fetch-user" }, ...); await step.run({ name: "validate-subscription" }, ...); await step.run({ name: "charge-payment" }, ...); await step.run({ name: "send-receipt" }, ...); ``` ```typescript // Too granular - overhead outweighs benefits await step.run({ name: "parse-json" }, ...); await step.run({ name: "validate-field-1" }, ...); await step.run({ name: "validate-field-2" }, ...); ``` ```typescript // Too coarse - no benefit from checkpointing await step.run({ name: "do-everything" }, async () => { await fetchUser(); await chargeCard(); await sendEmail(); }); ``` -------------------------------- ### Install PostgreSQL Driver (bun) Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/migration-v6.mdx If using PostgreSQL, install the 'postgres' driver directly using bun after removing legacy packages. This is required for v0.6. ```bash bun add postgres ``` -------------------------------- ### Load Environment Variables from .env File Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/configuration.mdx Example of how environment variables like database URLs and namespace IDs can be loaded from a .env file. ```bash # .env OPENWORKFLOW_POSTGRES_URL=postgresql://user:pass@localhost:5432/openworkflow OPENWORKFLOW_NAMESPACE_ID=development ``` -------------------------------- ### Start a Worker using pnpm Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/workers.mdx Use this command to start a worker process with pnpm. It loads configuration, discovers workflows, and begins polling for work. ```bash pnpx @openworkflow/cli worker start ``` -------------------------------- ### Start OpenWorkflow Dashboard Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/cli.mdx Start the web dashboard for OpenWorkflow. By default, it runs on http://localhost:3000. ```bash npx @openworkflow/cli dashboard ``` ```bash pnpx @openworkflow/cli dashboard ``` ```bash bunx @openworkflow/cli dashboard ``` -------------------------------- ### Start Dashboard with pnpm Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/dashboard.mdx Starts the OpenWorkflow dashboard using pnpm. The dashboard will be accessible at http://localhost:3000 by default. ```bash pnpx @openworkflow/cli dashboard ``` -------------------------------- ### Initialize OpenWorkflow Project Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/cli.mdx Initialize OpenWorkflow in your project. This interactive command sets up the configuration file, example workflow, and package.json scripts. ```bash npx @openworkflow/cli init ``` ```bash pnpx @openworkflow/cli init ``` ```bash bunx @openworkflow/cli init ``` -------------------------------- ### Run Parallel Child Workflows Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/child-workflows.mdx Start multiple child workflows concurrently using `Promise.all`. This example runs payment and shipping workflows in parallel for an order. ```typescript const [payment, shipping] = await Promise.all([ step.runWorkflow(paymentWorkflow.spec, { orderId: input.orderId, }), step.runWorkflow(shippingWorkflow.spec, { orderId: input.orderId, }), ]); ``` -------------------------------- ### Dockerfile for Node.js Worker (bun) Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/production.mdx A Dockerfile template for deploying an OpenWorkflow worker using bun. It installs dependencies with bun, copies project files, and sets the command to start the worker. ```dockerfile FROM oven/bun:1 WORKDIR /app COPY package.json bun.lock ./ RUN bun install --frozen-lockfile COPY . . CMD ["bunx", "@openworkflow/cli", "worker", "start"] ``` -------------------------------- ### Start Dashboard on Custom Port with bun Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/dashboard.mdx Starts the OpenWorkflow dashboard on a custom port (e.g., 4000) using bun. ```bash bunx @openworkflow/cli dashboard --port 4000 ``` -------------------------------- ### Start Dashboard on Custom Port with npm Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/dashboard.mdx Starts the OpenWorkflow dashboard on a custom port (e.g., 4000) using npm. ```bash npx @openworkflow/cli dashboard --port 4000 ``` -------------------------------- ### Dockerfile for Node.js Worker (npm) Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/production.mdx A Dockerfile template for deploying an OpenWorkflow worker using npm. It installs dependencies, copies project files, and sets the command to start the worker. ```dockerfile FROM node:22-slim WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . CMD ["npx", "@openworkflow/cli", "worker", "start"] ``` -------------------------------- ### Start Dashboard on Custom Port Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/cli.mdx Start the OpenWorkflow dashboard on a custom port by specifying the --port option. ```bash npx @openworkflow/cli dashboard --port 4000 ``` ```bash pnpx @openworkflow/cli dashboard --port 4000 ``` ```bash bunx @openworkflow/cli dashboard --port 4000 ``` -------------------------------- ### Install PostgreSQL Driver (npm) Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/migration-v6.mdx If using PostgreSQL, install the 'postgres' driver directly using npm after removing legacy packages. This is required for v0.6. ```bash npm install postgres ``` -------------------------------- ### Start Dashboard on Custom Port with pnpm Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/dashboard.mdx Starts the OpenWorkflow dashboard on a custom port (e.g., 4000) using pnpm. ```bash pnpx @openworkflow/cli dashboard --port 4000 ``` -------------------------------- ### Install PostgreSQL Driver (pnpm) Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/migration-v6.mdx If using PostgreSQL, install the 'postgres' driver directly using pnpm after removing legacy packages. This is required for v0.6. ```bash pnpm add postgres ``` -------------------------------- ### Configure Workflow Directories Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/configuration.mdx Examples of specifying a single directory or multiple directories for OpenWorkflow to scan for workflow files. ```typescript // Single directory dirs: "./openworkflow", // Multiple directories dirs: ["./openworkflow", "./src/workflows"], ``` -------------------------------- ### Show CLI Version Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/cli.mdx Display the installed version of the OpenWorkflow CLI. ```bash npx @openworkflow/cli --version ``` ```bash pnpx @openworkflow/cli --version ``` ```bash bunx @openworkflow/cli --version ``` -------------------------------- ### Get Backend for Tenant ID Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/namespaces.mdx Demonstrates how to dynamically create a backend connection for a specific tenant by prefixing the tenant ID to the namespace. This is useful for multi-tenancy. ```typescript async function getBackendForTenant(tenantId: string) { return BackendPostgres.connect(process.env.OPENWORKFLOW_POSTGRES_URL!, { namespaceId: `tenant-${tenantId}`, }); } ``` -------------------------------- ### Run a Workflow Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/workflows.mdx Start a workflow execution using `ow.runWorkflow` with the workflow's spec and input. This returns a handle immediately, with execution happening in a worker process. ```typescript import { ow } from "./openworkflow/client"; import { sendWelcomeEmail } from "./workflows/send-welcome-email"; const handle = await ow.runWorkflow(sendWelcomeEmail.spec, { userId: "user_123", }); ``` -------------------------------- ### Specify Configuration File Path Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/configuration.mdx How to start the OpenWorkflow worker with an explicitly defined configuration file path. ```bash npx @openworkflow/cli worker start --config src/openworkflow.config.ts ``` -------------------------------- ### Conditional Backend Setup for Dev/Prod Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/sqlite.mdx Dynamically choose between SQLite for development and PostgreSQL for production based on the `NODE_ENV` environment variable. Ensure PostgreSQL connection URL is provided in production. ```typescript import { defineConfig } from "@openworkflow/cli"; import { BackendPostgres } from "openworkflow/postgres"; import { BackendSqlite } from "openworkflow/sqlite"; const isDev = process.env.NODE_ENV !== "production"; const backend = isDev ? BackendSqlite.connect("./openworkflow/backend.db") : await BackendPostgres.connect(process.env.OPENWORKFLOW_POSTGRES_URL!); export default defineConfig({ backend, dirs: ["./openworkflow"], }); ``` -------------------------------- ### Worker Replay Loop Example Source: https://github.com/openworkflowdev/openworkflow/blob/main/ARCHITECTURE.md Demonstrates how a worker claims a workflow run, replays completed steps from history, and executes new steps. ```typescript const user = await step.run({ name: "fetch-user" }, async () => { // 1. The framework sees "fetch-user". // 2. It finds a completed result in the history. // 3. It returns the cached output immediately without executing the function. return await db.users.findOne({ id: 1 }); }); const welcomeEmail = await step.run({ name: "welcome-email" }, async () => { // 4. The framework sees "welcome-email". // 5. It is NOT in the history. // 6. It creates a step_attempt with status "running". // 7. It executes the function and saves the result. // 8. It updates the step_attempt to status "completed" and continues. return await email.send(user); }); ``` -------------------------------- ### Start OpenWorkflow Worker Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/cli.mdx Start a worker to process workflows. This command loads configuration, discovers workflows, and begins polling for work. ```bash npx @openworkflow/cli worker start ``` ```bash pnpx @openworkflow/cli worker start ``` ```bash bunx @openworkflow/cli worker start ``` -------------------------------- ### Workflow with Steps for Safe Operations Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/steps.mdx This example demonstrates how to use steps to ensure operations like charging a credit card and sending an email are not accidentally repeated if the workflow crashes. Each operation is wrapped in `step.run()`. ```typescript defineWorkflow({ name: "process-order" }, async ({ input, step }) => { await step.run({ name: "charge-card" }, async () => { await chargeCard(input.orderId); }); await step.run({ name: "send-email" }, async () => { await sendConfirmationEmail(input.orderId); }); }); ``` -------------------------------- ### Basic Workflow Sleep Example Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/sleeping.mdx Demonstrates how to pause a workflow for 7 days using `step.sleep()`. Ensure `emailService` is properly configured and imported. ```typescript import { defineWorkflow } from "openworkflow"; export const reminderWorkflow = defineWorkflow( { name: "send-reminder" }, async ({ input, step }) => { await step.run({ name: "send-initial-email" }, async () => { await emailService.send({ to: input.email, subject: "Welcome!", }); }); // Pause for 7 days await step.sleep("wait-7-days", "7d"); await step.run({ name: "send-followup" }, async () => { await emailService.send({ to: input.email, subject: "How's it going?", }); }); }, ); ``` -------------------------------- ### OpenWorkflow Durable Workflow Example Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/openworkflow-vs-bullmq.mdx Demonstrates how to define a multi-step process as a single function in OpenWorkflow, which handles durable step history and replay. ```typescript import { workflow, step } from "openworkflow"; export const sendWelcomeEmail = workflow({ id: "send-welcome-email", version: "1.0.0", steps: { sendEmail: step({ handler: async ({ input }) => { // ... send email logic ... return { emailSent: true }; }, }), logToDatabase: step({ dependsOn: "sendEmail", handler: async ({ output }) => { // ... log email status to DB ... return { logged: true }; }, }), }, }); ``` -------------------------------- ### Start Child Workflow with `step.runWorkflow()` Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/steps.mdx Use `step.runWorkflow()` to initiate a child workflow and await its durable result. Pass the child workflow's spec, input, and optional configuration like timeout. ```typescript const childOutput = await step.runWorkflow( generateReportWorkflow.spec, { reportId: input.reportId }, { timeout: "5m" }, // optional, defaults to 1 year ); ``` -------------------------------- ### Define a Workflow Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/workers.mdx Example of defining a workflow using 'defineWorkflow'. Workflows are exported from files in the configured discovery directories. ```typescript // openworkflow/send-email.ts import { defineWorkflow } from "openworkflow"; export const sendEmail = defineWorkflow( { name: "send-email" }, async ({ input, step }) => { // ... }, ); ``` -------------------------------- ### Updated package.json Dependencies Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/migration-v6.mdx Example of a package.json file after upgrading to OpenWorkflow v0.6, including the core package and the 'postgres' driver if applicable. ```json { "dependencies": { "openworkflow": "^0.6.0", "postgres": "^3.4.8" // Only if using PostgreSQL } } ``` -------------------------------- ### Start Worker with Custom Concurrency Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/cli.mdx Run the worker with a specified number of concurrent workflow executions, overriding the configuration setting. ```bash # Run with 4 concurrent workflows npx @openworkflow/cli worker start --concurrency 4 ``` ```bash # Run with 4 concurrent workflows pnpx @openworkflow/cli worker start --concurrency 4 ``` ```bash # Run with 4 concurrent workflows bunx @openworkflow/cli worker start --concurrency 4 ``` -------------------------------- ### Configure Step Retry Policy Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/retries.mdx This example shows how to override the default retry policy for a specific step. You can customize the initial interval, backoff coefficient, maximum interval, and maximum attempts. ```typescript await step.run( { name: "call-api", retryPolicy: { initialInterval: "500ms", backoffCoefficient: 2, maximumInterval: "30s", maximumAttempts: 5, }, }, async () => { // step logic }, ); ``` -------------------------------- ### Uninstall Legacy Backend Packages (bun) Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/migration-v6.mdx Remove the old backend packages using bun before upgrading to v0.6. This ensures a clean installation of the new core package. ```bash bun remove @openworkflow/backend-postgres @openworkflow/backend-sqlite ``` -------------------------------- ### Define a Durable Workflow with Checkpointed Steps Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/snippets/comparison-durable-workflow.mdx This example demonstrates how to define a durable workflow using `defineWorkflow`. Each `step.run` call represents a durable checkpoint. If the workflow crashes, it will resume from the last completed step. ```typescript import { defineWorkflow } from "openworkflow"; export const processOrder = defineWorkflow( { name: "process-order" }, async ({ input, step }) => { // validate the order, charge the payment, and fulfill the order const order = await step.run({ name: "validate-order" }, async () => { return await orders.validate(input.orderId); }); await step.run({ name: "charge-payment" }, async () => { await payments.charge(order.paymentMethod, order.total); }); await step.run({ name: "fulfill-order" }, async () => { await warehouse.ship(order.id, order.shippingAddress); }); // wait 7 days for delivery, then ask for a review await step.sleep("wait-for-delivery", "7d"); await step.run({ name: "request-review" }, async () => { await email.send({ to: order.email, template: "review-request" }); }); }, ); ``` -------------------------------- ### Parallel Steps Crash Recovery Example Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/parallel-steps.mdx Demonstrates how parallel steps recover from worker crashes. In-progress steps are re-executed by a new worker, while completed steps return cached results. ```typescript const [a, b, c] = await Promise.all([ step.run({ name: "step-a" }, ...), // Completed before crash - cached step.run({ name: "step-b" }, ...), // Completed before crash - cached step.run({ name: "step-c" }, ...), // In progress during crash - re-runs ]); ``` -------------------------------- ### Define and Run Child Workflows Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/child-workflows.mdx Defines a `generate-report` workflow and a `process-order` workflow that calls `generate-report` as a child. Use `step.runWorkflow()` to start a child and wait for its output. ```typescript import { defineWorkflow } from "openworkflow"; const generateReport = defineWorkflow( { name: "generate-report" }, async ({ input, step }) => { const data = await step.run({ name: "fetch-data" }, async () => { return await db.reports.getData(input.reportId); }); await step.run({ name: "upload-report" }, async () => { await storage.upload(`reports/${input.reportId}.pdf`, data); }); return { reportUrl: `https://example.com/reports/${input.reportId}.pdf` }; }, ); const processOrder = defineWorkflow( { name: "process-order" }, async ({ input, step }) => { await step.run({ name: "charge-card" }, async () => { await payments.charge(input.orderId); }); // Start the report workflow and wait for it to finish const report = await step.runWorkflow(generateReport.spec, { reportId: input.orderId, }); await step.run({ name: "send-confirmation" }, async () => { await email.send({ to: input.email, subject: "Order complete", body: `Your report is ready: ${report.reportUrl}`, }); }); }, ); ``` -------------------------------- ### Uninstall Legacy Backend Packages (pnpm) Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/migration-v6.mdx Remove the old backend packages using pnpm before upgrading to v0.6. This ensures a clean installation of the new core package. ```bash pnpm remove @openworkflow/backend-postgres @openworkflow/backend-sqlite ``` -------------------------------- ### Graceful Shutdown Example with npm Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/workers.mdx Observe the graceful shutdown process when a worker receives a SIGINT signal (Ctrl+C). The worker stops polling for new work and waits for active workflows to complete. ```bash # The worker handles Ctrl+C gracefully npx @openworkflow/cli worker start ^C # [info] Shutting down worker... # [info] Worker stopped ``` -------------------------------- ### Uninstall Legacy Backend Packages (npm) Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/migration-v6.mdx Remove the old backend packages using npm before upgrading to v0.6. This ensures a clean installation of the new core package. ```bash npm uninstall @openworkflow/backend-postgres @openworkflow/backend-sqlite ``` -------------------------------- ### Initialize New Project with v0.6 CLI (bun) Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/migration-v6.mdx Use the OpenWorkflow CLI with bun to initialize a new project. The CLI automatically generates code with the updated v0.6 import paths. ```bash bunx @openworkflow/cli init ``` -------------------------------- ### Graceful Shutdown Example with pnpm Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/workers.mdx Observe the graceful shutdown process when a worker receives a SIGINT signal (Ctrl+C). The worker stops polling for new work and waits for active workflows to complete. ```bash # The worker handles Ctrl+C gracefully pnpx @openworkflow/cli worker start ^C # [info] Shutting down worker... # [info] Worker stopped ``` -------------------------------- ### Dockerfile for Node.js Worker (pnpm) Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/production.mdx A Dockerfile template for deploying an OpenWorkflow worker using pnpm. It enables corepack, installs dependencies with pnpm, copies project files, and sets the command to start the worker. ```dockerfile FROM node:22-slim RUN corepack enable WORKDIR /app COPY package.json pnpm-lock.yaml ./ RUN pnpm install --frozen-lockfile COPY . . CMD ["pnpx", "@openworkflow/cli", "worker", "start"] ``` -------------------------------- ### Initialize New Project with v0.6 CLI (pnpm) Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/migration-v6.mdx Use the OpenWorkflow CLI with pnpm to initialize a new project. The CLI automatically generates code with the updated v0.6 import paths. ```bash pnpx @openworkflow/cli init ``` -------------------------------- ### Initialize New Project with v0.6 CLI (npm) Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/migration-v6.mdx Use the OpenWorkflow CLI with npm to initialize a new project. The CLI automatically generates code with the updated v0.6 import paths. ```bash npx @openworkflow/cli init ``` -------------------------------- ### Show Help for CLI Commands Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/cli.mdx Display help information for the OpenWorkflow CLI or specific commands. ```bash npx @openworkflow/cli --help npx @openworkflow/cli worker --help npx @openworkflow/cli worker start --help ``` ```bash pnpx @openworkflow/cli --help pnpx @openworkflow/cli worker --help pnpx @openworkflow/cli worker start --help ``` ```bash bunx @openworkflow/cli --help bunx @openworkflow/cli worker --help bunx @openworkflow/cli worker start --help ``` -------------------------------- ### Return Object from Step Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/steps.mdx Steps can return complex JSON-serializable objects. This example shows returning a user object fetched from a database. ```typescript const user = await step.run({ name: "fetch-user" }, async () => { return await db.users.findOne({ id: input.userId }); }); ``` -------------------------------- ### Configure SQLite Backend Options Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/sqlite.mdx Configure the SQLite backend with options like namespace isolation and automatic migration execution. Defaults are provided for convenience. ```typescript const backend = BackendSqlite.connect(path, { // Namespace for multi-tenant isolation (default: "default") namespaceId: "development", // Whether to run migrations on connect (default: true) runMigrations: true, }); ``` -------------------------------- ### Run Steps Concurrently with Promise.all Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/advanced-patterns.mdx Use `Promise.all` to execute multiple steps concurrently. Each step is memoized individually, and completed steps return instantly on resume if the workflow crashes mid-execution. ```typescript const [user, subscription, settings] = await Promise.all([ step.run({ name: "fetch-user" }, async () => { await db.users.findOne({ id: input.userId }); }), step.run({ name: "fetch-subscription" }, async () => { await stripe.subscriptions.retrieve(input.subId); }), step.run({ name: "fetch-settings" }, async () => { await db.settings.findOne({ userId: input.userId }); }), ]); ``` -------------------------------- ### Return Primitive from Step Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/steps.mdx Steps can return simple JSON-serializable primitive values like numbers. This example returns the length of an items array. ```typescript const count = await step.run({ name: "count-items" }, async () => { return items.length; }); ``` -------------------------------- ### Connect to Production and Staging Namespaces Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/namespaces.mdx Demonstrates connecting to separate production and staging namespaces using the same database. Specify the `namespaceId` option during connection. ```typescript import { BackendPostgres } from "openworkflow/postgres"; // Production namespace const prodBackend = await BackendPostgres.connect(url, { namespaceId: "production", }); // Staging namespace (same database) const stagingBackend = await BackendPostgres.connect(url, { namespaceId: "staging", }); ``` -------------------------------- ### Configure PostgreSQL Backend Options Source: https://github.com/openworkflowdev/openworkflow/blob/main/apps/docs/docs/postgres.mdx Customize the PostgreSQL backend connection with options like namespaceId, schema, and migration settings. ```typescript const backend = await BackendPostgres.connect(url, { // Namespace for multi-tenant isolation (default: "default") namespaceId: "production", // Database schema for OpenWorkflow tables (default: "openworkflow") schema: "openworkflow", // Whether to run migrations on connect (default: true) runMigrations: true, }); ``` -------------------------------- ### Define a Workflow with Steps Source: https://github.com/openworkflowdev/openworkflow/blob/main/packages/openworkflow/README.md Defines a workflow named 'send-welcome-email' that fetches user data, sends an email, and updates user status. Use this to structure sequential or parallel tasks within a workflow. ```typescript import { defineWorkflow } from "openworkflow"; export const sendWelcomeEmail = defineWorkflow( { name: "send-welcome-email" }, async ({ input, step }) => { const user = await step.run({ name: "fetch-user" }, async () => { return await db.users.findOne({ id: input.userId }); }); await step.run({ name: "send-email" }, async () => { return await resend.emails.send({ from: "me@example.com", to: user.email, replyTo: "me@example.com", subject: "Welcome!", html: "