TypeORM
The TypeORM StateStore adapter. Register the durable entities on your DataSource, pass it to TypeOrmStateStore, and run on Postgres, MySQL/MariaDB or SQLite — with auto-schema on boot or an ensureTypeOrmDurableSchema helper for your own migration.
@dudousxd/nestjs-durable-store-typeorm persists runs and step checkpoints through TypeORM, on
any dialect it supports — Postgres, MySQL/MariaDB, SQLite. It declares typeorm as a peer and
rides the DataSource you already configure.
pnpm add @dudousxd/nestjs-durable-store-typeorm1. Register the durable entities
The adapter uses dataSource.getRepository(...) for each durable table, so its entities must be
registered on your DataSource. The package exports them as ENTITIES:
import { DataSource } from 'typeorm';
import { ENTITIES as DURABLE_ENTITIES } from '@dudousxd/nestjs-durable-store-typeorm';
export const dataSource = new DataSource({
type: 'postgres',
// …host, database, etc.
entities: [...DURABLE_ENTITIES, /* your own entities */],
});ENTITIES is the five durable_* entities the engine owns — WorkflowRunEntity,
StepCheckpointEntity, RunAttributeEntity, SignalWaiterEntity, BufferedSignalEntity.
Column naming
ENTITIES uses the canonical snake_case columns. To read a table an older, unpinned setup wrote in
camelCase, or to supply a custom mapping, build the schemas with durableEntities({ naming }) instead:
import { durableEntities } from '@dudousxd/nestjs-durable-store-typeorm';
export const dataSource = new DataSource({
type: 'postgres',
entities: [...durableEntities({ naming: 'snake_case' }), /* your own entities */],
});naming accepts 'snake_case' (default), 'preserve' (the legacy camelCase this adapter used to
produce), or (property: string) => string. Same contract as the MikroORM adapter's
durableEntities — the physical column names must agree
across adapters so a run written by one store stays readable by another.
2. Wire the store into the module
TypeOrmStateStore takes the DataSource:
import { DataSource } from 'typeorm';
import { TypeOrmStateStore } from '@dudousxd/nestjs-durable-store-typeorm';
DurableModule.forRootAsync({
inject: [DataSource],
useFactory: (ds: DataSource) => ({
store: new TypeOrmStateStore(ds),
transport,
}),
});Schema: auto on boot, or your own migration
With auto-schema on (the default), the module calls store.ensureSchema(), which runs the
dialect-aware ensureTypeOrmDurableSchema(dataSource) — additive, never destructive. It quotes
identifiers per driver, uses varchar(191) for keyed columns (MySQL can't index a text column)
and longtext for the free-form JSON payloads on MySQL (its text caps at 64 KB and would
silently truncate a large fan-out step's events).
To own the schema yourself, disable it and call the helper from a migration:
import { ensureTypeOrmDurableSchema } from '@dudousxd/nestjs-durable-store-typeorm';
export class AddDurableTables implements MigrationInterface {
async up(q: QueryRunner) {
await ensureTypeOrmDurableSchema(q.connection);
}
}DurableModule.forRoot({ store, transport, autoSchema: false });Three gaps versus the MikroORM adapter, worth knowing before you pick this one:
- No
withScope. This adapter doesn't implement the tenant-namespace-scoped-view capability, soDurableModule'sscopeReads: trueoption is a silent no-op here — the store keeps returning every namespace's runs regardless of the setting. Only the MikroORM adapter honors it today. - No fingerprint gate.
ensureTypeOrmDurableSchemare-runs itsCREATE TABLE IF NOT EXISTS/ALTER TABLE ... ADD COLUMNdiff on every boot, unconditionally — there's no marker-table short-circuit like MikroORM'sdurable_schema_metafingerprint check. It's a much lighter diff than MikroORM's whole-schema introspection (this one only ever touches the durable tables), but it's still real DDL-planning work repeated on every pod's every boot rather than skipped on a steady-state boot where nothing changed. - No
pruneTerminalRuns. This adapter doesn't implement the retention capability, so aretentionpolicy configured against it no-ops with a warning instead of actually deleting terminal runs. Only the MikroORM adapter implements it today.
MikroORM
The reference StateStore adapter. Register the durable entities with your MikroORM config, pass the ORM to MikroOrmStateStore, and run on Postgres, MySQL or SQLite — with auto-schema on boot or an ensure* helper for your own migration.
Prisma
The Prisma StateStore adapter. Add the durable models to your schema.prisma, prisma generate, and pass your PrismaClient to PrismaStateStore. Schema is owned by Prisma Migrate — there is no auto-schema.