@dudousxd/nestjs-durable-store-prisma 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -221,6 +221,7 @@ var PrismaStateStore = class {
221
221
  async listRuns(query) {
222
222
  const where = {};
223
223
  if (query.workflow) where.workflow = query.workflow;
224
+ if (query.origin !== void 0) where.origin = query.origin;
224
225
  if (query.status && query.statuses) {
225
226
  where.AND = [
226
227
  {
@@ -461,6 +462,8 @@ function toRunData(run) {
461
462
  tags: jsonOrNull(run.tags),
462
463
  searchAttributes: jsonOrNull(run.searchAttributes),
463
464
  priority: run.priority ?? null,
465
+ // Absent origin stays SQL NULL — "unknown", never coerced into a real-looking library name.
466
+ origin: run.origin ?? null,
464
467
  createdAt: run.createdAt,
465
468
  updatedAt: run.updatedAt
466
469
  };
@@ -482,6 +485,7 @@ function toRunPatch(patch) {
482
485
  if ("tags" in patch) data.tags = jsonOrNull(patch.tags);
483
486
  if ("searchAttributes" in patch) data.searchAttributes = jsonOrNull(patch.searchAttributes);
484
487
  if ("priority" in patch) data.priority = patch.priority ?? null;
488
+ if ("origin" in patch) data.origin = patch.origin ?? null;
485
489
  if (patch.createdAt != null) data.createdAt = patch.createdAt;
486
490
  if (patch.updatedAt != null) data.updatedAt = patch.updatedAt;
487
491
  return data;
@@ -504,6 +508,8 @@ function fromRunRow(row) {
504
508
  tags: row.tags ?? void 0,
505
509
  searchAttributes: row.searchAttributes ?? void 0,
506
510
  priority: row.priority ?? void 0,
511
+ // NULL (a row written before the column existed) surfaces as `undefined` = unknown origin.
512
+ origin: row.origin ?? void 0,
507
513
  createdAt: row.createdAt,
508
514
  updatedAt: row.updatedAt
509
515
  };
@@ -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 RunQuery,\n type SignalWaiter,\n type StateStore,\n type StepCheckpoint,\n type StepError,\n type StepEvent,\n type WorkflowRun,\n attributeColumnFor,\n attributeOperand,\n normalizeAttributeRows,\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 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}\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}\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 * 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 */\nexport class PrismaStateStore implements StateStore {\n constructor(private readonly db: DurablePrismaClient) {}\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, patch: Partial<WorkflowRun>): Promise<void> {\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 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 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(): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: { in: ['running', 'cancelling'] } },\n });\n return rows.map(fromRunRow);\n }\n\n async listPendingRuns(limit: number): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: 'pending' },\n orderBy: { createdAt: 'asc' }, // FIFO dispatch\n take: limit,\n });\n return rows.map(fromRunRow);\n }\n\n async listDueTimers(nowMs: number): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: 'suspended', wakeAt: { not: null, lte: BigInt(nowMs) } },\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 async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n const where: Record<string, unknown> = {};\n if (query.workflow) where.workflow = query.workflow;\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 where.AND = [{ 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 // 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) {\n const existing = (where.AND as unknown[] | undefined) ?? [];\n where.AND = [...existing, ...query.attributes.map((f) => attributeSome(f))];\n }\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,\n take: query.limit,\n skip: query.offset,\n orderBy,\n });\n return rows.map(fromRunRow);\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 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 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 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 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): { attributes: { some: Record<string, unknown> } } {\n const col = attributeColumnFor(f); // 'numValue' | 'strValue'\n const operand = attributeOperand(f);\n const condition =\n f.op === 'eq' ? operand : f.op === 'ne' ? { not: operand } : { [f.op]: operand }; // gt/gte/lt/lte map 1:1 to Prisma operators\n return { attributes: { some: { key: f.key, [col]: condition } } };\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 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 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 createdAt: row.createdAt,\n updatedAt: row.updatedAt,\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","/**\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 ];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;ACAA,iCAYO;AA8GA,IAAMA,mBAAN,MAAMA;EA1Hb,OA0HaA;;;;EACX,YAA6BC,IAAyB;SAAzBA,KAAAA;EAA0B;EAEvD,MAAMC,UAAUC,KAAiC;AAC/C,UAAM,KAAKF,GAAGG,mBAAmBC,OAAO;MAAEC,MAAMC,UAAUJ,GAAAA;IAAK,CAAA;AAC/D,UAAM,KAAKK,kBAAkBL,IAAIM,IAAIN,IAAIO,gBAAgB;EAC3D;EAEA,MAAMC,UAAUC,OAAeC,OAA4C;AACzE,UAAM,KAAKZ,GAAGG,mBAAmBU,OAAO;MAAEC,OAAO;QAAEN,IAAIG;MAAM;MAAGN,MAAMU,WAAWH,KAAAA;IAAO,CAAA;AAExF,QAAI,sBAAsBA,MAAO,OAAM,KAAKL,kBAAkBI,OAAOC,MAAMH,gBAAgB;EAC7F;;;EAIA,MAAcF,kBACZI,OACAK,YACe;AACf,UAAM,KAAKhB,GAAGiB,oBAAoBC,WAAW;MAAEJ,OAAO;QAAEH;MAAM;IAAE,CAAA;AAChE,UAAMQ,WAAOC,mDAAuBT,OAAOK,UAAAA;AAC3C,QAAIG,KAAKE,OAAQ,OAAM,KAAKrB,GAAGiB,oBAAoBK,WAAW;MAAEjB,MAAMc;IAAK,CAAA;EAC7E;EAEA,MAAMI,OAAOZ,OAA4C;AACvD,UAAMa,MAAM,MAAM,KAAKxB,GAAGG,mBAAmBsB,WAAW;MAAEX,OAAO;QAAEN,IAAIG;MAAM;IAAE,CAAA;AAC/E,WAAOa,MAAME,WAAWF,GAAAA,IAAO;EACjC;EAEA,MAAMG,UAAUhB,OAA8B;AAE5C,UAAM,KAAKX,GAAG4B,sBAAsBV,WAAW;MAAEJ,OAAO;QAAEH;MAAM;IAAE,CAAA;AAClE,UAAM,KAAKX,GAAG6B,oBAAoBX,WAAW;MAAEJ,OAAO;QAAEH;MAAM;IAAE,CAAA;AAChE,UAAM,KAAKX,GAAGiB,oBAAoBC,WAAW;MAAEJ,OAAO;QAAEH;MAAM;IAAE,CAAA;AAChE,UAAM,KAAKX,GAAGG,mBAAmBe,WAAW;MAAEJ,OAAO;QAAEN,IAAIG;MAAM;IAAE,CAAA;EACrE;EAEA,MAAMmB,cAAcnB,OAAeoB,KAA6C;AAC9E,UAAMP,MAAM,MAAM,KAAKxB,GAAG4B,sBAAsBH,WAAW;MACzDX,OAAO;QAAEkB,WAAW;UAAErB;UAAOoB;QAAI;MAAE;IACrC,CAAA;AACA,WAAOP,MAAMS,kBAAkBT,GAAAA,IAAO;EACxC;EAEA,MAAMU,eAAeC,YAA2C;AAC9D,UAAM9B,OAAO+B,iBAAiBD,UAAAA;AAC9B,UAAM,KAAKnC,GAAG4B,sBAAsBS,OAAO;MACzCvB,OAAO;QAAEkB,WAAW;UAAErB,OAAOwB,WAAWxB;UAAOoB,KAAKI,WAAWJ;QAAI;MAAE;MACrE3B,QAAQC;MACRQ,QAAQR;IACV,CAAA;EACF;EAEA,MAAMiC,YACJC,MAIY;AACZ,WAAO,KAAKvC,GAAGwC,aAAa,OAAOC,OACjCF,KAAK;MACHG,KAAKD;MACLP,gBAAgB,8BAAOS,OAAAA;AACrB,cAAMtC,OAAO+B,iBAAiBO,EAAAA;AAC9B,cAAMF,GAAGb,sBAAsBS,OAAO;UACpCvB,OAAO;YAAEkB,WAAW;cAAErB,OAAOgC,GAAGhC;cAAOoB,KAAKY,GAAGZ;YAAI;UAAE;UACrD3B,QAAQC;UACRQ,QAAQR;QACV,CAAA;MACF,GAPgB;IAQlB,CAAA,CAAA;EAEJ;EAEA,MAAMuC,qBAA6C;AACjD,UAAMzB,OAAO,MAAM,KAAKnB,GAAGG,mBAAmB0C,SAAS;MACrD/B,OAAO;QAAEgC,QAAQ;UAAEC,IAAI;YAAC;YAAW;;QAAc;MAAE;IACrD,CAAA;AACA,WAAO5B,KAAK6B,IAAItB,UAAAA;EAClB;EAEA,MAAMuB,gBAAgBC,OAAuC;AAC3D,UAAM/B,OAAO,MAAM,KAAKnB,GAAGG,mBAAmB0C,SAAS;MACrD/B,OAAO;QAAEgC,QAAQ;MAAU;MAC3BK,SAAS;QAAEC,WAAW;MAAM;MAC5BC,MAAMH;IACR,CAAA;AACA,WAAO/B,KAAK6B,IAAItB,UAAAA;EAClB;EAEA,MAAM4B,cAAcC,OAAuC;AACzD,UAAMpC,OAAO,MAAM,KAAKnB,GAAGG,mBAAmB0C,SAAS;MACrD/B,OAAO;QAAEgC,QAAQ;QAAaU,QAAQ;UAAEC,KAAK;UAAMC,KAAKC,OAAOJ,KAAAA;QAAO;MAAE;IAC1E,CAAA;AACA,WAAOpC,KAAK6B,IAAItB,UAAAA;EAClB;EAEA,MAAMkC,WACJjD,OACAkD,OACAC,cACAP,OACkB;AAClB,UAAMQ,SAAS,MAAM,KAAK/D,GAAGG,mBAAmB6D,WAAW;MACzDlD,OAAO;QACLN,IAAIG;QACJsD,IAAI;UAAC;YAAEC,aAAa;UAAK;UAAG;YAAEA,aAAa;cAAER,KAAK,IAAIS,KAAKZ,KAAAA;YAAO;UAAE;;MACtE;MACAlD,MAAM;QAAE+D,UAAUP;QAAOK,aAAa,IAAIC,KAAKL,YAAAA;MAAc;IAC/D,CAAA;AACA,WAAOC,OAAOM,UAAU;EAC1B;EAEA,MAAMC,eAAe3D,OAA8B;AAQjD,UAAM,KAAKX,GAAGG,mBAAmB6D,WAAW;MAC1ClD,OAAO;QAAEN,IAAIG;MAAM;MACnBN,MAAM;QAAE+D,UAAU;QAAMF,aAAa;MAAK;IAC5C,CAAA;EACF;EAEA,MAAMK,aAAa5D,OAAekD,OAAeC,cAAwC;AACvF,UAAMC,SAAS,MAAM,KAAK/D,GAAGG,mBAAmB6D,WAAW;MACzDlD,OAAO;QAAEN,IAAIG;QAAOyD,UAAUP;MAAM;MACpCxD,MAAM;QAAE6D,aAAa,IAAIC,KAAKL,YAAAA;MAAc;IAC9C,CAAA;AACA,WAAOC,OAAOM,UAAU;EAC1B;EAEA,MAAMG,SAASC,OAAyC;AACtD,UAAM3D,QAAiC,CAAC;AACxC,QAAI2D,MAAMC,SAAU5D,OAAM4D,WAAWD,MAAMC;AAG3C,QAAID,MAAM3B,UAAU2B,MAAME,UAAU;AAClC7D,YAAM8D,MAAM;QAAC;UAAE9B,QAAQ2B,MAAM3B;QAAO;QAAG;UAAEA,QAAQ;YAAEC,IAAI0B,MAAME;UAAS;QAAE;;IAC1E,WAAWF,MAAM3B,QAAQ;AACvBhC,YAAMgC,SAAS2B,MAAM3B;IACvB,WAAW2B,MAAME,UAAU;AACzB7D,YAAMgC,SAAS;QAAEC,IAAI0B,MAAME;MAAS;IACtC;AACA,QAAIF,MAAMI,IAAK/D,OAAMgE,OAAO;MAAEC,gBAAgBN,MAAMI;IAAI;AAIxD,QAAIJ,MAAMzD,YAAYK,QAAQ;AAC5B,YAAM2D,WAAYlE,MAAM8D,OAAiC,CAAA;AACzD9D,YAAM8D,MAAM;WAAII;WAAaP,MAAMzD,WAAWgC,IAAI,CAACiC,MAAMC,cAAcD,CAAAA,CAAAA;;IACzE;AACA,UAAM9B,UAAU;MAAEC,WAAW;IAAgB;AAC7C,UAAMjC,OAAO,MAAM,KAAKnB,GAAGG,mBAAmB0C,SAAS;MACrD/B;MACAuC,MAAMoB,MAAMvB;MACZiC,MAAMV,MAAMW;MACZjC;IACF,CAAA;AACA,WAAOhC,KAAK6B,IAAItB,UAAAA;EAClB;EAEA,MAAM2D,gBAAgB1E,OAA0C;AAC9D,UAAMQ,OAAO,MAAM,KAAKnB,GAAG4B,sBAAsBiB,SAAS;MACxD/B,OAAO;QAAEH;MAAM;MACfwC,SAAS;QAAEpB,KAAK;MAAM;IACxB,CAAA;AACA,WAAOZ,KAAK6B,IAAIf,iBAAAA;EAClB;EAEA,MAAMqD,0BACJ3E,OACA4E,MACqC;AACrC,UAAM/D,MAAM,MAAM,KAAKxB,GAAG4B,sBAAsB4D,UAAU;MACxD1E,OAAO;QAAEH;QAAO4E;MAAK;MACrBpC,SAAS;QAAEpB,KAAK;MAAO;IACzB,CAAA;AACA,WAAOP,MAAMS,kBAAkBT,GAAAA,IAAOiE;EACxC;EAEA,MAAMC,4BAA4B/E,OAAegF,UAA+C;AAC9F,QAAIA,SAAStE,WAAW,EAAG,QAAO,CAAA;AAClC,UAAMF,OAAO,MAAM,KAAKnB,GAAG4B,sBAAsBiB,SAAS;MACxD/B,OAAO;QAAEH;QAAOsD,IAAI0B,SAAS3C,IAAI,CAAC4C,OAAO;UAAEL,MAAM;YAAEM,YAAYD;UAAE;QAAE,EAAA;MAAI;MACvEzC,SAAS;QAAEpB,KAAK;MAAM;IACxB,CAAA;AACA,WAAOZ,KAAK6B,IAAIf,iBAAAA;EAClB;EAEA,MAAM6D,gBAAgBC,QAAqC;AACzD,UAAM,KAAK/F,GAAG6B,oBAAoBQ,OAAO;MACvCvB,OAAO;QAAEkF,OAAOD,OAAOC;MAAM;MAC7B5F,QAAQ;QACN4F,OAAOD,OAAOC;QACdrF,OAAOoF,OAAOpF;QACdoB,KAAKgE,OAAOhE;QACZkE,eAAeF,OAAOE,iBAAiB;MACzC;MACApF,QAAQ;QACNF,OAAOoF,OAAOpF;QACdoB,KAAKgE,OAAOhE;QACZkE,eAAeF,OAAOE,iBAAiB;MACzC;IACF,CAAA;EACF;EAEA,MAAMC,iBAAiBF,OAA6C;AAClE,UAAMxE,MAAM,MAAM,KAAKxB,GAAG6B,oBAAoBJ,WAAW;MAAEX,OAAO;QAAEkF;MAAM;IAAE,CAAA;AAC5E,QAAI,CAACxE,IAAK,QAAO;AACjB,UAAM,KAAKxB,GAAG6B,oBAAoBsE,OAAO;MAAErF,OAAO;QAAEkF;MAAM;IAAE,CAAA;AAC5D,WAAO;MACLA,OAAOxE,IAAIwE;MACXrF,OAAOa,IAAIb;MACXoB,KAAKP,IAAIO;MACTkE,eAAezE,IAAIyE,iBAAiBR;IACtC;EACF;EAEA,MAAMW,kBAAkBC,QAAyC;AAC/D,UAAMlF,OAAO,MAAM,KAAKnB,GAAG6B,oBAAoBgB,SAAS;MACtD/B,OAAO;QAAEkF,OAAO;UAAEH,YAAYQ;QAAO;MAAE;IACzC,CAAA;AACA,WAAOlF,KAAK6B,IAAI,CAACsD,OAAO;MACtBN,OAAOM,EAAEN;MACTrF,OAAO2F,EAAE3F;MACToB,KAAKuE,EAAEvE;MACPkE,eAAeK,EAAEL,iBAAiBR;IACpC,EAAA;EACF;EAEA,MAAMc,mBAAmBR,QAAqC;AAI5D,UAAM,KAAK/F,GAAG6B,oBAAoBX,WAAW;MAC3CJ,OAAO;QAAEkF,OAAOD,OAAOC;QAAOrF,OAAOoF,OAAOpF;QAAOoB,KAAKgE,OAAOhE;MAAI;IACrE,CAAA;EACF;EAEA,MAAMyE,aAAaR,OAAeS,SAAiC;AACjE,UAAM,KAAKzG,GAAG0G,sBAAsBtG,OAAO;MAAEC,MAAM;QAAE2F;QAAOS,SAASE,WAAWF,OAAAA;MAAS;IAAE,CAAA;EAC7F;EAEA,MAAMG,mBAAmBZ,OAAqD;AAC5E,UAAMxE,MAAM,MAAM,KAAKxB,GAAG0G,sBAAsBlB,UAAU;MACxD1E,OAAO;QAAEkF;MAAM;MACf7C,SAAS;QAAE3C,IAAI;MAAM;IACvB,CAAA;AACA,QAAI,CAACgB,IAAK,QAAO;AACjB,UAAM,KAAKxB,GAAG0G,sBAAsBP,OAAO;MAAErF,OAAO;QAAEN,IAAIgB,IAAIhB;MAAG;IAAE,CAAA;AACnE,WAAO;MAAEiG,SAASjF,IAAIiF,WAAWhB;IAAU;EAC7C;EAEA,MAAMoB,YAAYC,OAKA;AAChB,UAAM,KAAK9G,GAAG+G,qBAAqB3G,OAAO;MACxCC,MAAM;QACJG,IAAIsG,MAAMtG;QACV+E,MAAMuB,MAAMvB;QACZkB,SAASE,WAAWG,MAAML,OAAO;QACjCO,aAAarD,OAAOmD,MAAME,WAAW;MACvC;IACF,CAAA;EACF;EAEA,MAAMC,mBACJ1B,MACArC,OACuE;AACvE,UAAM/B,OAAO,MAAM,KAAKnB,GAAG+G,qBAAqBlE,SAAS;MACvD/B,OAAO;QAAEyE;MAAK;MACdpC,SAAS;QAAE6D,aAAa;MAAM;MAC9B3D,MAAMH;IACR,CAAA;AACA,WAAO/B,KAAK6B,IAAI,CAACsD,OAAO;MACtB9F,IAAI8F,EAAE9F;MACNiG,SAASH,EAAEG,WAAWhB;MACtBuB,aAAaE,OAAOZ,EAAEU,WAAW;IACnC,EAAA;EACF;EAEA,MAAMG,oBAAoB3G,IAA8B;AAItD,UAAMuD,SAAS,MAAM,KAAK/D,GAAG+G,qBAAqB7F,WAAW;MAAEJ,OAAO;QAAEN;MAAG;IAAE,CAAA;AAC7E,WAAOuD,OAAOM,UAAU;EAC1B;AACF;AAQA,SAASa,cAAcD,GAAkB;AACvC,QAAMmC,UAAMC,+CAAmBpC,CAAAA;AAC/B,QAAMqC,cAAUC,6CAAiBtC,CAAAA;AACjC,QAAMuC,YACJvC,EAAEwC,OAAO,OAAOH,UAAUrC,EAAEwC,OAAO,OAAO;IAAEhE,KAAK6D;EAAQ,IAAI;IAAE,CAACrC,EAAEwC,EAAE,GAAGH;EAAQ;AACjF,SAAO;IAAEtG,YAAY;MAAE0G,MAAM;QAAEC,KAAK1C,EAAE0C;QAAK,CAACP,GAAAA,GAAMI;MAAU;IAAE;EAAE;AAClE;AANStC;AAQT,IAAM0C,YAAY,wBAACC,MAA2BA,KAAK,OAAO,OAAOlE,OAAOkE,CAAAA,GAAtD;AAClB,IAAMC,aAAa,wBAACD,MAAsBA,KAAK,OAAOpC,SAAYyB,OAAOW,CAAAA,GAAtD;AACnB,IAAMlB,aAAa,wBAACoB,MAAeA,KAAK,MAArB;AAEnB,SAASzH,UAAUJ,KAAgB;AACjC,SAAO;IACLM,IAAIN,IAAIM;IACRkE,UAAUxE,IAAIwE;IACdsD,iBAAiB9H,IAAI8H;IACrBlF,QAAQ5C,IAAI4C;IACZgE,OAAOH,WAAWzG,IAAI4G,KAAK;IAC3BmB,QAAQtB,WAAWzG,IAAI+H,MAAM;IAC7BC,OAAOvB,WAAWzG,IAAIgI,KAAK;IAC3B1E,QAAQoE,UAAU1H,IAAIsD,MAAM;IAC5BY,UAAUlE,IAAIkE,YAAY;IAC1BF,aAAahE,IAAIgE,eAAe,OAAO,OAAO,IAAIC,KAAKjE,IAAIgE,WAAW;IACtEiE,wBAAwBjI,IAAIiI,0BAA0B;IACtDC,kBAAkBlI,IAAIkI,oBAAoB;IAC1CtD,MAAM6B,WAAWzG,IAAI4E,IAAI;IACzBrE,kBAAkBkG,WAAWzG,IAAIO,gBAAgB;IACjD4H,UAAUnI,IAAImI,YAAY;IAC1BjF,WAAWlD,IAAIkD;IACfkF,WAAWpI,IAAIoI;EACjB;AACF;AApBShI;AAsBT,SAASS,WAAWH,OAA2B;AAM7C,QAAMP,OAAgC,CAAC;AACvC,MAAI,cAAcO,MAAOP,MAAKqE,WAAW9D,MAAM8D;AAC/C,MAAI,qBAAqB9D,MAAOP,MAAK2H,kBAAkBpH,MAAMoH;AAC7D,MAAI,YAAYpH,MAAOP,MAAKyC,SAASlC,MAAMkC;AAC3C,MAAI,WAAWlC,MAAOP,MAAKyG,QAAQH,WAAW/F,MAAMkG,KAAK;AACzD,MAAI,YAAYlG,MAAOP,MAAK4H,SAAStB,WAAW/F,MAAMqH,MAAM;AAC5D,MAAI,WAAWrH,MAAOP,MAAK6H,QAAQvB,WAAW/F,MAAMsH,KAAK;AACzD,MAAI,YAAYtH,MAAOP,MAAKmD,SAASoE,UAAUhH,MAAM4C,MAAM;AAC3D,MAAI,cAAc5C,MAAOP,MAAK+D,WAAWxD,MAAMwD,YAAY;AAC3D,MAAI,iBAAiBxD,MACnBP,MAAK6D,cAActD,MAAMsD,eAAe,OAAO,OAAO,IAAIC,KAAKvD,MAAMsD,WAAW;AAClF,MAAI,4BAA4BtD,MAC9BP,MAAK8H,yBAAyBvH,MAAMuH,0BAA0B;AAChE,MAAI,sBAAsBvH,MAAOP,MAAK+H,mBAAmBxH,MAAMwH,oBAAoB;AACnF,MAAI,UAAUxH,MAAOP,MAAKyE,OAAO6B,WAAW/F,MAAMkE,IAAI;AACtD,MAAI,sBAAsBlE,MAAOP,MAAKI,mBAAmBkG,WAAW/F,MAAMH,gBAAgB;AAC1F,MAAI,cAAcG,MAAOP,MAAKgI,WAAWzH,MAAMyH,YAAY;AAC3D,MAAIzH,MAAMwC,aAAa,KAAM/C,MAAK+C,YAAYxC,MAAMwC;AACpD,MAAIxC,MAAM0H,aAAa,KAAMjI,MAAKiI,YAAY1H,MAAM0H;AACpD,SAAOjI;AACT;AA1BSU;AA4BT,SAASW,WAAWF,KAAW;AAC7B,SAAO;IACLhB,IAAIgB,IAAIhB;IACRkE,UAAUlD,IAAIkD;IACdsD,iBAAiBxG,IAAIwG;IACrBlF,QAAQtB,IAAIsB;IACZgE,OAAOtF,IAAIsF,SAASrB;IACpBwC,QAAQzG,IAAIyG,UAAUxC;IACtByC,OAAQ1G,IAAI0G,SAASzC;IACrBjC,QAAQsE,WAAWtG,IAAIgC,MAAM;IAC7BY,UAAU5C,IAAI4C,YAAYqB;IAC1BvB,aAAa1C,IAAI0C,eAAe,OAAOuB,SAAYjE,IAAI0C,YAAYqE,QAAO;IAC1EJ,wBAAwB3G,IAAI2G,0BAA0B1C;IACtD2C,kBAAkB5G,IAAI4G,oBAAoB3C;IAC1CX,MAAOtD,IAAIsD,QAA4BW;IACvChF,kBACGe,IAAIf,oBAAyEgF;IAChF4C,UAAU7G,IAAI6G,YAAY5C;IAC1BrC,WAAW5B,IAAI4B;IACfkF,WAAW9G,IAAI8G;EACjB;AACF;AArBS5G;AAuBT,SAASU,iBAAiBO,IAAkB;AAC1C,SAAO;IACLhC,OAAOgC,GAAGhC;IACVoB,KAAKY,GAAGZ;IACRwD,MAAM5C,GAAG4C;IACTiD,MAAM7F,GAAG6F;IACTC,QAAQ9F,GAAG8F;IACX3F,QAAQH,GAAGG;IACXgE,OAAOH,WAAWhE,GAAGmE,KAAK;IAC1BmB,QAAQtB,WAAWhE,GAAGsF,MAAM;IAC5BC,OAAOvB,WAAWhE,GAAGuF,KAAK;IAC1BQ,QAAQ/B,WAAWhE,GAAG+F,MAAM;IAC5BC,UAAUhG,GAAGgG;IACbC,aAAajG,GAAGiG,eAAe;IAC/B3C,eAAetD,GAAGsD,iBAAiB;IACnCzC,QAAQoE,UAAUjF,GAAGa,MAAM;IAC3BqF,YAAYlG,GAAGkG;IACfC,WAAWnG,GAAGmG;IACdC,YAAYpG,GAAGoG;EACjB;AACF;AApBS3G;AAsBT,SAASH,kBAAkBT,KAAkB;AAC3C,SAAO;IACLb,OAAOa,IAAIb;IACXoB,KAAKP,IAAIO;IACTwD,MAAM/D,IAAI+D;IACViD,MAAMhH,IAAIgH;IACVC,QAAQjH,IAAIiH;IACZ3F,QAAQtB,IAAIsB;IACZgE,OAAOtF,IAAIsF,SAASrB;IACpBwC,QAAQzG,IAAIyG,UAAUxC;IACtByC,OAAQ1G,IAAI0G,SAASzC;IACrBiD,QAASlH,IAAIkH,UAAUjD;IACvBkD,UAAUnH,IAAImH;IACdC,aAAapH,IAAIoH,eAAenD;IAChCQ,eAAezE,IAAIyE,iBAAiBR;IACpCjC,QAAQsE,WAAWtG,IAAIgC,MAAM;IAC7BqF,YAAYrH,IAAIqH,cAAcrH,IAAIsH;IAClCA,WAAWtH,IAAIsH;IACfC,YAAYvH,IAAIuH;EAClB;AACF;AApBS9G;;;ACjgBF,SAAS+G,uBAAAA;AACd,SAAO;IACL;IACA;IACA;IACA;IACA;IACA;;AAEJ;AATgBA;","names":["PrismaStateStore","db","createRun","run","durableWorkflowRun","create","data","toRunData","reindexAttributes","id","searchAttributes","updateRun","runId","patch","update","where","toRunPatch","attributes","durableRunAttribute","deleteMany","rows","normalizeAttributeRows","length","createMany","getRun","row","findUnique","fromRunRow","deleteRun","durableStepCheckpoint","durableSignalWaiter","getCheckpoint","seq","runId_seq","fromCheckpointRow","saveCheckpoint","checkpoint","toCheckpointData","upsert","transaction","work","$transaction","tx","raw","cp","listIncompleteRuns","findMany","status","in","map","listPendingRuns","limit","orderBy","createdAt","take","listDueTimers","nowMs","wakeAt","not","lte","BigInt","tryLockRun","owner","leaseUntilMs","result","updateMany","OR","lockedUntil","Date","lockedBy","count","releaseRunLock","renewRunLock","listRuns","query","workflow","statuses","AND","tag","tags","array_contains","existing","f","attributeSome","skip","offset","listCheckpoints","getLatestCheckpointByName","name","findFirst","undefined","listCheckpointsByNamePrefix","prefixes","p","startsWith","putSignalWaiter","waiter","token","parallelGroup","takeSignalWaiter","delete","listSignalWaiters","prefix","r","removeSignalWaiter","bufferSignal","payload","durableBufferedSignal","jsonOrNull","takeBufferedSignal","bufferEvent","input","durableBufferedEvent","publishedAt","listBufferedEvents","Number","removeBufferedEvent","col","attributeColumnFor","operand","attributeOperand","condition","op","some","key","bigOrNull","n","numOrUndef","v","workflowVersion","output","error","awaitingDecisionTaskId","recoveryAttempts","priority","updatedAt","getTime","kind","stepId","events","attempts","workerGroup","enqueuedAt","startedAt","finishedAt","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 RunQuery,\n type SignalWaiter,\n type StateStore,\n type StepCheckpoint,\n type StepError,\n type StepEvent,\n type WorkflowRun,\n attributeColumnFor,\n attributeOperand,\n normalizeAttributeRows,\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 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}\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}\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 * 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 */\nexport class PrismaStateStore implements StateStore {\n constructor(private readonly db: DurablePrismaClient) {}\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, patch: Partial<WorkflowRun>): Promise<void> {\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 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 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(): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: { in: ['running', 'cancelling'] } },\n });\n return rows.map(fromRunRow);\n }\n\n async listPendingRuns(limit: number): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: 'pending' },\n orderBy: { createdAt: 'asc' }, // FIFO dispatch\n take: limit,\n });\n return rows.map(fromRunRow);\n }\n\n async listDueTimers(nowMs: number): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: 'suspended', wakeAt: { not: null, lte: BigInt(nowMs) } },\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 async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n const where: Record<string, unknown> = {};\n if (query.workflow) where.workflow = query.workflow;\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 if (query.origin !== undefined) where.origin = query.origin;\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 where.AND = [{ 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 // 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) {\n const existing = (where.AND as unknown[] | undefined) ?? [];\n where.AND = [...existing, ...query.attributes.map((f) => attributeSome(f))];\n }\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,\n take: query.limit,\n skip: query.offset,\n orderBy,\n });\n return rows.map(fromRunRow);\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 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 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 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 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): { attributes: { some: Record<string, unknown> } } {\n const col = attributeColumnFor(f); // 'numValue' | 'strValue'\n const operand = attributeOperand(f);\n const condition =\n f.op === 'eq' ? operand : f.op === 'ne' ? { not: operand } : { [f.op]: operand }; // gt/gte/lt/lte map 1:1 to Prisma operators\n return { attributes: { some: { key: f.key, [col]: condition } } };\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 // 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 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 // 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\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","/**\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 ];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;ACAA,iCAYO;AA+GA,IAAMA,mBAAN,MAAMA;EA3Hb,OA2HaA;;;;EACX,YAA6BC,IAAyB;SAAzBA,KAAAA;EAA0B;EAEvD,MAAMC,UAAUC,KAAiC;AAC/C,UAAM,KAAKF,GAAGG,mBAAmBC,OAAO;MAAEC,MAAMC,UAAUJ,GAAAA;IAAK,CAAA;AAC/D,UAAM,KAAKK,kBAAkBL,IAAIM,IAAIN,IAAIO,gBAAgB;EAC3D;EAEA,MAAMC,UAAUC,OAAeC,OAA4C;AACzE,UAAM,KAAKZ,GAAGG,mBAAmBU,OAAO;MAAEC,OAAO;QAAEN,IAAIG;MAAM;MAAGN,MAAMU,WAAWH,KAAAA;IAAO,CAAA;AAExF,QAAI,sBAAsBA,MAAO,OAAM,KAAKL,kBAAkBI,OAAOC,MAAMH,gBAAgB;EAC7F;;;EAIA,MAAcF,kBACZI,OACAK,YACe;AACf,UAAM,KAAKhB,GAAGiB,oBAAoBC,WAAW;MAAEJ,OAAO;QAAEH;MAAM;IAAE,CAAA;AAChE,UAAMQ,WAAOC,mDAAuBT,OAAOK,UAAAA;AAC3C,QAAIG,KAAKE,OAAQ,OAAM,KAAKrB,GAAGiB,oBAAoBK,WAAW;MAAEjB,MAAMc;IAAK,CAAA;EAC7E;EAEA,MAAMI,OAAOZ,OAA4C;AACvD,UAAMa,MAAM,MAAM,KAAKxB,GAAGG,mBAAmBsB,WAAW;MAAEX,OAAO;QAAEN,IAAIG;MAAM;IAAE,CAAA;AAC/E,WAAOa,MAAME,WAAWF,GAAAA,IAAO;EACjC;EAEA,MAAMG,UAAUhB,OAA8B;AAE5C,UAAM,KAAKX,GAAG4B,sBAAsBV,WAAW;MAAEJ,OAAO;QAAEH;MAAM;IAAE,CAAA;AAClE,UAAM,KAAKX,GAAG6B,oBAAoBX,WAAW;MAAEJ,OAAO;QAAEH;MAAM;IAAE,CAAA;AAChE,UAAM,KAAKX,GAAGiB,oBAAoBC,WAAW;MAAEJ,OAAO;QAAEH;MAAM;IAAE,CAAA;AAChE,UAAM,KAAKX,GAAGG,mBAAmBe,WAAW;MAAEJ,OAAO;QAAEN,IAAIG;MAAM;IAAE,CAAA;EACrE;EAEA,MAAMmB,cAAcnB,OAAeoB,KAA6C;AAC9E,UAAMP,MAAM,MAAM,KAAKxB,GAAG4B,sBAAsBH,WAAW;MACzDX,OAAO;QAAEkB,WAAW;UAAErB;UAAOoB;QAAI;MAAE;IACrC,CAAA;AACA,WAAOP,MAAMS,kBAAkBT,GAAAA,IAAO;EACxC;EAEA,MAAMU,eAAeC,YAA2C;AAC9D,UAAM9B,OAAO+B,iBAAiBD,UAAAA;AAC9B,UAAM,KAAKnC,GAAG4B,sBAAsBS,OAAO;MACzCvB,OAAO;QAAEkB,WAAW;UAAErB,OAAOwB,WAAWxB;UAAOoB,KAAKI,WAAWJ;QAAI;MAAE;MACrE3B,QAAQC;MACRQ,QAAQR;IACV,CAAA;EACF;EAEA,MAAMiC,YACJC,MAIY;AACZ,WAAO,KAAKvC,GAAGwC,aAAa,OAAOC,OACjCF,KAAK;MACHG,KAAKD;MACLP,gBAAgB,8BAAOS,OAAAA;AACrB,cAAMtC,OAAO+B,iBAAiBO,EAAAA;AAC9B,cAAMF,GAAGb,sBAAsBS,OAAO;UACpCvB,OAAO;YAAEkB,WAAW;cAAErB,OAAOgC,GAAGhC;cAAOoB,KAAKY,GAAGZ;YAAI;UAAE;UACrD3B,QAAQC;UACRQ,QAAQR;QACV,CAAA;MACF,GAPgB;IAQlB,CAAA,CAAA;EAEJ;EAEA,MAAMuC,qBAA6C;AACjD,UAAMzB,OAAO,MAAM,KAAKnB,GAAGG,mBAAmB0C,SAAS;MACrD/B,OAAO;QAAEgC,QAAQ;UAAEC,IAAI;YAAC;YAAW;;QAAc;MAAE;IACrD,CAAA;AACA,WAAO5B,KAAK6B,IAAItB,UAAAA;EAClB;EAEA,MAAMuB,gBAAgBC,OAAuC;AAC3D,UAAM/B,OAAO,MAAM,KAAKnB,GAAGG,mBAAmB0C,SAAS;MACrD/B,OAAO;QAAEgC,QAAQ;MAAU;MAC3BK,SAAS;QAAEC,WAAW;MAAM;MAC5BC,MAAMH;IACR,CAAA;AACA,WAAO/B,KAAK6B,IAAItB,UAAAA;EAClB;EAEA,MAAM4B,cAAcC,OAAuC;AACzD,UAAMpC,OAAO,MAAM,KAAKnB,GAAGG,mBAAmB0C,SAAS;MACrD/B,OAAO;QAAEgC,QAAQ;QAAaU,QAAQ;UAAEC,KAAK;UAAMC,KAAKC,OAAOJ,KAAAA;QAAO;MAAE;IAC1E,CAAA;AACA,WAAOpC,KAAK6B,IAAItB,UAAAA;EAClB;EAEA,MAAMkC,WACJjD,OACAkD,OACAC,cACAP,OACkB;AAClB,UAAMQ,SAAS,MAAM,KAAK/D,GAAGG,mBAAmB6D,WAAW;MACzDlD,OAAO;QACLN,IAAIG;QACJsD,IAAI;UAAC;YAAEC,aAAa;UAAK;UAAG;YAAEA,aAAa;cAAER,KAAK,IAAIS,KAAKZ,KAAAA;YAAO;UAAE;;MACtE;MACAlD,MAAM;QAAE+D,UAAUP;QAAOK,aAAa,IAAIC,KAAKL,YAAAA;MAAc;IAC/D,CAAA;AACA,WAAOC,OAAOM,UAAU;EAC1B;EAEA,MAAMC,eAAe3D,OAA8B;AAQjD,UAAM,KAAKX,GAAGG,mBAAmB6D,WAAW;MAC1ClD,OAAO;QAAEN,IAAIG;MAAM;MACnBN,MAAM;QAAE+D,UAAU;QAAMF,aAAa;MAAK;IAC5C,CAAA;EACF;EAEA,MAAMK,aAAa5D,OAAekD,OAAeC,cAAwC;AACvF,UAAMC,SAAS,MAAM,KAAK/D,GAAGG,mBAAmB6D,WAAW;MACzDlD,OAAO;QAAEN,IAAIG;QAAOyD,UAAUP;MAAM;MACpCxD,MAAM;QAAE6D,aAAa,IAAIC,KAAKL,YAAAA;MAAc;IAC9C,CAAA;AACA,WAAOC,OAAOM,UAAU;EAC1B;EAEA,MAAMG,SAASC,OAAyC;AACtD,UAAM3D,QAAiC,CAAC;AACxC,QAAI2D,MAAMC,SAAU5D,OAAM4D,WAAWD,MAAMC;AAM3C,QAAID,MAAME,WAAWC,OAAW9D,OAAM6D,SAASF,MAAME;AAGrD,QAAIF,MAAM3B,UAAU2B,MAAMI,UAAU;AAClC/D,YAAMgE,MAAM;QAAC;UAAEhC,QAAQ2B,MAAM3B;QAAO;QAAG;UAAEA,QAAQ;YAAEC,IAAI0B,MAAMI;UAAS;QAAE;;IAC1E,WAAWJ,MAAM3B,QAAQ;AACvBhC,YAAMgC,SAAS2B,MAAM3B;IACvB,WAAW2B,MAAMI,UAAU;AACzB/D,YAAMgC,SAAS;QAAEC,IAAI0B,MAAMI;MAAS;IACtC;AACA,QAAIJ,MAAMM,IAAKjE,OAAMkE,OAAO;MAAEC,gBAAgBR,MAAMM;IAAI;AAIxD,QAAIN,MAAMzD,YAAYK,QAAQ;AAC5B,YAAM6D,WAAYpE,MAAMgE,OAAiC,CAAA;AACzDhE,YAAMgE,MAAM;WAAII;WAAaT,MAAMzD,WAAWgC,IAAI,CAACmC,MAAMC,cAAcD,CAAAA,CAAAA;;IACzE;AACA,UAAMhC,UAAU;MAAEC,WAAW;IAAgB;AAC7C,UAAMjC,OAAO,MAAM,KAAKnB,GAAGG,mBAAmB0C,SAAS;MACrD/B;MACAuC,MAAMoB,MAAMvB;MACZmC,MAAMZ,MAAMa;MACZnC;IACF,CAAA;AACA,WAAOhC,KAAK6B,IAAItB,UAAAA;EAClB;EAEA,MAAM6D,gBAAgB5E,OAA0C;AAC9D,UAAMQ,OAAO,MAAM,KAAKnB,GAAG4B,sBAAsBiB,SAAS;MACxD/B,OAAO;QAAEH;MAAM;MACfwC,SAAS;QAAEpB,KAAK;MAAM;IACxB,CAAA;AACA,WAAOZ,KAAK6B,IAAIf,iBAAAA;EAClB;EAEA,MAAMuD,0BACJ7E,OACA8E,MACqC;AACrC,UAAMjE,MAAM,MAAM,KAAKxB,GAAG4B,sBAAsB8D,UAAU;MACxD5E,OAAO;QAAEH;QAAO8E;MAAK;MACrBtC,SAAS;QAAEpB,KAAK;MAAO;IACzB,CAAA;AACA,WAAOP,MAAMS,kBAAkBT,GAAAA,IAAOoD;EACxC;EAEA,MAAMe,4BAA4BhF,OAAeiF,UAA+C;AAC9F,QAAIA,SAASvE,WAAW,EAAG,QAAO,CAAA;AAClC,UAAMF,OAAO,MAAM,KAAKnB,GAAG4B,sBAAsBiB,SAAS;MACxD/B,OAAO;QAAEH;QAAOsD,IAAI2B,SAAS5C,IAAI,CAAC6C,OAAO;UAAEJ,MAAM;YAAEK,YAAYD;UAAE;QAAE,EAAA;MAAI;MACvE1C,SAAS;QAAEpB,KAAK;MAAM;IACxB,CAAA;AACA,WAAOZ,KAAK6B,IAAIf,iBAAAA;EAClB;EAEA,MAAM8D,gBAAgBC,QAAqC;AACzD,UAAM,KAAKhG,GAAG6B,oBAAoBQ,OAAO;MACvCvB,OAAO;QAAEmF,OAAOD,OAAOC;MAAM;MAC7B7F,QAAQ;QACN6F,OAAOD,OAAOC;QACdtF,OAAOqF,OAAOrF;QACdoB,KAAKiE,OAAOjE;QACZmE,eAAeF,OAAOE,iBAAiB;MACzC;MACArF,QAAQ;QACNF,OAAOqF,OAAOrF;QACdoB,KAAKiE,OAAOjE;QACZmE,eAAeF,OAAOE,iBAAiB;MACzC;IACF,CAAA;EACF;EAEA,MAAMC,iBAAiBF,OAA6C;AAClE,UAAMzE,MAAM,MAAM,KAAKxB,GAAG6B,oBAAoBJ,WAAW;MAAEX,OAAO;QAAEmF;MAAM;IAAE,CAAA;AAC5E,QAAI,CAACzE,IAAK,QAAO;AACjB,UAAM,KAAKxB,GAAG6B,oBAAoBuE,OAAO;MAAEtF,OAAO;QAAEmF;MAAM;IAAE,CAAA;AAC5D,WAAO;MACLA,OAAOzE,IAAIyE;MACXtF,OAAOa,IAAIb;MACXoB,KAAKP,IAAIO;MACTmE,eAAe1E,IAAI0E,iBAAiBtB;IACtC;EACF;EAEA,MAAMyB,kBAAkBC,QAAyC;AAC/D,UAAMnF,OAAO,MAAM,KAAKnB,GAAG6B,oBAAoBgB,SAAS;MACtD/B,OAAO;QAAEmF,OAAO;UAAEH,YAAYQ;QAAO;MAAE;IACzC,CAAA;AACA,WAAOnF,KAAK6B,IAAI,CAACuD,OAAO;MACtBN,OAAOM,EAAEN;MACTtF,OAAO4F,EAAE5F;MACToB,KAAKwE,EAAExE;MACPmE,eAAeK,EAAEL,iBAAiBtB;IACpC,EAAA;EACF;EAEA,MAAM4B,mBAAmBR,QAAqC;AAI5D,UAAM,KAAKhG,GAAG6B,oBAAoBX,WAAW;MAC3CJ,OAAO;QAAEmF,OAAOD,OAAOC;QAAOtF,OAAOqF,OAAOrF;QAAOoB,KAAKiE,OAAOjE;MAAI;IACrE,CAAA;EACF;EAEA,MAAM0E,aAAaR,OAAeS,SAAiC;AACjE,UAAM,KAAK1G,GAAG2G,sBAAsBvG,OAAO;MAAEC,MAAM;QAAE4F;QAAOS,SAASE,WAAWF,OAAAA;MAAS;IAAE,CAAA;EAC7F;EAEA,MAAMG,mBAAmBZ,OAAqD;AAC5E,UAAMzE,MAAM,MAAM,KAAKxB,GAAG2G,sBAAsBjB,UAAU;MACxD5E,OAAO;QAAEmF;MAAM;MACf9C,SAAS;QAAE3C,IAAI;MAAM;IACvB,CAAA;AACA,QAAI,CAACgB,IAAK,QAAO;AACjB,UAAM,KAAKxB,GAAG2G,sBAAsBP,OAAO;MAAEtF,OAAO;QAAEN,IAAIgB,IAAIhB;MAAG;IAAE,CAAA;AACnE,WAAO;MAAEkG,SAASlF,IAAIkF,WAAW9B;IAAU;EAC7C;EAEA,MAAMkC,YAAYC,OAKA;AAChB,UAAM,KAAK/G,GAAGgH,qBAAqB5G,OAAO;MACxCC,MAAM;QACJG,IAAIuG,MAAMvG;QACViF,MAAMsB,MAAMtB;QACZiB,SAASE,WAAWG,MAAML,OAAO;QACjCO,aAAatD,OAAOoD,MAAME,WAAW;MACvC;IACF,CAAA;EACF;EAEA,MAAMC,mBACJzB,MACAvC,OACuE;AACvE,UAAM/B,OAAO,MAAM,KAAKnB,GAAGgH,qBAAqBnE,SAAS;MACvD/B,OAAO;QAAE2E;MAAK;MACdtC,SAAS;QAAE8D,aAAa;MAAM;MAC9B5D,MAAMH;IACR,CAAA;AACA,WAAO/B,KAAK6B,IAAI,CAACuD,OAAO;MACtB/F,IAAI+F,EAAE/F;MACNkG,SAASH,EAAEG,WAAW9B;MACtBqC,aAAaE,OAAOZ,EAAEU,WAAW;IACnC,EAAA;EACF;EAEA,MAAMG,oBAAoB5G,IAA8B;AAItD,UAAMuD,SAAS,MAAM,KAAK/D,GAAGgH,qBAAqB9F,WAAW;MAAEJ,OAAO;QAAEN;MAAG;IAAE,CAAA;AAC7E,WAAOuD,OAAOM,UAAU;EAC1B;AACF;AAQA,SAASe,cAAcD,GAAkB;AACvC,QAAMkC,UAAMC,+CAAmBnC,CAAAA;AAC/B,QAAMoC,cAAUC,6CAAiBrC,CAAAA;AACjC,QAAMsC,YACJtC,EAAEuC,OAAO,OAAOH,UAAUpC,EAAEuC,OAAO,OAAO;IAAEjE,KAAK8D;EAAQ,IAAI;IAAE,CAACpC,EAAEuC,EAAE,GAAGH;EAAQ;AACjF,SAAO;IAAEvG,YAAY;MAAE2G,MAAM;QAAEC,KAAKzC,EAAEyC;QAAK,CAACP,GAAAA,GAAMI;MAAU;IAAE;EAAE;AAClE;AANSrC;AAQT,IAAMyC,YAAY,wBAACC,MAA2BA,KAAK,OAAO,OAAOnE,OAAOmE,CAAAA,GAAtD;AAClB,IAAMC,aAAa,wBAACD,MAAsBA,KAAK,OAAOlD,SAAYuC,OAAOW,CAAAA,GAAtD;AACnB,IAAMlB,aAAa,wBAACoB,MAAeA,KAAK,MAArB;AAEnB,SAAS1H,UAAUJ,KAAgB;AACjC,SAAO;IACLM,IAAIN,IAAIM;IACRkE,UAAUxE,IAAIwE;IACduD,iBAAiB/H,IAAI+H;IACrBnF,QAAQ5C,IAAI4C;IACZiE,OAAOH,WAAW1G,IAAI6G,KAAK;IAC3BmB,QAAQtB,WAAW1G,IAAIgI,MAAM;IAC7BC,OAAOvB,WAAW1G,IAAIiI,KAAK;IAC3B3E,QAAQqE,UAAU3H,IAAIsD,MAAM;IAC5BY,UAAUlE,IAAIkE,YAAY;IAC1BF,aAAahE,IAAIgE,eAAe,OAAO,OAAO,IAAIC,KAAKjE,IAAIgE,WAAW;IACtEkE,wBAAwBlI,IAAIkI,0BAA0B;IACtDC,kBAAkBnI,IAAImI,oBAAoB;IAC1CrD,MAAM4B,WAAW1G,IAAI8E,IAAI;IACzBvE,kBAAkBmG,WAAW1G,IAAIO,gBAAgB;IACjD6H,UAAUpI,IAAIoI,YAAY;;IAE1B3D,QAAQzE,IAAIyE,UAAU;IACtBvB,WAAWlD,IAAIkD;IACfmF,WAAWrI,IAAIqI;EACjB;AACF;AAtBSjI;AAwBT,SAASS,WAAWH,OAA2B;AAM7C,QAAMP,OAAgC,CAAC;AACvC,MAAI,cAAcO,MAAOP,MAAKqE,WAAW9D,MAAM8D;AAC/C,MAAI,qBAAqB9D,MAAOP,MAAK4H,kBAAkBrH,MAAMqH;AAC7D,MAAI,YAAYrH,MAAOP,MAAKyC,SAASlC,MAAMkC;AAC3C,MAAI,WAAWlC,MAAOP,MAAK0G,QAAQH,WAAWhG,MAAMmG,KAAK;AACzD,MAAI,YAAYnG,MAAOP,MAAK6H,SAAStB,WAAWhG,MAAMsH,MAAM;AAC5D,MAAI,WAAWtH,MAAOP,MAAK8H,QAAQvB,WAAWhG,MAAMuH,KAAK;AACzD,MAAI,YAAYvH,MAAOP,MAAKmD,SAASqE,UAAUjH,MAAM4C,MAAM;AAC3D,MAAI,cAAc5C,MAAOP,MAAK+D,WAAWxD,MAAMwD,YAAY;AAC3D,MAAI,iBAAiBxD,MACnBP,MAAK6D,cAActD,MAAMsD,eAAe,OAAO,OAAO,IAAIC,KAAKvD,MAAMsD,WAAW;AAClF,MAAI,4BAA4BtD,MAC9BP,MAAK+H,yBAAyBxH,MAAMwH,0BAA0B;AAChE,MAAI,sBAAsBxH,MAAOP,MAAKgI,mBAAmBzH,MAAMyH,oBAAoB;AACnF,MAAI,UAAUzH,MAAOP,MAAK2E,OAAO4B,WAAWhG,MAAMoE,IAAI;AACtD,MAAI,sBAAsBpE,MAAOP,MAAKI,mBAAmBmG,WAAWhG,MAAMH,gBAAgB;AAC1F,MAAI,cAAcG,MAAOP,MAAKiI,WAAW1H,MAAM0H,YAAY;AAC3D,MAAI,YAAY1H,MAAOP,MAAKsE,SAAS/D,MAAM+D,UAAU;AACrD,MAAI/D,MAAMwC,aAAa,KAAM/C,MAAK+C,YAAYxC,MAAMwC;AACpD,MAAIxC,MAAM2H,aAAa,KAAMlI,MAAKkI,YAAY3H,MAAM2H;AACpD,SAAOlI;AACT;AA3BSU;AA6BT,SAASW,WAAWF,KAAW;AAC7B,SAAO;IACLhB,IAAIgB,IAAIhB;IACRkE,UAAUlD,IAAIkD;IACduD,iBAAiBzG,IAAIyG;IACrBnF,QAAQtB,IAAIsB;IACZiE,OAAOvF,IAAIuF,SAASnC;IACpBsD,QAAQ1G,IAAI0G,UAAUtD;IACtBuD,OAAQ3G,IAAI2G,SAASvD;IACrBpB,QAAQuE,WAAWvG,IAAIgC,MAAM;IAC7BY,UAAU5C,IAAI4C,YAAYQ;IAC1BV,aAAa1C,IAAI0C,eAAe,OAAOU,SAAYpD,IAAI0C,YAAYsE,QAAO;IAC1EJ,wBAAwB5G,IAAI4G,0BAA0BxD;IACtDyD,kBAAkB7G,IAAI6G,oBAAoBzD;IAC1CI,MAAOxD,IAAIwD,QAA4BJ;IACvCnE,kBACGe,IAAIf,oBAAyEmE;IAChF0D,UAAU9G,IAAI8G,YAAY1D;;IAE1BD,QAAQnD,IAAImD,UAAUC;IACtBxB,WAAW5B,IAAI4B;IACfmF,WAAW/G,IAAI+G;EACjB;AACF;AAvBS7G;AAyBT,SAASU,iBAAiBO,IAAkB;AAC1C,SAAO;IACLhC,OAAOgC,GAAGhC;IACVoB,KAAKY,GAAGZ;IACR0D,MAAM9C,GAAG8C;IACTgD,MAAM9F,GAAG8F;IACTC,QAAQ/F,GAAG+F;IACX5F,QAAQH,GAAGG;IACXiE,OAAOH,WAAWjE,GAAGoE,KAAK;IAC1BmB,QAAQtB,WAAWjE,GAAGuF,MAAM;IAC5BC,OAAOvB,WAAWjE,GAAGwF,KAAK;IAC1BQ,QAAQ/B,WAAWjE,GAAGgG,MAAM;IAC5BC,UAAUjG,GAAGiG;IACbC,aAAalG,GAAGkG,eAAe;IAC/B3C,eAAevD,GAAGuD,iBAAiB;IACnC1C,QAAQqE,UAAUlF,GAAGa,MAAM;IAC3BsF,YAAYnG,GAAGmG;IACfC,WAAWpG,GAAGoG;IACdC,YAAYrG,GAAGqG;EACjB;AACF;AApBS5G;AAsBT,SAASH,kBAAkBT,KAAkB;AAC3C,SAAO;IACLb,OAAOa,IAAIb;IACXoB,KAAKP,IAAIO;IACT0D,MAAMjE,IAAIiE;IACVgD,MAAMjH,IAAIiH;IACVC,QAAQlH,IAAIkH;IACZ5F,QAAQtB,IAAIsB;IACZiE,OAAOvF,IAAIuF,SAASnC;IACpBsD,QAAQ1G,IAAI0G,UAAUtD;IACtBuD,OAAQ3G,IAAI2G,SAASvD;IACrB+D,QAASnH,IAAImH,UAAU/D;IACvBgE,UAAUpH,IAAIoH;IACdC,aAAarH,IAAIqH,eAAejE;IAChCsB,eAAe1E,IAAI0E,iBAAiBtB;IACpCpB,QAAQuE,WAAWvG,IAAIgC,MAAM;IAC7BsF,YAAYtH,IAAIsH,cAActH,IAAIuH;IAClCA,WAAWvH,IAAIuH;IACfC,YAAYxH,IAAIwH;EAClB;AACF;AApBS/G;;;AC7gBF,SAASgH,uBAAAA;AACd,SAAO;IACL;IACA;IACA;IACA;IACA;IACA;;AAEJ;AATgBA;","names":["PrismaStateStore","db","createRun","run","durableWorkflowRun","create","data","toRunData","reindexAttributes","id","searchAttributes","updateRun","runId","patch","update","where","toRunPatch","attributes","durableRunAttribute","deleteMany","rows","normalizeAttributeRows","length","createMany","getRun","row","findUnique","fromRunRow","deleteRun","durableStepCheckpoint","durableSignalWaiter","getCheckpoint","seq","runId_seq","fromCheckpointRow","saveCheckpoint","checkpoint","toCheckpointData","upsert","transaction","work","$transaction","tx","raw","cp","listIncompleteRuns","findMany","status","in","map","listPendingRuns","limit","orderBy","createdAt","take","listDueTimers","nowMs","wakeAt","not","lte","BigInt","tryLockRun","owner","leaseUntilMs","result","updateMany","OR","lockedUntil","Date","lockedBy","count","releaseRunLock","renewRunLock","listRuns","query","workflow","origin","undefined","statuses","AND","tag","tags","array_contains","existing","f","attributeSome","skip","offset","listCheckpoints","getLatestCheckpointByName","name","findFirst","listCheckpointsByNamePrefix","prefixes","p","startsWith","putSignalWaiter","waiter","token","parallelGroup","takeSignalWaiter","delete","listSignalWaiters","prefix","r","removeSignalWaiter","bufferSignal","payload","durableBufferedSignal","jsonOrNull","takeBufferedSignal","bufferEvent","input","durableBufferedEvent","publishedAt","listBufferedEvents","Number","removeBufferedEvent","col","attributeColumnFor","operand","attributeOperand","condition","op","some","key","bigOrNull","n","numOrUndef","v","workflowVersion","output","error","awaitingDecisionTaskId","recoveryAttempts","priority","updatedAt","getTime","kind","stepId","events","attempts","workerGroup","enqueuedAt","startedAt","finishedAt","durableManagedTables"]}
package/dist/index.d.cts CHANGED
@@ -16,6 +16,7 @@ interface RunRow {
16
16
  tags: unknown;
17
17
  searchAttributes: unknown;
18
18
  priority: number | null;
19
+ origin: string | null;
19
20
  createdAt: Date;
20
21
  updatedAt: Date;
21
22
  }
