@usehelical/workflows 0.0.1-alpha.17 → 0.0.1-alpha.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,12 +1,80 @@
1
1
  # Helical Workflows
2
2
 
3
- Simple, typesafe durable workflows without bundler magic
4
-
5
3
  > [!WARNING]
6
4
  > This is a work in progress
7
5
 
8
- # Goals
6
+ Simple, typesafe durable workflows without bundler magic
7
+
8
+ ## Features
9
+
10
+ - Effortless setup
11
+ - Effortless deployment
12
+ - Automatic workflow recovery
13
+ - Messages
14
+ - State
15
+ - Queues
16
+
17
+ # Getting started
18
+
19
+ ## Installation
20
+
21
+ Install the hkit CLI and apply migrations to your Postgres database
22
+
23
+ ```sh
24
+ curl -sSfL https://releases.usehelical.com/install.sh | sh
25
+ ```
26
+
27
+ Apply migrations to your Postgres instance
28
+
29
+ ```sh
30
+ hkit migrate --databaseUrl postgresql://postgres:postgres@localhost:5432/postgres
31
+ ```
32
+
33
+ Install the @usehelical/workflows npm package to use it in your project
34
+
35
+ ```sh
36
+ pnpm add @usehelical/workflows
37
+ ```
38
+
39
+ ## Defining a workflow
40
+
41
+ Define a workflow by using the defineWorkflow function and execute steps by using the runStep function. It is important that the steps you run are idempotent to ensure correct and reliable execution of your workflow.
42
+
43
+ ```ts
44
+ import { defineWorkflow, runStep } from '@usehelical/workflows/api';
45
+
46
+ export const checkoutWorkflow = defineWorkflow('checkout', async (id: string) => {
47
+ await runStep(async () => {
48
+ await decrementInventory();
49
+ });
50
+
51
+ await runStep(async () => {
52
+ await createOrder(id);
53
+ });
54
+ });
55
+ ```
56
+
57
+ ## Creating a worker
58
+
59
+ Create a worker by using the createWorker function registering the workflows it can run. And connecting it to the previously setup Postgres database.
60
+
61
+ ```ts
62
+ import { createWorker } from '@usehelical/workflows';
63
+
64
+ export const worker = createWorker({
65
+ workflows: [checkoutWorkflow],
66
+ options: {
67
+ connectionString: process.env.DATABASE_URL,
68
+ },
69
+ });
70
+ ```
71
+
72
+ ## Starting a workflow
73
+
74
+ Pass the workflow to the runWorkflow function and pass the arguments to the workflow as an array. The waitForResult function will await the workflow completion.
75
+
76
+ ```ts
77
+ const { id, getStatus, waitForResult } = await worker.runWorkflow(checkoutWorkflow, [id]);
9
78
 
10
- - simple & typesafe api
11
- - minimal deployment complexity (just postgres)
12
- - low latency (making it suitable for user-facing ai workflows)
79
+ const { success, data, error } = await waitForResult();
80
+ ```
package/dist/api.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as StateDefinition, M as MessageDefinition } from './state-B6QkOxSb.js';
2
- export { Q as QueueDefinition, a as QueueOptions, b as QueueRateLimit, R as RunStatus, T as TERMINAL_STATES, W as WorkflowDefinition, c as WorkflowFunction, d as defineMessage, e as defineQueue, f as defineState, g as defineWorkflow } from './state-B6QkOxSb.js';
1
+ import { g as StateDefinition, M as MessageDefinition } from './external-JXNhdgzR.js';
2
+ export { C as CancelRunFunction, G as GetRunFunction, c as GetStateFunction, Q as QueueDefinition, r as QueueOptions, s as QueueRateLimit, a as QueueWorkflowFunction, b as ResumeRunFunction, t as RunStatus, R as RunWorkflowFunction, S as SendMessageFunction, T as TERMINAL_STATES, W as WorkflowDefinition, u as WorkflowFunction, v as cancelRun, w as defineMessage, x as defineQueue, y as defineState, z as defineWorkflow, A as getRun, D as getState, H as queueWorkflow, I as resumeRun, J as runWorkflow, K as sendMessage } from './external-JXNhdgzR.js';
3
3
 
