@tanstack/workflow-store-drizzle-postgres 0.0.1 → 0.0.2
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/dist/store.cjs +20 -6
- package/dist/store.cjs.map +1 -1
- package/dist/store.js +20 -6
- package/dist/store.js.map +1 -1
- package/package.json +1 -1
- package/src/store.ts +20 -6
package/dist/store.cjs
CHANGED
|
@@ -498,12 +498,26 @@ function createDrizzlePostgresWorkflowStore(options) {
|
|
|
498
498
|
},
|
|
499
499
|
async claimDueScheduleBuckets(args) {
|
|
500
500
|
const schedules = await queryRows(db, drizzle_orm.sql`
|
|
501
|
-
select
|
|
502
|
-
from ${tableSql.schedules}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
and
|
|
506
|
-
|
|
501
|
+
select schedule.*
|
|
502
|
+
from ${tableSql.schedules} schedule
|
|
503
|
+
left join ${tableSql.scheduleBuckets} bucket
|
|
504
|
+
on bucket.schedule_id = schedule.schedule_id
|
|
505
|
+
and bucket.bucket_id = schedule.next_fire_at::text
|
|
506
|
+
where schedule.enabled = true
|
|
507
|
+
and schedule.next_fire_at is not null
|
|
508
|
+
and schedule.next_fire_at <= ${args.now}
|
|
509
|
+
and (
|
|
510
|
+
bucket.schedule_id is null
|
|
511
|
+
or (
|
|
512
|
+
bucket.status <> 'started'
|
|
513
|
+
and (
|
|
514
|
+
bucket.lease_owner is null
|
|
515
|
+
or bucket.lease_owner = ${args.leaseOwner}
|
|
516
|
+
or bucket.lease_expires_at <= ${args.now}
|
|
517
|
+
)
|
|
518
|
+
)
|
|
519
|
+
)
|
|
520
|
+
order by schedule.next_fire_at asc, schedule.schedule_id asc
|
|
507
521
|
limit ${args.limit}
|
|
508
522
|
`);
|
|
509
523
|
const buckets = [];
|
package/dist/store.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.cjs","names":["sql","LogConflictError"],"sources":["../src/store.ts"],"sourcesContent":["import { LogConflictError } from '@tanstack/workflow-core'\nimport { sql } from 'drizzle-orm'\nimport type { RunState, WorkflowEvent } from '@tanstack/workflow-core'\nimport type { SQL } from 'drizzle-orm'\nimport type {\n AppendEventsArgs,\n AppendEventsResult,\n ClaimDueScheduleBucketsArgs,\n ClaimDueTimersArgs,\n ClaimRunArgs,\n ClaimRunResult,\n ClaimStaleRunsArgs,\n CreateRunArgs,\n CreateRunResult,\n DeliverApprovalArgs,\n DeliverApprovalResult,\n DeliverSignalArgs,\n DeliverSignalResult,\n HeartbeatRunLeaseArgs,\n ListRunsArgs,\n LoadedExecution,\n MarkRunErroredArgs,\n MarkRunFinishedArgs,\n MarkRunPausedArgs,\n MarkScheduleBucketStartedArgs,\n ReadEventsArgs,\n ReleaseRunLeaseArgs,\n RunClaim,\n RunId,\n RunSummary,\n RunTimeline,\n SaveRunStateArgs,\n ScheduleBucket,\n ScheduleBucketId,\n ScheduleId,\n ScheduleTimerArgs,\n StoredWorkflowEvent,\n TimerWakeup,\n UpsertScheduleArgs,\n WorkflowExecution,\n WorkflowExecutionStatus,\n WorkflowExecutionStore,\n WorkflowRunStoreAdapterStore,\n} from '@tanstack/workflow-runtime'\n\nexport interface DrizzlePostgresDatabase {\n execute: (query: SQL | string) => PromiseLike<unknown>\n transaction?: <TResult>(\n callback: (tx: DrizzlePostgresDatabase) => Promise<TResult>,\n ) => Promise<TResult>\n}\n\nexport interface DrizzlePostgresWorkflowStoreTables {\n runs: string\n runStates: string\n eventLocks: string\n events: string\n timers: string\n signalDeliveries: string\n schedules: string\n scheduleBuckets: string\n}\n\nexport interface DrizzlePostgresWorkflowStoreOptions {\n db: DrizzlePostgresDatabase\n schema?: string\n tables?: Partial<DrizzlePostgresWorkflowStoreTables>\n}\n\nexport type DrizzlePostgresWorkflowStore = WorkflowExecutionStore &\n WorkflowRunStoreAdapterStore & {\n ensureSchema: () => Promise<void>\n }\n\nexport const defaultDrizzlePostgresWorkflowStoreTables: DrizzlePostgresWorkflowStoreTables =\n {\n runs: 'workflow_runs',\n runStates: 'workflow_run_states',\n eventLocks: 'workflow_event_locks',\n events: 'workflow_events',\n timers: 'workflow_timers',\n signalDeliveries: 'workflow_signal_deliveries',\n schedules: 'workflow_schedules',\n scheduleBuckets: 'workflow_schedule_buckets',\n }\n\nexport function createDrizzlePostgresWorkflowStore(\n options: DrizzlePostgresWorkflowStoreOptions,\n): DrizzlePostgresWorkflowStore {\n const tableNames = {\n ...defaultDrizzlePostgresWorkflowStoreTables,\n ...options.tables,\n }\n const tableSql = tableSqls(options.schema, tableNames)\n const db = options.db\n\n return {\n async ensureSchema() {\n for (const statement of schemaStatements(options.schema, tableNames)) {\n await db.execute(sql.raw(statement))\n }\n },\n\n async createRun(args: CreateRunArgs): Promise<CreateRunResult> {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n insert into ${tableSql.runs} (\n run_id,\n workflow_id,\n workflow_version,\n status,\n input,\n created_at,\n updated_at\n )\n values (\n ${args.runId},\n ${args.workflowId},\n ${args.workflowVersion ?? null},\n 'queued',\n ${encodeJson(args.input)}::jsonb,\n ${args.now},\n ${args.now}\n )\n on conflict (run_id) do nothing\n returning *\n `,\n )\n if (rows[0]) return { kind: 'created', run: runFromRow(rows[0]) }\n\n const existing = await loadRunById(db, tableSql, args.runId)\n if (!existing) {\n throw new Error(`Run \"${args.runId}\" was not inserted or loaded.`)\n }\n return { kind: 'existing', run: existing }\n },\n\n loadRun(runId: RunId) {\n return loadRunById(db, tableSql, runId)\n },\n\n async loadExecution(runId: RunId): Promise<LoadedExecution | undefined> {\n const run = await loadRunById(db, tableSql, runId)\n if (!run) return undefined\n return {\n run,\n events: await readStoredEvents(db, tableSql, { runId }),\n }\n },\n\n async loadRunState(runId: RunId) {\n return loadRunStateById(db, tableSql, runId)\n },\n\n async saveRunState(args: SaveRunStateArgs) {\n const state = args.state\n await withTransaction(db, async (tx) => {\n await tx.execute(sql`\n insert into ${tableSql.runStates} (\n run_id,\n workflow_id,\n workflow_version,\n status,\n input,\n output,\n error,\n waiting_for,\n pending_approval,\n created_at,\n updated_at\n )\n values (\n ${state.runId},\n ${state.workflowId},\n ${state.workflowVersion ?? null},\n ${state.status},\n ${encodeJson(state.input)}::jsonb,\n ${encodeJsonOrNull(state.output)}::jsonb,\n ${encodeJsonOrNull(state.error)}::jsonb,\n ${encodeJsonOrNull(state.waitingFor)}::jsonb,\n ${encodeJsonOrNull(state.pendingApproval)}::jsonb,\n ${state.createdAt},\n ${state.updatedAt}\n )\n on conflict (run_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n status = excluded.status,\n input = excluded.input,\n output = excluded.output,\n error = excluded.error,\n waiting_for = excluded.waiting_for,\n pending_approval = excluded.pending_approval,\n created_at = excluded.created_at,\n updated_at = excluded.updated_at\n `)\n await tx.execute(sql`\n insert into ${tableSql.runs} (\n run_id,\n workflow_id,\n workflow_version,\n status,\n input,\n output,\n error,\n waiting_for,\n pending_approval,\n wake_at,\n created_at,\n updated_at\n )\n values (\n ${state.runId},\n ${state.workflowId},\n ${state.workflowVersion ?? null},\n ${state.status},\n ${encodeJson(state.input)}::jsonb,\n ${encodeJsonOrNull(state.output)}::jsonb,\n ${encodeJsonOrNull(state.error)}::jsonb,\n ${encodeJsonOrNull(state.waitingFor)}::jsonb,\n ${encodeJsonOrNull(state.pendingApproval)}::jsonb,\n ${\n state.waitingFor?.signalName === '__timer'\n ? state.waitingFor.deadline\n : null\n },\n ${state.createdAt},\n ${state.updatedAt}\n )\n on conflict (run_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n status = excluded.status,\n input = excluded.input,\n output = excluded.output,\n error = excluded.error,\n waiting_for = excluded.waiting_for,\n pending_approval = excluded.pending_approval,\n wake_at = excluded.wake_at,\n created_at = excluded.created_at,\n updated_at = excluded.updated_at\n `)\n })\n },\n\n async deleteRun(runId, _reason) {\n await withTransaction(db, async (tx) => {\n await tx.execute(sql`\n delete from ${tableSql.runStates}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.eventLocks}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.signalDeliveries}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.timers}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.events}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.runs}\n where run_id = ${runId}\n `)\n })\n },\n\n async appendEvents(args: AppendEventsArgs): Promise<AppendEventsResult> {\n return withTransaction(db, async (tx) => {\n await tx.execute(sql`\n insert into ${tableSql.eventLocks} (run_id, created_at)\n values (${args.runId}, ${Date.now()})\n on conflict (run_id) do nothing\n `)\n await queryRows<{ run_id: string }>(\n tx,\n sql`\n select run_id\n from ${tableSql.eventLocks}\n where run_id = ${args.runId}\n for update\n `,\n )\n\n const countRows = await queryRows<{ count: number | string }>(\n tx,\n sql`\n select count(*)::int as count\n from ${tableSql.events}\n where run_id = ${args.runId}\n `,\n )\n const currentCount = Number(countRows[0]?.count ?? 0)\n\n if (currentCount !== args.expectedNextIndex) {\n const conflict = await queryRows<EventRow>(\n tx,\n sql`\n select *\n from ${tableSql.events}\n where run_id = ${args.runId}\n and event_index = ${args.expectedNextIndex}\n limit 1\n `,\n )\n throw new LogConflictError(\n args.runId,\n args.expectedNextIndex,\n conflict[0] ? eventFromRow(conflict[0]).event : undefined,\n )\n }\n\n let nextIndex = args.expectedNextIndex\n for (const event of args.events) {\n await tx.execute(sql`\n insert into ${tableSql.events} (\n run_id,\n event_index,\n event_type,\n step_id,\n event,\n created_at\n )\n values (\n ${args.runId},\n ${nextIndex},\n ${event.type},\n ${getStepId(event) ?? null},\n ${encodeJson(event)}::jsonb,\n ${event.ts}\n )\n `)\n nextIndex++\n }\n\n return { nextIndex }\n })\n },\n\n readEvents(args: ReadEventsArgs) {\n return readStoredEvents(db, tableSql, args)\n },\n\n async claimRun(args: ClaimRunArgs): Promise<ClaimRunResult> {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n update ${tableSql.runs}\n set\n status = 'running',\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs},\n updated_at = ${args.now}\n where run_id = ${args.runId}\n and status not in ('finished', 'errored', 'aborted')\n and (\n lease_owner is null\n or lease_owner = ${args.leaseOwner}\n or lease_expires_at <= ${args.now}\n )\n returning *\n `,\n )\n if (rows[0]) return { kind: 'claimed', run: runFromRow(rows[0]) }\n\n const run = await loadRunById(db, tableSql, args.runId)\n return run ? { kind: 'not-claimable', run } : { kind: 'not-found' }\n },\n\n async heartbeatRunLease(args: HeartbeatRunLeaseArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n lease_expires_at = ${args.now + args.leaseMs},\n updated_at = ${args.now}\n where run_id = ${args.runId}\n and lease_owner = ${args.leaseOwner}\n `)\n },\n\n async releaseRunLease(args: ReleaseRunLeaseArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n lease_owner = null,\n lease_expires_at = null\n where run_id = ${args.runId}\n and lease_owner = ${args.leaseOwner}\n `)\n },\n\n async markRunPaused(args: MarkRunPausedArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n status = 'paused',\n waiting_for = ${encodeJsonOrNull(args.waitingFor)}::jsonb,\n pending_approval = ${encodeJsonOrNull(args.pendingApproval)}::jsonb,\n wake_at = ${args.wakeAt ?? null},\n lease_owner = null,\n lease_expires_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n },\n\n async markRunFinished(args: MarkRunFinishedArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n status = 'finished',\n output = ${encodeJson(args.output)}::jsonb,\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n lease_owner = null,\n lease_expires_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n },\n\n async markRunErrored(args: MarkRunErroredArgs) {\n void args.code\n await db.execute(sql`\n update ${tableSql.runs}\n set\n status = 'errored',\n error = ${encodeJson(args.error)}::jsonb,\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n lease_owner = null,\n lease_expires_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n },\n\n async scheduleTimer(args: ScheduleTimerArgs) {\n await withTransaction(db, async (tx) => {\n await tx.execute(sql`\n insert into ${tableSql.timers} (\n run_id,\n signal_id,\n workflow_id,\n workflow_version,\n wake_at\n )\n values (\n ${args.runId},\n ${args.signalId},\n ${args.workflowId},\n ${args.workflowVersion ?? null},\n ${args.wakeAt}\n )\n on conflict (run_id, signal_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n wake_at = excluded.wake_at,\n lease_owner = null,\n lease_expires_at = null\n `)\n await tx.execute(sql`\n update ${tableSql.runs}\n set\n wake_at = ${args.wakeAt},\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n })\n },\n\n async claimDueTimers(args: ClaimDueTimersArgs) {\n const rows = await queryRows<TimerRow>(\n db,\n sql`\n with due as (\n select run_id, signal_id\n from ${tableSql.timers}\n where wake_at <= ${args.now}\n and (\n lease_owner is null\n or lease_owner = ${args.leaseOwner}\n or lease_expires_at <= ${args.now}\n )\n order by wake_at asc, run_id asc, signal_id asc\n limit ${args.limit}\n for update skip locked\n )\n update ${tableSql.timers} timer\n set\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs}\n from due\n where timer.run_id = due.run_id\n and timer.signal_id = due.signal_id\n returning timer.*\n `,\n )\n return rows.map(timerFromRow)\n },\n\n async deliverSignal<TPayload>(\n args: DeliverSignalArgs<TPayload>,\n ): Promise<DeliverSignalResult> {\n return withTransaction(db, async (tx) => {\n const run = await loadRunById(tx, tableSql, args.runId)\n if (!run) return { kind: 'not-found' }\n\n const existingDelivery = await loadSignalDelivery(\n tx,\n tableSql,\n args.runId,\n args.delivery.signalId,\n )\n if (existingDelivery) return { kind: 'duplicate', run }\n\n if (run.waitingFor?.signalName !== args.delivery.name) {\n return { kind: 'not-waiting', run }\n }\n\n const inserted = await insertSignalDelivery(\n tx,\n tableSql,\n args.runId,\n args.delivery.signalId,\n args.now,\n )\n if (!inserted) return { kind: 'duplicate', run }\n\n await tx.execute(sql`\n delete from ${tableSql.timers}\n where run_id = ${args.runId}\n and signal_id = ${args.delivery.signalId}\n `)\n\n const rows = await queryRows<RunRow>(\n tx,\n sql`\n update ${tableSql.runs}\n set\n status = 'queued',\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n returning *\n `,\n )\n\n return { kind: 'delivered', run: runFromRow(rows[0]!) }\n })\n },\n\n async deliverApproval(\n args: DeliverApprovalArgs,\n ): Promise<DeliverApprovalResult> {\n return withTransaction(db, async (tx) => {\n const run = await loadRunById(tx, tableSql, args.runId)\n if (!run) return { kind: 'not-found' }\n\n const signalId = `approval:${args.approval.approvalId}`\n const existingDelivery = await loadSignalDelivery(\n tx,\n tableSql,\n args.runId,\n signalId,\n )\n if (existingDelivery) return { kind: 'duplicate', run }\n\n if (run.pendingApproval?.approvalId !== args.approval.approvalId) {\n return { kind: 'not-waiting', run }\n }\n\n const inserted = await insertSignalDelivery(\n tx,\n tableSql,\n args.runId,\n signalId,\n args.now,\n )\n if (!inserted) return { kind: 'duplicate', run }\n\n const rows = await queryRows<RunRow>(\n tx,\n sql`\n update ${tableSql.runs}\n set\n status = 'queued',\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n returning *\n `,\n )\n\n return { kind: 'delivered', run: runFromRow(rows[0]!) }\n })\n },\n\n async upsertSchedule(args: UpsertScheduleArgs) {\n await db.execute(sql`\n insert into ${tableSql.schedules} (\n schedule_id,\n workflow_id,\n workflow_version,\n schedule,\n overlap_policy,\n input,\n next_fire_at,\n enabled,\n updated_at\n )\n values (\n ${args.scheduleId},\n ${args.workflowId},\n ${args.workflowVersion ?? null},\n ${encodeJson(args.schedule)}::jsonb,\n ${args.overlapPolicy},\n ${encodeJsonOrNull(args.input)}::jsonb,\n ${args.nextFireAt ?? null},\n ${args.enabled},\n ${args.now}\n )\n on conflict (schedule_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n schedule = excluded.schedule,\n overlap_policy = excluded.overlap_policy,\n input = excluded.input,\n next_fire_at = excluded.next_fire_at,\n enabled = excluded.enabled,\n updated_at = excluded.updated_at\n `)\n },\n\n async claimDueScheduleBuckets(args: ClaimDueScheduleBucketsArgs) {\n const schedules = await queryRows<ScheduleRow>(\n db,\n sql`\n select *\n from ${tableSql.schedules}\n where enabled = true\n and next_fire_at is not null\n and next_fire_at <= ${args.now}\n order by next_fire_at asc, schedule_id asc\n limit ${args.limit}\n `,\n )\n const buckets: Array<ScheduleBucket> = []\n\n for (const scheduleRow of schedules) {\n if (buckets.length >= args.limit) break\n\n const schedule = scheduleFromRow(scheduleRow)\n const bucketId = `${schedule.nextFireAt}` satisfies ScheduleBucketId\n const runId = `${schedule.workflowId}:${schedule.scheduleId}:${bucketId}`\n\n await db.execute(sql`\n insert into ${tableSql.scheduleBuckets} (\n schedule_id,\n bucket_id,\n workflow_id,\n workflow_version,\n run_id,\n fire_at,\n input,\n overlap_policy,\n status\n )\n values (\n ${schedule.scheduleId},\n ${bucketId},\n ${schedule.workflowId},\n ${schedule.workflowVersion ?? null},\n ${runId},\n ${schedule.nextFireAt},\n ${encodeJsonOrNull(schedule.input)}::jsonb,\n ${schedule.overlapPolicy},\n 'claimed'\n )\n on conflict (schedule_id, bucket_id) do nothing\n `)\n\n const rows = await queryRows<ScheduleBucketRow>(\n db,\n sql`\n update ${tableSql.scheduleBuckets}\n set\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs}\n where schedule_id = ${schedule.scheduleId}\n and bucket_id = ${bucketId}\n and status <> 'started'\n and (\n lease_owner is null\n or lease_owner = ${args.leaseOwner}\n or lease_expires_at <= ${args.now}\n )\n returning *\n `,\n )\n if (rows[0]) buckets.push(scheduleBucketFromRow(rows[0]))\n }\n\n return buckets\n },\n\n async markScheduleBucketStarted(args: MarkScheduleBucketStartedArgs) {\n await db.execute(sql`\n update ${tableSql.scheduleBuckets}\n set\n run_id = ${args.runId},\n status = 'started',\n started_at = ${args.now}\n where schedule_id = ${args.scheduleId}\n and bucket_id = ${args.bucketId}\n `)\n },\n\n async claimStaleRuns(args: ClaimStaleRunsArgs) {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n with stale as (\n select run_id\n from ${tableSql.runs}\n where status = 'running'\n and lease_expires_at is not null\n and lease_expires_at <= ${args.now}\n order by updated_at asc, run_id asc\n limit ${args.limit}\n for update skip locked\n )\n update ${tableSql.runs} run\n set\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs},\n updated_at = ${args.now}\n from stale\n where run.run_id = stale.run_id\n returning run.*\n `,\n )\n\n return rows.map((row): RunClaim => {\n const run = runFromRow(row)\n return { run, lease: run.lease! }\n })\n },\n\n async listRuns(args: ListRunsArgs) {\n const offset = args.cursor ? Number(args.cursor) : 0\n const start = Number.isFinite(offset) && offset > 0 ? offset : 0\n const rows = await queryRows<RunRow>(\n db,\n sql`\n select *\n from ${tableSql.runs}\n where (${args.workflowId ?? null}::text is null or workflow_id = ${args.workflowId ?? null})\n and (${args.status ?? null}::text is null or status = ${args.status ?? null})\n order by updated_at desc, run_id asc\n limit ${args.limit}\n offset ${start}\n `,\n )\n\n return rows.map(toRunSummary)\n },\n\n async getRunTimeline(runId: RunId): Promise<RunTimeline | undefined> {\n const run = await loadRunById(db, tableSql, runId)\n if (!run) return undefined\n return {\n run,\n events: await readStoredEvents(db, tableSql, { runId }),\n }\n },\n }\n}\n\ninterface TableSqls {\n runs: SQL\n runStates: SQL\n eventLocks: SQL\n events: SQL\n timers: SQL\n signalDeliveries: SQL\n schedules: SQL\n scheduleBuckets: SQL\n}\n\ninterface RunRow {\n run_id: string\n workflow_id: string\n workflow_version: string | null\n status: WorkflowExecutionStatus\n input: unknown\n output: unknown\n error: unknown\n waiting_for: unknown\n pending_approval: unknown\n wake_at: number | string | null\n lease_owner: string | null\n lease_expires_at: number | string | null\n created_at: number | string\n updated_at: number | string\n}\n\ninterface RunStateRow {\n run_id: string\n workflow_id: string\n workflow_version: string | null\n status: RunState['status']\n input: unknown\n output: unknown\n error: unknown\n waiting_for: unknown\n pending_approval: unknown\n created_at: number | string\n updated_at: number | string\n}\n\ninterface EventRow {\n run_id: string\n event_index: number | string\n event_type: WorkflowEvent['type']\n step_id: string | null\n event: unknown\n created_at: number | string\n}\n\ninterface TimerRow {\n run_id: string\n workflow_id: string\n workflow_version: string | null\n wake_at: number | string\n signal_id: string\n}\n\ninterface ScheduleRow {\n schedule_id: string\n workflow_id: string\n workflow_version: string | null\n input: unknown\n overlap_policy: ScheduleBucket['overlapPolicy']\n next_fire_at: number | string\n}\n\ninterface ScheduleBucketRow {\n schedule_id: string\n bucket_id: string\n workflow_id: string\n workflow_version: string | null\n run_id: string\n fire_at: number | string\n input: unknown\n overlap_policy: ScheduleBucket['overlapPolicy']\n}\n\nfunction tableSqls(\n schema: string | undefined,\n tables: DrizzlePostgresWorkflowStoreTables,\n): TableSqls {\n return {\n runs: sql.raw(qualifiedTableName(schema, tables.runs)),\n runStates: sql.raw(qualifiedTableName(schema, tables.runStates)),\n eventLocks: sql.raw(qualifiedTableName(schema, tables.eventLocks)),\n events: sql.raw(qualifiedTableName(schema, tables.events)),\n timers: sql.raw(qualifiedTableName(schema, tables.timers)),\n signalDeliveries: sql.raw(\n qualifiedTableName(schema, tables.signalDeliveries),\n ),\n schedules: sql.raw(qualifiedTableName(schema, tables.schedules)),\n scheduleBuckets: sql.raw(\n qualifiedTableName(schema, tables.scheduleBuckets),\n ),\n }\n}\n\nfunction schemaStatements(\n schema: string | undefined,\n tables: DrizzlePostgresWorkflowStoreTables,\n): Array<string> {\n const runs = qualifiedTableName(schema, tables.runs)\n const runStates = qualifiedTableName(schema, tables.runStates)\n const eventLocks = qualifiedTableName(schema, tables.eventLocks)\n const events = qualifiedTableName(schema, tables.events)\n const timers = qualifiedTableName(schema, tables.timers)\n const signalDeliveries = qualifiedTableName(schema, tables.signalDeliveries)\n const schedules = qualifiedTableName(schema, tables.schedules)\n const scheduleBuckets = qualifiedTableName(schema, tables.scheduleBuckets)\n\n return [\n ...(schema ? [`create schema if not exists ${quoteIdent(schema)}`] : []),\n `create table if not exists ${runs} (\n run_id text primary key,\n workflow_id text not null,\n workflow_version text,\n status text not null,\n input jsonb not null,\n output jsonb,\n error jsonb,\n waiting_for jsonb,\n pending_approval jsonb,\n wake_at bigint,\n lease_owner text,\n lease_expires_at bigint,\n created_at bigint not null,\n updated_at bigint not null\n )`,\n `create index if not exists ${quoteIdent(`${tables.runs}_status_idx`)}\n on ${runs} (status, updated_at)`,\n `create index if not exists ${quoteIdent(`${tables.runs}_lease_idx`)}\n on ${runs} (status, lease_expires_at)`,\n `create table if not exists ${runStates} (\n run_id text primary key,\n workflow_id text not null,\n workflow_version text,\n status text not null,\n input jsonb not null,\n output jsonb,\n error jsonb,\n waiting_for jsonb,\n pending_approval jsonb,\n created_at bigint not null,\n updated_at bigint not null\n )`,\n `create table if not exists ${eventLocks} (\n run_id text primary key,\n created_at bigint not null\n )`,\n `create table if not exists ${events} (\n run_id text not null,\n event_index integer not null,\n event_type text not null,\n step_id text,\n event jsonb not null,\n created_at bigint not null,\n primary key (run_id, event_index)\n )`,\n `create index if not exists ${quoteIdent(`${tables.events}_type_idx`)}\n on ${events} (run_id, event_type)`,\n `create table if not exists ${timers} (\n run_id text not null,\n signal_id text not null,\n workflow_id text not null,\n workflow_version text,\n wake_at bigint not null,\n lease_owner text,\n lease_expires_at bigint,\n primary key (run_id, signal_id)\n )`,\n `create index if not exists ${quoteIdent(`${tables.timers}_due_idx`)}\n on ${timers} (wake_at, lease_expires_at)`,\n `create table if not exists ${signalDeliveries} (\n run_id text not null,\n signal_id text not null,\n created_at bigint not null,\n primary key (run_id, signal_id)\n )`,\n `create table if not exists ${schedules} (\n schedule_id text primary key,\n workflow_id text not null,\n workflow_version text,\n schedule jsonb not null,\n overlap_policy text not null,\n input jsonb,\n next_fire_at bigint,\n enabled boolean not null,\n updated_at bigint not null\n )`,\n `create index if not exists ${quoteIdent(`${tables.schedules}_due_idx`)}\n on ${schedules} (enabled, next_fire_at)`,\n `create table if not exists ${scheduleBuckets} (\n schedule_id text not null,\n bucket_id text not null,\n workflow_id text not null,\n workflow_version text,\n run_id text not null,\n fire_at bigint not null,\n input jsonb,\n overlap_policy text not null,\n status text not null,\n lease_owner text,\n lease_expires_at bigint,\n started_at bigint,\n primary key (schedule_id, bucket_id)\n )`,\n `create index if not exists ${quoteIdent(\n `${tables.scheduleBuckets}_lease_idx`,\n )}\n on ${scheduleBuckets} (status, fire_at, lease_expires_at)`,\n ]\n}\n\nasync function loadRunById(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n) {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n select *\n from ${tables.runs}\n where run_id = ${runId}\n limit 1\n `,\n )\n return rows[0] ? runFromRow(rows[0]) : undefined\n}\n\nasync function loadRunStateById(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n): Promise<RunState | undefined> {\n const rows = await queryRows<RunStateRow>(\n db,\n sql`\n select *\n from ${tables.runStates}\n where run_id = ${runId}\n limit 1\n `,\n )\n return rows[0] ? runStateFromRow(rows[0]) : undefined\n}\n\nasync function readStoredEvents(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n args: ReadEventsArgs,\n): Promise<ReadonlyArray<StoredWorkflowEvent>> {\n const rows = await queryRows<EventRow>(\n db,\n sql`\n select *\n from ${tables.events}\n where run_id = ${args.runId}\n and event_index >= ${args.fromIndex ?? 0}\n order by event_index asc\n `,\n )\n return rows.map(eventFromRow)\n}\n\nasync function loadSignalDelivery(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n signalId: string,\n) {\n const rows = await queryRows<{ run_id: string }>(\n db,\n sql`\n select run_id\n from ${tables.signalDeliveries}\n where run_id = ${runId}\n and signal_id = ${signalId}\n limit 1\n `,\n )\n return Boolean(rows[0])\n}\n\nasync function insertSignalDelivery(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n signalId: string,\n now: number,\n) {\n const rows = await queryRows<{ run_id: string }>(\n db,\n sql`\n insert into ${tables.signalDeliveries} (run_id, signal_id, created_at)\n values (${runId}, ${signalId}, ${now})\n on conflict (run_id, signal_id) do nothing\n returning run_id\n `,\n )\n return Boolean(rows[0])\n}\n\nasync function withTransaction<TResult>(\n db: DrizzlePostgresDatabase,\n callback: (tx: DrizzlePostgresDatabase) => Promise<TResult>,\n) {\n if (db.transaction) return db.transaction(callback)\n\n await db.execute(sql.raw('begin'))\n try {\n const result = await callback(db)\n await db.execute(sql.raw('commit'))\n return result\n } catch (error) {\n await db.execute(sql.raw('rollback'))\n throw error\n }\n}\n\nasync function queryRows<TRow>(\n db: DrizzlePostgresDatabase,\n query: SQL,\n): Promise<Array<TRow>> {\n const result = await db.execute(query)\n return rowsFromResult<TRow>(result)\n}\n\nfunction rowsFromResult<TRow>(result: unknown): Array<TRow> {\n if (Array.isArray(result)) return result as Array<TRow>\n\n if (isObjectWithRows(result) && Array.isArray(result.rows)) {\n return result.rows as Array<TRow>\n }\n\n return []\n}\n\nfunction isObjectWithRows(value: unknown): value is { rows: unknown } {\n return typeof value === 'object' && value !== null && 'rows' in value\n}\n\nfunction runFromRow(row: RunRow): WorkflowExecution {\n return {\n runId: row.run_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n status: row.status,\n input: decodeJson(row.input),\n output: decodeJsonOrUndefined(row.output),\n error: decodeJsonOrUndefined(row.error),\n waitingFor: decodeJsonOrUndefined(row.waiting_for),\n pendingApproval: decodeJsonOrUndefined(row.pending_approval),\n wakeAt: numberOrUndefined(row.wake_at),\n lease:\n row.lease_owner && row.lease_expires_at !== null\n ? {\n owner: row.lease_owner,\n expiresAt: Number(row.lease_expires_at),\n }\n : undefined,\n createdAt: Number(row.created_at),\n updatedAt: Number(row.updated_at),\n }\n}\n\nfunction runStateFromRow(row: RunStateRow): RunState {\n return {\n runId: row.run_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n status: row.status,\n input: decodeJson(row.input),\n output: decodeJsonOrUndefined(row.output),\n error: decodeJsonOrUndefined(row.error),\n waitingFor: decodeJsonOrUndefined(row.waiting_for),\n pendingApproval: decodeJsonOrUndefined(row.pending_approval),\n createdAt: Number(row.created_at),\n updatedAt: Number(row.updated_at),\n }\n}\n\nfunction eventFromRow(row: EventRow): StoredWorkflowEvent {\n return {\n runId: row.run_id,\n eventIndex: Number(row.event_index),\n eventType: row.event_type,\n stepId: row.step_id ?? undefined,\n event: decodeJson(row.event) as WorkflowEvent,\n createdAt: Number(row.created_at),\n }\n}\n\nfunction timerFromRow(row: TimerRow): TimerWakeup {\n return {\n runId: row.run_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n wakeAt: Number(row.wake_at),\n signalId: row.signal_id,\n }\n}\n\nfunction scheduleFromRow(row: ScheduleRow) {\n return {\n scheduleId: row.schedule_id satisfies ScheduleId,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n input: decodeJsonOrUndefined(row.input),\n overlapPolicy: row.overlap_policy,\n nextFireAt: Number(row.next_fire_at),\n }\n}\n\nfunction scheduleBucketFromRow(row: ScheduleBucketRow): ScheduleBucket {\n return {\n scheduleId: row.schedule_id,\n bucketId: row.bucket_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n runId: row.run_id,\n fireAt: Number(row.fire_at),\n input: decodeJsonOrUndefined(row.input),\n overlapPolicy: row.overlap_policy,\n }\n}\n\nfunction toRunSummary(row: RunRow): RunSummary {\n const run = runFromRow(row)\n return {\n runId: run.runId,\n workflowId: run.workflowId,\n workflowVersion: run.workflowVersion,\n status: run.status,\n waitingFor: run.waitingFor,\n pendingApproval: run.pendingApproval,\n wakeAt: run.wakeAt,\n createdAt: run.createdAt,\n updatedAt: run.updatedAt,\n }\n}\n\nfunction encodeJson(value: unknown) {\n return JSON.stringify(value ?? null)\n}\n\nfunction encodeJsonOrNull(value: unknown) {\n return value === undefined ? null : JSON.stringify(value)\n}\n\nfunction decodeJson(value: unknown): unknown {\n if (typeof value !== 'string') return value\n try {\n return JSON.parse(value)\n } catch {\n return value\n }\n}\n\nfunction decodeJsonOrUndefined<TValue = unknown>(\n value: unknown,\n): TValue | undefined {\n if (value === null || value === undefined) return undefined\n return decodeJson(value) as TValue\n}\n\nfunction numberOrUndefined(value: number | string | null) {\n return value === null ? undefined : Number(value)\n}\n\nfunction getStepId(event: WorkflowEvent) {\n return 'stepId' in event ? event.stepId : undefined\n}\n\nfunction qualifiedTableName(schema: string | undefined, table: string) {\n return schema\n ? `${quoteIdent(schema)}.${quoteIdent(table)}`\n : quoteIdent(table)\n}\n\nfunction quoteIdent(identifier: string) {\n return `\"${identifier.replaceAll('\"', '\"\"')}\"`\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"store.cjs","names":["sql","LogConflictError"],"sources":["../src/store.ts"],"sourcesContent":["import { LogConflictError } from '@tanstack/workflow-core'\nimport { sql } from 'drizzle-orm'\nimport type { RunState, WorkflowEvent } from '@tanstack/workflow-core'\nimport type { SQL } from 'drizzle-orm'\nimport type {\n AppendEventsArgs,\n AppendEventsResult,\n ClaimDueScheduleBucketsArgs,\n ClaimDueTimersArgs,\n ClaimRunArgs,\n ClaimRunResult,\n ClaimStaleRunsArgs,\n CreateRunArgs,\n CreateRunResult,\n DeliverApprovalArgs,\n DeliverApprovalResult,\n DeliverSignalArgs,\n DeliverSignalResult,\n HeartbeatRunLeaseArgs,\n ListRunsArgs,\n LoadedExecution,\n MarkRunErroredArgs,\n MarkRunFinishedArgs,\n MarkRunPausedArgs,\n MarkScheduleBucketStartedArgs,\n ReadEventsArgs,\n ReleaseRunLeaseArgs,\n RunClaim,\n RunId,\n RunSummary,\n RunTimeline,\n SaveRunStateArgs,\n ScheduleBucket,\n ScheduleBucketId,\n ScheduleId,\n ScheduleTimerArgs,\n StoredWorkflowEvent,\n TimerWakeup,\n UpsertScheduleArgs,\n WorkflowExecution,\n WorkflowExecutionStatus,\n WorkflowExecutionStore,\n WorkflowRunStoreAdapterStore,\n} from '@tanstack/workflow-runtime'\n\nexport interface DrizzlePostgresDatabase {\n execute: (query: SQL | string) => PromiseLike<unknown>\n transaction?: <TResult>(\n callback: (tx: DrizzlePostgresDatabase) => Promise<TResult>,\n ) => Promise<TResult>\n}\n\nexport interface DrizzlePostgresWorkflowStoreTables {\n runs: string\n runStates: string\n eventLocks: string\n events: string\n timers: string\n signalDeliveries: string\n schedules: string\n scheduleBuckets: string\n}\n\nexport interface DrizzlePostgresWorkflowStoreOptions {\n db: DrizzlePostgresDatabase\n schema?: string\n tables?: Partial<DrizzlePostgresWorkflowStoreTables>\n}\n\nexport type DrizzlePostgresWorkflowStore = WorkflowExecutionStore &\n WorkflowRunStoreAdapterStore & {\n ensureSchema: () => Promise<void>\n }\n\nexport const defaultDrizzlePostgresWorkflowStoreTables: DrizzlePostgresWorkflowStoreTables =\n {\n runs: 'workflow_runs',\n runStates: 'workflow_run_states',\n eventLocks: 'workflow_event_locks',\n events: 'workflow_events',\n timers: 'workflow_timers',\n signalDeliveries: 'workflow_signal_deliveries',\n schedules: 'workflow_schedules',\n scheduleBuckets: 'workflow_schedule_buckets',\n }\n\nexport function createDrizzlePostgresWorkflowStore(\n options: DrizzlePostgresWorkflowStoreOptions,\n): DrizzlePostgresWorkflowStore {\n const tableNames = {\n ...defaultDrizzlePostgresWorkflowStoreTables,\n ...options.tables,\n }\n const tableSql = tableSqls(options.schema, tableNames)\n const db = options.db\n\n return {\n async ensureSchema() {\n for (const statement of schemaStatements(options.schema, tableNames)) {\n await db.execute(sql.raw(statement))\n }\n },\n\n async createRun(args: CreateRunArgs): Promise<CreateRunResult> {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n insert into ${tableSql.runs} (\n run_id,\n workflow_id,\n workflow_version,\n status,\n input,\n created_at,\n updated_at\n )\n values (\n ${args.runId},\n ${args.workflowId},\n ${args.workflowVersion ?? null},\n 'queued',\n ${encodeJson(args.input)}::jsonb,\n ${args.now},\n ${args.now}\n )\n on conflict (run_id) do nothing\n returning *\n `,\n )\n if (rows[0]) return { kind: 'created', run: runFromRow(rows[0]) }\n\n const existing = await loadRunById(db, tableSql, args.runId)\n if (!existing) {\n throw new Error(`Run \"${args.runId}\" was not inserted or loaded.`)\n }\n return { kind: 'existing', run: existing }\n },\n\n loadRun(runId: RunId) {\n return loadRunById(db, tableSql, runId)\n },\n\n async loadExecution(runId: RunId): Promise<LoadedExecution | undefined> {\n const run = await loadRunById(db, tableSql, runId)\n if (!run) return undefined\n return {\n run,\n events: await readStoredEvents(db, tableSql, { runId }),\n }\n },\n\n async loadRunState(runId: RunId) {\n return loadRunStateById(db, tableSql, runId)\n },\n\n async saveRunState(args: SaveRunStateArgs) {\n const state = args.state\n await withTransaction(db, async (tx) => {\n await tx.execute(sql`\n insert into ${tableSql.runStates} (\n run_id,\n workflow_id,\n workflow_version,\n status,\n input,\n output,\n error,\n waiting_for,\n pending_approval,\n created_at,\n updated_at\n )\n values (\n ${state.runId},\n ${state.workflowId},\n ${state.workflowVersion ?? null},\n ${state.status},\n ${encodeJson(state.input)}::jsonb,\n ${encodeJsonOrNull(state.output)}::jsonb,\n ${encodeJsonOrNull(state.error)}::jsonb,\n ${encodeJsonOrNull(state.waitingFor)}::jsonb,\n ${encodeJsonOrNull(state.pendingApproval)}::jsonb,\n ${state.createdAt},\n ${state.updatedAt}\n )\n on conflict (run_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n status = excluded.status,\n input = excluded.input,\n output = excluded.output,\n error = excluded.error,\n waiting_for = excluded.waiting_for,\n pending_approval = excluded.pending_approval,\n created_at = excluded.created_at,\n updated_at = excluded.updated_at\n `)\n await tx.execute(sql`\n insert into ${tableSql.runs} (\n run_id,\n workflow_id,\n workflow_version,\n status,\n input,\n output,\n error,\n waiting_for,\n pending_approval,\n wake_at,\n created_at,\n updated_at\n )\n values (\n ${state.runId},\n ${state.workflowId},\n ${state.workflowVersion ?? null},\n ${state.status},\n ${encodeJson(state.input)}::jsonb,\n ${encodeJsonOrNull(state.output)}::jsonb,\n ${encodeJsonOrNull(state.error)}::jsonb,\n ${encodeJsonOrNull(state.waitingFor)}::jsonb,\n ${encodeJsonOrNull(state.pendingApproval)}::jsonb,\n ${\n state.waitingFor?.signalName === '__timer'\n ? state.waitingFor.deadline\n : null\n },\n ${state.createdAt},\n ${state.updatedAt}\n )\n on conflict (run_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n status = excluded.status,\n input = excluded.input,\n output = excluded.output,\n error = excluded.error,\n waiting_for = excluded.waiting_for,\n pending_approval = excluded.pending_approval,\n wake_at = excluded.wake_at,\n created_at = excluded.created_at,\n updated_at = excluded.updated_at\n `)\n })\n },\n\n async deleteRun(runId, _reason) {\n await withTransaction(db, async (tx) => {\n await tx.execute(sql`\n delete from ${tableSql.runStates}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.eventLocks}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.signalDeliveries}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.timers}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.events}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.runs}\n where run_id = ${runId}\n `)\n })\n },\n\n async appendEvents(args: AppendEventsArgs): Promise<AppendEventsResult> {\n return withTransaction(db, async (tx) => {\n await tx.execute(sql`\n insert into ${tableSql.eventLocks} (run_id, created_at)\n values (${args.runId}, ${Date.now()})\n on conflict (run_id) do nothing\n `)\n await queryRows<{ run_id: string }>(\n tx,\n sql`\n select run_id\n from ${tableSql.eventLocks}\n where run_id = ${args.runId}\n for update\n `,\n )\n\n const countRows = await queryRows<{ count: number | string }>(\n tx,\n sql`\n select count(*)::int as count\n from ${tableSql.events}\n where run_id = ${args.runId}\n `,\n )\n const currentCount = Number(countRows[0]?.count ?? 0)\n\n if (currentCount !== args.expectedNextIndex) {\n const conflict = await queryRows<EventRow>(\n tx,\n sql`\n select *\n from ${tableSql.events}\n where run_id = ${args.runId}\n and event_index = ${args.expectedNextIndex}\n limit 1\n `,\n )\n throw new LogConflictError(\n args.runId,\n args.expectedNextIndex,\n conflict[0] ? eventFromRow(conflict[0]).event : undefined,\n )\n }\n\n let nextIndex = args.expectedNextIndex\n for (const event of args.events) {\n await tx.execute(sql`\n insert into ${tableSql.events} (\n run_id,\n event_index,\n event_type,\n step_id,\n event,\n created_at\n )\n values (\n ${args.runId},\n ${nextIndex},\n ${event.type},\n ${getStepId(event) ?? null},\n ${encodeJson(event)}::jsonb,\n ${event.ts}\n )\n `)\n nextIndex++\n }\n\n return { nextIndex }\n })\n },\n\n readEvents(args: ReadEventsArgs) {\n return readStoredEvents(db, tableSql, args)\n },\n\n async claimRun(args: ClaimRunArgs): Promise<ClaimRunResult> {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n update ${tableSql.runs}\n set\n status = 'running',\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs},\n updated_at = ${args.now}\n where run_id = ${args.runId}\n and status not in ('finished', 'errored', 'aborted')\n and (\n lease_owner is null\n or lease_owner = ${args.leaseOwner}\n or lease_expires_at <= ${args.now}\n )\n returning *\n `,\n )\n if (rows[0]) return { kind: 'claimed', run: runFromRow(rows[0]) }\n\n const run = await loadRunById(db, tableSql, args.runId)\n return run ? { kind: 'not-claimable', run } : { kind: 'not-found' }\n },\n\n async heartbeatRunLease(args: HeartbeatRunLeaseArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n lease_expires_at = ${args.now + args.leaseMs},\n updated_at = ${args.now}\n where run_id = ${args.runId}\n and lease_owner = ${args.leaseOwner}\n `)\n },\n\n async releaseRunLease(args: ReleaseRunLeaseArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n lease_owner = null,\n lease_expires_at = null\n where run_id = ${args.runId}\n and lease_owner = ${args.leaseOwner}\n `)\n },\n\n async markRunPaused(args: MarkRunPausedArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n status = 'paused',\n waiting_for = ${encodeJsonOrNull(args.waitingFor)}::jsonb,\n pending_approval = ${encodeJsonOrNull(args.pendingApproval)}::jsonb,\n wake_at = ${args.wakeAt ?? null},\n lease_owner = null,\n lease_expires_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n },\n\n async markRunFinished(args: MarkRunFinishedArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n status = 'finished',\n output = ${encodeJson(args.output)}::jsonb,\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n lease_owner = null,\n lease_expires_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n },\n\n async markRunErrored(args: MarkRunErroredArgs) {\n void args.code\n await db.execute(sql`\n update ${tableSql.runs}\n set\n status = 'errored',\n error = ${encodeJson(args.error)}::jsonb,\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n lease_owner = null,\n lease_expires_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n },\n\n async scheduleTimer(args: ScheduleTimerArgs) {\n await withTransaction(db, async (tx) => {\n await tx.execute(sql`\n insert into ${tableSql.timers} (\n run_id,\n signal_id,\n workflow_id,\n workflow_version,\n wake_at\n )\n values (\n ${args.runId},\n ${args.signalId},\n ${args.workflowId},\n ${args.workflowVersion ?? null},\n ${args.wakeAt}\n )\n on conflict (run_id, signal_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n wake_at = excluded.wake_at,\n lease_owner = null,\n lease_expires_at = null\n `)\n await tx.execute(sql`\n update ${tableSql.runs}\n set\n wake_at = ${args.wakeAt},\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n })\n },\n\n async claimDueTimers(args: ClaimDueTimersArgs) {\n const rows = await queryRows<TimerRow>(\n db,\n sql`\n with due as (\n select run_id, signal_id\n from ${tableSql.timers}\n where wake_at <= ${args.now}\n and (\n lease_owner is null\n or lease_owner = ${args.leaseOwner}\n or lease_expires_at <= ${args.now}\n )\n order by wake_at asc, run_id asc, signal_id asc\n limit ${args.limit}\n for update skip locked\n )\n update ${tableSql.timers} timer\n set\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs}\n from due\n where timer.run_id = due.run_id\n and timer.signal_id = due.signal_id\n returning timer.*\n `,\n )\n return rows.map(timerFromRow)\n },\n\n async deliverSignal<TPayload>(\n args: DeliverSignalArgs<TPayload>,\n ): Promise<DeliverSignalResult> {\n return withTransaction(db, async (tx) => {\n const run = await loadRunById(tx, tableSql, args.runId)\n if (!run) return { kind: 'not-found' }\n\n const existingDelivery = await loadSignalDelivery(\n tx,\n tableSql,\n args.runId,\n args.delivery.signalId,\n )\n if (existingDelivery) return { kind: 'duplicate', run }\n\n if (run.waitingFor?.signalName !== args.delivery.name) {\n return { kind: 'not-waiting', run }\n }\n\n const inserted = await insertSignalDelivery(\n tx,\n tableSql,\n args.runId,\n args.delivery.signalId,\n args.now,\n )\n if (!inserted) return { kind: 'duplicate', run }\n\n await tx.execute(sql`\n delete from ${tableSql.timers}\n where run_id = ${args.runId}\n and signal_id = ${args.delivery.signalId}\n `)\n\n const rows = await queryRows<RunRow>(\n tx,\n sql`\n update ${tableSql.runs}\n set\n status = 'queued',\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n returning *\n `,\n )\n\n return { kind: 'delivered', run: runFromRow(rows[0]!) }\n })\n },\n\n async deliverApproval(\n args: DeliverApprovalArgs,\n ): Promise<DeliverApprovalResult> {\n return withTransaction(db, async (tx) => {\n const run = await loadRunById(tx, tableSql, args.runId)\n if (!run) return { kind: 'not-found' }\n\n const signalId = `approval:${args.approval.approvalId}`\n const existingDelivery = await loadSignalDelivery(\n tx,\n tableSql,\n args.runId,\n signalId,\n )\n if (existingDelivery) return { kind: 'duplicate', run }\n\n if (run.pendingApproval?.approvalId !== args.approval.approvalId) {\n return { kind: 'not-waiting', run }\n }\n\n const inserted = await insertSignalDelivery(\n tx,\n tableSql,\n args.runId,\n signalId,\n args.now,\n )\n if (!inserted) return { kind: 'duplicate', run }\n\n const rows = await queryRows<RunRow>(\n tx,\n sql`\n update ${tableSql.runs}\n set\n status = 'queued',\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n returning *\n `,\n )\n\n return { kind: 'delivered', run: runFromRow(rows[0]!) }\n })\n },\n\n async upsertSchedule(args: UpsertScheduleArgs) {\n await db.execute(sql`\n insert into ${tableSql.schedules} (\n schedule_id,\n workflow_id,\n workflow_version,\n schedule,\n overlap_policy,\n input,\n next_fire_at,\n enabled,\n updated_at\n )\n values (\n ${args.scheduleId},\n ${args.workflowId},\n ${args.workflowVersion ?? null},\n ${encodeJson(args.schedule)}::jsonb,\n ${args.overlapPolicy},\n ${encodeJsonOrNull(args.input)}::jsonb,\n ${args.nextFireAt ?? null},\n ${args.enabled},\n ${args.now}\n )\n on conflict (schedule_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n schedule = excluded.schedule,\n overlap_policy = excluded.overlap_policy,\n input = excluded.input,\n next_fire_at = excluded.next_fire_at,\n enabled = excluded.enabled,\n updated_at = excluded.updated_at\n `)\n },\n\n async claimDueScheduleBuckets(args: ClaimDueScheduleBucketsArgs) {\n const schedules = await queryRows<ScheduleRow>(\n db,\n sql`\n select schedule.*\n from ${tableSql.schedules} schedule\n left join ${tableSql.scheduleBuckets} bucket\n on bucket.schedule_id = schedule.schedule_id\n and bucket.bucket_id = schedule.next_fire_at::text\n where schedule.enabled = true\n and schedule.next_fire_at is not null\n and schedule.next_fire_at <= ${args.now}\n and (\n bucket.schedule_id is null\n or (\n bucket.status <> 'started'\n and (\n bucket.lease_owner is null\n or bucket.lease_owner = ${args.leaseOwner}\n or bucket.lease_expires_at <= ${args.now}\n )\n )\n )\n order by schedule.next_fire_at asc, schedule.schedule_id asc\n limit ${args.limit}\n `,\n )\n const buckets: Array<ScheduleBucket> = []\n\n for (const scheduleRow of schedules) {\n if (buckets.length >= args.limit) break\n\n const schedule = scheduleFromRow(scheduleRow)\n const bucketId = `${schedule.nextFireAt}` satisfies ScheduleBucketId\n const runId = `${schedule.workflowId}:${schedule.scheduleId}:${bucketId}`\n\n await db.execute(sql`\n insert into ${tableSql.scheduleBuckets} (\n schedule_id,\n bucket_id,\n workflow_id,\n workflow_version,\n run_id,\n fire_at,\n input,\n overlap_policy,\n status\n )\n values (\n ${schedule.scheduleId},\n ${bucketId},\n ${schedule.workflowId},\n ${schedule.workflowVersion ?? null},\n ${runId},\n ${schedule.nextFireAt},\n ${encodeJsonOrNull(schedule.input)}::jsonb,\n ${schedule.overlapPolicy},\n 'claimed'\n )\n on conflict (schedule_id, bucket_id) do nothing\n `)\n\n const rows = await queryRows<ScheduleBucketRow>(\n db,\n sql`\n update ${tableSql.scheduleBuckets}\n set\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs}\n where schedule_id = ${schedule.scheduleId}\n and bucket_id = ${bucketId}\n and status <> 'started'\n and (\n lease_owner is null\n or lease_owner = ${args.leaseOwner}\n or lease_expires_at <= ${args.now}\n )\n returning *\n `,\n )\n if (rows[0]) buckets.push(scheduleBucketFromRow(rows[0]))\n }\n\n return buckets\n },\n\n async markScheduleBucketStarted(args: MarkScheduleBucketStartedArgs) {\n await db.execute(sql`\n update ${tableSql.scheduleBuckets}\n set\n run_id = ${args.runId},\n status = 'started',\n started_at = ${args.now}\n where schedule_id = ${args.scheduleId}\n and bucket_id = ${args.bucketId}\n `)\n },\n\n async claimStaleRuns(args: ClaimStaleRunsArgs) {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n with stale as (\n select run_id\n from ${tableSql.runs}\n where status = 'running'\n and lease_expires_at is not null\n and lease_expires_at <= ${args.now}\n order by updated_at asc, run_id asc\n limit ${args.limit}\n for update skip locked\n )\n update ${tableSql.runs} run\n set\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs},\n updated_at = ${args.now}\n from stale\n where run.run_id = stale.run_id\n returning run.*\n `,\n )\n\n return rows.map((row): RunClaim => {\n const run = runFromRow(row)\n return { run, lease: run.lease! }\n })\n },\n\n async listRuns(args: ListRunsArgs) {\n const offset = args.cursor ? Number(args.cursor) : 0\n const start = Number.isFinite(offset) && offset > 0 ? offset : 0\n const rows = await queryRows<RunRow>(\n db,\n sql`\n select *\n from ${tableSql.runs}\n where (${args.workflowId ?? null}::text is null or workflow_id = ${args.workflowId ?? null})\n and (${args.status ?? null}::text is null or status = ${args.status ?? null})\n order by updated_at desc, run_id asc\n limit ${args.limit}\n offset ${start}\n `,\n )\n\n return rows.map(toRunSummary)\n },\n\n async getRunTimeline(runId: RunId): Promise<RunTimeline | undefined> {\n const run = await loadRunById(db, tableSql, runId)\n if (!run) return undefined\n return {\n run,\n events: await readStoredEvents(db, tableSql, { runId }),\n }\n },\n }\n}\n\ninterface TableSqls {\n runs: SQL\n runStates: SQL\n eventLocks: SQL\n events: SQL\n timers: SQL\n signalDeliveries: SQL\n schedules: SQL\n scheduleBuckets: SQL\n}\n\ninterface RunRow {\n run_id: string\n workflow_id: string\n workflow_version: string | null\n status: WorkflowExecutionStatus\n input: unknown\n output: unknown\n error: unknown\n waiting_for: unknown\n pending_approval: unknown\n wake_at: number | string | null\n lease_owner: string | null\n lease_expires_at: number | string | null\n created_at: number | string\n updated_at: number | string\n}\n\ninterface RunStateRow {\n run_id: string\n workflow_id: string\n workflow_version: string | null\n status: RunState['status']\n input: unknown\n output: unknown\n error: unknown\n waiting_for: unknown\n pending_approval: unknown\n created_at: number | string\n updated_at: number | string\n}\n\ninterface EventRow {\n run_id: string\n event_index: number | string\n event_type: WorkflowEvent['type']\n step_id: string | null\n event: unknown\n created_at: number | string\n}\n\ninterface TimerRow {\n run_id: string\n workflow_id: string\n workflow_version: string | null\n wake_at: number | string\n signal_id: string\n}\n\ninterface ScheduleRow {\n schedule_id: string\n workflow_id: string\n workflow_version: string | null\n input: unknown\n overlap_policy: ScheduleBucket['overlapPolicy']\n next_fire_at: number | string\n}\n\ninterface ScheduleBucketRow {\n schedule_id: string\n bucket_id: string\n workflow_id: string\n workflow_version: string | null\n run_id: string\n fire_at: number | string\n input: unknown\n overlap_policy: ScheduleBucket['overlapPolicy']\n}\n\nfunction tableSqls(\n schema: string | undefined,\n tables: DrizzlePostgresWorkflowStoreTables,\n): TableSqls {\n return {\n runs: sql.raw(qualifiedTableName(schema, tables.runs)),\n runStates: sql.raw(qualifiedTableName(schema, tables.runStates)),\n eventLocks: sql.raw(qualifiedTableName(schema, tables.eventLocks)),\n events: sql.raw(qualifiedTableName(schema, tables.events)),\n timers: sql.raw(qualifiedTableName(schema, tables.timers)),\n signalDeliveries: sql.raw(\n qualifiedTableName(schema, tables.signalDeliveries),\n ),\n schedules: sql.raw(qualifiedTableName(schema, tables.schedules)),\n scheduleBuckets: sql.raw(\n qualifiedTableName(schema, tables.scheduleBuckets),\n ),\n }\n}\n\nfunction schemaStatements(\n schema: string | undefined,\n tables: DrizzlePostgresWorkflowStoreTables,\n): Array<string> {\n const runs = qualifiedTableName(schema, tables.runs)\n const runStates = qualifiedTableName(schema, tables.runStates)\n const eventLocks = qualifiedTableName(schema, tables.eventLocks)\n const events = qualifiedTableName(schema, tables.events)\n const timers = qualifiedTableName(schema, tables.timers)\n const signalDeliveries = qualifiedTableName(schema, tables.signalDeliveries)\n const schedules = qualifiedTableName(schema, tables.schedules)\n const scheduleBuckets = qualifiedTableName(schema, tables.scheduleBuckets)\n\n return [\n ...(schema ? [`create schema if not exists ${quoteIdent(schema)}`] : []),\n `create table if not exists ${runs} (\n run_id text primary key,\n workflow_id text not null,\n workflow_version text,\n status text not null,\n input jsonb not null,\n output jsonb,\n error jsonb,\n waiting_for jsonb,\n pending_approval jsonb,\n wake_at bigint,\n lease_owner text,\n lease_expires_at bigint,\n created_at bigint not null,\n updated_at bigint not null\n )`,\n `create index if not exists ${quoteIdent(`${tables.runs}_status_idx`)}\n on ${runs} (status, updated_at)`,\n `create index if not exists ${quoteIdent(`${tables.runs}_lease_idx`)}\n on ${runs} (status, lease_expires_at)`,\n `create table if not exists ${runStates} (\n run_id text primary key,\n workflow_id text not null,\n workflow_version text,\n status text not null,\n input jsonb not null,\n output jsonb,\n error jsonb,\n waiting_for jsonb,\n pending_approval jsonb,\n created_at bigint not null,\n updated_at bigint not null\n )`,\n `create table if not exists ${eventLocks} (\n run_id text primary key,\n created_at bigint not null\n )`,\n `create table if not exists ${events} (\n run_id text not null,\n event_index integer not null,\n event_type text not null,\n step_id text,\n event jsonb not null,\n created_at bigint not null,\n primary key (run_id, event_index)\n )`,\n `create index if not exists ${quoteIdent(`${tables.events}_type_idx`)}\n on ${events} (run_id, event_type)`,\n `create table if not exists ${timers} (\n run_id text not null,\n signal_id text not null,\n workflow_id text not null,\n workflow_version text,\n wake_at bigint not null,\n lease_owner text,\n lease_expires_at bigint,\n primary key (run_id, signal_id)\n )`,\n `create index if not exists ${quoteIdent(`${tables.timers}_due_idx`)}\n on ${timers} (wake_at, lease_expires_at)`,\n `create table if not exists ${signalDeliveries} (\n run_id text not null,\n signal_id text not null,\n created_at bigint not null,\n primary key (run_id, signal_id)\n )`,\n `create table if not exists ${schedules} (\n schedule_id text primary key,\n workflow_id text not null,\n workflow_version text,\n schedule jsonb not null,\n overlap_policy text not null,\n input jsonb,\n next_fire_at bigint,\n enabled boolean not null,\n updated_at bigint not null\n )`,\n `create index if not exists ${quoteIdent(`${tables.schedules}_due_idx`)}\n on ${schedules} (enabled, next_fire_at)`,\n `create table if not exists ${scheduleBuckets} (\n schedule_id text not null,\n bucket_id text not null,\n workflow_id text not null,\n workflow_version text,\n run_id text not null,\n fire_at bigint not null,\n input jsonb,\n overlap_policy text not null,\n status text not null,\n lease_owner text,\n lease_expires_at bigint,\n started_at bigint,\n primary key (schedule_id, bucket_id)\n )`,\n `create index if not exists ${quoteIdent(\n `${tables.scheduleBuckets}_lease_idx`,\n )}\n on ${scheduleBuckets} (status, fire_at, lease_expires_at)`,\n ]\n}\n\nasync function loadRunById(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n) {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n select *\n from ${tables.runs}\n where run_id = ${runId}\n limit 1\n `,\n )\n return rows[0] ? runFromRow(rows[0]) : undefined\n}\n\nasync function loadRunStateById(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n): Promise<RunState | undefined> {\n const rows = await queryRows<RunStateRow>(\n db,\n sql`\n select *\n from ${tables.runStates}\n where run_id = ${runId}\n limit 1\n `,\n )\n return rows[0] ? runStateFromRow(rows[0]) : undefined\n}\n\nasync function readStoredEvents(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n args: ReadEventsArgs,\n): Promise<ReadonlyArray<StoredWorkflowEvent>> {\n const rows = await queryRows<EventRow>(\n db,\n sql`\n select *\n from ${tables.events}\n where run_id = ${args.runId}\n and event_index >= ${args.fromIndex ?? 0}\n order by event_index asc\n `,\n )\n return rows.map(eventFromRow)\n}\n\nasync function loadSignalDelivery(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n signalId: string,\n) {\n const rows = await queryRows<{ run_id: string }>(\n db,\n sql`\n select run_id\n from ${tables.signalDeliveries}\n where run_id = ${runId}\n and signal_id = ${signalId}\n limit 1\n `,\n )\n return Boolean(rows[0])\n}\n\nasync function insertSignalDelivery(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n signalId: string,\n now: number,\n) {\n const rows = await queryRows<{ run_id: string }>(\n db,\n sql`\n insert into ${tables.signalDeliveries} (run_id, signal_id, created_at)\n values (${runId}, ${signalId}, ${now})\n on conflict (run_id, signal_id) do nothing\n returning run_id\n `,\n )\n return Boolean(rows[0])\n}\n\nasync function withTransaction<TResult>(\n db: DrizzlePostgresDatabase,\n callback: (tx: DrizzlePostgresDatabase) => Promise<TResult>,\n) {\n if (db.transaction) return db.transaction(callback)\n\n await db.execute(sql.raw('begin'))\n try {\n const result = await callback(db)\n await db.execute(sql.raw('commit'))\n return result\n } catch (error) {\n await db.execute(sql.raw('rollback'))\n throw error\n }\n}\n\nasync function queryRows<TRow>(\n db: DrizzlePostgresDatabase,\n query: SQL,\n): Promise<Array<TRow>> {\n const result = await db.execute(query)\n return rowsFromResult<TRow>(result)\n}\n\nfunction rowsFromResult<TRow>(result: unknown): Array<TRow> {\n if (Array.isArray(result)) return result as Array<TRow>\n\n if (isObjectWithRows(result) && Array.isArray(result.rows)) {\n return result.rows as Array<TRow>\n }\n\n return []\n}\n\nfunction isObjectWithRows(value: unknown): value is { rows: unknown } {\n return typeof value === 'object' && value !== null && 'rows' in value\n}\n\nfunction runFromRow(row: RunRow): WorkflowExecution {\n return {\n runId: row.run_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n status: row.status,\n input: decodeJson(row.input),\n output: decodeJsonOrUndefined(row.output),\n error: decodeJsonOrUndefined(row.error),\n waitingFor: decodeJsonOrUndefined(row.waiting_for),\n pendingApproval: decodeJsonOrUndefined(row.pending_approval),\n wakeAt: numberOrUndefined(row.wake_at),\n lease:\n row.lease_owner && row.lease_expires_at !== null\n ? {\n owner: row.lease_owner,\n expiresAt: Number(row.lease_expires_at),\n }\n : undefined,\n createdAt: Number(row.created_at),\n updatedAt: Number(row.updated_at),\n }\n}\n\nfunction runStateFromRow(row: RunStateRow): RunState {\n return {\n runId: row.run_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n status: row.status,\n input: decodeJson(row.input),\n output: decodeJsonOrUndefined(row.output),\n error: decodeJsonOrUndefined(row.error),\n waitingFor: decodeJsonOrUndefined(row.waiting_for),\n pendingApproval: decodeJsonOrUndefined(row.pending_approval),\n createdAt: Number(row.created_at),\n updatedAt: Number(row.updated_at),\n }\n}\n\nfunction eventFromRow(row: EventRow): StoredWorkflowEvent {\n return {\n runId: row.run_id,\n eventIndex: Number(row.event_index),\n eventType: row.event_type,\n stepId: row.step_id ?? undefined,\n event: decodeJson(row.event) as WorkflowEvent,\n createdAt: Number(row.created_at),\n }\n}\n\nfunction timerFromRow(row: TimerRow): TimerWakeup {\n return {\n runId: row.run_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n wakeAt: Number(row.wake_at),\n signalId: row.signal_id,\n }\n}\n\nfunction scheduleFromRow(row: ScheduleRow) {\n return {\n scheduleId: row.schedule_id satisfies ScheduleId,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n input: decodeJsonOrUndefined(row.input),\n overlapPolicy: row.overlap_policy,\n nextFireAt: Number(row.next_fire_at),\n }\n}\n\nfunction scheduleBucketFromRow(row: ScheduleBucketRow): ScheduleBucket {\n return {\n scheduleId: row.schedule_id,\n bucketId: row.bucket_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n runId: row.run_id,\n fireAt: Number(row.fire_at),\n input: decodeJsonOrUndefined(row.input),\n overlapPolicy: row.overlap_policy,\n }\n}\n\nfunction toRunSummary(row: RunRow): RunSummary {\n const run = runFromRow(row)\n return {\n runId: run.runId,\n workflowId: run.workflowId,\n workflowVersion: run.workflowVersion,\n status: run.status,\n waitingFor: run.waitingFor,\n pendingApproval: run.pendingApproval,\n wakeAt: run.wakeAt,\n createdAt: run.createdAt,\n updatedAt: run.updatedAt,\n }\n}\n\nfunction encodeJson(value: unknown) {\n return JSON.stringify(value ?? null)\n}\n\nfunction encodeJsonOrNull(value: unknown) {\n return value === undefined ? null : JSON.stringify(value)\n}\n\nfunction decodeJson(value: unknown): unknown {\n if (typeof value !== 'string') return value\n try {\n return JSON.parse(value)\n } catch {\n return value\n }\n}\n\nfunction decodeJsonOrUndefined<TValue = unknown>(\n value: unknown,\n): TValue | undefined {\n if (value === null || value === undefined) return undefined\n return decodeJson(value) as TValue\n}\n\nfunction numberOrUndefined(value: number | string | null) {\n return value === null ? undefined : Number(value)\n}\n\nfunction getStepId(event: WorkflowEvent) {\n return 'stepId' in event ? event.stepId : undefined\n}\n\nfunction qualifiedTableName(schema: string | undefined, table: string) {\n return schema\n ? `${quoteIdent(schema)}.${quoteIdent(table)}`\n : quoteIdent(table)\n}\n\nfunction quoteIdent(identifier: string) {\n return `\"${identifier.replaceAll('\"', '\"\"')}\"`\n}\n"],"mappings":"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"}
|
package/dist/store.js
CHANGED
|
@@ -498,12 +498,26 @@ function createDrizzlePostgresWorkflowStore(options) {
|
|
|
498
498
|
},
|
|
499
499
|
async claimDueScheduleBuckets(args) {
|
|
500
500
|
const schedules = await queryRows(db, sql`
|
|
501
|
-
select
|
|
502
|
-
from ${tableSql.schedules}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
and
|
|
506
|
-
|
|
501
|
+
select schedule.*
|
|
502
|
+
from ${tableSql.schedules} schedule
|
|
503
|
+
left join ${tableSql.scheduleBuckets} bucket
|
|
504
|
+
on bucket.schedule_id = schedule.schedule_id
|
|
505
|
+
and bucket.bucket_id = schedule.next_fire_at::text
|
|
506
|
+
where schedule.enabled = true
|
|
507
|
+
and schedule.next_fire_at is not null
|
|
508
|
+
and schedule.next_fire_at <= ${args.now}
|
|
509
|
+
and (
|
|
510
|
+
bucket.schedule_id is null
|
|
511
|
+
or (
|
|
512
|
+
bucket.status <> 'started'
|
|
513
|
+
and (
|
|
514
|
+
bucket.lease_owner is null
|
|
515
|
+
or bucket.lease_owner = ${args.leaseOwner}
|
|
516
|
+
or bucket.lease_expires_at <= ${args.now}
|
|
517
|
+
)
|
|
518
|
+
)
|
|
519
|
+
)
|
|
520
|
+
order by schedule.next_fire_at asc, schedule.schedule_id asc
|
|
507
521
|
limit ${args.limit}
|
|
508
522
|
`);
|
|
509
523
|
const buckets = [];
|
package/dist/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","names":[],"sources":["../src/store.ts"],"sourcesContent":["import { LogConflictError } from '@tanstack/workflow-core'\nimport { sql } from 'drizzle-orm'\nimport type { RunState, WorkflowEvent } from '@tanstack/workflow-core'\nimport type { SQL } from 'drizzle-orm'\nimport type {\n AppendEventsArgs,\n AppendEventsResult,\n ClaimDueScheduleBucketsArgs,\n ClaimDueTimersArgs,\n ClaimRunArgs,\n ClaimRunResult,\n ClaimStaleRunsArgs,\n CreateRunArgs,\n CreateRunResult,\n DeliverApprovalArgs,\n DeliverApprovalResult,\n DeliverSignalArgs,\n DeliverSignalResult,\n HeartbeatRunLeaseArgs,\n ListRunsArgs,\n LoadedExecution,\n MarkRunErroredArgs,\n MarkRunFinishedArgs,\n MarkRunPausedArgs,\n MarkScheduleBucketStartedArgs,\n ReadEventsArgs,\n ReleaseRunLeaseArgs,\n RunClaim,\n RunId,\n RunSummary,\n RunTimeline,\n SaveRunStateArgs,\n ScheduleBucket,\n ScheduleBucketId,\n ScheduleId,\n ScheduleTimerArgs,\n StoredWorkflowEvent,\n TimerWakeup,\n UpsertScheduleArgs,\n WorkflowExecution,\n WorkflowExecutionStatus,\n WorkflowExecutionStore,\n WorkflowRunStoreAdapterStore,\n} from '@tanstack/workflow-runtime'\n\nexport interface DrizzlePostgresDatabase {\n execute: (query: SQL | string) => PromiseLike<unknown>\n transaction?: <TResult>(\n callback: (tx: DrizzlePostgresDatabase) => Promise<TResult>,\n ) => Promise<TResult>\n}\n\nexport interface DrizzlePostgresWorkflowStoreTables {\n runs: string\n runStates: string\n eventLocks: string\n events: string\n timers: string\n signalDeliveries: string\n schedules: string\n scheduleBuckets: string\n}\n\nexport interface DrizzlePostgresWorkflowStoreOptions {\n db: DrizzlePostgresDatabase\n schema?: string\n tables?: Partial<DrizzlePostgresWorkflowStoreTables>\n}\n\nexport type DrizzlePostgresWorkflowStore = WorkflowExecutionStore &\n WorkflowRunStoreAdapterStore & {\n ensureSchema: () => Promise<void>\n }\n\nexport const defaultDrizzlePostgresWorkflowStoreTables: DrizzlePostgresWorkflowStoreTables =\n {\n runs: 'workflow_runs',\n runStates: 'workflow_run_states',\n eventLocks: 'workflow_event_locks',\n events: 'workflow_events',\n timers: 'workflow_timers',\n signalDeliveries: 'workflow_signal_deliveries',\n schedules: 'workflow_schedules',\n scheduleBuckets: 'workflow_schedule_buckets',\n }\n\nexport function createDrizzlePostgresWorkflowStore(\n options: DrizzlePostgresWorkflowStoreOptions,\n): DrizzlePostgresWorkflowStore {\n const tableNames = {\n ...defaultDrizzlePostgresWorkflowStoreTables,\n ...options.tables,\n }\n const tableSql = tableSqls(options.schema, tableNames)\n const db = options.db\n\n return {\n async ensureSchema() {\n for (const statement of schemaStatements(options.schema, tableNames)) {\n await db.execute(sql.raw(statement))\n }\n },\n\n async createRun(args: CreateRunArgs): Promise<CreateRunResult> {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n insert into ${tableSql.runs} (\n run_id,\n workflow_id,\n workflow_version,\n status,\n input,\n created_at,\n updated_at\n )\n values (\n ${args.runId},\n ${args.workflowId},\n ${args.workflowVersion ?? null},\n 'queued',\n ${encodeJson(args.input)}::jsonb,\n ${args.now},\n ${args.now}\n )\n on conflict (run_id) do nothing\n returning *\n `,\n )\n if (rows[0]) return { kind: 'created', run: runFromRow(rows[0]) }\n\n const existing = await loadRunById(db, tableSql, args.runId)\n if (!existing) {\n throw new Error(`Run \"${args.runId}\" was not inserted or loaded.`)\n }\n return { kind: 'existing', run: existing }\n },\n\n loadRun(runId: RunId) {\n return loadRunById(db, tableSql, runId)\n },\n\n async loadExecution(runId: RunId): Promise<LoadedExecution | undefined> {\n const run = await loadRunById(db, tableSql, runId)\n if (!run) return undefined\n return {\n run,\n events: await readStoredEvents(db, tableSql, { runId }),\n }\n },\n\n async loadRunState(runId: RunId) {\n return loadRunStateById(db, tableSql, runId)\n },\n\n async saveRunState(args: SaveRunStateArgs) {\n const state = args.state\n await withTransaction(db, async (tx) => {\n await tx.execute(sql`\n insert into ${tableSql.runStates} (\n run_id,\n workflow_id,\n workflow_version,\n status,\n input,\n output,\n error,\n waiting_for,\n pending_approval,\n created_at,\n updated_at\n )\n values (\n ${state.runId},\n ${state.workflowId},\n ${state.workflowVersion ?? null},\n ${state.status},\n ${encodeJson(state.input)}::jsonb,\n ${encodeJsonOrNull(state.output)}::jsonb,\n ${encodeJsonOrNull(state.error)}::jsonb,\n ${encodeJsonOrNull(state.waitingFor)}::jsonb,\n ${encodeJsonOrNull(state.pendingApproval)}::jsonb,\n ${state.createdAt},\n ${state.updatedAt}\n )\n on conflict (run_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n status = excluded.status,\n input = excluded.input,\n output = excluded.output,\n error = excluded.error,\n waiting_for = excluded.waiting_for,\n pending_approval = excluded.pending_approval,\n created_at = excluded.created_at,\n updated_at = excluded.updated_at\n `)\n await tx.execute(sql`\n insert into ${tableSql.runs} (\n run_id,\n workflow_id,\n workflow_version,\n status,\n input,\n output,\n error,\n waiting_for,\n pending_approval,\n wake_at,\n created_at,\n updated_at\n )\n values (\n ${state.runId},\n ${state.workflowId},\n ${state.workflowVersion ?? null},\n ${state.status},\n ${encodeJson(state.input)}::jsonb,\n ${encodeJsonOrNull(state.output)}::jsonb,\n ${encodeJsonOrNull(state.error)}::jsonb,\n ${encodeJsonOrNull(state.waitingFor)}::jsonb,\n ${encodeJsonOrNull(state.pendingApproval)}::jsonb,\n ${\n state.waitingFor?.signalName === '__timer'\n ? state.waitingFor.deadline\n : null\n },\n ${state.createdAt},\n ${state.updatedAt}\n )\n on conflict (run_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n status = excluded.status,\n input = excluded.input,\n output = excluded.output,\n error = excluded.error,\n waiting_for = excluded.waiting_for,\n pending_approval = excluded.pending_approval,\n wake_at = excluded.wake_at,\n created_at = excluded.created_at,\n updated_at = excluded.updated_at\n `)\n })\n },\n\n async deleteRun(runId, _reason) {\n await withTransaction(db, async (tx) => {\n await tx.execute(sql`\n delete from ${tableSql.runStates}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.eventLocks}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.signalDeliveries}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.timers}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.events}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.runs}\n where run_id = ${runId}\n `)\n })\n },\n\n async appendEvents(args: AppendEventsArgs): Promise<AppendEventsResult> {\n return withTransaction(db, async (tx) => {\n await tx.execute(sql`\n insert into ${tableSql.eventLocks} (run_id, created_at)\n values (${args.runId}, ${Date.now()})\n on conflict (run_id) do nothing\n `)\n await queryRows<{ run_id: string }>(\n tx,\n sql`\n select run_id\n from ${tableSql.eventLocks}\n where run_id = ${args.runId}\n for update\n `,\n )\n\n const countRows = await queryRows<{ count: number | string }>(\n tx,\n sql`\n select count(*)::int as count\n from ${tableSql.events}\n where run_id = ${args.runId}\n `,\n )\n const currentCount = Number(countRows[0]?.count ?? 0)\n\n if (currentCount !== args.expectedNextIndex) {\n const conflict = await queryRows<EventRow>(\n tx,\n sql`\n select *\n from ${tableSql.events}\n where run_id = ${args.runId}\n and event_index = ${args.expectedNextIndex}\n limit 1\n `,\n )\n throw new LogConflictError(\n args.runId,\n args.expectedNextIndex,\n conflict[0] ? eventFromRow(conflict[0]).event : undefined,\n )\n }\n\n let nextIndex = args.expectedNextIndex\n for (const event of args.events) {\n await tx.execute(sql`\n insert into ${tableSql.events} (\n run_id,\n event_index,\n event_type,\n step_id,\n event,\n created_at\n )\n values (\n ${args.runId},\n ${nextIndex},\n ${event.type},\n ${getStepId(event) ?? null},\n ${encodeJson(event)}::jsonb,\n ${event.ts}\n )\n `)\n nextIndex++\n }\n\n return { nextIndex }\n })\n },\n\n readEvents(args: ReadEventsArgs) {\n return readStoredEvents(db, tableSql, args)\n },\n\n async claimRun(args: ClaimRunArgs): Promise<ClaimRunResult> {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n update ${tableSql.runs}\n set\n status = 'running',\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs},\n updated_at = ${args.now}\n where run_id = ${args.runId}\n and status not in ('finished', 'errored', 'aborted')\n and (\n lease_owner is null\n or lease_owner = ${args.leaseOwner}\n or lease_expires_at <= ${args.now}\n )\n returning *\n `,\n )\n if (rows[0]) return { kind: 'claimed', run: runFromRow(rows[0]) }\n\n const run = await loadRunById(db, tableSql, args.runId)\n return run ? { kind: 'not-claimable', run } : { kind: 'not-found' }\n },\n\n async heartbeatRunLease(args: HeartbeatRunLeaseArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n lease_expires_at = ${args.now + args.leaseMs},\n updated_at = ${args.now}\n where run_id = ${args.runId}\n and lease_owner = ${args.leaseOwner}\n `)\n },\n\n async releaseRunLease(args: ReleaseRunLeaseArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n lease_owner = null,\n lease_expires_at = null\n where run_id = ${args.runId}\n and lease_owner = ${args.leaseOwner}\n `)\n },\n\n async markRunPaused(args: MarkRunPausedArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n status = 'paused',\n waiting_for = ${encodeJsonOrNull(args.waitingFor)}::jsonb,\n pending_approval = ${encodeJsonOrNull(args.pendingApproval)}::jsonb,\n wake_at = ${args.wakeAt ?? null},\n lease_owner = null,\n lease_expires_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n },\n\n async markRunFinished(args: MarkRunFinishedArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n status = 'finished',\n output = ${encodeJson(args.output)}::jsonb,\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n lease_owner = null,\n lease_expires_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n },\n\n async markRunErrored(args: MarkRunErroredArgs) {\n void args.code\n await db.execute(sql`\n update ${tableSql.runs}\n set\n status = 'errored',\n error = ${encodeJson(args.error)}::jsonb,\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n lease_owner = null,\n lease_expires_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n },\n\n async scheduleTimer(args: ScheduleTimerArgs) {\n await withTransaction(db, async (tx) => {\n await tx.execute(sql`\n insert into ${tableSql.timers} (\n run_id,\n signal_id,\n workflow_id,\n workflow_version,\n wake_at\n )\n values (\n ${args.runId},\n ${args.signalId},\n ${args.workflowId},\n ${args.workflowVersion ?? null},\n ${args.wakeAt}\n )\n on conflict (run_id, signal_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n wake_at = excluded.wake_at,\n lease_owner = null,\n lease_expires_at = null\n `)\n await tx.execute(sql`\n update ${tableSql.runs}\n set\n wake_at = ${args.wakeAt},\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n })\n },\n\n async claimDueTimers(args: ClaimDueTimersArgs) {\n const rows = await queryRows<TimerRow>(\n db,\n sql`\n with due as (\n select run_id, signal_id\n from ${tableSql.timers}\n where wake_at <= ${args.now}\n and (\n lease_owner is null\n or lease_owner = ${args.leaseOwner}\n or lease_expires_at <= ${args.now}\n )\n order by wake_at asc, run_id asc, signal_id asc\n limit ${args.limit}\n for update skip locked\n )\n update ${tableSql.timers} timer\n set\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs}\n from due\n where timer.run_id = due.run_id\n and timer.signal_id = due.signal_id\n returning timer.*\n `,\n )\n return rows.map(timerFromRow)\n },\n\n async deliverSignal<TPayload>(\n args: DeliverSignalArgs<TPayload>,\n ): Promise<DeliverSignalResult> {\n return withTransaction(db, async (tx) => {\n const run = await loadRunById(tx, tableSql, args.runId)\n if (!run) return { kind: 'not-found' }\n\n const existingDelivery = await loadSignalDelivery(\n tx,\n tableSql,\n args.runId,\n args.delivery.signalId,\n )\n if (existingDelivery) return { kind: 'duplicate', run }\n\n if (run.waitingFor?.signalName !== args.delivery.name) {\n return { kind: 'not-waiting', run }\n }\n\n const inserted = await insertSignalDelivery(\n tx,\n tableSql,\n args.runId,\n args.delivery.signalId,\n args.now,\n )\n if (!inserted) return { kind: 'duplicate', run }\n\n await tx.execute(sql`\n delete from ${tableSql.timers}\n where run_id = ${args.runId}\n and signal_id = ${args.delivery.signalId}\n `)\n\n const rows = await queryRows<RunRow>(\n tx,\n sql`\n update ${tableSql.runs}\n set\n status = 'queued',\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n returning *\n `,\n )\n\n return { kind: 'delivered', run: runFromRow(rows[0]!) }\n })\n },\n\n async deliverApproval(\n args: DeliverApprovalArgs,\n ): Promise<DeliverApprovalResult> {\n return withTransaction(db, async (tx) => {\n const run = await loadRunById(tx, tableSql, args.runId)\n if (!run) return { kind: 'not-found' }\n\n const signalId = `approval:${args.approval.approvalId}`\n const existingDelivery = await loadSignalDelivery(\n tx,\n tableSql,\n args.runId,\n signalId,\n )\n if (existingDelivery) return { kind: 'duplicate', run }\n\n if (run.pendingApproval?.approvalId !== args.approval.approvalId) {\n return { kind: 'not-waiting', run }\n }\n\n const inserted = await insertSignalDelivery(\n tx,\n tableSql,\n args.runId,\n signalId,\n args.now,\n )\n if (!inserted) return { kind: 'duplicate', run }\n\n const rows = await queryRows<RunRow>(\n tx,\n sql`\n update ${tableSql.runs}\n set\n status = 'queued',\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n returning *\n `,\n )\n\n return { kind: 'delivered', run: runFromRow(rows[0]!) }\n })\n },\n\n async upsertSchedule(args: UpsertScheduleArgs) {\n await db.execute(sql`\n insert into ${tableSql.schedules} (\n schedule_id,\n workflow_id,\n workflow_version,\n schedule,\n overlap_policy,\n input,\n next_fire_at,\n enabled,\n updated_at\n )\n values (\n ${args.scheduleId},\n ${args.workflowId},\n ${args.workflowVersion ?? null},\n ${encodeJson(args.schedule)}::jsonb,\n ${args.overlapPolicy},\n ${encodeJsonOrNull(args.input)}::jsonb,\n ${args.nextFireAt ?? null},\n ${args.enabled},\n ${args.now}\n )\n on conflict (schedule_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n schedule = excluded.schedule,\n overlap_policy = excluded.overlap_policy,\n input = excluded.input,\n next_fire_at = excluded.next_fire_at,\n enabled = excluded.enabled,\n updated_at = excluded.updated_at\n `)\n },\n\n async claimDueScheduleBuckets(args: ClaimDueScheduleBucketsArgs) {\n const schedules = await queryRows<ScheduleRow>(\n db,\n sql`\n select *\n from ${tableSql.schedules}\n where enabled = true\n and next_fire_at is not null\n and next_fire_at <= ${args.now}\n order by next_fire_at asc, schedule_id asc\n limit ${args.limit}\n `,\n )\n const buckets: Array<ScheduleBucket> = []\n\n for (const scheduleRow of schedules) {\n if (buckets.length >= args.limit) break\n\n const schedule = scheduleFromRow(scheduleRow)\n const bucketId = `${schedule.nextFireAt}` satisfies ScheduleBucketId\n const runId = `${schedule.workflowId}:${schedule.scheduleId}:${bucketId}`\n\n await db.execute(sql`\n insert into ${tableSql.scheduleBuckets} (\n schedule_id,\n bucket_id,\n workflow_id,\n workflow_version,\n run_id,\n fire_at,\n input,\n overlap_policy,\n status\n )\n values (\n ${schedule.scheduleId},\n ${bucketId},\n ${schedule.workflowId},\n ${schedule.workflowVersion ?? null},\n ${runId},\n ${schedule.nextFireAt},\n ${encodeJsonOrNull(schedule.input)}::jsonb,\n ${schedule.overlapPolicy},\n 'claimed'\n )\n on conflict (schedule_id, bucket_id) do nothing\n `)\n\n const rows = await queryRows<ScheduleBucketRow>(\n db,\n sql`\n update ${tableSql.scheduleBuckets}\n set\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs}\n where schedule_id = ${schedule.scheduleId}\n and bucket_id = ${bucketId}\n and status <> 'started'\n and (\n lease_owner is null\n or lease_owner = ${args.leaseOwner}\n or lease_expires_at <= ${args.now}\n )\n returning *\n `,\n )\n if (rows[0]) buckets.push(scheduleBucketFromRow(rows[0]))\n }\n\n return buckets\n },\n\n async markScheduleBucketStarted(args: MarkScheduleBucketStartedArgs) {\n await db.execute(sql`\n update ${tableSql.scheduleBuckets}\n set\n run_id = ${args.runId},\n status = 'started',\n started_at = ${args.now}\n where schedule_id = ${args.scheduleId}\n and bucket_id = ${args.bucketId}\n `)\n },\n\n async claimStaleRuns(args: ClaimStaleRunsArgs) {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n with stale as (\n select run_id\n from ${tableSql.runs}\n where status = 'running'\n and lease_expires_at is not null\n and lease_expires_at <= ${args.now}\n order by updated_at asc, run_id asc\n limit ${args.limit}\n for update skip locked\n )\n update ${tableSql.runs} run\n set\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs},\n updated_at = ${args.now}\n from stale\n where run.run_id = stale.run_id\n returning run.*\n `,\n )\n\n return rows.map((row): RunClaim => {\n const run = runFromRow(row)\n return { run, lease: run.lease! }\n })\n },\n\n async listRuns(args: ListRunsArgs) {\n const offset = args.cursor ? Number(args.cursor) : 0\n const start = Number.isFinite(offset) && offset > 0 ? offset : 0\n const rows = await queryRows<RunRow>(\n db,\n sql`\n select *\n from ${tableSql.runs}\n where (${args.workflowId ?? null}::text is null or workflow_id = ${args.workflowId ?? null})\n and (${args.status ?? null}::text is null or status = ${args.status ?? null})\n order by updated_at desc, run_id asc\n limit ${args.limit}\n offset ${start}\n `,\n )\n\n return rows.map(toRunSummary)\n },\n\n async getRunTimeline(runId: RunId): Promise<RunTimeline | undefined> {\n const run = await loadRunById(db, tableSql, runId)\n if (!run) return undefined\n return {\n run,\n events: await readStoredEvents(db, tableSql, { runId }),\n }\n },\n }\n}\n\ninterface TableSqls {\n runs: SQL\n runStates: SQL\n eventLocks: SQL\n events: SQL\n timers: SQL\n signalDeliveries: SQL\n schedules: SQL\n scheduleBuckets: SQL\n}\n\ninterface RunRow {\n run_id: string\n workflow_id: string\n workflow_version: string | null\n status: WorkflowExecutionStatus\n input: unknown\n output: unknown\n error: unknown\n waiting_for: unknown\n pending_approval: unknown\n wake_at: number | string | null\n lease_owner: string | null\n lease_expires_at: number | string | null\n created_at: number | string\n updated_at: number | string\n}\n\ninterface RunStateRow {\n run_id: string\n workflow_id: string\n workflow_version: string | null\n status: RunState['status']\n input: unknown\n output: unknown\n error: unknown\n waiting_for: unknown\n pending_approval: unknown\n created_at: number | string\n updated_at: number | string\n}\n\ninterface EventRow {\n run_id: string\n event_index: number | string\n event_type: WorkflowEvent['type']\n step_id: string | null\n event: unknown\n created_at: number | string\n}\n\ninterface TimerRow {\n run_id: string\n workflow_id: string\n workflow_version: string | null\n wake_at: number | string\n signal_id: string\n}\n\ninterface ScheduleRow {\n schedule_id: string\n workflow_id: string\n workflow_version: string | null\n input: unknown\n overlap_policy: ScheduleBucket['overlapPolicy']\n next_fire_at: number | string\n}\n\ninterface ScheduleBucketRow {\n schedule_id: string\n bucket_id: string\n workflow_id: string\n workflow_version: string | null\n run_id: string\n fire_at: number | string\n input: unknown\n overlap_policy: ScheduleBucket['overlapPolicy']\n}\n\nfunction tableSqls(\n schema: string | undefined,\n tables: DrizzlePostgresWorkflowStoreTables,\n): TableSqls {\n return {\n runs: sql.raw(qualifiedTableName(schema, tables.runs)),\n runStates: sql.raw(qualifiedTableName(schema, tables.runStates)),\n eventLocks: sql.raw(qualifiedTableName(schema, tables.eventLocks)),\n events: sql.raw(qualifiedTableName(schema, tables.events)),\n timers: sql.raw(qualifiedTableName(schema, tables.timers)),\n signalDeliveries: sql.raw(\n qualifiedTableName(schema, tables.signalDeliveries),\n ),\n schedules: sql.raw(qualifiedTableName(schema, tables.schedules)),\n scheduleBuckets: sql.raw(\n qualifiedTableName(schema, tables.scheduleBuckets),\n ),\n }\n}\n\nfunction schemaStatements(\n schema: string | undefined,\n tables: DrizzlePostgresWorkflowStoreTables,\n): Array<string> {\n const runs = qualifiedTableName(schema, tables.runs)\n const runStates = qualifiedTableName(schema, tables.runStates)\n const eventLocks = qualifiedTableName(schema, tables.eventLocks)\n const events = qualifiedTableName(schema, tables.events)\n const timers = qualifiedTableName(schema, tables.timers)\n const signalDeliveries = qualifiedTableName(schema, tables.signalDeliveries)\n const schedules = qualifiedTableName(schema, tables.schedules)\n const scheduleBuckets = qualifiedTableName(schema, tables.scheduleBuckets)\n\n return [\n ...(schema ? [`create schema if not exists ${quoteIdent(schema)}`] : []),\n `create table if not exists ${runs} (\n run_id text primary key,\n workflow_id text not null,\n workflow_version text,\n status text not null,\n input jsonb not null,\n output jsonb,\n error jsonb,\n waiting_for jsonb,\n pending_approval jsonb,\n wake_at bigint,\n lease_owner text,\n lease_expires_at bigint,\n created_at bigint not null,\n updated_at bigint not null\n )`,\n `create index if not exists ${quoteIdent(`${tables.runs}_status_idx`)}\n on ${runs} (status, updated_at)`,\n `create index if not exists ${quoteIdent(`${tables.runs}_lease_idx`)}\n on ${runs} (status, lease_expires_at)`,\n `create table if not exists ${runStates} (\n run_id text primary key,\n workflow_id text not null,\n workflow_version text,\n status text not null,\n input jsonb not null,\n output jsonb,\n error jsonb,\n waiting_for jsonb,\n pending_approval jsonb,\n created_at bigint not null,\n updated_at bigint not null\n )`,\n `create table if not exists ${eventLocks} (\n run_id text primary key,\n created_at bigint not null\n )`,\n `create table if not exists ${events} (\n run_id text not null,\n event_index integer not null,\n event_type text not null,\n step_id text,\n event jsonb not null,\n created_at bigint not null,\n primary key (run_id, event_index)\n )`,\n `create index if not exists ${quoteIdent(`${tables.events}_type_idx`)}\n on ${events} (run_id, event_type)`,\n `create table if not exists ${timers} (\n run_id text not null,\n signal_id text not null,\n workflow_id text not null,\n workflow_version text,\n wake_at bigint not null,\n lease_owner text,\n lease_expires_at bigint,\n primary key (run_id, signal_id)\n )`,\n `create index if not exists ${quoteIdent(`${tables.timers}_due_idx`)}\n on ${timers} (wake_at, lease_expires_at)`,\n `create table if not exists ${signalDeliveries} (\n run_id text not null,\n signal_id text not null,\n created_at bigint not null,\n primary key (run_id, signal_id)\n )`,\n `create table if not exists ${schedules} (\n schedule_id text primary key,\n workflow_id text not null,\n workflow_version text,\n schedule jsonb not null,\n overlap_policy text not null,\n input jsonb,\n next_fire_at bigint,\n enabled boolean not null,\n updated_at bigint not null\n )`,\n `create index if not exists ${quoteIdent(`${tables.schedules}_due_idx`)}\n on ${schedules} (enabled, next_fire_at)`,\n `create table if not exists ${scheduleBuckets} (\n schedule_id text not null,\n bucket_id text not null,\n workflow_id text not null,\n workflow_version text,\n run_id text not null,\n fire_at bigint not null,\n input jsonb,\n overlap_policy text not null,\n status text not null,\n lease_owner text,\n lease_expires_at bigint,\n started_at bigint,\n primary key (schedule_id, bucket_id)\n )`,\n `create index if not exists ${quoteIdent(\n `${tables.scheduleBuckets}_lease_idx`,\n )}\n on ${scheduleBuckets} (status, fire_at, lease_expires_at)`,\n ]\n}\n\nasync function loadRunById(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n) {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n select *\n from ${tables.runs}\n where run_id = ${runId}\n limit 1\n `,\n )\n return rows[0] ? runFromRow(rows[0]) : undefined\n}\n\nasync function loadRunStateById(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n): Promise<RunState | undefined> {\n const rows = await queryRows<RunStateRow>(\n db,\n sql`\n select *\n from ${tables.runStates}\n where run_id = ${runId}\n limit 1\n `,\n )\n return rows[0] ? runStateFromRow(rows[0]) : undefined\n}\n\nasync function readStoredEvents(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n args: ReadEventsArgs,\n): Promise<ReadonlyArray<StoredWorkflowEvent>> {\n const rows = await queryRows<EventRow>(\n db,\n sql`\n select *\n from ${tables.events}\n where run_id = ${args.runId}\n and event_index >= ${args.fromIndex ?? 0}\n order by event_index asc\n `,\n )\n return rows.map(eventFromRow)\n}\n\nasync function loadSignalDelivery(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n signalId: string,\n) {\n const rows = await queryRows<{ run_id: string }>(\n db,\n sql`\n select run_id\n from ${tables.signalDeliveries}\n where run_id = ${runId}\n and signal_id = ${signalId}\n limit 1\n `,\n )\n return Boolean(rows[0])\n}\n\nasync function insertSignalDelivery(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n signalId: string,\n now: number,\n) {\n const rows = await queryRows<{ run_id: string }>(\n db,\n sql`\n insert into ${tables.signalDeliveries} (run_id, signal_id, created_at)\n values (${runId}, ${signalId}, ${now})\n on conflict (run_id, signal_id) do nothing\n returning run_id\n `,\n )\n return Boolean(rows[0])\n}\n\nasync function withTransaction<TResult>(\n db: DrizzlePostgresDatabase,\n callback: (tx: DrizzlePostgresDatabase) => Promise<TResult>,\n) {\n if (db.transaction) return db.transaction(callback)\n\n await db.execute(sql.raw('begin'))\n try {\n const result = await callback(db)\n await db.execute(sql.raw('commit'))\n return result\n } catch (error) {\n await db.execute(sql.raw('rollback'))\n throw error\n }\n}\n\nasync function queryRows<TRow>(\n db: DrizzlePostgresDatabase,\n query: SQL,\n): Promise<Array<TRow>> {\n const result = await db.execute(query)\n return rowsFromResult<TRow>(result)\n}\n\nfunction rowsFromResult<TRow>(result: unknown): Array<TRow> {\n if (Array.isArray(result)) return result as Array<TRow>\n\n if (isObjectWithRows(result) && Array.isArray(result.rows)) {\n return result.rows as Array<TRow>\n }\n\n return []\n}\n\nfunction isObjectWithRows(value: unknown): value is { rows: unknown } {\n return typeof value === 'object' && value !== null && 'rows' in value\n}\n\nfunction runFromRow(row: RunRow): WorkflowExecution {\n return {\n runId: row.run_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n status: row.status,\n input: decodeJson(row.input),\n output: decodeJsonOrUndefined(row.output),\n error: decodeJsonOrUndefined(row.error),\n waitingFor: decodeJsonOrUndefined(row.waiting_for),\n pendingApproval: decodeJsonOrUndefined(row.pending_approval),\n wakeAt: numberOrUndefined(row.wake_at),\n lease:\n row.lease_owner && row.lease_expires_at !== null\n ? {\n owner: row.lease_owner,\n expiresAt: Number(row.lease_expires_at),\n }\n : undefined,\n createdAt: Number(row.created_at),\n updatedAt: Number(row.updated_at),\n }\n}\n\nfunction runStateFromRow(row: RunStateRow): RunState {\n return {\n runId: row.run_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n status: row.status,\n input: decodeJson(row.input),\n output: decodeJsonOrUndefined(row.output),\n error: decodeJsonOrUndefined(row.error),\n waitingFor: decodeJsonOrUndefined(row.waiting_for),\n pendingApproval: decodeJsonOrUndefined(row.pending_approval),\n createdAt: Number(row.created_at),\n updatedAt: Number(row.updated_at),\n }\n}\n\nfunction eventFromRow(row: EventRow): StoredWorkflowEvent {\n return {\n runId: row.run_id,\n eventIndex: Number(row.event_index),\n eventType: row.event_type,\n stepId: row.step_id ?? undefined,\n event: decodeJson(row.event) as WorkflowEvent,\n createdAt: Number(row.created_at),\n }\n}\n\nfunction timerFromRow(row: TimerRow): TimerWakeup {\n return {\n runId: row.run_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n wakeAt: Number(row.wake_at),\n signalId: row.signal_id,\n }\n}\n\nfunction scheduleFromRow(row: ScheduleRow) {\n return {\n scheduleId: row.schedule_id satisfies ScheduleId,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n input: decodeJsonOrUndefined(row.input),\n overlapPolicy: row.overlap_policy,\n nextFireAt: Number(row.next_fire_at),\n }\n}\n\nfunction scheduleBucketFromRow(row: ScheduleBucketRow): ScheduleBucket {\n return {\n scheduleId: row.schedule_id,\n bucketId: row.bucket_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n runId: row.run_id,\n fireAt: Number(row.fire_at),\n input: decodeJsonOrUndefined(row.input),\n overlapPolicy: row.overlap_policy,\n }\n}\n\nfunction toRunSummary(row: RunRow): RunSummary {\n const run = runFromRow(row)\n return {\n runId: run.runId,\n workflowId: run.workflowId,\n workflowVersion: run.workflowVersion,\n status: run.status,\n waitingFor: run.waitingFor,\n pendingApproval: run.pendingApproval,\n wakeAt: run.wakeAt,\n createdAt: run.createdAt,\n updatedAt: run.updatedAt,\n }\n}\n\nfunction encodeJson(value: unknown) {\n return JSON.stringify(value ?? null)\n}\n\nfunction encodeJsonOrNull(value: unknown) {\n return value === undefined ? null : JSON.stringify(value)\n}\n\nfunction decodeJson(value: unknown): unknown {\n if (typeof value !== 'string') return value\n try {\n return JSON.parse(value)\n } catch {\n return value\n }\n}\n\nfunction decodeJsonOrUndefined<TValue = unknown>(\n value: unknown,\n): TValue | undefined {\n if (value === null || value === undefined) return undefined\n return decodeJson(value) as TValue\n}\n\nfunction numberOrUndefined(value: number | string | null) {\n return value === null ? undefined : Number(value)\n}\n\nfunction getStepId(event: WorkflowEvent) {\n return 'stepId' in event ? event.stepId : undefined\n}\n\nfunction qualifiedTableName(schema: string | undefined, table: string) {\n return schema\n ? `${quoteIdent(schema)}.${quoteIdent(table)}`\n : quoteIdent(table)\n}\n\nfunction quoteIdent(identifier: string) {\n return `\"${identifier.replaceAll('\"', '\"\"')}\"`\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"store.js","names":[],"sources":["../src/store.ts"],"sourcesContent":["import { LogConflictError } from '@tanstack/workflow-core'\nimport { sql } from 'drizzle-orm'\nimport type { RunState, WorkflowEvent } from '@tanstack/workflow-core'\nimport type { SQL } from 'drizzle-orm'\nimport type {\n AppendEventsArgs,\n AppendEventsResult,\n ClaimDueScheduleBucketsArgs,\n ClaimDueTimersArgs,\n ClaimRunArgs,\n ClaimRunResult,\n ClaimStaleRunsArgs,\n CreateRunArgs,\n CreateRunResult,\n DeliverApprovalArgs,\n DeliverApprovalResult,\n DeliverSignalArgs,\n DeliverSignalResult,\n HeartbeatRunLeaseArgs,\n ListRunsArgs,\n LoadedExecution,\n MarkRunErroredArgs,\n MarkRunFinishedArgs,\n MarkRunPausedArgs,\n MarkScheduleBucketStartedArgs,\n ReadEventsArgs,\n ReleaseRunLeaseArgs,\n RunClaim,\n RunId,\n RunSummary,\n RunTimeline,\n SaveRunStateArgs,\n ScheduleBucket,\n ScheduleBucketId,\n ScheduleId,\n ScheduleTimerArgs,\n StoredWorkflowEvent,\n TimerWakeup,\n UpsertScheduleArgs,\n WorkflowExecution,\n WorkflowExecutionStatus,\n WorkflowExecutionStore,\n WorkflowRunStoreAdapterStore,\n} from '@tanstack/workflow-runtime'\n\nexport interface DrizzlePostgresDatabase {\n execute: (query: SQL | string) => PromiseLike<unknown>\n transaction?: <TResult>(\n callback: (tx: DrizzlePostgresDatabase) => Promise<TResult>,\n ) => Promise<TResult>\n}\n\nexport interface DrizzlePostgresWorkflowStoreTables {\n runs: string\n runStates: string\n eventLocks: string\n events: string\n timers: string\n signalDeliveries: string\n schedules: string\n scheduleBuckets: string\n}\n\nexport interface DrizzlePostgresWorkflowStoreOptions {\n db: DrizzlePostgresDatabase\n schema?: string\n tables?: Partial<DrizzlePostgresWorkflowStoreTables>\n}\n\nexport type DrizzlePostgresWorkflowStore = WorkflowExecutionStore &\n WorkflowRunStoreAdapterStore & {\n ensureSchema: () => Promise<void>\n }\n\nexport const defaultDrizzlePostgresWorkflowStoreTables: DrizzlePostgresWorkflowStoreTables =\n {\n runs: 'workflow_runs',\n runStates: 'workflow_run_states',\n eventLocks: 'workflow_event_locks',\n events: 'workflow_events',\n timers: 'workflow_timers',\n signalDeliveries: 'workflow_signal_deliveries',\n schedules: 'workflow_schedules',\n scheduleBuckets: 'workflow_schedule_buckets',\n }\n\nexport function createDrizzlePostgresWorkflowStore(\n options: DrizzlePostgresWorkflowStoreOptions,\n): DrizzlePostgresWorkflowStore {\n const tableNames = {\n ...defaultDrizzlePostgresWorkflowStoreTables,\n ...options.tables,\n }\n const tableSql = tableSqls(options.schema, tableNames)\n const db = options.db\n\n return {\n async ensureSchema() {\n for (const statement of schemaStatements(options.schema, tableNames)) {\n await db.execute(sql.raw(statement))\n }\n },\n\n async createRun(args: CreateRunArgs): Promise<CreateRunResult> {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n insert into ${tableSql.runs} (\n run_id,\n workflow_id,\n workflow_version,\n status,\n input,\n created_at,\n updated_at\n )\n values (\n ${args.runId},\n ${args.workflowId},\n ${args.workflowVersion ?? null},\n 'queued',\n ${encodeJson(args.input)}::jsonb,\n ${args.now},\n ${args.now}\n )\n on conflict (run_id) do nothing\n returning *\n `,\n )\n if (rows[0]) return { kind: 'created', run: runFromRow(rows[0]) }\n\n const existing = await loadRunById(db, tableSql, args.runId)\n if (!existing) {\n throw new Error(`Run \"${args.runId}\" was not inserted or loaded.`)\n }\n return { kind: 'existing', run: existing }\n },\n\n loadRun(runId: RunId) {\n return loadRunById(db, tableSql, runId)\n },\n\n async loadExecution(runId: RunId): Promise<LoadedExecution | undefined> {\n const run = await loadRunById(db, tableSql, runId)\n if (!run) return undefined\n return {\n run,\n events: await readStoredEvents(db, tableSql, { runId }),\n }\n },\n\n async loadRunState(runId: RunId) {\n return loadRunStateById(db, tableSql, runId)\n },\n\n async saveRunState(args: SaveRunStateArgs) {\n const state = args.state\n await withTransaction(db, async (tx) => {\n await tx.execute(sql`\n insert into ${tableSql.runStates} (\n run_id,\n workflow_id,\n workflow_version,\n status,\n input,\n output,\n error,\n waiting_for,\n pending_approval,\n created_at,\n updated_at\n )\n values (\n ${state.runId},\n ${state.workflowId},\n ${state.workflowVersion ?? null},\n ${state.status},\n ${encodeJson(state.input)}::jsonb,\n ${encodeJsonOrNull(state.output)}::jsonb,\n ${encodeJsonOrNull(state.error)}::jsonb,\n ${encodeJsonOrNull(state.waitingFor)}::jsonb,\n ${encodeJsonOrNull(state.pendingApproval)}::jsonb,\n ${state.createdAt},\n ${state.updatedAt}\n )\n on conflict (run_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n status = excluded.status,\n input = excluded.input,\n output = excluded.output,\n error = excluded.error,\n waiting_for = excluded.waiting_for,\n pending_approval = excluded.pending_approval,\n created_at = excluded.created_at,\n updated_at = excluded.updated_at\n `)\n await tx.execute(sql`\n insert into ${tableSql.runs} (\n run_id,\n workflow_id,\n workflow_version,\n status,\n input,\n output,\n error,\n waiting_for,\n pending_approval,\n wake_at,\n created_at,\n updated_at\n )\n values (\n ${state.runId},\n ${state.workflowId},\n ${state.workflowVersion ?? null},\n ${state.status},\n ${encodeJson(state.input)}::jsonb,\n ${encodeJsonOrNull(state.output)}::jsonb,\n ${encodeJsonOrNull(state.error)}::jsonb,\n ${encodeJsonOrNull(state.waitingFor)}::jsonb,\n ${encodeJsonOrNull(state.pendingApproval)}::jsonb,\n ${\n state.waitingFor?.signalName === '__timer'\n ? state.waitingFor.deadline\n : null\n },\n ${state.createdAt},\n ${state.updatedAt}\n )\n on conflict (run_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n status = excluded.status,\n input = excluded.input,\n output = excluded.output,\n error = excluded.error,\n waiting_for = excluded.waiting_for,\n pending_approval = excluded.pending_approval,\n wake_at = excluded.wake_at,\n created_at = excluded.created_at,\n updated_at = excluded.updated_at\n `)\n })\n },\n\n async deleteRun(runId, _reason) {\n await withTransaction(db, async (tx) => {\n await tx.execute(sql`\n delete from ${tableSql.runStates}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.eventLocks}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.signalDeliveries}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.timers}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.events}\n where run_id = ${runId}\n `)\n await tx.execute(sql`\n delete from ${tableSql.runs}\n where run_id = ${runId}\n `)\n })\n },\n\n async appendEvents(args: AppendEventsArgs): Promise<AppendEventsResult> {\n return withTransaction(db, async (tx) => {\n await tx.execute(sql`\n insert into ${tableSql.eventLocks} (run_id, created_at)\n values (${args.runId}, ${Date.now()})\n on conflict (run_id) do nothing\n `)\n await queryRows<{ run_id: string }>(\n tx,\n sql`\n select run_id\n from ${tableSql.eventLocks}\n where run_id = ${args.runId}\n for update\n `,\n )\n\n const countRows = await queryRows<{ count: number | string }>(\n tx,\n sql`\n select count(*)::int as count\n from ${tableSql.events}\n where run_id = ${args.runId}\n `,\n )\n const currentCount = Number(countRows[0]?.count ?? 0)\n\n if (currentCount !== args.expectedNextIndex) {\n const conflict = await queryRows<EventRow>(\n tx,\n sql`\n select *\n from ${tableSql.events}\n where run_id = ${args.runId}\n and event_index = ${args.expectedNextIndex}\n limit 1\n `,\n )\n throw new LogConflictError(\n args.runId,\n args.expectedNextIndex,\n conflict[0] ? eventFromRow(conflict[0]).event : undefined,\n )\n }\n\n let nextIndex = args.expectedNextIndex\n for (const event of args.events) {\n await tx.execute(sql`\n insert into ${tableSql.events} (\n run_id,\n event_index,\n event_type,\n step_id,\n event,\n created_at\n )\n values (\n ${args.runId},\n ${nextIndex},\n ${event.type},\n ${getStepId(event) ?? null},\n ${encodeJson(event)}::jsonb,\n ${event.ts}\n )\n `)\n nextIndex++\n }\n\n return { nextIndex }\n })\n },\n\n readEvents(args: ReadEventsArgs) {\n return readStoredEvents(db, tableSql, args)\n },\n\n async claimRun(args: ClaimRunArgs): Promise<ClaimRunResult> {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n update ${tableSql.runs}\n set\n status = 'running',\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs},\n updated_at = ${args.now}\n where run_id = ${args.runId}\n and status not in ('finished', 'errored', 'aborted')\n and (\n lease_owner is null\n or lease_owner = ${args.leaseOwner}\n or lease_expires_at <= ${args.now}\n )\n returning *\n `,\n )\n if (rows[0]) return { kind: 'claimed', run: runFromRow(rows[0]) }\n\n const run = await loadRunById(db, tableSql, args.runId)\n return run ? { kind: 'not-claimable', run } : { kind: 'not-found' }\n },\n\n async heartbeatRunLease(args: HeartbeatRunLeaseArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n lease_expires_at = ${args.now + args.leaseMs},\n updated_at = ${args.now}\n where run_id = ${args.runId}\n and lease_owner = ${args.leaseOwner}\n `)\n },\n\n async releaseRunLease(args: ReleaseRunLeaseArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n lease_owner = null,\n lease_expires_at = null\n where run_id = ${args.runId}\n and lease_owner = ${args.leaseOwner}\n `)\n },\n\n async markRunPaused(args: MarkRunPausedArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n status = 'paused',\n waiting_for = ${encodeJsonOrNull(args.waitingFor)}::jsonb,\n pending_approval = ${encodeJsonOrNull(args.pendingApproval)}::jsonb,\n wake_at = ${args.wakeAt ?? null},\n lease_owner = null,\n lease_expires_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n },\n\n async markRunFinished(args: MarkRunFinishedArgs) {\n await db.execute(sql`\n update ${tableSql.runs}\n set\n status = 'finished',\n output = ${encodeJson(args.output)}::jsonb,\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n lease_owner = null,\n lease_expires_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n },\n\n async markRunErrored(args: MarkRunErroredArgs) {\n void args.code\n await db.execute(sql`\n update ${tableSql.runs}\n set\n status = 'errored',\n error = ${encodeJson(args.error)}::jsonb,\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n lease_owner = null,\n lease_expires_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n },\n\n async scheduleTimer(args: ScheduleTimerArgs) {\n await withTransaction(db, async (tx) => {\n await tx.execute(sql`\n insert into ${tableSql.timers} (\n run_id,\n signal_id,\n workflow_id,\n workflow_version,\n wake_at\n )\n values (\n ${args.runId},\n ${args.signalId},\n ${args.workflowId},\n ${args.workflowVersion ?? null},\n ${args.wakeAt}\n )\n on conflict (run_id, signal_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n wake_at = excluded.wake_at,\n lease_owner = null,\n lease_expires_at = null\n `)\n await tx.execute(sql`\n update ${tableSql.runs}\n set\n wake_at = ${args.wakeAt},\n updated_at = ${args.now}\n where run_id = ${args.runId}\n `)\n })\n },\n\n async claimDueTimers(args: ClaimDueTimersArgs) {\n const rows = await queryRows<TimerRow>(\n db,\n sql`\n with due as (\n select run_id, signal_id\n from ${tableSql.timers}\n where wake_at <= ${args.now}\n and (\n lease_owner is null\n or lease_owner = ${args.leaseOwner}\n or lease_expires_at <= ${args.now}\n )\n order by wake_at asc, run_id asc, signal_id asc\n limit ${args.limit}\n for update skip locked\n )\n update ${tableSql.timers} timer\n set\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs}\n from due\n where timer.run_id = due.run_id\n and timer.signal_id = due.signal_id\n returning timer.*\n `,\n )\n return rows.map(timerFromRow)\n },\n\n async deliverSignal<TPayload>(\n args: DeliverSignalArgs<TPayload>,\n ): Promise<DeliverSignalResult> {\n return withTransaction(db, async (tx) => {\n const run = await loadRunById(tx, tableSql, args.runId)\n if (!run) return { kind: 'not-found' }\n\n const existingDelivery = await loadSignalDelivery(\n tx,\n tableSql,\n args.runId,\n args.delivery.signalId,\n )\n if (existingDelivery) return { kind: 'duplicate', run }\n\n if (run.waitingFor?.signalName !== args.delivery.name) {\n return { kind: 'not-waiting', run }\n }\n\n const inserted = await insertSignalDelivery(\n tx,\n tableSql,\n args.runId,\n args.delivery.signalId,\n args.now,\n )\n if (!inserted) return { kind: 'duplicate', run }\n\n await tx.execute(sql`\n delete from ${tableSql.timers}\n where run_id = ${args.runId}\n and signal_id = ${args.delivery.signalId}\n `)\n\n const rows = await queryRows<RunRow>(\n tx,\n sql`\n update ${tableSql.runs}\n set\n status = 'queued',\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n returning *\n `,\n )\n\n return { kind: 'delivered', run: runFromRow(rows[0]!) }\n })\n },\n\n async deliverApproval(\n args: DeliverApprovalArgs,\n ): Promise<DeliverApprovalResult> {\n return withTransaction(db, async (tx) => {\n const run = await loadRunById(tx, tableSql, args.runId)\n if (!run) return { kind: 'not-found' }\n\n const signalId = `approval:${args.approval.approvalId}`\n const existingDelivery = await loadSignalDelivery(\n tx,\n tableSql,\n args.runId,\n signalId,\n )\n if (existingDelivery) return { kind: 'duplicate', run }\n\n if (run.pendingApproval?.approvalId !== args.approval.approvalId) {\n return { kind: 'not-waiting', run }\n }\n\n const inserted = await insertSignalDelivery(\n tx,\n tableSql,\n args.runId,\n signalId,\n args.now,\n )\n if (!inserted) return { kind: 'duplicate', run }\n\n const rows = await queryRows<RunRow>(\n tx,\n sql`\n update ${tableSql.runs}\n set\n status = 'queued',\n waiting_for = null,\n pending_approval = null,\n wake_at = null,\n updated_at = ${args.now}\n where run_id = ${args.runId}\n returning *\n `,\n )\n\n return { kind: 'delivered', run: runFromRow(rows[0]!) }\n })\n },\n\n async upsertSchedule(args: UpsertScheduleArgs) {\n await db.execute(sql`\n insert into ${tableSql.schedules} (\n schedule_id,\n workflow_id,\n workflow_version,\n schedule,\n overlap_policy,\n input,\n next_fire_at,\n enabled,\n updated_at\n )\n values (\n ${args.scheduleId},\n ${args.workflowId},\n ${args.workflowVersion ?? null},\n ${encodeJson(args.schedule)}::jsonb,\n ${args.overlapPolicy},\n ${encodeJsonOrNull(args.input)}::jsonb,\n ${args.nextFireAt ?? null},\n ${args.enabled},\n ${args.now}\n )\n on conflict (schedule_id) do update set\n workflow_id = excluded.workflow_id,\n workflow_version = excluded.workflow_version,\n schedule = excluded.schedule,\n overlap_policy = excluded.overlap_policy,\n input = excluded.input,\n next_fire_at = excluded.next_fire_at,\n enabled = excluded.enabled,\n updated_at = excluded.updated_at\n `)\n },\n\n async claimDueScheduleBuckets(args: ClaimDueScheduleBucketsArgs) {\n const schedules = await queryRows<ScheduleRow>(\n db,\n sql`\n select schedule.*\n from ${tableSql.schedules} schedule\n left join ${tableSql.scheduleBuckets} bucket\n on bucket.schedule_id = schedule.schedule_id\n and bucket.bucket_id = schedule.next_fire_at::text\n where schedule.enabled = true\n and schedule.next_fire_at is not null\n and schedule.next_fire_at <= ${args.now}\n and (\n bucket.schedule_id is null\n or (\n bucket.status <> 'started'\n and (\n bucket.lease_owner is null\n or bucket.lease_owner = ${args.leaseOwner}\n or bucket.lease_expires_at <= ${args.now}\n )\n )\n )\n order by schedule.next_fire_at asc, schedule.schedule_id asc\n limit ${args.limit}\n `,\n )\n const buckets: Array<ScheduleBucket> = []\n\n for (const scheduleRow of schedules) {\n if (buckets.length >= args.limit) break\n\n const schedule = scheduleFromRow(scheduleRow)\n const bucketId = `${schedule.nextFireAt}` satisfies ScheduleBucketId\n const runId = `${schedule.workflowId}:${schedule.scheduleId}:${bucketId}`\n\n await db.execute(sql`\n insert into ${tableSql.scheduleBuckets} (\n schedule_id,\n bucket_id,\n workflow_id,\n workflow_version,\n run_id,\n fire_at,\n input,\n overlap_policy,\n status\n )\n values (\n ${schedule.scheduleId},\n ${bucketId},\n ${schedule.workflowId},\n ${schedule.workflowVersion ?? null},\n ${runId},\n ${schedule.nextFireAt},\n ${encodeJsonOrNull(schedule.input)}::jsonb,\n ${schedule.overlapPolicy},\n 'claimed'\n )\n on conflict (schedule_id, bucket_id) do nothing\n `)\n\n const rows = await queryRows<ScheduleBucketRow>(\n db,\n sql`\n update ${tableSql.scheduleBuckets}\n set\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs}\n where schedule_id = ${schedule.scheduleId}\n and bucket_id = ${bucketId}\n and status <> 'started'\n and (\n lease_owner is null\n or lease_owner = ${args.leaseOwner}\n or lease_expires_at <= ${args.now}\n )\n returning *\n `,\n )\n if (rows[0]) buckets.push(scheduleBucketFromRow(rows[0]))\n }\n\n return buckets\n },\n\n async markScheduleBucketStarted(args: MarkScheduleBucketStartedArgs) {\n await db.execute(sql`\n update ${tableSql.scheduleBuckets}\n set\n run_id = ${args.runId},\n status = 'started',\n started_at = ${args.now}\n where schedule_id = ${args.scheduleId}\n and bucket_id = ${args.bucketId}\n `)\n },\n\n async claimStaleRuns(args: ClaimStaleRunsArgs) {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n with stale as (\n select run_id\n from ${tableSql.runs}\n where status = 'running'\n and lease_expires_at is not null\n and lease_expires_at <= ${args.now}\n order by updated_at asc, run_id asc\n limit ${args.limit}\n for update skip locked\n )\n update ${tableSql.runs} run\n set\n lease_owner = ${args.leaseOwner},\n lease_expires_at = ${args.now + args.leaseMs},\n updated_at = ${args.now}\n from stale\n where run.run_id = stale.run_id\n returning run.*\n `,\n )\n\n return rows.map((row): RunClaim => {\n const run = runFromRow(row)\n return { run, lease: run.lease! }\n })\n },\n\n async listRuns(args: ListRunsArgs) {\n const offset = args.cursor ? Number(args.cursor) : 0\n const start = Number.isFinite(offset) && offset > 0 ? offset : 0\n const rows = await queryRows<RunRow>(\n db,\n sql`\n select *\n from ${tableSql.runs}\n where (${args.workflowId ?? null}::text is null or workflow_id = ${args.workflowId ?? null})\n and (${args.status ?? null}::text is null or status = ${args.status ?? null})\n order by updated_at desc, run_id asc\n limit ${args.limit}\n offset ${start}\n `,\n )\n\n return rows.map(toRunSummary)\n },\n\n async getRunTimeline(runId: RunId): Promise<RunTimeline | undefined> {\n const run = await loadRunById(db, tableSql, runId)\n if (!run) return undefined\n return {\n run,\n events: await readStoredEvents(db, tableSql, { runId }),\n }\n },\n }\n}\n\ninterface TableSqls {\n runs: SQL\n runStates: SQL\n eventLocks: SQL\n events: SQL\n timers: SQL\n signalDeliveries: SQL\n schedules: SQL\n scheduleBuckets: SQL\n}\n\ninterface RunRow {\n run_id: string\n workflow_id: string\n workflow_version: string | null\n status: WorkflowExecutionStatus\n input: unknown\n output: unknown\n error: unknown\n waiting_for: unknown\n pending_approval: unknown\n wake_at: number | string | null\n lease_owner: string | null\n lease_expires_at: number | string | null\n created_at: number | string\n updated_at: number | string\n}\n\ninterface RunStateRow {\n run_id: string\n workflow_id: string\n workflow_version: string | null\n status: RunState['status']\n input: unknown\n output: unknown\n error: unknown\n waiting_for: unknown\n pending_approval: unknown\n created_at: number | string\n updated_at: number | string\n}\n\ninterface EventRow {\n run_id: string\n event_index: number | string\n event_type: WorkflowEvent['type']\n step_id: string | null\n event: unknown\n created_at: number | string\n}\n\ninterface TimerRow {\n run_id: string\n workflow_id: string\n workflow_version: string | null\n wake_at: number | string\n signal_id: string\n}\n\ninterface ScheduleRow {\n schedule_id: string\n workflow_id: string\n workflow_version: string | null\n input: unknown\n overlap_policy: ScheduleBucket['overlapPolicy']\n next_fire_at: number | string\n}\n\ninterface ScheduleBucketRow {\n schedule_id: string\n bucket_id: string\n workflow_id: string\n workflow_version: string | null\n run_id: string\n fire_at: number | string\n input: unknown\n overlap_policy: ScheduleBucket['overlapPolicy']\n}\n\nfunction tableSqls(\n schema: string | undefined,\n tables: DrizzlePostgresWorkflowStoreTables,\n): TableSqls {\n return {\n runs: sql.raw(qualifiedTableName(schema, tables.runs)),\n runStates: sql.raw(qualifiedTableName(schema, tables.runStates)),\n eventLocks: sql.raw(qualifiedTableName(schema, tables.eventLocks)),\n events: sql.raw(qualifiedTableName(schema, tables.events)),\n timers: sql.raw(qualifiedTableName(schema, tables.timers)),\n signalDeliveries: sql.raw(\n qualifiedTableName(schema, tables.signalDeliveries),\n ),\n schedules: sql.raw(qualifiedTableName(schema, tables.schedules)),\n scheduleBuckets: sql.raw(\n qualifiedTableName(schema, tables.scheduleBuckets),\n ),\n }\n}\n\nfunction schemaStatements(\n schema: string | undefined,\n tables: DrizzlePostgresWorkflowStoreTables,\n): Array<string> {\n const runs = qualifiedTableName(schema, tables.runs)\n const runStates = qualifiedTableName(schema, tables.runStates)\n const eventLocks = qualifiedTableName(schema, tables.eventLocks)\n const events = qualifiedTableName(schema, tables.events)\n const timers = qualifiedTableName(schema, tables.timers)\n const signalDeliveries = qualifiedTableName(schema, tables.signalDeliveries)\n const schedules = qualifiedTableName(schema, tables.schedules)\n const scheduleBuckets = qualifiedTableName(schema, tables.scheduleBuckets)\n\n return [\n ...(schema ? [`create schema if not exists ${quoteIdent(schema)}`] : []),\n `create table if not exists ${runs} (\n run_id text primary key,\n workflow_id text not null,\n workflow_version text,\n status text not null,\n input jsonb not null,\n output jsonb,\n error jsonb,\n waiting_for jsonb,\n pending_approval jsonb,\n wake_at bigint,\n lease_owner text,\n lease_expires_at bigint,\n created_at bigint not null,\n updated_at bigint not null\n )`,\n `create index if not exists ${quoteIdent(`${tables.runs}_status_idx`)}\n on ${runs} (status, updated_at)`,\n `create index if not exists ${quoteIdent(`${tables.runs}_lease_idx`)}\n on ${runs} (status, lease_expires_at)`,\n `create table if not exists ${runStates} (\n run_id text primary key,\n workflow_id text not null,\n workflow_version text,\n status text not null,\n input jsonb not null,\n output jsonb,\n error jsonb,\n waiting_for jsonb,\n pending_approval jsonb,\n created_at bigint not null,\n updated_at bigint not null\n )`,\n `create table if not exists ${eventLocks} (\n run_id text primary key,\n created_at bigint not null\n )`,\n `create table if not exists ${events} (\n run_id text not null,\n event_index integer not null,\n event_type text not null,\n step_id text,\n event jsonb not null,\n created_at bigint not null,\n primary key (run_id, event_index)\n )`,\n `create index if not exists ${quoteIdent(`${tables.events}_type_idx`)}\n on ${events} (run_id, event_type)`,\n `create table if not exists ${timers} (\n run_id text not null,\n signal_id text not null,\n workflow_id text not null,\n workflow_version text,\n wake_at bigint not null,\n lease_owner text,\n lease_expires_at bigint,\n primary key (run_id, signal_id)\n )`,\n `create index if not exists ${quoteIdent(`${tables.timers}_due_idx`)}\n on ${timers} (wake_at, lease_expires_at)`,\n `create table if not exists ${signalDeliveries} (\n run_id text not null,\n signal_id text not null,\n created_at bigint not null,\n primary key (run_id, signal_id)\n )`,\n `create table if not exists ${schedules} (\n schedule_id text primary key,\n workflow_id text not null,\n workflow_version text,\n schedule jsonb not null,\n overlap_policy text not null,\n input jsonb,\n next_fire_at bigint,\n enabled boolean not null,\n updated_at bigint not null\n )`,\n `create index if not exists ${quoteIdent(`${tables.schedules}_due_idx`)}\n on ${schedules} (enabled, next_fire_at)`,\n `create table if not exists ${scheduleBuckets} (\n schedule_id text not null,\n bucket_id text not null,\n workflow_id text not null,\n workflow_version text,\n run_id text not null,\n fire_at bigint not null,\n input jsonb,\n overlap_policy text not null,\n status text not null,\n lease_owner text,\n lease_expires_at bigint,\n started_at bigint,\n primary key (schedule_id, bucket_id)\n )`,\n `create index if not exists ${quoteIdent(\n `${tables.scheduleBuckets}_lease_idx`,\n )}\n on ${scheduleBuckets} (status, fire_at, lease_expires_at)`,\n ]\n}\n\nasync function loadRunById(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n) {\n const rows = await queryRows<RunRow>(\n db,\n sql`\n select *\n from ${tables.runs}\n where run_id = ${runId}\n limit 1\n `,\n )\n return rows[0] ? runFromRow(rows[0]) : undefined\n}\n\nasync function loadRunStateById(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n): Promise<RunState | undefined> {\n const rows = await queryRows<RunStateRow>(\n db,\n sql`\n select *\n from ${tables.runStates}\n where run_id = ${runId}\n limit 1\n `,\n )\n return rows[0] ? runStateFromRow(rows[0]) : undefined\n}\n\nasync function readStoredEvents(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n args: ReadEventsArgs,\n): Promise<ReadonlyArray<StoredWorkflowEvent>> {\n const rows = await queryRows<EventRow>(\n db,\n sql`\n select *\n from ${tables.events}\n where run_id = ${args.runId}\n and event_index >= ${args.fromIndex ?? 0}\n order by event_index asc\n `,\n )\n return rows.map(eventFromRow)\n}\n\nasync function loadSignalDelivery(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n signalId: string,\n) {\n const rows = await queryRows<{ run_id: string }>(\n db,\n sql`\n select run_id\n from ${tables.signalDeliveries}\n where run_id = ${runId}\n and signal_id = ${signalId}\n limit 1\n `,\n )\n return Boolean(rows[0])\n}\n\nasync function insertSignalDelivery(\n db: DrizzlePostgresDatabase,\n tables: TableSqls,\n runId: RunId,\n signalId: string,\n now: number,\n) {\n const rows = await queryRows<{ run_id: string }>(\n db,\n sql`\n insert into ${tables.signalDeliveries} (run_id, signal_id, created_at)\n values (${runId}, ${signalId}, ${now})\n on conflict (run_id, signal_id) do nothing\n returning run_id\n `,\n )\n return Boolean(rows[0])\n}\n\nasync function withTransaction<TResult>(\n db: DrizzlePostgresDatabase,\n callback: (tx: DrizzlePostgresDatabase) => Promise<TResult>,\n) {\n if (db.transaction) return db.transaction(callback)\n\n await db.execute(sql.raw('begin'))\n try {\n const result = await callback(db)\n await db.execute(sql.raw('commit'))\n return result\n } catch (error) {\n await db.execute(sql.raw('rollback'))\n throw error\n }\n}\n\nasync function queryRows<TRow>(\n db: DrizzlePostgresDatabase,\n query: SQL,\n): Promise<Array<TRow>> {\n const result = await db.execute(query)\n return rowsFromResult<TRow>(result)\n}\n\nfunction rowsFromResult<TRow>(result: unknown): Array<TRow> {\n if (Array.isArray(result)) return result as Array<TRow>\n\n if (isObjectWithRows(result) && Array.isArray(result.rows)) {\n return result.rows as Array<TRow>\n }\n\n return []\n}\n\nfunction isObjectWithRows(value: unknown): value is { rows: unknown } {\n return typeof value === 'object' && value !== null && 'rows' in value\n}\n\nfunction runFromRow(row: RunRow): WorkflowExecution {\n return {\n runId: row.run_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n status: row.status,\n input: decodeJson(row.input),\n output: decodeJsonOrUndefined(row.output),\n error: decodeJsonOrUndefined(row.error),\n waitingFor: decodeJsonOrUndefined(row.waiting_for),\n pendingApproval: decodeJsonOrUndefined(row.pending_approval),\n wakeAt: numberOrUndefined(row.wake_at),\n lease:\n row.lease_owner && row.lease_expires_at !== null\n ? {\n owner: row.lease_owner,\n expiresAt: Number(row.lease_expires_at),\n }\n : undefined,\n createdAt: Number(row.created_at),\n updatedAt: Number(row.updated_at),\n }\n}\n\nfunction runStateFromRow(row: RunStateRow): RunState {\n return {\n runId: row.run_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n status: row.status,\n input: decodeJson(row.input),\n output: decodeJsonOrUndefined(row.output),\n error: decodeJsonOrUndefined(row.error),\n waitingFor: decodeJsonOrUndefined(row.waiting_for),\n pendingApproval: decodeJsonOrUndefined(row.pending_approval),\n createdAt: Number(row.created_at),\n updatedAt: Number(row.updated_at),\n }\n}\n\nfunction eventFromRow(row: EventRow): StoredWorkflowEvent {\n return {\n runId: row.run_id,\n eventIndex: Number(row.event_index),\n eventType: row.event_type,\n stepId: row.step_id ?? undefined,\n event: decodeJson(row.event) as WorkflowEvent,\n createdAt: Number(row.created_at),\n }\n}\n\nfunction timerFromRow(row: TimerRow): TimerWakeup {\n return {\n runId: row.run_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n wakeAt: Number(row.wake_at),\n signalId: row.signal_id,\n }\n}\n\nfunction scheduleFromRow(row: ScheduleRow) {\n return {\n scheduleId: row.schedule_id satisfies ScheduleId,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n input: decodeJsonOrUndefined(row.input),\n overlapPolicy: row.overlap_policy,\n nextFireAt: Number(row.next_fire_at),\n }\n}\n\nfunction scheduleBucketFromRow(row: ScheduleBucketRow): ScheduleBucket {\n return {\n scheduleId: row.schedule_id,\n bucketId: row.bucket_id,\n workflowId: row.workflow_id,\n workflowVersion: row.workflow_version ?? undefined,\n runId: row.run_id,\n fireAt: Number(row.fire_at),\n input: decodeJsonOrUndefined(row.input),\n overlapPolicy: row.overlap_policy,\n }\n}\n\nfunction toRunSummary(row: RunRow): RunSummary {\n const run = runFromRow(row)\n return {\n runId: run.runId,\n workflowId: run.workflowId,\n workflowVersion: run.workflowVersion,\n status: run.status,\n waitingFor: run.waitingFor,\n pendingApproval: run.pendingApproval,\n wakeAt: run.wakeAt,\n createdAt: run.createdAt,\n updatedAt: run.updatedAt,\n }\n}\n\nfunction encodeJson(value: unknown) {\n return JSON.stringify(value ?? null)\n}\n\nfunction encodeJsonOrNull(value: unknown) {\n return value === undefined ? null : JSON.stringify(value)\n}\n\nfunction decodeJson(value: unknown): unknown {\n if (typeof value !== 'string') return value\n try {\n return JSON.parse(value)\n } catch {\n return value\n }\n}\n\nfunction decodeJsonOrUndefined<TValue = unknown>(\n value: unknown,\n): TValue | undefined {\n if (value === null || value === undefined) return undefined\n return decodeJson(value) as TValue\n}\n\nfunction numberOrUndefined(value: number | string | null) {\n return value === null ? undefined : Number(value)\n}\n\nfunction getStepId(event: WorkflowEvent) {\n return 'stepId' in event ? event.stepId : undefined\n}\n\nfunction qualifiedTableName(schema: string | undefined, table: string) {\n return schema\n ? `${quoteIdent(schema)}.${quoteIdent(table)}`\n : quoteIdent(table)\n}\n\nfunction quoteIdent(identifier: string) {\n return `\"${identifier.replaceAll('\"', '\"\"')}\"`\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
package/src/store.ts
CHANGED
|
@@ -650,12 +650,26 @@ export function createDrizzlePostgresWorkflowStore(
|
|
|
650
650
|
const schedules = await queryRows<ScheduleRow>(
|
|
651
651
|
db,
|
|
652
652
|
sql`
|
|
653
|
-
select
|
|
654
|
-
from ${tableSql.schedules}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
and
|
|
658
|
-
|
|
653
|
+
select schedule.*
|
|
654
|
+
from ${tableSql.schedules} schedule
|
|
655
|
+
left join ${tableSql.scheduleBuckets} bucket
|
|
656
|
+
on bucket.schedule_id = schedule.schedule_id
|
|
657
|
+
and bucket.bucket_id = schedule.next_fire_at::text
|
|
658
|
+
where schedule.enabled = true
|
|
659
|
+
and schedule.next_fire_at is not null
|
|
660
|
+
and schedule.next_fire_at <= ${args.now}
|
|
661
|
+
and (
|
|
662
|
+
bucket.schedule_id is null
|
|
663
|
+
or (
|
|
664
|
+
bucket.status <> 'started'
|
|
665
|
+
and (
|
|
666
|
+
bucket.lease_owner is null
|
|
667
|
+
or bucket.lease_owner = ${args.leaseOwner}
|
|
668
|
+
or bucket.lease_expires_at <= ${args.now}
|
|
669
|
+
)
|
|
670
|
+
)
|
|
671
|
+
)
|
|
672
|
+
order by schedule.next_fire_at asc, schedule.schedule_id asc
|
|
659
673
|
limit ${args.limit}
|
|
660
674
|
`,
|
|
661
675
|
)
|