package/dist/index.d.ts CHANGED
@@ -16,6 +16,7 @@ interface RunRow {
16
16
  tags: unknown;
17
17
  searchAttributes: unknown;
18
18
  priority: number | null;
19
+ origin: string | null;
19
20
  createdAt: Date;
20
21
  updatedAt: Date;
21
22
  }
package/dist/index.js CHANGED
@@ -196,6 +196,7 @@ var PrismaStateStore = class {
196
196
  async listRuns(query) {
197
197
  const where = {};
198
198
  if (query.workflow) where.workflow = query.workflow;
199
+ if (query.origin !== void 0) where.origin = query.origin;
199
200
  if (query.status && query.statuses) {
200
201
  where.AND = [
201
202
  {
@@ -436,6 +437,8 @@ function toRunData(run) {
436
437
  tags: jsonOrNull(run.tags),
437
438
  searchAttributes: jsonOrNull(run.searchAttributes),
438
439
  priority: run.priority ?? null,
440
+ // Absent origin stays SQL NULL — "unknown", never coerced into a real-looking library name.
441
+ origin: run.origin ?? null,
439
442
  createdAt: run.createdAt,
440
443
  updatedAt: run.updatedAt
441
444
  };
@@ -457,6 +460,7 @@ function toRunPatch(patch) {
457
460
  if ("tags" in patch) data.tags = jsonOrNull(patch.tags);
458
461
  if ("searchAttributes" in patch) data.searchAttributes = jsonOrNull(patch.searchAttributes);
459
462
  if ("priority" in patch) data.priority = patch.priority ?? null;
463
+ if ("origin" in patch) data.origin = patch.origin ?? null;
460
464
  if (patch.createdAt != null) data.createdAt = patch.createdAt;
461
465
  if (patch.updatedAt != null) data.updatedAt = patch.updatedAt;
462
466
  return data;
@@ -479,6 +483,8 @@ function fromRunRow(row) {
479
483
  tags: row.tags ?? void 0,
480
484
  searchAttributes: row.searchAttributes ?? void 0,
481
485
  priority: row.priority ?? void 0,
486
+ // NULL (a row written before the column existed) surfaces as `undefined` = unknown origin.
487
+ origin: row.origin ?? void 0,
482
488
  createdAt: row.createdAt,
483
489
  updatedAt: row.updatedAt
484
490
  };
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 RunQuery,\n type SignalWaiter,\n type StateStore,\n type StepCheckpoint,\n type StepError,\n type StepEvent,\n type WorkflowRun,\n attributeColumnFor,\n attributeOperand,\n normalizeAttributeRows,\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 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}\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}\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 * 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 */\nexport class PrismaStateStore implements StateStore {\n constructor(private readonly db: DurablePrismaClient) {}\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, patch: Partial<WorkflowRun>): Promise<void> {\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 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 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(): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: { in: ['running', 'cancelling'] } },\n });\n return rows.map(fromRunRow);\n }\n\n async listPendingRuns(limit: number): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: 'pending' },\n orderBy: { createdAt: 'asc' }, // FIFO dispatch\n take: limit,\n });\n return rows.map(fromRunRow);\n }\n\n async listDueTimers(nowMs: number): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: 'suspended', wakeAt: { not: null, lte: BigInt(nowMs) } },\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 async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n const where: Record<string, unknown> = {};\n if (query.workflow) where.workflow = query.workflow;\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 where.AND = [{ 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 // 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) {\n const existing = (where.AND as unknown[] | undefined) ?? [];\n where.AND = [...existing, ...query.attributes.map((f) => attributeSome(f))];\n }\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,\n take: query.limit,\n skip: query.offset,\n orderBy,\n });\n return rows.map(fromRunRow);\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 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 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 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 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): { attributes: { some: Record<string, unknown> } } {\n const col = attributeColumnFor(f); // 'numValue' | 'strValue'\n const operand = attributeOperand(f);\n const condition =\n f.op === 'eq' ? operand : f.op === 'ne' ? { not: operand } : { [f.op]: operand }; // gt/gte/lt/lte map 1:1 to Prisma operators\n return { attributes: { some: { key: f.key, [col]: condition } } };\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 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 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 createdAt: row.createdAt,\n updatedAt: row.updatedAt,\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","/**\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 ];\n}\n"],"mappings":"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","names":["attributeColumnFor","attributeOperand","normalizeAttributeRows","PrismaStateStore","db","createRun","run","durableWorkflowRun","create","data","toRunData","reindexAttributes","id","searchAttributes","updateRun","runId","patch","update","where","toRunPatch","attributes","durableRunAttribute","deleteMany","rows","normalizeAttributeRows","length","createMany","getRun","row","findUnique","fromRunRow","deleteRun","durableStepCheckpoint","durableSignalWaiter","getCheckpoint","seq","runId_seq","fromCheckpointRow","saveCheckpoint","checkpoint","toCheckpointData","upsert","transaction","work","$transaction","tx","raw","cp","listIncompleteRuns","findMany","status","in","map","listPendingRuns","limit","orderBy","createdAt","take","listDueTimers","nowMs","wakeAt","not","lte","BigInt","tryLockRun","owner","leaseUntilMs","result","updateMany","OR","lockedUntil","Date","lockedBy","count","releaseRunLock","renewRunLock","listRuns","query","workflow","statuses","AND","tag","tags","array_contains","existing","f","attributeSome","skip","offset","listCheckpoints","getLatestCheckpointByName","name","findFirst","undefined","listCheckpointsByNamePrefix","prefixes","p","startsWith","putSignalWaiter","waiter","token","parallelGroup","takeSignalWaiter","delete","listSignalWaiters","prefix","r","removeSignalWaiter","bufferSignal","payload","durableBufferedSignal","jsonOrNull","takeBufferedSignal","bufferEvent","input","durableBufferedEvent","publishedAt","listBufferedEvents","Number","removeBufferedEvent","col","attributeColumnFor","operand","attributeOperand","condition","op","some","key","bigOrNull","n","numOrUndef","v","workflowVersion","output","error","awaitingDecisionTaskId","recoveryAttempts","priority","updatedAt","getTime","kind","stepId","events","attempts","workerGroup","enqueuedAt","startedAt","finishedAt","durableManagedTables"]}
1
+ {"version":3,"sources":["../src/prisma-state-store.ts","../src/schema.ts"],"sourcesContent":["import {\n type AttributeFilter,\n type RunQuery,\n type SignalWaiter,\n type StateStore,\n type StepCheckpoint,\n type StepError,\n type StepEvent,\n type WorkflowRun,\n attributeColumnFor,\n attributeOperand,\n normalizeAttributeRows,\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 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}\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}\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 * 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 */\nexport class PrismaStateStore implements StateStore {\n constructor(private readonly db: DurablePrismaClient) {}\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, patch: Partial<WorkflowRun>): Promise<void> {\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 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 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(): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: { in: ['running', 'cancelling'] } },\n });\n return rows.map(fromRunRow);\n }\n\n async listPendingRuns(limit: number): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: 'pending' },\n orderBy: { createdAt: 'asc' }, // FIFO dispatch\n take: limit,\n });\n return rows.map(fromRunRow);\n }\n\n async listDueTimers(nowMs: number): Promise<WorkflowRun[]> {\n const rows = await this.db.durableWorkflowRun.findMany({\n where: { status: 'suspended', wakeAt: { not: null, lte: BigInt(nowMs) } },\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 async listRuns(query: RunQuery): Promise<WorkflowRun[]> {\n const where: Record<string, unknown> = {};\n if (query.workflow) where.workflow = query.workflow;\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 if (query.origin !== undefined) where.origin = query.origin;\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 where.AND = [{ 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 // 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) {\n const existing = (where.AND as unknown[] | undefined) ?? [];\n where.AND = [...existing, ...query.attributes.map((f) => attributeSome(f))];\n }\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,\n take: query.limit,\n skip: query.offset,\n orderBy,\n });\n return rows.map(fromRunRow);\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 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 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 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 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): { attributes: { some: Record<string, unknown> } } {\n const col = attributeColumnFor(f); // 'numValue' | 'strValue'\n const operand = attributeOperand(f);\n const condition =\n f.op === 'eq' ? operand : f.op === 'ne' ? { not: operand } : { [f.op]: operand }; // gt/gte/lt/lte map 1:1 to Prisma operators\n return { attributes: { some: { key: f.key, [col]: condition } } };\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 // 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 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 // 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\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","/**\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 ];\n}\n"],"mappings":"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","names":["attributeColumnFor","attributeOperand","normalizeAttributeRows","PrismaStateStore","db","createRun","run","durableWorkflowRun","create","data","toRunData","reindexAttributes","id","searchAttributes","updateRun","runId","patch","update","where","toRunPatch","attributes","durableRunAttribute","deleteMany","rows","normalizeAttributeRows","length","createMany","getRun","row","findUnique","fromRunRow","deleteRun","durableStepCheckpoint","durableSignalWaiter","getCheckpoint","seq","runId_seq","fromCheckpointRow","saveCheckpoint","checkpoint","toCheckpointData","upsert","transaction","work","$transaction","tx","raw","cp","listIncompleteRuns","findMany","status","in","map","listPendingRuns","limit","orderBy","createdAt","take","listDueTimers","nowMs","wakeAt","not","lte","BigInt","tryLockRun","owner","leaseUntilMs","result","updateMany","OR","lockedUntil","Date","lockedBy","count","releaseRunLock","renewRunLock","listRuns","query","workflow","origin","undefined","statuses","AND","tag","tags","array_contains","existing","f","attributeSome","skip","offset","listCheckpoints","getLatestCheckpointByName","name","findFirst","listCheckpointsByNamePrefix","prefixes","p","startsWith","putSignalWaiter","waiter","token","parallelGroup","takeSignalWaiter","delete","listSignalWaiters","prefix","r","removeSignalWaiter","bufferSignal","payload","durableBufferedSignal","jsonOrNull","takeBufferedSignal","bufferEvent","input","durableBufferedEvent","publishedAt","listBufferedEvents","Number","removeBufferedEvent","col","attributeColumnFor","operand","attributeOperand","condition","op","some","key","bigOrNull","n","numOrUndef","v","workflowVersion","output","error","awaitingDecisionTaskId","recoveryAttempts","priority","updatedAt","getTime","kind","stepId","events","attempts","workerGroup","enqueuedAt","startedAt","finishedAt","durableManagedTables"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dudousxd/nestjs-durable-store-prisma",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Prisma adapter for the nestjs-durable StateStore",
5
5
  "license": "MIT",
6
6
  "author": "Davide Carvalho",
@@ -26,8 +26,8 @@
26
26
  "prisma": "6.19.3",
27
27
  "typescript": "5.9.3",
28
28
  "tsup": "8.3.5",
29
- "@dudousxd/nestjs-durable-core": "^0.54.0",
30
- "@dudousxd/nestjs-durable-testing": "^0.9.0"
29
+ "@dudousxd/nestjs-durable-core": "^0.63.0",
30
+ "@dudousxd/nestjs-durable-testing": "^0.10.0"
31
31
  },
32
32
  "module": "./dist/index.js",
33
33
  "exports": {
@@ -17,6 +17,12 @@ model DurableWorkflowRun {
17
17
  tags Json?
18
18
  searchAttributes Json? @map("search_attributes")
19
19
  priority Int? @map("priority")
20
+ // Which library/module registered the workflow this run belongs to (e.g.
21
+ // `@dudousxd/nestjs-catalog-pipeline`), derived at registration time — never caller input.
22
+ // Nullable with NO default: an origin cannot be reconstructed for a row written before this
23
+ // column existed, so it stays NULL and reads back as `undefined` = "unknown". A real-looking
24
+ // default would be indistinguishable from a genuine registration in the dashboard facet.
25
+ origin String? @map("origin")
20
26
  createdAt DateTime @map("created_at")
21
27
  updatedAt DateTime @map("updated_at")
22
28