Changelog - 2026-07-14
Database Driver Bundling Fix
Breaking Change Bug Fix EnhancementIn one line. Relational datasources now declare their driver as a class reference instead of a string, so a bundler only packages the driver you actually use.
What changed
- Bundled applications no longer pull in the unused driver. Any application that bundled -
bun build --compile, esbuild, webpack, rollup - used to fail or bloat because bothpgandpostgreswere pulled into the output, even for apps that only installed one of them. @datasource({ driver })now takes a class, not a string. A string can never carry an optional package into a bundle; a class reference can. This is the two-line change described in Breaking changes below.- A pool-only datasource now gets a working connector. Previously it silently had no connector at all, so every query on it read through an
undefinedvalue. - A bare
pg.Clientis no longer silently accepted where aPoolis required. Passing one used to compile and run, but broke per-transaction connection handling under load. - Search datasources (Typesense, Meilisearch) no longer accept a
driveroption. It was never read - drop it if you have it.
Who is affected
- Every application with a relational (Postgres) datasource - needs the two-line migration below. Nothing else in the framework changes.
- Applications that bundle their build - fixed for free, once the driver is migrated to a class.
- Applications with a search-only datasource that sets
driver- drop the option; it now has no effect and may fail to type-check. - Anyone with a custom driver calling
useDriver()- still works, but its constructor now takes{ client }instead of{ pool }. - Everyone else - no action needed.
Breaking changes
Datasource driver: string to class.
typescript
// BEFORE
import { DataSourceDrivers, datasource } from '@venizia/ignis';
import { drizzle } from 'drizzle-orm/node-postgres';
@datasource({ driver: DataSourceDrivers.NODE_POSTGRES })
export class PostgresDataSource extends BasePostgresDataSource<IConfigs> {
override configure(): ValueOrPromise<void> {
const schema = this.getSchema();
this.client = new Pool(this.settings);
this.connector = drizzle({ client: this.client, schema });
}
}
// AFTER
import { datasource } from '@venizia/ignis';
import { NodePostgresDriver } from '@venizia/ignis/postgres/node-postgres';
@datasource({ driver: NodePostgresDriver })
export class PostgresDataSource extends BasePostgresDataSource<IConfigs> {
override configure(): ValueOrPromise<void> {
this.client = new Pool(this.settings); // that is all - the base builds the connector
}
}| If you | Then |
|---|---|
write @datasource({ driver: DataSourceDrivers.NODE_POSTGRES }) | name the class instead: @datasource({ driver: NodePostgresDriver }) |
build the Drizzle connector by hand in configure() | delete that line - the base class builds it |
call useDriver({ driver: new NodePostgresDriver({ pool }) }) | the constructor now takes { client } |
pass a bare pg.Client | construct a Pool instead - a Client was never supported and now fails at construction |
carry --external postgres in a bundler config | remove it - no longer necessary |
write @datasource({ driver: DataSourceDrivers.TYPESENSE }) on a search datasource | drop driver entirely: @datasource() |
| maintain a custom driver | keep calling useDriver() - unchanged and still public |
Details
- Root cause: a dynamic
import()defers execution, not packaging. Every bundler statically resolves the specifier and includes the target regardless, so the previous "import whichever driver you need at runtime" approach never actually kept the other one out of the bundle. - A bundling test (
bundle/optional-peers.test.ts) now builds four fixtures and checks the actual bundle output, so this class of bug cannot regress silently again. DataSourceDriversstill exists as an identity constant for names and validation - it is just no longer a configuration channel for choosing a driver.
| Package | Tests passing |
|---|---|
| inversion | 96 |
| helpers | 1014 |
| boot | 81 |
| core | 1518 |
Zero type errors, zero lint findings across all four packages; all nine examples type-check.