Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
17 changes: 10 additions & 7 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,21 @@ async function main(opts: GeneratorOptions = {}) {
'😶‍🌫️ drizzle-zero: Using all tables/columns from Drizzle schema',
);
}
const allTsConfigPaths = await discoverAllTsConfigs(resolvedTsConfigPath);

const tsProject = new Project({
tsConfigFilePath: resolvedTsConfigPath,
skipAddingFilesFromTsConfig: true,
});
for (const tsConfigPath of allTsConfigPaths) {
addSourceFilesFromTsConfigSafe({
tsProject,
tsConfigPath,
debug: Boolean(debug),
});

if (process.env.DRIZZLE_ZERO_EAGER_LOADING) {
const allTsConfigPaths = await discoverAllTsConfigs(resolvedTsConfigPath);
for (const tsConfigPath of allTsConfigPaths) {
addSourceFilesFromTsConfigSafe({
tsProject,
tsConfigPath,
debug: Boolean(debug),
});
}
}

if (configFilePath) {
Expand Down
36 changes: 36 additions & 0 deletions tests/benchmark.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {execSync} from 'node:child_process';
import * as path from 'node:path';
import {bench, describe} from 'vitest';

const cliPath = path.resolve(__dirname, '../dist/cli/index.js');
const fixtureDir = path.resolve(__dirname, 'benchmarks/synthetic-monorepo');
const cmd = `node ${cliPath} generate --config schema/drizzle-zero.config.ts --output /tmp/drizzle-zero-bench-output.ts --suppress-defaults-warning --force`;

// This synthetic benchmark shows a modest ~1.2x speedup because the fixture files
// are small and self-contained. In real monorepos with heavy type dependencies
// (Effect-TS, Drizzle ORM, etc.), the improvement is 4x+ because the eager path
// loads all files AND their transitive type dependencies from node_modules.
//
// Set DRIZZLE_ZERO_EAGER_LOADING=1 to force the old eager loading behavior.

describe('generate', () => {
bench(
'eager (DRIZZLE_ZERO_EAGER_LOADING=1)',
() => {
execSync(cmd, {
cwd: fixtureDir,
stdio: 'ignore',
env: {...process.env, DRIZZLE_ZERO_EAGER_LOADING: '1'},
});
},
{warmupIterations: 1, iterations: 5, time: 0},
);

bench(
'lazy (default)',
() => {
execSync(cmd, {cwd: fixtureDir, stdio: 'ignore'});
},
{warmupIterations: 1, iterations: 5, time: 0},
);
});
13 changes: 13 additions & 0 deletions tests/benchmarks/synthetic-monorepo/pkg-01/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"composite": true,
"strict": true,
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"declaration": true,
"outDir": "dist",
"rootDir": "."
},
"include": ["*.ts"]
}
41 changes: 41 additions & 0 deletions tests/benchmarks/synthetic-monorepo/pkg-01/types-01.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// pkg-01/types-01 - heavy interconnected types


type DeepMerge_0101<T, U> = {
[K in keyof T | keyof U]: K extends keyof T & keyof U
? T[K] extends object ? U[K] extends object ? DeepMerge_0101<T[K], U[K]> : U[K] : U[K]
: K extends keyof T ? T[K] : K extends keyof U ? U[K] : never;
};

interface Entity_01_01 {
id: string;
meta: { created: Date; updated: Date; version: number; tags: string[]; attrs: Record<string, { v: unknown; t: string; ok: boolean }> };
rels: { parent: Entity_01_01 | null; children: Entity_01_01[]; };
cfg: { enabled: boolean; priority: number; rules: Array<{ cond: string; action: string; params: Record<string, unknown>; sub: { items: Array<{ id: string; w: number }> } }> };
d01: { x0101: number; y0101: string; z0101: boolean };
}

type Path_0101<T, D extends unknown[] = []> = D['length'] extends 6 ? never
: T extends object ? { [K in keyof T & string]: K | `${K}.${Path_0101<T[K], [...D, unknown]>}` }[keyof T & string] : never;
type EP_0101 = Path_0101<Entity_01_01>;

type Val_0101<T> = {
[K in keyof T]: T[K] extends string ? { t: 's'; min: number; max: number }
: T[K] extends number ? { t: 'n'; min: number; max: number }
: T[K] extends boolean ? { t: 'b'; def: boolean }
: T[K] extends unknown[] ? { t: 'a'; items: Val_0101<T[K][number]> }
: T[K] extends object ? { t: 'o'; props: Val_0101<T[K]> }
: { t: 'u' };
};
type EV_0101 = Val_0101<Entity_01_01>;

interface Registry_01_01 {
entities: Map<string, Entity_01_01>;
validators: EV_0101;
paths: Set<EP_0101>;
merged: DeepMerge_0101<Entity_01_01, { extra0101: string }>;
}

