@dudousxd/nestjs-durable-store-drizzle 0.22.0 → 0.23.0
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/index.cjs +11 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +11 -6
- package/dist/index.js.map +1 -1
- package/dist/pg/index.cjs +18 -6
- package/dist/pg/index.cjs.map +1 -1
- package/dist/pg/index.d.cts +2 -2
- package/dist/pg/index.d.ts +2 -2
- package/dist/pg/index.js +18 -6
- package/dist/pg/index.js.map +1 -1
- package/package.json +3 -3
package/dist/pg/index.cjs
CHANGED
|
@@ -349,7 +349,14 @@ function anyOf(conditions) {
|
|
|
349
349
|
}
|
|
350
350
|
__name(anyOf, "anyOf");
|
|
351
351
|
function namespaceFilter(namespace) {
|
|
352
|
-
|
|
352
|
+
if (namespace === void 0) return void 0;
|
|
353
|
+
if (namespace === DEFAULT_NAMESPACE || namespace === "") {
|
|
354
|
+
return (0, import_drizzle_orm4.inArray)(durableWorkflowRuns.namespace, [
|
|
355
|
+
DEFAULT_NAMESPACE,
|
|
356
|
+
""
|
|
357
|
+
]);
|
|
358
|
+
}
|
|
359
|
+
return (0, import_drizzle_orm4.eq)(durableWorkflowRuns.namespace, namespace);
|
|
353
360
|
}
|
|
354
361
|
__name(namespaceFilter, "namespaceFilter");
|
|
355
362
|
function hasTag(tag) {
|
|
@@ -548,12 +555,17 @@ var DrizzlePgStateStore = class _DrizzlePgStateStore {
|
|
|
548
555
|
]), namespaceFilter(namespace), this.scope()));
|
|
549
556
|
return rows.map(fromRunRow);
|
|
550
557
|
}
|
|
551
|
-
async listOrphanedRuns(nowMs, limit, namespace) {
|
|
558
|
+
async listOrphanedRuns(nowMs, limit, namespace, ownedBy) {
|
|
552
559
|
if (limit <= 0) return [];
|
|
553
560
|
const rows = await this.db.select().from(durableWorkflowRuns).where((0, import_drizzle_orm4.and)((0, import_drizzle_orm4.inArray)(durableWorkflowRuns.status, [
|
|
554
561
|
"running",
|
|
555
562
|
"cancelling"
|
|
556
|
-
]), (0, import_drizzle_orm4.or)(
|
|
563
|
+
]), (0, import_drizzle_orm4.or)(
|
|
564
|
+
(0, import_drizzle_orm4.isNull)(durableWorkflowRuns.lockedUntil),
|
|
565
|
+
(0, import_drizzle_orm4.lte)(durableWorkflowRuns.lockedUntil, new Date(nowMs)),
|
|
566
|
+
// A live lease left by a previous process with the caller's own instance id.
|
|
567
|
+
ownedBy ? (0, import_drizzle_orm4.and)((0, import_drizzle_orm4.eq)(durableWorkflowRuns.lockedBy, ownedBy.owner), (0, import_drizzle_orm4.lt)(durableWorkflowRuns.lockedUntil, new Date(ownedBy.lockedBefore))) : void 0
|
|
568
|
+
), namespaceFilter(namespace), this.scope())).orderBy((0, import_drizzle_orm4.asc)(durableWorkflowRuns.createdAt)).limit(limit);
|
|
557
569
|
return rows.map(fromRunRow);
|
|
558
570
|
}
|
|
559
571
|
/** FIFO pick-up, served by `durable_workflow_runs_namespace_status_idx`. The engine then leases
|
|
@@ -971,7 +983,7 @@ function toRunRow(run) {
|
|
|
971
983
|
tags: run.tags ?? null,
|
|
972
984
|
searchAttributes: run.searchAttributes ?? null,
|
|
973
985
|
priority: run.priority ?? null,
|
|
974
|
-
namespace: run.namespace
|
|
986
|
+
namespace: run.namespace || DEFAULT_NAMESPACE,
|
|
975
987
|
origin: run.origin ?? null,
|
|
976
988
|
createdAt: run.createdAt,
|
|
977
989
|
updatedAt: run.updatedAt
|
|
@@ -994,7 +1006,7 @@ function toRunPatch(patch) {
|
|
|
994
1006
|
if ("tags" in patch) row.tags = patch.tags ?? null;
|
|
995
1007
|
if ("searchAttributes" in patch) row.searchAttributes = patch.searchAttributes ?? null;
|
|
996
1008
|
if ("priority" in patch) row.priority = patch.priority ?? null;
|
|
997
|
-
if ("namespace" in patch) row.namespace = patch.namespace
|
|
1009
|
+
if ("namespace" in patch) row.namespace = patch.namespace || DEFAULT_NAMESPACE;
|
|
998
1010
|
if ("origin" in patch) row.origin = patch.origin ?? null;
|
|
999
1011
|
if (patch.createdAt != null) row.createdAt = patch.createdAt;
|
|
1000
1012
|
if (patch.updatedAt != null) row.updatedAt = patch.updatedAt;
|
|
@@ -1018,7 +1030,7 @@ function fromRunRow(row) {
|
|
|
1018
1030
|
tags: row.tags ?? void 0,
|
|
1019
1031
|
searchAttributes: row.searchAttributes ?? void 0,
|
|
1020
1032
|
priority: row.priority ?? void 0,
|
|
1021
|
-
namespace: row.namespace,
|
|
1033
|
+
namespace: row.namespace || DEFAULT_NAMESPACE,
|
|
1022
1034
|
origin: row.origin ?? void 0,
|
|
1023
1035
|
createdAt: row.createdAt,
|
|
1024
1036
|
updatedAt: row.updatedAt
|
package/dist/pg/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pg/index.ts","../../src/pg/ddl.ts","../../src/pg/drizzle-pg-state-store.ts","../../src/pg/executor.ts","../../src/pg/schema.ts"],"sourcesContent":["// `@dudousxd/nestjs-durable-store-drizzle/pg` — the PostgreSQL flavour of the Drizzle store.\n// The package root (`@dudousxd/nestjs-durable-store-drizzle`) stays the SQLite / libSQL store.\nexport * from './ddl';\nexport * from './drizzle-pg-state-store';\nexport * from './executor';\nexport * from './schema';\n","import { sql } from 'drizzle-orm';\nimport type { PgDatabase } from 'drizzle-orm/pg-core';\n\n/**\n * The durable tables as idempotent Postgres DDL — the exact SQL twin of the `pgTable` definitions in\n * `./schema` (same tables, columns, types, defaults, primary keys and index names; a spec pins the two\n * against each other on a real Postgres, so they cannot drift).\n *\n * Every statement is `IF NOT EXISTS`, so the list is safe to run on every boot\n * ({@link ensureDrizzlePgDurableSchema}, which `DrizzlePgStateStore.ensureSchema()` calls when the\n * module's `autoSchema` is on) or to paste into a hand-written migration:\n *\n * ```ts\n * // drizzle/0007_durable.sql — or a custom migration step\n * import { DURABLE_PG_DDL } from '@dudousxd/nestjs-durable-store-drizzle/pg';\n * console.log(DURABLE_PG_DDL.join(';\\n') + ';');\n * ```\n *\n * A column added by a future version is appended here as `ALTER TABLE … ADD COLUMN IF NOT EXISTS`, so\n * an existing database heals on the next boot exactly like the MikroORM / TypeORM auto-schema does.\n */\nexport const DURABLE_PG_DDL: readonly string[] = [\n `CREATE TABLE IF NOT EXISTS \"durable_workflow_runs\" (\n \"id\" text PRIMARY KEY NOT NULL,\n \"workflow\" text NOT NULL,\n \"workflow_version\" text NOT NULL,\n \"status\" text NOT NULL,\n \"input\" jsonb,\n \"output\" jsonb,\n \"error\" jsonb,\n \"wake_at\" timestamp with time zone,\n \"locked_by\" text,\n \"locked_until\" timestamp with time zone,\n \"awaiting_decision_task_id\" text,\n \"recovery_attempts\" integer,\n \"tags\" jsonb,\n \"search_attributes\" jsonb,\n \"priority\" integer,\n \"namespace\" text DEFAULT 'default' NOT NULL,\n \"origin\" text,\n \"created_at\" timestamp with time zone NOT NULL,\n \"updated_at\" timestamp with time zone NOT NULL\n)`,\n `CREATE TABLE IF NOT EXISTS \"durable_step_checkpoints\" (\n \"run_id\" text NOT NULL,\n \"seq\" integer NOT NULL,\n \"name\" text NOT NULL,\n \"kind\" text NOT NULL,\n \"step_id\" text NOT NULL,\n \"status\" text NOT NULL,\n \"input\" jsonb,\n \"output\" jsonb,\n \"error\" jsonb,\n \"events\" jsonb,\n \"attempts\" integer NOT NULL,\n \"worker_group\" text,\n \"parallel_group\" text,\n \"wake_at\" timestamp with time zone,\n \"enqueued_at\" timestamp with time zone,\n \"started_at\" timestamp with time zone NOT NULL,\n \"finished_at\" timestamp with time zone NOT NULL,\n CONSTRAINT \"durable_step_checkpoints_run_id_seq_pk\" PRIMARY KEY(\"run_id\",\"seq\")\n)`,\n `CREATE TABLE IF NOT EXISTS \"durable_run_attributes\" (\n \"run_id\" text NOT NULL,\n \"key\" text NOT NULL,\n \"str_value\" text,\n \"num_value\" double precision,\n CONSTRAINT \"durable_run_attributes_run_id_key_pk\" PRIMARY KEY(\"run_id\",\"key\")\n)`,\n `CREATE TABLE IF NOT EXISTS \"durable_signal_waiters\" (\n \"token\" text PRIMARY KEY NOT NULL,\n \"run_id\" text NOT NULL,\n \"seq\" integer NOT NULL,\n \"parallel_group\" text\n)`,\n `CREATE TABLE IF NOT EXISTS \"durable_buffered_signals\" (\n \"id\" bigserial PRIMARY KEY NOT NULL,\n \"token\" text NOT NULL,\n \"payload\" jsonb\n)`,\n `CREATE TABLE IF NOT EXISTS \"durable_buffered_events\" (\n \"id\" text PRIMARY KEY NOT NULL,\n \"name\" text NOT NULL,\n \"payload\" jsonb,\n \"published_at\" timestamp with time zone NOT NULL\n)`,\n `CREATE TABLE IF NOT EXISTS \"durable_schedules\" (\n \"id\" text PRIMARY KEY NOT NULL,\n \"namespace\" text DEFAULT 'default' NOT NULL,\n \"workflow\" text NOT NULL,\n \"paused\" boolean DEFAULT false NOT NULL,\n \"next_fire_at\" timestamp with time zone,\n \"tags\" jsonb,\n \"spec\" jsonb NOT NULL,\n \"state\" jsonb NOT NULL,\n \"created_at\" timestamp with time zone NOT NULL,\n \"updated_at\" timestamp with time zone NOT NULL\n)`,\n `CREATE INDEX IF NOT EXISTS \"durable_runs_status_idx\" ON \"durable_workflow_runs\" USING btree (\"status\",\"wake_at\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_runs_workflow_status_idx\" ON \"durable_workflow_runs\" USING btree (\"workflow\",\"status\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_workflow_runs_namespace_status_idx\" ON \"durable_workflow_runs\" USING btree (\"namespace\",\"status\",\"created_at\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_runs_tags_gin_idx\" ON \"durable_workflow_runs\" USING gin (\"tags\" jsonb_path_ops)`,\n `CREATE INDEX IF NOT EXISTS \"durable_runs_status_updated_idx\" ON \"durable_workflow_runs\" USING btree (\"status\",\"updated_at\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_step_checkpoints_group_idx\" ON \"durable_step_checkpoints\" USING btree (\"run_id\",\"parallel_group\",\"seq\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_run_attributes_num_idx\" ON \"durable_run_attributes\" USING btree (\"key\",\"num_value\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_run_attributes_str_idx\" ON \"durable_run_attributes\" USING btree (\"key\",\"str_value\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_signal_waiters_run_id_idx\" ON \"durable_signal_waiters\" USING btree (\"run_id\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_buffered_signals_token_idx\" ON \"durable_buffered_signals\" USING btree (\"token\",\"id\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_buffered_events_name_published_at_idx\" ON \"durable_buffered_events\" USING btree (\"name\",\"published_at\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_schedules_due_idx\" ON \"durable_schedules\" USING btree (\"paused\",\"next_fire_at\")`,\n];\n\n/** Key for the transaction-scoped advisory lock that serializes concurrent heals (several pods\n * booting at once would otherwise race `CREATE INDEX IF NOT EXISTS` into a duplicate-key error). */\nconst SCHEMA_LOCK_KEY = 'durable_schema';\n\n/**\n * Idempotently create the durable tables + indexes on `db` (any drizzle Postgres driver). Runs in one\n * transaction under a `pg_advisory_xact_lock`, so N pods booting together heal the schema once and\n * the rest see it done. Only ever touches the `durable_*` tables.\n */\nexport async function ensureDrizzlePgDurableSchema(db: PgDatabase<any, any, any>): Promise<void> {\n await db.transaction(async (tx) => {\n await tx.execute(sql`SELECT pg_advisory_xact_lock(hashtext(${SCHEMA_LOCK_KEY}))`);\n for (const statement of DURABLE_PG_DDL) await tx.execute(sql.raw(statement));\n });\n}\n","import {\n type AttributeFilter,\n type CheckpointNameKind,\n type CheckpointQuery,\n type CheckpointStat,\n type ChildWait,\n RUN_VALUE_FACET_SCAN,\n type RetentionPolicy,\n type RunFacetQuery,\n type RunFacetRow,\n type RunQuery,\n type RunStatus,\n type RunValueAxis,\n type RunValueFacetOptions,\n type RunValueFacetRow,\n SINGLETON_ACTIVE_STATUSES,\n type ScheduleQuery,\n type ScheduleRecord,\n type SignalWaiter,\n type StateStore,\n type StepCheckpoint,\n type StepError,\n type StepEvent,\n type StoreTransaction,\n TERMINAL_RUN_STATUSES,\n type WorkflowRun,\n attributePredicateOperands,\n axisIsRunColumn,\n clearTerminalSingletonAdmission,\n mergeRunFacetRows,\n mergeRunValueFacetRows,\n normalizeAttributeRows,\n parseDuration,\n runValueFacetsFromRuns,\n singletonAdmissionDenialPatch,\n singletonAdmissionTags,\n} from '@dudousxd/nestjs-durable-core';\nimport {\n type SQL,\n type Table,\n and,\n asc,\n desc,\n eq,\n exists,\n getTableColumns,\n gte,\n inArray,\n isNotNull,\n isNull,\n like,\n lt,\n lte,\n notInArray,\n or,\n sql,\n} from 'drizzle-orm';\nimport type { PgDatabase } from 'drizzle-orm/pg-core';\nimport { ensureDrizzlePgDurableSchema } from './ddl';\nimport { rowsOf } from './executor';\nimport {\n DEFAULT_NAMESPACE,\n durableBufferedEvents as bufferedEvents,\n durableBufferedSignals as bufferedSignals,\n durableRunAttributes as runAttributes,\n durableSchedules as schedules,\n durableSignalWaiters as signalWaiters,\n durableStepCheckpoints as stepCheckpoints,\n durableWorkflowRuns as workflowRuns,\n} from './schema';\n\ntype RunRow = typeof workflowRuns.$inferSelect;\ntype RunInsert = typeof workflowRuns.$inferInsert;\ntype CheckpointRow = typeof stepCheckpoints.$inferSelect;\n\n/**\n * Any drizzle Postgres database — `drizzle-orm/node-postgres`, `drizzle-orm/postgres-js`,\n * `drizzle-orm/pglite`, Neon, … — built with or without a relational schema. The store only uses the\n * query builder (never `db.query.*`), so you do not have to register the durable tables on it.\n */\nexport type DrizzlePgDatabase = PgDatabase<any, any, any>;\n\nexport interface DrizzlePgStateStoreOptions {\n /**\n * Confine every RUN read (`getRun`, `listRuns`, facets, and the pending / incomplete / due-timer\n * polls) to one namespace — a tenant-boundary view of the store. Omit for the operator\n * (control-plane) view that sees every namespace. The NestJS module's `scopeReads` option applies\n * this for you via {@link DrizzlePgStateStore.withScope}.\n */\n scope?: { namespace?: string | undefined } | undefined;\n}\n\n/** OR a set of conditions where an EMPTY set means \"matches nothing\" (every plural `RunQuery`\n * predicate's contract) — `or()` of nothing would be dropped by `and()` and match everything. */\nfunction anyOf(conditions: (SQL | undefined)[]): SQL {\n const present = conditions.filter((c): c is SQL => c !== undefined);\n return present.length ? (or(...present) as SQL) : sql`1 = 0`;\n}\n\n/** `undefined` = no restriction (the operator view), never `namespace IS NULL`. The column is\n * NOT NULL DEFAULT 'default', so plain equality is exact. */\nfunction namespaceFilter(namespace: string | undefined): SQL | undefined {\n return namespace === undefined ? undefined : eq(workflowRuns.namespace, namespace);\n}\n\n/** `tags @> '[\"tag\"]'::jsonb` — exact element containment (so `etl` never matches `etl-foo`), and\n * served by the `durable_runs_tags_gin_idx` GIN (`jsonb_path_ops`) index. */\nfunction hasTag(tag: string): SQL {\n return sql`${workflowRuns.tags} @> ${JSON.stringify([tag])}::jsonb`;\n}\n\nconst date = (ms: number | undefined | null): Date | null => (ms == null ? null : new Date(ms));\nconst ms = (d: Date | null): number | undefined => (d == null ? undefined : d.getTime());\n\n/**\n * Drizzle `StateStore` for **PostgreSQL**. Pass any drizzle Postgres db (see {@link DrizzlePgDatabase});\n * the durable tables come from `./schema` (drizzle-kit) or {@link ensureSchema} (auto-schema).\n *\n * Postgres-specific behaviour, beyond the shared contract:\n * - leases (`tryLockRun` / `renewRunLock`) are a single conditional `UPDATE … RETURNING`, so two\n * instances racing for the same run serialize on the row lock and exactly one wins;\n * - `takeSignalWaiter` is one `DELETE … RETURNING` (atomic take), and `takeBufferedSignal` claims the\n * oldest row with `FOR UPDATE SKIP LOCKED`, so concurrent takers each get a DIFFERENT signal\n * instead of blocking or double-delivering;\n * - `pruneTerminalRuns` (retention) selects its batch with `FOR UPDATE SKIP LOCKED`, so several\n * pods sweeping at once split the backlog instead of contending on it;\n * - tag filters are jsonb containment (GIN-indexed) and attribute filters push down as EXISTS\n * probes on the indexed side table.\n */\nexport class DrizzlePgStateStore implements StateStore {\n private readonly scopeNamespace: string | undefined;\n\n constructor(\n private readonly db: DrizzlePgDatabase,\n private readonly options: DrizzlePgStateStoreOptions = {},\n ) {\n this.scopeNamespace = options.scope?.namespace;\n }\n\n /** A store confined to `scope.namespace`, sharing this store's db (no new connection). Used by the\n * NestJS module's `scopeReads`; `{ namespace: undefined }` is the unscoped operator view. */\n withScope(scope: { namespace?: string | undefined }): DrizzlePgStateStore {\n return new DrizzlePgStateStore(this.db, { ...this.options, scope });\n }\n\n /** Idempotent CREATE TABLE / INDEX IF NOT EXISTS under an advisory lock — called on boot when the\n * module's `autoSchema` is on. Turn `autoSchema` off if drizzle-kit owns these tables. */\n async ensureSchema(): Promise<void> {\n await ensureDrizzlePgDurableSchema(this.db);\n }\n\n /** The read-scope predicate on the runs table (undefined when the store is unscoped). */\n private scope(): SQL | undefined {\n return namespaceFilter(this.scopeNamespace);\n }\n\n async tryAdmitSingleton(\n runId: string,\n tag: string,\n workflow: string,\n limit: number,\n retryWakeAt?: number,\n ): Promise<boolean> {\n return this.db.transaction(async (tx) => {\n const where = and(\n eq(workflowRuns.workflow, workflow),\n inArray(workflowRuns.status, SINGLETON_ACTIVE_STATUSES),\n this.scope(),\n );\n await tx.update(workflowRuns).set({ workflow }).where(where);\n const rows = await tx.select().from(workflowRuns).where(where);\n const runs = rows.map(fromRunRow);\n const tags = singletonAdmissionTags(runs, runId, tag, workflow, limit);\n if (!tags) {\n const patch = singletonAdmissionDenialPatch(runs, runId, tag, workflow, retryWakeAt);\n if (patch)\n await tx.update(workflowRuns).set(toRunPatch(patch)).where(eq(workflowRuns.id, runId));\n return false;\n }\n await tx.update(workflowRuns).set({ tags }).where(eq(workflowRuns.id, runId));\n return true;\n });\n }\n\n async createRun(run: WorkflowRun): Promise<void> {\n // One transaction: a run is never visible without its attribute rows (or vice versa).\n await this.db.transaction(async (tx) => {\n await tx.insert(workflowRuns).values(toRunRow(run));\n await reindexAttributes(tx, run.id, run.searchAttributes);\n });\n }\n\n async updateRun(runId: string, inputPatch: Partial<WorkflowRun>): Promise<void> {\n // Writes are unscoped, so preserve tags even when settling a run outside the read scope.\n const patch =\n inputPatch.status && TERMINAL_RUN_STATUSES.includes(inputPatch.status)\n ? await clearTerminalSingletonAdmission(runId, inputPatch, (id) =>\n this.withScope({}).getRun(id),\n )\n : inputPatch;\n const row = toRunPatch(patch);\n const reindex = 'searchAttributes' in patch;\n if (!Object.keys(row).length && !reindex) return;\n await this.db.transaction(async (tx) => {\n // Drizzle throws on `.set({})`; skip the UPDATE when no mapped column changed.\n if (Object.keys(row).length)\n await tx.update(workflowRuns).set(row).where(eq(workflowRuns.id, runId));\n if (reindex) await reindexAttributes(tx, runId, patch.searchAttributes);\n });\n }\n\n async updateRunIf(\n runId: string,\n expectedStatuses: RunStatus[],\n inputPatch: Partial<WorkflowRun>,\n ): Promise<boolean> {\n if (expectedStatuses.length === 0) return false;\n // Writes are unscoped, like updateRun.\n const patch =\n inputPatch.status && TERMINAL_RUN_STATUSES.includes(inputPatch.status)\n ? await clearTerminalSingletonAdmission(runId, inputPatch, (id) =>\n this.withScope({}).getRun(id),\n )\n : inputPatch;\n const row = toRunPatch(patch);\n const reindex = 'searchAttributes' in patch;\n const matches = and(eq(workflowRuns.id, runId), inArray(workflowRuns.status, expectedStatuses));\n return this.db.transaction(async (tx) => {\n // One conditional UPDATE: a writer racing another blocks on the row lock, then re-evaluates\n // the status predicate against the committed row. With no mapped column to write, the compare\n // is a locking read instead.\n const applied = Object.keys(row).length\n ? (await tx.update(workflowRuns).set(row).where(matches).returning({ id: workflowRuns.id }))\n .length === 1\n : (await tx.select({ id: workflowRuns.id }).from(workflowRuns).where(matches).for('update'))\n .length === 1;\n if (applied && reindex) await reindexAttributes(tx, runId, patch.searchAttributes);\n return applied;\n });\n }\n\n async getRun(runId: string): Promise<WorkflowRun | null> {\n const rows = await this.db\n .select()\n .from(workflowRuns)\n .where(and(eq(workflowRuns.id, runId), this.scope()))\n .limit(1);\n return rows[0] ? fromRunRow(rows[0]) : null;\n }\n\n async deleteRun(runId: string): Promise<void> {\n await this.db.transaction(async (tx) => {\n await deleteRunsCascade(tx, [runId]);\n });\n }\n\n async deleteRuns(runIds: string[]): Promise<void> {\n if (runIds.length === 0) return;\n await this.db.transaction(async (tx) => {\n await deleteRunsCascade(tx, runIds);\n });\n }\n\n async pruneTerminalRuns(policy: RetentionPolicy, nowMs: number, limit: number): Promise<number> {\n // Only terminal statuses are ever eligible — a policy naming a live status would race the engine.\n const statuses = policy.statuses.filter((s) => TERMINAL_RUN_STATUSES.includes(s));\n if (statuses.length === 0 || limit <= 0) return 0;\n if (policy.maxAge == null && policy.maxCount == null) return 0;\n // A scoped policy only ever sees (and, for maxCount, counts) the runs its scope matches.\n const scoped = this.runFilters({ ...(policy.scope ?? {}), statuses });\n return this.db.transaction(async (tx) => {\n const ids = new Set<string>();\n if (policy.maxAge != null) {\n const cutoff = new Date(nowMs - parseDuration(policy.maxAge));\n const rows = await tx\n .select({ id: workflowRuns.id })\n .from(workflowRuns)\n .where(and(...scoped, lt(workflowRuns.updatedAt, cutoff)))\n .orderBy(asc(workflowRuns.updatedAt)) // oldest first\n .limit(limit)\n .for('update', { skipLocked: true });\n for (const r of rows) ids.add(r.id);\n }\n if (policy.maxCount != null && ids.size < limit) {\n // Everything past the newest `maxCount` rows of the status set. The kept window is skipped by\n // OFFSET (no row lock there), and only the rows past it are locked for deletion.\n const rows = await tx\n .select({ id: workflowRuns.id })\n .from(workflowRuns)\n .where(and(...scoped))\n .orderBy(desc(workflowRuns.updatedAt), desc(workflowRuns.id))\n .limit(limit)\n .offset(policy.maxCount)\n .for('update', { skipLocked: true });\n for (const r of rows) {\n if (ids.size >= limit) break;\n ids.add(r.id);\n }\n }\n if (ids.size === 0) return 0;\n const idList = [...ids].slice(0, limit);\n await deleteRunsCascade(tx, idList);\n return idList.length;\n });\n }\n\n async getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null> {\n const rows = await this.db\n .select()\n .from(stepCheckpoints)\n .where(and(eq(stepCheckpoints.runId, runId), eq(stepCheckpoints.seq, seq)))\n .limit(1);\n return rows[0] ? fromCheckpointRow(rows[0]) : null;\n }\n\n async saveCheckpoint(checkpoint: StepCheckpoint): Promise<void> {\n await upsertCheckpoint(this.db, checkpoint);\n }\n\n async saveCheckpointIfPending(checkpoint: StepCheckpoint): Promise<boolean> {\n // One conditional UPDATE: a writer racing a settling result blocks on the row lock, then\n // re-evaluates `status = 'pending'` against the committed row and matches nothing. A missing\n // row matches nothing either, so it is never created.\n const { runId, seq, ...set } = toCheckpointRow(checkpoint);\n const rows = await this.db\n .update(stepCheckpoints)\n .set(set)\n .where(\n and(\n eq(stepCheckpoints.runId, runId),\n eq(stepCheckpoints.seq, seq),\n eq(stepCheckpoints.status, 'pending'),\n ),\n )\n .returning({ seq: stepCheckpoints.seq });\n return rows.length === 1;\n }\n\n async saveCheckpointsIfPending(checkpoints: StepCheckpoint[]): Promise<boolean[]> {\n const wrote = checkpoints.map(() => false);\n if (checkpoints.length === 0) return wrote;\n await this.db.transaction(async (tx) => {\n // One statement can only update a row once, so a repeated row goes in a later round, which\n // then compares against the earlier entry's write.\n for (const round of distinctRounds(checkpoints)) {\n for (let at = 0; at < round.length; at += CHECKPOINT_BATCH_ROWS) {\n const chunk = round.slice(at, at + CHECKPOINT_BATCH_ROWS);\n const updated = rowsOf<{ run_id: string; seq: number }>(\n await tx.execute(\n updateIfPendingFrom(chunk.map((i) => checkpoints[i] as StepCheckpoint)),\n ),\n );\n const byKey = new Map(chunk.map((i) => [rowKey(checkpoints[i] as StepCheckpoint), i]));\n for (const row of updated) {\n const i = byKey.get(rowKey({ runId: row.run_id, seq: Number(row.seq) }));\n if (i !== undefined) wrote[i] = true;\n }\n }\n }\n });\n return wrote;\n }\n\n async transaction<T>(work: (tx: StoreTransaction) => Promise<T>): Promise<T> {\n return this.db.transaction(async (tx) =>\n work({ raw: tx, saveCheckpoint: (cp) => upsertCheckpoint(tx, cp) }),\n );\n }\n\n /** Crash recovery. Namespace-scoped: a worker re-drives only its own tenant's runs. */\n async listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]> {\n const rows = await this.db\n .select()\n .from(workflowRuns)\n .where(\n and(\n inArray(workflowRuns.status, ['running', 'cancelling']),\n namespaceFilter(namespace),\n this.scope(),\n ),\n );\n return rows.map(fromRunRow);\n }\n\n async listOrphanedRuns(nowMs: number, limit: number, namespace?: string): Promise<WorkflowRun[]> {\n if (limit <= 0) return [];\n const rows = await this.db\n .select()\n .from(workflowRuns)\n .where(\n and(\n inArray(workflowRuns.status, ['running', 'cancelling']),\n or(isNull(workflowRuns.lockedUntil), lte(workflowRuns.lockedUntil, new Date(nowMs))),\n namespaceFilter(namespace),\n this.scope(),\n ),\n )\n .orderBy(asc(workflowRuns.createdAt))\n .limit(limit);\n return rows.map(fromRunRow);\n }\n\n /** FIFO pick-up, served by `durable_workflow_runs_namespace_status_idx`. The engine then leases\n * each run with {@link tryLockRun}; the listing itself takes no locks (it runs outside a tx). */\n async listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]> {\n const rows = await this.db\n .select()\n .from(workflowRuns)\n .where(and(eq(workflowRuns.status, 'pending'), namespaceFilter(namespace), this.scope()))\n .orderBy(asc(workflowRuns.createdAt))\n .limit(limit);\n return rows.map(fromRunRow);\n }\n\n async listDueTimers(nowMs: number, namespace?: string, limit?: number): Promise<WorkflowRun[]> {\n const query = this.db\n .select()\n .from(workflowRuns)\n .where(\n and(\n eq(workflowRuns.status, 'suspended'),\n isNotNull(workflowRuns.wakeAt),\n lte(workflowRuns.wakeAt, new Date(nowMs)),\n namespaceFilter(namespace),\n this.scope(),\n ),\n )\n .orderBy(asc(workflowRuns.wakeAt));\n const rows = limit !== undefined ? await query.limit(limit) : await query;\n return rows.map(fromRunRow);\n }\n\n async tryLockRun(\n runId: string,\n owner: string,\n leaseUntilMs: number,\n nowMs: number,\n ): Promise<boolean> {\n // One conditional UPDATE: under READ COMMITTED a concurrent contender blocks on the row lock,\n // then re-evaluates the WHERE against the winner's committed row and matches nothing.\n const rows = await this.db\n .update(workflowRuns)\n .set({ lockedBy: owner, lockedUntil: new Date(leaseUntilMs) })\n .where(\n and(\n eq(workflowRuns.id, runId),\n or(isNull(workflowRuns.lockedUntil), lte(workflowRuns.lockedUntil, new Date(nowMs))),\n ),\n )\n .returning({ id: workflowRuns.id });\n return rows.length === 1;\n }\n\n async releaseRunLock(runId: string): Promise<void> {\n await this.db\n .update(workflowRuns)\n .set({ lockedBy: null, lockedUntil: null })\n .where(eq(workflowRuns.id, runId));\n }\n\n async renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean> {\n const rows = await this.db\n .update(workflowRuns)\n .set({ lockedUntil: new Date(leaseUntilMs) })\n .where(and(eq(workflowRuns.id, runId), eq(workflowRuns.lockedBy, owner)))\n .returning({ id: workflowRuns.id });\n return rows.length === 1;\n }\n\n /** The predicates every run query shares — {@link listRuns} pages them, the facets group them. */\n private runFilters(query: RunQuery): SQL[] {\n return [\n this.scope(),\n query.workflow ? eq(workflowRuns.workflow, query.workflow) : undefined,\n query.workflows\n ? query.workflows.length\n ? inArray(workflowRuns.workflow, query.workflows)\n : sql`1 = 0`\n : undefined,\n // The tenant boundary. Also the engine's execution-timeout sweep path\n // (`listRuns({ workflow, status, namespace })`) — unscoped, it would cancel another tenant's runs.\n namespaceFilter(query.namespace),\n query.namespaces\n ? query.namespaces.length\n ? inArray(workflowRuns.namespace, query.namespaces)\n : sql`1 = 0`\n : undefined,\n // `null` selects the unattributed bucket; a value never matches a NULL origin.\n query.origin === null\n ? isNull(workflowRuns.origin)\n : query.origin !== undefined\n ? eq(workflowRuns.origin, query.origin)\n : undefined,\n query.origins\n ? anyOf(\n query.origins.map((o) =>\n o === null ? isNull(workflowRuns.origin) : eq(workflowRuns.origin, o),\n ),\n )\n : undefined,\n query.status ? eq(workflowRuns.status, query.status) : undefined,\n query.statuses\n ? query.statuses.length\n ? inArray(workflowRuns.status, query.statuses)\n : sql`1 = 0`\n : undefined,\n query.tag ? hasTag(query.tag) : undefined,\n query.tags ? anyOf(query.tags.map(hasTag)) : undefined,\n // One EXISTS per attribute predicate against the normalized side table (ANDed).\n ...(query.attributes?.map((f) => this.attributeExists(f)) ?? []),\n ].filter((f): f is SQL => f !== undefined);\n }\n\n async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n const filters = this.runFilters(query);\n const base = this.db\n .select()\n .from(workflowRuns)\n .where(filters.length ? and(...filters) : undefined)\n // newest first; id breaks created_at ties so limit/offset pages are stable\n .orderBy(desc(workflowRuns.createdAt), desc(workflowRuns.id))\n .$dynamic();\n if (query.limit != null) base.limit(query.limit);\n if (query.offset != null) base.offset(query.offset);\n const rows = await base;\n return rows.map(fromRunRow);\n }\n\n async countRuns(query: Omit<RunQuery, 'limit' | 'offset'>): Promise<number> {\n const filters = this.runFilters(query);\n const rows = await this.db\n .select({ count: sql<number>`count(*)`.mapWith(Number) })\n .from(workflowRuns)\n .where(filters.length ? and(...filters) : undefined);\n return rows[0]?.count ?? 0;\n }\n\n async runFacets(query: RunFacetQuery): Promise<RunFacetRow[]> {\n const filters = this.runFilters(query);\n const rows = await this.db\n .select({\n status: workflowRuns.status,\n origin: workflowRuns.origin,\n count: sql<number>`count(*)`.mapWith(Number),\n })\n .from(workflowRuns)\n .where(filters.length ? and(...filters) : undefined)\n .groupBy(workflowRuns.status, workflowRuns.origin);\n return mergeRunFacetRows(\n rows.map((r) => ({ status: r.status as RunStatus, origin: r.origin, count: r.count })),\n );\n }\n\n /** Run-table axes are an exact `GROUP BY`; the tag / attribute axes are counted over a bounded\n * page of runs (see `RunValueFacetOptions.scan`), like the TypeORM and SQLite Drizzle adapters. */\n async runValueFacets(\n axis: RunValueAxis,\n query: RunFacetQuery,\n opts?: RunValueFacetOptions,\n ): Promise<RunValueFacetRow[]> {\n if (!axisIsRunColumn(axis)) {\n const runs = await this.listRuns({ ...query, limit: opts?.scan ?? RUN_VALUE_FACET_SCAN });\n return runValueFacetsFromRuns(runs, axis, opts);\n }\n const column = workflowRuns[axis.field];\n const filters = this.runFilters(query);\n const rows = await this.db\n .select({ value: column, count: sql<number>`count(*)`.mapWith(Number) })\n .from(workflowRuns)\n .where(filters.length ? and(...filters) : undefined)\n .groupBy(column);\n return mergeRunValueFacetRows(\n rows.map((r) => ({ value: (r.value as string | null) ?? null, count: r.count })),\n opts,\n );\n }\n\n /** One attribute predicate as an EXISTS on the side table, correlated to the outer run. `ne` also\n * excludes runs lacking the key (EXISTS requires the row). Numbers compare `num_value`, strings\n * and booleans `str_value`; an `in` set ORs its members inside the one EXISTS. */\n private attributeExists(f: AttributeFilter): SQL {\n const comparisons = attributePredicateOperands(f).map(\n ({ column, comparator, operand }) =>\n sql`${column === 'numValue' ? runAttributes.numValue : runAttributes.strValue} ${sql.raw(comparator)} ${operand}`,\n );\n return exists(\n this.db\n .select({ one: sql`1` })\n .from(runAttributes)\n .where(\n and(\n eq(runAttributes.runId, workflowRuns.id),\n eq(runAttributes.key, f.key),\n anyOf(comparisons),\n ),\n ),\n );\n }\n\n // ---- persisted schedules ----------------------------------------------------------------------\n\n async saveSchedule(record: ScheduleRecord): Promise<void> {\n const row = toScheduleRow(record);\n await this.db\n .insert(schedules)\n .values(row)\n .onConflictDoUpdate({ target: schedules.id, set: row });\n }\n\n async getSchedule(id: string): Promise<ScheduleRecord | null> {\n const rows = await this.db.select().from(schedules).where(eq(schedules.id, id)).limit(1);\n return rows[0] ? fromScheduleRow(rows[0]) : null;\n }\n\n /** A single conditional `UPDATE … RETURNING`: the compare-and-set on `next_fire_at` is atomic. */\n async updateSchedule(\n id: string,\n patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>,\n expectedNextFireAt?: number | null,\n ): Promise<boolean> {\n const set = toSchedulePatch(patch);\n if (!Object.keys(set).length) return (await this.getSchedule(id)) !== null;\n const rows = await this.db\n .update(schedules)\n .set(set)\n .where(\n and(\n eq(schedules.id, id),\n expectedNextFireAt === undefined\n ? undefined\n : expectedNextFireAt === null\n ? isNull(schedules.nextFireAt)\n : eq(schedules.nextFireAt, new Date(expectedNextFireAt)),\n ),\n )\n .returning({ id: schedules.id });\n return rows.length > 0;\n }\n\n async deleteSchedule(id: string): Promise<boolean> {\n const rows = await this.db\n .delete(schedules)\n .where(eq(schedules.id, id))\n .returning({ id: schedules.id });\n return rows.length > 0;\n }\n\n async listSchedules(query: ScheduleQuery): Promise<ScheduleRecord[]> {\n const base = this.db\n .select()\n .from(schedules)\n .where(\n and(\n query.namespace !== undefined ? eq(schedules.namespace, query.namespace) : undefined,\n query.workflow !== undefined ? eq(schedules.workflow, query.workflow) : undefined,\n query.paused !== undefined ? eq(schedules.paused, query.paused) : undefined,\n query.tag !== undefined\n ? sql`${schedules.tags} @> ${JSON.stringify([query.tag])}::jsonb`\n : undefined,\n query.dueBy !== undefined\n ? and(eq(schedules.paused, false), lte(schedules.nextFireAt, new Date(query.dueBy)))\n : undefined,\n ),\n )\n // Soonest-due first, never-firing (NULL) last, id as the stable tie-break.\n .orderBy(sql`${schedules.nextFireAt} ASC NULLS LAST`, asc(schedules.id))\n .$dynamic();\n if (query.limit != null) base.limit(query.limit);\n if (query.offset != null) base.offset(query.offset);\n return (await base).map(fromScheduleRow);\n }\n\n async listCheckpoints(runId: string): Promise<StepCheckpoint[]> {\n const rows = await this.db\n .select()\n .from(stepCheckpoints)\n .where(eq(stepCheckpoints.runId, runId))\n .orderBy(asc(stepCheckpoints.seq));\n return rows.map(fromCheckpointRow);\n }\n\n async getLatestCheckpointByName(\n runId: string,\n name: string,\n ): Promise<StepCheckpoint | undefined> {\n const rows = await this.db\n .select()\n .from(stepCheckpoints)\n .where(and(eq(stepCheckpoints.runId, runId), eq(stepCheckpoints.name, name)))\n .orderBy(desc(stepCheckpoints.seq))\n .limit(1);\n return rows[0] ? fromCheckpointRow(rows[0]) : undefined;\n }\n\n async countCheckpoints(\n runId: string,\n fromSeq: number,\n toSeq: number,\n statuses: StepCheckpoint['status'][],\n ): Promise<number> {\n if (statuses.length === 0) return 0;\n const rows = await this.db\n .select({ count: sql<number>`count(*)`.mapWith(Number) })\n .from(stepCheckpoints)\n .where(\n and(\n eq(stepCheckpoints.runId, runId),\n gte(stepCheckpoints.seq, fromSeq),\n lte(stepCheckpoints.seq, toSeq),\n inArray(stepCheckpoints.status, statuses),\n ),\n );\n return rows[0]?.count ?? 0;\n }\n\n async listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]> {\n if (prefixes.length === 0) return [];\n const rows = await this.db\n .select()\n .from(stepCheckpoints)\n .where(\n and(\n eq(stepCheckpoints.runId, runId),\n or(...prefixes.map((p) => like(stepCheckpoints.name, `${escapeLike(p)}%`))),\n ),\n )\n .orderBy(asc(stepCheckpoints.seq));\n return rows.map(fromCheckpointRow);\n }\n\n /** {@link StateStore.checkpointStats}: one `GROUP BY parallel_group, status, name_kind` over the\n * run's checkpoints, so a wide fan comes back as a few bucket rows instead of every member. */\n async checkpointStats(\n runId: string,\n opts?: { group?: string | undefined },\n ): Promise<CheckpointStat[]> {\n const c = stepCheckpoints;\n const nameKind = sql<CheckpointNameKind>`CASE\n WHEN ${c.name} LIKE 'signal:child:%' THEN 'child'\n WHEN ${c.name} LIKE 'fan:%' THEN 'folded'\n WHEN ${c.name} LIKE 'spawn:%' THEN 'spawn'\n ELSE 'step' END`.as('name_kind');\n // Aggregates come back raw from the driver (count/sum as bigint strings, timestamps unparsed);\n // `mapWith` a column decodes them as that column's rows are decoded.\n const rows = await this.db\n .select({\n group: c.parallelGroup,\n status: c.status,\n nameKind,\n count: sql<number>`count(*)`.mapWith(Number),\n minSeq: sql<number>`min(${c.seq})`.mapWith(Number),\n maxSeq: sql<number>`max(${c.seq})`.mapWith(Number),\n minName: sql<string>`min(${c.name})`,\n maxName: sql<string>`max(${c.name})`,\n minEnqueuedAt: sql<Date>`min(coalesce(${c.enqueuedAt}, ${c.startedAt}))`.mapWith(\n c.startedAt,\n ),\n minStartedAt: sql<Date>`min(${c.startedAt})`.mapWith(c.startedAt),\n maxStartedAt: sql<Date>`max(${c.startedAt})`.mapWith(c.startedAt),\n maxFinishedAt: sql<Date>`max(${c.finishedAt})`.mapWith(c.finishedAt),\n sumAttempts: sql<number>`sum(${c.attempts})`.mapWith(Number),\n })\n .from(c)\n .where(\n and(\n eq(c.runId, runId),\n opts?.group !== undefined ? eq(c.parallelGroup, opts.group) : undefined,\n ),\n )\n .groupBy(c.parallelGroup, c.status, sql`name_kind`);\n return rows.map((r) => ({\n ...r,\n group: r.group ?? null,\n status: r.status as StepCheckpoint['status'],\n }));\n }\n\n /** {@link StateStore.queryCheckpoints}: the run's checkpoints narrowed in SQL, in `seq` order and\n * paged there, so reading one page of a wide fan never loads the rest of it. */\n async queryCheckpoints(runId: string, query: CheckpointQuery): Promise<StepCheckpoint[]> {\n if (query.statuses?.length === 0 || query.namePrefixes?.length === 0) return [];\n const c = stepCheckpoints;\n const base = this.db\n .select()\n .from(c)\n .where(\n and(\n eq(c.runId, runId),\n query.group !== undefined ? eq(c.parallelGroup, query.group) : undefined,\n // `NOT IN` is never true for a NULL group, so ungrouped rows are kept explicitly.\n query.excludeGroups?.length\n ? or(isNull(c.parallelGroup), notInArray(c.parallelGroup, query.excludeGroups))\n : undefined,\n query.statuses ? inArray(c.status, query.statuses) : undefined,\n query.namePrefixes\n ? or(...query.namePrefixes.map((p) => like(c.name, `${escapeLike(p)}%`)))\n : undefined,\n ),\n )\n .orderBy(asc(c.seq))\n .$dynamic();\n if (query.limit != null) base.limit(query.limit);\n if (query.offset != null) base.offset(query.offset);\n return (await base).map(fromCheckpointRow);\n }\n\n async putSignalWaiter(waiter: SignalWaiter): Promise<void> {\n const set = {\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n };\n await this.db\n .insert(signalWaiters)\n .values({ token: waiter.token, ...set })\n .onConflictDoUpdate({ target: signalWaiters.token, set });\n }\n\n async takeSignalWaiter(token: string): Promise<SignalWaiter | null> {\n // Atomic take: one DELETE … RETURNING, so two concurrent signals for the same token can never\n // both resume the run.\n const rows = await this.db\n .delete(signalWaiters)\n .where(eq(signalWaiters.token, token))\n .returning();\n const row = rows[0];\n return row ? fromWaiterRow(row) : null;\n }\n\n async listSignalWaiters(prefix: string): Promise<SignalWaiter[]> {\n const rows = await this.db\n .select()\n .from(signalWaiters)\n .where(like(signalWaiters.token, `${escapeLike(prefix)}%`));\n return rows.map(fromWaiterRow);\n }\n\n async registerChildWaits(entries: ChildWait[]): Promise<void> {\n if (entries.length === 0) return;\n await this.db.transaction(async (tx) => {\n await tx\n .insert(signalWaiters)\n .values(\n entries.map(({ waiter }) => ({\n token: waiter.token,\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n })),\n )\n .onConflictDoUpdate({\n target: signalWaiters.token,\n set: excludedSet(signalWaiters, ['runId', 'seq', 'parallelGroup']),\n });\n await tx\n .insert(stepCheckpoints)\n .values(entries.map(({ checkpoint }) => toCheckpointRow(checkpoint)))\n .onConflictDoUpdate({\n target: [stepCheckpoints.runId, stepCheckpoints.seq],\n set: excludedSet(stepCheckpoints),\n });\n });\n }\n\n async compactCheckpoints(\n runId: string,\n fromSeq: number,\n toSeq: number,\n into: StepCheckpoint,\n ): Promise<void> {\n await this.db.transaction(async (tx) => {\n await tx\n .delete(stepCheckpoints)\n .where(\n and(\n eq(stepCheckpoints.runId, runId),\n gte(stepCheckpoints.seq, fromSeq),\n lte(stepCheckpoints.seq, toSeq),\n ),\n );\n await upsertCheckpoint(tx, into);\n });\n }\n\n async listSignalWaitersByRun(runIds: string[]): Promise<SignalWaiter[]> {\n if (runIds.length === 0) return [];\n const rows = await this.db\n .select()\n .from(signalWaiters)\n .where(inArray(signalWaiters.runId, runIds));\n return rows.map(fromWaiterRow);\n }\n\n async hasSignalWaiter(runId: string, tokenPrefix: string): Promise<boolean> {\n const rows = await this.db\n .select({ token: signalWaiters.token })\n .from(signalWaiters)\n .where(\n and(\n eq(signalWaiters.runId, runId),\n like(signalWaiters.token, `${escapeLike(tokenPrefix)}%`),\n ),\n )\n .limit(1);\n return rows.length > 0;\n }\n\n async removeSignalWaiter(waiter: SignalWaiter): Promise<void> {\n // Exact match — never remove a row a DIFFERENT run has since claimed the token with.\n await this.db\n .delete(signalWaiters)\n .where(\n and(\n eq(signalWaiters.token, waiter.token),\n eq(signalWaiters.runId, waiter.runId),\n eq(signalWaiters.seq, waiter.seq),\n ),\n );\n }\n\n async bufferSignal(token: string, payload: unknown): Promise<void> {\n await this.db.insert(bufferedSignals).values({ token, payload: payload ?? null });\n }\n\n async takeBufferedSignal(token: string): Promise<{ payload: unknown } | null> {\n // Claim the oldest buffered signal for `token` with SKIP LOCKED and delete it in the same\n // statement: concurrent takers each get a different row (FIFO), none blocks, none double-reads.\n const oldest = this.db\n .select({ id: bufferedSignals.id })\n .from(bufferedSignals)\n .where(eq(bufferedSignals.token, token))\n .orderBy(asc(bufferedSignals.id))\n .limit(1)\n .for('update', { skipLocked: true });\n const rows = await this.db\n .delete(bufferedSignals)\n .where(inArray(bufferedSignals.id, oldest))\n .returning({ payload: bufferedSignals.payload });\n const row = rows[0];\n return row ? { payload: row.payload ?? undefined } : null;\n }\n\n async bufferEvent(input: {\n name: string;\n payload: unknown;\n id: string;\n publishedAt: number;\n }): Promise<void> {\n await this.db.insert(bufferedEvents).values({\n id: input.id,\n name: input.name,\n payload: input.payload ?? null,\n publishedAt: new Date(input.publishedAt),\n });\n }\n\n async listBufferedEvents(\n name: string,\n limit: number,\n ): Promise<Array<{ id: string; payload: unknown; publishedAt: number }>> {\n const rows = await this.db\n .select()\n .from(bufferedEvents)\n .where(eq(bufferedEvents.name, name))\n .orderBy(asc(bufferedEvents.publishedAt), asc(bufferedEvents.id))\n .limit(limit);\n return rows.map((r) => ({\n id: r.id,\n payload: r.payload ?? undefined,\n publishedAt: r.publishedAt.getTime(),\n }));\n }\n\n async removeBufferedEvent(id: string): Promise<boolean> {\n const rows = await this.db\n .delete(bufferedEvents)\n .where(eq(bufferedEvents.id, id))\n .returning({ id: bufferedEvents.id });\n return rows.length === 1;\n }\n}\n\n/** Escape LIKE metacharacters so a literal prefix (`event:50%_off`) matches only itself. */\nfunction escapeLike(value: string): string {\n return value.replace(/[\\\\%_]/g, (c) => `\\\\${c}`);\n}\n\n/** Rows per `UPDATE … FROM (VALUES …)`: 17 parameters each, well under Postgres's 65535. */\nconst CHECKPOINT_BATCH_ROWS = 500;\n\nconst rowKey = (cp: { runId: string; seq: number }): string => `${cp.seq}:${cp.runId}`;\n\n/** Indexes of `checkpoints` split into rounds that each name a row at most once, in input order. */\nfunction distinctRounds(checkpoints: StepCheckpoint[]): number[][] {\n const rounds: number[][] = [];\n const seen = new Map<string, number>();\n checkpoints.forEach((cp, i) => {\n const key = rowKey(cp);\n const round = seen.get(key) ?? 0;\n seen.set(key, round + 1);\n const indexes = rounds[round] ?? [];\n rounds[round] = indexes;\n indexes.push(i);\n });\n return rounds;\n}\n\n/**\n * `saveCheckpointIfPending` for many rows in one statement: each `VALUES` row overwrites its\n * checkpoint only while that row is still `pending` (a concurrent writer blocks on the row lock,\n * then re-evaluates the predicate against the committed row), and `RETURNING` names the rows that\n * were written. The rows must be distinct.\n */\nfunction updateIfPendingFrom(checkpoints: StepCheckpoint[]): SQL {\n const json = (v: unknown) => (v == null ? null : JSON.stringify(v));\n const ts = (v: Date | null) => (v == null ? null : v.toISOString());\n const values = checkpoints.map((cp) => {\n const r = toCheckpointRow(cp);\n return sql`(${r.runId}::text, ${r.seq}::integer, ${r.name}::text, ${r.kind}::text, ${r.stepId}::text, ${r.status}::text, ${json(r.input)}::jsonb, ${json(r.output)}::jsonb, ${json(r.error)}::jsonb, ${json(r.events)}::jsonb, ${r.attempts}::integer, ${r.workerGroup}::text, ${r.parallelGroup}::text, ${ts(r.wakeAt)}::timestamptz, ${ts(r.enqueuedAt)}::timestamptz, ${ts(r.startedAt)}::timestamptz, ${ts(r.finishedAt)}::timestamptz)`;\n });\n return sql`UPDATE ${stepCheckpoints} AS c SET\n name = v.name, kind = v.kind, step_id = v.step_id, status = v.status, input = v.input,\n output = v.output, error = v.error, events = v.events, attempts = v.attempts,\n worker_group = v.worker_group, parallel_group = v.parallel_group, wake_at = v.wake_at,\n enqueued_at = v.enqueued_at, started_at = v.started_at, finished_at = v.finished_at\n FROM (VALUES ${sql.join(values, sql`, `)}) AS v(run_id, seq, name, kind, step_id, status, input,\n output, error, events, attempts, worker_group, parallel_group, wake_at, enqueued_at, started_at,\n finished_at)\n WHERE c.run_id = v.run_id AND c.seq = v.seq AND c.status = 'pending'\n RETURNING c.run_id, c.seq`;\n}\n\nasync function upsertCheckpoint(db: DrizzlePgDatabase, cp: StepCheckpoint): Promise<void> {\n const row = toCheckpointRow(cp);\n await db\n .insert(stepCheckpoints)\n .values(row)\n .onConflictDoUpdate({ target: [stepCheckpoints.runId, stepCheckpoints.seq], set: row });\n}\n\n/** Rewrite a run's normalized attribute rows so the side table mirrors its live searchAttributes. */\nasync function reindexAttributes(\n db: DrizzlePgDatabase,\n runId: string,\n attributes: WorkflowRun['searchAttributes'],\n): Promise<void> {\n await db.delete(runAttributes).where(eq(runAttributes.runId, runId));\n const rows = normalizeAttributeRows(runId, attributes);\n if (rows.length) await db.insert(runAttributes).values(rows);\n}\n\n/** Children first, then the runs — checkpoints, waiters, attribute rows. Call inside a tx. */\nasync function deleteRunsCascade(db: DrizzlePgDatabase, runIds: string[]): Promise<void> {\n await db.delete(stepCheckpoints).where(inArray(stepCheckpoints.runId, runIds));\n await db.delete(signalWaiters).where(inArray(signalWaiters.runId, runIds));\n await db.delete(runAttributes).where(inArray(runAttributes.runId, runIds));\n await db.delete(workflowRuns).where(inArray(workflowRuns.id, runIds));\n}\n\nfunction fromWaiterRow(row: typeof signalWaiters.$inferSelect): SignalWaiter {\n return {\n token: row.token,\n runId: row.runId,\n seq: row.seq,\n parallelGroup: row.parallelGroup ?? undefined,\n };\n}\n\nfunction toRunRow(run: WorkflowRun): RunInsert {\n return {\n id: run.id,\n workflow: run.workflow,\n workflowVersion: run.workflowVersion,\n status: run.status,\n input: run.input ?? null,\n output: run.output ?? null,\n error: run.error ?? null,\n wakeAt: date(run.wakeAt),\n lockedBy: run.lockedBy ?? null,\n lockedUntil: date(run.lockedUntil),\n awaitingDecisionTaskId: run.awaitingDecisionTaskId ?? null,\n recoveryAttempts: run.recoveryAttempts ?? null,\n tags: run.tags ?? null,\n searchAttributes: run.searchAttributes ?? null,\n priority: run.priority ?? null,\n namespace: run.namespace ?? DEFAULT_NAMESPACE,\n origin: run.origin ?? null,\n createdAt: run.createdAt,\n updatedAt: run.updatedAt,\n };\n}\n\n/** Presence (`'x' in patch`) semantics, so a patch can CLEAR a nullable column (`{ error: undefined }`\n * → NULL), matching the other adapters and the in-memory reference store. */\nfunction toRunPatch(patch: Partial<WorkflowRun>): Partial<RunInsert> {\n const row: Partial<RunInsert> = {};\n if (patch.workflow !== undefined) row.workflow = patch.workflow;\n if (patch.workflowVersion !== undefined) row.workflowVersion = patch.workflowVersion;\n if (patch.status !== undefined) row.status = patch.status;\n if ('input' in patch) row.input = patch.input ?? null;\n if ('output' in patch) row.output = patch.output ?? null;\n if ('error' in patch) row.error = patch.error ?? null;\n if ('wakeAt' in patch) row.wakeAt = date(patch.wakeAt);\n if ('lockedBy' in patch) row.lockedBy = patch.lockedBy ?? null;\n if ('lockedUntil' in patch) row.lockedUntil = date(patch.lockedUntil);\n if ('awaitingDecisionTaskId' in patch)\n row.awaitingDecisionTaskId = patch.awaitingDecisionTaskId ?? null;\n if ('recoveryAttempts' in patch) row.recoveryAttempts = patch.recoveryAttempts ?? null;\n if ('tags' in patch) row.tags = patch.tags ?? null;\n if ('searchAttributes' in patch) row.searchAttributes = patch.searchAttributes ?? null;\n if ('priority' in patch) row.priority = patch.priority ?? null;\n // Never cleared to NULL: an undefined namespace means the default one.\n if ('namespace' in patch) row.namespace = patch.namespace ?? DEFAULT_NAMESPACE;\n if ('origin' in patch) row.origin = patch.origin ?? null;\n if (patch.createdAt != null) row.createdAt = patch.createdAt;\n if (patch.updatedAt != null) row.updatedAt = patch.updatedAt;\n return row;\n}\n\nfunction fromRunRow(row: RunRow): WorkflowRun {\n return {\n id: row.id,\n workflow: row.workflow,\n workflowVersion: row.workflowVersion,\n status: row.status as RunStatus,\n input: row.input ?? undefined,\n output: row.output ?? undefined,\n error: (row.error ?? undefined) as StepError | undefined,\n wakeAt: ms(row.wakeAt),\n lockedBy: row.lockedBy ?? undefined,\n lockedUntil: ms(row.lockedUntil),\n awaitingDecisionTaskId: row.awaitingDecisionTaskId ?? undefined,\n recoveryAttempts: row.recoveryAttempts ?? undefined,\n tags: row.tags ?? undefined,\n searchAttributes: row.searchAttributes ?? undefined,\n priority: row.priority ?? undefined,\n namespace: row.namespace,\n origin: row.origin ?? undefined,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\nfunction toCheckpointRow(cp: StepCheckpoint): CheckpointRow {\n return {\n runId: cp.runId,\n seq: cp.seq,\n name: cp.name,\n kind: cp.kind,\n stepId: cp.stepId,\n status: cp.status,\n input: cp.input ?? null,\n output: cp.output ?? null,\n error: cp.error ?? null,\n events: cp.events ?? null,\n attempts: cp.attempts,\n workerGroup: cp.workerGroup ?? null,\n parallelGroup: cp.parallelGroup ?? null,\n wakeAt: date(cp.wakeAt),\n enqueuedAt: cp.enqueuedAt ?? cp.startedAt,\n startedAt: cp.startedAt,\n finishedAt: cp.finishedAt,\n };\n}\n\nfunction fromCheckpointRow(row: CheckpointRow): StepCheckpoint {\n return {\n runId: row.runId,\n seq: row.seq,\n name: row.name,\n kind: row.kind as StepCheckpoint['kind'],\n stepId: row.stepId,\n status: row.status as StepCheckpoint['status'],\n input: row.input ?? undefined,\n output: row.output ?? undefined,\n error: (row.error ?? undefined) as StepError | undefined,\n events: (row.events ?? undefined) as StepEvent[] | undefined,\n attempts: row.attempts,\n workerGroup: row.workerGroup ?? undefined,\n parallelGroup: row.parallelGroup ?? undefined,\n wakeAt: ms(row.wakeAt),\n // Older rows may lack enqueued_at; treat the start as enqueue time (queue-wait reads zero).\n enqueuedAt: row.enqueuedAt ?? row.startedAt,\n startedAt: row.startedAt,\n finishedAt: row.finishedAt,\n };\n}\n\ntype ScheduleRow = typeof schedules.$inferSelect;\n\nfunction toScheduleRow(r: ScheduleRecord): ScheduleRow {\n return {\n id: r.id,\n namespace: r.namespace,\n workflow: r.workflow,\n paused: r.paused,\n nextFireAt: r.nextFireAt == null ? null : new Date(r.nextFireAt),\n tags: r.tags ?? null,\n spec: r.spec,\n state: r.state,\n createdAt: r.createdAt,\n updatedAt: r.updatedAt,\n };\n}\n\nfunction toSchedulePatch(\n patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>,\n): Partial<ScheduleRow> {\n const set: Partial<ScheduleRow> = {};\n if (patch.namespace !== undefined) set.namespace = patch.namespace;\n if (patch.workflow !== undefined) set.workflow = patch.workflow;\n if (patch.paused !== undefined) set.paused = patch.paused;\n if ('nextFireAt' in patch)\n set.nextFireAt = patch.nextFireAt == null ? null : new Date(patch.nextFireAt);\n if ('tags' in patch) set.tags = patch.tags ?? null;\n if (patch.spec !== undefined) set.spec = patch.spec;\n if (patch.state !== undefined) set.state = patch.state;\n if (patch.updatedAt !== undefined) set.updatedAt = patch.updatedAt;\n return set;\n}\n\nfunction fromScheduleRow(row: ScheduleRow): ScheduleRecord {\n return {\n id: row.id,\n namespace: row.namespace,\n workflow: row.workflow,\n paused: row.paused,\n nextFireAt: row.nextFireAt ? row.nextFireAt.getTime() : null,\n ...(row.tags ? { tags: row.tags } : {}),\n spec: row.spec ?? {},\n state: row.state ?? {},\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\n/**\n * The `ON CONFLICT DO UPDATE` set for a multi-row upsert: each column (or each of `only`) takes the\n * value the conflicting row proposed.\n */\nfunction excludedSet<T extends Table>(table: T, only?: string[]): Record<string, SQL> {\n return Object.fromEntries(\n Object.entries(getTableColumns(table))\n .filter(([key]) => !only || only.includes(key))\n .map(([key, column]) => [key, sql.raw(`excluded.\"${column.name}\"`)]),\n );\n}\n","import { type SQL, sql } from 'drizzle-orm';\nimport type { DrizzlePgDatabase } from './drizzle-pg-state-store';\n\n/**\n * The structural `SqlExecutor` surface `@dudousxd/nestjs-durable-transport-db`'s `DbTransport` rides\n * (declared here, not imported, so this package takes no dependency on the transport).\n */\nexport interface DrizzlePgSqlExecutor {\n readonly dialect: 'postgres';\n escapeId(id: string): string;\n query<T = unknown>(sql: string, params?: unknown[]): Promise<T[]>;\n transaction<T>(\n fn: (tx: { query<U = unknown>(sql: string, params?: unknown[]): Promise<U[]> }) => Promise<T>,\n ): Promise<T>;\n}\n\n/** Turn a `$1`-placeholder SQL string + params into a parameterized drizzle `SQL` object, so it runs\n * through whatever driver the drizzle db wraps (node-postgres, postgres-js, PGlite, Neon, …). */\nexport function toDrizzleSql(text: string, params: unknown[] = []): SQL {\n const chunks: SQL[] = [];\n let last = 0;\n for (const match of text.matchAll(/\\$(\\d+)/g)) {\n const index = Number(match[1]) - 1;\n if (index < 0 || index >= params.length)\n throw new Error(`placeholder ${match[0]} has no bound parameter`);\n chunks.push(sql.raw(text.slice(last, match.index)), sql`${params[index]}`);\n last = (match.index ?? 0) + match[0].length;\n }\n chunks.push(sql.raw(text.slice(last)));\n return sql.join(chunks);\n}\n\n/** node-postgres / PGlite hand back `{ rows }`; postgres-js hands back the row array itself. */\nexport function rowsOf<T>(result: unknown): T[] {\n if (Array.isArray(result)) return result as T[];\n return ((result as { rows?: T[] } | undefined)?.rows ?? []) as T[];\n}\n\n/**\n * Build a `DbTransport` executor from your drizzle Postgres db — the broker-less, DBOS-style\n * transport (remote steps as rows, claimed with `SELECT … FOR UPDATE SKIP LOCKED`) on the SAME\n * connection pool your app and the durable store already use:\n *\n * ```ts\n * import { DbTransport } from '@dudousxd/nestjs-durable-transport-db';\n * import { DrizzlePgStateStore, drizzlePgExecutor } from '@dudousxd/nestjs-durable-store-drizzle/pg';\n *\n * DurableModule.forRoot({\n * store: new DrizzlePgStateStore(db),\n * transport: new DbTransport({ executor: drizzlePgExecutor(db), group: 'api' }),\n * });\n * ```\n */\nexport function drizzlePgExecutor(db: DrizzlePgDatabase): DrizzlePgSqlExecutor {\n return {\n dialect: 'postgres',\n escapeId: (id) => `\"${id.replace(/\"/g, '\"\"')}\"`,\n query: async <T>(text: string, params?: unknown[]) =>\n rowsOf<T>(await db.execute(toDrizzleSql(text, params))),\n transaction: <T>(fn: Parameters<DrizzlePgSqlExecutor['transaction']>[0]) =>\n db.transaction((tx) =>\n fn({\n query: async <U>(text: string, params?: unknown[]) =>\n rowsOf<U>(await tx.execute(toDrizzleSql(text, params))),\n }),\n ) as Promise<T>,\n };\n}\n","import { getTableName } from 'drizzle-orm';\nimport {\n bigserial,\n boolean,\n doublePrecision,\n index,\n integer,\n jsonb,\n pgTable,\n primaryKey,\n text,\n timestamp,\n} from 'drizzle-orm/pg-core';\n\n// PostgreSQL schema for the durable tables. Physical table + column names are the canonical\n// cross-adapter ones (`DURABLE_CANONICAL_COLUMNS` in -testing) — the same ones the SQLite schema in\n// `../schema`, the MikroORM, TypeORM and Prisma adapters use. The Postgres-native choices:\n// - timestamps / `wake_at` / `locked_until` are `timestamptz` (like the TypeORM + MikroORM PG DDL),\n// - JSON payloads are `jsonb` (like MikroORM's PG mapping) — which is what lets `tags` be matched\n// with the GIN-indexable `@>` containment operator instead of a leading-wildcard LIKE,\n// - every string is `text` (Postgres has no `varchar(n)` speed advantage, and a signal/event token\n// can be longer than the `varchar(191)` MySQL forces on the TypeORM DDL).\n//\n// Spread `durablePgSchema` (or re-export the individual tables) from the schema file your\n// `drizzle.config.ts` points at, and drizzle-kit generates the migration for you. Or skip drizzle-kit\n// for these tables and let `DrizzlePgStateStore.ensureSchema()` create them — `./ddl` is the same DDL\n// as SQL, and a spec pins the two against each other so they can never drift.\n\n/** The namespace a run belongs to when its creating engine named none (column DEFAULT below). */\nexport const DEFAULT_NAMESPACE = 'default';\n\nconst tstz = (name: string) => timestamp(name, { withTimezone: true, mode: 'date' });\n\nexport const durableWorkflowRuns = pgTable(\n 'durable_workflow_runs',\n {\n id: text('id').primaryKey(),\n workflow: text('workflow').notNull(),\n workflowVersion: text('workflow_version').notNull(),\n status: text('status').notNull(),\n input: jsonb('input'),\n output: jsonb('output'),\n error: jsonb('error'),\n wakeAt: tstz('wake_at'),\n lockedBy: text('locked_by'),\n lockedUntil: tstz('locked_until'),\n // REMOTE turn the engine suspended on awaiting a decision; matched by completeRemoteDecision so\n // only the currently-awaited turn's decision is applied. Nullable: cleared when a decision lands.\n awaitingDecisionTaskId: text('awaiting_decision_task_id'),\n recoveryAttempts: integer('recovery_attempts'),\n tags: jsonb('tags').$type<string[]>(),\n searchAttributes: jsonb('search_attributes').$type<Record<string, string | number | boolean>>(),\n priority: integer('priority'),\n // The worker-pool partition (tenant) — THE isolation boundary every poll predicate filters on.\n // NOT NULL DEFAULT 'default' so a row can never fall outside every worker's namespace.\n namespace: text('namespace').notNull().default(DEFAULT_NAMESPACE),\n // Which package declared the workflow. Nullable, no default: NULL = unknown, never guessed.\n origin: text('origin'),\n createdAt: tstz('created_at').notNull(),\n updatedAt: tstz('updated_at').notNull(),\n },\n (t) => [\n // Timer poller (`listDueTimers`) + recovery (`listIncompleteRuns`). Same name as the TypeORM DDL.\n index('durable_runs_status_idx').on(t.status, t.wakeAt),\n // Dashboard `listRuns({ workflow, status })` and the singleton gate's per-workflow scans.\n index('durable_runs_workflow_status_idx').on(t.workflow, t.status),\n // Every namespaced poll tick: `namespace = $1 AND status = $2 ORDER BY created_at` (FIFO pick-up).\n // Name matches the MikroORM adapter + the SQLite drizzle schema so a store swap keeps the index.\n index('durable_workflow_runs_namespace_status_idx').on(t.namespace, t.status, t.createdAt),\n // `listRuns({ tag })` compiles to `tags @> '[\"tag\"]'`, which a `jsonb_path_ops` GIN index serves —\n // this is what keeps the singleton gate (`tag: singleton:<key>`, e.g. a per-tenant concurrency\n // key) an index probe instead of a scan of every run the workflow ever had.\n index('durable_runs_tags_gin_idx').using('gin', t.tags.op('jsonb_path_ops')),\n // Retention (`pruneTerminalRuns`) orders a status set by `updated_at`.\n index('durable_runs_status_updated_idx').on(t.status, t.updatedAt),\n ],\n);\n\nexport const durableStepCheckpoints = pgTable(\n 'durable_step_checkpoints',\n {\n runId: text('run_id').notNull(),\n seq: integer('seq').notNull(),\n name: text('name').notNull(),\n kind: text('kind').notNull(),\n stepId: text('step_id').notNull(),\n status: text('status').notNull(),\n input: jsonb('input'),\n output: jsonb('output'),\n error: jsonb('error'),\n events: jsonb('events'),\n attempts: integer('attempts').notNull(),\n workerGroup: text('worker_group'),\n parallelGroup: text('parallel_group'),\n wakeAt: tstz('wake_at'),\n enqueuedAt: tstz('enqueued_at'),\n startedAt: tstz('started_at').notNull(),\n finishedAt: tstz('finished_at').notNull(),\n },\n // (run_id, seq) is the primary key, so listCheckpoints / getEvent already hit an index.\n (t) => [\n primaryKey({ columns: [t.runId, t.seq] }),\n // A run detail reads one fan at a time: checkpointStats / queryCheckpoints by group, seq-paged.\n index('durable_step_checkpoints_group_idx').on(t.runId, t.parallelGroup, t.seq),\n ],\n);\n\n// Normalized search-attribute side-table: one row per (run, key), so attribute predicates push DOWN\n// into SQL as an EXISTS probe on the (key, value) indexes below instead of scan + in-process filter.\nexport const durableRunAttributes = pgTable(\n 'durable_run_attributes',\n {\n runId: text('run_id').notNull(),\n key: text('key').notNull(),\n strValue: text('str_value'),\n numValue: doublePrecision('num_value'),\n },\n (t) => [\n primaryKey({ columns: [t.runId, t.key] }),\n index('durable_run_attributes_num_idx').on(t.key, t.numValue),\n index('durable_run_attributes_str_idx').on(t.key, t.strValue),\n ],\n);\n\nexport const durableSignalWaiters = pgTable(\n 'durable_signal_waiters',\n {\n token: text('token').primaryKey(),\n runId: text('run_id').notNull(),\n seq: integer('seq').notNull(),\n parallelGroup: text('parallel_group'),\n },\n // deleteRun / pruneTerminalRuns delete a run's waiters by run_id.\n (t) => [index('durable_signal_waiters_run_id_idx').on(t.runId)],\n);\n\nexport const durableBufferedSignals = pgTable(\n 'durable_buffered_signals',\n {\n id: bigserial('id', { mode: 'number' }).primaryKey(),\n token: text('token').notNull(),\n payload: jsonb('payload'),\n },\n // Taken FIFO per token (smallest id first).\n (t) => [index('durable_buffered_signals_token_idx').on(t.token, t.id)],\n);\n\n// A published event that matched no live waiter. Keyed by a caller-minted id (engine.publishEvent)\n// so removeBufferedEvent can target that exact row.\nexport const durableBufferedEvents = pgTable(\n 'durable_buffered_events',\n {\n id: text('id').primaryKey(),\n name: text('name').notNull(),\n payload: jsonb('payload'),\n publishedAt: tstz('published_at').notNull(),\n },\n (t) => [index('durable_buffered_events_name_published_at_idx').on(t.name, t.publishedAt)],\n);\n\n// Persisted schedules (`engine.schedules`): the store filters on the columns; `spec`/`state` are\n// engine-owned JSON documents it keeps verbatim.\nexport const durableSchedules = pgTable(\n 'durable_schedules',\n {\n id: text('id').primaryKey(),\n namespace: text('namespace').notNull().default(DEFAULT_NAMESPACE),\n workflow: text('workflow').notNull(),\n paused: boolean('paused').notNull().default(false),\n nextFireAt: tstz('next_fire_at'),\n tags: jsonb('tags').$type<string[]>(),\n spec: jsonb('spec').$type<Record<string, unknown>>().notNull(),\n state: jsonb('state').$type<Record<string, unknown>>().notNull(),\n createdAt: tstz('created_at').notNull(),\n updatedAt: tstz('updated_at').notNull(),\n },\n // The poll's \"due by T\" scan: `paused = false AND next_fire_at <= T ORDER BY next_fire_at`.\n (t) => [index('durable_schedules_due_idx').on(t.paused, t.nextFireAt)],\n);\n\n/**\n * Every durable table, keyed by the name to export it under. Spread into your drizzle-kit schema file\n * (`export const { durableWorkflowRuns, ... } = durablePgSchema;` or `export * from` the `/pg` entry)\n * so `drizzle-kit generate` emits the durable DDL alongside your own tables.\n */\nexport const durablePgSchema = {\n durableWorkflowRuns,\n durableStepCheckpoints,\n durableRunAttributes,\n durableSignalWaiters,\n durableBufferedSignals,\n durableBufferedEvents,\n durableSchedules,\n};\n\n/**\n * The durable table names, derived from {@link durablePgSchema} (one list, never drifts). Feed to a\n * migration tool's exclude list — e.g. drizzle-kit `tablesFilter: ['!durable_*']` — if you let\n * `ensureSchema()` own these tables instead of drizzle-kit.\n */\nexport function durablePgManagedTables(): string[] {\n return Object.values(durablePgSchema).map((table) => getTableName(table));\n}\n"],"mappings":"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","names":["DURABLE_PG_DDL","SCHEMA_LOCK_KEY","ensureDrizzlePgDurableSchema","db","transaction","tx","execute","sql","statement","raw","import_drizzle_orm","import_drizzle_orm","toDrizzleSql","text","params","chunks","last","match","matchAll","index","Number","length","Error","push","sql","raw","slice","join","rowsOf","result","Array","isArray","rows","drizzlePgExecutor","db","dialect","escapeId","id","replace","query","execute","transaction","fn","tx","import_drizzle_orm","DEFAULT_NAMESPACE","tstz","name","timestamp","withTimezone","mode","durableWorkflowRuns","pgTable","id","text","primaryKey","workflow","notNull","workflowVersion","status","input","jsonb","output","error","wakeAt","lockedBy","lockedUntil","awaitingDecisionTaskId","recoveryAttempts","integer","tags","$type","searchAttributes","priority","namespace","default","origin","createdAt","updatedAt","t","index","on","using","op","durableStepCheckpoints","runId","seq","kind","stepId","events","attempts","workerGroup","parallelGroup","enqueuedAt","startedAt","finishedAt","columns","durableRunAttributes","key","strValue","numValue","doublePrecision","durableSignalWaiters","token","durableBufferedSignals","bigserial","payload","durableBufferedEvents","publishedAt","durableSchedules","paused","boolean","nextFireAt","spec","state","durablePgSchema","durablePgManagedTables","Object","values","map","table","getTableName","anyOf","conditions","present","filter","c","undefined","length","or","sql","namespaceFilter","namespace","eq","workflowRuns","hasTag","tag","tags","JSON","stringify","date","ms","Date","d","getTime","DrizzlePgStateStore","scopeNamespace","db","options","scope","withScope","ensureSchema","ensureDrizzlePgDurableSchema","tryAdmitSingleton","runId","workflow","limit","retryWakeAt","transaction","tx","where","and","inArray","status","SINGLETON_ACTIVE_STATUSES","update","set","rows","select","from","runs","map","fromRunRow","singletonAdmissionTags","patch","singletonAdmissionDenialPatch","toRunPatch","id","createRun","run","insert","values","toRunRow","reindexAttributes","searchAttributes","updateRun","inputPatch","TERMINAL_RUN_STATUSES","includes","clearTerminalSingletonAdmission","getRun","row","reindex","Object","keys","updateRunIf","expectedStatuses","matches","applied","returning","for","deleteRun","deleteRunsCascade","deleteRuns","runIds","pruneTerminalRuns","policy","nowMs","statuses","s","maxAge","maxCount","scoped","runFilters","ids","Set","cutoff","parseDuration","lt","updatedAt","orderBy","asc","skipLocked","r","add","size","desc","offset","idList","slice","getCheckpoint","seq","stepCheckpoints","fromCheckpointRow","saveCheckpoint","checkpoint","upsertCheckpoint","saveCheckpointIfPending","toCheckpointRow","saveCheckpointsIfPending","checkpoints","wrote","round","distinctRounds","at","CHECKPOINT_BATCH_ROWS","chunk","updated","rowsOf","execute","updateIfPendingFrom","i","byKey","Map","rowKey","get","run_id","Number","work","raw","cp","listIncompleteRuns","listOrphanedRuns","isNull","lockedUntil","lte","createdAt","listPendingRuns","listDueTimers","query","isNotNull","wakeAt","tryLockRun","owner","leaseUntilMs","lockedBy","releaseRunLock","renewRunLock","workflows","namespaces","origin","origins","o","attributes","f","attributeExists","listRuns","filters","base","$dynamic","countRuns","count","mapWith","runFacets","groupBy","mergeRunFacetRows","runValueFacets","axis","opts","axisIsRunColumn","scan","RUN_VALUE_FACET_SCAN","runValueFacetsFromRuns","column","field","value","mergeRunValueFacetRows","comparisons","attributePredicateOperands","comparator","operand","runAttributes","numValue","strValue","exists","one","key","saveSchedule","record","toScheduleRow","schedules","onConflictDoUpdate","target","getSchedule","fromScheduleRow","updateSchedule","expectedNextFireAt","toSchedulePatch","nextFireAt","deleteSchedule","delete","listSchedules","paused","dueBy","listCheckpoints","getLatestCheckpointByName","name","countCheckpoints","fromSeq","toSeq","gte","listCheckpointsByNamePrefix","prefixes","p","like","escapeLike","checkpointStats","nameKind","as","group","parallelGroup","minSeq","maxSeq","minName","maxName","minEnqueuedAt","enqueuedAt","startedAt","minStartedAt","maxStartedAt","maxFinishedAt","finishedAt","sumAttempts","attempts","queryCheckpoints","namePrefixes","excludeGroups","notInArray","putSignalWaiter","waiter","signalWaiters","token","takeSignalWaiter","fromWaiterRow","listSignalWaiters","prefix","registerChildWaits","entries","excludedSet","compactCheckpoints","into","listSignalWaitersByRun","hasSignalWaiter","tokenPrefix","removeSignalWaiter","bufferSignal","payload","bufferedSignals","takeBufferedSignal","oldest","bufferEvent","input","bufferedEvents","publishedAt","listBufferedEvents","removeBufferedEvent","replace","rounds","seen","forEach","indexes","push","json","v","ts","toISOString","kind","stepId","output","error","events","workerGroup","join","normalizeAttributeRows","workflowVersion","awaitingDecisionTaskId","recoveryAttempts","priority","DEFAULT_NAMESPACE","spec","state","table","only","fromEntries","getTableColumns"]}
|
|
1
|
+
{"version":3,"sources":["../../src/pg/index.ts","../../src/pg/ddl.ts","../../src/pg/drizzle-pg-state-store.ts","../../src/pg/executor.ts","../../src/pg/schema.ts"],"sourcesContent":["// `@dudousxd/nestjs-durable-store-drizzle/pg` — the PostgreSQL flavour of the Drizzle store.\n// The package root (`@dudousxd/nestjs-durable-store-drizzle`) stays the SQLite / libSQL store.\nexport * from './ddl';\nexport * from './drizzle-pg-state-store';\nexport * from './executor';\nexport * from './schema';\n","import { sql } from 'drizzle-orm';\nimport type { PgDatabase } from 'drizzle-orm/pg-core';\n\n/**\n * The durable tables as idempotent Postgres DDL — the exact SQL twin of the `pgTable` definitions in\n * `./schema` (same tables, columns, types, defaults, primary keys and index names; a spec pins the two\n * against each other on a real Postgres, so they cannot drift).\n *\n * Every statement is `IF NOT EXISTS`, so the list is safe to run on every boot\n * ({@link ensureDrizzlePgDurableSchema}, which `DrizzlePgStateStore.ensureSchema()` calls when the\n * module's `autoSchema` is on) or to paste into a hand-written migration:\n *\n * ```ts\n * // drizzle/0007_durable.sql — or a custom migration step\n * import { DURABLE_PG_DDL } from '@dudousxd/nestjs-durable-store-drizzle/pg';\n * console.log(DURABLE_PG_DDL.join(';\\n') + ';');\n * ```\n *\n * A column added by a future version is appended here as `ALTER TABLE … ADD COLUMN IF NOT EXISTS`, so\n * an existing database heals on the next boot exactly like the MikroORM / TypeORM auto-schema does.\n */\nexport const DURABLE_PG_DDL: readonly string[] = [\n `CREATE TABLE IF NOT EXISTS \"durable_workflow_runs\" (\n \"id\" text PRIMARY KEY NOT NULL,\n \"workflow\" text NOT NULL,\n \"workflow_version\" text NOT NULL,\n \"status\" text NOT NULL,\n \"input\" jsonb,\n \"output\" jsonb,\n \"error\" jsonb,\n \"wake_at\" timestamp with time zone,\n \"locked_by\" text,\n \"locked_until\" timestamp with time zone,\n \"awaiting_decision_task_id\" text,\n \"recovery_attempts\" integer,\n \"tags\" jsonb,\n \"search_attributes\" jsonb,\n \"priority\" integer,\n \"namespace\" text DEFAULT 'default' NOT NULL,\n \"origin\" text,\n \"created_at\" timestamp with time zone NOT NULL,\n \"updated_at\" timestamp with time zone NOT NULL\n)`,\n `CREATE TABLE IF NOT EXISTS \"durable_step_checkpoints\" (\n \"run_id\" text NOT NULL,\n \"seq\" integer NOT NULL,\n \"name\" text NOT NULL,\n \"kind\" text NOT NULL,\n \"step_id\" text NOT NULL,\n \"status\" text NOT NULL,\n \"input\" jsonb,\n \"output\" jsonb,\n \"error\" jsonb,\n \"events\" jsonb,\n \"attempts\" integer NOT NULL,\n \"worker_group\" text,\n \"parallel_group\" text,\n \"wake_at\" timestamp with time zone,\n \"enqueued_at\" timestamp with time zone,\n \"started_at\" timestamp with time zone NOT NULL,\n \"finished_at\" timestamp with time zone NOT NULL,\n CONSTRAINT \"durable_step_checkpoints_run_id_seq_pk\" PRIMARY KEY(\"run_id\",\"seq\")\n)`,\n `CREATE TABLE IF NOT EXISTS \"durable_run_attributes\" (\n \"run_id\" text NOT NULL,\n \"key\" text NOT NULL,\n \"str_value\" text,\n \"num_value\" double precision,\n CONSTRAINT \"durable_run_attributes_run_id_key_pk\" PRIMARY KEY(\"run_id\",\"key\")\n)`,\n `CREATE TABLE IF NOT EXISTS \"durable_signal_waiters\" (\n \"token\" text PRIMARY KEY NOT NULL,\n \"run_id\" text NOT NULL,\n \"seq\" integer NOT NULL,\n \"parallel_group\" text\n)`,\n `CREATE TABLE IF NOT EXISTS \"durable_buffered_signals\" (\n \"id\" bigserial PRIMARY KEY NOT NULL,\n \"token\" text NOT NULL,\n \"payload\" jsonb\n)`,\n `CREATE TABLE IF NOT EXISTS \"durable_buffered_events\" (\n \"id\" text PRIMARY KEY NOT NULL,\n \"name\" text NOT NULL,\n \"payload\" jsonb,\n \"published_at\" timestamp with time zone NOT NULL\n)`,\n `CREATE TABLE IF NOT EXISTS \"durable_schedules\" (\n \"id\" text PRIMARY KEY NOT NULL,\n \"namespace\" text DEFAULT 'default' NOT NULL,\n \"workflow\" text NOT NULL,\n \"paused\" boolean DEFAULT false NOT NULL,\n \"next_fire_at\" timestamp with time zone,\n \"tags\" jsonb,\n \"spec\" jsonb NOT NULL,\n \"state\" jsonb NOT NULL,\n \"created_at\" timestamp with time zone NOT NULL,\n \"updated_at\" timestamp with time zone NOT NULL\n)`,\n `CREATE INDEX IF NOT EXISTS \"durable_runs_status_idx\" ON \"durable_workflow_runs\" USING btree (\"status\",\"wake_at\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_runs_workflow_status_idx\" ON \"durable_workflow_runs\" USING btree (\"workflow\",\"status\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_workflow_runs_namespace_status_idx\" ON \"durable_workflow_runs\" USING btree (\"namespace\",\"status\",\"created_at\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_runs_tags_gin_idx\" ON \"durable_workflow_runs\" USING gin (\"tags\" jsonb_path_ops)`,\n `CREATE INDEX IF NOT EXISTS \"durable_runs_status_updated_idx\" ON \"durable_workflow_runs\" USING btree (\"status\",\"updated_at\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_step_checkpoints_group_idx\" ON \"durable_step_checkpoints\" USING btree (\"run_id\",\"parallel_group\",\"seq\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_run_attributes_num_idx\" ON \"durable_run_attributes\" USING btree (\"key\",\"num_value\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_run_attributes_str_idx\" ON \"durable_run_attributes\" USING btree (\"key\",\"str_value\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_signal_waiters_run_id_idx\" ON \"durable_signal_waiters\" USING btree (\"run_id\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_buffered_signals_token_idx\" ON \"durable_buffered_signals\" USING btree (\"token\",\"id\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_buffered_events_name_published_at_idx\" ON \"durable_buffered_events\" USING btree (\"name\",\"published_at\")`,\n `CREATE INDEX IF NOT EXISTS \"durable_schedules_due_idx\" ON \"durable_schedules\" USING btree (\"paused\",\"next_fire_at\")`,\n];\n\n/** Key for the transaction-scoped advisory lock that serializes concurrent heals (several pods\n * booting at once would otherwise race `CREATE INDEX IF NOT EXISTS` into a duplicate-key error). */\nconst SCHEMA_LOCK_KEY = 'durable_schema';\n\n/**\n * Idempotently create the durable tables + indexes on `db` (any drizzle Postgres driver). Runs in one\n * transaction under a `pg_advisory_xact_lock`, so N pods booting together heal the schema once and\n * the rest see it done. Only ever touches the `durable_*` tables.\n */\nexport async function ensureDrizzlePgDurableSchema(db: PgDatabase<any, any, any>): Promise<void> {\n await db.transaction(async (tx) => {\n await tx.execute(sql`SELECT pg_advisory_xact_lock(hashtext(${SCHEMA_LOCK_KEY}))`);\n for (const statement of DURABLE_PG_DDL) await tx.execute(sql.raw(statement));\n });\n}\n","import {\n type AttributeFilter,\n type CheckpointNameKind,\n type CheckpointQuery,\n type CheckpointStat,\n type ChildWait,\n type OwnedLeaseReclaim,\n RUN_VALUE_FACET_SCAN,\n type RetentionPolicy,\n type RunFacetQuery,\n type RunFacetRow,\n type RunQuery,\n type RunStatus,\n type RunValueAxis,\n type RunValueFacetOptions,\n type RunValueFacetRow,\n SINGLETON_ACTIVE_STATUSES,\n type ScheduleQuery,\n type ScheduleRecord,\n type SignalWaiter,\n type StateStore,\n type StepCheckpoint,\n type StepError,\n type StepEvent,\n type StoreTransaction,\n TERMINAL_RUN_STATUSES,\n type WorkflowRun,\n attributePredicateOperands,\n axisIsRunColumn,\n clearTerminalSingletonAdmission,\n mergeRunFacetRows,\n mergeRunValueFacetRows,\n normalizeAttributeRows,\n parseDuration,\n runValueFacetsFromRuns,\n singletonAdmissionDenialPatch,\n singletonAdmissionTags,\n} from '@dudousxd/nestjs-durable-core';\nimport {\n type SQL,\n type Table,\n and,\n asc,\n desc,\n eq,\n exists,\n getTableColumns,\n gte,\n inArray,\n isNotNull,\n isNull,\n like,\n lt,\n lte,\n notInArray,\n or,\n sql,\n} from 'drizzle-orm';\nimport type { PgDatabase } from 'drizzle-orm/pg-core';\nimport { ensureDrizzlePgDurableSchema } from './ddl';\nimport { rowsOf } from './executor';\nimport {\n DEFAULT_NAMESPACE,\n durableBufferedEvents as bufferedEvents,\n durableBufferedSignals as bufferedSignals,\n durableRunAttributes as runAttributes,\n durableSchedules as schedules,\n durableSignalWaiters as signalWaiters,\n durableStepCheckpoints as stepCheckpoints,\n durableWorkflowRuns as workflowRuns,\n} from './schema';\n\ntype RunRow = typeof workflowRuns.$inferSelect;\ntype RunInsert = typeof workflowRuns.$inferInsert;\ntype CheckpointRow = typeof stepCheckpoints.$inferSelect;\n\n/**\n * Any drizzle Postgres database — `drizzle-orm/node-postgres`, `drizzle-orm/postgres-js`,\n * `drizzle-orm/pglite`, Neon, … — built with or without a relational schema. The store only uses the\n * query builder (never `db.query.*`), so you do not have to register the durable tables on it.\n */\nexport type DrizzlePgDatabase = PgDatabase<any, any, any>;\n\nexport interface DrizzlePgStateStoreOptions {\n /**\n * Confine every RUN read (`getRun`, `listRuns`, facets, and the pending / incomplete / due-timer\n * polls) to one namespace — a tenant-boundary view of the store. Omit for the operator\n * (control-plane) view that sees every namespace. The NestJS module's `scopeReads` option applies\n * this for you via {@link DrizzlePgStateStore.withScope}.\n */\n scope?: { namespace?: string | undefined } | undefined;\n}\n\n/** OR a set of conditions where an EMPTY set means \"matches nothing\" (every plural `RunQuery`\n * predicate's contract) — `or()` of nothing would be dropped by `and()` and match everything. */\nfunction anyOf(conditions: (SQL | undefined)[]): SQL {\n const present = conditions.filter((c): c is SQL => c !== undefined);\n return present.length ? (or(...present) as SQL) : sql`1 = 0`;\n}\n\n/** `undefined` = no restriction (the operator view), never `namespace IS NULL`. The column is\n * NOT NULL DEFAULT 'default', so plain equality is exact — except that the default pool also\n * matches legacy `''` rows (an engine configured with `namespace: ''` before '' was normalised). */\nfunction namespaceFilter(namespace: string | undefined): SQL | undefined {\n if (namespace === undefined) return undefined;\n if (namespace === DEFAULT_NAMESPACE || namespace === '') {\n return inArray(workflowRuns.namespace, [DEFAULT_NAMESPACE, '']);\n }\n return eq(workflowRuns.namespace, namespace);\n}\n\n/** `tags @> '[\"tag\"]'::jsonb` — exact element containment (so `etl` never matches `etl-foo`), and\n * served by the `durable_runs_tags_gin_idx` GIN (`jsonb_path_ops`) index. */\nfunction hasTag(tag: string): SQL {\n return sql`${workflowRuns.tags} @> ${JSON.stringify([tag])}::jsonb`;\n}\n\nconst date = (ms: number | undefined | null): Date | null => (ms == null ? null : new Date(ms));\nconst ms = (d: Date | null): number | undefined => (d == null ? undefined : d.getTime());\n\n/**\n * Drizzle `StateStore` for **PostgreSQL**. Pass any drizzle Postgres db (see {@link DrizzlePgDatabase});\n * the durable tables come from `./schema` (drizzle-kit) or {@link ensureSchema} (auto-schema).\n *\n * Postgres-specific behaviour, beyond the shared contract:\n * - leases (`tryLockRun` / `renewRunLock`) are a single conditional `UPDATE … RETURNING`, so two\n * instances racing for the same run serialize on the row lock and exactly one wins;\n * - `takeSignalWaiter` is one `DELETE … RETURNING` (atomic take), and `takeBufferedSignal` claims the\n * oldest row with `FOR UPDATE SKIP LOCKED`, so concurrent takers each get a DIFFERENT signal\n * instead of blocking or double-delivering;\n * - `pruneTerminalRuns` (retention) selects its batch with `FOR UPDATE SKIP LOCKED`, so several\n * pods sweeping at once split the backlog instead of contending on it;\n * - tag filters are jsonb containment (GIN-indexed) and attribute filters push down as EXISTS\n * probes on the indexed side table.\n */\nexport class DrizzlePgStateStore implements StateStore {\n private readonly scopeNamespace: string | undefined;\n\n constructor(\n private readonly db: DrizzlePgDatabase,\n private readonly options: DrizzlePgStateStoreOptions = {},\n ) {\n this.scopeNamespace = options.scope?.namespace;\n }\n\n /** A store confined to `scope.namespace`, sharing this store's db (no new connection). Used by the\n * NestJS module's `scopeReads`; `{ namespace: undefined }` is the unscoped operator view. */\n withScope(scope: { namespace?: string | undefined }): DrizzlePgStateStore {\n return new DrizzlePgStateStore(this.db, { ...this.options, scope });\n }\n\n /** Idempotent CREATE TABLE / INDEX IF NOT EXISTS under an advisory lock — called on boot when the\n * module's `autoSchema` is on. Turn `autoSchema` off if drizzle-kit owns these tables. */\n async ensureSchema(): Promise<void> {\n await ensureDrizzlePgDurableSchema(this.db);\n }\n\n /** The read-scope predicate on the runs table (undefined when the store is unscoped). */\n private scope(): SQL | undefined {\n return namespaceFilter(this.scopeNamespace);\n }\n\n async tryAdmitSingleton(\n runId: string,\n tag: string,\n workflow: string,\n limit: number,\n retryWakeAt?: number,\n ): Promise<boolean> {\n return this.db.transaction(async (tx) => {\n const where = and(\n eq(workflowRuns.workflow, workflow),\n inArray(workflowRuns.status, SINGLETON_ACTIVE_STATUSES),\n this.scope(),\n );\n await tx.update(workflowRuns).set({ workflow }).where(where);\n const rows = await tx.select().from(workflowRuns).where(where);\n const runs = rows.map(fromRunRow);\n const tags = singletonAdmissionTags(runs, runId, tag, workflow, limit);\n if (!tags) {\n const patch = singletonAdmissionDenialPatch(runs, runId, tag, workflow, retryWakeAt);\n if (patch)\n await tx.update(workflowRuns).set(toRunPatch(patch)).where(eq(workflowRuns.id, runId));\n return false;\n }\n await tx.update(workflowRuns).set({ tags }).where(eq(workflowRuns.id, runId));\n return true;\n });\n }\n\n async createRun(run: WorkflowRun): Promise<void> {\n // One transaction: a run is never visible without its attribute rows (or vice versa).\n await this.db.transaction(async (tx) => {\n await tx.insert(workflowRuns).values(toRunRow(run));\n await reindexAttributes(tx, run.id, run.searchAttributes);\n });\n }\n\n async updateRun(runId: string, inputPatch: Partial<WorkflowRun>): Promise<void> {\n // Writes are unscoped, so preserve tags even when settling a run outside the read scope.\n const patch =\n inputPatch.status && TERMINAL_RUN_STATUSES.includes(inputPatch.status)\n ? await clearTerminalSingletonAdmission(runId, inputPatch, (id) =>\n this.withScope({}).getRun(id),\n )\n : inputPatch;\n const row = toRunPatch(patch);\n const reindex = 'searchAttributes' in patch;\n if (!Object.keys(row).length && !reindex) return;\n await this.db.transaction(async (tx) => {\n // Drizzle throws on `.set({})`; skip the UPDATE when no mapped column changed.\n if (Object.keys(row).length)\n await tx.update(workflowRuns).set(row).where(eq(workflowRuns.id, runId));\n if (reindex) await reindexAttributes(tx, runId, patch.searchAttributes);\n });\n }\n\n async updateRunIf(\n runId: string,\n expectedStatuses: RunStatus[],\n inputPatch: Partial<WorkflowRun>,\n ): Promise<boolean> {\n if (expectedStatuses.length === 0) return false;\n // Writes are unscoped, like updateRun.\n const patch =\n inputPatch.status && TERMINAL_RUN_STATUSES.includes(inputPatch.status)\n ? await clearTerminalSingletonAdmission(runId, inputPatch, (id) =>\n this.withScope({}).getRun(id),\n )\n : inputPatch;\n const row = toRunPatch(patch);\n const reindex = 'searchAttributes' in patch;\n const matches = and(eq(workflowRuns.id, runId), inArray(workflowRuns.status, expectedStatuses));\n return this.db.transaction(async (tx) => {\n // One conditional UPDATE: a writer racing another blocks on the row lock, then re-evaluates\n // the status predicate against the committed row. With no mapped column to write, the compare\n // is a locking read instead.\n const applied = Object.keys(row).length\n ? (await tx.update(workflowRuns).set(row).where(matches).returning({ id: workflowRuns.id }))\n .length === 1\n : (await tx.select({ id: workflowRuns.id }).from(workflowRuns).where(matches).for('update'))\n .length === 1;\n if (applied && reindex) await reindexAttributes(tx, runId, patch.searchAttributes);\n return applied;\n });\n }\n\n async getRun(runId: string): Promise<WorkflowRun | null> {\n const rows = await this.db\n .select()\n .from(workflowRuns)\n .where(and(eq(workflowRuns.id, runId), this.scope()))\n .limit(1);\n return rows[0] ? fromRunRow(rows[0]) : null;\n }\n\n async deleteRun(runId: string): Promise<void> {\n await this.db.transaction(async (tx) => {\n await deleteRunsCascade(tx, [runId]);\n });\n }\n\n async deleteRuns(runIds: string[]): Promise<void> {\n if (runIds.length === 0) return;\n await this.db.transaction(async (tx) => {\n await deleteRunsCascade(tx, runIds);\n });\n }\n\n async pruneTerminalRuns(policy: RetentionPolicy, nowMs: number, limit: number): Promise<number> {\n // Only terminal statuses are ever eligible — a policy naming a live status would race the engine.\n const statuses = policy.statuses.filter((s) => TERMINAL_RUN_STATUSES.includes(s));\n if (statuses.length === 0 || limit <= 0) return 0;\n if (policy.maxAge == null && policy.maxCount == null) return 0;\n // A scoped policy only ever sees (and, for maxCount, counts) the runs its scope matches.\n const scoped = this.runFilters({ ...(policy.scope ?? {}), statuses });\n return this.db.transaction(async (tx) => {\n const ids = new Set<string>();\n if (policy.maxAge != null) {\n const cutoff = new Date(nowMs - parseDuration(policy.maxAge));\n const rows = await tx\n .select({ id: workflowRuns.id })\n .from(workflowRuns)\n .where(and(...scoped, lt(workflowRuns.updatedAt, cutoff)))\n .orderBy(asc(workflowRuns.updatedAt)) // oldest first\n .limit(limit)\n .for('update', { skipLocked: true });\n for (const r of rows) ids.add(r.id);\n }\n if (policy.maxCount != null && ids.size < limit) {\n // Everything past the newest `maxCount` rows of the status set. The kept window is skipped by\n // OFFSET (no row lock there), and only the rows past it are locked for deletion.\n const rows = await tx\n .select({ id: workflowRuns.id })\n .from(workflowRuns)\n .where(and(...scoped))\n .orderBy(desc(workflowRuns.updatedAt), desc(workflowRuns.id))\n .limit(limit)\n .offset(policy.maxCount)\n .for('update', { skipLocked: true });\n for (const r of rows) {\n if (ids.size >= limit) break;\n ids.add(r.id);\n }\n }\n if (ids.size === 0) return 0;\n const idList = [...ids].slice(0, limit);\n await deleteRunsCascade(tx, idList);\n return idList.length;\n });\n }\n\n async getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null> {\n const rows = await this.db\n .select()\n .from(stepCheckpoints)\n .where(and(eq(stepCheckpoints.runId, runId), eq(stepCheckpoints.seq, seq)))\n .limit(1);\n return rows[0] ? fromCheckpointRow(rows[0]) : null;\n }\n\n async saveCheckpoint(checkpoint: StepCheckpoint): Promise<void> {\n await upsertCheckpoint(this.db, checkpoint);\n }\n\n async saveCheckpointIfPending(checkpoint: StepCheckpoint): Promise<boolean> {\n // One conditional UPDATE: a writer racing a settling result blocks on the row lock, then\n // re-evaluates `status = 'pending'` against the committed row and matches nothing. A missing\n // row matches nothing either, so it is never created.\n const { runId, seq, ...set } = toCheckpointRow(checkpoint);\n const rows = await this.db\n .update(stepCheckpoints)\n .set(set)\n .where(\n and(\n eq(stepCheckpoints.runId, runId),\n eq(stepCheckpoints.seq, seq),\n eq(stepCheckpoints.status, 'pending'),\n ),\n )\n .returning({ seq: stepCheckpoints.seq });\n return rows.length === 1;\n }\n\n async saveCheckpointsIfPending(checkpoints: StepCheckpoint[]): Promise<boolean[]> {\n const wrote = checkpoints.map(() => false);\n if (checkpoints.length === 0) return wrote;\n await this.db.transaction(async (tx) => {\n // One statement can only update a row once, so a repeated row goes in a later round, which\n // then compares against the earlier entry's write.\n for (const round of distinctRounds(checkpoints)) {\n for (let at = 0; at < round.length; at += CHECKPOINT_BATCH_ROWS) {\n const chunk = round.slice(at, at + CHECKPOINT_BATCH_ROWS);\n const updated = rowsOf<{ run_id: string; seq: number }>(\n await tx.execute(\n updateIfPendingFrom(chunk.map((i) => checkpoints[i] as StepCheckpoint)),\n ),\n );\n const byKey = new Map(chunk.map((i) => [rowKey(checkpoints[i] as StepCheckpoint), i]));\n for (const row of updated) {\n const i = byKey.get(rowKey({ runId: row.run_id, seq: Number(row.seq) }));\n if (i !== undefined) wrote[i] = true;\n }\n }\n }\n });\n return wrote;\n }\n\n async transaction<T>(work: (tx: StoreTransaction) => Promise<T>): Promise<T> {\n return this.db.transaction(async (tx) =>\n work({ raw: tx, saveCheckpoint: (cp) => upsertCheckpoint(tx, cp) }),\n );\n }\n\n /** Crash recovery. Namespace-scoped: a worker re-drives only its own tenant's runs. */\n async listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]> {\n const rows = await this.db\n .select()\n .from(workflowRuns)\n .where(\n and(\n inArray(workflowRuns.status, ['running', 'cancelling']),\n namespaceFilter(namespace),\n this.scope(),\n ),\n );\n return rows.map(fromRunRow);\n }\n\n async listOrphanedRuns(\n nowMs: number,\n limit: number,\n namespace?: string,\n ownedBy?: OwnedLeaseReclaim,\n ): Promise<WorkflowRun[]> {\n if (limit <= 0) return [];\n const rows = await this.db\n .select()\n .from(workflowRuns)\n .where(\n and(\n inArray(workflowRuns.status, ['running', 'cancelling']),\n or(\n isNull(workflowRuns.lockedUntil),\n lte(workflowRuns.lockedUntil, new Date(nowMs)),\n // A live lease left by a previous process with the caller's own instance id.\n ownedBy\n ? and(\n eq(workflowRuns.lockedBy, ownedBy.owner),\n lt(workflowRuns.lockedUntil, new Date(ownedBy.lockedBefore)),\n )\n : undefined,\n ),\n namespaceFilter(namespace),\n this.scope(),\n ),\n )\n .orderBy(asc(workflowRuns.createdAt))\n .limit(limit);\n return rows.map(fromRunRow);\n }\n\n /** FIFO pick-up, served by `durable_workflow_runs_namespace_status_idx`. The engine then leases\n * each run with {@link tryLockRun}; the listing itself takes no locks (it runs outside a tx). */\n async listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]> {\n const rows = await this.db\n .select()\n .from(workflowRuns)\n .where(and(eq(workflowRuns.status, 'pending'), namespaceFilter(namespace), this.scope()))\n .orderBy(asc(workflowRuns.createdAt))\n .limit(limit);\n return rows.map(fromRunRow);\n }\n\n async listDueTimers(nowMs: number, namespace?: string, limit?: number): Promise<WorkflowRun[]> {\n const query = this.db\n .select()\n .from(workflowRuns)\n .where(\n and(\n eq(workflowRuns.status, 'suspended'),\n isNotNull(workflowRuns.wakeAt),\n lte(workflowRuns.wakeAt, new Date(nowMs)),\n namespaceFilter(namespace),\n this.scope(),\n ),\n )\n .orderBy(asc(workflowRuns.wakeAt));\n const rows = limit !== undefined ? await query.limit(limit) : await query;\n return rows.map(fromRunRow);\n }\n\n async tryLockRun(\n runId: string,\n owner: string,\n leaseUntilMs: number,\n nowMs: number,\n ): Promise<boolean> {\n // One conditional UPDATE: under READ COMMITTED a concurrent contender blocks on the row lock,\n // then re-evaluates the WHERE against the winner's committed row and matches nothing.\n const rows = await this.db\n .update(workflowRuns)\n .set({ lockedBy: owner, lockedUntil: new Date(leaseUntilMs) })\n .where(\n and(\n eq(workflowRuns.id, runId),\n or(isNull(workflowRuns.lockedUntil), lte(workflowRuns.lockedUntil, new Date(nowMs))),\n ),\n )\n .returning({ id: workflowRuns.id });\n return rows.length === 1;\n }\n\n async releaseRunLock(runId: string): Promise<void> {\n await this.db\n .update(workflowRuns)\n .set({ lockedBy: null, lockedUntil: null })\n .where(eq(workflowRuns.id, runId));\n }\n\n async renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean> {\n const rows = await this.db\n .update(workflowRuns)\n .set({ lockedUntil: new Date(leaseUntilMs) })\n .where(and(eq(workflowRuns.id, runId), eq(workflowRuns.lockedBy, owner)))\n .returning({ id: workflowRuns.id });\n return rows.length === 1;\n }\n\n /** The predicates every run query shares — {@link listRuns} pages them, the facets group them. */\n private runFilters(query: RunQuery): SQL[] {\n return [\n this.scope(),\n query.workflow ? eq(workflowRuns.workflow, query.workflow) : undefined,\n query.workflows\n ? query.workflows.length\n ? inArray(workflowRuns.workflow, query.workflows)\n : sql`1 = 0`\n : undefined,\n // The tenant boundary. Also the engine's execution-timeout sweep path\n // (`listRuns({ workflow, status, namespace })`) — unscoped, it would cancel another tenant's runs.\n namespaceFilter(query.namespace),\n query.namespaces\n ? query.namespaces.length\n ? inArray(workflowRuns.namespace, query.namespaces)\n : sql`1 = 0`\n : undefined,\n // `null` selects the unattributed bucket; a value never matches a NULL origin.\n query.origin === null\n ? isNull(workflowRuns.origin)\n : query.origin !== undefined\n ? eq(workflowRuns.origin, query.origin)\n : undefined,\n query.origins\n ? anyOf(\n query.origins.map((o) =>\n o === null ? isNull(workflowRuns.origin) : eq(workflowRuns.origin, o),\n ),\n )\n : undefined,\n query.status ? eq(workflowRuns.status, query.status) : undefined,\n query.statuses\n ? query.statuses.length\n ? inArray(workflowRuns.status, query.statuses)\n : sql`1 = 0`\n : undefined,\n query.tag ? hasTag(query.tag) : undefined,\n query.tags ? anyOf(query.tags.map(hasTag)) : undefined,\n // One EXISTS per attribute predicate against the normalized side table (ANDed).\n ...(query.attributes?.map((f) => this.attributeExists(f)) ?? []),\n ].filter((f): f is SQL => f !== undefined);\n }\n\n async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n const filters = this.runFilters(query);\n const base = this.db\n .select()\n .from(workflowRuns)\n .where(filters.length ? and(...filters) : undefined)\n // newest first; id breaks created_at ties so limit/offset pages are stable\n .orderBy(desc(workflowRuns.createdAt), desc(workflowRuns.id))\n .$dynamic();\n if (query.limit != null) base.limit(query.limit);\n if (query.offset != null) base.offset(query.offset);\n const rows = await base;\n return rows.map(fromRunRow);\n }\n\n async countRuns(query: Omit<RunQuery, 'limit' | 'offset'>): Promise<number> {\n const filters = this.runFilters(query);\n const rows = await this.db\n .select({ count: sql<number>`count(*)`.mapWith(Number) })\n .from(workflowRuns)\n .where(filters.length ? and(...filters) : undefined);\n return rows[0]?.count ?? 0;\n }\n\n async runFacets(query: RunFacetQuery): Promise<RunFacetRow[]> {\n const filters = this.runFilters(query);\n const rows = await this.db\n .select({\n status: workflowRuns.status,\n origin: workflowRuns.origin,\n count: sql<number>`count(*)`.mapWith(Number),\n })\n .from(workflowRuns)\n .where(filters.length ? and(...filters) : undefined)\n .groupBy(workflowRuns.status, workflowRuns.origin);\n return mergeRunFacetRows(\n rows.map((r) => ({ status: r.status as RunStatus, origin: r.origin, count: r.count })),\n );\n }\n\n /** Run-table axes are an exact `GROUP BY`; the tag / attribute axes are counted over a bounded\n * page of runs (see `RunValueFacetOptions.scan`), like the TypeORM and SQLite Drizzle adapters. */\n async runValueFacets(\n axis: RunValueAxis,\n query: RunFacetQuery,\n opts?: RunValueFacetOptions,\n ): Promise<RunValueFacetRow[]> {\n if (!axisIsRunColumn(axis)) {\n const runs = await this.listRuns({ ...query, limit: opts?.scan ?? RUN_VALUE_FACET_SCAN });\n return runValueFacetsFromRuns(runs, axis, opts);\n }\n const column = workflowRuns[axis.field];\n const filters = this.runFilters(query);\n const rows = await this.db\n .select({ value: column, count: sql<number>`count(*)`.mapWith(Number) })\n .from(workflowRuns)\n .where(filters.length ? and(...filters) : undefined)\n .groupBy(column);\n return mergeRunValueFacetRows(\n rows.map((r) => ({ value: (r.value as string | null) ?? null, count: r.count })),\n opts,\n );\n }\n\n /** One attribute predicate as an EXISTS on the side table, correlated to the outer run. `ne` also\n * excludes runs lacking the key (EXISTS requires the row). Numbers compare `num_value`, strings\n * and booleans `str_value`; an `in` set ORs its members inside the one EXISTS. */\n private attributeExists(f: AttributeFilter): SQL {\n const comparisons = attributePredicateOperands(f).map(\n ({ column, comparator, operand }) =>\n sql`${column === 'numValue' ? runAttributes.numValue : runAttributes.strValue} ${sql.raw(comparator)} ${operand}`,\n );\n return exists(\n this.db\n .select({ one: sql`1` })\n .from(runAttributes)\n .where(\n and(\n eq(runAttributes.runId, workflowRuns.id),\n eq(runAttributes.key, f.key),\n anyOf(comparisons),\n ),\n ),\n );\n }\n\n // ---- persisted schedules ----------------------------------------------------------------------\n\n async saveSchedule(record: ScheduleRecord): Promise<void> {\n const row = toScheduleRow(record);\n await this.db\n .insert(schedules)\n .values(row)\n .onConflictDoUpdate({ target: schedules.id, set: row });\n }\n\n async getSchedule(id: string): Promise<ScheduleRecord | null> {\n const rows = await this.db.select().from(schedules).where(eq(schedules.id, id)).limit(1);\n return rows[0] ? fromScheduleRow(rows[0]) : null;\n }\n\n /** A single conditional `UPDATE … RETURNING`: the compare-and-set on `next_fire_at` is atomic. */\n async updateSchedule(\n id: string,\n patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>,\n expectedNextFireAt?: number | null,\n ): Promise<boolean> {\n const set = toSchedulePatch(patch);\n if (!Object.keys(set).length) return (await this.getSchedule(id)) !== null;\n const rows = await this.db\n .update(schedules)\n .set(set)\n .where(\n and(\n eq(schedules.id, id),\n expectedNextFireAt === undefined\n ? undefined\n : expectedNextFireAt === null\n ? isNull(schedules.nextFireAt)\n : eq(schedules.nextFireAt, new Date(expectedNextFireAt)),\n ),\n )\n .returning({ id: schedules.id });\n return rows.length > 0;\n }\n\n async deleteSchedule(id: string): Promise<boolean> {\n const rows = await this.db\n .delete(schedules)\n .where(eq(schedules.id, id))\n .returning({ id: schedules.id });\n return rows.length > 0;\n }\n\n async listSchedules(query: ScheduleQuery): Promise<ScheduleRecord[]> {\n const base = this.db\n .select()\n .from(schedules)\n .where(\n and(\n query.namespace !== undefined ? eq(schedules.namespace, query.namespace) : undefined,\n query.workflow !== undefined ? eq(schedules.workflow, query.workflow) : undefined,\n query.paused !== undefined ? eq(schedules.paused, query.paused) : undefined,\n query.tag !== undefined\n ? sql`${schedules.tags} @> ${JSON.stringify([query.tag])}::jsonb`\n : undefined,\n query.dueBy !== undefined\n ? and(eq(schedules.paused, false), lte(schedules.nextFireAt, new Date(query.dueBy)))\n : undefined,\n ),\n )\n // Soonest-due first, never-firing (NULL) last, id as the stable tie-break.\n .orderBy(sql`${schedules.nextFireAt} ASC NULLS LAST`, asc(schedules.id))\n .$dynamic();\n if (query.limit != null) base.limit(query.limit);\n if (query.offset != null) base.offset(query.offset);\n return (await base).map(fromScheduleRow);\n }\n\n async listCheckpoints(runId: string): Promise<StepCheckpoint[]> {\n const rows = await this.db\n .select()\n .from(stepCheckpoints)\n .where(eq(stepCheckpoints.runId, runId))\n .orderBy(asc(stepCheckpoints.seq));\n return rows.map(fromCheckpointRow);\n }\n\n async getLatestCheckpointByName(\n runId: string,\n name: string,\n ): Promise<StepCheckpoint | undefined> {\n const rows = await this.db\n .select()\n .from(stepCheckpoints)\n .where(and(eq(stepCheckpoints.runId, runId), eq(stepCheckpoints.name, name)))\n .orderBy(desc(stepCheckpoints.seq))\n .limit(1);\n return rows[0] ? fromCheckpointRow(rows[0]) : undefined;\n }\n\n async countCheckpoints(\n runId: string,\n fromSeq: number,\n toSeq: number,\n statuses: StepCheckpoint['status'][],\n ): Promise<number> {\n if (statuses.length === 0) return 0;\n const rows = await this.db\n .select({ count: sql<number>`count(*)`.mapWith(Number) })\n .from(stepCheckpoints)\n .where(\n and(\n eq(stepCheckpoints.runId, runId),\n gte(stepCheckpoints.seq, fromSeq),\n lte(stepCheckpoints.seq, toSeq),\n inArray(stepCheckpoints.status, statuses),\n ),\n );\n return rows[0]?.count ?? 0;\n }\n\n async listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]> {\n if (prefixes.length === 0) return [];\n const rows = await this.db\n .select()\n .from(stepCheckpoints)\n .where(\n and(\n eq(stepCheckpoints.runId, runId),\n or(...prefixes.map((p) => like(stepCheckpoints.name, `${escapeLike(p)}%`))),\n ),\n )\n .orderBy(asc(stepCheckpoints.seq));\n return rows.map(fromCheckpointRow);\n }\n\n /** {@link StateStore.checkpointStats}: one `GROUP BY parallel_group, status, name_kind` over the\n * run's checkpoints, so a wide fan comes back as a few bucket rows instead of every member. */\n async checkpointStats(\n runId: string,\n opts?: { group?: string | undefined },\n ): Promise<CheckpointStat[]> {\n const c = stepCheckpoints;\n const nameKind = sql<CheckpointNameKind>`CASE\n WHEN ${c.name} LIKE 'signal:child:%' THEN 'child'\n WHEN ${c.name} LIKE 'fan:%' THEN 'folded'\n WHEN ${c.name} LIKE 'spawn:%' THEN 'spawn'\n ELSE 'step' END`.as('name_kind');\n // Aggregates come back raw from the driver (count/sum as bigint strings, timestamps unparsed);\n // `mapWith` a column decodes them as that column's rows are decoded.\n const rows = await this.db\n .select({\n group: c.parallelGroup,\n status: c.status,\n nameKind,\n count: sql<number>`count(*)`.mapWith(Number),\n minSeq: sql<number>`min(${c.seq})`.mapWith(Number),\n maxSeq: sql<number>`max(${c.seq})`.mapWith(Number),\n minName: sql<string>`min(${c.name})`,\n maxName: sql<string>`max(${c.name})`,\n minEnqueuedAt: sql<Date>`min(coalesce(${c.enqueuedAt}, ${c.startedAt}))`.mapWith(\n c.startedAt,\n ),\n minStartedAt: sql<Date>`min(${c.startedAt})`.mapWith(c.startedAt),\n maxStartedAt: sql<Date>`max(${c.startedAt})`.mapWith(c.startedAt),\n maxFinishedAt: sql<Date>`max(${c.finishedAt})`.mapWith(c.finishedAt),\n sumAttempts: sql<number>`sum(${c.attempts})`.mapWith(Number),\n })\n .from(c)\n .where(\n and(\n eq(c.runId, runId),\n opts?.group !== undefined ? eq(c.parallelGroup, opts.group) : undefined,\n ),\n )\n .groupBy(c.parallelGroup, c.status, sql`name_kind`);\n return rows.map((r) => ({\n ...r,\n group: r.group ?? null,\n status: r.status as StepCheckpoint['status'],\n }));\n }\n\n /** {@link StateStore.queryCheckpoints}: the run's checkpoints narrowed in SQL, in `seq` order and\n * paged there, so reading one page of a wide fan never loads the rest of it. */\n async queryCheckpoints(runId: string, query: CheckpointQuery): Promise<StepCheckpoint[]> {\n if (query.statuses?.length === 0 || query.namePrefixes?.length === 0) return [];\n const c = stepCheckpoints;\n const base = this.db\n .select()\n .from(c)\n .where(\n and(\n eq(c.runId, runId),\n query.group !== undefined ? eq(c.parallelGroup, query.group) : undefined,\n // `NOT IN` is never true for a NULL group, so ungrouped rows are kept explicitly.\n query.excludeGroups?.length\n ? or(isNull(c.parallelGroup), notInArray(c.parallelGroup, query.excludeGroups))\n : undefined,\n query.statuses ? inArray(c.status, query.statuses) : undefined,\n query.namePrefixes\n ? or(...query.namePrefixes.map((p) => like(c.name, `${escapeLike(p)}%`)))\n : undefined,\n ),\n )\n .orderBy(asc(c.seq))\n .$dynamic();\n if (query.limit != null) base.limit(query.limit);\n if (query.offset != null) base.offset(query.offset);\n return (await base).map(fromCheckpointRow);\n }\n\n async putSignalWaiter(waiter: SignalWaiter): Promise<void> {\n const set = {\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n };\n await this.db\n .insert(signalWaiters)\n .values({ token: waiter.token, ...set })\n .onConflictDoUpdate({ target: signalWaiters.token, set });\n }\n\n async takeSignalWaiter(token: string): Promise<SignalWaiter | null> {\n // Atomic take: one DELETE … RETURNING, so two concurrent signals for the same token can never\n // both resume the run.\n const rows = await this.db\n .delete(signalWaiters)\n .where(eq(signalWaiters.token, token))\n .returning();\n const row = rows[0];\n return row ? fromWaiterRow(row) : null;\n }\n\n async listSignalWaiters(prefix: string): Promise<SignalWaiter[]> {\n const rows = await this.db\n .select()\n .from(signalWaiters)\n .where(like(signalWaiters.token, `${escapeLike(prefix)}%`));\n return rows.map(fromWaiterRow);\n }\n\n async registerChildWaits(entries: ChildWait[]): Promise<void> {\n if (entries.length === 0) return;\n await this.db.transaction(async (tx) => {\n await tx\n .insert(signalWaiters)\n .values(\n entries.map(({ waiter }) => ({\n token: waiter.token,\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n })),\n )\n .onConflictDoUpdate({\n target: signalWaiters.token,\n set: excludedSet(signalWaiters, ['runId', 'seq', 'parallelGroup']),\n });\n await tx\n .insert(stepCheckpoints)\n .values(entries.map(({ checkpoint }) => toCheckpointRow(checkpoint)))\n .onConflictDoUpdate({\n target: [stepCheckpoints.runId, stepCheckpoints.seq],\n set: excludedSet(stepCheckpoints),\n });\n });\n }\n\n async compactCheckpoints(\n runId: string,\n fromSeq: number,\n toSeq: number,\n into: StepCheckpoint,\n ): Promise<void> {\n await this.db.transaction(async (tx) => {\n await tx\n .delete(stepCheckpoints)\n .where(\n and(\n eq(stepCheckpoints.runId, runId),\n gte(stepCheckpoints.seq, fromSeq),\n lte(stepCheckpoints.seq, toSeq),\n ),\n );\n await upsertCheckpoint(tx, into);\n });\n }\n\n async listSignalWaitersByRun(runIds: string[]): Promise<SignalWaiter[]> {\n if (runIds.length === 0) return [];\n const rows = await this.db\n .select()\n .from(signalWaiters)\n .where(inArray(signalWaiters.runId, runIds));\n return rows.map(fromWaiterRow);\n }\n\n async hasSignalWaiter(runId: string, tokenPrefix: string): Promise<boolean> {\n const rows = await this.db\n .select({ token: signalWaiters.token })\n .from(signalWaiters)\n .where(\n and(\n eq(signalWaiters.runId, runId),\n like(signalWaiters.token, `${escapeLike(tokenPrefix)}%`),\n ),\n )\n .limit(1);\n return rows.length > 0;\n }\n\n async removeSignalWaiter(waiter: SignalWaiter): Promise<void> {\n // Exact match — never remove a row a DIFFERENT run has since claimed the token with.\n await this.db\n .delete(signalWaiters)\n .where(\n and(\n eq(signalWaiters.token, waiter.token),\n eq(signalWaiters.runId, waiter.runId),\n eq(signalWaiters.seq, waiter.seq),\n ),\n );\n }\n\n async bufferSignal(token: string, payload: unknown): Promise<void> {\n await this.db.insert(bufferedSignals).values({ token, payload: payload ?? null });\n }\n\n async takeBufferedSignal(token: string): Promise<{ payload: unknown } | null> {\n // Claim the oldest buffered signal for `token` with SKIP LOCKED and delete it in the same\n // statement: concurrent takers each get a different row (FIFO), none blocks, none double-reads.\n const oldest = this.db\n .select({ id: bufferedSignals.id })\n .from(bufferedSignals)\n .where(eq(bufferedSignals.token, token))\n .orderBy(asc(bufferedSignals.id))\n .limit(1)\n .for('update', { skipLocked: true });\n const rows = await this.db\n .delete(bufferedSignals)\n .where(inArray(bufferedSignals.id, oldest))\n .returning({ payload: bufferedSignals.payload });\n const row = rows[0];\n return row ? { payload: row.payload ?? undefined } : null;\n }\n\n async bufferEvent(input: {\n name: string;\n payload: unknown;\n id: string;\n publishedAt: number;\n }): Promise<void> {\n await this.db.insert(bufferedEvents).values({\n id: input.id,\n name: input.name,\n payload: input.payload ?? null,\n publishedAt: new Date(input.publishedAt),\n });\n }\n\n async listBufferedEvents(\n name: string,\n limit: number,\n ): Promise<Array<{ id: string; payload: unknown; publishedAt: number }>> {\n const rows = await this.db\n .select()\n .from(bufferedEvents)\n .where(eq(bufferedEvents.name, name))\n .orderBy(asc(bufferedEvents.publishedAt), asc(bufferedEvents.id))\n .limit(limit);\n return rows.map((r) => ({\n id: r.id,\n payload: r.payload ?? undefined,\n publishedAt: r.publishedAt.getTime(),\n }));\n }\n\n async removeBufferedEvent(id: string): Promise<boolean> {\n const rows = await this.db\n .delete(bufferedEvents)\n .where(eq(bufferedEvents.id, id))\n .returning({ id: bufferedEvents.id });\n return rows.length === 1;\n }\n}\n\n/** Escape LIKE metacharacters so a literal prefix (`event:50%_off`) matches only itself. */\nfunction escapeLike(value: string): string {\n return value.replace(/[\\\\%_]/g, (c) => `\\\\${c}`);\n}\n\n/** Rows per `UPDATE … FROM (VALUES …)`: 17 parameters each, well under Postgres's 65535. */\nconst CHECKPOINT_BATCH_ROWS = 500;\n\nconst rowKey = (cp: { runId: string; seq: number }): string => `${cp.seq}:${cp.runId}`;\n\n/** Indexes of `checkpoints` split into rounds that each name a row at most once, in input order. */\nfunction distinctRounds(checkpoints: StepCheckpoint[]): number[][] {\n const rounds: number[][] = [];\n const seen = new Map<string, number>();\n checkpoints.forEach((cp, i) => {\n const key = rowKey(cp);\n const round = seen.get(key) ?? 0;\n seen.set(key, round + 1);\n const indexes = rounds[round] ?? [];\n rounds[round] = indexes;\n indexes.push(i);\n });\n return rounds;\n}\n\n/**\n * `saveCheckpointIfPending` for many rows in one statement: each `VALUES` row overwrites its\n * checkpoint only while that row is still `pending` (a concurrent writer blocks on the row lock,\n * then re-evaluates the predicate against the committed row), and `RETURNING` names the rows that\n * were written. The rows must be distinct.\n */\nfunction updateIfPendingFrom(checkpoints: StepCheckpoint[]): SQL {\n const json = (v: unknown) => (v == null ? null : JSON.stringify(v));\n const ts = (v: Date | null) => (v == null ? null : v.toISOString());\n const values = checkpoints.map((cp) => {\n const r = toCheckpointRow(cp);\n return sql`(${r.runId}::text, ${r.seq}::integer, ${r.name}::text, ${r.kind}::text, ${r.stepId}::text, ${r.status}::text, ${json(r.input)}::jsonb, ${json(r.output)}::jsonb, ${json(r.error)}::jsonb, ${json(r.events)}::jsonb, ${r.attempts}::integer, ${r.workerGroup}::text, ${r.parallelGroup}::text, ${ts(r.wakeAt)}::timestamptz, ${ts(r.enqueuedAt)}::timestamptz, ${ts(r.startedAt)}::timestamptz, ${ts(r.finishedAt)}::timestamptz)`;\n });\n return sql`UPDATE ${stepCheckpoints} AS c SET\n name = v.name, kind = v.kind, step_id = v.step_id, status = v.status, input = v.input,\n output = v.output, error = v.error, events = v.events, attempts = v.attempts,\n worker_group = v.worker_group, parallel_group = v.parallel_group, wake_at = v.wake_at,\n enqueued_at = v.enqueued_at, started_at = v.started_at, finished_at = v.finished_at\n FROM (VALUES ${sql.join(values, sql`, `)}) AS v(run_id, seq, name, kind, step_id, status, input,\n output, error, events, attempts, worker_group, parallel_group, wake_at, enqueued_at, started_at,\n finished_at)\n WHERE c.run_id = v.run_id AND c.seq = v.seq AND c.status = 'pending'\n RETURNING c.run_id, c.seq`;\n}\n\nasync function upsertCheckpoint(db: DrizzlePgDatabase, cp: StepCheckpoint): Promise<void> {\n const row = toCheckpointRow(cp);\n await db\n .insert(stepCheckpoints)\n .values(row)\n .onConflictDoUpdate({ target: [stepCheckpoints.runId, stepCheckpoints.seq], set: row });\n}\n\n/** Rewrite a run's normalized attribute rows so the side table mirrors its live searchAttributes. */\nasync function reindexAttributes(\n db: DrizzlePgDatabase,\n runId: string,\n attributes: WorkflowRun['searchAttributes'],\n): Promise<void> {\n await db.delete(runAttributes).where(eq(runAttributes.runId, runId));\n const rows = normalizeAttributeRows(runId, attributes);\n if (rows.length) await db.insert(runAttributes).values(rows);\n}\n\n/** Children first, then the runs — checkpoints, waiters, attribute rows. Call inside a tx. */\nasync function deleteRunsCascade(db: DrizzlePgDatabase, runIds: string[]): Promise<void> {\n await db.delete(stepCheckpoints).where(inArray(stepCheckpoints.runId, runIds));\n await db.delete(signalWaiters).where(inArray(signalWaiters.runId, runIds));\n await db.delete(runAttributes).where(inArray(runAttributes.runId, runIds));\n await db.delete(workflowRuns).where(inArray(workflowRuns.id, runIds));\n}\n\nfunction fromWaiterRow(row: typeof signalWaiters.$inferSelect): SignalWaiter {\n return {\n token: row.token,\n runId: row.runId,\n seq: row.seq,\n parallelGroup: row.parallelGroup ?? undefined,\n };\n}\n\nfunction toRunRow(run: WorkflowRun): RunInsert {\n return {\n id: run.id,\n workflow: run.workflow,\n workflowVersion: run.workflowVersion,\n status: run.status,\n input: run.input ?? null,\n output: run.output ?? null,\n error: run.error ?? null,\n wakeAt: date(run.wakeAt),\n lockedBy: run.lockedBy ?? null,\n lockedUntil: date(run.lockedUntil),\n awaitingDecisionTaskId: run.awaitingDecisionTaskId ?? null,\n recoveryAttempts: run.recoveryAttempts ?? null,\n tags: run.tags ?? null,\n searchAttributes: run.searchAttributes ?? null,\n priority: run.priority ?? null,\n namespace: run.namespace || DEFAULT_NAMESPACE, // '' is the default pool too\n origin: run.origin ?? null,\n createdAt: run.createdAt,\n updatedAt: run.updatedAt,\n };\n}\n\n/** Presence (`'x' in patch`) semantics, so a patch can CLEAR a nullable column (`{ error: undefined }`\n * → NULL), matching the other adapters and the in-memory reference store. */\nfunction toRunPatch(patch: Partial<WorkflowRun>): Partial<RunInsert> {\n const row: Partial<RunInsert> = {};\n if (patch.workflow !== undefined) row.workflow = patch.workflow;\n if (patch.workflowVersion !== undefined) row.workflowVersion = patch.workflowVersion;\n if (patch.status !== undefined) row.status = patch.status;\n if ('input' in patch) row.input = patch.input ?? null;\n if ('output' in patch) row.output = patch.output ?? null;\n if ('error' in patch) row.error = patch.error ?? null;\n if ('wakeAt' in patch) row.wakeAt = date(patch.wakeAt);\n if ('lockedBy' in patch) row.lockedBy = patch.lockedBy ?? null;\n if ('lockedUntil' in patch) row.lockedUntil = date(patch.lockedUntil);\n if ('awaitingDecisionTaskId' in patch)\n row.awaitingDecisionTaskId = patch.awaitingDecisionTaskId ?? null;\n if ('recoveryAttempts' in patch) row.recoveryAttempts = patch.recoveryAttempts ?? null;\n if ('tags' in patch) row.tags = patch.tags ?? null;\n if ('searchAttributes' in patch) row.searchAttributes = patch.searchAttributes ?? null;\n if ('priority' in patch) row.priority = patch.priority ?? null;\n // Never cleared to NULL: an undefined namespace means the default one.\n if ('namespace' in patch) row.namespace = patch.namespace || DEFAULT_NAMESPACE;\n if ('origin' in patch) row.origin = patch.origin ?? null;\n if (patch.createdAt != null) row.createdAt = patch.createdAt;\n if (patch.updatedAt != null) row.updatedAt = patch.updatedAt;\n return row;\n}\n\nfunction fromRunRow(row: RunRow): WorkflowRun {\n return {\n id: row.id,\n workflow: row.workflow,\n workflowVersion: row.workflowVersion,\n status: row.status as RunStatus,\n input: row.input ?? undefined,\n output: row.output ?? undefined,\n error: (row.error ?? undefined) as StepError | undefined,\n wakeAt: ms(row.wakeAt),\n lockedBy: row.lockedBy ?? undefined,\n lockedUntil: ms(row.lockedUntil),\n awaitingDecisionTaskId: row.awaitingDecisionTaskId ?? undefined,\n recoveryAttempts: row.recoveryAttempts ?? undefined,\n tags: row.tags ?? undefined,\n searchAttributes: row.searchAttributes ?? undefined,\n priority: row.priority ?? undefined,\n namespace: row.namespace || DEFAULT_NAMESPACE, // a legacy '' row reads back as the default pool\n origin: row.origin ?? undefined,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\nfunction toCheckpointRow(cp: StepCheckpoint): CheckpointRow {\n return {\n runId: cp.runId,\n seq: cp.seq,\n name: cp.name,\n kind: cp.kind,\n stepId: cp.stepId,\n status: cp.status,\n input: cp.input ?? null,\n output: cp.output ?? null,\n error: cp.error ?? null,\n events: cp.events ?? null,\n attempts: cp.attempts,\n workerGroup: cp.workerGroup ?? null,\n parallelGroup: cp.parallelGroup ?? null,\n wakeAt: date(cp.wakeAt),\n enqueuedAt: cp.enqueuedAt ?? cp.startedAt,\n startedAt: cp.startedAt,\n finishedAt: cp.finishedAt,\n };\n}\n\nfunction fromCheckpointRow(row: CheckpointRow): StepCheckpoint {\n return {\n runId: row.runId,\n seq: row.seq,\n name: row.name,\n kind: row.kind as StepCheckpoint['kind'],\n stepId: row.stepId,\n status: row.status as StepCheckpoint['status'],\n input: row.input ?? undefined,\n output: row.output ?? undefined,\n error: (row.error ?? undefined) as StepError | undefined,\n events: (row.events ?? undefined) as StepEvent[] | undefined,\n attempts: row.attempts,\n workerGroup: row.workerGroup ?? undefined,\n parallelGroup: row.parallelGroup ?? undefined,\n wakeAt: ms(row.wakeAt),\n // Older rows may lack enqueued_at; treat the start as enqueue time (queue-wait reads zero).\n enqueuedAt: row.enqueuedAt ?? row.startedAt,\n startedAt: row.startedAt,\n finishedAt: row.finishedAt,\n };\n}\n\ntype ScheduleRow = typeof schedules.$inferSelect;\n\nfunction toScheduleRow(r: ScheduleRecord): ScheduleRow {\n return {\n id: r.id,\n namespace: r.namespace,\n workflow: r.workflow,\n paused: r.paused,\n nextFireAt: r.nextFireAt == null ? null : new Date(r.nextFireAt),\n tags: r.tags ?? null,\n spec: r.spec,\n state: r.state,\n createdAt: r.createdAt,\n updatedAt: r.updatedAt,\n };\n}\n\nfunction toSchedulePatch(\n patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>,\n): Partial<ScheduleRow> {\n const set: Partial<ScheduleRow> = {};\n if (patch.namespace !== undefined) set.namespace = patch.namespace;\n if (patch.workflow !== undefined) set.workflow = patch.workflow;\n if (patch.paused !== undefined) set.paused = patch.paused;\n if ('nextFireAt' in patch)\n set.nextFireAt = patch.nextFireAt == null ? null : new Date(patch.nextFireAt);\n if ('tags' in patch) set.tags = patch.tags ?? null;\n if (patch.spec !== undefined) set.spec = patch.spec;\n if (patch.state !== undefined) set.state = patch.state;\n if (patch.updatedAt !== undefined) set.updatedAt = patch.updatedAt;\n return set;\n}\n\nfunction fromScheduleRow(row: ScheduleRow): ScheduleRecord {\n return {\n id: row.id,\n namespace: row.namespace,\n workflow: row.workflow,\n paused: row.paused,\n nextFireAt: row.nextFireAt ? row.nextFireAt.getTime() : null,\n ...(row.tags ? { tags: row.tags } : {}),\n spec: row.spec ?? {},\n state: row.state ?? {},\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\n/**\n * The `ON CONFLICT DO UPDATE` set for a multi-row upsert: each column (or each of `only`) takes the\n * value the conflicting row proposed.\n */\nfunction excludedSet<T extends Table>(table: T, only?: string[]): Record<string, SQL> {\n return Object.fromEntries(\n Object.entries(getTableColumns(table))\n .filter(([key]) => !only || only.includes(key))\n .map(([key, column]) => [key, sql.raw(`excluded.\"${column.name}\"`)]),\n );\n}\n","import { type SQL, sql } from 'drizzle-orm';\nimport type { DrizzlePgDatabase } from './drizzle-pg-state-store';\n\n/**\n * The structural `SqlExecutor` surface `@dudousxd/nestjs-durable-transport-db`'s `DbTransport` rides\n * (declared here, not imported, so this package takes no dependency on the transport).\n */\nexport interface DrizzlePgSqlExecutor {\n readonly dialect: 'postgres';\n escapeId(id: string): string;\n query<T = unknown>(sql: string, params?: unknown[]): Promise<T[]>;\n transaction<T>(\n fn: (tx: { query<U = unknown>(sql: string, params?: unknown[]): Promise<U[]> }) => Promise<T>,\n ): Promise<T>;\n}\n\n/** Turn a `$1`-placeholder SQL string + params into a parameterized drizzle `SQL` object, so it runs\n * through whatever driver the drizzle db wraps (node-postgres, postgres-js, PGlite, Neon, …). */\nexport function toDrizzleSql(text: string, params: unknown[] = []): SQL {\n const chunks: SQL[] = [];\n let last = 0;\n for (const match of text.matchAll(/\\$(\\d+)/g)) {\n const index = Number(match[1]) - 1;\n if (index < 0 || index >= params.length)\n throw new Error(`placeholder ${match[0]} has no bound parameter`);\n chunks.push(sql.raw(text.slice(last, match.index)), sql`${params[index]}`);\n last = (match.index ?? 0) + match[0].length;\n }\n chunks.push(sql.raw(text.slice(last)));\n return sql.join(chunks);\n}\n\n/** node-postgres / PGlite hand back `{ rows }`; postgres-js hands back the row array itself. */\nexport function rowsOf<T>(result: unknown): T[] {\n if (Array.isArray(result)) return result as T[];\n return ((result as { rows?: T[] } | undefined)?.rows ?? []) as T[];\n}\n\n/**\n * Build a `DbTransport` executor from your drizzle Postgres db — the broker-less, DBOS-style\n * transport (remote steps as rows, claimed with `SELECT … FOR UPDATE SKIP LOCKED`) on the SAME\n * connection pool your app and the durable store already use:\n *\n * ```ts\n * import { DbTransport } from '@dudousxd/nestjs-durable-transport-db';\n * import { DrizzlePgStateStore, drizzlePgExecutor } from '@dudousxd/nestjs-durable-store-drizzle/pg';\n *\n * DurableModule.forRoot({\n * store: new DrizzlePgStateStore(db),\n * transport: new DbTransport({ executor: drizzlePgExecutor(db), group: 'api' }),\n * });\n * ```\n */\nexport function drizzlePgExecutor(db: DrizzlePgDatabase): DrizzlePgSqlExecutor {\n return {\n dialect: 'postgres',\n escapeId: (id) => `\"${id.replace(/\"/g, '\"\"')}\"`,\n query: async <T>(text: string, params?: unknown[]) =>\n rowsOf<T>(await db.execute(toDrizzleSql(text, params))),\n transaction: <T>(fn: Parameters<DrizzlePgSqlExecutor['transaction']>[0]) =>\n db.transaction((tx) =>\n fn({\n query: async <U>(text: string, params?: unknown[]) =>\n rowsOf<U>(await tx.execute(toDrizzleSql(text, params))),\n }),\n ) as Promise<T>,\n };\n}\n","import { getTableName } from 'drizzle-orm';\nimport {\n bigserial,\n boolean,\n doublePrecision,\n index,\n integer,\n jsonb,\n pgTable,\n primaryKey,\n text,\n timestamp,\n} from 'drizzle-orm/pg-core';\n\n// PostgreSQL schema for the durable tables. Physical table + column names are the canonical\n// cross-adapter ones (`DURABLE_CANONICAL_COLUMNS` in -testing) — the same ones the SQLite schema in\n// `../schema`, the MikroORM, TypeORM and Prisma adapters use. The Postgres-native choices:\n// - timestamps / `wake_at` / `locked_until` are `timestamptz` (like the TypeORM + MikroORM PG DDL),\n// - JSON payloads are `jsonb` (like MikroORM's PG mapping) — which is what lets `tags` be matched\n// with the GIN-indexable `@>` containment operator instead of a leading-wildcard LIKE,\n// - every string is `text` (Postgres has no `varchar(n)` speed advantage, and a signal/event token\n// can be longer than the `varchar(191)` MySQL forces on the TypeORM DDL).\n//\n// Spread `durablePgSchema` (or re-export the individual tables) from the schema file your\n// `drizzle.config.ts` points at, and drizzle-kit generates the migration for you. Or skip drizzle-kit\n// for these tables and let `DrizzlePgStateStore.ensureSchema()` create them — `./ddl` is the same DDL\n// as SQL, and a spec pins the two against each other so they can never drift.\n\n/** The namespace a run belongs to when its creating engine named none (column DEFAULT below). */\nexport const DEFAULT_NAMESPACE = 'default';\n\nconst tstz = (name: string) => timestamp(name, { withTimezone: true, mode: 'date' });\n\nexport const durableWorkflowRuns = pgTable(\n 'durable_workflow_runs',\n {\n id: text('id').primaryKey(),\n workflow: text('workflow').notNull(),\n workflowVersion: text('workflow_version').notNull(),\n status: text('status').notNull(),\n input: jsonb('input'),\n output: jsonb('output'),\n error: jsonb('error'),\n wakeAt: tstz('wake_at'),\n lockedBy: text('locked_by'),\n lockedUntil: tstz('locked_until'),\n // REMOTE turn the engine suspended on awaiting a decision; matched by completeRemoteDecision so\n // only the currently-awaited turn's decision is applied. Nullable: cleared when a decision lands.\n awaitingDecisionTaskId: text('awaiting_decision_task_id'),\n recoveryAttempts: integer('recovery_attempts'),\n tags: jsonb('tags').$type<string[]>(),\n searchAttributes: jsonb('search_attributes').$type<Record<string, string | number | boolean>>(),\n priority: integer('priority'),\n // The worker-pool partition (tenant) — THE isolation boundary every poll predicate filters on.\n // NOT NULL DEFAULT 'default' so a row can never fall outside every worker's namespace.\n namespace: text('namespace').notNull().default(DEFAULT_NAMESPACE),\n // Which package declared the workflow. Nullable, no default: NULL = unknown, never guessed.\n origin: text('origin'),\n createdAt: tstz('created_at').notNull(),\n updatedAt: tstz('updated_at').notNull(),\n },\n (t) => [\n // Timer poller (`listDueTimers`) + recovery (`listIncompleteRuns`). Same name as the TypeORM DDL.\n index('durable_runs_status_idx').on(t.status, t.wakeAt),\n // Dashboard `listRuns({ workflow, status })` and the singleton gate's per-workflow scans.\n index('durable_runs_workflow_status_idx').on(t.workflow, t.status),\n // Every namespaced poll tick: `namespace = $1 AND status = $2 ORDER BY created_at` (FIFO pick-up).\n // Name matches the MikroORM adapter + the SQLite drizzle schema so a store swap keeps the index.\n index('durable_workflow_runs_namespace_status_idx').on(t.namespace, t.status, t.createdAt),\n // `listRuns({ tag })` compiles to `tags @> '[\"tag\"]'`, which a `jsonb_path_ops` GIN index serves —\n // this is what keeps the singleton gate (`tag: singleton:<key>`, e.g. a per-tenant concurrency\n // key) an index probe instead of a scan of every run the workflow ever had.\n index('durable_runs_tags_gin_idx').using('gin', t.tags.op('jsonb_path_ops')),\n // Retention (`pruneTerminalRuns`) orders a status set by `updated_at`.\n index('durable_runs_status_updated_idx').on(t.status, t.updatedAt),\n ],\n);\n\nexport const durableStepCheckpoints = pgTable(\n 'durable_step_checkpoints',\n {\n runId: text('run_id').notNull(),\n seq: integer('seq').notNull(),\n name: text('name').notNull(),\n kind: text('kind').notNull(),\n stepId: text('step_id').notNull(),\n status: text('status').notNull(),\n input: jsonb('input'),\n output: jsonb('output'),\n error: jsonb('error'),\n events: jsonb('events'),\n attempts: integer('attempts').notNull(),\n workerGroup: text('worker_group'),\n parallelGroup: text('parallel_group'),\n wakeAt: tstz('wake_at'),\n enqueuedAt: tstz('enqueued_at'),\n startedAt: tstz('started_at').notNull(),\n finishedAt: tstz('finished_at').notNull(),\n },\n // (run_id, seq) is the primary key, so listCheckpoints / getEvent already hit an index.\n (t) => [\n primaryKey({ columns: [t.runId, t.seq] }),\n // A run detail reads one fan at a time: checkpointStats / queryCheckpoints by group, seq-paged.\n index('durable_step_checkpoints_group_idx').on(t.runId, t.parallelGroup, t.seq),\n ],\n);\n\n// Normalized search-attribute side-table: one row per (run, key), so attribute predicates push DOWN\n// into SQL as an EXISTS probe on the (key, value) indexes below instead of scan + in-process filter.\nexport const durableRunAttributes = pgTable(\n 'durable_run_attributes',\n {\n runId: text('run_id').notNull(),\n key: text('key').notNull(),\n strValue: text('str_value'),\n numValue: doublePrecision('num_value'),\n },\n (t) => [\n primaryKey({ columns: [t.runId, t.key] }),\n index('durable_run_attributes_num_idx').on(t.key, t.numValue),\n index('durable_run_attributes_str_idx').on(t.key, t.strValue),\n ],\n);\n\nexport const durableSignalWaiters = pgTable(\n 'durable_signal_waiters',\n {\n token: text('token').primaryKey(),\n runId: text('run_id').notNull(),\n seq: integer('seq').notNull(),\n parallelGroup: text('parallel_group'),\n },\n // deleteRun / pruneTerminalRuns delete a run's waiters by run_id.\n (t) => [index('durable_signal_waiters_run_id_idx').on(t.runId)],\n);\n\nexport const durableBufferedSignals = pgTable(\n 'durable_buffered_signals',\n {\n id: bigserial('id', { mode: 'number' }).primaryKey(),\n token: text('token').notNull(),\n payload: jsonb('payload'),\n },\n // Taken FIFO per token (smallest id first).\n (t) => [index('durable_buffered_signals_token_idx').on(t.token, t.id)],\n);\n\n// A published event that matched no live waiter. Keyed by a caller-minted id (engine.publishEvent)\n// so removeBufferedEvent can target that exact row.\nexport const durableBufferedEvents = pgTable(\n 'durable_buffered_events',\n {\n id: text('id').primaryKey(),\n name: text('name').notNull(),\n payload: jsonb('payload'),\n publishedAt: tstz('published_at').notNull(),\n },\n (t) => [index('durable_buffered_events_name_published_at_idx').on(t.name, t.publishedAt)],\n);\n\n// Persisted schedules (`engine.schedules`): the store filters on the columns; `spec`/`state` are\n// engine-owned JSON documents it keeps verbatim.\nexport const durableSchedules = pgTable(\n 'durable_schedules',\n {\n id: text('id').primaryKey(),\n namespace: text('namespace').notNull().default(DEFAULT_NAMESPACE),\n workflow: text('workflow').notNull(),\n paused: boolean('paused').notNull().default(false),\n nextFireAt: tstz('next_fire_at'),\n tags: jsonb('tags').$type<string[]>(),\n spec: jsonb('spec').$type<Record<string, unknown>>().notNull(),\n state: jsonb('state').$type<Record<string, unknown>>().notNull(),\n createdAt: tstz('created_at').notNull(),\n updatedAt: tstz('updated_at').notNull(),\n },\n // The poll's \"due by T\" scan: `paused = false AND next_fire_at <= T ORDER BY next_fire_at`.\n (t) => [index('durable_schedules_due_idx').on(t.paused, t.nextFireAt)],\n);\n\n/**\n * Every durable table, keyed by the name to export it under. Spread into your drizzle-kit schema file\n * (`export const { durableWorkflowRuns, ... } = durablePgSchema;` or `export * from` the `/pg` entry)\n * so `drizzle-kit generate` emits the durable DDL alongside your own tables.\n */\nexport const durablePgSchema = {\n durableWorkflowRuns,\n durableStepCheckpoints,\n durableRunAttributes,\n durableSignalWaiters,\n durableBufferedSignals,\n durableBufferedEvents,\n durableSchedules,\n};\n\n/**\n * The durable table names, derived from {@link durablePgSchema} (one list, never drifts). Feed to a\n * migration tool's exclude list — e.g. drizzle-kit `tablesFilter: ['!durable_*']` — if you let\n * `ensureSchema()` own these tables instead of drizzle-kit.\n */\nexport function durablePgManagedTables(): string[] {\n return Object.values(durablePgSchema).map((table) => getTableName(table));\n}\n"],"mappings":"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","names":["DURABLE_PG_DDL","SCHEMA_LOCK_KEY","ensureDrizzlePgDurableSchema","db","transaction","tx","execute","sql","statement","raw","import_drizzle_orm","import_drizzle_orm","toDrizzleSql","text","params","chunks","last","match","matchAll","index","Number","length","Error","push","sql","raw","slice","join","rowsOf","result","Array","isArray","rows","drizzlePgExecutor","db","dialect","escapeId","id","replace","query","execute","transaction","fn","tx","import_drizzle_orm","DEFAULT_NAMESPACE","tstz","name","timestamp","withTimezone","mode","durableWorkflowRuns","pgTable","id","text","primaryKey","workflow","notNull","workflowVersion","status","input","jsonb","output","error","wakeAt","lockedBy","lockedUntil","awaitingDecisionTaskId","recoveryAttempts","integer","tags","$type","searchAttributes","priority","namespace","default","origin","createdAt","updatedAt","t","index","on","using","op","durableStepCheckpoints","runId","seq","kind","stepId","events","attempts","workerGroup","parallelGroup","enqueuedAt","startedAt","finishedAt","columns","durableRunAttributes","key","strValue","numValue","doublePrecision","durableSignalWaiters","token","durableBufferedSignals","bigserial","payload","durableBufferedEvents","publishedAt","durableSchedules","paused","boolean","nextFireAt","spec","state","durablePgSchema","durablePgManagedTables","Object","values","map","table","getTableName","anyOf","conditions","present","filter","c","undefined","length","or","sql","namespaceFilter","namespace","DEFAULT_NAMESPACE","inArray","workflowRuns","eq","hasTag","tag","tags","JSON","stringify","date","ms","Date","d","getTime","DrizzlePgStateStore","scopeNamespace","db","options","scope","withScope","ensureSchema","ensureDrizzlePgDurableSchema","tryAdmitSingleton","runId","workflow","limit","retryWakeAt","transaction","tx","where","and","status","SINGLETON_ACTIVE_STATUSES","update","set","rows","select","from","runs","map","fromRunRow","singletonAdmissionTags","patch","singletonAdmissionDenialPatch","toRunPatch","id","createRun","run","insert","values","toRunRow","reindexAttributes","searchAttributes","updateRun","inputPatch","TERMINAL_RUN_STATUSES","includes","clearTerminalSingletonAdmission","getRun","row","reindex","Object","keys","updateRunIf","expectedStatuses","matches","applied","returning","for","deleteRun","deleteRunsCascade","deleteRuns","runIds","pruneTerminalRuns","policy","nowMs","statuses","s","maxAge","maxCount","scoped","runFilters","ids","Set","cutoff","parseDuration","lt","updatedAt","orderBy","asc","skipLocked","r","add","size","desc","offset","idList","slice","getCheckpoint","seq","stepCheckpoints","fromCheckpointRow","saveCheckpoint","checkpoint","upsertCheckpoint","saveCheckpointIfPending","toCheckpointRow","saveCheckpointsIfPending","checkpoints","wrote","round","distinctRounds","at","CHECKPOINT_BATCH_ROWS","chunk","updated","rowsOf","execute","updateIfPendingFrom","i","byKey","Map","rowKey","get","run_id","Number","work","raw","cp","listIncompleteRuns","listOrphanedRuns","ownedBy","isNull","lockedUntil","lte","lockedBy","owner","lockedBefore","createdAt","listPendingRuns","listDueTimers","query","isNotNull","wakeAt","tryLockRun","leaseUntilMs","releaseRunLock","renewRunLock","workflows","namespaces","origin","origins","o","attributes","f","attributeExists","listRuns","filters","base","$dynamic","countRuns","count","mapWith","runFacets","groupBy","mergeRunFacetRows","runValueFacets","axis","opts","axisIsRunColumn","scan","RUN_VALUE_FACET_SCAN","runValueFacetsFromRuns","column","field","value","mergeRunValueFacetRows","comparisons","attributePredicateOperands","comparator","operand","runAttributes","numValue","strValue","exists","one","key","saveSchedule","record","toScheduleRow","schedules","onConflictDoUpdate","target","getSchedule","fromScheduleRow","updateSchedule","expectedNextFireAt","toSchedulePatch","nextFireAt","deleteSchedule","delete","listSchedules","paused","dueBy","listCheckpoints","getLatestCheckpointByName","name","countCheckpoints","fromSeq","toSeq","gte","listCheckpointsByNamePrefix","prefixes","p","like","escapeLike","checkpointStats","nameKind","as","group","parallelGroup","minSeq","maxSeq","minName","maxName","minEnqueuedAt","enqueuedAt","startedAt","minStartedAt","maxStartedAt","maxFinishedAt","finishedAt","sumAttempts","attempts","queryCheckpoints","namePrefixes","excludeGroups","notInArray","putSignalWaiter","waiter","signalWaiters","token","takeSignalWaiter","fromWaiterRow","listSignalWaiters","prefix","registerChildWaits","entries","excludedSet","compactCheckpoints","into","listSignalWaitersByRun","hasSignalWaiter","tokenPrefix","removeSignalWaiter","bufferSignal","payload","bufferedSignals","takeBufferedSignal","oldest","bufferEvent","input","bufferedEvents","publishedAt","listBufferedEvents","removeBufferedEvent","replace","rounds","seen","forEach","indexes","push","json","v","ts","toISOString","kind","stepId","output","error","events","workerGroup","join","normalizeAttributeRows","workflowVersion","awaitingDecisionTaskId","recoveryAttempts","priority","spec","state","table","only","fromEntries","getTableColumns"]}
|