4
4
  type RetryConfig = {
5
5
  maxRetries?: number;
package/dist/api.js CHANGED
@@ -1,5 +1,5 @@
1
- import { getExecutionContext, returnOrThrowOperationResult, executeAndRecordOperation, FatalError, MaxRetriesExceededError, sleep, withDbRetry, serialize, OperationTimedOutError, serializeError, deserialize, RunCancelledError } from './chunk-6L2Y7WUY.js';
2
- export { TERMINAL_STATES, defineWorkflow } from './chunk-6L2Y7WUY.js';
1
+ import { getExecutionContext, returnOrThrowOperationResult, executeAndRecordOperation, FatalError, MaxRetriesExceededError, sleep, withDbRetry, serialize, runWorkflow, queueWorkflow, createRunHandle, cancelRun, resumeRun, sendMessage, getState2 as getState2$1, OperationTimedOutError, serializeError, deserialize, RunCancelledError } from './chunk-7I6XZ2V3.js';
2
+ export { TERMINAL_STATES, defineWorkflow } from './chunk-7I6XZ2V3.js';
3
3
  import { sql } from 'kysely';
4
4
  import crypto, { createHash } from 'crypto';
5
5
 
@@ -9,8 +9,11 @@ function defineMessage(name) {
9
9
  }
10
10
 
11
11
  // src/api/queue.ts
12
- function defineQueue(options = {}) {
13
- return options;
12
+ function defineQueue(name, options = {}) {
13
+ return {
14
+ name,
15
+ ...options
16
+ };
14
17
  }
15
18
 
16
19
  // src/api/state.ts
@@ -246,10 +249,9 @@ function getRunId() {
246
249
  }
247
250
 
248
251
  // src/api/steps/sleep.ts
249
- var SLEEP_OPERATION_NAME = "_helical::sleep";
250
252
  async function sleep2(ms) {
251
253
  const { abortSignal } = getExecutionContext();
252
- return await withDurableDeadline(ms, SLEEP_OPERATION_NAME, async (deadlineMs) => {
254
+ return await withDurableDeadline(ms, "sleep", async (deadlineMs) => {
253
255
  const remainingMs = deadlineMs - Date.now();
254
256
  try {
255
257
  await cancellableSleep(remainingMs, abortSignal);
@@ -304,6 +306,47 @@ async function now() {
304
306
  }
305
307
  }
306
308
 
307
- export { cancellableSleep, defineMessage, defineQueue, defineState, executeStepWithRetries, getAbortSignal, getRunId, getStepId, now, randomUUID, receiveMessage, runStep, setState, sleep2 as sleep };
309
+ // src/api/external.ts
310
+ var runWorkflow2 = async (workflow, argsOrOptions, options) => {
311
+ let args, opts;
312
+ if (argsOrOptions !== void 0) {
313
+ if (Array.isArray(argsOrOptions)) {
314
+ args = argsOrOptions;
315
+ opts = options;
316
+ } else {
317
+ opts = argsOrOptions;
318
+ }
319
+ }
320
+ return runWorkflow(getExecutionContext(), workflow.name, args, opts);
321
+ };
322
+ var queueWorkflow2 = async (queue, workflow, argsOrOptions, options) => {
323
+ let args, opts;
324
+ if (argsOrOptions !== void 0) {
325
+ if (Array.isArray(argsOrOptions)) {
326
+ args = argsOrOptions;
327
+ opts = options;
328
+ } else {
329
+ opts = argsOrOptions;
330
+ }
331
+ }
332
+ return queueWorkflow(getExecutionContext(), queue.name, workflow.name, args, opts);
333
+ };
334
+ var getRun = async (runId) => {
335
+ return createRunHandle(getExecutionContext(), runId);
336
+ };
337
+ var cancelRun2 = async (runId) => {
338
+ return cancelRun(getExecutionContext(), runId);
339
+ };
340
+ var resumeRun2 = async (runId) => {
341
+ return resumeRun(getExecutionContext(), runId);
342
+ };
343
+ var sendMessage2 = async (runId, name, data) => {
344
+ return sendMessage(getExecutionContext(), runId, name, data);
345
+ };
346
+ var getState2 = async (runId, key) => {
347
+ return getState2$1(getExecutionContext(), runId, key);
348
+ };
349
+
350
+ export { cancelRun2 as cancelRun, cancellableSleep, defineMessage, defineQueue, defineState, executeStepWithRetries, getAbortSignal, getRun, getRunId, getState2 as getState, getStepId, now, queueWorkflow2 as queueWorkflow, randomUUID, receiveMessage, resumeRun2 as resumeRun, runStep, runWorkflow2 as runWorkflow, sendMessage2 as sendMessage, setState, sleep2 as sleep };
308
351
  //# sourceMappingURL=api.js.map
309
352
  //# sourceMappingURL=api.js.map
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/message.ts","../src/api/queue.ts","../src/api/state.ts","../src/api/steps/run-step.ts","../src/internal/db/commands/insert-state.ts","../src/api/steps/set-state.ts","../src/internal/db/commands/read-and-delete-message.ts","../src/internal/with-durable-deadline.ts","../src/api/steps/receive-message.ts","../src/api/steps/helpers/get-step-id.ts","../src/api/steps/helpers/get-abort-signal.ts","../src/api/steps/helpers/get-run-id.ts","../src/api/steps/sleep.ts","../src/api/steps/random-uuid.ts","../src/api/steps/now.ts"],"names":["sleep"],"mappings":"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","file":"api.js","sourcesContent":["export type MessageDefinition<T> = {\n name: string;\n __data?: T;\n};\n\nexport function defineMessage<T>(name: string): MessageDefinition<T> {\n return { name } as MessageDefinition<T>;\n}\n","export type QueueRateLimit = {\n limitPerPeriod: number;\n period: number;\n};\n\nexport type QueueOptions = {\n workerConcurrency?: number;\n concurrency?: number;\n rateLimit?: QueueRateLimit;\n priorityEnabled?: boolean;\n partitioningEnabled?: boolean;\n};\n\nexport type QueueDefinition = QueueOptions;\n\nexport function defineQueue(options: QueueOptions = {}): QueueDefinition {\n return options;\n}\n","export interface StateDefinition<T> {\n name: string;\n data?: T;\n}\n\nexport function defineState<T>(name: string) {\n return {\n name,\n } as StateDefinition<T>;\n}\n","import { FatalError, MaxRetriesExceededError } from '@internal/errors';\nimport { getExecutionContext } from '@internal/context/execution-context';\nimport { sleep } from '@internal/utils/sleep';\nimport {\n executeAndRecordOperation,\n returnOrThrowOperationResult,\n} from '@internal/context/operation-manager';\n\nexport type RetryConfig = {\n maxRetries?: number;\n retryDelay?: number;\n backOffRate?: number;\n};\n\ntype RunStepOptions = RetryConfig & {\n name?: string;\n};\n\nexport async function runStep<TReturn>(\n stepFn: () => Promise<TReturn>,\n options: RunStepOptions = {},\n) {\n const { maxRetries, retryDelay, backOffRate } = options;\n const { operationManager } = getExecutionContext();\n const stepName = options.name || stepFn.name || '<unknown>';\n\n const op = operationManager.getOperationResult();\n if (op) {\n return returnOrThrowOperationResult<TReturn>(op);\n }\n return await executeAndRecordOperation(operationManager, stepName, async () => {\n return await executeStepWithRetries(stepName, stepFn, { maxRetries, retryDelay, backOffRate });\n });\n}\n\nclass ErrorThatShouldNeverHappen extends Error {\n constructor() {\n super('This error should never happen');\n }\n}\n\nexport async function executeStepWithRetries<TReturn>(\n stepName: string,\n fn: () => Promise<TReturn>,\n retryConfig: RetryConfig,\n): Promise<TReturn> {\n const maxRetries = retryConfig.maxRetries ?? 0;\n const retryDelay = retryConfig.retryDelay ?? 0;\n const backOffRate = retryConfig.backOffRate ?? 1;\n\n const attemptErrors: Error[] = [];\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n attemptErrors.push(err);\n if (err instanceof FatalError) {\n throw err;\n }\n if (maxRetries === 0) {\n throw err;\n }\n if (attempt >= maxRetries) {\n throw new MaxRetriesExceededError(stepName, maxRetries, attemptErrors);\n }\n const delay = retryDelay * Math.pow(backOffRate, attempt);\n await sleep(delay);\n }\n }\n throw new ErrorThatShouldNeverHappen();\n}\n","import { Database, Transaction } from '../db';\n\ntype InsertStateOptions = {\n runId: string;\n key: string;\n value: string;\n sequenceId: number;\n};\n\nexport async function insertState(tx: Transaction | Database, options: InsertStateOptions) {\n await tx\n .insertInto('state')\n .values({\n run_id: options.runId,\n key: options.key,\n value: options.value,\n })\n .onConflict((oc) =>\n oc.column('run_id').column('key').doUpdateSet({\n value: options.value,\n }),\n )\n .execute();\n\n await tx\n .insertInto('state_history')\n .values({\n run_id: options.runId,\n sequence_id: options.sequenceId,\n key: options.key,\n value: options.value,\n })\n .execute();\n}\n","import { withDbRetry } from '@internal/db/retry';\nimport { getExecutionContext } from '@internal/context/execution-context';\nimport { returnOrThrowOperationResult } from '@internal/context/operation-manager';\nimport { insertState } from '@internal/db/commands/insert-state';\nimport { serialize } from '@internal/utils/serialization';\nimport { StateDefinition } from '@api/state';\n\nconst SET_STATE_OPERATION_NAME = 'workflow::state::set';\n\nexport async function setState<T = unknown>(state: StateDefinition<T> | string, value: T) {\n const stateKey = typeof state === 'string' ? state : state.name;\n const { operationManager, runId, db } = getExecutionContext();\n\n const op = operationManager.getOperationResult();\n if (op) {\n return returnOrThrowOperationResult<void>(op);\n }\n\n const seqId = operationManager.reserveSequenceId();\n\n await withDbRetry(async () => {\n return await db.transaction().execute(async (tx) => {\n await insertState(tx, { runId, key: stateKey, value: serialize(value), sequenceId: seqId });\n await operationManager.recordResult(SET_STATE_OPERATION_NAME, seqId, null, tx);\n });\n });\n}\n","import { sql } from 'kysely';\nimport { Transaction } from '../db';\n\ntype Message = {\n id: string;\n payload?: string;\n type?: string;\n};\n\nexport async function readAndDeleteMessage(\n tx: Transaction,\n runId: string,\n messageType?: string,\n): Promise<Message | undefined> {\n const results = await sql<Message>`\n DELETE FROM messages\n WHERE id IN (\n SELECT id FROM messages\n WHERE destination_run_id = ${runId}\n ${messageType !== undefined ? sql`AND type = ${messageType}` : sql``}\n ORDER BY created_at_epoch_ms ASC\n LIMIT 1\n )\n RETURNING id, payload, type\n `.execute(tx);\n\n const result = results.rows[0];\n\n return result\n ? {\n id: result.id,\n payload: result.payload ?? undefined,\n type: result.type ?? undefined,\n }\n : undefined;\n}\n","import { getExecutionContext } from './context/execution-context';\nimport { executeAndRecordOperation } from './context/operation-manager';\n\nexport async function withDurableDeadline<T>(\n timeoutMs: number | undefined,\n operationName: string,\n fn: (deadlineMs: number | undefined) => Promise<T>,\n): Promise<T> {\n if (!timeoutMs) {\n return await fn(undefined);\n }\n\n const { operationManager } = getExecutionContext();\n\n let deadlineMs: number;\n const op = operationManager.getOperationResult();\n if (op) {\n deadlineMs = Number(op.result);\n } else {\n deadlineMs = Date.now() + timeoutMs;\n await executeAndRecordOperation(operationManager, operationName, async () => {\n return deadlineMs;\n });\n }\n\n return await fn(deadlineMs);\n}\n","import { withDbRetry } from '@internal/db/retry';\nimport { OperationTimedOutError } from '@internal/errors';\nimport { MessageEventBus } from '@internal/events/message-event-bus';\nimport { getExecutionContext } from '@internal/context/execution-context';\nimport { returnOrThrowOperationResult } from '@internal/context/operation-manager';\nimport { readAndDeleteMessage } from '@internal/db/commands/read-and-delete-message';\nimport { deserialize, serialize, serializeError } from '@internal/utils/serialization';\nimport { withDurableDeadline } from '@internal/with-durable-deadline';\nimport { MessageDefinition } from '@api/message';\n\nconst RECEIVE_MESSAGE_OPERATION_NAME = 'receiveMessage';\n\nconst RECEIVE_MESSAGE_DURABLE_DEADLINE_OPERATION_NAME = 'receiveMessageDurableDeadline';\n\nclass MessageNotAvailableError extends Error {}\n\nexport type ReceiveMessageOptions = {\n timeout?: number;\n};\n\nexport async function receiveMessage<T>(\n message: MessageDefinition<T> | string,\n options?: ReceiveMessageOptions,\n): Promise<T> {\n const messageType = typeof message === 'string' ? message : message.name;\n return await withDurableDeadline(\n options?.timeout,\n RECEIVE_MESSAGE_DURABLE_DEADLINE_OPERATION_NAME,\n async (deadlineMs) => {\n return await receiveMessageWithDeadline(messageType, deadlineMs);\n },\n );\n}\n\nasync function receiveMessageWithDeadline<T>(\n messageType: string,\n deadlineMs: number | undefined,\n): Promise<T> {\n const { runId, operationManager, messageEventBus, db } = getExecutionContext();\n\n const op = operationManager.getOperationResult();\n if (op) {\n return returnOrThrowOperationResult<T>(op) as T;\n }\n\n const seqId = operationManager.reserveSequenceId();\n\n while (true) {\n // Check if timeout expired\n if (deadlineMs && Date.now() >= deadlineMs) {\n const error = new OperationTimedOutError('receiveMessage');\n await operationManager.recordError(\n RECEIVE_MESSAGE_OPERATION_NAME,\n seqId,\n serializeError(error),\n );\n throw error;\n }\n\n try {\n return await withDbRetry(async () => {\n return await db.transaction().execute(async (tx) => {\n const msg = await readAndDeleteMessage(tx, runId, messageType);\n if (!msg) {\n throw new MessageNotAvailableError();\n }\n await operationManager.recordResult(\n RECEIVE_MESSAGE_OPERATION_NAME,\n seqId,\n serialize(msg.payload),\n tx,\n );\n return deserialize(msg.payload!) as T;\n });\n });\n } catch (error) {\n if (error instanceof MessageNotAvailableError) {\n const remainingMs = deadlineMs ? deadlineMs - Date.now() : undefined;\n await waitForMessageNotification(messageEventBus, runId, messageType, remainingMs);\n continue;\n }\n // Record and re-throw other errors\n await operationManager.recordError(\n RECEIVE_MESSAGE_OPERATION_NAME,\n seqId,\n serializeError(error as Error),\n );\n throw error;\n }\n }\n}\n\nasync function waitForMessageNotification(\n messageEventBus: MessageEventBus,\n runId: string,\n messageType: string,\n timeoutMs?: number,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n let timeoutId: NodeJS.Timeout | undefined;\n\n if (timeoutMs !== undefined) {\n if (timeoutMs <= 0) {\n reject(new OperationTimedOutError('receiveMessageDurableDeadline'));\n return;\n }\n\n timeoutId = setTimeout(() => {\n unsubscribe();\n reject(new OperationTimedOutError('waitForMessageNotification'));\n }, timeoutMs);\n }\n\n const unsubscribe = messageEventBus.subscribe(runId, messageType, () => {\n if (timeoutId) clearTimeout(timeoutId);\n unsubscribe();\n resolve();\n });\n });\n}\n","import { getExecutionContext } from '@internal/context/execution-context';\nimport { createHash } from 'node:crypto';\n\n/**\n * Generates a stable, unique step ID based on the current run ID and sequence ID.\n * This ID is deterministic and will remain the same across retries, making it\n * suitable for use as an idempotency key with third-party systems.\n *\n * The step ID is a SHA-256 hash of the run ID and sequence ID, formatted as a\n * hex string for easy use with external APIs.\n *\n * @returns A unique, stable identifier for the current step execution\n */\nexport function getStepId(): string {\n const ctx = getExecutionContext();\n const sequenceId = ctx.operationManager.getActiveSequenceId();\n\n if (sequenceId === null) {\n throw new Error('getStepId() can only be called from within a step function');\n }\n\n const hash = createHash('sha256');\n hash.update(`${ctx.runId}:${sequenceId}`);\n return hash.digest('hex');\n}\n","import { getExecutionContext } from '@internal/context/execution-context';\n\nexport function getAbortSignal() {\n return getExecutionContext().abortSignal;\n}\n","import { getExecutionContext } from '@internal/context/execution-context';\n\nexport function getRunId() {\n const { runId } = getExecutionContext();\n return runId;\n}\n","import { RunCancelledError } from '@internal/errors';\nimport { getExecutionContext } from '@internal/context/execution-context';\nimport { withDurableDeadline } from '@internal/with-durable-deadline';\n\nconst SLEEP_OPERATION_NAME = '_helical::sleep';\n\nexport async function sleep(ms: number) {\n const { abortSignal } = getExecutionContext();\n return await withDurableDeadline(ms, SLEEP_OPERATION_NAME, async (deadlineMs) => {\n const remainingMs = deadlineMs! - Date.now();\n try {\n await cancellableSleep(remainingMs, abortSignal);\n } catch {\n throw new RunCancelledError();\n }\n });\n}\n\nexport function cancellableSleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error('Sleep aborted'));\n return;\n }\n\n const timeoutId = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n\n const onAbort = () => {\n cleanup();\n reject(new Error('Sleep aborted'));\n };\n\n const cleanup = () => {\n clearTimeout(timeoutId);\n signal?.removeEventListener('abort', onAbort);\n };\n\n signal?.addEventListener('abort', onAbort);\n });\n}\n","import crypto from 'node:crypto';\nimport { getExecutionContext } from '@internal/context/execution-context';\nimport { executeAndRecordOperation } from '@internal/context/operation-manager';\n\nexport async function randomUUID() {\n const { operationManager } = getExecutionContext();\n const existingResult = operationManager.getOperationResult();\n if (existingResult) {\n return existingResult.result as string;\n } else {\n return await executeAndRecordOperation(operationManager, 'randomUUID', async () => {\n return crypto.randomUUID();\n });\n }\n}\n","import { getExecutionContext } from '@internal/context/execution-context';\nimport { executeAndRecordOperation } from '@internal/context/operation-manager';\n\nexport async function now() {\n const { operationManager } = getExecutionContext();\n const op = operationManager.getOperationResult();\n if (op) {\n return Number(op.result);\n } else {\n return await executeAndRecordOperation(operationManager, 'now', async () => {\n return Date.now();\n });\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/api/message.ts","../src/api/queue.ts","../src/api/state.ts","../src/api/steps/run-step.ts","../src/internal/db/commands/insert-state.ts","../src/api/steps/set-state.ts","../src/internal/db/commands/read-and-delete-message.ts","../src/internal/with-durable-deadline.ts","../src/api/steps/receive-message.ts","../src/api/steps/helpers/get-step-id.ts","../src/api/steps/helpers/get-abort-signal.ts","../src/api/steps/helpers/get-run-id.ts","../src/api/steps/sleep.ts","../src/api/steps/random-uuid.ts","../src/api/steps/now.ts","../src/api/external.ts"],"names":["sleep","runWorkflow","queueWorkflow","cancelRun","resumeRun","sendMessage","getState"],"mappings":"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","file":"api.js","sourcesContent":["export type MessageDefinition<T> = {\n name: string;\n __data?: T;\n};\n\nexport function defineMessage<T>(name: string): MessageDefinition<T> {\n return { name } as MessageDefinition<T>;\n}\n","export type QueueRateLimit = {\n limitPerPeriod: number;\n period: number;\n};\n\nexport type QueueOptions = {\n workerConcurrency?: number;\n concurrency?: number;\n rateLimit?: QueueRateLimit;\n priorityEnabled?: boolean;\n partitioningEnabled?: boolean;\n};\n\nexport type QueueDefinition = QueueOptions & {\n name: string;\n};\n\nexport function defineQueue(name: string, options: QueueOptions = {}): QueueDefinition {\n return {\n name,\n ...options,\n };\n}\n","export interface StateDefinition<T> {\n name: string;\n __data?: T;\n}\n\nexport function defineState<T>(name: string) {\n return {\n name,\n } as StateDefinition<T>;\n}\n","import { FatalError, MaxRetriesExceededError } from '@internal/errors';\nimport { getExecutionContext } from '@internal/context/execution-context';\nimport { sleep } from '@internal/utils/sleep';\nimport {\n executeAndRecordOperation,\n returnOrThrowOperationResult,\n} from '@internal/context/operation-manager';\n\nexport type RetryConfig = {\n maxRetries?: number;\n retryDelay?: number;\n backOffRate?: number;\n};\n\ntype RunStepOptions = RetryConfig & {\n name?: string;\n};\n\nexport async function runStep<TReturn>(\n stepFn: () => Promise<TReturn>,\n options: RunStepOptions = {},\n) {\n const { maxRetries, retryDelay, backOffRate } = options;\n const { operationManager } = getExecutionContext();\n const stepName = options.name || stepFn.name || '<unknown>';\n\n const op = operationManager.getOperationResult();\n if (op) {\n return returnOrThrowOperationResult<TReturn>(op);\n }\n return await executeAndRecordOperation(operationManager, stepName, async () => {\n return await executeStepWithRetries(stepName, stepFn, { maxRetries, retryDelay, backOffRate });\n });\n}\n\nclass ErrorThatShouldNeverHappen extends Error {\n constructor() {\n super('This error should never happen');\n }\n}\n\nexport async function executeStepWithRetries<TReturn>(\n stepName: string,\n fn: () => Promise<TReturn>,\n retryConfig: RetryConfig,\n): Promise<TReturn> {\n const maxRetries = retryConfig.maxRetries ?? 0;\n const retryDelay = retryConfig.retryDelay ?? 0;\n const backOffRate = retryConfig.backOffRate ?? 1;\n\n const attemptErrors: Error[] = [];\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n attemptErrors.push(err);\n if (err instanceof FatalError) {\n throw err;\n }\n if (maxRetries === 0) {\n throw err;\n }\n if (attempt >= maxRetries) {\n throw new MaxRetriesExceededError(stepName, maxRetries, attemptErrors);\n }\n const delay = retryDelay * Math.pow(backOffRate, attempt);\n await sleep(delay);\n }\n }\n throw new ErrorThatShouldNeverHappen();\n}\n","import { Database, Transaction } from '../db';\n\ntype InsertStateOptions = {\n runId: string;\n key: string;\n value: string;\n sequenceId: number;\n};\n\nexport async function insertState(tx: Transaction | Database, options: InsertStateOptions) {\n await tx\n .insertInto('state')\n .values({\n run_id: options.runId,\n key: options.key,\n value: options.value,\n })\n .onConflict((oc) =>\n oc.column('run_id').column('key').doUpdateSet({\n value: options.value,\n }),\n )\n .execute();\n\n await tx\n .insertInto('state_history')\n .values({\n run_id: options.runId,\n sequence_id: options.sequenceId,\n key: options.key,\n value: options.value,\n })\n .execute();\n}\n","import { withDbRetry } from '@internal/db/retry';\nimport { getExecutionContext } from '@internal/context/execution-context';\nimport { returnOrThrowOperationResult } from '@internal/context/operation-manager';\nimport { insertState } from '@internal/db/commands/insert-state';\nimport { serialize } from '@internal/utils/serialization';\nimport { StateDefinition } from '@api/state';\n\nconst SET_STATE_OPERATION_NAME = 'workflow::state::set';\n\nexport async function setState<T = unknown>(state: StateDefinition<T> | string, value: T) {\n const stateKey = typeof state === 'string' ? state : state.name;\n const { operationManager, runId, db } = getExecutionContext();\n\n const op = operationManager.getOperationResult();\n if (op) {\n return returnOrThrowOperationResult<void>(op);\n }\n\n const seqId = operationManager.reserveSequenceId();\n\n await withDbRetry(async () => {\n return await db.transaction().execute(async (tx) => {\n await insertState(tx, { runId, key: stateKey, value: serialize(value), sequenceId: seqId });\n await operationManager.recordResult(SET_STATE_OPERATION_NAME, seqId, null, tx);\n });\n });\n}\n","import { sql } from 'kysely';\nimport { Transaction } from '../db';\n\ntype Message = {\n id: string;\n payload?: string;\n type?: string;\n};\n\nexport async function readAndDeleteMessage(\n tx: Transaction,\n runId: string,\n messageType?: string,\n): Promise<Message | undefined> {\n const results = await sql<Message>`\n DELETE FROM messages\n WHERE id IN (\n SELECT id FROM messages\n WHERE destination_run_id = ${runId}\n ${messageType !== undefined ? sql`AND type = ${messageType}` : sql``}\n ORDER BY created_at_epoch_ms ASC\n LIMIT 1\n )\n RETURNING id, payload, type\n `.execute(tx);\n\n const result = results.rows[0];\n\n return result\n ? {\n id: result.id,\n payload: result.payload ?? undefined,\n type: result.type ?? undefined,\n }\n : undefined;\n}\n","import { getExecutionContext } from './context/execution-context';\nimport { executeAndRecordOperation } from './context/operation-manager';\n\nexport async function withDurableDeadline<T>(\n timeoutMs: number | undefined,\n operationName: string,\n fn: (deadlineMs: number | undefined) => Promise<T>,\n): Promise<T> {\n if (!timeoutMs) {\n return await fn(undefined);\n }\n\n const { operationManager } = getExecutionContext();\n\n let deadlineMs: number;\n const op = operationManager.getOperationResult();\n if (op) {\n deadlineMs = Number(op.result);\n } else {\n deadlineMs = Date.now() + timeoutMs;\n await executeAndRecordOperation(operationManager, operationName, async () => {\n return deadlineMs;\n });\n }\n\n return await fn(deadlineMs);\n}\n","import { withDbRetry } from '@internal/db/retry';\nimport { OperationTimedOutError } from '@internal/errors';\nimport { MessageEventBus } from '@internal/events/message-event-bus';\nimport { getExecutionContext } from '@internal/context/execution-context';\nimport { returnOrThrowOperationResult } from '@internal/context/operation-manager';\nimport { readAndDeleteMessage } from '@internal/db/commands/read-and-delete-message';\nimport { deserialize, serialize, serializeError } from '@internal/utils/serialization';\nimport { withDurableDeadline } from '@internal/with-durable-deadline';\nimport { MessageDefinition } from '@api/message';\n\nconst RECEIVE_MESSAGE_OPERATION_NAME = 'receiveMessage';\n\nconst RECEIVE_MESSAGE_DURABLE_DEADLINE_OPERATION_NAME = 'receiveMessageDurableDeadline';\n\nclass MessageNotAvailableError extends Error {}\n\nexport type ReceiveMessageOptions = {\n timeout?: number;\n};\n\nexport async function receiveMessage<T>(\n message: MessageDefinition<T> | string,\n options?: ReceiveMessageOptions,\n): Promise<T> {\n const messageType = typeof message === 'string' ? message : message.name;\n return await withDurableDeadline(\n options?.timeout,\n RECEIVE_MESSAGE_DURABLE_DEADLINE_OPERATION_NAME,\n async (deadlineMs) => {\n return await receiveMessageWithDeadline(messageType, deadlineMs);\n },\n );\n}\n\nasync function receiveMessageWithDeadline<T>(\n messageType: string,\n deadlineMs: number | undefined,\n): Promise<T> {\n const { runId, operationManager, messageEventBus, db } = getExecutionContext();\n\n const op = operationManager.getOperationResult();\n if (op) {\n return returnOrThrowOperationResult<T>(op) as T;\n }\n\n const seqId = operationManager.reserveSequenceId();\n\n while (true) {\n // Check if timeout expired\n if (deadlineMs && Date.now() >= deadlineMs) {\n const error = new OperationTimedOutError('receiveMessage');\n await operationManager.recordError(\n RECEIVE_MESSAGE_OPERATION_NAME,\n seqId,\n serializeError(error),\n );\n throw error;\n }\n\n try {\n return await withDbRetry(async () => {\n return await db.transaction().execute(async (tx) => {\n const msg = await readAndDeleteMessage(tx, runId, messageType);\n if (!msg) {\n throw new MessageNotAvailableError();\n }\n await operationManager.recordResult(\n RECEIVE_MESSAGE_OPERATION_NAME,\n seqId,\n serialize(msg.payload),\n tx,\n );\n return deserialize(msg.payload!) as T;\n });\n });\n } catch (error) {\n if (error instanceof MessageNotAvailableError) {\n const remainingMs = deadlineMs ? deadlineMs - Date.now() : undefined;\n await waitForMessageNotification(messageEventBus, runId, messageType, remainingMs);\n continue;\n }\n // Record and re-throw other errors\n await operationManager.recordError(\n RECEIVE_MESSAGE_OPERATION_NAME,\n seqId,\n serializeError(error as Error),\n );\n throw error;\n }\n }\n}\n\nasync function waitForMessageNotification(\n messageEventBus: MessageEventBus,\n runId: string,\n messageType: string,\n timeoutMs?: number,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n let timeoutId: NodeJS.Timeout | undefined;\n\n if (timeoutMs !== undefined) {\n if (timeoutMs <= 0) {\n reject(new OperationTimedOutError('receiveMessageDurableDeadline'));\n return;\n }\n\n timeoutId = setTimeout(() => {\n unsubscribe();\n reject(new OperationTimedOutError('waitForMessageNotification'));\n }, timeoutMs);\n }\n\n const unsubscribe = messageEventBus.subscribe(runId, messageType, () => {\n if (timeoutId) clearTimeout(timeoutId);\n unsubscribe();\n resolve();\n });\n });\n}\n","import { getExecutionContext } from '@internal/context/execution-context';\nimport { createHash } from 'node:crypto';\n\n/**\n * Generates a stable, unique step ID based on the current run ID and sequence ID.\n * This ID is deterministic and will remain the same across retries, making it\n * suitable for use as an idempotency key with third-party systems.\n *\n * The step ID is a SHA-256 hash of the run ID and sequence ID, formatted as a\n * hex string for easy use with external APIs.\n *\n * @returns A unique, stable identifier for the current step execution\n */\nexport function getStepId(): string {\n const ctx = getExecutionContext();\n const sequenceId = ctx.operationManager.getActiveSequenceId();\n\n if (sequenceId === null) {\n throw new Error('getStepId() can only be called from within a step function');\n }\n\n const hash = createHash('sha256');\n hash.update(`${ctx.runId}:${sequenceId}`);\n return hash.digest('hex');\n}\n","import { getExecutionContext } from '@internal/context/execution-context';\n\nexport function getAbortSignal() {\n return getExecutionContext().abortSignal;\n}\n","import { getExecutionContext } from '@internal/context/execution-context';\n\nexport function getRunId() {\n const { runId } = getExecutionContext();\n return runId;\n}\n","import { RunCancelledError } from '@internal/errors';\nimport { getExecutionContext } from '@internal/context/execution-context';\nimport { withDurableDeadline } from '@internal/with-durable-deadline';\n\nexport async function sleep(ms: number) {\n const { abortSignal } = getExecutionContext();\n return await withDurableDeadline(ms, 'sleep', async (deadlineMs) => {\n const remainingMs = deadlineMs! - Date.now();\n try {\n await cancellableSleep(remainingMs, abortSignal);\n } catch {\n throw new RunCancelledError();\n }\n });\n}\n\nexport function cancellableSleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error('Sleep aborted'));\n return;\n }\n\n const timeoutId = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n\n const onAbort = () => {\n cleanup();\n reject(new Error('Sleep aborted'));\n };\n\n const cleanup = () => {\n clearTimeout(timeoutId);\n signal?.removeEventListener('abort', onAbort);\n };\n\n signal?.addEventListener('abort', onAbort);\n });\n}\n","import crypto from 'node:crypto';\nimport { getExecutionContext } from '@internal/context/execution-context';\nimport { executeAndRecordOperation } from '@internal/context/operation-manager';\n\nexport async function randomUUID() {\n const { operationManager } = getExecutionContext();\n const existingResult = operationManager.getOperationResult();\n if (existingResult) {\n return existingResult.result as string;\n } else {\n return await executeAndRecordOperation(operationManager, 'randomUUID', async () => {\n return crypto.randomUUID();\n });\n }\n}\n","import { getExecutionContext } from '@internal/context/execution-context';\nimport { executeAndRecordOperation } from '@internal/context/operation-manager';\n\nexport async function now() {\n const { operationManager } = getExecutionContext();\n const op = operationManager.getOperationResult();\n if (op) {\n return Number(op.result);\n } else {\n return await executeAndRecordOperation(operationManager, 'now', async () => {\n return Date.now();\n });\n }\n}\n","import { WorkflowDefinition } from './workflow';\nimport { QueueDefinition } from './queue';\nimport { MessageDefinition } from './message';\nimport { StateDefinition } from './state';\nimport {\n queueWorkflow as queueWorkflowInternal,\n type QueueWorkflowOptions,\n} from '@internal/queue-workflow';\nimport {\n runWorkflow as runWorkflowInternal,\n type RunWorkflowOptions,\n} from '@internal/run-workflow';\nimport { cancelRun as cancelRunInternal } from '@internal/cancel-run';\nimport { resumeRun as resumeRunInternal } from '@internal/resume-run';\nimport { sendMessage as sendMessageInternal } from '@internal/send-message';\nimport { getState as getStateInternal } from '@internal/get-state';\nimport { createRunHandle, type Run } from '@internal/run';\nimport { getExecutionContext } from '@internal/context/execution-context';\n\nexport interface RunWorkflowFunction {\n <TArgs extends unknown[], TReturn>(\n workflow: WorkflowDefinition<TArgs, TReturn>,\n options: RunWorkflowOptions,\n ): Promise<Run<TReturn>>;\n\n <TArgs extends unknown[], TReturn>(\n workflow: WorkflowDefinition<TArgs, TReturn>,\n args?: TArgs,\n options?: RunWorkflowOptions,\n ): Promise<Run<TReturn>>;\n}\n\nexport interface QueueWorkflowFunction {\n <TArgs extends unknown[], TReturn = unknown>(\n queue: QueueDefinition,\n workflow: WorkflowDefinition<TArgs, TReturn>,\n args: TArgs,\n options?: QueueWorkflowOptions,\n ): Promise<Run<TReturn>>;\n\n <TArgs extends unknown[], TReturn = unknown>(\n queue: QueueDefinition,\n workflow: WorkflowDefinition<TArgs, TReturn>,\n options: QueueWorkflowOptions,\n ): Promise<Run<TReturn>>;\n\n <TArgs extends unknown[], TReturn = unknown>(\n queue: QueueDefinition,\n workflow: WorkflowDefinition<TArgs, TReturn>,\n ): Promise<Run<TReturn>>;\n}\n\nexport type CancelRunFunction = (runId: string) => Promise<void>;\nexport type ResumeRunFunction = (runId: string) => Promise<void>;\nexport type GetRunFunction = <TReturn = unknown>(runId: string) => Promise<Run<TReturn>>;\nexport type SendMessageFunction = <TData = unknown>(\n runId: string,\n name: MessageDefinition<TData>,\n data: TData,\n) => Promise<void>;\nexport type GetStateFunction = <TData = unknown>(\n runId: string,\n key: StateDefinition<TData>,\n) => Promise<TData | undefined>;\n\nexport const runWorkflow: RunWorkflowFunction = async <TArgs extends unknown[], TReturn = unknown>(\n workflow: WorkflowDefinition<TArgs, TReturn>,\n argsOrOptions?: TArgs | RunWorkflowOptions,\n options?: RunWorkflowOptions,\n) => {\n let args, opts;\n if (argsOrOptions !== undefined) {\n if (Array.isArray(argsOrOptions)) {\n args = argsOrOptions;\n opts = options;\n } else {\n opts = argsOrOptions;\n }\n }\n return runWorkflowInternal<TArgs, TReturn>(getExecutionContext(), workflow.name, args, opts);\n};\n\nexport const queueWorkflow: QueueWorkflowFunction = async <\n TArgs extends unknown[],\n TReturn = unknown,\n>(\n queue: QueueDefinition,\n workflow: WorkflowDefinition<TArgs, TReturn>,\n argsOrOptions?: TArgs | QueueWorkflowOptions,\n options?: QueueWorkflowOptions,\n) => {\n let args, opts;\n if (argsOrOptions !== undefined) {\n if (Array.isArray(argsOrOptions)) {\n args = argsOrOptions;\n opts = options;\n } else {\n opts = argsOrOptions;\n }\n }\n return queueWorkflowInternal(getExecutionContext(), queue.name, workflow.name, args, opts);\n};\n\nexport const getRun: GetRunFunction = async <TReturn = unknown>(runId: string) => {\n return createRunHandle<TReturn>(getExecutionContext(), runId);\n};\n\nexport const cancelRun: CancelRunFunction = async (runId: string) => {\n return cancelRunInternal(getExecutionContext(), runId);\n};\n\nexport const resumeRun: ResumeRunFunction = async (runId: string) => {\n return resumeRunInternal(getExecutionContext(), runId);\n};\n\nexport const sendMessage: SendMessageFunction = async <TData = unknown>(\n runId: string,\n name: MessageDefinition<TData>,\n data: TData,\n) => {\n return sendMessageInternal(getExecutionContext(), runId, name, data);\n};\n\nexport const getState: GetStateFunction = async <TData = unknown>(\n runId: string,\n key: StateDefinition<TData>,\n) => {\n return getStateInternal(getExecutionContext(), runId, key);\n};\n"]}