UNPKG

@convex-dev/workflow

Version:

Convex component for durably executing workflows.

115 lines 3.88 kB
import { BaseChannel } from "async-channel"; import { parse } from "convex-helpers/validators"; import { safeFunctionName } from "./safeFunctionName.js"; export function createWorkflowCtx(workflowId, sender) { return { workflowId, runQuery: async (query, args, opts) => { return runFunction(sender, "query", query, args, opts); }, runMutation: async (mutation, args, opts) => { return runFunction(sender, "mutation", mutation, args, opts); }, runAction: async (action, args, opts) => { return runFunction(sender, "action", action, args, opts); }, runWorkflow: async (workflow, args, opts) => { const { name, unstableArgs, ...schedulerOptions } = opts ?? {}; return run(sender, { name: name ?? safeFunctionName(workflow), target: { kind: "workflow", function: workflow, args, }, retry: undefined, inline: false, unstableArgs: unstableArgs ?? false, schedulerOptions, transactionLimits: undefined, }); }, sleep: async (duration, opts) => { await run(sender, { name: opts?.name ?? "sleep", target: { kind: "sleep", args: {}, }, retry: undefined, inline: false, unstableArgs: false, schedulerOptions: { runAfter: duration }, transactionLimits: undefined, }); }, awaitEvent: async (event) => { const result = await run(sender, { name: event.name ?? event.id ?? "Event", target: { kind: "event", args: { eventId: event.id }, }, retry: undefined, inline: false, unstableArgs: false, schedulerOptions: {}, transactionLimits: undefined, }); if (event.validator) { return parse(event.validator, result); } return result; }, }; } async function runFunction(sender, functionType, f, args, opts) { const { name, retry, inline, transactionLimits, unstableArgs, ...schedulerOptions } = opts ?? {}; if (inline && schedulerOptions && (schedulerOptions.runAt || schedulerOptions.runAfter)) { throw new Error("Cannot combine `inline` with `runAt` or `runAfter`."); } if (inline && functionType === "action") { throw new Error("Cannot run an action inline."); } if (!inline && transactionLimits) { throw new Error("Cannot set transaction limits for non-inline functions."); } return run(sender, { name: name ?? safeFunctionName(f), target: { kind: "function", functionType, function: f, args: args ?? {}, }, retry, inline: inline ?? false, unstableArgs: unstableArgs ?? false, transactionLimits, schedulerOptions, }); } async function run(sender, request) { let send; const p = new Promise((resolve) => { send = sender.push({ ...request, resolve, }); }); await send; const result = await p; switch (result.kind) { case "success": return result.returnValue; case "failed": throw new Error(result.error); case "canceled": throw new Error("Canceled"); default: throw new Error("Unknown result kind: " + result.kind); } } //# sourceMappingURL=workflowContext.js.map