type CK_0101 = `p01.t01.${'on' | 'off' | 'auto'}.${'dev' | 'stg' | 'prd'}.${'v1' | 'v2' | 'v3'}`;

export type { Entity_01_01, Registry_01_01, CK_0101, EP_0101, EV_0101, DeepMerge_0101 };
41 changes: 41 additions & 0 deletions tests/benchmarks/synthetic-monorepo/pkg-01/types-02.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// pkg-01/types-02 - heavy interconnected types


type DeepMerge_0102<T, U> = {
[K in keyof T | keyof U]: K extends keyof T & keyof U
? T[K] extends object ? U[K] extends object ? DeepMerge_0102<T[K], U[K]> : U[K] : U[K]
: K extends keyof T ? T[K] : K extends keyof U ? U[K] : never;
};

interface Entity_01_02 {
id: string;
meta: { created: Date; updated: Date; version: number; tags: string[]; attrs: Record<string, { v: unknown; t: string; ok: boolean }> };
rels: { parent: Entity_01_02 | null; children: Entity_01_02[]; };
cfg: { enabled: boolean; priority: number; rules: Array<{ cond: string; action: string; params: Record<string, unknown>; sub: { items: Array<{ id: string; w: number }> } }> };
d02: { x0102: number; y0102: string; z0102: boolean };
}

type Path_0102<T, D extends unknown[] = []> = D['length'] extends 6 ? never
: T extends object ? { [K in keyof T & string]: K | `${K}.${Path_0102<T[K], [...D, unknown]>}` }[keyof T & string] : never;
type EP_0102 = Path_0102<Entity_01_02>;

type Val_0102<T> = {
[K in keyof T]: T[K] extends string ? { t: 's'; min: number; max: number }
: T[K] extends number ? { t: 'n'; min: number; max: number }
: T[K] extends boolean ? { t: 'b'; def: boolean }
: T[K] extends unknown[] ? { t: 'a'; items: Val_0102<T[K][number]> }
: T[K] extends object ? { t: 'o'; props: Val_0102<T[K]> }
: { t: 'u' };
};
type EV_0102 = Val_0102<Entity_01_02>;

interface Registry_01_02 {
entities: Map<string, Entity_01_02>;
validators: EV_0102;
paths: Set<EP_0102>;
merged: DeepMerge_0102<Entity_01_02, { extra0102: string }>;
}

type CK_0102 = `p01.t02.${'on' | 'off' | 'auto'}.${'dev' | 'stg' | 'prd'}.${'v1' | 'v2' | 'v3'}`;

export type { Entity_01_02, Registry_01_02, CK_0102, EP_0102, EV_0102, DeepMerge_0102 };
41 changes: 41 additions & 0 deletions tests/benchmarks/synthetic-monorepo/pkg-01/types-03.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// pkg-01/types-03 - heavy interconnected types


type DeepMerge_0103<T, U> = {
[K in keyof T | keyof U]: K extends keyof T & keyof U
? T[K] extends object ? U[K] extends object ? DeepMerge_0103<T[K], U[K]> : U[K] : U[K]
: K extends keyof T ? T[K] : K extends keyof U ? U[K] : never;
};

interface Entity_01_03 {
id: string;
meta: { created: Date; updated: Date; version: number; tags: string[]; attrs: Record<string, { v: unknown; t: string; ok: boolean }> };
rels: { parent: Entity_01_03 | null; children: Entity_01_03[]; };
cfg: { enabled: boolean; priority: number; rules: Array<{ cond: string; action: string; params: Record<string, unknown>; sub: { items: Array<{ id: string; w: number }> } }> };
d03: { x0103: number; y0103: string; z0103: boolean };
}

type Path_0103<T, D extends unknown[] = []> = D['length'] extends 6 ? never
: T extends object ? { [K in keyof T & string]: K | `${K}.${Path_0103<T[K], [...D, unknown]>}` }[keyof T & string] : never;
type EP_0103 = Path_0103<Entity_01_03>;

type Val_0103<T> = {
[K in keyof T]: T[K] extends string ? { t: 's'; min: number; max: number }
: T[K] extends number ? { t: 'n'; min: number; max: number }
: T[K] extends boolean ? { t: 'b'; def: boolean }
: T[K] extends unknown[] ? { t: 'a'; items: Val_0103<T[K][number]> }
: T[K] extends object ? { t: 'o'; props: Val_0103<T[K]> }
: { t: 'u' };
};
type EV_0103 = Val_0103<Entity_01_03>;

interface Registry_01_03 {
entities: Map<string, Entity_01_03>;
validators: EV_0103;
paths: Set<EP_0103>;
merged: DeepMerge_0103<Entity_01_03, { extra0103: string }>;
}

type CK_0103 = `p01.t03.${'on' | 'off' | 'auto'}.${'dev' | 'stg' | 'prd'}.${'v1' | 'v2' | 'v3'}`;

