@dudousxd/nestjs-durable-store-prisma 0.21.0 → 0.22.1
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 +49 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -99,6 +99,26 @@ var PrismaStateStore = class {
|
|
|
99
99
|
});
|
|
100
100
|
if ("searchAttributes" in patch) await this.reindexAttributes(runId, patch.searchAttributes);
|
|
101
101
|
}
|
|
102
|
+
async updateRunIf(runId, expectedStatuses, inputPatch) {
|
|
103
|
+
if (expectedStatuses.length === 0) return false;
|
|
104
|
+
const patch = inputPatch.status && import_nestjs_durable_core.TERMINAL_RUN_STATUSES.includes(inputPatch.status) ? await (0, import_nestjs_durable_core.clearTerminalSingletonAdmission)(runId, inputPatch, (id) => this.getRun(id)) : inputPatch;
|
|
105
|
+
const where = {
|
|
106
|
+
id: runId,
|
|
107
|
+
status: {
|
|
108
|
+
in: expectedStatuses
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const data = toRunPatch(patch);
|
|
112
|
+
const count = Object.keys(data).length ? (await this.db.durableWorkflowRun.updateMany({
|
|
113
|
+
where,
|
|
114
|
+
data
|
|
115
|
+
})).count : await this.db.durableWorkflowRun.count({
|
|
116
|
+
where
|
|
117
|
+
});
|
|
118
|
+
if (count === 0) return false;
|
|
119
|
+
if ("searchAttributes" in patch) await this.reindexAttributes(runId, patch.searchAttributes);
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
102
122
|
/** Rewrite a run's normalized attribute rows: delete the old set, insert the current one. Mirrors
|
|
103
123
|
* the in-memory store's reindex so the side-table always reflects the run's live searchAttributes. */
|
|
104
124
|
async reindexAttributes(runId, attributes) {
|
|
@@ -322,6 +342,35 @@ var PrismaStateStore = class {
|
|
|
322
342
|
});
|
|
323
343
|
return rows.map(fromRunRow);
|
|
324
344
|
}
|
|
345
|
+
async listOrphanedRuns(nowMs, limit, namespace) {
|
|
346
|
+
if (limit <= 0) return [];
|
|
347
|
+
const rows = await this.db.durableWorkflowRun.findMany({
|
|
348
|
+
where: {
|
|
349
|
+
status: {
|
|
350
|
+
in: [
|
|
351
|
+
"running",
|
|
352
|
+
"cancelling"
|
|
353
|
+
]
|
|
354
|
+
},
|
|
355
|
+
OR: [
|
|
356
|
+
{
|
|
357
|
+
lockedUntil: null
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
lockedUntil: {
|
|
361
|
+
lte: new Date(nowMs)
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
],
|
|
365
|
+
...namespaceWhere(namespace)
|
|
366
|
+
},
|
|
367
|
+
orderBy: {
|
|
368
|
+
createdAt: "asc"
|
|
369
|
+
},
|
|
370
|
+
take: limit
|
|
371
|
+
});
|
|
372
|
+
return rows.map(fromRunRow);
|
|
373
|
+
}
|
|
325
374
|
async listPendingRuns(limit, namespace) {
|
|
326
375
|
const rows = await this.db.durableWorkflowRun.findMany({
|
|
327
376
|
where: {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/prisma-state-store.ts","../src/schema.ts"],"sourcesContent":["export * from './prisma-state-store';\nexport * from './schema';\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 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';\n\n/* The Prisma client is generated per-schema, so the adapter can't import a concrete one. Instead\n it depends on this structural surface — the three model delegates and the methods it uses. A\n real `PrismaClient` (with the models from prisma/schema.prisma added) satisfies it. Query-arg\n shapes are Prisma's own generics, so they're left as `any` at this single boundary; the row\n return types are precise, which is what the mapping code below relies on. */\n\ninterface RunRow {\n id: string;\n workflow: string;\n workflowVersion: string;\n status: string;\n input: unknown;\n output: unknown;\n error: unknown;\n wakeAt: bigint | null;\n lockedBy: string | null;\n lockedUntil: Date | null;\n awaitingDecisionTaskId: string | null;\n recoveryAttempts: number | null;\n tags: unknown;\n searchAttributes: unknown;\n priority: number | null;\n /** NOT NULL in the schema (defaulted to `'default'`), so every row carries a real namespace. */\n namespace: string;\n origin: string | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface CheckpointRow {\n runId: string;\n seq: number;\n name: string;\n kind: string;\n stepId: string;\n status: string;\n input: unknown;\n output: unknown;\n error: unknown;\n events: unknown;\n attempts: number;\n workerGroup: string | null;\n parallelGroup: string | null;\n wakeAt: bigint | null;\n enqueuedAt: Date | null;\n startedAt: Date;\n finishedAt: Date;\n}\n\ninterface WaiterRow {\n token: string;\n runId: string;\n seq: number;\n parallelGroup: string | null;\n}\n\ninterface RunAttributeRow {\n runId: string;\n key: string;\n strValue: string | null;\n numValue: number | null;\n}\n\ninterface BufferedSignalRow {\n id: bigint;\n token: string;\n payload: unknown;\n}\n\ninterface BufferedEventRow {\n id: string;\n name: string;\n payload: unknown;\n publishedAt: bigint;\n}\n\n// Prisma's per-model query args are generated generics; left as `any` at this single boundary.\ntype Args = any;\n\ninterface Delegate<Row> {\n create(args: Args): Promise<Row>;\n createMany(args: Args): Promise<{ count: number }>;\n findUnique(args: Args): Promise<Row | null>;\n findFirst(args?: Args): Promise<Row | null>;\n findMany(args?: Args): Promise<Row[]>;\n update(args: Args): Promise<Row>;\n updateMany(args: Args): Promise<{ count: number }>;\n upsert(args: Args): Promise<Row>;\n delete(args: Args): Promise<Row>;\n deleteMany(args?: Args): Promise<{ count: number }>;\n count(args?: Args): Promise<number>;\n /** Aggregate form — used by the run facets and `checkpointStats`, whose rows are aggregate cells,\n * not model rows, so the result type is stated at the call site rather than derived from `Row`. */\n groupBy(args: Args): Promise<Record<string, unknown>[]>;\n}\n\ninterface ScheduleRow {\n id: string;\n namespace: string;\n workflow: string;\n paused: boolean;\n nextFireAt: bigint | null;\n tags: unknown;\n spec: unknown;\n state: unknown;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface DurablePrismaTx {\n durableWorkflowRun: Delegate<RunRow>;\n durableStepCheckpoint: Delegate<CheckpointRow>;\n durableRunAttribute: Delegate<RunAttributeRow>;\n durableSignalWaiter: Delegate<WaiterRow>;\n durableBufferedSignal: Delegate<BufferedSignalRow>;\n durableBufferedEvent: Delegate<BufferedEventRow>;\n /** Only needed for persisted schedules (`engine.schedules`) — add the `DurableSchedule` model. */\n durableSchedule?: Delegate<ScheduleRow>;\n}\n\nexport interface DurablePrismaClient extends DurablePrismaTx {\n /** Prisma's interactive-transaction form: runs `fn` with a tx-scoped client and commits on resolve. */\n $transaction<T>(fn: (tx: DurablePrismaTx) => Promise<T>): Promise<T>;\n}\n\n/**\n * The `namespace` read boundary as a spreadable Prisma `where` fragment.\n *\n * `undefined` means NO RESTRICTION — `{}` — because that is the operator (control-plane) view that\n * sees every tenant, and it is what the engine passes when it runs unscoped. It does NOT mean\n * \"namespace IS NULL\": the column is NOT NULL, so `{ namespace: undefined }` would be Prisma's\n * \"ignore this predicate\" anyway, but `{ namespace: null }` would match nothing in production while\n * still looking correct in a single-tenant test where every worker polls unscoped.\n *\n * A named namespace is plain equality, so a worker sees only its own tenant's rows — the boundary\n * {@link WorkflowRun.namespace} promises for the four worker paths (pick up, recover, resume timers,\n * time out).\n */\nfunction namespaceWhere(namespace?: string): { namespace?: string } {\n if (namespace === undefined) return {};\n return { namespace };\n}\n\n/**\n * Prisma-backed `StateStore`. Pass your `PrismaClient` after adding the models from\n * `prisma/schema.prisma` to your schema. JSON columns carry the run/step payloads directly;\n * `wakeAt` is a `BigInt` (epoch ms).\n *\n * Every path a worker acts on is namespace-scoped when it is given one — `listPendingRuns` (pick up),\n * `listIncompleteRuns` (recover), `listDueTimers` (resume timers) and `listRuns`'s `namespace`\n * (the engine's timeout sweep). Omit it for the operator view across all tenants. Point-reads\n * (`getRun`, checkpoints) are deliberately NOT scoped, per {@link StateStore}.\n */\nexport class PrismaStateStore implements StateStore {\n constructor(private readonly db: DurablePrismaClient) {}\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 = { workflow, status: { in: SINGLETON_ACTIVE_STATUSES } };\n // A locking write first: concurrent claims cannot read the same free slot.\n await tx.durableWorkflowRun.updateMany({ where, data: { workflow } });\n const rows = await tx.durableWorkflowRun.findMany({ 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.durableWorkflowRun.update({ where: { id: runId }, data: toRunPatch(patch) });\n return false;\n }\n await tx.durableWorkflowRun.update({ where: { id: runId }, data: { tags } });\n return true;\n });\n }\n\n async createRun(run: WorkflowRun): Promise<void> {\n await this.db.durableWorkflowRun.create({ data: toRunData(run) });\n await this.reindexAttributes(run.id, run.searchAttributes);\n }\n\n async updateRun(runId: string, inputPatch: Partial<WorkflowRun>): Promise<void> {\n const patch =\n inputPatch.status && TERMINAL_RUN_STATUSES.includes(inputPatch.status)\n ? await clearTerminalSingletonAdmission(runId, inputPatch, (id) => this.getRun(id))\n : inputPatch;\n await this.db.durableWorkflowRun.update({ where: { id: runId }, data: toRunPatch(patch) });\n // Keep the side-table in step with the run's attributes whenever they're patched.\n if ('searchAttributes' in patch) await this.reindexAttributes(runId, patch.searchAttributes);\n }\n\n /** Rewrite a run's normalized attribute rows: delete the old set, insert the current one. Mirrors\n * the in-memory store's reindex so the side-table always reflects the run's live searchAttributes. */\n private async reindexAttributes(\n runId: string,\n attributes: WorkflowRun['searchAttributes'],\n ): Promise<void> {\n await this.db.durableRunAttribute.deleteMany({ where: { runId } });\n const rows = normalizeAttributeRows(runId, attributes);\n if (rows.length) await this.db.durableRunAttribute.createMany({ data: rows });\n }\n\n async getRun(runId: string): Promise<WorkflowRun | null> {\n const row = await this.db.durableWorkflowRun.findUnique({ where: { id: runId } });\n return row ? fromRunRow(row) : null;\n }\n\n async deleteRun(runId: string): Promise<void> {\n // Child rows first, then the run — checkpoints, signal waiters, attribute rows.\n await this.db.durableStepCheckpoint.deleteMany({ where: { runId } });\n await this.db.durableSignalWaiter.deleteMany({ where: { runId } });\n await this.db.durableRunAttribute.deleteMany({ where: { runId } });\n await this.db.durableWorkflowRun.deleteMany({ where: { id: runId } });\n }\n\n async deleteRuns(runIds: string[]): Promise<void> {\n if (runIds.length === 0) return;\n // Same cascade as deleteRun, one `IN (...)` per table, atomically.\n await this.db.$transaction(async (tx) => {\n await tx.durableStepCheckpoint.deleteMany({ where: { runId: { in: runIds } } });\n await tx.durableSignalWaiter.deleteMany({ where: { runId: { in: runIds } } });\n await tx.durableRunAttribute.deleteMany({ where: { runId: { in: runIds } } });\n await tx.durableWorkflowRun.deleteMany({ where: { id: { in: 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.runWhere({ ...(policy.scope ?? {}), statuses });\n const ids = new Set<string>();\n if (policy.maxAge != null) {\n const cutoff = new Date(nowMs - parseDuration(policy.maxAge));\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { AND: [scoped, { updatedAt: { lt: cutoff } }] },\n select: { id: true },\n orderBy: { updatedAt: 'asc' }, // oldest first\n take: limit,\n });\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 scoped status set (skipped by OFFSET).\n const rows = await this.db.durableWorkflowRun.findMany({\n where: scoped,\n select: { id: true },\n orderBy: [{ updatedAt: 'desc' }, { id: 'desc' }],\n skip: policy.maxCount,\n take: limit,\n });\n for (const r of rows) {\n if (ids.size >= limit) break;\n ids.add(r.id);\n }\n }\n const doomed = [...ids].slice(0, limit);\n await this.deleteRuns(doomed);\n return doomed.length;\n }\n\n async getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null> {\n const row = await this.db.durableStepCheckpoint.findUnique({\n where: { runId_seq: { runId, seq } },\n });\n return row ? fromCheckpointRow(row) : null;\n }\n\n async saveCheckpoint(checkpoint: StepCheckpoint): Promise<void> {\n const data = toCheckpointData(checkpoint);\n await this.db.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: checkpoint.runId, seq: checkpoint.seq } },\n create: data,\n update: data,\n });\n }\n\n async saveCheckpointIfPending(checkpoint: StepCheckpoint): Promise<boolean> {\n // One conditional `updateMany` (`UPDATE … WHERE run_id = ? AND seq = ? AND status = 'pending'`):\n // the status predicate is the compare, the row count the answer, and a missing row is never made.\n const { runId, seq, ...data } = toCheckpointData(checkpoint);\n const { count } = await this.db.durableStepCheckpoint.updateMany({\n where: { runId, seq, status: 'pending' },\n data,\n });\n return count > 0;\n }\n\n async saveCheckpointsIfPending(checkpoints: StepCheckpoint[]): Promise<boolean[]> {\n if (checkpoints.length === 0) return [];\n // The conditional `updateMany` of `saveCheckpointIfPending`, once per entry, in order, in one\n // transaction: one commit for the batch, and a rejection writes nothing.\n return this.db.$transaction(async (tx) => {\n const wrote: boolean[] = [];\n for (const checkpoint of checkpoints) {\n const { runId, seq, ...data } = toCheckpointData(checkpoint);\n const { count } = await tx.durableStepCheckpoint.updateMany({\n where: { runId, seq, status: 'pending' },\n data,\n });\n wrote.push(count > 0);\n }\n return wrote;\n });\n }\n\n async transaction<T>(\n work: (tx: {\n raw: unknown;\n saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;\n }) => Promise<T>,\n ): Promise<T> {\n return this.db.$transaction(async (tx) =>\n work({\n raw: tx,\n saveCheckpoint: async (cp) => {\n const data = toCheckpointData(cp);\n await tx.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: cp.runId, seq: cp.seq } },\n create: data,\n update: data,\n });\n },\n }),\n );\n }\n\n async listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: { in: ['running', 'cancelling'] }, ...namespaceWhere(namespace) },\n });\n return rows.map(fromRunRow);\n }\n\n async listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: 'pending', ...namespaceWhere(namespace) },\n orderBy: { createdAt: 'asc' }, // FIFO dispatch\n take: limit,\n });\n return rows.map(fromRunRow);\n }\n\n async listDueTimers(nowMs: number, namespace?: string, limit?: number): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: {\n status: 'suspended',\n wakeAt: { not: null, lte: BigInt(nowMs) },\n ...namespaceWhere(namespace),\n },\n orderBy: { wakeAt: 'asc' },\n ...(limit !== undefined ? { take: limit } : {}),\n });\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 const result = await this.db.durableWorkflowRun.updateMany({\n where: {\n id: runId,\n OR: [{ lockedUntil: null }, { lockedUntil: { lte: new Date(nowMs) } }],\n },\n data: { lockedBy: owner, lockedUntil: new Date(leaseUntilMs) },\n });\n return result.count === 1;\n }\n\n async releaseRunLock(runId: string): Promise<void> {\n // Idempotent by design: releasing the lease on a run that no longer exists is a no-op, not an\n // error. The engine calls this best-effort in a `finally` AFTER the run has settled, so it can\n // race a concurrent purge/teardown — Prisma's `update({ where: { id } })` would throw P2025\n // (\"No record was found for an update\") on that race and, since the call is fire-and-forget on\n // the engine's terminal path, surface as an unhandled rejection. `updateMany` matches a 0-row\n // WHERE to an empty result (no throw), mirroring the in-memory store's `if (run)` guard and the\n // set-where semantics of every sibling adapter (TypeORM/MikroORM/Drizzle).\n await this.db.durableWorkflowRun.updateMany({\n where: { id: runId },\n data: { lockedBy: null, lockedUntil: null },\n });\n }\n\n async renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean> {\n const result = await this.db.durableWorkflowRun.updateMany({\n where: { id: runId, lockedBy: owner },\n data: { lockedUntil: new Date(leaseUntilMs) },\n });\n return result.count === 1;\n }\n\n /** The `where` every run query shares — {@link listRuns} pages it, {@link runFacets} groups it. */\n private runWhere(query: RunQuery): Record<string, unknown> {\n // The tenant boundary, and NOT only a dashboard facet: the engine's `sweepTimeouts` finds the runs\n // it may cancel through `listRuns({ workflow, status, namespace })`, so an unfiltered `namespace`\n // here lets a worker serving one tenant time out another tenant's runs — a write, not a stale\n // read. Same `undefined` = no restriction rule as the poll paths above (see `namespaceWhere`),\n // which is what keeps the operator's dashboard showing every tenant by default.\n const where: Record<string, unknown> = { ...namespaceWhere(query.namespace) };\n // The plural predicates below can't sit on `where` directly (a key holds one condition, and the\n // single form may already own it), so they accumulate here and are ANDed at the end. Each is ORed\n // within itself and matches NOTHING when empty — the contract `statuses` already had.\n const and: Record<string, unknown>[] = [];\n if (query.workflow) where.workflow = query.workflow;\n if (query.workflows) and.push(anyOf(query.workflows.map((w) => ({ workflow: w }))));\n if (query.namespaces) and.push(anyOf(query.namespaces.map((n) => ({ namespace: n }))));\n // Which library registered the workflow. Plain equality, so a run whose origin is NULL (created\n // before the column existed, or registered through a path the derivation could not classify)\n // matches NO origin value — it is never folded into a bucket to make the facet look complete.\n // Unknown-origin runs are reachable only with the filter OFF, so \"all origins\" must stay the\n // default view; a dashboard that filtered by default would make those runs look deleted.\n // Passing `null` asks for exactly the unattributed bucket (`origin IS NULL`) — Prisma spells that\n // as the same equality — which is how a paginated console can offer an \"unknown\" chip.\n if (query.origin !== undefined) where.origin = query.origin;\n // `null` is a member like any other in a set of origins — Prisma spells `origin IS NULL` as the\n // same equality — so one branch per value covers both the named ones and the unattributed bucket.\n if (query.origins) and.push(anyOf(query.origins.map((o) => ({ origin: o }))));\n // `status IN (...)`; an empty set matches nothing (mirrors the in-memory store). Combined with the\n // single-value `status` via AND when both are present, so the narrower set wins.\n if (query.status && query.statuses) {\n and.push({ status: query.status }, { status: { in: query.statuses } });\n } else if (query.status) {\n where.status = query.status;\n } else if (query.statuses) {\n where.status = { in: query.statuses };\n }\n if (query.tag) where.tags = { array_contains: query.tag };\n if (query.tags) and.push(anyOf(query.tags.map((t) => ({ tags: { array_contains: t } }))));\n // Typed/range attribute predicates push DOWN into SQL: each filter becomes a relation `some`\n // (EXISTS) on the normalized `durable_run_attributes` side-table, so the DB filters AND paginates\n // — no full scan + in-process filter. ANDed: a run must match every filter, so one `some` each.\n if (query.attributes?.length) and.push(...query.attributes.map((f) => attributeSome(f)));\n if (and.length) where.AND = and;\n return where;\n }\n\n async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n const orderBy = { createdAt: 'desc' as const }; // newest first — recent runs on top in the dashboard\n const rows = await this.db.durableWorkflowRun.findMany({\n where: this.runWhere(query),\n take: query.limit,\n skip: query.offset,\n orderBy,\n });\n return rows.map(fromRunRow);\n }\n\n async countRuns(query: Omit<RunQuery, 'limit' | 'offset'>): Promise<number> {\n return this.db.durableWorkflowRun.count({ where: this.runWhere(query) });\n }\n\n /** `GROUP BY status, origin` over the same predicates {@link listRuns} pages — one aggregate, so a\n * console can show whole-set counts next to a bounded page instead of downloading every run to\n * count them in the browser. */\n async runFacets(query: RunFacetQuery): Promise<RunFacetRow[]> {\n const rows = (await this.db.durableWorkflowRun.groupBy({\n by: ['status', 'origin'],\n where: this.runWhere(query),\n _count: { _all: true },\n })) as { status: RunStatus; origin: string | null; _count: { _all: number } }[];\n return mergeRunFacetRows(\n rows.map((r) => ({ status: r.status, origin: r.origin, count: r._count._all })),\n );\n }\n\n /** Distinct values of one filter axis over the same predicates {@link listRuns} pages. A run-table\n * column is a `groupBy` like {@link runFacets}, exact over the whole matching set; the tag and\n * attribute axes live outside the row (json column / side table) and are counted from a bounded\n * page of runs instead — see `RunValueFacetOptions.scan`. */\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 rows = (await this.db.durableWorkflowRun.groupBy({\n by: [axis.field],\n where: this.runWhere(query),\n _count: { _all: true },\n })) as (Record<string, string | null> & { _count: { _all: number } })[];\n return mergeRunValueFacetRows(\n rows.map((r) => ({ value: r[axis.field] ?? null, count: r._count._all })),\n opts,\n );\n }\n\n // ---- persisted schedules ----------------------------------------------------------------------\n\n private schedules(): Delegate<ScheduleRow> {\n const delegate = this.db.durableSchedule;\n if (!delegate) {\n throw new Error(\n 'persisted schedules need the DurableSchedule model — copy it from prisma/schema.prisma into your schema and re-run `prisma generate`',\n );\n }\n return delegate;\n }\n\n async saveSchedule(record: ScheduleRecord): Promise<void> {\n const data = toScheduleData(record);\n await this.schedules().upsert({ where: { id: record.id }, create: data, update: data });\n }\n\n async getSchedule(id: string): Promise<ScheduleRecord | null> {\n const row = await this.schedules().findUnique({ where: { id } });\n return row ? fromScheduleRow(row) : null;\n }\n\n /** One conditional `updateMany`: the compare-and-set on `next_fire_at` is a single statement. */\n async updateSchedule(\n id: string,\n patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>,\n expectedNextFireAt?: number | null,\n ): Promise<boolean> {\n const data: Record<string, unknown> = {};\n if (patch.namespace !== undefined) data.namespace = patch.namespace;\n if (patch.workflow !== undefined) data.workflow = patch.workflow;\n if (patch.paused !== undefined) data.paused = patch.paused;\n if ('nextFireAt' in patch)\n data.nextFireAt = patch.nextFireAt == null ? null : BigInt(patch.nextFireAt);\n if ('tags' in patch) data.tags = jsonOrNull(patch.tags);\n if (patch.spec !== undefined) data.spec = patch.spec;\n if (patch.state !== undefined) data.state = patch.state;\n if (patch.updatedAt !== undefined) data.updatedAt = patch.updatedAt;\n if (!Object.keys(data).length) return (await this.getSchedule(id)) !== null;\n const where: Record<string, unknown> = { id };\n if (expectedNextFireAt !== undefined)\n where.nextFireAt = expectedNextFireAt === null ? null : BigInt(expectedNextFireAt);\n const { count } = await this.schedules().updateMany({ where, data });\n return count > 0;\n }\n\n async deleteSchedule(id: string): Promise<boolean> {\n const { count } = await this.schedules().deleteMany({ where: { id } });\n return count > 0;\n }\n\n async listSchedules(query: ScheduleQuery): Promise<ScheduleRecord[]> {\n const where: Record<string, unknown> = {};\n if (query.namespace !== undefined) where.namespace = query.namespace;\n if (query.workflow !== undefined) where.workflow = query.workflow;\n if (query.paused !== undefined) where.paused = query.paused;\n if (query.tag !== undefined) where.tags = { array_contains: query.tag };\n if (query.dueBy !== undefined) {\n where.AND = [{ paused: false }, { nextFireAt: { lte: BigInt(query.dueBy) } }];\n }\n const rows = await this.schedules().findMany({\n where,\n // Soonest-due first, never-firing (NULL) last, id as the stable tie-break.\n orderBy: [{ nextFireAt: { sort: 'asc', nulls: 'last' } }, { id: 'asc' }],\n take: query.limit,\n skip: query.offset,\n });\n return rows.map(fromScheduleRow);\n }\n\n async listCheckpoints(runId: string): Promise<StepCheckpoint[]> {\n const rows = await this.db.durableStepCheckpoint.findMany({\n where: { runId },\n orderBy: { seq: 'asc' },\n });\n return rows.map(fromCheckpointRow);\n }\n\n async getLatestCheckpointByName(\n runId: string,\n name: string,\n ): Promise<StepCheckpoint | undefined> {\n const row = await this.db.durableStepCheckpoint.findFirst({\n where: { runId, name },\n orderBy: { seq: 'desc' },\n });\n return row ? fromCheckpointRow(row) : 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 return this.db.durableStepCheckpoint.count({\n where: { runId, seq: { gte: fromSeq, lte: toSeq }, status: { in: statuses } },\n });\n }\n\n async listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]> {\n if (prefixes.length === 0) return [];\n const rows = await this.db.durableStepCheckpoint.findMany({\n where: { runId, OR: prefixes.map((p) => ({ name: { startsWith: p } })) },\n orderBy: { seq: 'asc' },\n });\n // On some providers (SQLite) `startsWith` compiles to a `LIKE` that reads `_` and `%` as wildcards,\n // so it can match more than the prefix: keep only the exact matches.\n return rows.filter((r) => prefixes.some((p) => r.name.startsWith(p))).map(fromCheckpointRow);\n }\n\n /**\n * One `groupBy(parallelGroup, status)` per {@link CheckpointNameKind}, each narrowed to its kind by\n * a name-prefix predicate, run concurrently — Prisma cannot group by a `CASE`, so the kind is the\n * `where` instead. `minEnqueuedAt` reads a NULL `enqueuedAt` as `startedAt` (as\n * {@link fromCheckpointRow} does): a bucket whose non-null `enqueuedAt` count falls short of its\n * row count has such rows, and only for those kinds is the NULL subset's `min(startedAt)` asked for.\n *\n * On SQLite `startsWith` is a case-insensitive `LIKE`, as in {@link listCheckpointsByNamePrefix};\n * the kind prefixes are lower-case and wildcard-free, so only a step whose name starts with one of\n * them in another case would be classified differently there.\n */\n async checkpointStats(\n runId: string,\n opts?: { group?: string | undefined },\n ): Promise<CheckpointStat[]> {\n const scope = opts?.group === undefined ? { runId } : { runId, parallelGroup: opts.group };\n const grouped = await Promise.all(\n NAME_KINDS.map(async ({ kind, where }) => ({\n kind,\n where,\n rows: (await this.db.durableStepCheckpoint.groupBy({\n by: ['parallelGroup', 'status'],\n where: { ...scope, ...where },\n _count: { _all: true, enqueuedAt: true },\n _min: { seq: true, name: true, enqueuedAt: true, startedAt: true },\n _max: { seq: true, name: true, startedAt: true, finishedAt: true },\n _sum: { attempts: true },\n })) as CheckpointStatRow[],\n })),\n );\n const stats = await Promise.all(\n grouped.map(async ({ kind, where, rows }) => {\n const unenqueued = rows.some((r) => r._count.enqueuedAt < r._count._all)\n ? await this.unenqueuedStartedAt({ ...scope, ...where })\n : new Map<string, Date>();\n return rows.map((r) => toCheckpointStat(kind, r, unenqueued));\n }),\n );\n return stats.flat();\n }\n\n /** `min(startedAt)` per `(parallelGroup, status)` over the rows whose `enqueuedAt` is NULL. */\n private async unenqueuedStartedAt(where: Record<string, unknown>): Promise<Map<string, Date>> {\n const rows = (await this.db.durableStepCheckpoint.groupBy({\n by: ['parallelGroup', 'status'],\n where: { ...where, enqueuedAt: null },\n _min: { startedAt: true },\n })) as { parallelGroup: string | null; status: string; _min: { startedAt: Date } }[];\n return new Map(rows.map((r) => [bucketKey(r.parallelGroup, r.status), r._min.startedAt]));\n }\n\n /** {@link CheckpointQuery} as one `findMany`, in `seq` order, paged by `skip`/`take`. Ungrouped rows\n * are kept past `excludeGroups` explicitly: `NOT IN` alone drops a NULL `parallelGroup`. */\n async queryCheckpoints(runId: string, query: CheckpointQuery): Promise<StepCheckpoint[]> {\n if (query.statuses?.length === 0 || query.namePrefixes?.length === 0) return [];\n const and: Record<string, unknown>[] = [];\n if (query.excludeGroups?.length) {\n and.push({\n OR: [{ parallelGroup: null }, { parallelGroup: { notIn: query.excludeGroups } }],\n });\n }\n if (query.namePrefixes) {\n and.push({ OR: query.namePrefixes.map((p) => ({ name: { startsWith: p } })) });\n }\n const rows = await this.db.durableStepCheckpoint.findMany({\n where: {\n runId,\n ...(query.group === undefined ? {} : { parallelGroup: query.group }),\n ...(query.statuses ? { status: { in: query.statuses } } : {}),\n ...(and.length ? { AND: and } : {}),\n },\n orderBy: { seq: 'asc' },\n skip: query.offset,\n take: query.limit,\n });\n return rows.map(fromCheckpointRow);\n }\n\n async putSignalWaiter(waiter: SignalWaiter): Promise<void> {\n await this.db.durableSignalWaiter.upsert({\n where: { token: waiter.token },\n create: {\n token: waiter.token,\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n },\n update: {\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n },\n });\n }\n\n async takeSignalWaiter(token: string): Promise<SignalWaiter | null> {\n const row = await this.db.durableSignalWaiter.findUnique({ where: { token } });\n if (!row) return null;\n await this.db.durableSignalWaiter.delete({ where: { token } });\n return {\n token: row.token,\n runId: row.runId,\n seq: row.seq,\n parallelGroup: row.parallelGroup ?? undefined,\n };\n }\n\n async listSignalWaiters(prefix: string): Promise<SignalWaiter[]> {\n const rows = await this.db.durableSignalWaiter.findMany({\n where: { token: { startsWith: prefix } },\n });\n // On some providers (SQLite) `startsWith` compiles to a `LIKE` that reads `_` and `%` as wildcards,\n // so it can match more than the prefix: keep only the exact matches.\n return rows\n .filter((r) => r.token.startsWith(prefix))\n .map((r) => ({\n token: r.token,\n runId: r.runId,\n seq: r.seq,\n parallelGroup: r.parallelGroup ?? undefined,\n }));\n }\n\n async registerChildWaits(entries: ChildWait[]): Promise<void> {\n if (entries.length === 0) return;\n // Prisma has no multi-row upsert: one upsert per row, inside a single transaction.\n await this.db.$transaction(async (tx) => {\n for (const { waiter } of entries) {\n const data = {\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n };\n await tx.durableSignalWaiter.upsert({\n where: { token: waiter.token },\n create: { token: waiter.token, ...data },\n update: data,\n });\n }\n for (const { checkpoint } of entries) {\n const data = toCheckpointData(checkpoint);\n await tx.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: checkpoint.runId, seq: checkpoint.seq } },\n create: data,\n update: data,\n });\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.durableStepCheckpoint.deleteMany({\n where: { runId, seq: { gte: fromSeq, lte: toSeq } },\n });\n const data = toCheckpointData(into);\n await tx.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: into.runId, seq: into.seq } },\n create: data,\n update: data,\n });\n });\n }\n\n async listSignalWaitersByRun(runIds: string[]): Promise<SignalWaiter[]> {\n if (runIds.length === 0) return [];\n const rows = await this.db.durableSignalWaiter.findMany({ where: { runId: { in: runIds } } });\n return rows.map((r) => ({\n token: r.token,\n runId: r.runId,\n seq: r.seq,\n parallelGroup: r.parallelGroup ?? undefined,\n }));\n }\n\n async hasSignalWaiter(runId: string, tokenPrefix: string): Promise<boolean> {\n // On SQLite, Prisma's `startsWith` is a bare `LIKE`: `_`/`%` in the prefix act as wildcards and\n // case is ignored. So a hit is confirmed in JS; only a pattern match that is not a real prefix\n // match pays for the full read.\n const where = { runId, token: { startsWith: tokenPrefix } };\n const first = await this.db.durableSignalWaiter.findFirst({ where, select: { token: true } });\n if (!first) return false;\n if (first.token.startsWith(tokenPrefix)) return true;\n const rows = await this.db.durableSignalWaiter.findMany({ where, select: { token: true } });\n return rows.some((r) => r.token.startsWith(tokenPrefix));\n }\n\n async removeSignalWaiter(waiter: SignalWaiter): Promise<void> {\n // Exact-match delete (token AND runId AND seq): `token` is the only unique column, so a plain\n // `delete({ where: { token } })` would remove whatever row currently owns it, even if a different\n // run has since claimed the same token — `deleteMany` with all three fields is a safe no-op then.\n await this.db.durableSignalWaiter.deleteMany({\n where: { token: waiter.token, runId: waiter.runId, seq: waiter.seq },\n });\n }\n\n async bufferSignal(token: string, payload: unknown): Promise<void> {\n await this.db.durableBufferedSignal.create({ data: { token, payload: jsonOrNull(payload) } });\n }\n\n async takeBufferedSignal(token: string): Promise<{ payload: unknown } | null> {\n const row = await this.db.durableBufferedSignal.findFirst({\n where: { token },\n orderBy: { id: 'asc' },\n });\n if (!row) return null;\n await this.db.durableBufferedSignal.delete({ where: { id: row.id } });\n return { payload: row.payload ?? undefined };\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.durableBufferedEvent.create({\n data: {\n id: input.id,\n name: input.name,\n payload: jsonOrNull(input.payload),\n publishedAt: BigInt(input.publishedAt),\n },\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.durableBufferedEvent.findMany({\n where: { name },\n orderBy: { publishedAt: 'asc' }, // oldest first\n take: limit,\n });\n return rows.map((r) => ({\n id: r.id,\n payload: r.payload ?? undefined,\n publishedAt: Number(r.publishedAt),\n }));\n }\n\n async removeBufferedEvent(id: string): Promise<boolean> {\n // deleteMany's `where: { id }` matches at most one row (id is the PK) and is a safe no-op if it's\n // already gone — unlike `delete({ where: { id } })`, which throws P2025 on a missing row (the same\n // reasoning as releaseRunLock's updateMany above).\n const result = await this.db.durableBufferedEvent.deleteMany({ where: { id } });\n return result.count === 1;\n }\n}\n\n/**\n * One attribute predicate as a Prisma relation `some` filter on the side-table — compiles to an\n * EXISTS, so the predicate runs in SQL. `<>` (ne) maps to `{ not }`, which under `some` also excludes\n * runs where the attribute is absent (the missing-key-never-matches contract): `some` already\n * requires a matching row to exist. Numeric operands compare `numValue`, everything else `strValue`.\n */\nfunction attributeSome(f: AttributeFilter): Record<string, unknown> {\n // One comparison for a scalar op, one per member for `in` — ORed inside the single `some`, since\n // `in`'s operands may be of mixed types and so land in different typed columns. No comparisons at\n // all (an `in` over no values) can match no run, which is a run-level fact, not a side-table one.\n const comparisons = attributePredicateOperands(f).map(({ column, comparator, operand }) => ({\n [column]:\n comparator === '=' ? operand : comparator === '<>' ? { not: operand } : { [f.op]: operand },\n }));\n if (comparisons.length === 0) return MATCHES_NOTHING;\n return { attributes: { some: { key: f.key, ...anyOf(comparisons) } } };\n}\n\n/** A where fragment no run satisfies — what a plural predicate over an EMPTY set means. Spelled as an\n * impossible `id` rather than `OR: []` so it does not depend on how a Prisma version reads an empty\n * disjunction. */\nconst MATCHES_NOTHING: Record<string, unknown> = { id: { in: [] as string[] } };\n\n/** OR a set of where fragments, where an EMPTY set matches nothing rather than everything. */\nfunction anyOf(branches: Record<string, unknown>[]): Record<string, unknown> {\n return branches.length ? { OR: branches } : MATCHES_NOTHING;\n}\n\nconst bigOrNull = (n: number | undefined) => (n == null ? null : BigInt(n));\nconst numOrUndef = (n: bigint | null) => (n == null ? undefined : Number(n));\nconst jsonOrNull = (v: unknown) => v ?? null;\n\nfunction toRunData(run: WorkflowRun) {\n return {\n id: run.id,\n workflow: run.workflow,\n workflowVersion: run.workflowVersion,\n status: run.status,\n input: jsonOrNull(run.input),\n output: jsonOrNull(run.output),\n error: jsonOrNull(run.error),\n wakeAt: bigOrNull(run.wakeAt),\n lockedBy: run.lockedBy ?? null,\n lockedUntil: run.lockedUntil == null ? null : new Date(run.lockedUntil),\n awaitingDecisionTaskId: run.awaitingDecisionTaskId ?? null,\n recoveryAttempts: run.recoveryAttempts ?? null,\n tags: jsonOrNull(run.tags),\n searchAttributes: jsonOrNull(run.searchAttributes),\n priority: run.priority ?? null,\n // An absent namespace IS `'default'` — unlike `origin` below, this is a reconstruction and not a\n // guess: an engine started without a namespace stamps its runs and routes its workers as\n // `'default'`, so writing anything else (or NULL) would put the run in a partition no worker polls.\n namespace: run.namespace ?? 'default',\n // Absent origin stays SQL NULL — \"unknown\", never coerced into a real-looking library name.\n origin: run.origin ?? null,\n createdAt: run.createdAt,\n updatedAt: run.updatedAt,\n };\n}\n\nfunction toRunPatch(patch: Partial<WorkflowRun>) {\n // Map EVERY patchable field, using presence (`'x' in patch`) semantics for the nullable ones so a\n // patch can CLEAR a column (e.g. `{ error: undefined }` on completion sets it to NULL — matching\n // the TypeORM / MikroORM / in-memory stores). The two non-null Date fields use a defined-guard\n // since they are never cleared. Previously only 7 fields were mapped, so `updateRun({ tags })` /\n // `{ lockedBy }` / clearing `error` silently no-opped on this adapter.\n const data: Record<string, unknown> = {};\n if ('workflow' in patch) data.workflow = patch.workflow;\n if ('workflowVersion' in patch) data.workflowVersion = patch.workflowVersion;\n if ('status' in patch) data.status = patch.status;\n if ('input' in patch) data.input = jsonOrNull(patch.input);\n if ('output' in patch) data.output = jsonOrNull(patch.output);\n if ('error' in patch) data.error = jsonOrNull(patch.error);\n if ('wakeAt' in patch) data.wakeAt = bigOrNull(patch.wakeAt);\n if ('lockedBy' in patch) data.lockedBy = patch.lockedBy ?? null;\n if ('lockedUntil' in patch)\n data.lockedUntil = patch.lockedUntil == null ? null : new Date(patch.lockedUntil);\n if ('awaitingDecisionTaskId' in patch)\n data.awaitingDecisionTaskId = patch.awaitingDecisionTaskId ?? null;\n if ('recoveryAttempts' in patch) data.recoveryAttempts = patch.recoveryAttempts ?? null;\n if ('tags' in patch) data.tags = jsonOrNull(patch.tags);\n if ('searchAttributes' in patch) data.searchAttributes = jsonOrNull(patch.searchAttributes);\n if ('priority' in patch) data.priority = patch.priority ?? null;\n // `?? 'default'` rather than `?? null` like its neighbours: the column is NOT NULL, and clearing a\n // run's namespace means \"back to the unscoped partition\", which is what `'default'` names. A patch\n // that does not mention `namespace` leaves the stored one alone — a status update must never move a\n // run between tenants.\n if ('namespace' in patch) data.namespace = patch.namespace ?? 'default';\n if ('origin' in patch) data.origin = patch.origin ?? null;\n if (patch.createdAt != null) data.createdAt = patch.createdAt;\n if (patch.updatedAt != null) data.updatedAt = patch.updatedAt;\n return data;\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 WorkflowRun['status'],\n input: row.input ?? undefined,\n output: row.output ?? undefined,\n error: (row.error ?? undefined) as StepError | undefined,\n wakeAt: numOrUndef(row.wakeAt),\n lockedBy: row.lockedBy ?? undefined,\n lockedUntil: row.lockedUntil == null ? undefined : row.lockedUntil.getTime(),\n awaitingDecisionTaskId: row.awaitingDecisionTaskId ?? undefined,\n recoveryAttempts: row.recoveryAttempts ?? undefined,\n tags: (row.tags as string[] | null) ?? undefined,\n searchAttributes:\n (row.searchAttributes as Record<string, string | number | boolean> | null) ?? undefined,\n priority: row.priority ?? undefined,\n // Read back verbatim, with NO `?? 'default'` fallback. The column is NOT NULL and the migration\n // back-fills old rows, so there is nothing legitimate to fall back FROM; a fallback would only fire\n // on a deployment that added the column nullable without back-filling, and there it would lie —\n // the dashboard would show `default` for a row whose stored NULL keeps every `default` worker's\n // `WHERE namespace = 'default'` from ever picking it up.\n namespace: row.namespace,\n // NULL (a row written before the column existed) surfaces as `undefined` = unknown origin.\n origin: row.origin ?? undefined,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\n/** The name prefix each non-`step` {@link CheckpointNameKind} is, as `checkpointNameKind` reads it. */\nconst KIND_PREFIXES: [CheckpointNameKind, string][] = [\n ['child', 'signal:child:'],\n ['folded', 'fan:'],\n ['spawn', 'spawn:'],\n];\n\n/** Each {@link CheckpointNameKind} as the `where` that selects its rows; `step` is \"none of the others\". */\nconst NAME_KINDS: { kind: CheckpointNameKind; where: Record<string, unknown> }[] = [\n ...KIND_PREFIXES.map(([kind, prefix]) => ({ kind, where: { name: { startsWith: prefix } } })),\n {\n kind: 'step',\n where: { NOT: KIND_PREFIXES.map(([, prefix]) => ({ name: { startsWith: prefix } })) },\n },\n];\n\n/** One `groupBy` row of {@link PrismaStateStore.checkpointStats}. */\ntype CheckpointStatRow = {\n parallelGroup: string | null;\n status: string;\n _count: { _all: number; enqueuedAt: number };\n _min: { seq: number; name: string; enqueuedAt: Date | null; startedAt: Date };\n _max: { seq: number; name: string; startedAt: Date; finishedAt: Date };\n _sum: { attempts: number | bigint | null };\n};\n\nfunction bucketKey(group: string | null, status: string): string {\n return JSON.stringify([group, status]);\n}\n\nfunction toCheckpointStat(\n nameKind: CheckpointNameKind,\n r: CheckpointStatRow,\n unenqueued: Map<string, Date>,\n): CheckpointStat {\n const fallback = unenqueued.get(bucketKey(r.parallelGroup, r.status));\n const enqueued = r._min.enqueuedAt;\n const minEnqueuedAt =\n enqueued && fallback ? (enqueued < fallback ? enqueued : fallback) : (enqueued ?? fallback);\n return {\n group: r.parallelGroup,\n status: r.status as StepCheckpoint['status'],\n nameKind,\n count: r._count._all,\n minSeq: r._min.seq,\n maxSeq: r._max.seq,\n minName: r._min.name,\n maxName: r._max.name,\n // Every row has `enqueuedAt` or is in the NULL subset, so one of the two is set.\n minEnqueuedAt: minEnqueuedAt as Date,\n minStartedAt: r._min.startedAt,\n maxStartedAt: r._max.startedAt,\n maxFinishedAt: r._max.finishedAt,\n sumAttempts: Number(r._sum.attempts ?? 0),\n };\n}\n\nfunction toCheckpointData(cp: StepCheckpoint) {\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: jsonOrNull(cp.input),\n output: jsonOrNull(cp.output),\n error: jsonOrNull(cp.error),\n events: jsonOrNull(cp.events),\n attempts: cp.attempts,\n workerGroup: cp.workerGroup ?? null,\n parallelGroup: cp.parallelGroup ?? null,\n wakeAt: bigOrNull(cp.wakeAt),\n enqueuedAt: cp.enqueuedAt,\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: numOrUndef(row.wakeAt),\n enqueuedAt: row.enqueuedAt ?? row.startedAt,\n startedAt: row.startedAt,\n finishedAt: row.finishedAt,\n };\n}\n\nfunction toScheduleData(r: ScheduleRecord) {\n return {\n id: r.id,\n namespace: r.namespace,\n workflow: r.workflow,\n paused: r.paused,\n nextFireAt: r.nextFireAt == null ? null : BigInt(r.nextFireAt),\n tags: jsonOrNull(r.tags),\n spec: r.spec,\n state: r.state,\n createdAt: r.createdAt,\n updatedAt: r.updatedAt,\n };\n}\n\nfunction fromScheduleRow(row: ScheduleRow): ScheduleRecord {\n const tags = Array.isArray(row.tags) ? (row.tags as string[]) : undefined;\n return {\n id: row.id,\n namespace: row.namespace,\n workflow: row.workflow,\n paused: row.paused,\n nextFireAt: row.nextFireAt == null ? null : Number(row.nextFireAt),\n ...(tags?.length ? { tags } : {}),\n spec: (row.spec ?? {}) as Record<string, unknown>,\n state: (row.state ?? {}) as Record<string, unknown>,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n","/**\n * Tables this store's durable models own, physically. UNLIKE the other store adapters, this store\n * doesn't create or manage them at boot: the models in `prisma/schema.prisma` are meant to be copied\n * into YOUR OWN `schema.prisma` (see that file's header comment), and Prisma Migrate diffs whatever\n * models live in your schema — so a consumer who copied the models in already has them accounted for\n * and never needs a denylist for Prisma Migrate itself.\n *\n * This is exported anyway for the same reason the other adapters export it: any OTHER tooling that\n * introspects the database outside of `prisma migrate diff` (a raw schema dump, a second ORM/CLI\n * pointed at the same database, a linter that flags \"table not in any model\") needs the same fixed\n * list of table names this store's models declare via `@@map(...)`.\n *\n * ```ts\n * const skipTables = new Set(durableManagedTables());\n * ```\n *\n * Kept in sync with the `@@map(...)` table names in `prisma/schema.prisma` by `schema.spec.ts`,\n * which parses that file and asserts the two lists match — there is no single TypeScript source to\n * derive from (the schema is a `.prisma` text file copied into the consumer's own schema, not\n * imported at runtime), so the list here is intentionally a literal mirror.\n */\nexport function durableManagedTables(): string[] {\n return [\n 'durable_workflow_runs',\n 'durable_step_checkpoints',\n 'durable_run_attributes',\n 'durable_signal_waiters',\n 'durable_buffered_signals',\n 'durable_buffered_events',\n 'durable_schedules',\n ];\n}\n"],"mappings":"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","names":["namespaceWhere","namespace","undefined","PrismaStateStore","db","tryAdmitSingleton","runId","tag","workflow","limit","retryWakeAt","$transaction","tx","where","status","in","SINGLETON_ACTIVE_STATUSES","durableWorkflowRun","updateMany","data","rows","findMany","runs","map","fromRunRow","tags","singletonAdmissionTags","patch","singletonAdmissionDenialPatch","update","id","toRunPatch","createRun","run","create","toRunData","reindexAttributes","searchAttributes","updateRun","inputPatch","TERMINAL_RUN_STATUSES","includes","clearTerminalSingletonAdmission","getRun","attributes","durableRunAttribute","deleteMany","normalizeAttributeRows","length","createMany","row","findUnique","deleteRun","durableStepCheckpoint","durableSignalWaiter","deleteRuns","runIds","pruneTerminalRuns","policy","nowMs","statuses","filter","s","maxAge","maxCount","scoped","runWhere","scope","ids","Set","cutoff","Date","parseDuration","AND","updatedAt","lt","select","orderBy","take","r","add","size","skip","doomed","slice","getCheckpoint","seq","runId_seq","fromCheckpointRow","saveCheckpoint","checkpoint","toCheckpointData","upsert","saveCheckpointIfPending","count","saveCheckpointsIfPending","checkpoints","wrote","push","transaction","work","raw","cp","listIncompleteRuns","listPendingRuns","createdAt","listDueTimers","wakeAt","not","lte","BigInt","tryLockRun","owner","leaseUntilMs","result","OR","lockedUntil","lockedBy","releaseRunLock","renewRunLock","query","and","workflows","anyOf","w","namespaces","n","origin","origins","o","array_contains","t","f","attributeSome","listRuns","offset","countRuns","runFacets","groupBy","by","_count","_all","mergeRunFacetRows","runValueFacets","axis","opts","axisIsRunColumn","scan","RUN_VALUE_FACET_SCAN","runValueFacetsFromRuns","field","mergeRunValueFacetRows","value","schedules","delegate","durableSchedule","Error","saveSchedule","record","toScheduleData","getSchedule","fromScheduleRow","updateSchedule","expectedNextFireAt","paused","nextFireAt","jsonOrNull","spec","state","Object","keys","deleteSchedule","listSchedules","dueBy","sort","nulls","listCheckpoints","getLatestCheckpointByName","name","findFirst","countCheckpoints","fromSeq","toSeq","gte","listCheckpointsByNamePrefix","prefixes","p","startsWith","some","checkpointStats","group","parallelGroup","grouped","Promise","all","NAME_KINDS","kind","enqueuedAt","_min","startedAt","_max","finishedAt","_sum","attempts","stats","unenqueued","unenqueuedStartedAt","Map","toCheckpointStat","flat","bucketKey","queryCheckpoints","namePrefixes","excludeGroups","notIn","putSignalWaiter","waiter","token","takeSignalWaiter","delete","listSignalWaiters","prefix","registerChildWaits","entries","compactCheckpoints","into","listSignalWaitersByRun","hasSignalWaiter","tokenPrefix","first","removeSignalWaiter","bufferSignal","payload","durableBufferedSignal","takeBufferedSignal","bufferEvent","input","durableBufferedEvent","publishedAt","listBufferedEvents","Number","removeBufferedEvent","comparisons","attributePredicateOperands","column","comparator","operand","op","MATCHES_NOTHING","key","branches","bigOrNull","numOrUndef","v","workflowVersion","output","error","awaitingDecisionTaskId","recoveryAttempts","priority","getTime","KIND_PREFIXES","NOT","JSON","stringify","nameKind","fallback","get","enqueued","minEnqueuedAt","minSeq","maxSeq","minName","maxName","minStartedAt","maxStartedAt","maxFinishedAt","sumAttempts","stepId","events","workerGroup","Array","isArray","durableManagedTables"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/prisma-state-store.ts","../src/schema.ts"],"sourcesContent":["export * from './prisma-state-store';\nexport * from './schema';\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 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';\n\n/* The Prisma client is generated per-schema, so the adapter can't import a concrete one. Instead\n it depends on this structural surface — the three model delegates and the methods it uses. A\n real `PrismaClient` (with the models from prisma/schema.prisma added) satisfies it. Query-arg\n shapes are Prisma's own generics, so they're left as `any` at this single boundary; the row\n return types are precise, which is what the mapping code below relies on. */\n\ninterface RunRow {\n id: string;\n workflow: string;\n workflowVersion: string;\n status: string;\n input: unknown;\n output: unknown;\n error: unknown;\n wakeAt: bigint | null;\n lockedBy: string | null;\n lockedUntil: Date | null;\n awaitingDecisionTaskId: string | null;\n recoveryAttempts: number | null;\n tags: unknown;\n searchAttributes: unknown;\n priority: number | null;\n /** NOT NULL in the schema (defaulted to `'default'`), so every row carries a real namespace. */\n namespace: string;\n origin: string | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface CheckpointRow {\n runId: string;\n seq: number;\n name: string;\n kind: string;\n stepId: string;\n status: string;\n input: unknown;\n output: unknown;\n error: unknown;\n events: unknown;\n attempts: number;\n workerGroup: string | null;\n parallelGroup: string | null;\n wakeAt: bigint | null;\n enqueuedAt: Date | null;\n startedAt: Date;\n finishedAt: Date;\n}\n\ninterface WaiterRow {\n token: string;\n runId: string;\n seq: number;\n parallelGroup: string | null;\n}\n\ninterface RunAttributeRow {\n runId: string;\n key: string;\n strValue: string | null;\n numValue: number | null;\n}\n\ninterface BufferedSignalRow {\n id: bigint;\n token: string;\n payload: unknown;\n}\n\ninterface BufferedEventRow {\n id: string;\n name: string;\n payload: unknown;\n publishedAt: bigint;\n}\n\n// Prisma's per-model query args are generated generics; left as `any` at this single boundary.\ntype Args = any;\n\ninterface Delegate<Row> {\n create(args: Args): Promise<Row>;\n createMany(args: Args): Promise<{ count: number }>;\n findUnique(args: Args): Promise<Row | null>;\n findFirst(args?: Args): Promise<Row | null>;\n findMany(args?: Args): Promise<Row[]>;\n update(args: Args): Promise<Row>;\n updateMany(args: Args): Promise<{ count: number }>;\n upsert(args: Args): Promise<Row>;\n delete(args: Args): Promise<Row>;\n deleteMany(args?: Args): Promise<{ count: number }>;\n count(args?: Args): Promise<number>;\n /** Aggregate form — used by the run facets and `checkpointStats`, whose rows are aggregate cells,\n * not model rows, so the result type is stated at the call site rather than derived from `Row`. */\n groupBy(args: Args): Promise<Record<string, unknown>[]>;\n}\n\ninterface ScheduleRow {\n id: string;\n namespace: string;\n workflow: string;\n paused: boolean;\n nextFireAt: bigint | null;\n tags: unknown;\n spec: unknown;\n state: unknown;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface DurablePrismaTx {\n durableWorkflowRun: Delegate<RunRow>;\n durableStepCheckpoint: Delegate<CheckpointRow>;\n durableRunAttribute: Delegate<RunAttributeRow>;\n durableSignalWaiter: Delegate<WaiterRow>;\n durableBufferedSignal: Delegate<BufferedSignalRow>;\n durableBufferedEvent: Delegate<BufferedEventRow>;\n /** Only needed for persisted schedules (`engine.schedules`) — add the `DurableSchedule` model. */\n durableSchedule?: Delegate<ScheduleRow>;\n}\n\nexport interface DurablePrismaClient extends DurablePrismaTx {\n /** Prisma's interactive-transaction form: runs `fn` with a tx-scoped client and commits on resolve. */\n $transaction<T>(fn: (tx: DurablePrismaTx) => Promise<T>): Promise<T>;\n}\n\n/**\n * The `namespace` read boundary as a spreadable Prisma `where` fragment.\n *\n * `undefined` means NO RESTRICTION — `{}` — because that is the operator (control-plane) view that\n * sees every tenant, and it is what the engine passes when it runs unscoped. It does NOT mean\n * \"namespace IS NULL\": the column is NOT NULL, so `{ namespace: undefined }` would be Prisma's\n * \"ignore this predicate\" anyway, but `{ namespace: null }` would match nothing in production while\n * still looking correct in a single-tenant test where every worker polls unscoped.\n *\n * A named namespace is plain equality, so a worker sees only its own tenant's rows — the boundary\n * {@link WorkflowRun.namespace} promises for the four worker paths (pick up, recover, resume timers,\n * time out).\n */\nfunction namespaceWhere(namespace?: string): { namespace?: string } {\n if (namespace === undefined) return {};\n return { namespace };\n}\n\n/**\n * Prisma-backed `StateStore`. Pass your `PrismaClient` after adding the models from\n * `prisma/schema.prisma` to your schema. JSON columns carry the run/step payloads directly;\n * `wakeAt` is a `BigInt` (epoch ms).\n *\n * Every path a worker acts on is namespace-scoped when it is given one — `listPendingRuns` (pick up),\n * `listIncompleteRuns` (recover), `listDueTimers` (resume timers) and `listRuns`'s `namespace`\n * (the engine's timeout sweep). Omit it for the operator view across all tenants. Point-reads\n * (`getRun`, checkpoints) are deliberately NOT scoped, per {@link StateStore}.\n */\nexport class PrismaStateStore implements StateStore {\n constructor(private readonly db: DurablePrismaClient) {}\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 = { workflow, status: { in: SINGLETON_ACTIVE_STATUSES } };\n // A locking write first: concurrent claims cannot read the same free slot.\n await tx.durableWorkflowRun.updateMany({ where, data: { workflow } });\n const rows = await tx.durableWorkflowRun.findMany({ 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.durableWorkflowRun.update({ where: { id: runId }, data: toRunPatch(patch) });\n return false;\n }\n await tx.durableWorkflowRun.update({ where: { id: runId }, data: { tags } });\n return true;\n });\n }\n\n async createRun(run: WorkflowRun): Promise<void> {\n await this.db.durableWorkflowRun.create({ data: toRunData(run) });\n await this.reindexAttributes(run.id, run.searchAttributes);\n }\n\n async updateRun(runId: string, inputPatch: Partial<WorkflowRun>): Promise<void> {\n const patch =\n inputPatch.status && TERMINAL_RUN_STATUSES.includes(inputPatch.status)\n ? await clearTerminalSingletonAdmission(runId, inputPatch, (id) => this.getRun(id))\n : inputPatch;\n await this.db.durableWorkflowRun.update({ where: { id: runId }, data: toRunPatch(patch) });\n // Keep the side-table in step with the run's attributes whenever they're patched.\n if ('searchAttributes' in patch) await this.reindexAttributes(runId, patch.searchAttributes);\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 const patch =\n inputPatch.status && TERMINAL_RUN_STATUSES.includes(inputPatch.status)\n ? await clearTerminalSingletonAdmission(runId, inputPatch, (id) => this.getRun(id))\n : inputPatch;\n // One conditional `updateMany` (`UPDATE … WHERE id = ? AND status IN (…)`): the status\n // predicate is the compare, the row count the answer, and a missing row matches nothing.\n const where = { id: runId, status: { in: expectedStatuses } };\n const data = toRunPatch(patch);\n // Nothing to write but (maybe) the attribute side-table: the compare is a read (an `updateMany`\n // with no data would report zero rows even on a match).\n const count = Object.keys(data).length\n ? (await this.db.durableWorkflowRun.updateMany({ where, data })).count\n : await this.db.durableWorkflowRun.count({ where });\n if (count === 0) return false;\n if ('searchAttributes' in patch) await this.reindexAttributes(runId, patch.searchAttributes);\n return true;\n }\n\n /** Rewrite a run's normalized attribute rows: delete the old set, insert the current one. Mirrors\n * the in-memory store's reindex so the side-table always reflects the run's live searchAttributes. */\n private async reindexAttributes(\n runId: string,\n attributes: WorkflowRun['searchAttributes'],\n ): Promise<void> {\n await this.db.durableRunAttribute.deleteMany({ where: { runId } });\n const rows = normalizeAttributeRows(runId, attributes);\n if (rows.length) await this.db.durableRunAttribute.createMany({ data: rows });\n }\n\n async getRun(runId: string): Promise<WorkflowRun | null> {\n const row = await this.db.durableWorkflowRun.findUnique({ where: { id: runId } });\n return row ? fromRunRow(row) : null;\n }\n\n async deleteRun(runId: string): Promise<void> {\n // Child rows first, then the run — checkpoints, signal waiters, attribute rows.\n await this.db.durableStepCheckpoint.deleteMany({ where: { runId } });\n await this.db.durableSignalWaiter.deleteMany({ where: { runId } });\n await this.db.durableRunAttribute.deleteMany({ where: { runId } });\n await this.db.durableWorkflowRun.deleteMany({ where: { id: runId } });\n }\n\n async deleteRuns(runIds: string[]): Promise<void> {\n if (runIds.length === 0) return;\n // Same cascade as deleteRun, one `IN (...)` per table, atomically.\n await this.db.$transaction(async (tx) => {\n await tx.durableStepCheckpoint.deleteMany({ where: { runId: { in: runIds } } });\n await tx.durableSignalWaiter.deleteMany({ where: { runId: { in: runIds } } });\n await tx.durableRunAttribute.deleteMany({ where: { runId: { in: runIds } } });\n await tx.durableWorkflowRun.deleteMany({ where: { id: { in: 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.runWhere({ ...(policy.scope ?? {}), statuses });\n const ids = new Set<string>();\n if (policy.maxAge != null) {\n const cutoff = new Date(nowMs - parseDuration(policy.maxAge));\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { AND: [scoped, { updatedAt: { lt: cutoff } }] },\n select: { id: true },\n orderBy: { updatedAt: 'asc' }, // oldest first\n take: limit,\n });\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 scoped status set (skipped by OFFSET).\n const rows = await this.db.durableWorkflowRun.findMany({\n where: scoped,\n select: { id: true },\n orderBy: [{ updatedAt: 'desc' }, { id: 'desc' }],\n skip: policy.maxCount,\n take: limit,\n });\n for (const r of rows) {\n if (ids.size >= limit) break;\n ids.add(r.id);\n }\n }\n const doomed = [...ids].slice(0, limit);\n await this.deleteRuns(doomed);\n return doomed.length;\n }\n\n async getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null> {\n const row = await this.db.durableStepCheckpoint.findUnique({\n where: { runId_seq: { runId, seq } },\n });\n return row ? fromCheckpointRow(row) : null;\n }\n\n async saveCheckpoint(checkpoint: StepCheckpoint): Promise<void> {\n const data = toCheckpointData(checkpoint);\n await this.db.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: checkpoint.runId, seq: checkpoint.seq } },\n create: data,\n update: data,\n });\n }\n\n async saveCheckpointIfPending(checkpoint: StepCheckpoint): Promise<boolean> {\n // One conditional `updateMany` (`UPDATE … WHERE run_id = ? AND seq = ? AND status = 'pending'`):\n // the status predicate is the compare, the row count the answer, and a missing row is never made.\n const { runId, seq, ...data } = toCheckpointData(checkpoint);\n const { count } = await this.db.durableStepCheckpoint.updateMany({\n where: { runId, seq, status: 'pending' },\n data,\n });\n return count > 0;\n }\n\n async saveCheckpointsIfPending(checkpoints: StepCheckpoint[]): Promise<boolean[]> {\n if (checkpoints.length === 0) return [];\n // The conditional `updateMany` of `saveCheckpointIfPending`, once per entry, in order, in one\n // transaction: one commit for the batch, and a rejection writes nothing.\n return this.db.$transaction(async (tx) => {\n const wrote: boolean[] = [];\n for (const checkpoint of checkpoints) {\n const { runId, seq, ...data } = toCheckpointData(checkpoint);\n const { count } = await tx.durableStepCheckpoint.updateMany({\n where: { runId, seq, status: 'pending' },\n data,\n });\n wrote.push(count > 0);\n }\n return wrote;\n });\n }\n\n async transaction<T>(\n work: (tx: {\n raw: unknown;\n saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;\n }) => Promise<T>,\n ): Promise<T> {\n return this.db.$transaction(async (tx) =>\n work({\n raw: tx,\n saveCheckpoint: async (cp) => {\n const data = toCheckpointData(cp);\n await tx.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: cp.runId, seq: cp.seq } },\n create: data,\n update: data,\n });\n },\n }),\n );\n }\n\n async listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: { in: ['running', 'cancelling'] }, ...namespaceWhere(namespace) },\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.durableWorkflowRun.findMany({\n where: {\n status: { in: ['running', 'cancelling'] },\n OR: [{ lockedUntil: null }, { lockedUntil: { lte: new Date(nowMs) } }],\n ...namespaceWhere(namespace),\n },\n orderBy: { createdAt: 'asc' },\n take: limit,\n });\n return rows.map(fromRunRow);\n }\n\n async listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: 'pending', ...namespaceWhere(namespace) },\n orderBy: { createdAt: 'asc' }, // FIFO dispatch\n take: limit,\n });\n return rows.map(fromRunRow);\n }\n\n async listDueTimers(nowMs: number, namespace?: string, limit?: number): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: {\n status: 'suspended',\n wakeAt: { not: null, lte: BigInt(nowMs) },\n ...namespaceWhere(namespace),\n },\n orderBy: { wakeAt: 'asc' },\n ...(limit !== undefined ? { take: limit } : {}),\n });\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 const result = await this.db.durableWorkflowRun.updateMany({\n where: {\n id: runId,\n OR: [{ lockedUntil: null }, { lockedUntil: { lte: new Date(nowMs) } }],\n },\n data: { lockedBy: owner, lockedUntil: new Date(leaseUntilMs) },\n });\n return result.count === 1;\n }\n\n async releaseRunLock(runId: string): Promise<void> {\n // Idempotent by design: releasing the lease on a run that no longer exists is a no-op, not an\n // error. The engine calls this best-effort in a `finally` AFTER the run has settled, so it can\n // race a concurrent purge/teardown — Prisma's `update({ where: { id } })` would throw P2025\n // (\"No record was found for an update\") on that race and, since the call is fire-and-forget on\n // the engine's terminal path, surface as an unhandled rejection. `updateMany` matches a 0-row\n // WHERE to an empty result (no throw), mirroring the in-memory store's `if (run)` guard and the\n // set-where semantics of every sibling adapter (TypeORM/MikroORM/Drizzle).\n await this.db.durableWorkflowRun.updateMany({\n where: { id: runId },\n data: { lockedBy: null, lockedUntil: null },\n });\n }\n\n async renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean> {\n const result = await this.db.durableWorkflowRun.updateMany({\n where: { id: runId, lockedBy: owner },\n data: { lockedUntil: new Date(leaseUntilMs) },\n });\n return result.count === 1;\n }\n\n /** The `where` every run query shares — {@link listRuns} pages it, {@link runFacets} groups it. */\n private runWhere(query: RunQuery): Record<string, unknown> {\n // The tenant boundary, and NOT only a dashboard facet: the engine's `sweepTimeouts` finds the runs\n // it may cancel through `listRuns({ workflow, status, namespace })`, so an unfiltered `namespace`\n // here lets a worker serving one tenant time out another tenant's runs — a write, not a stale\n // read. Same `undefined` = no restriction rule as the poll paths above (see `namespaceWhere`),\n // which is what keeps the operator's dashboard showing every tenant by default.\n const where: Record<string, unknown> = { ...namespaceWhere(query.namespace) };\n // The plural predicates below can't sit on `where` directly (a key holds one condition, and the\n // single form may already own it), so they accumulate here and are ANDed at the end. Each is ORed\n // within itself and matches NOTHING when empty — the contract `statuses` already had.\n const and: Record<string, unknown>[] = [];\n if (query.workflow) where.workflow = query.workflow;\n if (query.workflows) and.push(anyOf(query.workflows.map((w) => ({ workflow: w }))));\n if (query.namespaces) and.push(anyOf(query.namespaces.map((n) => ({ namespace: n }))));\n // Which library registered the workflow. Plain equality, so a run whose origin is NULL (created\n // before the column existed, or registered through a path the derivation could not classify)\n // matches NO origin value — it is never folded into a bucket to make the facet look complete.\n // Unknown-origin runs are reachable only with the filter OFF, so \"all origins\" must stay the\n // default view; a dashboard that filtered by default would make those runs look deleted.\n // Passing `null` asks for exactly the unattributed bucket (`origin IS NULL`) — Prisma spells that\n // as the same equality — which is how a paginated console can offer an \"unknown\" chip.\n if (query.origin !== undefined) where.origin = query.origin;\n // `null` is a member like any other in a set of origins — Prisma spells `origin IS NULL` as the\n // same equality — so one branch per value covers both the named ones and the unattributed bucket.\n if (query.origins) and.push(anyOf(query.origins.map((o) => ({ origin: o }))));\n // `status IN (...)`; an empty set matches nothing (mirrors the in-memory store). Combined with the\n // single-value `status` via AND when both are present, so the narrower set wins.\n if (query.status && query.statuses) {\n and.push({ status: query.status }, { status: { in: query.statuses } });\n } else if (query.status) {\n where.status = query.status;\n } else if (query.statuses) {\n where.status = { in: query.statuses };\n }\n if (query.tag) where.tags = { array_contains: query.tag };\n if (query.tags) and.push(anyOf(query.tags.map((t) => ({ tags: { array_contains: t } }))));\n // Typed/range attribute predicates push DOWN into SQL: each filter becomes a relation `some`\n // (EXISTS) on the normalized `durable_run_attributes` side-table, so the DB filters AND paginates\n // — no full scan + in-process filter. ANDed: a run must match every filter, so one `some` each.\n if (query.attributes?.length) and.push(...query.attributes.map((f) => attributeSome(f)));\n if (and.length) where.AND = and;\n return where;\n }\n\n async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n const orderBy = { createdAt: 'desc' as const }; // newest first — recent runs on top in the dashboard\n const rows = await this.db.durableWorkflowRun.findMany({\n where: this.runWhere(query),\n take: query.limit,\n skip: query.offset,\n orderBy,\n });\n return rows.map(fromRunRow);\n }\n\n async countRuns(query: Omit<RunQuery, 'limit' | 'offset'>): Promise<number> {\n return this.db.durableWorkflowRun.count({ where: this.runWhere(query) });\n }\n\n /** `GROUP BY status, origin` over the same predicates {@link listRuns} pages — one aggregate, so a\n * console can show whole-set counts next to a bounded page instead of downloading every run to\n * count them in the browser. */\n async runFacets(query: RunFacetQuery): Promise<RunFacetRow[]> {\n const rows = (await this.db.durableWorkflowRun.groupBy({\n by: ['status', 'origin'],\n where: this.runWhere(query),\n _count: { _all: true },\n })) as { status: RunStatus; origin: string | null; _count: { _all: number } }[];\n return mergeRunFacetRows(\n rows.map((r) => ({ status: r.status, origin: r.origin, count: r._count._all })),\n );\n }\n\n /** Distinct values of one filter axis over the same predicates {@link listRuns} pages. A run-table\n * column is a `groupBy` like {@link runFacets}, exact over the whole matching set; the tag and\n * attribute axes live outside the row (json column / side table) and are counted from a bounded\n * page of runs instead — see `RunValueFacetOptions.scan`. */\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 rows = (await this.db.durableWorkflowRun.groupBy({\n by: [axis.field],\n where: this.runWhere(query),\n _count: { _all: true },\n })) as (Record<string, string | null> & { _count: { _all: number } })[];\n return mergeRunValueFacetRows(\n rows.map((r) => ({ value: r[axis.field] ?? null, count: r._count._all })),\n opts,\n );\n }\n\n // ---- persisted schedules ----------------------------------------------------------------------\n\n private schedules(): Delegate<ScheduleRow> {\n const delegate = this.db.durableSchedule;\n if (!delegate) {\n throw new Error(\n 'persisted schedules need the DurableSchedule model — copy it from prisma/schema.prisma into your schema and re-run `prisma generate`',\n );\n }\n return delegate;\n }\n\n async saveSchedule(record: ScheduleRecord): Promise<void> {\n const data = toScheduleData(record);\n await this.schedules().upsert({ where: { id: record.id }, create: data, update: data });\n }\n\n async getSchedule(id: string): Promise<ScheduleRecord | null> {\n const row = await this.schedules().findUnique({ where: { id } });\n return row ? fromScheduleRow(row) : null;\n }\n\n /** One conditional `updateMany`: the compare-and-set on `next_fire_at` is a single statement. */\n async updateSchedule(\n id: string,\n patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>,\n expectedNextFireAt?: number | null,\n ): Promise<boolean> {\n const data: Record<string, unknown> = {};\n if (patch.namespace !== undefined) data.namespace = patch.namespace;\n if (patch.workflow !== undefined) data.workflow = patch.workflow;\n if (patch.paused !== undefined) data.paused = patch.paused;\n if ('nextFireAt' in patch)\n data.nextFireAt = patch.nextFireAt == null ? null : BigInt(patch.nextFireAt);\n if ('tags' in patch) data.tags = jsonOrNull(patch.tags);\n if (patch.spec !== undefined) data.spec = patch.spec;\n if (patch.state !== undefined) data.state = patch.state;\n if (patch.updatedAt !== undefined) data.updatedAt = patch.updatedAt;\n if (!Object.keys(data).length) return (await this.getSchedule(id)) !== null;\n const where: Record<string, unknown> = { id };\n if (expectedNextFireAt !== undefined)\n where.nextFireAt = expectedNextFireAt === null ? null : BigInt(expectedNextFireAt);\n const { count } = await this.schedules().updateMany({ where, data });\n return count > 0;\n }\n\n async deleteSchedule(id: string): Promise<boolean> {\n const { count } = await this.schedules().deleteMany({ where: { id } });\n return count > 0;\n }\n\n async listSchedules(query: ScheduleQuery): Promise<ScheduleRecord[]> {\n const where: Record<string, unknown> = {};\n if (query.namespace !== undefined) where.namespace = query.namespace;\n if (query.workflow !== undefined) where.workflow = query.workflow;\n if (query.paused !== undefined) where.paused = query.paused;\n if (query.tag !== undefined) where.tags = { array_contains: query.tag };\n if (query.dueBy !== undefined) {\n where.AND = [{ paused: false }, { nextFireAt: { lte: BigInt(query.dueBy) } }];\n }\n const rows = await this.schedules().findMany({\n where,\n // Soonest-due first, never-firing (NULL) last, id as the stable tie-break.\n orderBy: [{ nextFireAt: { sort: 'asc', nulls: 'last' } }, { id: 'asc' }],\n take: query.limit,\n skip: query.offset,\n });\n return rows.map(fromScheduleRow);\n }\n\n async listCheckpoints(runId: string): Promise<StepCheckpoint[]> {\n const rows = await this.db.durableStepCheckpoint.findMany({\n where: { runId },\n orderBy: { seq: 'asc' },\n });\n return rows.map(fromCheckpointRow);\n }\n\n async getLatestCheckpointByName(\n runId: string,\n name: string,\n ): Promise<StepCheckpoint | undefined> {\n const row = await this.db.durableStepCheckpoint.findFirst({\n where: { runId, name },\n orderBy: { seq: 'desc' },\n });\n return row ? fromCheckpointRow(row) : 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 return this.db.durableStepCheckpoint.count({\n where: { runId, seq: { gte: fromSeq, lte: toSeq }, status: { in: statuses } },\n });\n }\n\n async listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]> {\n if (prefixes.length === 0) return [];\n const rows = await this.db.durableStepCheckpoint.findMany({\n where: { runId, OR: prefixes.map((p) => ({ name: { startsWith: p } })) },\n orderBy: { seq: 'asc' },\n });\n // On some providers (SQLite) `startsWith` compiles to a `LIKE` that reads `_` and `%` as wildcards,\n // so it can match more than the prefix: keep only the exact matches.\n return rows.filter((r) => prefixes.some((p) => r.name.startsWith(p))).map(fromCheckpointRow);\n }\n\n /**\n * One `groupBy(parallelGroup, status)` per {@link CheckpointNameKind}, each narrowed to its kind by\n * a name-prefix predicate, run concurrently — Prisma cannot group by a `CASE`, so the kind is the\n * `where` instead. `minEnqueuedAt` reads a NULL `enqueuedAt` as `startedAt` (as\n * {@link fromCheckpointRow} does): a bucket whose non-null `enqueuedAt` count falls short of its\n * row count has such rows, and only for those kinds is the NULL subset's `min(startedAt)` asked for.\n *\n * On SQLite `startsWith` is a case-insensitive `LIKE`, as in {@link listCheckpointsByNamePrefix};\n * the kind prefixes are lower-case and wildcard-free, so only a step whose name starts with one of\n * them in another case would be classified differently there.\n */\n async checkpointStats(\n runId: string,\n opts?: { group?: string | undefined },\n ): Promise<CheckpointStat[]> {\n const scope = opts?.group === undefined ? { runId } : { runId, parallelGroup: opts.group };\n const grouped = await Promise.all(\n NAME_KINDS.map(async ({ kind, where }) => ({\n kind,\n where,\n rows: (await this.db.durableStepCheckpoint.groupBy({\n by: ['parallelGroup', 'status'],\n where: { ...scope, ...where },\n _count: { _all: true, enqueuedAt: true },\n _min: { seq: true, name: true, enqueuedAt: true, startedAt: true },\n _max: { seq: true, name: true, startedAt: true, finishedAt: true },\n _sum: { attempts: true },\n })) as CheckpointStatRow[],\n })),\n );\n const stats = await Promise.all(\n grouped.map(async ({ kind, where, rows }) => {\n const unenqueued = rows.some((r) => r._count.enqueuedAt < r._count._all)\n ? await this.unenqueuedStartedAt({ ...scope, ...where })\n : new Map<string, Date>();\n return rows.map((r) => toCheckpointStat(kind, r, unenqueued));\n }),\n );\n return stats.flat();\n }\n\n /** `min(startedAt)` per `(parallelGroup, status)` over the rows whose `enqueuedAt` is NULL. */\n private async unenqueuedStartedAt(where: Record<string, unknown>): Promise<Map<string, Date>> {\n const rows = (await this.db.durableStepCheckpoint.groupBy({\n by: ['parallelGroup', 'status'],\n where: { ...where, enqueuedAt: null },\n _min: { startedAt: true },\n })) as { parallelGroup: string | null; status: string; _min: { startedAt: Date } }[];\n return new Map(rows.map((r) => [bucketKey(r.parallelGroup, r.status), r._min.startedAt]));\n }\n\n /** {@link CheckpointQuery} as one `findMany`, in `seq` order, paged by `skip`/`take`. Ungrouped rows\n * are kept past `excludeGroups` explicitly: `NOT IN` alone drops a NULL `parallelGroup`. */\n async queryCheckpoints(runId: string, query: CheckpointQuery): Promise<StepCheckpoint[]> {\n if (query.statuses?.length === 0 || query.namePrefixes?.length === 0) return [];\n const and: Record<string, unknown>[] = [];\n if (query.excludeGroups?.length) {\n and.push({\n OR: [{ parallelGroup: null }, { parallelGroup: { notIn: query.excludeGroups } }],\n });\n }\n if (query.namePrefixes) {\n and.push({ OR: query.namePrefixes.map((p) => ({ name: { startsWith: p } })) });\n }\n const rows = await this.db.durableStepCheckpoint.findMany({\n where: {\n runId,\n ...(query.group === undefined ? {} : { parallelGroup: query.group }),\n ...(query.statuses ? { status: { in: query.statuses } } : {}),\n ...(and.length ? { AND: and } : {}),\n },\n orderBy: { seq: 'asc' },\n skip: query.offset,\n take: query.limit,\n });\n return rows.map(fromCheckpointRow);\n }\n\n async putSignalWaiter(waiter: SignalWaiter): Promise<void> {\n await this.db.durableSignalWaiter.upsert({\n where: { token: waiter.token },\n create: {\n token: waiter.token,\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n },\n update: {\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n },\n });\n }\n\n async takeSignalWaiter(token: string): Promise<SignalWaiter | null> {\n const row = await this.db.durableSignalWaiter.findUnique({ where: { token } });\n if (!row) return null;\n await this.db.durableSignalWaiter.delete({ where: { token } });\n return {\n token: row.token,\n runId: row.runId,\n seq: row.seq,\n parallelGroup: row.parallelGroup ?? undefined,\n };\n }\n\n async listSignalWaiters(prefix: string): Promise<SignalWaiter[]> {\n const rows = await this.db.durableSignalWaiter.findMany({\n where: { token: { startsWith: prefix } },\n });\n // On some providers (SQLite) `startsWith` compiles to a `LIKE` that reads `_` and `%` as wildcards,\n // so it can match more than the prefix: keep only the exact matches.\n return rows\n .filter((r) => r.token.startsWith(prefix))\n .map((r) => ({\n token: r.token,\n runId: r.runId,\n seq: r.seq,\n parallelGroup: r.parallelGroup ?? undefined,\n }));\n }\n\n async registerChildWaits(entries: ChildWait[]): Promise<void> {\n if (entries.length === 0) return;\n // Prisma has no multi-row upsert: one upsert per row, inside a single transaction.\n await this.db.$transaction(async (tx) => {\n for (const { waiter } of entries) {\n const data = {\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n };\n await tx.durableSignalWaiter.upsert({\n where: { token: waiter.token },\n create: { token: waiter.token, ...data },\n update: data,\n });\n }\n for (const { checkpoint } of entries) {\n const data = toCheckpointData(checkpoint);\n await tx.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: checkpoint.runId, seq: checkpoint.seq } },\n create: data,\n update: data,\n });\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.durableStepCheckpoint.deleteMany({\n where: { runId, seq: { gte: fromSeq, lte: toSeq } },\n });\n const data = toCheckpointData(into);\n await tx.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: into.runId, seq: into.seq } },\n create: data,\n update: data,\n });\n });\n }\n\n async listSignalWaitersByRun(runIds: string[]): Promise<SignalWaiter[]> {\n if (runIds.length === 0) return [];\n const rows = await this.db.durableSignalWaiter.findMany({ where: { runId: { in: runIds } } });\n return rows.map((r) => ({\n token: r.token,\n runId: r.runId,\n seq: r.seq,\n parallelGroup: r.parallelGroup ?? undefined,\n }));\n }\n\n async hasSignalWaiter(runId: string, tokenPrefix: string): Promise<boolean> {\n // On SQLite, Prisma's `startsWith` is a bare `LIKE`: `_`/`%` in the prefix act as wildcards and\n // case is ignored. So a hit is confirmed in JS; only a pattern match that is not a real prefix\n // match pays for the full read.\n const where = { runId, token: { startsWith: tokenPrefix } };\n const first = await this.db.durableSignalWaiter.findFirst({ where, select: { token: true } });\n if (!first) return false;\n if (first.token.startsWith(tokenPrefix)) return true;\n const rows = await this.db.durableSignalWaiter.findMany({ where, select: { token: true } });\n return rows.some((r) => r.token.startsWith(tokenPrefix));\n }\n\n async removeSignalWaiter(waiter: SignalWaiter): Promise<void> {\n // Exact-match delete (token AND runId AND seq): `token` is the only unique column, so a plain\n // `delete({ where: { token } })` would remove whatever row currently owns it, even if a different\n // run has since claimed the same token — `deleteMany` with all three fields is a safe no-op then.\n await this.db.durableSignalWaiter.deleteMany({\n where: { token: waiter.token, runId: waiter.runId, seq: waiter.seq },\n });\n }\n\n async bufferSignal(token: string, payload: unknown): Promise<void> {\n await this.db.durableBufferedSignal.create({ data: { token, payload: jsonOrNull(payload) } });\n }\n\n async takeBufferedSignal(token: string): Promise<{ payload: unknown } | null> {\n const row = await this.db.durableBufferedSignal.findFirst({\n where: { token },\n orderBy: { id: 'asc' },\n });\n if (!row) return null;\n await this.db.durableBufferedSignal.delete({ where: { id: row.id } });\n return { payload: row.payload ?? undefined };\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.durableBufferedEvent.create({\n data: {\n id: input.id,\n name: input.name,\n payload: jsonOrNull(input.payload),\n publishedAt: BigInt(input.publishedAt),\n },\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.durableBufferedEvent.findMany({\n where: { name },\n orderBy: { publishedAt: 'asc' }, // oldest first\n take: limit,\n });\n return rows.map((r) => ({\n id: r.id,\n payload: r.payload ?? undefined,\n publishedAt: Number(r.publishedAt),\n }));\n }\n\n async removeBufferedEvent(id: string): Promise<boolean> {\n // deleteMany's `where: { id }` matches at most one row (id is the PK) and is a safe no-op if it's\n // already gone — unlike `delete({ where: { id } })`, which throws P2025 on a missing row (the same\n // reasoning as releaseRunLock's updateMany above).\n const result = await this.db.durableBufferedEvent.deleteMany({ where: { id } });\n return result.count === 1;\n }\n}\n\n/**\n * One attribute predicate as a Prisma relation `some` filter on the side-table — compiles to an\n * EXISTS, so the predicate runs in SQL. `<>` (ne) maps to `{ not }`, which under `some` also excludes\n * runs where the attribute is absent (the missing-key-never-matches contract): `some` already\n * requires a matching row to exist. Numeric operands compare `numValue`, everything else `strValue`.\n */\nfunction attributeSome(f: AttributeFilter): Record<string, unknown> {\n // One comparison for a scalar op, one per member for `in` — ORed inside the single `some`, since\n // `in`'s operands may be of mixed types and so land in different typed columns. No comparisons at\n // all (an `in` over no values) can match no run, which is a run-level fact, not a side-table one.\n const comparisons = attributePredicateOperands(f).map(({ column, comparator, operand }) => ({\n [column]:\n comparator === '=' ? operand : comparator === '<>' ? { not: operand } : { [f.op]: operand },\n }));\n if (comparisons.length === 0) return MATCHES_NOTHING;\n return { attributes: { some: { key: f.key, ...anyOf(comparisons) } } };\n}\n\n/** A where fragment no run satisfies — what a plural predicate over an EMPTY set means. Spelled as an\n * impossible `id` rather than `OR: []` so it does not depend on how a Prisma version reads an empty\n * disjunction. */\nconst MATCHES_NOTHING: Record<string, unknown> = { id: { in: [] as string[] } };\n\n/** OR a set of where fragments, where an EMPTY set matches nothing rather than everything. */\nfunction anyOf(branches: Record<string, unknown>[]): Record<string, unknown> {\n return branches.length ? { OR: branches } : MATCHES_NOTHING;\n}\n\nconst bigOrNull = (n: number | undefined) => (n == null ? null : BigInt(n));\nconst numOrUndef = (n: bigint | null) => (n == null ? undefined : Number(n));\nconst jsonOrNull = (v: unknown) => v ?? null;\n\nfunction toRunData(run: WorkflowRun) {\n return {\n id: run.id,\n workflow: run.workflow,\n workflowVersion: run.workflowVersion,\n status: run.status,\n input: jsonOrNull(run.input),\n output: jsonOrNull(run.output),\n error: jsonOrNull(run.error),\n wakeAt: bigOrNull(run.wakeAt),\n lockedBy: run.lockedBy ?? null,\n lockedUntil: run.lockedUntil == null ? null : new Date(run.lockedUntil),\n awaitingDecisionTaskId: run.awaitingDecisionTaskId ?? null,\n recoveryAttempts: run.recoveryAttempts ?? null,\n tags: jsonOrNull(run.tags),\n searchAttributes: jsonOrNull(run.searchAttributes),\n priority: run.priority ?? null,\n // An absent namespace IS `'default'` — unlike `origin` below, this is a reconstruction and not a\n // guess: an engine started without a namespace stamps its runs and routes its workers as\n // `'default'`, so writing anything else (or NULL) would put the run in a partition no worker polls.\n namespace: run.namespace ?? 'default',\n // Absent origin stays SQL NULL — \"unknown\", never coerced into a real-looking library name.\n origin: run.origin ?? null,\n createdAt: run.createdAt,\n updatedAt: run.updatedAt,\n };\n}\n\nfunction toRunPatch(patch: Partial<WorkflowRun>) {\n // Map EVERY patchable field, using presence (`'x' in patch`) semantics for the nullable ones so a\n // patch can CLEAR a column (e.g. `{ error: undefined }` on completion sets it to NULL — matching\n // the TypeORM / MikroORM / in-memory stores). The two non-null Date fields use a defined-guard\n // since they are never cleared. Previously only 7 fields were mapped, so `updateRun({ tags })` /\n // `{ lockedBy }` / clearing `error` silently no-opped on this adapter.\n const data: Record<string, unknown> = {};\n if ('workflow' in patch) data.workflow = patch.workflow;\n if ('workflowVersion' in patch) data.workflowVersion = patch.workflowVersion;\n if ('status' in patch) data.status = patch.status;\n if ('input' in patch) data.input = jsonOrNull(patch.input);\n if ('output' in patch) data.output = jsonOrNull(patch.output);\n if ('error' in patch) data.error = jsonOrNull(patch.error);\n if ('wakeAt' in patch) data.wakeAt = bigOrNull(patch.wakeAt);\n if ('lockedBy' in patch) data.lockedBy = patch.lockedBy ?? null;\n if ('lockedUntil' in patch)\n data.lockedUntil = patch.lockedUntil == null ? null : new Date(patch.lockedUntil);\n if ('awaitingDecisionTaskId' in patch)\n data.awaitingDecisionTaskId = patch.awaitingDecisionTaskId ?? null;\n if ('recoveryAttempts' in patch) data.recoveryAttempts = patch.recoveryAttempts ?? null;\n if ('tags' in patch) data.tags = jsonOrNull(patch.tags);\n if ('searchAttributes' in patch) data.searchAttributes = jsonOrNull(patch.searchAttributes);\n if ('priority' in patch) data.priority = patch.priority ?? null;\n // `?? 'default'` rather than `?? null` like its neighbours: the column is NOT NULL, and clearing a\n // run's namespace means \"back to the unscoped partition\", which is what `'default'` names. A patch\n // that does not mention `namespace` leaves the stored one alone — a status update must never move a\n // run between tenants.\n if ('namespace' in patch) data.namespace = patch.namespace ?? 'default';\n if ('origin' in patch) data.origin = patch.origin ?? null;\n if (patch.createdAt != null) data.createdAt = patch.createdAt;\n if (patch.updatedAt != null) data.updatedAt = patch.updatedAt;\n return data;\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 WorkflowRun['status'],\n input: row.input ?? undefined,\n output: row.output ?? undefined,\n error: (row.error ?? undefined) as StepError | undefined,\n wakeAt: numOrUndef(row.wakeAt),\n lockedBy: row.lockedBy ?? undefined,\n lockedUntil: row.lockedUntil == null ? undefined : row.lockedUntil.getTime(),\n awaitingDecisionTaskId: row.awaitingDecisionTaskId ?? undefined,\n recoveryAttempts: row.recoveryAttempts ?? undefined,\n tags: (row.tags as string[] | null) ?? undefined,\n searchAttributes:\n (row.searchAttributes as Record<string, string | number | boolean> | null) ?? undefined,\n priority: row.priority ?? undefined,\n // Read back verbatim, with NO `?? 'default'` fallback. The column is NOT NULL and the migration\n // back-fills old rows, so there is nothing legitimate to fall back FROM; a fallback would only fire\n // on a deployment that added the column nullable without back-filling, and there it would lie —\n // the dashboard would show `default` for a row whose stored NULL keeps every `default` worker's\n // `WHERE namespace = 'default'` from ever picking it up.\n namespace: row.namespace,\n // NULL (a row written before the column existed) surfaces as `undefined` = unknown origin.\n origin: row.origin ?? undefined,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\n/** The name prefix each non-`step` {@link CheckpointNameKind} is, as `checkpointNameKind` reads it. */\nconst KIND_PREFIXES: [CheckpointNameKind, string][] = [\n ['child', 'signal:child:'],\n ['folded', 'fan:'],\n ['spawn', 'spawn:'],\n];\n\n/** Each {@link CheckpointNameKind} as the `where` that selects its rows; `step` is \"none of the others\". */\nconst NAME_KINDS: { kind: CheckpointNameKind; where: Record<string, unknown> }[] = [\n ...KIND_PREFIXES.map(([kind, prefix]) => ({ kind, where: { name: { startsWith: prefix } } })),\n {\n kind: 'step',\n where: { NOT: KIND_PREFIXES.map(([, prefix]) => ({ name: { startsWith: prefix } })) },\n },\n];\n\n/** One `groupBy` row of {@link PrismaStateStore.checkpointStats}. */\ntype CheckpointStatRow = {\n parallelGroup: string | null;\n status: string;\n _count: { _all: number; enqueuedAt: number };\n _min: { seq: number; name: string; enqueuedAt: Date | null; startedAt: Date };\n _max: { seq: number; name: string; startedAt: Date; finishedAt: Date };\n _sum: { attempts: number | bigint | null };\n};\n\nfunction bucketKey(group: string | null, status: string): string {\n return JSON.stringify([group, status]);\n}\n\nfunction toCheckpointStat(\n nameKind: CheckpointNameKind,\n r: CheckpointStatRow,\n unenqueued: Map<string, Date>,\n): CheckpointStat {\n const fallback = unenqueued.get(bucketKey(r.parallelGroup, r.status));\n const enqueued = r._min.enqueuedAt;\n const minEnqueuedAt =\n enqueued && fallback ? (enqueued < fallback ? enqueued : fallback) : (enqueued ?? fallback);\n return {\n group: r.parallelGroup,\n status: r.status as StepCheckpoint['status'],\n nameKind,\n count: r._count._all,\n minSeq: r._min.seq,\n maxSeq: r._max.seq,\n minName: r._min.name,\n maxName: r._max.name,\n // Every row has `enqueuedAt` or is in the NULL subset, so one of the two is set.\n minEnqueuedAt: minEnqueuedAt as Date,\n minStartedAt: r._min.startedAt,\n maxStartedAt: r._max.startedAt,\n maxFinishedAt: r._max.finishedAt,\n sumAttempts: Number(r._sum.attempts ?? 0),\n };\n}\n\nfunction toCheckpointData(cp: StepCheckpoint) {\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: jsonOrNull(cp.input),\n output: jsonOrNull(cp.output),\n error: jsonOrNull(cp.error),\n events: jsonOrNull(cp.events),\n attempts: cp.attempts,\n workerGroup: cp.workerGroup ?? null,\n parallelGroup: cp.parallelGroup ?? null,\n wakeAt: bigOrNull(cp.wakeAt),\n enqueuedAt: cp.enqueuedAt,\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: numOrUndef(row.wakeAt),\n enqueuedAt: row.enqueuedAt ?? row.startedAt,\n startedAt: row.startedAt,\n finishedAt: row.finishedAt,\n };\n}\n\nfunction toScheduleData(r: ScheduleRecord) {\n return {\n id: r.id,\n namespace: r.namespace,\n workflow: r.workflow,\n paused: r.paused,\n nextFireAt: r.nextFireAt == null ? null : BigInt(r.nextFireAt),\n tags: jsonOrNull(r.tags),\n spec: r.spec,\n state: r.state,\n createdAt: r.createdAt,\n updatedAt: r.updatedAt,\n };\n}\n\nfunction fromScheduleRow(row: ScheduleRow): ScheduleRecord {\n const tags = Array.isArray(row.tags) ? (row.tags as string[]) : undefined;\n return {\n id: row.id,\n namespace: row.namespace,\n workflow: row.workflow,\n paused: row.paused,\n nextFireAt: row.nextFireAt == null ? null : Number(row.nextFireAt),\n ...(tags?.length ? { tags } : {}),\n spec: (row.spec ?? {}) as Record<string, unknown>,\n state: (row.state ?? {}) as Record<string, unknown>,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n","/**\n * Tables this store's durable models own, physically. UNLIKE the other store adapters, this store\n * doesn't create or manage them at boot: the models in `prisma/schema.prisma` are meant to be copied\n * into YOUR OWN `schema.prisma` (see that file's header comment), and Prisma Migrate diffs whatever\n * models live in your schema — so a consumer who copied the models in already has them accounted for\n * and never needs a denylist for Prisma Migrate itself.\n *\n * This is exported anyway for the same reason the other adapters export it: any OTHER tooling that\n * introspects the database outside of `prisma migrate diff` (a raw schema dump, a second ORM/CLI\n * pointed at the same database, a linter that flags \"table not in any model\") needs the same fixed\n * list of table names this store's models declare via `@@map(...)`.\n *\n * ```ts\n * const skipTables = new Set(durableManagedTables());\n * ```\n *\n * Kept in sync with the `@@map(...)` table names in `prisma/schema.prisma` by `schema.spec.ts`,\n * which parses that file and asserts the two lists match — there is no single TypeScript source to\n * derive from (the schema is a `.prisma` text file copied into the consumer's own schema, not\n * imported at runtime), so the list here is intentionally a literal mirror.\n */\nexport function durableManagedTables(): string[] {\n return [\n 'durable_workflow_runs',\n 'durable_step_checkpoints',\n 'durable_run_attributes',\n 'durable_signal_waiters',\n 'durable_buffered_signals',\n 'durable_buffered_events',\n 'durable_schedules',\n ];\n}\n"],"mappings":"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","names":["namespaceWhere","namespace","undefined","PrismaStateStore","db","tryAdmitSingleton","runId","tag","workflow","limit","retryWakeAt","$transaction","tx","where","status","in","SINGLETON_ACTIVE_STATUSES","durableWorkflowRun","updateMany","data","rows","findMany","runs","map","fromRunRow","tags","singletonAdmissionTags","patch","singletonAdmissionDenialPatch","update","id","toRunPatch","createRun","run","create","toRunData","reindexAttributes","searchAttributes","updateRun","inputPatch","TERMINAL_RUN_STATUSES","includes","clearTerminalSingletonAdmission","getRun","updateRunIf","expectedStatuses","length","count","Object","keys","attributes","durableRunAttribute","deleteMany","normalizeAttributeRows","createMany","row","findUnique","deleteRun","durableStepCheckpoint","durableSignalWaiter","deleteRuns","runIds","pruneTerminalRuns","policy","nowMs","statuses","filter","s","maxAge","maxCount","scoped","runWhere","scope","ids","Set","cutoff","Date","parseDuration","AND","updatedAt","lt","select","orderBy","take","r","add","size","skip","doomed","slice","getCheckpoint","seq","runId_seq","fromCheckpointRow","saveCheckpoint","checkpoint","toCheckpointData","upsert","saveCheckpointIfPending","saveCheckpointsIfPending","checkpoints","wrote","push","transaction","work","raw","cp","listIncompleteRuns","listOrphanedRuns","OR","lockedUntil","lte","createdAt","listPendingRuns","listDueTimers","wakeAt","not","BigInt","tryLockRun","owner","leaseUntilMs","result","lockedBy","releaseRunLock","renewRunLock","query","and","workflows","anyOf","w","namespaces","n","origin","origins","o","array_contains","t","f","attributeSome","listRuns","offset","countRuns","runFacets","groupBy","by","_count","_all","mergeRunFacetRows","runValueFacets","axis","opts","axisIsRunColumn","scan","RUN_VALUE_FACET_SCAN","runValueFacetsFromRuns","field","mergeRunValueFacetRows","value","schedules","delegate","durableSchedule","Error","saveSchedule","record","toScheduleData","getSchedule","fromScheduleRow","updateSchedule","expectedNextFireAt","paused","nextFireAt","jsonOrNull","spec","state","deleteSchedule","listSchedules","dueBy","sort","nulls","listCheckpoints","getLatestCheckpointByName","name","findFirst","countCheckpoints","fromSeq","toSeq","gte","listCheckpointsByNamePrefix","prefixes","p","startsWith","some","checkpointStats","group","parallelGroup","grouped","Promise","all","NAME_KINDS","kind","enqueuedAt","_min","startedAt","_max","finishedAt","_sum","attempts","stats","unenqueued","unenqueuedStartedAt","Map","toCheckpointStat","flat","bucketKey","queryCheckpoints","namePrefixes","excludeGroups","notIn","putSignalWaiter","waiter","token","takeSignalWaiter","delete","listSignalWaiters","prefix","registerChildWaits","entries","compactCheckpoints","into","listSignalWaitersByRun","hasSignalWaiter","tokenPrefix","first","removeSignalWaiter","bufferSignal","payload","durableBufferedSignal","takeBufferedSignal","bufferEvent","input","durableBufferedEvent","publishedAt","listBufferedEvents","Number","removeBufferedEvent","comparisons","attributePredicateOperands","column","comparator","operand","op","MATCHES_NOTHING","key","branches","bigOrNull","numOrUndef","v","workflowVersion","output","error","awaitingDecisionTaskId","recoveryAttempts","priority","getTime","KIND_PREFIXES","NOT","JSON","stringify","nameKind","fallback","get","enqueued","minEnqueuedAt","minSeq","maxSeq","minName","maxName","minStartedAt","maxStartedAt","maxFinishedAt","sumAttempts","stepId","events","workerGroup","Array","isArray","durableManagedTables"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StateStore, WorkflowRun, RetentionPolicy, StepCheckpoint, RunQuery, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, ScheduleRecord, ScheduleQuery, CheckpointStat, CheckpointQuery, SignalWaiter, ChildWait } from '@dudousxd/nestjs-durable-core';
|
|
1
|
+
import { StateStore, WorkflowRun, RunStatus, RetentionPolicy, StepCheckpoint, RunQuery, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, ScheduleRecord, ScheduleQuery, CheckpointStat, CheckpointQuery, SignalWaiter, ChildWait } from '@dudousxd/nestjs-durable-core';
|
|
2
2
|
|
|
3
3
|
interface RunRow {
|
|
4
4
|
id: string;
|
|
@@ -129,6 +129,7 @@ declare class PrismaStateStore implements StateStore {
|
|
|
129
129
|
tryAdmitSingleton(runId: string, tag: string, workflow: string, limit: number, retryWakeAt?: number): Promise<boolean>;
|
|
130
130
|
createRun(run: WorkflowRun): Promise<void>;
|
|
131
131
|
updateRun(runId: string, inputPatch: Partial<WorkflowRun>): Promise<void>;
|
|
132
|
+
updateRunIf(runId: string, expectedStatuses: RunStatus[], inputPatch: Partial<WorkflowRun>): Promise<boolean>;
|
|
132
133
|
/** Rewrite a run's normalized attribute rows: delete the old set, insert the current one. Mirrors
|
|
133
134
|
* the in-memory store's reindex so the side-table always reflects the run's live searchAttributes. */
|
|
134
135
|
private reindexAttributes;
|
|
@@ -145,6 +146,7 @@ declare class PrismaStateStore implements StateStore {
|
|
|
145
146
|
saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;
|
|
146
147
|
}) => Promise<T>): Promise<T>;
|
|
147
148
|
listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
|
|
149
|
+
listOrphanedRuns(nowMs: number, limit: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
148
150
|
listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
149
151
|
listDueTimers(nowMs: number, namespace?: string, limit?: number): Promise<WorkflowRun[]>;
|
|
150
152
|
tryLockRun(runId: string, owner: string, leaseUntilMs: number, nowMs: number): Promise<boolean>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StateStore, WorkflowRun, RetentionPolicy, StepCheckpoint, RunQuery, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, ScheduleRecord, ScheduleQuery, CheckpointStat, CheckpointQuery, SignalWaiter, ChildWait } from '@dudousxd/nestjs-durable-core';
|
|
1
|
+
import { StateStore, WorkflowRun, RunStatus, RetentionPolicy, StepCheckpoint, RunQuery, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, ScheduleRecord, ScheduleQuery, CheckpointStat, CheckpointQuery, SignalWaiter, ChildWait } from '@dudousxd/nestjs-durable-core';
|
|
2
2
|
|
|
3
3
|
interface RunRow {
|
|
4
4
|
id: string;
|
|
@@ -129,6 +129,7 @@ declare class PrismaStateStore implements StateStore {
|
|
|
129
129
|
tryAdmitSingleton(runId: string, tag: string, workflow: string, limit: number, retryWakeAt?: number): Promise<boolean>;
|
|
130
130
|
createRun(run: WorkflowRun): Promise<void>;
|
|
131
131
|
updateRun(runId: string, inputPatch: Partial<WorkflowRun>): Promise<void>;
|
|
132
|
+
updateRunIf(runId: string, expectedStatuses: RunStatus[], inputPatch: Partial<WorkflowRun>): Promise<boolean>;
|
|
132
133
|
/** Rewrite a run's normalized attribute rows: delete the old set, insert the current one. Mirrors
|
|
133
134
|
* the in-memory store's reindex so the side-table always reflects the run's live searchAttributes. */
|
|
134
135
|
private reindexAttributes;
|
|
@@ -145,6 +146,7 @@ declare class PrismaStateStore implements StateStore {
|
|
|
145
146
|
saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;
|
|
146
147
|
}) => Promise<T>): Promise<T>;
|
|
147
148
|
listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
|
|
149
|
+
listOrphanedRuns(nowMs: number, limit: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
148
150
|
listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
149
151
|
listDueTimers(nowMs: number, namespace?: string, limit?: number): Promise<WorkflowRun[]>;
|
|
150
152
|
tryLockRun(runId: string, owner: string, leaseUntilMs: number, nowMs: number): Promise<boolean>;
|
package/dist/index.js
CHANGED
|
@@ -74,6 +74,26 @@ var PrismaStateStore = class {
|
|
|
74
74
|
});
|
|
75
75
|
if ("searchAttributes" in patch) await this.reindexAttributes(runId, patch.searchAttributes);
|
|
76
76
|
}
|
|
77
|
+
async updateRunIf(runId, expectedStatuses, inputPatch) {
|
|
78
|
+
if (expectedStatuses.length === 0) return false;
|
|
79
|
+
const patch = inputPatch.status && TERMINAL_RUN_STATUSES.includes(inputPatch.status) ? await clearTerminalSingletonAdmission(runId, inputPatch, (id) => this.getRun(id)) : inputPatch;
|
|
80
|
+
const where = {
|
|
81
|
+
id: runId,
|
|
82
|
+
status: {
|
|
83
|
+
in: expectedStatuses
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const data = toRunPatch(patch);
|
|
87
|
+
const count = Object.keys(data).length ? (await this.db.durableWorkflowRun.updateMany({
|
|
88
|
+
where,
|
|
89
|
+
data
|
|
90
|
+
})).count : await this.db.durableWorkflowRun.count({
|
|
91
|
+
where
|
|
92
|
+
});
|
|
93
|
+
if (count === 0) return false;
|
|
94
|
+
if ("searchAttributes" in patch) await this.reindexAttributes(runId, patch.searchAttributes);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
77
97
|
/** Rewrite a run's normalized attribute rows: delete the old set, insert the current one. Mirrors
|
|
78
98
|
* the in-memory store's reindex so the side-table always reflects the run's live searchAttributes. */
|
|
79
99
|
async reindexAttributes(runId, attributes) {
|
|
@@ -297,6 +317,35 @@ var PrismaStateStore = class {
|
|
|
297
317
|
});
|
|
298
318
|
return rows.map(fromRunRow);
|
|
299
319
|
}
|
|
320
|
+
async listOrphanedRuns(nowMs, limit, namespace) {
|
|
321
|
+
if (limit <= 0) return [];
|
|
322
|
+
const rows = await this.db.durableWorkflowRun.findMany({
|
|
323
|
+
where: {
|
|
324
|
+
status: {
|
|
325
|
+
in: [
|
|
326
|
+
"running",
|
|
327
|
+
"cancelling"
|
|
328
|
+
]
|
|
329
|
+
},
|
|
330
|
+
OR: [
|
|
331
|
+
{
|
|
332
|
+
lockedUntil: null
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
lockedUntil: {
|
|
336
|
+
lte: new Date(nowMs)
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
],
|
|
340
|
+
...namespaceWhere(namespace)
|
|
341
|
+
},
|
|
342
|
+
orderBy: {
|
|
343
|
+
createdAt: "asc"
|
|
344
|
+
},
|
|
345
|
+
take: limit
|
|
346
|
+
});
|
|
347
|
+
return rows.map(fromRunRow);
|
|
348
|
+
}
|
|
300
349
|
async listPendingRuns(limit, namespace) {
|
|
301
350
|
const rows = await this.db.durableWorkflowRun.findMany({
|
|
302
351
|
where: {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/prisma-state-store.ts","../src/schema.ts"],"sourcesContent":["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 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';\n\n/* The Prisma client is generated per-schema, so the adapter can't import a concrete one. Instead\n it depends on this structural surface — the three model delegates and the methods it uses. A\n real `PrismaClient` (with the models from prisma/schema.prisma added) satisfies it. Query-arg\n shapes are Prisma's own generics, so they're left as `any` at this single boundary; the row\n return types are precise, which is what the mapping code below relies on. */\n\ninterface RunRow {\n id: string;\n workflow: string;\n workflowVersion: string;\n status: string;\n input: unknown;\n output: unknown;\n error: unknown;\n wakeAt: bigint | null;\n lockedBy: string | null;\n lockedUntil: Date | null;\n awaitingDecisionTaskId: string | null;\n recoveryAttempts: number | null;\n tags: unknown;\n searchAttributes: unknown;\n priority: number | null;\n /** NOT NULL in the schema (defaulted to `'default'`), so every row carries a real namespace. */\n namespace: string;\n origin: string | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface CheckpointRow {\n runId: string;\n seq: number;\n name: string;\n kind: string;\n stepId: string;\n status: string;\n input: unknown;\n output: unknown;\n error: unknown;\n events: unknown;\n attempts: number;\n workerGroup: string | null;\n parallelGroup: string | null;\n wakeAt: bigint | null;\n enqueuedAt: Date | null;\n startedAt: Date;\n finishedAt: Date;\n}\n\ninterface WaiterRow {\n token: string;\n runId: string;\n seq: number;\n parallelGroup: string | null;\n}\n\ninterface RunAttributeRow {\n runId: string;\n key: string;\n strValue: string | null;\n numValue: number | null;\n}\n\ninterface BufferedSignalRow {\n id: bigint;\n token: string;\n payload: unknown;\n}\n\ninterface BufferedEventRow {\n id: string;\n name: string;\n payload: unknown;\n publishedAt: bigint;\n}\n\n// Prisma's per-model query args are generated generics; left as `any` at this single boundary.\ntype Args = any;\n\ninterface Delegate<Row> {\n create(args: Args): Promise<Row>;\n createMany(args: Args): Promise<{ count: number }>;\n findUnique(args: Args): Promise<Row | null>;\n findFirst(args?: Args): Promise<Row | null>;\n findMany(args?: Args): Promise<Row[]>;\n update(args: Args): Promise<Row>;\n updateMany(args: Args): Promise<{ count: number }>;\n upsert(args: Args): Promise<Row>;\n delete(args: Args): Promise<Row>;\n deleteMany(args?: Args): Promise<{ count: number }>;\n count(args?: Args): Promise<number>;\n /** Aggregate form — used by the run facets and `checkpointStats`, whose rows are aggregate cells,\n * not model rows, so the result type is stated at the call site rather than derived from `Row`. */\n groupBy(args: Args): Promise<Record<string, unknown>[]>;\n}\n\ninterface ScheduleRow {\n id: string;\n namespace: string;\n workflow: string;\n paused: boolean;\n nextFireAt: bigint | null;\n tags: unknown;\n spec: unknown;\n state: unknown;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface DurablePrismaTx {\n durableWorkflowRun: Delegate<RunRow>;\n durableStepCheckpoint: Delegate<CheckpointRow>;\n durableRunAttribute: Delegate<RunAttributeRow>;\n durableSignalWaiter: Delegate<WaiterRow>;\n durableBufferedSignal: Delegate<BufferedSignalRow>;\n durableBufferedEvent: Delegate<BufferedEventRow>;\n /** Only needed for persisted schedules (`engine.schedules`) — add the `DurableSchedule` model. */\n durableSchedule?: Delegate<ScheduleRow>;\n}\n\nexport interface DurablePrismaClient extends DurablePrismaTx {\n /** Prisma's interactive-transaction form: runs `fn` with a tx-scoped client and commits on resolve. */\n $transaction<T>(fn: (tx: DurablePrismaTx) => Promise<T>): Promise<T>;\n}\n\n/**\n * The `namespace` read boundary as a spreadable Prisma `where` fragment.\n *\n * `undefined` means NO RESTRICTION — `{}` — because that is the operator (control-plane) view that\n * sees every tenant, and it is what the engine passes when it runs unscoped. It does NOT mean\n * \"namespace IS NULL\": the column is NOT NULL, so `{ namespace: undefined }` would be Prisma's\n * \"ignore this predicate\" anyway, but `{ namespace: null }` would match nothing in production while\n * still looking correct in a single-tenant test where every worker polls unscoped.\n *\n * A named namespace is plain equality, so a worker sees only its own tenant's rows — the boundary\n * {@link WorkflowRun.namespace} promises for the four worker paths (pick up, recover, resume timers,\n * time out).\n */\nfunction namespaceWhere(namespace?: string): { namespace?: string } {\n if (namespace === undefined) return {};\n return { namespace };\n}\n\n/**\n * Prisma-backed `StateStore`. Pass your `PrismaClient` after adding the models from\n * `prisma/schema.prisma` to your schema. JSON columns carry the run/step payloads directly;\n * `wakeAt` is a `BigInt` (epoch ms).\n *\n * Every path a worker acts on is namespace-scoped when it is given one — `listPendingRuns` (pick up),\n * `listIncompleteRuns` (recover), `listDueTimers` (resume timers) and `listRuns`'s `namespace`\n * (the engine's timeout sweep). Omit it for the operator view across all tenants. Point-reads\n * (`getRun`, checkpoints) are deliberately NOT scoped, per {@link StateStore}.\n */\nexport class PrismaStateStore implements StateStore {\n constructor(private readonly db: DurablePrismaClient) {}\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 = { workflow, status: { in: SINGLETON_ACTIVE_STATUSES } };\n // A locking write first: concurrent claims cannot read the same free slot.\n await tx.durableWorkflowRun.updateMany({ where, data: { workflow } });\n const rows = await tx.durableWorkflowRun.findMany({ 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.durableWorkflowRun.update({ where: { id: runId }, data: toRunPatch(patch) });\n return false;\n }\n await tx.durableWorkflowRun.update({ where: { id: runId }, data: { tags } });\n return true;\n });\n }\n\n async createRun(run: WorkflowRun): Promise<void> {\n await this.db.durableWorkflowRun.create({ data: toRunData(run) });\n await this.reindexAttributes(run.id, run.searchAttributes);\n }\n\n async updateRun(runId: string, inputPatch: Partial<WorkflowRun>): Promise<void> {\n const patch =\n inputPatch.status && TERMINAL_RUN_STATUSES.includes(inputPatch.status)\n ? await clearTerminalSingletonAdmission(runId, inputPatch, (id) => this.getRun(id))\n : inputPatch;\n await this.db.durableWorkflowRun.update({ where: { id: runId }, data: toRunPatch(patch) });\n // Keep the side-table in step with the run's attributes whenever they're patched.\n if ('searchAttributes' in patch) await this.reindexAttributes(runId, patch.searchAttributes);\n }\n\n /** Rewrite a run's normalized attribute rows: delete the old set, insert the current one. Mirrors\n * the in-memory store's reindex so the side-table always reflects the run's live searchAttributes. */\n private async reindexAttributes(\n runId: string,\n attributes: WorkflowRun['searchAttributes'],\n ): Promise<void> {\n await this.db.durableRunAttribute.deleteMany({ where: { runId } });\n const rows = normalizeAttributeRows(runId, attributes);\n if (rows.length) await this.db.durableRunAttribute.createMany({ data: rows });\n }\n\n async getRun(runId: string): Promise<WorkflowRun | null> {\n const row = await this.db.durableWorkflowRun.findUnique({ where: { id: runId } });\n return row ? fromRunRow(row) : null;\n }\n\n async deleteRun(runId: string): Promise<void> {\n // Child rows first, then the run — checkpoints, signal waiters, attribute rows.\n await this.db.durableStepCheckpoint.deleteMany({ where: { runId } });\n await this.db.durableSignalWaiter.deleteMany({ where: { runId } });\n await this.db.durableRunAttribute.deleteMany({ where: { runId } });\n await this.db.durableWorkflowRun.deleteMany({ where: { id: runId } });\n }\n\n async deleteRuns(runIds: string[]): Promise<void> {\n if (runIds.length === 0) return;\n // Same cascade as deleteRun, one `IN (...)` per table, atomically.\n await this.db.$transaction(async (tx) => {\n await tx.durableStepCheckpoint.deleteMany({ where: { runId: { in: runIds } } });\n await tx.durableSignalWaiter.deleteMany({ where: { runId: { in: runIds } } });\n await tx.durableRunAttribute.deleteMany({ where: { runId: { in: runIds } } });\n await tx.durableWorkflowRun.deleteMany({ where: { id: { in: 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.runWhere({ ...(policy.scope ?? {}), statuses });\n const ids = new Set<string>();\n if (policy.maxAge != null) {\n const cutoff = new Date(nowMs - parseDuration(policy.maxAge));\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { AND: [scoped, { updatedAt: { lt: cutoff } }] },\n select: { id: true },\n orderBy: { updatedAt: 'asc' }, // oldest first\n take: limit,\n });\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 scoped status set (skipped by OFFSET).\n const rows = await this.db.durableWorkflowRun.findMany({\n where: scoped,\n select: { id: true },\n orderBy: [{ updatedAt: 'desc' }, { id: 'desc' }],\n skip: policy.maxCount,\n take: limit,\n });\n for (const r of rows) {\n if (ids.size >= limit) break;\n ids.add(r.id);\n }\n }\n const doomed = [...ids].slice(0, limit);\n await this.deleteRuns(doomed);\n return doomed.length;\n }\n\n async getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null> {\n const row = await this.db.durableStepCheckpoint.findUnique({\n where: { runId_seq: { runId, seq } },\n });\n return row ? fromCheckpointRow(row) : null;\n }\n\n async saveCheckpoint(checkpoint: StepCheckpoint): Promise<void> {\n const data = toCheckpointData(checkpoint);\n await this.db.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: checkpoint.runId, seq: checkpoint.seq } },\n create: data,\n update: data,\n });\n }\n\n async saveCheckpointIfPending(checkpoint: StepCheckpoint): Promise<boolean> {\n // One conditional `updateMany` (`UPDATE … WHERE run_id = ? AND seq = ? AND status = 'pending'`):\n // the status predicate is the compare, the row count the answer, and a missing row is never made.\n const { runId, seq, ...data } = toCheckpointData(checkpoint);\n const { count } = await this.db.durableStepCheckpoint.updateMany({\n where: { runId, seq, status: 'pending' },\n data,\n });\n return count > 0;\n }\n\n async saveCheckpointsIfPending(checkpoints: StepCheckpoint[]): Promise<boolean[]> {\n if (checkpoints.length === 0) return [];\n // The conditional `updateMany` of `saveCheckpointIfPending`, once per entry, in order, in one\n // transaction: one commit for the batch, and a rejection writes nothing.\n return this.db.$transaction(async (tx) => {\n const wrote: boolean[] = [];\n for (const checkpoint of checkpoints) {\n const { runId, seq, ...data } = toCheckpointData(checkpoint);\n const { count } = await tx.durableStepCheckpoint.updateMany({\n where: { runId, seq, status: 'pending' },\n data,\n });\n wrote.push(count > 0);\n }\n return wrote;\n });\n }\n\n async transaction<T>(\n work: (tx: {\n raw: unknown;\n saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;\n }) => Promise<T>,\n ): Promise<T> {\n return this.db.$transaction(async (tx) =>\n work({\n raw: tx,\n saveCheckpoint: async (cp) => {\n const data = toCheckpointData(cp);\n await tx.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: cp.runId, seq: cp.seq } },\n create: data,\n update: data,\n });\n },\n }),\n );\n }\n\n async listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: { in: ['running', 'cancelling'] }, ...namespaceWhere(namespace) },\n });\n return rows.map(fromRunRow);\n }\n\n async listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: 'pending', ...namespaceWhere(namespace) },\n orderBy: { createdAt: 'asc' }, // FIFO dispatch\n take: limit,\n });\n return rows.map(fromRunRow);\n }\n\n async listDueTimers(nowMs: number, namespace?: string, limit?: number): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: {\n status: 'suspended',\n wakeAt: { not: null, lte: BigInt(nowMs) },\n ...namespaceWhere(namespace),\n },\n orderBy: { wakeAt: 'asc' },\n ...(limit !== undefined ? { take: limit } : {}),\n });\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 const result = await this.db.durableWorkflowRun.updateMany({\n where: {\n id: runId,\n OR: [{ lockedUntil: null }, { lockedUntil: { lte: new Date(nowMs) } }],\n },\n data: { lockedBy: owner, lockedUntil: new Date(leaseUntilMs) },\n });\n return result.count === 1;\n }\n\n async releaseRunLock(runId: string): Promise<void> {\n // Idempotent by design: releasing the lease on a run that no longer exists is a no-op, not an\n // error. The engine calls this best-effort in a `finally` AFTER the run has settled, so it can\n // race a concurrent purge/teardown — Prisma's `update({ where: { id } })` would throw P2025\n // (\"No record was found for an update\") on that race and, since the call is fire-and-forget on\n // the engine's terminal path, surface as an unhandled rejection. `updateMany` matches a 0-row\n // WHERE to an empty result (no throw), mirroring the in-memory store's `if (run)` guard and the\n // set-where semantics of every sibling adapter (TypeORM/MikroORM/Drizzle).\n await this.db.durableWorkflowRun.updateMany({\n where: { id: runId },\n data: { lockedBy: null, lockedUntil: null },\n });\n }\n\n async renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean> {\n const result = await this.db.durableWorkflowRun.updateMany({\n where: { id: runId, lockedBy: owner },\n data: { lockedUntil: new Date(leaseUntilMs) },\n });\n return result.count === 1;\n }\n\n /** The `where` every run query shares — {@link listRuns} pages it, {@link runFacets} groups it. */\n private runWhere(query: RunQuery): Record<string, unknown> {\n // The tenant boundary, and NOT only a dashboard facet: the engine's `sweepTimeouts` finds the runs\n // it may cancel through `listRuns({ workflow, status, namespace })`, so an unfiltered `namespace`\n // here lets a worker serving one tenant time out another tenant's runs — a write, not a stale\n // read. Same `undefined` = no restriction rule as the poll paths above (see `namespaceWhere`),\n // which is what keeps the operator's dashboard showing every tenant by default.\n const where: Record<string, unknown> = { ...namespaceWhere(query.namespace) };\n // The plural predicates below can't sit on `where` directly (a key holds one condition, and the\n // single form may already own it), so they accumulate here and are ANDed at the end. Each is ORed\n // within itself and matches NOTHING when empty — the contract `statuses` already had.\n const and: Record<string, unknown>[] = [];\n if (query.workflow) where.workflow = query.workflow;\n if (query.workflows) and.push(anyOf(query.workflows.map((w) => ({ workflow: w }))));\n if (query.namespaces) and.push(anyOf(query.namespaces.map((n) => ({ namespace: n }))));\n // Which library registered the workflow. Plain equality, so a run whose origin is NULL (created\n // before the column existed, or registered through a path the derivation could not classify)\n // matches NO origin value — it is never folded into a bucket to make the facet look complete.\n // Unknown-origin runs are reachable only with the filter OFF, so \"all origins\" must stay the\n // default view; a dashboard that filtered by default would make those runs look deleted.\n // Passing `null` asks for exactly the unattributed bucket (`origin IS NULL`) — Prisma spells that\n // as the same equality — which is how a paginated console can offer an \"unknown\" chip.\n if (query.origin !== undefined) where.origin = query.origin;\n // `null` is a member like any other in a set of origins — Prisma spells `origin IS NULL` as the\n // same equality — so one branch per value covers both the named ones and the unattributed bucket.\n if (query.origins) and.push(anyOf(query.origins.map((o) => ({ origin: o }))));\n // `status IN (...)`; an empty set matches nothing (mirrors the in-memory store). Combined with the\n // single-value `status` via AND when both are present, so the narrower set wins.\n if (query.status && query.statuses) {\n and.push({ status: query.status }, { status: { in: query.statuses } });\n } else if (query.status) {\n where.status = query.status;\n } else if (query.statuses) {\n where.status = { in: query.statuses };\n }\n if (query.tag) where.tags = { array_contains: query.tag };\n if (query.tags) and.push(anyOf(query.tags.map((t) => ({ tags: { array_contains: t } }))));\n // Typed/range attribute predicates push DOWN into SQL: each filter becomes a relation `some`\n // (EXISTS) on the normalized `durable_run_attributes` side-table, so the DB filters AND paginates\n // — no full scan + in-process filter. ANDed: a run must match every filter, so one `some` each.\n if (query.attributes?.length) and.push(...query.attributes.map((f) => attributeSome(f)));\n if (and.length) where.AND = and;\n return where;\n }\n\n async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n const orderBy = { createdAt: 'desc' as const }; // newest first — recent runs on top in the dashboard\n const rows = await this.db.durableWorkflowRun.findMany({\n where: this.runWhere(query),\n take: query.limit,\n skip: query.offset,\n orderBy,\n });\n return rows.map(fromRunRow);\n }\n\n async countRuns(query: Omit<RunQuery, 'limit' | 'offset'>): Promise<number> {\n return this.db.durableWorkflowRun.count({ where: this.runWhere(query) });\n }\n\n /** `GROUP BY status, origin` over the same predicates {@link listRuns} pages — one aggregate, so a\n * console can show whole-set counts next to a bounded page instead of downloading every run to\n * count them in the browser. */\n async runFacets(query: RunFacetQuery): Promise<RunFacetRow[]> {\n const rows = (await this.db.durableWorkflowRun.groupBy({\n by: ['status', 'origin'],\n where: this.runWhere(query),\n _count: { _all: true },\n })) as { status: RunStatus; origin: string | null; _count: { _all: number } }[];\n return mergeRunFacetRows(\n rows.map((r) => ({ status: r.status, origin: r.origin, count: r._count._all })),\n );\n }\n\n /** Distinct values of one filter axis over the same predicates {@link listRuns} pages. A run-table\n * column is a `groupBy` like {@link runFacets}, exact over the whole matching set; the tag and\n * attribute axes live outside the row (json column / side table) and are counted from a bounded\n * page of runs instead — see `RunValueFacetOptions.scan`. */\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 rows = (await this.db.durableWorkflowRun.groupBy({\n by: [axis.field],\n where: this.runWhere(query),\n _count: { _all: true },\n })) as (Record<string, string | null> & { _count: { _all: number } })[];\n return mergeRunValueFacetRows(\n rows.map((r) => ({ value: r[axis.field] ?? null, count: r._count._all })),\n opts,\n );\n }\n\n // ---- persisted schedules ----------------------------------------------------------------------\n\n private schedules(): Delegate<ScheduleRow> {\n const delegate = this.db.durableSchedule;\n if (!delegate) {\n throw new Error(\n 'persisted schedules need the DurableSchedule model — copy it from prisma/schema.prisma into your schema and re-run `prisma generate`',\n );\n }\n return delegate;\n }\n\n async saveSchedule(record: ScheduleRecord): Promise<void> {\n const data = toScheduleData(record);\n await this.schedules().upsert({ where: { id: record.id }, create: data, update: data });\n }\n\n async getSchedule(id: string): Promise<ScheduleRecord | null> {\n const row = await this.schedules().findUnique({ where: { id } });\n return row ? fromScheduleRow(row) : null;\n }\n\n /** One conditional `updateMany`: the compare-and-set on `next_fire_at` is a single statement. */\n async updateSchedule(\n id: string,\n patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>,\n expectedNextFireAt?: number | null,\n ): Promise<boolean> {\n const data: Record<string, unknown> = {};\n if (patch.namespace !== undefined) data.namespace = patch.namespace;\n if (patch.workflow !== undefined) data.workflow = patch.workflow;\n if (patch.paused !== undefined) data.paused = patch.paused;\n if ('nextFireAt' in patch)\n data.nextFireAt = patch.nextFireAt == null ? null : BigInt(patch.nextFireAt);\n if ('tags' in patch) data.tags = jsonOrNull(patch.tags);\n if (patch.spec !== undefined) data.spec = patch.spec;\n if (patch.state !== undefined) data.state = patch.state;\n if (patch.updatedAt !== undefined) data.updatedAt = patch.updatedAt;\n if (!Object.keys(data).length) return (await this.getSchedule(id)) !== null;\n const where: Record<string, unknown> = { id };\n if (expectedNextFireAt !== undefined)\n where.nextFireAt = expectedNextFireAt === null ? null : BigInt(expectedNextFireAt);\n const { count } = await this.schedules().updateMany({ where, data });\n return count > 0;\n }\n\n async deleteSchedule(id: string): Promise<boolean> {\n const { count } = await this.schedules().deleteMany({ where: { id } });\n return count > 0;\n }\n\n async listSchedules(query: ScheduleQuery): Promise<ScheduleRecord[]> {\n const where: Record<string, unknown> = {};\n if (query.namespace !== undefined) where.namespace = query.namespace;\n if (query.workflow !== undefined) where.workflow = query.workflow;\n if (query.paused !== undefined) where.paused = query.paused;\n if (query.tag !== undefined) where.tags = { array_contains: query.tag };\n if (query.dueBy !== undefined) {\n where.AND = [{ paused: false }, { nextFireAt: { lte: BigInt(query.dueBy) } }];\n }\n const rows = await this.schedules().findMany({\n where,\n // Soonest-due first, never-firing (NULL) last, id as the stable tie-break.\n orderBy: [{ nextFireAt: { sort: 'asc', nulls: 'last' } }, { id: 'asc' }],\n take: query.limit,\n skip: query.offset,\n });\n return rows.map(fromScheduleRow);\n }\n\n async listCheckpoints(runId: string): Promise<StepCheckpoint[]> {\n const rows = await this.db.durableStepCheckpoint.findMany({\n where: { runId },\n orderBy: { seq: 'asc' },\n });\n return rows.map(fromCheckpointRow);\n }\n\n async getLatestCheckpointByName(\n runId: string,\n name: string,\n ): Promise<StepCheckpoint | undefined> {\n const row = await this.db.durableStepCheckpoint.findFirst({\n where: { runId, name },\n orderBy: { seq: 'desc' },\n });\n return row ? fromCheckpointRow(row) : 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 return this.db.durableStepCheckpoint.count({\n where: { runId, seq: { gte: fromSeq, lte: toSeq }, status: { in: statuses } },\n });\n }\n\n async listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]> {\n if (prefixes.length === 0) return [];\n const rows = await this.db.durableStepCheckpoint.findMany({\n where: { runId, OR: prefixes.map((p) => ({ name: { startsWith: p } })) },\n orderBy: { seq: 'asc' },\n });\n // On some providers (SQLite) `startsWith` compiles to a `LIKE` that reads `_` and `%` as wildcards,\n // so it can match more than the prefix: keep only the exact matches.\n return rows.filter((r) => prefixes.some((p) => r.name.startsWith(p))).map(fromCheckpointRow);\n }\n\n /**\n * One `groupBy(parallelGroup, status)` per {@link CheckpointNameKind}, each narrowed to its kind by\n * a name-prefix predicate, run concurrently — Prisma cannot group by a `CASE`, so the kind is the\n * `where` instead. `minEnqueuedAt` reads a NULL `enqueuedAt` as `startedAt` (as\n * {@link fromCheckpointRow} does): a bucket whose non-null `enqueuedAt` count falls short of its\n * row count has such rows, and only for those kinds is the NULL subset's `min(startedAt)` asked for.\n *\n * On SQLite `startsWith` is a case-insensitive `LIKE`, as in {@link listCheckpointsByNamePrefix};\n * the kind prefixes are lower-case and wildcard-free, so only a step whose name starts with one of\n * them in another case would be classified differently there.\n */\n async checkpointStats(\n runId: string,\n opts?: { group?: string | undefined },\n ): Promise<CheckpointStat[]> {\n const scope = opts?.group === undefined ? { runId } : { runId, parallelGroup: opts.group };\n const grouped = await Promise.all(\n NAME_KINDS.map(async ({ kind, where }) => ({\n kind,\n where,\n rows: (await this.db.durableStepCheckpoint.groupBy({\n by: ['parallelGroup', 'status'],\n where: { ...scope, ...where },\n _count: { _all: true, enqueuedAt: true },\n _min: { seq: true, name: true, enqueuedAt: true, startedAt: true },\n _max: { seq: true, name: true, startedAt: true, finishedAt: true },\n _sum: { attempts: true },\n })) as CheckpointStatRow[],\n })),\n );\n const stats = await Promise.all(\n grouped.map(async ({ kind, where, rows }) => {\n const unenqueued = rows.some((r) => r._count.enqueuedAt < r._count._all)\n ? await this.unenqueuedStartedAt({ ...scope, ...where })\n : new Map<string, Date>();\n return rows.map((r) => toCheckpointStat(kind, r, unenqueued));\n }),\n );\n return stats.flat();\n }\n\n /** `min(startedAt)` per `(parallelGroup, status)` over the rows whose `enqueuedAt` is NULL. */\n private async unenqueuedStartedAt(where: Record<string, unknown>): Promise<Map<string, Date>> {\n const rows = (await this.db.durableStepCheckpoint.groupBy({\n by: ['parallelGroup', 'status'],\n where: { ...where, enqueuedAt: null },\n _min: { startedAt: true },\n })) as { parallelGroup: string | null; status: string; _min: { startedAt: Date } }[];\n return new Map(rows.map((r) => [bucketKey(r.parallelGroup, r.status), r._min.startedAt]));\n }\n\n /** {@link CheckpointQuery} as one `findMany`, in `seq` order, paged by `skip`/`take`. Ungrouped rows\n * are kept past `excludeGroups` explicitly: `NOT IN` alone drops a NULL `parallelGroup`. */\n async queryCheckpoints(runId: string, query: CheckpointQuery): Promise<StepCheckpoint[]> {\n if (query.statuses?.length === 0 || query.namePrefixes?.length === 0) return [];\n const and: Record<string, unknown>[] = [];\n if (query.excludeGroups?.length) {\n and.push({\n OR: [{ parallelGroup: null }, { parallelGroup: { notIn: query.excludeGroups } }],\n });\n }\n if (query.namePrefixes) {\n and.push({ OR: query.namePrefixes.map((p) => ({ name: { startsWith: p } })) });\n }\n const rows = await this.db.durableStepCheckpoint.findMany({\n where: {\n runId,\n ...(query.group === undefined ? {} : { parallelGroup: query.group }),\n ...(query.statuses ? { status: { in: query.statuses } } : {}),\n ...(and.length ? { AND: and } : {}),\n },\n orderBy: { seq: 'asc' },\n skip: query.offset,\n take: query.limit,\n });\n return rows.map(fromCheckpointRow);\n }\n\n async putSignalWaiter(waiter: SignalWaiter): Promise<void> {\n await this.db.durableSignalWaiter.upsert({\n where: { token: waiter.token },\n create: {\n token: waiter.token,\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n },\n update: {\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n },\n });\n }\n\n async takeSignalWaiter(token: string): Promise<SignalWaiter | null> {\n const row = await this.db.durableSignalWaiter.findUnique({ where: { token } });\n if (!row) return null;\n await this.db.durableSignalWaiter.delete({ where: { token } });\n return {\n token: row.token,\n runId: row.runId,\n seq: row.seq,\n parallelGroup: row.parallelGroup ?? undefined,\n };\n }\n\n async listSignalWaiters(prefix: string): Promise<SignalWaiter[]> {\n const rows = await this.db.durableSignalWaiter.findMany({\n where: { token: { startsWith: prefix } },\n });\n // On some providers (SQLite) `startsWith` compiles to a `LIKE` that reads `_` and `%` as wildcards,\n // so it can match more than the prefix: keep only the exact matches.\n return rows\n .filter((r) => r.token.startsWith(prefix))\n .map((r) => ({\n token: r.token,\n runId: r.runId,\n seq: r.seq,\n parallelGroup: r.parallelGroup ?? undefined,\n }));\n }\n\n async registerChildWaits(entries: ChildWait[]): Promise<void> {\n if (entries.length === 0) return;\n // Prisma has no multi-row upsert: one upsert per row, inside a single transaction.\n await this.db.$transaction(async (tx) => {\n for (const { waiter } of entries) {\n const data = {\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n };\n await tx.durableSignalWaiter.upsert({\n where: { token: waiter.token },\n create: { token: waiter.token, ...data },\n update: data,\n });\n }\n for (const { checkpoint } of entries) {\n const data = toCheckpointData(checkpoint);\n await tx.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: checkpoint.runId, seq: checkpoint.seq } },\n create: data,\n update: data,\n });\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.durableStepCheckpoint.deleteMany({\n where: { runId, seq: { gte: fromSeq, lte: toSeq } },\n });\n const data = toCheckpointData(into);\n await tx.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: into.runId, seq: into.seq } },\n create: data,\n update: data,\n });\n });\n }\n\n async listSignalWaitersByRun(runIds: string[]): Promise<SignalWaiter[]> {\n if (runIds.length === 0) return [];\n const rows = await this.db.durableSignalWaiter.findMany({ where: { runId: { in: runIds } } });\n return rows.map((r) => ({\n token: r.token,\n runId: r.runId,\n seq: r.seq,\n parallelGroup: r.parallelGroup ?? undefined,\n }));\n }\n\n async hasSignalWaiter(runId: string, tokenPrefix: string): Promise<boolean> {\n // On SQLite, Prisma's `startsWith` is a bare `LIKE`: `_`/`%` in the prefix act as wildcards and\n // case is ignored. So a hit is confirmed in JS; only a pattern match that is not a real prefix\n // match pays for the full read.\n const where = { runId, token: { startsWith: tokenPrefix } };\n const first = await this.db.durableSignalWaiter.findFirst({ where, select: { token: true } });\n if (!first) return false;\n if (first.token.startsWith(tokenPrefix)) return true;\n const rows = await this.db.durableSignalWaiter.findMany({ where, select: { token: true } });\n return rows.some((r) => r.token.startsWith(tokenPrefix));\n }\n\n async removeSignalWaiter(waiter: SignalWaiter): Promise<void> {\n // Exact-match delete (token AND runId AND seq): `token` is the only unique column, so a plain\n // `delete({ where: { token } })` would remove whatever row currently owns it, even if a different\n // run has since claimed the same token — `deleteMany` with all three fields is a safe no-op then.\n await this.db.durableSignalWaiter.deleteMany({\n where: { token: waiter.token, runId: waiter.runId, seq: waiter.seq },\n });\n }\n\n async bufferSignal(token: string, payload: unknown): Promise<void> {\n await this.db.durableBufferedSignal.create({ data: { token, payload: jsonOrNull(payload) } });\n }\n\n async takeBufferedSignal(token: string): Promise<{ payload: unknown } | null> {\n const row = await this.db.durableBufferedSignal.findFirst({\n where: { token },\n orderBy: { id: 'asc' },\n });\n if (!row) return null;\n await this.db.durableBufferedSignal.delete({ where: { id: row.id } });\n return { payload: row.payload ?? undefined };\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.durableBufferedEvent.create({\n data: {\n id: input.id,\n name: input.name,\n payload: jsonOrNull(input.payload),\n publishedAt: BigInt(input.publishedAt),\n },\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.durableBufferedEvent.findMany({\n where: { name },\n orderBy: { publishedAt: 'asc' }, // oldest first\n take: limit,\n });\n return rows.map((r) => ({\n id: r.id,\n payload: r.payload ?? undefined,\n publishedAt: Number(r.publishedAt),\n }));\n }\n\n async removeBufferedEvent(id: string): Promise<boolean> {\n // deleteMany's `where: { id }` matches at most one row (id is the PK) and is a safe no-op if it's\n // already gone — unlike `delete({ where: { id } })`, which throws P2025 on a missing row (the same\n // reasoning as releaseRunLock's updateMany above).\n const result = await this.db.durableBufferedEvent.deleteMany({ where: { id } });\n return result.count === 1;\n }\n}\n\n/**\n * One attribute predicate as a Prisma relation `some` filter on the side-table — compiles to an\n * EXISTS, so the predicate runs in SQL. `<>` (ne) maps to `{ not }`, which under `some` also excludes\n * runs where the attribute is absent (the missing-key-never-matches contract): `some` already\n * requires a matching row to exist. Numeric operands compare `numValue`, everything else `strValue`.\n */\nfunction attributeSome(f: AttributeFilter): Record<string, unknown> {\n // One comparison for a scalar op, one per member for `in` — ORed inside the single `some`, since\n // `in`'s operands may be of mixed types and so land in different typed columns. No comparisons at\n // all (an `in` over no values) can match no run, which is a run-level fact, not a side-table one.\n const comparisons = attributePredicateOperands(f).map(({ column, comparator, operand }) => ({\n [column]:\n comparator === '=' ? operand : comparator === '<>' ? { not: operand } : { [f.op]: operand },\n }));\n if (comparisons.length === 0) return MATCHES_NOTHING;\n return { attributes: { some: { key: f.key, ...anyOf(comparisons) } } };\n}\n\n/** A where fragment no run satisfies — what a plural predicate over an EMPTY set means. Spelled as an\n * impossible `id` rather than `OR: []` so it does not depend on how a Prisma version reads an empty\n * disjunction. */\nconst MATCHES_NOTHING: Record<string, unknown> = { id: { in: [] as string[] } };\n\n/** OR a set of where fragments, where an EMPTY set matches nothing rather than everything. */\nfunction anyOf(branches: Record<string, unknown>[]): Record<string, unknown> {\n return branches.length ? { OR: branches } : MATCHES_NOTHING;\n}\n\nconst bigOrNull = (n: number | undefined) => (n == null ? null : BigInt(n));\nconst numOrUndef = (n: bigint | null) => (n == null ? undefined : Number(n));\nconst jsonOrNull = (v: unknown) => v ?? null;\n\nfunction toRunData(run: WorkflowRun) {\n return {\n id: run.id,\n workflow: run.workflow,\n workflowVersion: run.workflowVersion,\n status: run.status,\n input: jsonOrNull(run.input),\n output: jsonOrNull(run.output),\n error: jsonOrNull(run.error),\n wakeAt: bigOrNull(run.wakeAt),\n lockedBy: run.lockedBy ?? null,\n lockedUntil: run.lockedUntil == null ? null : new Date(run.lockedUntil),\n awaitingDecisionTaskId: run.awaitingDecisionTaskId ?? null,\n recoveryAttempts: run.recoveryAttempts ?? null,\n tags: jsonOrNull(run.tags),\n searchAttributes: jsonOrNull(run.searchAttributes),\n priority: run.priority ?? null,\n // An absent namespace IS `'default'` — unlike `origin` below, this is a reconstruction and not a\n // guess: an engine started without a namespace stamps its runs and routes its workers as\n // `'default'`, so writing anything else (or NULL) would put the run in a partition no worker polls.\n namespace: run.namespace ?? 'default',\n // Absent origin stays SQL NULL — \"unknown\", never coerced into a real-looking library name.\n origin: run.origin ?? null,\n createdAt: run.createdAt,\n updatedAt: run.updatedAt,\n };\n}\n\nfunction toRunPatch(patch: Partial<WorkflowRun>) {\n // Map EVERY patchable field, using presence (`'x' in patch`) semantics for the nullable ones so a\n // patch can CLEAR a column (e.g. `{ error: undefined }` on completion sets it to NULL — matching\n // the TypeORM / MikroORM / in-memory stores). The two non-null Date fields use a defined-guard\n // since they are never cleared. Previously only 7 fields were mapped, so `updateRun({ tags })` /\n // `{ lockedBy }` / clearing `error` silently no-opped on this adapter.\n const data: Record<string, unknown> = {};\n if ('workflow' in patch) data.workflow = patch.workflow;\n if ('workflowVersion' in patch) data.workflowVersion = patch.workflowVersion;\n if ('status' in patch) data.status = patch.status;\n if ('input' in patch) data.input = jsonOrNull(patch.input);\n if ('output' in patch) data.output = jsonOrNull(patch.output);\n if ('error' in patch) data.error = jsonOrNull(patch.error);\n if ('wakeAt' in patch) data.wakeAt = bigOrNull(patch.wakeAt);\n if ('lockedBy' in patch) data.lockedBy = patch.lockedBy ?? null;\n if ('lockedUntil' in patch)\n data.lockedUntil = patch.lockedUntil == null ? null : new Date(patch.lockedUntil);\n if ('awaitingDecisionTaskId' in patch)\n data.awaitingDecisionTaskId = patch.awaitingDecisionTaskId ?? null;\n if ('recoveryAttempts' in patch) data.recoveryAttempts = patch.recoveryAttempts ?? null;\n if ('tags' in patch) data.tags = jsonOrNull(patch.tags);\n if ('searchAttributes' in patch) data.searchAttributes = jsonOrNull(patch.searchAttributes);\n if ('priority' in patch) data.priority = patch.priority ?? null;\n // `?? 'default'` rather than `?? null` like its neighbours: the column is NOT NULL, and clearing a\n // run's namespace means \"back to the unscoped partition\", which is what `'default'` names. A patch\n // that does not mention `namespace` leaves the stored one alone — a status update must never move a\n // run between tenants.\n if ('namespace' in patch) data.namespace = patch.namespace ?? 'default';\n if ('origin' in patch) data.origin = patch.origin ?? null;\n if (patch.createdAt != null) data.createdAt = patch.createdAt;\n if (patch.updatedAt != null) data.updatedAt = patch.updatedAt;\n return data;\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 WorkflowRun['status'],\n input: row.input ?? undefined,\n output: row.output ?? undefined,\n error: (row.error ?? undefined) as StepError | undefined,\n wakeAt: numOrUndef(row.wakeAt),\n lockedBy: row.lockedBy ?? undefined,\n lockedUntil: row.lockedUntil == null ? undefined : row.lockedUntil.getTime(),\n awaitingDecisionTaskId: row.awaitingDecisionTaskId ?? undefined,\n recoveryAttempts: row.recoveryAttempts ?? undefined,\n tags: (row.tags as string[] | null) ?? undefined,\n searchAttributes:\n (row.searchAttributes as Record<string, string | number | boolean> | null) ?? undefined,\n priority: row.priority ?? undefined,\n // Read back verbatim, with NO `?? 'default'` fallback. The column is NOT NULL and the migration\n // back-fills old rows, so there is nothing legitimate to fall back FROM; a fallback would only fire\n // on a deployment that added the column nullable without back-filling, and there it would lie —\n // the dashboard would show `default` for a row whose stored NULL keeps every `default` worker's\n // `WHERE namespace = 'default'` from ever picking it up.\n namespace: row.namespace,\n // NULL (a row written before the column existed) surfaces as `undefined` = unknown origin.\n origin: row.origin ?? undefined,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\n/** The name prefix each non-`step` {@link CheckpointNameKind} is, as `checkpointNameKind` reads it. */\nconst KIND_PREFIXES: [CheckpointNameKind, string][] = [\n ['child', 'signal:child:'],\n ['folded', 'fan:'],\n ['spawn', 'spawn:'],\n];\n\n/** Each {@link CheckpointNameKind} as the `where` that selects its rows; `step` is \"none of the others\". */\nconst NAME_KINDS: { kind: CheckpointNameKind; where: Record<string, unknown> }[] = [\n ...KIND_PREFIXES.map(([kind, prefix]) => ({ kind, where: { name: { startsWith: prefix } } })),\n {\n kind: 'step',\n where: { NOT: KIND_PREFIXES.map(([, prefix]) => ({ name: { startsWith: prefix } })) },\n },\n];\n\n/** One `groupBy` row of {@link PrismaStateStore.checkpointStats}. */\ntype CheckpointStatRow = {\n parallelGroup: string | null;\n status: string;\n _count: { _all: number; enqueuedAt: number };\n _min: { seq: number; name: string; enqueuedAt: Date | null; startedAt: Date };\n _max: { seq: number; name: string; startedAt: Date; finishedAt: Date };\n _sum: { attempts: number | bigint | null };\n};\n\nfunction bucketKey(group: string | null, status: string): string {\n return JSON.stringify([group, status]);\n}\n\nfunction toCheckpointStat(\n nameKind: CheckpointNameKind,\n r: CheckpointStatRow,\n unenqueued: Map<string, Date>,\n): CheckpointStat {\n const fallback = unenqueued.get(bucketKey(r.parallelGroup, r.status));\n const enqueued = r._min.enqueuedAt;\n const minEnqueuedAt =\n enqueued && fallback ? (enqueued < fallback ? enqueued : fallback) : (enqueued ?? fallback);\n return {\n group: r.parallelGroup,\n status: r.status as StepCheckpoint['status'],\n nameKind,\n count: r._count._all,\n minSeq: r._min.seq,\n maxSeq: r._max.seq,\n minName: r._min.name,\n maxName: r._max.name,\n // Every row has `enqueuedAt` or is in the NULL subset, so one of the two is set.\n minEnqueuedAt: minEnqueuedAt as Date,\n minStartedAt: r._min.startedAt,\n maxStartedAt: r._max.startedAt,\n maxFinishedAt: r._max.finishedAt,\n sumAttempts: Number(r._sum.attempts ?? 0),\n };\n}\n\nfunction toCheckpointData(cp: StepCheckpoint) {\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: jsonOrNull(cp.input),\n output: jsonOrNull(cp.output),\n error: jsonOrNull(cp.error),\n events: jsonOrNull(cp.events),\n attempts: cp.attempts,\n workerGroup: cp.workerGroup ?? null,\n parallelGroup: cp.parallelGroup ?? null,\n wakeAt: bigOrNull(cp.wakeAt),\n enqueuedAt: cp.enqueuedAt,\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: numOrUndef(row.wakeAt),\n enqueuedAt: row.enqueuedAt ?? row.startedAt,\n startedAt: row.startedAt,\n finishedAt: row.finishedAt,\n };\n}\n\nfunction toScheduleData(r: ScheduleRecord) {\n return {\n id: r.id,\n namespace: r.namespace,\n workflow: r.workflow,\n paused: r.paused,\n nextFireAt: r.nextFireAt == null ? null : BigInt(r.nextFireAt),\n tags: jsonOrNull(r.tags),\n spec: r.spec,\n state: r.state,\n createdAt: r.createdAt,\n updatedAt: r.updatedAt,\n };\n}\n\nfunction fromScheduleRow(row: ScheduleRow): ScheduleRecord {\n const tags = Array.isArray(row.tags) ? (row.tags as string[]) : undefined;\n return {\n id: row.id,\n namespace: row.namespace,\n workflow: row.workflow,\n paused: row.paused,\n nextFireAt: row.nextFireAt == null ? null : Number(row.nextFireAt),\n ...(tags?.length ? { tags } : {}),\n spec: (row.spec ?? {}) as Record<string, unknown>,\n state: (row.state ?? {}) as Record<string, unknown>,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n","/**\n * Tables this store's durable models own, physically. UNLIKE the other store adapters, this store\n * doesn't create or manage them at boot: the models in `prisma/schema.prisma` are meant to be copied\n * into YOUR OWN `schema.prisma` (see that file's header comment), and Prisma Migrate diffs whatever\n * models live in your schema — so a consumer who copied the models in already has them accounted for\n * and never needs a denylist for Prisma Migrate itself.\n *\n * This is exported anyway for the same reason the other adapters export it: any OTHER tooling that\n * introspects the database outside of `prisma migrate diff` (a raw schema dump, a second ORM/CLI\n * pointed at the same database, a linter that flags \"table not in any model\") needs the same fixed\n * list of table names this store's models declare via `@@map(...)`.\n *\n * ```ts\n * const skipTables = new Set(durableManagedTables());\n * ```\n *\n * Kept in sync with the `@@map(...)` table names in `prisma/schema.prisma` by `schema.spec.ts`,\n * which parses that file and asserts the two lists match — there is no single TypeScript source to\n * derive from (the schema is a `.prisma` text file copied into the consumer's own schema, not\n * imported at runtime), so the list here is intentionally a literal mirror.\n */\nexport function durableManagedTables(): string[] {\n return [\n 'durable_workflow_runs',\n 'durable_step_checkpoints',\n 'durable_run_attributes',\n 'durable_signal_waiters',\n 'durable_buffered_signals',\n 'durable_buffered_events',\n 'durable_schedules',\n ];\n}\n"],"mappings":"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","names":["RUN_VALUE_FACET_SCAN","SINGLETON_ACTIVE_STATUSES","TERMINAL_RUN_STATUSES","attributePredicateOperands","axisIsRunColumn","clearTerminalSingletonAdmission","mergeRunFacetRows","mergeRunValueFacetRows","normalizeAttributeRows","parseDuration","runValueFacetsFromRuns","singletonAdmissionDenialPatch","singletonAdmissionTags","namespaceWhere","namespace","undefined","PrismaStateStore","db","tryAdmitSingleton","runId","tag","workflow","limit","retryWakeAt","$transaction","tx","where","status","in","SINGLETON_ACTIVE_STATUSES","durableWorkflowRun","updateMany","data","rows","findMany","runs","map","fromRunRow","tags","singletonAdmissionTags","patch","singletonAdmissionDenialPatch","update","id","toRunPatch","createRun","run","create","toRunData","reindexAttributes","searchAttributes","updateRun","inputPatch","TERMINAL_RUN_STATUSES","includes","clearTerminalSingletonAdmission","getRun","attributes","durableRunAttribute","deleteMany","normalizeAttributeRows","length","createMany","row","findUnique","deleteRun","durableStepCheckpoint","durableSignalWaiter","deleteRuns","runIds","pruneTerminalRuns","policy","nowMs","statuses","filter","s","maxAge","maxCount","scoped","runWhere","scope","ids","Set","cutoff","Date","parseDuration","AND","updatedAt","lt","select","orderBy","take","r","add","size","skip","doomed","slice","getCheckpoint","seq","runId_seq","fromCheckpointRow","saveCheckpoint","checkpoint","toCheckpointData","upsert","saveCheckpointIfPending","count","saveCheckpointsIfPending","checkpoints","wrote","push","transaction","work","raw","cp","listIncompleteRuns","listPendingRuns","createdAt","listDueTimers","wakeAt","not","lte","BigInt","tryLockRun","owner","leaseUntilMs","result","OR","lockedUntil","lockedBy","releaseRunLock","renewRunLock","query","and","workflows","anyOf","w","namespaces","n","origin","origins","o","array_contains","t","f","attributeSome","listRuns","offset","countRuns","runFacets","groupBy","by","_count","_all","mergeRunFacetRows","runValueFacets","axis","opts","axisIsRunColumn","scan","RUN_VALUE_FACET_SCAN","runValueFacetsFromRuns","field","mergeRunValueFacetRows","value","schedules","delegate","durableSchedule","Error","saveSchedule","record","toScheduleData","getSchedule","fromScheduleRow","updateSchedule","expectedNextFireAt","paused","nextFireAt","jsonOrNull","spec","state","Object","keys","deleteSchedule","listSchedules","dueBy","sort","nulls","listCheckpoints","getLatestCheckpointByName","name","findFirst","countCheckpoints","fromSeq","toSeq","gte","listCheckpointsByNamePrefix","prefixes","p","startsWith","some","checkpointStats","group","parallelGroup","grouped","Promise","all","NAME_KINDS","kind","enqueuedAt","_min","startedAt","_max","finishedAt","_sum","attempts","stats","unenqueued","unenqueuedStartedAt","Map","toCheckpointStat","flat","bucketKey","queryCheckpoints","namePrefixes","excludeGroups","notIn","putSignalWaiter","waiter","token","takeSignalWaiter","delete","listSignalWaiters","prefix","registerChildWaits","entries","compactCheckpoints","into","listSignalWaitersByRun","hasSignalWaiter","tokenPrefix","first","removeSignalWaiter","bufferSignal","payload","durableBufferedSignal","takeBufferedSignal","bufferEvent","input","durableBufferedEvent","publishedAt","listBufferedEvents","Number","removeBufferedEvent","comparisons","attributePredicateOperands","column","comparator","operand","op","MATCHES_NOTHING","key","branches","bigOrNull","numOrUndef","v","workflowVersion","output","error","awaitingDecisionTaskId","recoveryAttempts","priority","getTime","KIND_PREFIXES","NOT","JSON","stringify","nameKind","fallback","get","enqueued","minEnqueuedAt","minSeq","maxSeq","minName","maxName","minStartedAt","maxStartedAt","maxFinishedAt","sumAttempts","stepId","events","workerGroup","Array","isArray","durableManagedTables"]}
|
|
1
|
+
{"version":3,"sources":["../src/prisma-state-store.ts","../src/schema.ts"],"sourcesContent":["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 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';\n\n/* The Prisma client is generated per-schema, so the adapter can't import a concrete one. Instead\n it depends on this structural surface — the three model delegates and the methods it uses. A\n real `PrismaClient` (with the models from prisma/schema.prisma added) satisfies it. Query-arg\n shapes are Prisma's own generics, so they're left as `any` at this single boundary; the row\n return types are precise, which is what the mapping code below relies on. */\n\ninterface RunRow {\n id: string;\n workflow: string;\n workflowVersion: string;\n status: string;\n input: unknown;\n output: unknown;\n error: unknown;\n wakeAt: bigint | null;\n lockedBy: string | null;\n lockedUntil: Date | null;\n awaitingDecisionTaskId: string | null;\n recoveryAttempts: number | null;\n tags: unknown;\n searchAttributes: unknown;\n priority: number | null;\n /** NOT NULL in the schema (defaulted to `'default'`), so every row carries a real namespace. */\n namespace: string;\n origin: string | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface CheckpointRow {\n runId: string;\n seq: number;\n name: string;\n kind: string;\n stepId: string;\n status: string;\n input: unknown;\n output: unknown;\n error: unknown;\n events: unknown;\n attempts: number;\n workerGroup: string | null;\n parallelGroup: string | null;\n wakeAt: bigint | null;\n enqueuedAt: Date | null;\n startedAt: Date;\n finishedAt: Date;\n}\n\ninterface WaiterRow {\n token: string;\n runId: string;\n seq: number;\n parallelGroup: string | null;\n}\n\ninterface RunAttributeRow {\n runId: string;\n key: string;\n strValue: string | null;\n numValue: number | null;\n}\n\ninterface BufferedSignalRow {\n id: bigint;\n token: string;\n payload: unknown;\n}\n\ninterface BufferedEventRow {\n id: string;\n name: string;\n payload: unknown;\n publishedAt: bigint;\n}\n\n// Prisma's per-model query args are generated generics; left as `any` at this single boundary.\ntype Args = any;\n\ninterface Delegate<Row> {\n create(args: Args): Promise<Row>;\n createMany(args: Args): Promise<{ count: number }>;\n findUnique(args: Args): Promise<Row | null>;\n findFirst(args?: Args): Promise<Row | null>;\n findMany(args?: Args): Promise<Row[]>;\n update(args: Args): Promise<Row>;\n updateMany(args: Args): Promise<{ count: number }>;\n upsert(args: Args): Promise<Row>;\n delete(args: Args): Promise<Row>;\n deleteMany(args?: Args): Promise<{ count: number }>;\n count(args?: Args): Promise<number>;\n /** Aggregate form — used by the run facets and `checkpointStats`, whose rows are aggregate cells,\n * not model rows, so the result type is stated at the call site rather than derived from `Row`. */\n groupBy(args: Args): Promise<Record<string, unknown>[]>;\n}\n\ninterface ScheduleRow {\n id: string;\n namespace: string;\n workflow: string;\n paused: boolean;\n nextFireAt: bigint | null;\n tags: unknown;\n spec: unknown;\n state: unknown;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface DurablePrismaTx {\n durableWorkflowRun: Delegate<RunRow>;\n durableStepCheckpoint: Delegate<CheckpointRow>;\n durableRunAttribute: Delegate<RunAttributeRow>;\n durableSignalWaiter: Delegate<WaiterRow>;\n durableBufferedSignal: Delegate<BufferedSignalRow>;\n durableBufferedEvent: Delegate<BufferedEventRow>;\n /** Only needed for persisted schedules (`engine.schedules`) — add the `DurableSchedule` model. */\n durableSchedule?: Delegate<ScheduleRow>;\n}\n\nexport interface DurablePrismaClient extends DurablePrismaTx {\n /** Prisma's interactive-transaction form: runs `fn` with a tx-scoped client and commits on resolve. */\n $transaction<T>(fn: (tx: DurablePrismaTx) => Promise<T>): Promise<T>;\n}\n\n/**\n * The `namespace` read boundary as a spreadable Prisma `where` fragment.\n *\n * `undefined` means NO RESTRICTION — `{}` — because that is the operator (control-plane) view that\n * sees every tenant, and it is what the engine passes when it runs unscoped. It does NOT mean\n * \"namespace IS NULL\": the column is NOT NULL, so `{ namespace: undefined }` would be Prisma's\n * \"ignore this predicate\" anyway, but `{ namespace: null }` would match nothing in production while\n * still looking correct in a single-tenant test where every worker polls unscoped.\n *\n * A named namespace is plain equality, so a worker sees only its own tenant's rows — the boundary\n * {@link WorkflowRun.namespace} promises for the four worker paths (pick up, recover, resume timers,\n * time out).\n */\nfunction namespaceWhere(namespace?: string): { namespace?: string } {\n if (namespace === undefined) return {};\n return { namespace };\n}\n\n/**\n * Prisma-backed `StateStore`. Pass your `PrismaClient` after adding the models from\n * `prisma/schema.prisma` to your schema. JSON columns carry the run/step payloads directly;\n * `wakeAt` is a `BigInt` (epoch ms).\n *\n * Every path a worker acts on is namespace-scoped when it is given one — `listPendingRuns` (pick up),\n * `listIncompleteRuns` (recover), `listDueTimers` (resume timers) and `listRuns`'s `namespace`\n * (the engine's timeout sweep). Omit it for the operator view across all tenants. Point-reads\n * (`getRun`, checkpoints) are deliberately NOT scoped, per {@link StateStore}.\n */\nexport class PrismaStateStore implements StateStore {\n constructor(private readonly db: DurablePrismaClient) {}\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 = { workflow, status: { in: SINGLETON_ACTIVE_STATUSES } };\n // A locking write first: concurrent claims cannot read the same free slot.\n await tx.durableWorkflowRun.updateMany({ where, data: { workflow } });\n const rows = await tx.durableWorkflowRun.findMany({ 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.durableWorkflowRun.update({ where: { id: runId }, data: toRunPatch(patch) });\n return false;\n }\n await tx.durableWorkflowRun.update({ where: { id: runId }, data: { tags } });\n return true;\n });\n }\n\n async createRun(run: WorkflowRun): Promise<void> {\n await this.db.durableWorkflowRun.create({ data: toRunData(run) });\n await this.reindexAttributes(run.id, run.searchAttributes);\n }\n\n async updateRun(runId: string, inputPatch: Partial<WorkflowRun>): Promise<void> {\n const patch =\n inputPatch.status && TERMINAL_RUN_STATUSES.includes(inputPatch.status)\n ? await clearTerminalSingletonAdmission(runId, inputPatch, (id) => this.getRun(id))\n : inputPatch;\n await this.db.durableWorkflowRun.update({ where: { id: runId }, data: toRunPatch(patch) });\n // Keep the side-table in step with the run's attributes whenever they're patched.\n if ('searchAttributes' in patch) await this.reindexAttributes(runId, patch.searchAttributes);\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 const patch =\n inputPatch.status && TERMINAL_RUN_STATUSES.includes(inputPatch.status)\n ? await clearTerminalSingletonAdmission(runId, inputPatch, (id) => this.getRun(id))\n : inputPatch;\n // One conditional `updateMany` (`UPDATE … WHERE id = ? AND status IN (…)`): the status\n // predicate is the compare, the row count the answer, and a missing row matches nothing.\n const where = { id: runId, status: { in: expectedStatuses } };\n const data = toRunPatch(patch);\n // Nothing to write but (maybe) the attribute side-table: the compare is a read (an `updateMany`\n // with no data would report zero rows even on a match).\n const count = Object.keys(data).length\n ? (await this.db.durableWorkflowRun.updateMany({ where, data })).count\n : await this.db.durableWorkflowRun.count({ where });\n if (count === 0) return false;\n if ('searchAttributes' in patch) await this.reindexAttributes(runId, patch.searchAttributes);\n return true;\n }\n\n /** Rewrite a run's normalized attribute rows: delete the old set, insert the current one. Mirrors\n * the in-memory store's reindex so the side-table always reflects the run's live searchAttributes. */\n private async reindexAttributes(\n runId: string,\n attributes: WorkflowRun['searchAttributes'],\n ): Promise<void> {\n await this.db.durableRunAttribute.deleteMany({ where: { runId } });\n const rows = normalizeAttributeRows(runId, attributes);\n if (rows.length) await this.db.durableRunAttribute.createMany({ data: rows });\n }\n\n async getRun(runId: string): Promise<WorkflowRun | null> {\n const row = await this.db.durableWorkflowRun.findUnique({ where: { id: runId } });\n return row ? fromRunRow(row) : null;\n }\n\n async deleteRun(runId: string): Promise<void> {\n // Child rows first, then the run — checkpoints, signal waiters, attribute rows.\n await this.db.durableStepCheckpoint.deleteMany({ where: { runId } });\n await this.db.durableSignalWaiter.deleteMany({ where: { runId } });\n await this.db.durableRunAttribute.deleteMany({ where: { runId } });\n await this.db.durableWorkflowRun.deleteMany({ where: { id: runId } });\n }\n\n async deleteRuns(runIds: string[]): Promise<void> {\n if (runIds.length === 0) return;\n // Same cascade as deleteRun, one `IN (...)` per table, atomically.\n await this.db.$transaction(async (tx) => {\n await tx.durableStepCheckpoint.deleteMany({ where: { runId: { in: runIds } } });\n await tx.durableSignalWaiter.deleteMany({ where: { runId: { in: runIds } } });\n await tx.durableRunAttribute.deleteMany({ where: { runId: { in: runIds } } });\n await tx.durableWorkflowRun.deleteMany({ where: { id: { in: 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.runWhere({ ...(policy.scope ?? {}), statuses });\n const ids = new Set<string>();\n if (policy.maxAge != null) {\n const cutoff = new Date(nowMs - parseDuration(policy.maxAge));\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { AND: [scoped, { updatedAt: { lt: cutoff } }] },\n select: { id: true },\n orderBy: { updatedAt: 'asc' }, // oldest first\n take: limit,\n });\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 scoped status set (skipped by OFFSET).\n const rows = await this.db.durableWorkflowRun.findMany({\n where: scoped,\n select: { id: true },\n orderBy: [{ updatedAt: 'desc' }, { id: 'desc' }],\n skip: policy.maxCount,\n take: limit,\n });\n for (const r of rows) {\n if (ids.size >= limit) break;\n ids.add(r.id);\n }\n }\n const doomed = [...ids].slice(0, limit);\n await this.deleteRuns(doomed);\n return doomed.length;\n }\n\n async getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null> {\n const row = await this.db.durableStepCheckpoint.findUnique({\n where: { runId_seq: { runId, seq } },\n });\n return row ? fromCheckpointRow(row) : null;\n }\n\n async saveCheckpoint(checkpoint: StepCheckpoint): Promise<void> {\n const data = toCheckpointData(checkpoint);\n await this.db.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: checkpoint.runId, seq: checkpoint.seq } },\n create: data,\n update: data,\n });\n }\n\n async saveCheckpointIfPending(checkpoint: StepCheckpoint): Promise<boolean> {\n // One conditional `updateMany` (`UPDATE … WHERE run_id = ? AND seq = ? AND status = 'pending'`):\n // the status predicate is the compare, the row count the answer, and a missing row is never made.\n const { runId, seq, ...data } = toCheckpointData(checkpoint);\n const { count } = await this.db.durableStepCheckpoint.updateMany({\n where: { runId, seq, status: 'pending' },\n data,\n });\n return count > 0;\n }\n\n async saveCheckpointsIfPending(checkpoints: StepCheckpoint[]): Promise<boolean[]> {\n if (checkpoints.length === 0) return [];\n // The conditional `updateMany` of `saveCheckpointIfPending`, once per entry, in order, in one\n // transaction: one commit for the batch, and a rejection writes nothing.\n return this.db.$transaction(async (tx) => {\n const wrote: boolean[] = [];\n for (const checkpoint of checkpoints) {\n const { runId, seq, ...data } = toCheckpointData(checkpoint);\n const { count } = await tx.durableStepCheckpoint.updateMany({\n where: { runId, seq, status: 'pending' },\n data,\n });\n wrote.push(count > 0);\n }\n return wrote;\n });\n }\n\n async transaction<T>(\n work: (tx: {\n raw: unknown;\n saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;\n }) => Promise<T>,\n ): Promise<T> {\n return this.db.$transaction(async (tx) =>\n work({\n raw: tx,\n saveCheckpoint: async (cp) => {\n const data = toCheckpointData(cp);\n await tx.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: cp.runId, seq: cp.seq } },\n create: data,\n update: data,\n });\n },\n }),\n );\n }\n\n async listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: { in: ['running', 'cancelling'] }, ...namespaceWhere(namespace) },\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.durableWorkflowRun.findMany({\n where: {\n status: { in: ['running', 'cancelling'] },\n OR: [{ lockedUntil: null }, { lockedUntil: { lte: new Date(nowMs) } }],\n ...namespaceWhere(namespace),\n },\n orderBy: { createdAt: 'asc' },\n take: limit,\n });\n return rows.map(fromRunRow);\n }\n\n async listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: 'pending', ...namespaceWhere(namespace) },\n orderBy: { createdAt: 'asc' }, // FIFO dispatch\n take: limit,\n });\n return rows.map(fromRunRow);\n }\n\n async listDueTimers(nowMs: number, namespace?: string, limit?: number): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: {\n status: 'suspended',\n wakeAt: { not: null, lte: BigInt(nowMs) },\n ...namespaceWhere(namespace),\n },\n orderBy: { wakeAt: 'asc' },\n ...(limit !== undefined ? { take: limit } : {}),\n });\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 const result = await this.db.durableWorkflowRun.updateMany({\n where: {\n id: runId,\n OR: [{ lockedUntil: null }, { lockedUntil: { lte: new Date(nowMs) } }],\n },\n data: { lockedBy: owner, lockedUntil: new Date(leaseUntilMs) },\n });\n return result.count === 1;\n }\n\n async releaseRunLock(runId: string): Promise<void> {\n // Idempotent by design: releasing the lease on a run that no longer exists is a no-op, not an\n // error. The engine calls this best-effort in a `finally` AFTER the run has settled, so it can\n // race a concurrent purge/teardown — Prisma's `update({ where: { id } })` would throw P2025\n // (\"No record was found for an update\") on that race and, since the call is fire-and-forget on\n // the engine's terminal path, surface as an unhandled rejection. `updateMany` matches a 0-row\n // WHERE to an empty result (no throw), mirroring the in-memory store's `if (run)` guard and the\n // set-where semantics of every sibling adapter (TypeORM/MikroORM/Drizzle).\n await this.db.durableWorkflowRun.updateMany({\n where: { id: runId },\n data: { lockedBy: null, lockedUntil: null },\n });\n }\n\n async renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean> {\n const result = await this.db.durableWorkflowRun.updateMany({\n where: { id: runId, lockedBy: owner },\n data: { lockedUntil: new Date(leaseUntilMs) },\n });\n return result.count === 1;\n }\n\n /** The `where` every run query shares — {@link listRuns} pages it, {@link runFacets} groups it. */\n private runWhere(query: RunQuery): Record<string, unknown> {\n // The tenant boundary, and NOT only a dashboard facet: the engine's `sweepTimeouts` finds the runs\n // it may cancel through `listRuns({ workflow, status, namespace })`, so an unfiltered `namespace`\n // here lets a worker serving one tenant time out another tenant's runs — a write, not a stale\n // read. Same `undefined` = no restriction rule as the poll paths above (see `namespaceWhere`),\n // which is what keeps the operator's dashboard showing every tenant by default.\n const where: Record<string, unknown> = { ...namespaceWhere(query.namespace) };\n // The plural predicates below can't sit on `where` directly (a key holds one condition, and the\n // single form may already own it), so they accumulate here and are ANDed at the end. Each is ORed\n // within itself and matches NOTHING when empty — the contract `statuses` already had.\n const and: Record<string, unknown>[] = [];\n if (query.workflow) where.workflow = query.workflow;\n if (query.workflows) and.push(anyOf(query.workflows.map((w) => ({ workflow: w }))));\n if (query.namespaces) and.push(anyOf(query.namespaces.map((n) => ({ namespace: n }))));\n // Which library registered the workflow. Plain equality, so a run whose origin is NULL (created\n // before the column existed, or registered through a path the derivation could not classify)\n // matches NO origin value — it is never folded into a bucket to make the facet look complete.\n // Unknown-origin runs are reachable only with the filter OFF, so \"all origins\" must stay the\n // default view; a dashboard that filtered by default would make those runs look deleted.\n // Passing `null` asks for exactly the unattributed bucket (`origin IS NULL`) — Prisma spells that\n // as the same equality — which is how a paginated console can offer an \"unknown\" chip.\n if (query.origin !== undefined) where.origin = query.origin;\n // `null` is a member like any other in a set of origins — Prisma spells `origin IS NULL` as the\n // same equality — so one branch per value covers both the named ones and the unattributed bucket.\n if (query.origins) and.push(anyOf(query.origins.map((o) => ({ origin: o }))));\n // `status IN (...)`; an empty set matches nothing (mirrors the in-memory store). Combined with the\n // single-value `status` via AND when both are present, so the narrower set wins.\n if (query.status && query.statuses) {\n and.push({ status: query.status }, { status: { in: query.statuses } });\n } else if (query.status) {\n where.status = query.status;\n } else if (query.statuses) {\n where.status = { in: query.statuses };\n }\n if (query.tag) where.tags = { array_contains: query.tag };\n if (query.tags) and.push(anyOf(query.tags.map((t) => ({ tags: { array_contains: t } }))));\n // Typed/range attribute predicates push DOWN into SQL: each filter becomes a relation `some`\n // (EXISTS) on the normalized `durable_run_attributes` side-table, so the DB filters AND paginates\n // — no full scan + in-process filter. ANDed: a run must match every filter, so one `some` each.\n if (query.attributes?.length) and.push(...query.attributes.map((f) => attributeSome(f)));\n if (and.length) where.AND = and;\n return where;\n }\n\n async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n const orderBy = { createdAt: 'desc' as const }; // newest first — recent runs on top in the dashboard\n const rows = await this.db.durableWorkflowRun.findMany({\n where: this.runWhere(query),\n take: query.limit,\n skip: query.offset,\n orderBy,\n });\n return rows.map(fromRunRow);\n }\n\n async countRuns(query: Omit<RunQuery, 'limit' | 'offset'>): Promise<number> {\n return this.db.durableWorkflowRun.count({ where: this.runWhere(query) });\n }\n\n /** `GROUP BY status, origin` over the same predicates {@link listRuns} pages — one aggregate, so a\n * console can show whole-set counts next to a bounded page instead of downloading every run to\n * count them in the browser. */\n async runFacets(query: RunFacetQuery): Promise<RunFacetRow[]> {\n const rows = (await this.db.durableWorkflowRun.groupBy({\n by: ['status', 'origin'],\n where: this.runWhere(query),\n _count: { _all: true },\n })) as { status: RunStatus; origin: string | null; _count: { _all: number } }[];\n return mergeRunFacetRows(\n rows.map((r) => ({ status: r.status, origin: r.origin, count: r._count._all })),\n );\n }\n\n /** Distinct values of one filter axis over the same predicates {@link listRuns} pages. A run-table\n * column is a `groupBy` like {@link runFacets}, exact over the whole matching set; the tag and\n * attribute axes live outside the row (json column / side table) and are counted from a bounded\n * page of runs instead — see `RunValueFacetOptions.scan`. */\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 rows = (await this.db.durableWorkflowRun.groupBy({\n by: [axis.field],\n where: this.runWhere(query),\n _count: { _all: true },\n })) as (Record<string, string | null> & { _count: { _all: number } })[];\n return mergeRunValueFacetRows(\n rows.map((r) => ({ value: r[axis.field] ?? null, count: r._count._all })),\n opts,\n );\n }\n\n // ---- persisted schedules ----------------------------------------------------------------------\n\n private schedules(): Delegate<ScheduleRow> {\n const delegate = this.db.durableSchedule;\n if (!delegate) {\n throw new Error(\n 'persisted schedules need the DurableSchedule model — copy it from prisma/schema.prisma into your schema and re-run `prisma generate`',\n );\n }\n return delegate;\n }\n\n async saveSchedule(record: ScheduleRecord): Promise<void> {\n const data = toScheduleData(record);\n await this.schedules().upsert({ where: { id: record.id }, create: data, update: data });\n }\n\n async getSchedule(id: string): Promise<ScheduleRecord | null> {\n const row = await this.schedules().findUnique({ where: { id } });\n return row ? fromScheduleRow(row) : null;\n }\n\n /** One conditional `updateMany`: the compare-and-set on `next_fire_at` is a single statement. */\n async updateSchedule(\n id: string,\n patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>,\n expectedNextFireAt?: number | null,\n ): Promise<boolean> {\n const data: Record<string, unknown> = {};\n if (patch.namespace !== undefined) data.namespace = patch.namespace;\n if (patch.workflow !== undefined) data.workflow = patch.workflow;\n if (patch.paused !== undefined) data.paused = patch.paused;\n if ('nextFireAt' in patch)\n data.nextFireAt = patch.nextFireAt == null ? null : BigInt(patch.nextFireAt);\n if ('tags' in patch) data.tags = jsonOrNull(patch.tags);\n if (patch.spec !== undefined) data.spec = patch.spec;\n if (patch.state !== undefined) data.state = patch.state;\n if (patch.updatedAt !== undefined) data.updatedAt = patch.updatedAt;\n if (!Object.keys(data).length) return (await this.getSchedule(id)) !== null;\n const where: Record<string, unknown> = { id };\n if (expectedNextFireAt !== undefined)\n where.nextFireAt = expectedNextFireAt === null ? null : BigInt(expectedNextFireAt);\n const { count } = await this.schedules().updateMany({ where, data });\n return count > 0;\n }\n\n async deleteSchedule(id: string): Promise<boolean> {\n const { count } = await this.schedules().deleteMany({ where: { id } });\n return count > 0;\n }\n\n async listSchedules(query: ScheduleQuery): Promise<ScheduleRecord[]> {\n const where: Record<string, unknown> = {};\n if (query.namespace !== undefined) where.namespace = query.namespace;\n if (query.workflow !== undefined) where.workflow = query.workflow;\n if (query.paused !== undefined) where.paused = query.paused;\n if (query.tag !== undefined) where.tags = { array_contains: query.tag };\n if (query.dueBy !== undefined) {\n where.AND = [{ paused: false }, { nextFireAt: { lte: BigInt(query.dueBy) } }];\n }\n const rows = await this.schedules().findMany({\n where,\n // Soonest-due first, never-firing (NULL) last, id as the stable tie-break.\n orderBy: [{ nextFireAt: { sort: 'asc', nulls: 'last' } }, { id: 'asc' }],\n take: query.limit,\n skip: query.offset,\n });\n return rows.map(fromScheduleRow);\n }\n\n async listCheckpoints(runId: string): Promise<StepCheckpoint[]> {\n const rows = await this.db.durableStepCheckpoint.findMany({\n where: { runId },\n orderBy: { seq: 'asc' },\n });\n return rows.map(fromCheckpointRow);\n }\n\n async getLatestCheckpointByName(\n runId: string,\n name: string,\n ): Promise<StepCheckpoint | undefined> {\n const row = await this.db.durableStepCheckpoint.findFirst({\n where: { runId, name },\n orderBy: { seq: 'desc' },\n });\n return row ? fromCheckpointRow(row) : 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 return this.db.durableStepCheckpoint.count({\n where: { runId, seq: { gte: fromSeq, lte: toSeq }, status: { in: statuses } },\n });\n }\n\n async listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]> {\n if (prefixes.length === 0) return [];\n const rows = await this.db.durableStepCheckpoint.findMany({\n where: { runId, OR: prefixes.map((p) => ({ name: { startsWith: p } })) },\n orderBy: { seq: 'asc' },\n });\n // On some providers (SQLite) `startsWith` compiles to a `LIKE` that reads `_` and `%` as wildcards,\n // so it can match more than the prefix: keep only the exact matches.\n return rows.filter((r) => prefixes.some((p) => r.name.startsWith(p))).map(fromCheckpointRow);\n }\n\n /**\n * One `groupBy(parallelGroup, status)` per {@link CheckpointNameKind}, each narrowed to its kind by\n * a name-prefix predicate, run concurrently — Prisma cannot group by a `CASE`, so the kind is the\n * `where` instead. `minEnqueuedAt` reads a NULL `enqueuedAt` as `startedAt` (as\n * {@link fromCheckpointRow} does): a bucket whose non-null `enqueuedAt` count falls short of its\n * row count has such rows, and only for those kinds is the NULL subset's `min(startedAt)` asked for.\n *\n * On SQLite `startsWith` is a case-insensitive `LIKE`, as in {@link listCheckpointsByNamePrefix};\n * the kind prefixes are lower-case and wildcard-free, so only a step whose name starts with one of\n * them in another case would be classified differently there.\n */\n async checkpointStats(\n runId: string,\n opts?: { group?: string | undefined },\n ): Promise<CheckpointStat[]> {\n const scope = opts?.group === undefined ? { runId } : { runId, parallelGroup: opts.group };\n const grouped = await Promise.all(\n NAME_KINDS.map(async ({ kind, where }) => ({\n kind,\n where,\n rows: (await this.db.durableStepCheckpoint.groupBy({\n by: ['parallelGroup', 'status'],\n where: { ...scope, ...where },\n _count: { _all: true, enqueuedAt: true },\n _min: { seq: true, name: true, enqueuedAt: true, startedAt: true },\n _max: { seq: true, name: true, startedAt: true, finishedAt: true },\n _sum: { attempts: true },\n })) as CheckpointStatRow[],\n })),\n );\n const stats = await Promise.all(\n grouped.map(async ({ kind, where, rows }) => {\n const unenqueued = rows.some((r) => r._count.enqueuedAt < r._count._all)\n ? await this.unenqueuedStartedAt({ ...scope, ...where })\n : new Map<string, Date>();\n return rows.map((r) => toCheckpointStat(kind, r, unenqueued));\n }),\n );\n return stats.flat();\n }\n\n /** `min(startedAt)` per `(parallelGroup, status)` over the rows whose `enqueuedAt` is NULL. */\n private async unenqueuedStartedAt(where: Record<string, unknown>): Promise<Map<string, Date>> {\n const rows = (await this.db.durableStepCheckpoint.groupBy({\n by: ['parallelGroup', 'status'],\n where: { ...where, enqueuedAt: null },\n _min: { startedAt: true },\n })) as { parallelGroup: string | null; status: string; _min: { startedAt: Date } }[];\n return new Map(rows.map((r) => [bucketKey(r.parallelGroup, r.status), r._min.startedAt]));\n }\n\n /** {@link CheckpointQuery} as one `findMany`, in `seq` order, paged by `skip`/`take`. Ungrouped rows\n * are kept past `excludeGroups` explicitly: `NOT IN` alone drops a NULL `parallelGroup`. */\n async queryCheckpoints(runId: string, query: CheckpointQuery): Promise<StepCheckpoint[]> {\n if (query.statuses?.length === 0 || query.namePrefixes?.length === 0) return [];\n const and: Record<string, unknown>[] = [];\n if (query.excludeGroups?.length) {\n and.push({\n OR: [{ parallelGroup: null }, { parallelGroup: { notIn: query.excludeGroups } }],\n });\n }\n if (query.namePrefixes) {\n and.push({ OR: query.namePrefixes.map((p) => ({ name: { startsWith: p } })) });\n }\n const rows = await this.db.durableStepCheckpoint.findMany({\n where: {\n runId,\n ...(query.group === undefined ? {} : { parallelGroup: query.group }),\n ...(query.statuses ? { status: { in: query.statuses } } : {}),\n ...(and.length ? { AND: and } : {}),\n },\n orderBy: { seq: 'asc' },\n skip: query.offset,\n take: query.limit,\n });\n return rows.map(fromCheckpointRow);\n }\n\n async putSignalWaiter(waiter: SignalWaiter): Promise<void> {\n await this.db.durableSignalWaiter.upsert({\n where: { token: waiter.token },\n create: {\n token: waiter.token,\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n },\n update: {\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n },\n });\n }\n\n async takeSignalWaiter(token: string): Promise<SignalWaiter | null> {\n const row = await this.db.durableSignalWaiter.findUnique({ where: { token } });\n if (!row) return null;\n await this.db.durableSignalWaiter.delete({ where: { token } });\n return {\n token: row.token,\n runId: row.runId,\n seq: row.seq,\n parallelGroup: row.parallelGroup ?? undefined,\n };\n }\n\n async listSignalWaiters(prefix: string): Promise<SignalWaiter[]> {\n const rows = await this.db.durableSignalWaiter.findMany({\n where: { token: { startsWith: prefix } },\n });\n // On some providers (SQLite) `startsWith` compiles to a `LIKE` that reads `_` and `%` as wildcards,\n // so it can match more than the prefix: keep only the exact matches.\n return rows\n .filter((r) => r.token.startsWith(prefix))\n .map((r) => ({\n token: r.token,\n runId: r.runId,\n seq: r.seq,\n parallelGroup: r.parallelGroup ?? undefined,\n }));\n }\n\n async registerChildWaits(entries: ChildWait[]): Promise<void> {\n if (entries.length === 0) return;\n // Prisma has no multi-row upsert: one upsert per row, inside a single transaction.\n await this.db.$transaction(async (tx) => {\n for (const { waiter } of entries) {\n const data = {\n runId: waiter.runId,\n seq: waiter.seq,\n parallelGroup: waiter.parallelGroup ?? null,\n };\n await tx.durableSignalWaiter.upsert({\n where: { token: waiter.token },\n create: { token: waiter.token, ...data },\n update: data,\n });\n }\n for (const { checkpoint } of entries) {\n const data = toCheckpointData(checkpoint);\n await tx.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: checkpoint.runId, seq: checkpoint.seq } },\n create: data,\n update: data,\n });\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.durableStepCheckpoint.deleteMany({\n where: { runId, seq: { gte: fromSeq, lte: toSeq } },\n });\n const data = toCheckpointData(into);\n await tx.durableStepCheckpoint.upsert({\n where: { runId_seq: { runId: into.runId, seq: into.seq } },\n create: data,\n update: data,\n });\n });\n }\n\n async listSignalWaitersByRun(runIds: string[]): Promise<SignalWaiter[]> {\n if (runIds.length === 0) return [];\n const rows = await this.db.durableSignalWaiter.findMany({ where: { runId: { in: runIds } } });\n return rows.map((r) => ({\n token: r.token,\n runId: r.runId,\n seq: r.seq,\n parallelGroup: r.parallelGroup ?? undefined,\n }));\n }\n\n async hasSignalWaiter(runId: string, tokenPrefix: string): Promise<boolean> {\n // On SQLite, Prisma's `startsWith` is a bare `LIKE`: `_`/`%` in the prefix act as wildcards and\n // case is ignored. So a hit is confirmed in JS; only a pattern match that is not a real prefix\n // match pays for the full read.\n const where = { runId, token: { startsWith: tokenPrefix } };\n const first = await this.db.durableSignalWaiter.findFirst({ where, select: { token: true } });\n if (!first) return false;\n if (first.token.startsWith(tokenPrefix)) return true;\n const rows = await this.db.durableSignalWaiter.findMany({ where, select: { token: true } });\n return rows.some((r) => r.token.startsWith(tokenPrefix));\n }\n\n async removeSignalWaiter(waiter: SignalWaiter): Promise<void> {\n // Exact-match delete (token AND runId AND seq): `token` is the only unique column, so a plain\n // `delete({ where: { token } })` would remove whatever row currently owns it, even if a different\n // run has since claimed the same token — `deleteMany` with all three fields is a safe no-op then.\n await this.db.durableSignalWaiter.deleteMany({\n where: { token: waiter.token, runId: waiter.runId, seq: waiter.seq },\n });\n }\n\n async bufferSignal(token: string, payload: unknown): Promise<void> {\n await this.db.durableBufferedSignal.create({ data: { token, payload: jsonOrNull(payload) } });\n }\n\n async takeBufferedSignal(token: string): Promise<{ payload: unknown } | null> {\n const row = await this.db.durableBufferedSignal.findFirst({\n where: { token },\n orderBy: { id: 'asc' },\n });\n if (!row) return null;\n await this.db.durableBufferedSignal.delete({ where: { id: row.id } });\n return { payload: row.payload ?? undefined };\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.durableBufferedEvent.create({\n data: {\n id: input.id,\n name: input.name,\n payload: jsonOrNull(input.payload),\n publishedAt: BigInt(input.publishedAt),\n },\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.durableBufferedEvent.findMany({\n where: { name },\n orderBy: { publishedAt: 'asc' }, // oldest first\n take: limit,\n });\n return rows.map((r) => ({\n id: r.id,\n payload: r.payload ?? undefined,\n publishedAt: Number(r.publishedAt),\n }));\n }\n\n async removeBufferedEvent(id: string): Promise<boolean> {\n // deleteMany's `where: { id }` matches at most one row (id is the PK) and is a safe no-op if it's\n // already gone — unlike `delete({ where: { id } })`, which throws P2025 on a missing row (the same\n // reasoning as releaseRunLock's updateMany above).\n const result = await this.db.durableBufferedEvent.deleteMany({ where: { id } });\n return result.count === 1;\n }\n}\n\n/**\n * One attribute predicate as a Prisma relation `some` filter on the side-table — compiles to an\n * EXISTS, so the predicate runs in SQL. `<>` (ne) maps to `{ not }`, which under `some` also excludes\n * runs where the attribute is absent (the missing-key-never-matches contract): `some` already\n * requires a matching row to exist. Numeric operands compare `numValue`, everything else `strValue`.\n */\nfunction attributeSome(f: AttributeFilter): Record<string, unknown> {\n // One comparison for a scalar op, one per member for `in` — ORed inside the single `some`, since\n // `in`'s operands may be of mixed types and so land in different typed columns. No comparisons at\n // all (an `in` over no values) can match no run, which is a run-level fact, not a side-table one.\n const comparisons = attributePredicateOperands(f).map(({ column, comparator, operand }) => ({\n [column]:\n comparator === '=' ? operand : comparator === '<>' ? { not: operand } : { [f.op]: operand },\n }));\n if (comparisons.length === 0) return MATCHES_NOTHING;\n return { attributes: { some: { key: f.key, ...anyOf(comparisons) } } };\n}\n\n/** A where fragment no run satisfies — what a plural predicate over an EMPTY set means. Spelled as an\n * impossible `id` rather than `OR: []` so it does not depend on how a Prisma version reads an empty\n * disjunction. */\nconst MATCHES_NOTHING: Record<string, unknown> = { id: { in: [] as string[] } };\n\n/** OR a set of where fragments, where an EMPTY set matches nothing rather than everything. */\nfunction anyOf(branches: Record<string, unknown>[]): Record<string, unknown> {\n return branches.length ? { OR: branches } : MATCHES_NOTHING;\n}\n\nconst bigOrNull = (n: number | undefined) => (n == null ? null : BigInt(n));\nconst numOrUndef = (n: bigint | null) => (n == null ? undefined : Number(n));\nconst jsonOrNull = (v: unknown) => v ?? null;\n\nfunction toRunData(run: WorkflowRun) {\n return {\n id: run.id,\n workflow: run.workflow,\n workflowVersion: run.workflowVersion,\n status: run.status,\n input: jsonOrNull(run.input),\n output: jsonOrNull(run.output),\n error: jsonOrNull(run.error),\n wakeAt: bigOrNull(run.wakeAt),\n lockedBy: run.lockedBy ?? null,\n lockedUntil: run.lockedUntil == null ? null : new Date(run.lockedUntil),\n awaitingDecisionTaskId: run.awaitingDecisionTaskId ?? null,\n recoveryAttempts: run.recoveryAttempts ?? null,\n tags: jsonOrNull(run.tags),\n searchAttributes: jsonOrNull(run.searchAttributes),\n priority: run.priority ?? null,\n // An absent namespace IS `'default'` — unlike `origin` below, this is a reconstruction and not a\n // guess: an engine started without a namespace stamps its runs and routes its workers as\n // `'default'`, so writing anything else (or NULL) would put the run in a partition no worker polls.\n namespace: run.namespace ?? 'default',\n // Absent origin stays SQL NULL — \"unknown\", never coerced into a real-looking library name.\n origin: run.origin ?? null,\n createdAt: run.createdAt,\n updatedAt: run.updatedAt,\n };\n}\n\nfunction toRunPatch(patch: Partial<WorkflowRun>) {\n // Map EVERY patchable field, using presence (`'x' in patch`) semantics for the nullable ones so a\n // patch can CLEAR a column (e.g. `{ error: undefined }` on completion sets it to NULL — matching\n // the TypeORM / MikroORM / in-memory stores). The two non-null Date fields use a defined-guard\n // since they are never cleared. Previously only 7 fields were mapped, so `updateRun({ tags })` /\n // `{ lockedBy }` / clearing `error` silently no-opped on this adapter.\n const data: Record<string, unknown> = {};\n if ('workflow' in patch) data.workflow = patch.workflow;\n if ('workflowVersion' in patch) data.workflowVersion = patch.workflowVersion;\n if ('status' in patch) data.status = patch.status;\n if ('input' in patch) data.input = jsonOrNull(patch.input);\n if ('output' in patch) data.output = jsonOrNull(patch.output);\n if ('error' in patch) data.error = jsonOrNull(patch.error);\n if ('wakeAt' in patch) data.wakeAt = bigOrNull(patch.wakeAt);\n if ('lockedBy' in patch) data.lockedBy = patch.lockedBy ?? null;\n if ('lockedUntil' in patch)\n data.lockedUntil = patch.lockedUntil == null ? null : new Date(patch.lockedUntil);\n if ('awaitingDecisionTaskId' in patch)\n data.awaitingDecisionTaskId = patch.awaitingDecisionTaskId ?? null;\n if ('recoveryAttempts' in patch) data.recoveryAttempts = patch.recoveryAttempts ?? null;\n if ('tags' in patch) data.tags = jsonOrNull(patch.tags);\n if ('searchAttributes' in patch) data.searchAttributes = jsonOrNull(patch.searchAttributes);\n if ('priority' in patch) data.priority = patch.priority ?? null;\n // `?? 'default'` rather than `?? null` like its neighbours: the column is NOT NULL, and clearing a\n // run's namespace means \"back to the unscoped partition\", which is what `'default'` names. A patch\n // that does not mention `namespace` leaves the stored one alone — a status update must never move a\n // run between tenants.\n if ('namespace' in patch) data.namespace = patch.namespace ?? 'default';\n if ('origin' in patch) data.origin = patch.origin ?? null;\n if (patch.createdAt != null) data.createdAt = patch.createdAt;\n if (patch.updatedAt != null) data.updatedAt = patch.updatedAt;\n return data;\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 WorkflowRun['status'],\n input: row.input ?? undefined,\n output: row.output ?? undefined,\n error: (row.error ?? undefined) as StepError | undefined,\n wakeAt: numOrUndef(row.wakeAt),\n lockedBy: row.lockedBy ?? undefined,\n lockedUntil: row.lockedUntil == null ? undefined : row.lockedUntil.getTime(),\n awaitingDecisionTaskId: row.awaitingDecisionTaskId ?? undefined,\n recoveryAttempts: row.recoveryAttempts ?? undefined,\n tags: (row.tags as string[] | null) ?? undefined,\n searchAttributes:\n (row.searchAttributes as Record<string, string | number | boolean> | null) ?? undefined,\n priority: row.priority ?? undefined,\n // Read back verbatim, with NO `?? 'default'` fallback. The column is NOT NULL and the migration\n // back-fills old rows, so there is nothing legitimate to fall back FROM; a fallback would only fire\n // on a deployment that added the column nullable without back-filling, and there it would lie —\n // the dashboard would show `default` for a row whose stored NULL keeps every `default` worker's\n // `WHERE namespace = 'default'` from ever picking it up.\n namespace: row.namespace,\n // NULL (a row written before the column existed) surfaces as `undefined` = unknown origin.\n origin: row.origin ?? undefined,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\n/** The name prefix each non-`step` {@link CheckpointNameKind} is, as `checkpointNameKind` reads it. */\nconst KIND_PREFIXES: [CheckpointNameKind, string][] = [\n ['child', 'signal:child:'],\n ['folded', 'fan:'],\n ['spawn', 'spawn:'],\n];\n\n/** Each {@link CheckpointNameKind} as the `where` that selects its rows; `step` is \"none of the others\". */\nconst NAME_KINDS: { kind: CheckpointNameKind; where: Record<string, unknown> }[] = [\n ...KIND_PREFIXES.map(([kind, prefix]) => ({ kind, where: { name: { startsWith: prefix } } })),\n {\n kind: 'step',\n where: { NOT: KIND_PREFIXES.map(([, prefix]) => ({ name: { startsWith: prefix } })) },\n },\n];\n\n/** One `groupBy` row of {@link PrismaStateStore.checkpointStats}. */\ntype CheckpointStatRow = {\n parallelGroup: string | null;\n status: string;\n _count: { _all: number; enqueuedAt: number };\n _min: { seq: number; name: string; enqueuedAt: Date | null; startedAt: Date };\n _max: { seq: number; name: string; startedAt: Date; finishedAt: Date };\n _sum: { attempts: number | bigint | null };\n};\n\nfunction bucketKey(group: string | null, status: string): string {\n return JSON.stringify([group, status]);\n}\n\nfunction toCheckpointStat(\n nameKind: CheckpointNameKind,\n r: CheckpointStatRow,\n unenqueued: Map<string, Date>,\n): CheckpointStat {\n const fallback = unenqueued.get(bucketKey(r.parallelGroup, r.status));\n const enqueued = r._min.enqueuedAt;\n const minEnqueuedAt =\n enqueued && fallback ? (enqueued < fallback ? enqueued : fallback) : (enqueued ?? fallback);\n return {\n group: r.parallelGroup,\n status: r.status as StepCheckpoint['status'],\n nameKind,\n count: r._count._all,\n minSeq: r._min.seq,\n maxSeq: r._max.seq,\n minName: r._min.name,\n maxName: r._max.name,\n // Every row has `enqueuedAt` or is in the NULL subset, so one of the two is set.\n minEnqueuedAt: minEnqueuedAt as Date,\n minStartedAt: r._min.startedAt,\n maxStartedAt: r._max.startedAt,\n maxFinishedAt: r._max.finishedAt,\n sumAttempts: Number(r._sum.attempts ?? 0),\n };\n}\n\nfunction toCheckpointData(cp: StepCheckpoint) {\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: jsonOrNull(cp.input),\n output: jsonOrNull(cp.output),\n error: jsonOrNull(cp.error),\n events: jsonOrNull(cp.events),\n attempts: cp.attempts,\n workerGroup: cp.workerGroup ?? null,\n parallelGroup: cp.parallelGroup ?? null,\n wakeAt: bigOrNull(cp.wakeAt),\n enqueuedAt: cp.enqueuedAt,\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: numOrUndef(row.wakeAt),\n enqueuedAt: row.enqueuedAt ?? row.startedAt,\n startedAt: row.startedAt,\n finishedAt: row.finishedAt,\n };\n}\n\nfunction toScheduleData(r: ScheduleRecord) {\n return {\n id: r.id,\n namespace: r.namespace,\n workflow: r.workflow,\n paused: r.paused,\n nextFireAt: r.nextFireAt == null ? null : BigInt(r.nextFireAt),\n tags: jsonOrNull(r.tags),\n spec: r.spec,\n state: r.state,\n createdAt: r.createdAt,\n updatedAt: r.updatedAt,\n };\n}\n\nfunction fromScheduleRow(row: ScheduleRow): ScheduleRecord {\n const tags = Array.isArray(row.tags) ? (row.tags as string[]) : undefined;\n return {\n id: row.id,\n namespace: row.namespace,\n workflow: row.workflow,\n paused: row.paused,\n nextFireAt: row.nextFireAt == null ? null : Number(row.nextFireAt),\n ...(tags?.length ? { tags } : {}),\n spec: (row.spec ?? {}) as Record<string, unknown>,\n state: (row.state ?? {}) as Record<string, unknown>,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n","/**\n * Tables this store's durable models own, physically. UNLIKE the other store adapters, this store\n * doesn't create or manage them at boot: the models in `prisma/schema.prisma` are meant to be copied\n * into YOUR OWN `schema.prisma` (see that file's header comment), and Prisma Migrate diffs whatever\n * models live in your schema — so a consumer who copied the models in already has them accounted for\n * and never needs a denylist for Prisma Migrate itself.\n *\n * This is exported anyway for the same reason the other adapters export it: any OTHER tooling that\n * introspects the database outside of `prisma migrate diff` (a raw schema dump, a second ORM/CLI\n * pointed at the same database, a linter that flags \"table not in any model\") needs the same fixed\n * list of table names this store's models declare via `@@map(...)`.\n *\n * ```ts\n * const skipTables = new Set(durableManagedTables());\n * ```\n *\n * Kept in sync with the `@@map(...)` table names in `prisma/schema.prisma` by `schema.spec.ts`,\n * which parses that file and asserts the two lists match — there is no single TypeScript source to\n * derive from (the schema is a `.prisma` text file copied into the consumer's own schema, not\n * imported at runtime), so the list here is intentionally a literal mirror.\n */\nexport function durableManagedTables(): string[] {\n return [\n 'durable_workflow_runs',\n 'durable_step_checkpoints',\n 'durable_run_attributes',\n 'durable_signal_waiters',\n 'durable_buffered_signals',\n 'durable_buffered_events',\n 'durable_schedules',\n ];\n}\n"],"mappings":"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","names":["RUN_VALUE_FACET_SCAN","SINGLETON_ACTIVE_STATUSES","TERMINAL_RUN_STATUSES","attributePredicateOperands","axisIsRunColumn","clearTerminalSingletonAdmission","mergeRunFacetRows","mergeRunValueFacetRows","normalizeAttributeRows","parseDuration","runValueFacetsFromRuns","singletonAdmissionDenialPatch","singletonAdmissionTags","namespaceWhere","namespace","undefined","PrismaStateStore","db","tryAdmitSingleton","runId","tag","workflow","limit","retryWakeAt","$transaction","tx","where","status","in","SINGLETON_ACTIVE_STATUSES","durableWorkflowRun","updateMany","data","rows","findMany","runs","map","fromRunRow","tags","singletonAdmissionTags","patch","singletonAdmissionDenialPatch","update","id","toRunPatch","createRun","run","create","toRunData","reindexAttributes","searchAttributes","updateRun","inputPatch","TERMINAL_RUN_STATUSES","includes","clearTerminalSingletonAdmission","getRun","updateRunIf","expectedStatuses","length","count","Object","keys","attributes","durableRunAttribute","deleteMany","normalizeAttributeRows","createMany","row","findUnique","deleteRun","durableStepCheckpoint","durableSignalWaiter","deleteRuns","runIds","pruneTerminalRuns","policy","nowMs","statuses","filter","s","maxAge","maxCount","scoped","runWhere","scope","ids","Set","cutoff","Date","parseDuration","AND","updatedAt","lt","select","orderBy","take","r","add","size","skip","doomed","slice","getCheckpoint","seq","runId_seq","fromCheckpointRow","saveCheckpoint","checkpoint","toCheckpointData","upsert","saveCheckpointIfPending","saveCheckpointsIfPending","checkpoints","wrote","push","transaction","work","raw","cp","listIncompleteRuns","listOrphanedRuns","OR","lockedUntil","lte","createdAt","listPendingRuns","listDueTimers","wakeAt","not","BigInt","tryLockRun","owner","leaseUntilMs","result","lockedBy","releaseRunLock","renewRunLock","query","and","workflows","anyOf","w","namespaces","n","origin","origins","o","array_contains","t","f","attributeSome","listRuns","offset","countRuns","runFacets","groupBy","by","_count","_all","mergeRunFacetRows","runValueFacets","axis","opts","axisIsRunColumn","scan","RUN_VALUE_FACET_SCAN","runValueFacetsFromRuns","field","mergeRunValueFacetRows","value","schedules","delegate","durableSchedule","Error","saveSchedule","record","toScheduleData","getSchedule","fromScheduleRow","updateSchedule","expectedNextFireAt","paused","nextFireAt","jsonOrNull","spec","state","deleteSchedule","listSchedules","dueBy","sort","nulls","listCheckpoints","getLatestCheckpointByName","name","findFirst","countCheckpoints","fromSeq","toSeq","gte","listCheckpointsByNamePrefix","prefixes","p","startsWith","some","checkpointStats","group","parallelGroup","grouped","Promise","all","NAME_KINDS","kind","enqueuedAt","_min","startedAt","_max","finishedAt","_sum","attempts","stats","unenqueued","unenqueuedStartedAt","Map","toCheckpointStat","flat","bucketKey","queryCheckpoints","namePrefixes","excludeGroups","notIn","putSignalWaiter","waiter","token","takeSignalWaiter","delete","listSignalWaiters","prefix","registerChildWaits","entries","compactCheckpoints","into","listSignalWaitersByRun","hasSignalWaiter","tokenPrefix","first","removeSignalWaiter","bufferSignal","payload","durableBufferedSignal","takeBufferedSignal","bufferEvent","input","durableBufferedEvent","publishedAt","listBufferedEvents","Number","removeBufferedEvent","comparisons","attributePredicateOperands","column","comparator","operand","op","MATCHES_NOTHING","key","branches","bigOrNull","numOrUndef","v","workflowVersion","output","error","awaitingDecisionTaskId","recoveryAttempts","priority","getTime","KIND_PREFIXES","NOT","JSON","stringify","nameKind","fallback","get","enqueued","minEnqueuedAt","minSeq","maxSeq","minName","maxName","minStartedAt","maxStartedAt","maxFinishedAt","sumAttempts","stepId","events","workerGroup","Array","isArray","durableManagedTables"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dudousxd/nestjs-durable-store-prisma",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.1",
|
|
4
4
|
"description": "Prisma adapter for the nestjs-durable StateStore",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Davide Carvalho",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"prisma": "6.19.3",
|
|
37
37
|
"typescript": "5.9.3",
|
|
38
38
|
"tsup": "8.3.5",
|
|
39
|
-
"@dudousxd/nestjs-durable-core": "^0.
|
|
40
|
-
"@dudousxd/nestjs-durable-testing": "^0.
|
|
39
|
+
"@dudousxd/nestjs-durable-core": "^0.80.1",
|
|
40
|
+
"@dudousxd/nestjs-durable-testing": "^0.19.1"
|
|
41
41
|
},
|
|
42
42
|
"module": "./dist/index.js",
|
|
43
43
|
"exports": {
|