export type { Entity_01_03, Registry_01_03, CK_0103, EP_0103, EV_0103, DeepMerge_0103 };
41 changes: 41 additions & 0 deletions tests/benchmarks/synthetic-monorepo/pkg-01/types-04.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// pkg-01/types-04 - heavy interconnected types


type DeepMerge_0104<T, U> = {
[K in keyof T | keyof U]: K extends keyof T & keyof U
? T[K] extends object ? U[K] extends object ? DeepMerge_0104<T[K], U[K]> : U[K] : U[K]
: K extends keyof T ? T[K] : K extends keyof U ? U[K] : never;
};

interface Entity_01_04 {
id: string;
meta: { created: Date; updated: Date; version: number; tags: string[]; attrs: Record<string, { v: unknown; t: string; ok: boolean }> };
rels: { parent: Entity_01_04 | null; children: Entity_01_04[]; };
cfg: { enabled: boolean; priority: number; rules: Array<{ cond: string; action: string; params: Record<string, unknown>; sub: { items: Array<{ id: string; w: number }> } }> };
d04: { x0104: number; y0104: string; z0104: boolean };
}

type Path_0104<T, D extends unknown[] = []> = D['length'] extends 6 ? never
: T extends object ? { [K in keyof T & string]: K | `${K}.${Path_0104<T[K], [...D, unknown]>}` }[keyof T & string] : never;
type EP_0104 = Path_0104<Entity_01_04>;

type Val_0104<T> = {
[K in keyof T]: T[K] extends string ? { t: 's'; min: number; max: number }
: T[K] extends number ? { t: 'n'; min: number; max: number }
: T[K] extends boolean ? { t: 'b'; def: boolean }
: T[K] extends unknown[] ? { t: 'a'; items: Val_0104<T[K][number]> }
: T[K] extends object ? { t: 'o'; props: Val_0104<T[K]> }
: { t: 'u' };
};
type EV_0104 = Val_0104<Entity_01_04>;

interface Registry_01_04 {
entities: Map<string, Entity_01_04>;
validators: EV_0104;
paths: Set<EP_0104>;
merged: DeepMerge_0104<Entity_01_04, { extra0104: string }>;
}

type CK_0104 = `p01.t04.${'on' | 'off' | 'auto'}.${'dev' | 'stg' | 'prd'}.${'v1' | 'v2' | 'v3'}`;

export type { Entity_01_04, Registry_01_04, CK_0104, EP_0104, EV_0104, DeepMerge_0104 };
41 changes: 41 additions & 0 deletions tests/benchmarks/synthetic-monorepo/pkg-01/types-05.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// pkg-01/types-05 - heavy interconnected types


type DeepMerge_0105<T, U> = {
[K in keyof T | keyof U]: K extends keyof T & keyof U
? T[K] extends object ? U[K] extends object ? DeepMerge_0105<T[K], U[K]> : U[K] : U[K]
: K extends keyof T ? T[K] : K extends keyof U ? U[K] : never;
};

interface Entity_01_05 {
id: string;
meta: { created: Date; updated: Date; version: number; tags: string[]; attrs: Record<string, { v: unknown; t: string; ok: boolean }> };
rels: { parent: Entity_01_05 | null; children: Entity_01_05[]; };
cfg: { enabled: boolean; priority: number; rules: Array<{ cond: string; action: string; params: Record<string, unknown>; sub: { items: Array<{ id: string; w: number }> } }> };
d05: { x0105: number; y0105: string; z0105: boolean };
}

type Path_0105<T, D extends unknown[] = []> = D['length'] extends 6 ? never
: T extends object ? { [K in keyof T & string]: K | `${K}.${Path_0105<T[K], [...D, unknown]>}` }[keyof T & string] : never;
type EP_0105 = Path_0105<Entity_01_05>;

type Val_0105<T> = {
[K in keyof T]: T[K] extends string ? { t: 's'; min: number; max: number }
: T[K] extends number ? { t: 'n'; min: number; max: number }
: T[K] extends boolean ? { t: 'b'; def: boolean }
: T[K] extends unknown[] ? { t: 'a'; items: Val_0105<T[K][number]> }
: T[K] extends object ? { t: 'o'; props: Val_0105<T[K]> }
: { t: 'u' };
};
type EV_0105 = Val_0105<Entity_01_05>;

interface Registry_01_05 {
entities: Map<string, Entity_01_05>;
validators: EV_0105;
paths: Set<EP_0105>;
merged: DeepMerge_0105<Entity_01_05, { extra0105: string }>;
}

type CK_0105 = `p01.t05.${'on' | 'off' | 'auto'}.${'dev' | 'stg' | 'prd'}.${'v1' | 'v2' | 'v3'}`;

export type { Entity_01_05, Registry_01_05, CK_0105, EP_0105, EV_0105, DeepMerge_0105 };
41 changes: 41 additions & 0 deletions tests/benchmarks/synthetic-monorepo/pkg-01/types-06.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// pkg-01/types-06 - heavy interconnected types


type DeepMerge_0106<T, U> = {
[K in keyof T | keyof U]: K extends keyof T & keyof U
? T[K] extends object ? U[K] extends object ? DeepMerge_0106<T[K], U[K]> : U[K] : U[K]
: K extends keyof T ? T[K] : K extends keyof U ? U[K] : never;
};

interface Entity_01_06 {
id: string;
meta: { created: Date; updated: Date; version: number; tags: string[]; attrs: Record<string, { v: unknown; t: string; ok: boolean }> };
rels: { parent: Entity_01_06 | null; children: Entity_01_06[]; };
cfg: { enabled: boolean; priority: number; rules: Array<{ cond: string; action: string; params: Record<string, unknown>; sub: { items: Array<{ id: string; w: number }> } }> };
d06: { x0106: number; y0106: string; z0106: boolean };
}

type Path_0106<T, D extends unknown[] = []> = D['length'] extends 6 ? never
: T extends object ? { [K in keyof T & string]: K | `${K}.${Path_0106<T[K], [...D, unknown]>}` }[keyof T & string] : never;
type EP_0106 = Path_0106<Entity_01_06>;

type Val_0106<T> = {
[K in keyof T]: T[K] extends string ? { t: 's'; min: number; max: number }
: T[K] extends number ? { t: 'n'; min: number; max: number }
: T[K] extends boolean ? { t: 'b'; def: boolean }
: T[K] extends unknown[] ? { t: 'a'; items: Val_0106<T[K][number]> }
: T[K] extends object ? { t: 'o'; props: Val_0106<T[K]> }
: { t: 'u' };
};
type EV_0106 = Val_0106<Entity_01_06>;

interface Registry_01_06 {
entities: Map<string, Entity_01_06>;
validators: EV_0106;
paths: Set<EP_0106>;
merged: DeepMerge_0106<Entity_01_06, { extra0106: string }>;
}

type CK_0106 = `p01.t06.${'on' | 'off' | 'auto'}.${'dev' | 'stg' | 'prd'}.${'v1' | 'v2' | 'v3'}`;

export type { Entity_01_06, Registry_01_06, CK_0106, EP_0106, EV_0106, DeepMerge_0106 };
41 changes: 41 additions & 0 deletions tests/benchmarks/synthetic-monorepo/pkg-01/types-07.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// pkg-01/types-07 - heavy interconnected types


type DeepMerge_0107<T, U> = {
[K in keyof T | keyof U]: K extends keyof T & keyof U
? T[K] extends object ? U[K] extends object ? DeepMerge_0107<T[K], U[K]> : U[K] : U[K]
: K extends keyof T ? T[K] : K extends keyof U ? U[K] : never;
};

interface Entity_01_07 {
id: string;
meta: { created: Date; updated: Date; version: number; tags: string[]; attrs: Record<string, { v: unknown; t: string; ok: boolean }> };
rels: { parent: Entity_01_07 | null; children: Entity_01_07[]; };
cfg: { enabled: boolean; priority: number; rules: Array<{ cond: string; action: string; params: Record<string, unknown>; sub: { items: Array<{ id: string; w: number }> } }> };
d07: { x0107: number; y0107: string; z0107: boolean };
}

type Path_0107<T, D extends unknown[] = []> = D['length'] extends 6 ? never
: T extends object ? { [K in keyof T & string]: K | `${K}.${Path_0107<T[K], [...D, unknown]>}` }[keyof T & string] : never;
type EP_0107 = Path_0107<Entity_01_07>;

type Val_0107<T> = {
[K in keyof T]: T[K] extends string ? { t: 's'; min: number; max: number }
: T[K] extends number ? { t: 'n'; min: number; max: number }
: T[K] extends boolean ? { t: 'b'; def: boolean }
: T[K] extends unknown[] ? { t: 'a'; items: Val_0107<T[K][number]> }
: T[K] extends object ? { t: 'o'; props: Val_0107<T[K]> }
: { t: 'u' };
};
type EV_0107 = Val_0107<Entity_01_07>;

interface Registry_01_07 {
entities: Map<string, Entity_01_07>;
validators: EV_0107;
paths: Set<EP_0107>;
merged: DeepMerge_0107<Entity_01_07, { extra0107: string }>;
}

type CK_0107 = `p01.t07.${'on' | 'off' | 'auto'}.${'dev' | 'stg' | 'prd'}.${'v1' | 'v2' | 'v3'}`;

export type { Entity_01_07, Registry_01_07, CK_0107, EP_0107, EV_0107, DeepMerge_0107 };
Loading