@xwxfox/foxdb 0.0.1 → 0.0.4

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.d.mts CHANGED
@@ -1,5 +1,6 @@
1
- import { TObject as TObject2, TArray, TSchema, TProperties, Static } from "typebox";
2
- import { TObject, TString, TNumber, TInteger, TBoolean, TLiteral } from "typebox";
1
+ import { TSchema as TSchema6 } from "typebox";
2
+ import { TObject as TObject2, TArray, TSchema as TSchema2, TProperties, TOptional as TOptional2, Static } from "typebox";
3
+ import { TObject, TString, TNumber, TInteger, TBoolean, TLiteral, TSchema, TOptional } from "typebox";
3
4
  /** @category Schema */
4
5
  type TScalarSchema = TString | TNumber | TInteger | TBoolean | TLiteral<string> | TLiteral<number> | TLiteral<boolean>;
5
6
  /**
@@ -14,11 +15,24 @@ interface ColumnRef<
14
15
  readonly name: N;
15
16
  readonly schema: S;
16
17
  }
18
+ type UnwrapOptionalSchema<S extends TSchema> = S extends TOptional<infer U> ? U : S;
19
+ type IsScalarSchema<S extends TSchema> = S extends TString ? true : S extends TNumber ? true : S extends TInteger ? true : S extends TBoolean ? true : S extends TLiteral<string | number | boolean> ? true : false;
20
+ type NestedColumnKeys<T extends TSchema & {
21
+ properties: Record<string, TSchema>;
22
+ }> = { [K in keyof T["properties"] & string] : UnwrapOptionalSchema<T["properties"][K]> extends TObject<infer P> ? { [K2 in keyof P & string] : IsScalarSchema<UnwrapOptionalSchema<P[K2]>> extends true ? `${K}__${K2}` : UnwrapOptionalSchema<P[K2]> extends TObject<infer P2> ? { [K3 in keyof P2 & string] : IsScalarSchema<UnwrapOptionalSchema<P2[K3]>> extends true ? `${K}__${K2}__${K3}` : never }[keyof P2 & string] : never }[keyof P & string] : never }[keyof T["properties"] & string];
23
+ type NestedColumnRef<
24
+ T extends TSchema & {
25
+ properties: Record<string, TSchema>;
26
+ },
27
+ N extends string
28
+ > = N extends `${infer K}__${infer K2}__${infer K3}` ? K extends keyof T["properties"] & string ? UnwrapOptionalSchema<T["properties"][K]> extends TObject<infer P> ? K2 extends keyof P & string ? UnwrapOptionalSchema<P[K2]> extends TObject<infer P2> ? K3 extends keyof P2 & string ? UnwrapOptionalSchema<P2[K3]> extends infer U ? U extends TScalarSchema ? ColumnRef<N, U> : never : never : never : never : never : never : never : N extends `${infer K}__${infer K2}` ? K extends keyof T["properties"] & string ? UnwrapOptionalSchema<T["properties"][K]> extends TObject<infer P> ? K2 extends keyof P & string ? UnwrapOptionalSchema<P[K2]> extends infer U ? U extends TScalarSchema ? ColumnRef<N, U> : never : never : never : never : never : never;
17
29
  /**
18
30
  * map of scalar columns to their typed refs
19
31
  * @category Schema
20
32
  */
21
- type ColumnRefs<T extends TObject> = { readonly [K in keyof T["properties"] as T["properties"][K] extends TScalarSchema ? K : never] : T["properties"][K] extends TScalarSchema ? ColumnRef<K & string, T["properties"][K]> : never };
33
+ type ColumnRefs<T extends TSchema & {
34
+ properties: Record<string, TSchema>;
35
+ }> = { readonly [K in keyof T["properties"] as T["properties"][K] extends TScalarSchema ? K : never] : T["properties"][K] extends TScalarSchema ? ColumnRef<K & string, T["properties"][K]> : never } & { readonly [K in NestedColumnKeys<T>] : NestedColumnRef<T, K> };
22
36
  /**
23
37
  * foxdb/src/typed-relation.ts
24
38
  * Runtime + compile-time representation of a single relation.
@@ -39,20 +53,12 @@ interface TypedRelation<
39
53
  kind: K;
40
54
  as: A;
41
55
  }
42
- import { Database, SQLQueryBindings } from "bun:sqlite";
56
+ import { Database, Statement } from "bun:sqlite";
43
57
  /**
44
58
  * prepared sqlite statement
45
59
  * @category Database
46
60
  */
47
- interface BunStatement {
48
- run(...params: SQLQueryBindings[]): {
49
- changes: number;
50
- lastInsertRowid: number | bigint;
51
- };
52
- all(...params: SQLQueryBindings[]): unknown[];
53
- get(...params: SQLQueryBindings[]): unknown;
54
- finalize(): void;
55
- }
61
+ type BunStatement = Statement;
56
62
  /** @category Database */
57
63
  interface DatabaseOptions {
58
64
  /** Path to the SQLite file. Defaults to ":memory:" */
@@ -75,6 +81,8 @@ interface DatabaseOptions {
75
81
  synchronous?: "OFF" | "NORMAL" | "FULL" | "EXTRA";
76
82
  /** PRAGMA mmap_size in bytes. 0 disables. Defaults to 256 MB. */
77
83
  mmapSize?: number;
84
+ /** PRAGMA auto_vacuum level. "incremental" | "full" | false. Defaults to false. */
85
+ autoVacuum?: "incremental" | "full" | false;
78
86
  }
79
87
  /**
80
88
  * sqlite database with statement caching and pragma tuning
@@ -83,6 +91,8 @@ interface DatabaseOptions {
83
91
  declare class BunDatabase {
84
92
  /** underlying bun:sqlite database */
85
93
  readonly db: Database;
94
+ /** scheduler for table maintenance tasks */
95
+ readonly scheduler;
86
96
  constructor(opts?: DatabaseOptions);
87
97
  /** execute ddl (create table, index, etc) */
88
98
  exec(sql: string): void;
@@ -94,46 +104,192 @@ declare class BunDatabase {
94
104
  private readonly _stmtCache;
95
105
  /** get or compile a prepared statement */
96
106
  prepare(sql: string): BunStatement;
107
+ /** set synchronous pragma for bulk load or normal operation */
108
+ setSynchronous(mode: "OFF" | "NORMAL" | "FULL" | "EXTRA"): void;
97
109
  /** clear the statement cache */
98
110
  clearCache(): void;
99
111
  }
112
+ type JsonValue = null | boolean | number | string | JsonValue[] | {
113
+ [key: string]: JsonValue;
114
+ };
115
+ type DBBinary = Uint8Array;
116
+ type DBScalar = string | number | boolean | bigint | null;
117
+ type DBValue = DBScalar | JsonValue | DBBinary;
118
+ type DBRow = Record<string, DBValue | undefined>;
119
+ /** @internal */
120
+ type UnwrapOptional<T> = T extends TOptional2<infer U> ? U : T;
121
+ /** @internal */
122
+ type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
123
+ /** @internal */
124
+ type IsOptionalKey<
125
+ O,
126
+ K extends keyof O
127
+ > = {} extends Pick<O, K> ? true : false;
128
+ /** @internal */
129
+ type MergePath<
130
+ O,
131
+ P extends string
132
+ > = P extends `${infer K}.${infer Rest}` ? K extends keyof O ? IsOptionalKey<O, K> extends true ? { [k in K]? : MergePath<NonNullable<O[K]>, Rest> } : { [k in K] : MergePath<NonNullable<O[K]>, Rest> } : never : P extends keyof O ? IsOptionalKey<O, P> extends true ? { [k in P]? : O[P] } : { [k in P] : O[P] } : never;
133
+ /** @internal */
134
+ type SelectShape<
135
+ T extends TSchema2 & {
136
+ properties: Record<string, TSchema2>;
137
+ },
138
+ S extends readonly string[]
139
+ > = UnionToIntersection<S[number] extends infer P ? P extends string ? MergePath<Infer<T>, P> : never : never>;
140
+ /**
141
+ * scalar values sqlite can store natively
142
+ * @category Advanced
143
+ */
144
+ type SqliteScalar = string | number | boolean | null | bigint;
100
145
  /**
101
146
  * @internal
102
147
  * @category Advanced
103
148
  */
104
- type ScalarProperties<P extends TProperties> = { [K in keyof P as P[K] extends TArray<infer _> ? never : K] : P[K] };
149
+ type ScalarProperties<P extends TProperties> = { [K in keyof P as P[K] extends TArray<infer _> ? never : P[K] extends TObject2 ? never : K] : P[K] };
105
150
  /**
106
151
  * @internal
107
152
  * @category Advanced
108
153
  */
109
- type ArrayOfObjectProperties<P extends TProperties> = { [K in keyof P as P[K] extends TArray<TObject2> ? K : never] : P[K] extends TArray<infer Item> ? Item : never };
154
+ type ArrayOfObjectProperties<P extends TProperties> = { [K in keyof P as P[K] extends TArray<{
155
+ properties: Record<string, TSchema2>;
156
+ }> ? K : never] : P[K] extends TArray<infer Item> ? Item : never };
110
157
  /**
111
158
  * column names that are scalar (not arrays or nested objects)
112
159
  * @category Query Types
113
160
  */
114
- type ScalarKeys<T extends TObject2> = keyof ScalarProperties<T["properties"]> & string;
161
+ type ScalarKeys<T extends TSchema2 & {
162
+ properties: Record<string, TSchema2>;
163
+ }> = keyof ScalarProperties<T["properties"]> & string;
164
+ /** @internal */
165
+ type ObjectKeys<T extends TSchema2 & {
166
+ properties: Record<string, TSchema2>;
167
+ }> = { [K in keyof T["properties"] & string] : UnwrapOptional<T["properties"][K]> extends TObject2 ? K : never }[keyof T["properties"] & string];
168
+ /** @internal */
169
+ type PrimitiveArrayKeys<T extends TSchema2 & {
170
+ properties: Record<string, TSchema2>;
171
+ }> = { [K in keyof T["properties"] & string] : UnwrapOptional<T["properties"][K]> extends TArray<infer Item> ? Item extends TScalarSchema ? K : never : never }[keyof T["properties"] & string];
115
172
  /**
116
173
  * @internal
117
174
  * @category Query Types
118
175
  */
119
- type SubTableKeys<T extends TObject2> = keyof ArrayOfObjectProperties<T["properties"]> & string;
176
+ type SubTableKeys<T extends TSchema2 & {
177
+ properties: Record<string, TSchema2>;
178
+ }> = keyof ArrayOfObjectProperties<T["properties"]> & string;
120
179
  /**
121
180
  * @internal
122
181
  * @category Advanced
123
182
  */
124
- type SubTableScalarPath<T extends TObject2> = { [K in SubTableKeys<T>] : T["properties"][K] extends TArray<infer Item> ? Item extends TObject2 ? `${K}.${ScalarKeys<Item>}` : never : never }[SubTableKeys<T>];
183
+ type SubTableScalarPath<T extends TSchema2 & {
184
+ properties: Record<string, TSchema2>;
185
+ }> = { [K in SubTableKeys<T>] : T["properties"][K] extends TArray<infer Item> ? Item extends {
186
+ properties: Record<string, TSchema2>;
187
+ } ? `${K}.${ScalarKeys<Item>}` : never : never }[SubTableKeys<T>];
125
188
  /**
126
189
  * @internal
127
190
  * @category Advanced
128
191
  */
129
- type ScalarPath<T extends TObject2> = ScalarKeys<T> | SubTableScalarPath<T>;
192
+ type ScalarPath<T extends TSchema2 & {
193
+ properties: Record<string, TSchema2>;
194
+ }> = ScalarKeys<T> | SubTableScalarPath<T>;
195
+ /** @internal */
196
+ type JsonPathLevel1<T extends TSchema2 & {
197
+ properties: Record<string, TSchema2>;
198
+ }> = { [K in keyof T["properties"] & string] : UnwrapOptional<T["properties"][K]> extends {
199
+ properties: Record<string, TSchema2>;
200
+ } ? `${K}.${keyof UnwrapOptional<T["properties"][K]>["properties"] & string}` : never }[keyof T["properties"] & string];
201
+ /** @internal */
202
+ type JsonPathLevel2<T extends TSchema2 & {
203
+ properties: Record<string, TSchema2>;
204
+ }> = { [K in keyof T["properties"] & string] : UnwrapOptional<T["properties"][K]> extends {
205
+ properties: Record<string, TSchema2>;
206
+ } ? { [K2 in keyof UnwrapOptional<T["properties"][K]>["properties"] & string] : UnwrapOptional<UnwrapOptional<T["properties"][K]>["properties"][K2]> extends {
207
+ properties: Record<string, TSchema2>;
208
+ } ? `${K}.${K2}.${keyof UnwrapOptional<UnwrapOptional<T["properties"][K]>["properties"][K2]>["properties"] & string}` : never }[keyof UnwrapOptional<T["properties"][K]>["properties"] & string] : never }[keyof T["properties"] & string];
209
+ /** @internal */
210
+ type JsonPathLevel3<T extends TSchema2 & {
211
+ properties: Record<string, TSchema2>;
212
+ }> = { [K in keyof T["properties"] & string] : UnwrapOptional<T["properties"][K]> extends {
213
+ properties: Record<string, TSchema2>;
214
+ } ? { [K2 in keyof UnwrapOptional<T["properties"][K]>["properties"] & string] : UnwrapOptional<UnwrapOptional<T["properties"][K]>["properties"][K2]> extends {
215
+ properties: Record<string, TSchema2>;
216
+ } ? { [K3 in keyof UnwrapOptional<UnwrapOptional<T["properties"][K]>["properties"][K2]>["properties"] & string] : UnwrapOptional<UnwrapOptional<UnwrapOptional<T["properties"][K]>["properties"][K2]>["properties"][K3]> extends {
217
+ properties: Record<string, TSchema2>;
218
+ } ? `${K}.${K2}.${K3}.${keyof UnwrapOptional<UnwrapOptional<UnwrapOptional<T["properties"][K]>["properties"][K2]>["properties"][K3]>["properties"] & string}` : never }[keyof UnwrapOptional<UnwrapOptional<T["properties"][K]>["properties"][K2]>["properties"] & string] : never }[keyof UnwrapOptional<T["properties"][K]>["properties"] & string] : never }[keyof T["properties"] & string];
219
+ /** @internal */
220
+ type JsonPath<T extends TSchema2 & {
221
+ properties: Record<string, TSchema2>;
222
+ }> = JsonPathLevel1<T> | JsonPathLevel2<T> | JsonPathLevel3<T>;
223
+ /** @internal */
224
+ type ScalarJsonPathLevel1<T extends TSchema2 & {
225
+ properties: Record<string, TSchema2>;
226
+ }> = { [K in keyof T["properties"] & string] : UnwrapOptional<T["properties"][K]> extends TObject2<infer P> ? { [K2 in keyof P & string] : UnwrapOptional<P[K2]> extends TScalarSchema ? `${K}.${K2}` : never }[keyof P & string] : never }[keyof T["properties"] & string];
227
+ /** @internal */
228
+ type ScalarJsonPathLevel2<T extends TSchema2 & {
229
+ properties: Record<string, TSchema2>;
230
+ }> = { [K in keyof T["properties"] & string] : UnwrapOptional<T["properties"][K]> extends TObject2<infer P> ? { [K2 in keyof P & string] : UnwrapOptional<P[K2]> extends TObject2<infer P2> ? { [K3 in keyof P2 & string] : UnwrapOptional<P2[K3]> extends TScalarSchema ? `${K}.${K2}.${K3}` : never }[keyof P2 & string] : never }[keyof P & string] : never }[keyof T["properties"] & string];
231
+ /** @internal */
232
+ type ScalarJsonPathLevel3<T extends TSchema2 & {
233
+ properties: Record<string, TSchema2>;
234
+ }> = { [K in keyof T["properties"] & string] : UnwrapOptional<T["properties"][K]> extends TObject2<infer P> ? { [K2 in keyof P & string] : UnwrapOptional<P[K2]> extends TObject2<infer P2> ? { [K3 in keyof P2 & string] : UnwrapOptional<P2[K3]> extends TObject2<infer P3> ? { [K4 in keyof P3 & string] : UnwrapOptional<P3[K4]> extends TScalarSchema ? `${K}.${K2}.${K3}.${K4}` : never }[keyof P3 & string] : never }[keyof P2 & string] : never }[keyof P & string] : never }[keyof T["properties"] & string];
235
+ /** @internal */
236
+ type ScalarJsonPath<T extends TSchema2 & {
237
+ properties: Record<string, TSchema2>;
238
+ }> = ScalarJsonPathLevel1<T> | ScalarJsonPathLevel2<T> | ScalarJsonPathLevel3<T>;
239
+ /** @internal */
240
+ type PathValue<
241
+ T extends TSchema2 & {
242
+ properties: Record<string, TSchema2>;
243
+ },
244
+ P extends string
245
+ > = P extends `${infer K}.${infer Rest}` ? UnwrapOptional<T["properties"][K]> extends {
246
+ properties: Record<string, TSchema2>;
247
+ } ? Rest extends `${infer K2}.${infer Rest2}` ? UnwrapOptional<UnwrapOptional<T["properties"][K]>["properties"][K2]> extends {
248
+ properties: Record<string, TSchema2>;
249
+ } ? Rest2 extends `${infer K3}.${infer Rest3}` ? UnwrapOptional<UnwrapOptional<UnwrapOptional<T["properties"][K]>["properties"][K2]>["properties"][K3]> extends {
250
+ properties: Record<string, TSchema2>;
251
+ } ? UnwrapOptional<UnwrapOptional<UnwrapOptional<T["properties"][K]>["properties"][K2]>["properties"][K3]>["properties"][Rest3] extends TSchema2 ? Static<UnwrapOptional<UnwrapOptional<UnwrapOptional<T["properties"][K]>["properties"][K2]>["properties"][K3]>["properties"][Rest3]> : never : never : UnwrapOptional<UnwrapOptional<T["properties"][K]>["properties"][K2]>["properties"][Rest2] extends TSchema2 ? Static<UnwrapOptional<UnwrapOptional<T["properties"][K]>["properties"][K2]>["properties"][Rest2]> : never : never : UnwrapOptional<T["properties"][K]>["properties"][Rest] extends TSchema2 ? Static<UnwrapOptional<T["properties"][K]>["properties"][Rest]> : never : never : P extends keyof T["properties"] ? Static<T["properties"][P]> : never;
130
252
  /**
131
253
  * the typescript type that matches a typebox schema
132
254
  * @category Query Types
133
255
  */
134
- type Infer<T extends TSchema> = Static<T>;
256
+ type Infer<T extends TSchema2> = Static<T>;
257
+ /**
258
+ * @internal
259
+ * @category Advanced
260
+ */
261
+ type SubTableItem<
262
+ T extends TSchema2 & {
263
+ properties: Record<string, TSchema2>;
264
+ },
265
+ K extends SubTableKeys<T>
266
+ > = T["properties"][K] extends TArray<infer Item extends TSchema2> ? Static<Item> : never;
135
267
  /** @category Query Types */
136
- type ScalarFilter<V> = V extends string ? {
268
+ type ScalarFilter<V> = unknown extends V ? {
269
+ eq: V;
270
+ } | {
271
+ ne: V;
272
+ } | {
273
+ gt: V;
274
+ } | {
275
+ gte: V;
276
+ } | {
277
+ lt: V;
278
+ } | {
279
+ lte: V;
280
+ } | {
281
+ like: string;
282
+ } | {
283
+ between: [V, V];
284
+ } | {
285
+ in: V[];
286
+ } | {
287
+ notIn: V[];
288
+ } | {
289
+ isNull: true;
290
+ } | {
291
+ isNotNull: true;
292
+ } : V extends string ? {
137
293
  eq: V;
138
294
  } | {
139
295
  ne: V;
@@ -173,6 +329,14 @@ type ScalarFilter<V> = V extends string ? {
173
329
  isNull: true;
174
330
  } | {
175
331
  isNotNull: true;
332
+ } : V extends object ? {
333
+ eq: V;
334
+ } | {
335
+ ne: V;
336
+ } | {
337
+ isNull: true;
338
+ } | {
339
+ isNotNull: true;
176
340
  } : {
177
341
  isNull: true;
178
342
  } | {
@@ -198,13 +362,25 @@ type ScalarFilter<V> = V extends string ? {
198
362
  * @category Query Types
199
363
  * @category Query Types
200
364
  */
201
- type WhereClause<T extends TObject2> = { [K in ScalarKeys<T>]? : ScalarFilter<Static<T["properties"][K]>> };
365
+ type WhereClause<T extends TSchema2 & {
366
+ properties: Record<string, TSchema2>;
367
+ }> = { [K in ScalarKeys<T>]? : ScalarFilter<Static<T["properties"][K]>> } & { [K in ObjectKeys<T>]? : ScalarFilter<Static<T["properties"][K]>> } & { [K in JsonPath<T>]? : ScalarFilter<PathValue<T, K>> } & {
368
+ AND?: WhereClause<T>[];
369
+ OR?: WhereClause<T>[];
370
+ NOT?: WhereClause<T>;
371
+ _raw?: {
372
+ sql: string;
373
+ params: unknown[];
374
+ };
375
+ };
202
376
  /**
203
377
  * sort direction for queries
204
378
  * @category Query Types
205
379
  */
206
- type OrderByClause<T extends TObject2> = {
207
- column: ScalarKeys<T>;
380
+ type OrderByClause<T extends TSchema2 & {
381
+ properties: Record<string, TSchema2>;
382
+ }> = {
383
+ column: ScalarKeys<T> | ScalarJsonPath<T>;
208
384
  direction?: "ASC" | "DESC";
209
385
  };
210
386
  /**
@@ -215,6 +391,18 @@ interface PaginationOptions {
215
391
  limit?: number;
216
392
  offset?: number;
217
393
  }
394
+ interface Cursor {
395
+ column: string;
396
+ value: SqliteScalar;
397
+ }
398
+ interface CursorInput extends Cursor {
399
+ direction: "next" | "prev";
400
+ }
401
+ interface CursorPageResult<T> {
402
+ data: T[];
403
+ nextCursor: Cursor | null;
404
+ prevCursor: Cursor | null;
405
+ }
218
406
  /**
219
407
  * Options for `findMany`, `findPage`, and `findOne`.
220
408
  *
@@ -241,22 +429,36 @@ interface PaginationOptions {
241
429
  * @category Query Types
242
430
  * @category Query Types
243
431
  */
244
- interface FindOptions<T extends TObject2> extends PaginationOptions {
432
+ /** @internal */
433
+ type SelectableKeys<T extends TSchema2 & {
434
+ properties: Record<string, TSchema2>;
435
+ }> = ScalarKeys<T> | ObjectKeys<T> | PrimitiveArrayKeys<T> | JsonPath<T>;
436
+ interface FindOptions<T extends TSchema2 & {
437
+ properties: Record<string, TSchema2>;
438
+ }> extends PaginationOptions {
245
439
  where?: WhereClause<T>;
246
440
  orderBy?: OrderByClause<T> | OrderByClause<T>[];
247
441
  include?: SubTableKeys<T>[];
442
+ select?: SelectableKeys<T>[];
443
+ includeDeleted?: boolean;
444
+ distinct?: boolean;
445
+ distinctOn?: (ScalarKeys<T> | ScalarJsonPath<T>)[];
248
446
  }
249
447
  /**
250
448
  * full record to insert
251
449
  * @category Query Types
252
450
  */
253
- type InsertData<T extends TObject2> = Infer<T>;
451
+ type InsertData<T extends TSchema2 & {
452
+ properties: Record<string, TSchema2>;
453
+ }> = Infer<T>;
254
454
  /**
255
455
  * update payload - must include the primary key
256
456
  * @category Query Types
257
457
  */
258
458
  type UpdateData<
259
- T extends TObject2,
459
+ T extends TSchema2 & {
460
+ properties: Record<string, TSchema2>;
461
+ },
260
462
  PK extends ScalarKeys<T>
261
463
  > = Pick<Infer<T>, PK> & Partial<Omit<Infer<T>, PK>>;
262
464
  /**
@@ -265,8 +467,14 @@ type UpdateData<
265
467
  */
266
468
  interface IndexDefinition {
267
469
  name?: string;
268
- columns: ColumnRef<string, TScalarSchema>[];
470
+ columns: Array<ColumnRef<string, TScalarSchema> | {
471
+ name: string;
472
+ }>;
269
473
  unique?: boolean;
474
+ where?: string;
475
+ include?: Array<ColumnRef<string, TScalarSchema> | {
476
+ name: string;
477
+ }>;
270
478
  }
271
479
  /**
272
480
  * timestamp configuration for a table
@@ -318,10 +526,47 @@ type Entity<
318
526
  * table descriptor passed to createORM
319
527
  * @category Schema
320
528
  */
529
+ interface EvictionConfig {
530
+ maxRows?: number;
531
+ ttlColumn?: string;
532
+ ttlMs?: number;
533
+ lruColumn?: string;
534
+ }
535
+ interface CompressionConfig {
536
+ columns: ColumnRef<string, TScalarSchema>[];
537
+ algorithm: "gzip" | "none";
538
+ }
539
+ interface SoftDeleteConfig {
540
+ column: string;
541
+ }
542
+ type GeneratedColumnConfig = {
543
+ [name: string]: {
544
+ expr: string;
545
+ type: TSchema2;
546
+ };
547
+ };
548
+ type GeneratedColumnValues<C extends GeneratedColumnConfig> = { [K in keyof C & string] : Static<C[K]["type"]> };
549
+ type AugmentSchema<
550
+ T extends TSchema2 & {
551
+ properties: Record<string, TSchema2>;
552
+ },
553
+ G extends GeneratedColumnConfig
554
+ > = TObject2<T["properties"] & GeneratedColumnValues<G>>;
555
+ type QuerySchema<
556
+ T extends TSchema2 & {
557
+ properties: Record<string, TSchema2>;
558
+ },
559
+ G extends GeneratedColumnConfig | undefined
560
+ > = [G] extends [undefined] ? T : [G] extends [GeneratedColumnConfig] ? AugmentSchema<T, G> : T;
321
561
  interface TableConfig<
322
- T extends TObject2 = TObject2,
562
+ T extends TSchema2 & {
563
+ properties: Record<string, TSchema2>;
564
+ } = TSchema2 & {
565
+ properties: Record<string, TSchema2>;
566
+ },
323
567
  PK extends string = string,
324
- TS extends TimestampConfig = undefined
568
+ TS extends TimestampConfig = undefined,
569
+ G extends GeneratedColumnConfig | undefined = undefined
325
570
  > {
326
571
  schema: T;
327
572
  primaryKey: ColumnRef<PK>;
@@ -330,6 +575,10 @@ interface TableConfig<
330
575
  indexes?: IndexDefinition[];
331
576
  }>>;
332
577
  timestamps?: TS;
578
+ eviction?: EvictionConfig;
579
+ compression?: CompressionConfig;
580
+ softDelete?: SoftDeleteConfig;
581
+ generated?: G;
333
582
  }
334
583
  /**
335
584
  * read-only metadata about the current database schema
@@ -347,7 +596,7 @@ interface MetaAccessors {
347
596
  * @category Relations
348
597
  */
349
598
  interface RelationEntry<
350
- Tables extends Record<string, TableConfig<any, any, any>>,
599
+ Tables extends Record<string, TableConfig<any, any, any, any>>,
351
600
  Owner extends keyof Tables,
352
601
  Target extends keyof Tables
353
602
  > {
@@ -359,7 +608,7 @@ interface RelationEntry<
359
608
  * @internal
360
609
  * @category Relations
361
610
  */
362
- type RelationsConfig<Tables extends Record<string, TableConfig<any, any, any>>> = { [K in keyof Tables & string]? : Array<{ [Target in keyof Tables & string] : RelationEntry<Tables, K, Target> }[keyof Tables & string]> };
611
+ type RelationsConfig<Tables extends Record<string, TableConfig<any, any, any, any>>> = { [K in keyof Tables & string]? : Array<{ [Target in keyof Tables & string] : RelationEntry<Tables, K, Target> }[keyof Tables & string]> };
363
612
  /**
364
613
  * @internal
365
614
  * @category Relations
@@ -376,7 +625,7 @@ type ScalarMergeNames<
376
625
  * @category Relations
377
626
  */
378
627
  type ScalarMergeType<
379
- Tables extends Record<string, TableConfig<any, any, any>>,
628
+ Tables extends Record<string, TableConfig<any, any, any, any>>,
380
629
  Rels extends readonly TypedRelation[],
381
630
  Owner extends string,
382
631
  Name extends string
@@ -390,7 +639,7 @@ type ScalarMergeType<
390
639
  * @category Relations
391
640
  */
392
641
  type ScalarMerge<
393
- Tables extends Record<string, TableConfig<any, any, any>>,
642
+ Tables extends Record<string, TableConfig<any, any, any, any>>,
394
643
  Rels extends readonly TypedRelation[],
395
644
  Owner extends string
396
645
  > = { [K in ScalarMergeNames<Rels, Owner>] : ScalarMergeType<Tables, Rels, Owner, K> };
@@ -412,7 +661,7 @@ type SubMergeNames<
412
661
  * @category Relations
413
662
  */
414
663
  type SubMergeType<
415
- Tables extends Record<string, TableConfig<any, any, any>>,
664
+ Tables extends Record<string, TableConfig<any, any, any, any>>,
416
665
  Rels extends readonly TypedRelation[],
417
666
  Owner extends string,
418
667
  Sub extends string,
@@ -428,7 +677,7 @@ type SubMergeType<
428
677
  * @category Relations
429
678
  */
430
679
  type SubMerge<
431
- Tables extends Record<string, TableConfig<any, any, any>>,
680
+ Tables extends Record<string, TableConfig<any, any, any, any>>,
432
681
  Rels extends readonly TypedRelation[],
433
682
  Owner extends string,
434
683
  Sub extends string
@@ -450,8 +699,10 @@ type SubMerge<
450
699
  * @category Relations
451
700
  */
452
701
  type Materialized<
453
- T extends TObject2,
454
- Tables extends Record<string, TableConfig<any, any, any>>,
702
+ T extends TSchema2 & {
703
+ properties: Record<string, TSchema2>;
704
+ },
705
+ Tables extends Record<string, TableConfig<any, any, any, any>>,
455
706
  Rels extends readonly TypedRelation[],
456
707
  Owner extends string
457
708
  > = { [K in keyof Infer<T>] : K extends string ? Infer<T>[K] extends Array<infer Item> ? Array<Item & SubMerge<Tables, Rels, Owner, K>> : Infer<T>[K] : Infer<T>[K] } & ScalarMerge<Tables, Rels, Owner>;
@@ -470,7 +721,9 @@ interface PageResult<T> {
470
721
  * @category Query Types
471
722
  */
472
723
  interface UpsertOptions<
473
- T extends TObject2,
724
+ T extends TSchema2 & {
725
+ properties: Record<string, TSchema2>;
726
+ },
474
727
  PK extends ScalarKeys<T>
475
728
  > {
476
729
  data: InsertData<T>;
@@ -479,6 +732,35 @@ interface UpsertOptions<
479
732
  update?: Array<ScalarKeys<T>>;
480
733
  }
481
734
  /**
735
+ * bulk conditional update
736
+ * @category Query Types
737
+ */
738
+ interface UpdateWhereOptions<
739
+ T extends TSchema2 & {
740
+ properties: Record<string, TSchema2>;
741
+ },
742
+ PK extends ScalarKeys<T>
743
+ > {
744
+ where: WhereClause<T>;
745
+ data: Partial<Omit<Infer<T>, PK>>;
746
+ includeDeleted?: boolean;
747
+ }
748
+ /**
749
+ * bulk upsert with conflict resolution
750
+ * @category Query Types
751
+ */
752
+ interface UpsertManyOptions<
753
+ T extends TSchema2 & {
754
+ properties: Record<string, TSchema2>;
755
+ },
756
+ PK extends ScalarKeys<T>
757
+ > {
758
+ data: InsertData<T>[];
759
+ conflictTarget: PK | PK[];
760
+ /** columns to update on conflict - defaults to all non-pk columns */
761
+ update?: Array<ScalarKeys<T>>;
762
+ }
763
+ /**
482
764
  * a single migration step
483
765
  * @category Migration
484
766
  */
@@ -584,11 +866,121 @@ interface SchemaDiff {
584
866
  * @category Migration
585
867
  */
586
868
  type SyncPolicy = "ignore" | "warn" | "error" | "auto" | ((diff: SchemaDiff, db: BunDatabase) => boolean | void);
869
+ /** @category Query Types */
870
+ type WindowFunction<T extends TSchema2 & {
871
+ properties: Record<string, TSchema2>;
872
+ }> = {
873
+ rowNumber: true;
874
+ } | {
875
+ rank: true;
876
+ } | {
877
+ denseRank: true;
878
+ } | {
879
+ lead: ScalarKeys<T> | ScalarJsonPath<T>;
880
+ offset?: number;
881
+ } | {
882
+ lag: ScalarKeys<T> | ScalarJsonPath<T>;
883
+ offset?: number;
884
+ };
885
+ /** @category Query Types */
886
+ interface WindowQueryOptions<T extends TSchema2 & {
887
+ properties: Record<string, TSchema2>;
888
+ }> {
889
+ partitionBy?: (ScalarKeys<T> | ScalarJsonPath<T>)[];
890
+ orderBy?: OrderByClause<T> | OrderByClause<T>[];
891
+ where?: WhereClause<T>;
892
+ limit?: number;
893
+ select: Record<string, WindowFunction<T>>;
894
+ }
895
+ /** @internal */
896
+ type WindowFunctionResult<
897
+ T extends TSchema2 & {
898
+ properties: Record<string, TSchema2>;
899
+ },
900
+ W extends WindowFunction<T>
901
+ > = W extends {
902
+ lead: infer C extends string;
903
+ } ? PathValue<T, C> | null : W extends {
904
+ lag: infer C extends string;
905
+ } ? PathValue<T, C> | null : number;
906
+ /** @category Query Types */
907
+ type WindowResult<
908
+ T extends TSchema2 & {
909
+ properties: Record<string, TSchema2>;
910
+ },
911
+ W extends Record<string, WindowFunction<T>>
912
+ > = Array<{ [K in keyof W] : WindowFunctionResult<T, W[K]> }>;
913
+ /** @category Query Types */
914
+ type AggregationOp<T extends TSchema2 & {
915
+ properties: Record<string, TSchema2>;
916
+ } = TSchema2 & {
917
+ properties: Record<string, TSchema2>;
918
+ }> = {
919
+ sum?: ScalarKeys<T> | ScalarJsonPath<T>;
920
+ } | {
921
+ count?: "*" | ScalarKeys<T> | ScalarJsonPath<T>;
922
+ } | {
923
+ avg?: ScalarKeys<T> | ScalarJsonPath<T>;
924
+ } | {
925
+ min?: ScalarKeys<T> | ScalarJsonPath<T>;
926
+ } | {
927
+ max?: ScalarKeys<T> | ScalarJsonPath<T>;
928
+ };
929
+ /** @category Query Types */
930
+ interface AggregateOptions<
931
+ T extends TSchema2 & {
932
+ properties: Record<string, TSchema2>;
933
+ },
934
+ A extends Record<string, AggregationOp<T>> = Record<string, AggregationOp<T>>
935
+ > {
936
+ where?: WhereClause<T>;
937
+ groupBy?: readonly (ScalarKeys<T> | ScalarJsonPath<T>)[];
938
+ aggregations: A;
939
+ having?: { [K in keyof A]? : ScalarFilter<unknown> };
940
+ includeDeleted?: boolean;
941
+ }
942
+ /** @internal */
943
+ type AggregationOpResult<
944
+ T extends TSchema2 & {
945
+ properties: Record<string, TSchema2>;
946
+ },
947
+ Op extends AggregationOp<T>
948
+ > = Op extends {
949
+ sum: string;
950
+ } ? number | null : Op extends {
951
+ count: string;
952
+ } ? number : Op extends {
953
+ avg: string;
954
+ } ? number | null : Op extends {
955
+ min: infer C extends string;
956
+ } ? PathValue<T, C> | null : Op extends {
957
+ max: infer C extends string;
958
+ } ? PathValue<T, C> | null : never;
959
+ /** @category Query Types */
960
+ type AggregateResult<
961
+ T extends TSchema2 & {
962
+ properties: Record<string, TSchema2>;
963
+ },
964
+ A extends Record<string, AggregationOp<T>>,
965
+ G extends readonly string[] | undefined = undefined
966
+ > = Array<{ [K in keyof A] : AggregationOpResult<T, A[K]> } & (G extends readonly string[] ? { [K in G[number]] : PathValue<T, K> } : {})>;
967
+ /** @category Observability */
968
+ interface QueryMetrics {
969
+ table: string;
970
+ operation: string;
971
+ sql: string;
972
+ durationMs: number;
973
+ rowCount: number;
974
+ }
975
+ /** @category Observability */
976
+ interface QueryMetricsHook {
977
+ onQuery: (meta: QueryMetrics) => void;
978
+ }
587
979
  /**
588
980
  * specific operations that can be listened to per table
589
981
  * @category Events
590
982
  */
591
- type TableOperation = "insert" | "insertMany" | "update" | "delete" | "deleteWhere" | "upsert" | "findById" | "findMany" | "findOne" | "findPage" | "count" | "flush";
983
+ type TableOperation = "insert" | "insertMany" | "update" | "updateWhere" | "delete" | "deleteWhere" | "upsert" | "upsertMany" | "findById" | "findMany" | "findOne" | "findPage" | "findCursorPage" | "iterate" | "count" | "flush" | "aggregate" | "windowQuery";
592
984
  /**
593
985
  * broad categories for event listening
594
986
  * @category Events
@@ -626,7 +1018,58 @@ type ErrorPolicy = "throw" | "emit" | "emit-swallow" | "crash";
626
1018
  * @category Setup
627
1019
  */
628
1020
  type UnlinkPolicy = true | "onlyGraceful" | "any" | false | undefined;
629
- import { TObject as TObject4 } from "typebox";
1021
+ import { TSchema as TSchema5 } from "typebox";
1022
+ import { TSchema as TSchema3 } from "typebox";
1023
+ /** @category Schema */
1024
+ interface SubTableConfig {
1025
+ indexes?: IndexDefinition[];
1026
+ }
1027
+ interface TableDescriptor<
1028
+ T extends TSchema3 & {
1029
+ properties: Record<string, TSchema3>;
1030
+ },
1031
+ PK extends string,
1032
+ TS extends TimestampConfig = undefined,
1033
+ G extends GeneratedColumnConfig | undefined = undefined
1034
+ > extends TableConfig<T, PK, TS, G> {}
1035
+ interface TableConfigShape<
1036
+ PK extends string,
1037
+ TS extends TimestampConfig,
1038
+ G extends GeneratedColumnConfig | undefined = undefined
1039
+ > {
1040
+ primaryKey: ColumnRef<PK>;
1041
+ indexes?: IndexDefinition[];
1042
+ subTables?: Partial<Record<string, SubTableConfig>>;
1043
+ timestamps?: TS;
1044
+ eviction?: EvictionConfig;
1045
+ compression?: CompressionConfig;
1046
+ softDelete?: SoftDeleteConfig;
1047
+ generated?: G;
1048
+ }
1049
+ /**
1050
+ * Describe a table schema + config for `createORM`.
1051
+ *
1052
+ * @example
1053
+ * ```ts
1054
+ * const UserSchema = Object({ id: String(), name: String(), email: String() });
1055
+ *
1056
+ * const users = table(UserSchema, (s) => ({
1057
+ * primaryKey: s.id,
1058
+ * indexes: [{ columns: [s.email], unique: true }],
1059
+ * timestamps: true, // adds createdAt / updatedAt
1060
+ * }));
1061
+ * ```
1062
+ * @category Schema
1063
+ * @category Schema
1064
+ */
1065
+ declare function table<
1066
+ T extends TSchema3 & {
1067
+ properties: Record<string, TSchema3>;
1068
+ },
1069
+ PK extends string,
1070
+ TS extends TimestampConfig = undefined,
1071
+ G extends GeneratedColumnConfig | undefined = undefined
1072
+ >(schema: T, configure: (columns: ColumnRefs<T>) => TableConfigShape<PK, TS, G>): TableDescriptor<T, PK, TS, G>;
630
1073
  /** @category Events */
631
1074
  type Listener = (payload: unknown) => void;
632
1075
  /**
@@ -660,7 +1103,7 @@ interface LifecycleEventMap {
660
1103
  * typed event listener api
661
1104
  * @category Events
662
1105
  */
663
- interface ORMEvents<Tables extends Record<string, TableConfig<any, any, any>>> {
1106
+ interface ORMEvents<Tables extends Record<string, TableDescriptor<any, any, any, any>>> {
664
1107
  /** listen to lifecycle events (start, ready, shutdown, exit, fail) */
665
1108
  on<K extends (keyof LifecycleEventMap) & string>(event: K, listener: (payload: LifecycleEventMap[K]) => void): () => void;
666
1109
  /** listen to table events (insert, update, findMany, etc) */
@@ -682,7 +1125,7 @@ declare class EventBus {
682
1125
  emit(event: string, payload: unknown): void;
683
1126
  emitIf(event: string, payload: unknown): void;
684
1127
  }
685
- import { TObject as TObject3 } from "typebox";
1128
+ import { TSchema as TSchema4 } from "typebox";
686
1129
  /** @category Advanced */
687
1130
  type SqliteType = "TEXT" | "INTEGER" | "REAL" | "BLOB";
688
1131
  /** @category Advanced */
@@ -692,6 +1135,14 @@ interface ColumnMeta {
692
1135
  nullable: boolean;
693
1136
  /** True if this is actually an `Optional` wrapper */
694
1137
  optional: boolean;
1138
+ /** Path segments for flattened nested columns, e.g. ["Status", "Group"] */
1139
+ path?: string[];
1140
+ /** True if the underlying schema is a boolean (stored as INTEGER) */
1141
+ isBoolean?: boolean;
1142
+ /** True if this is a generated column */
1143
+ generated?: boolean;
1144
+ /** Expression for generated columns */
1145
+ generatedExpr?: string;
695
1146
  }
696
1147
  /** @category Advanced */
697
1148
  interface SubTableMeta {
@@ -700,20 +1151,57 @@ interface SubTableMeta {
700
1151
  /** e.g. "sales__lineItems" */
701
1152
  tableName: string;
702
1153
  /** Schema of a single item in the array */
703
- itemSchema: TObject3;
1154
+ itemSchema: TSchema4 & {
1155
+ properties: Record<string, TSchema4>;
1156
+ };
704
1157
  /** Columns of the sub-table row (owner PK is prepended automatically) */
705
1158
  columns: ColumnMeta[];
1159
+ columnByName: Map<string, ColumnMeta>;
1160
+ columnByPath: Map<string, ColumnMeta>;
706
1161
  }
707
1162
  /** @category Advanced */
708
1163
  interface TableMeta {
709
1164
  tableName: string;
710
1165
  columns: ColumnMeta[];
711
1166
  subTables: SubTableMeta[];
1167
+ /** Map from dotted path → ColumnMeta for O(1) resolution */
1168
+ columnByPath: Map<string, ColumnMeta>;
1169
+ /** Map from column name → ColumnMeta for O(1) resolution */
1170
+ columnByName: Map<string, ColumnMeta>;
712
1171
  }
713
1172
  /** @category Advanced */
714
- declare function introspectTable(tableName: string, schema: TObject3): TableMeta;
1173
+ declare function introspectTable(tableName: string, schema: TSchema4 & {
1174
+ properties: Record<string, TSchema4>;
1175
+ }, generated?: Array<{
1176
+ name: string;
1177
+ expr: string;
1178
+ sqlType?: SqliteType;
1179
+ }>): TableMeta;
715
1180
  /** @category Advanced */
716
1181
  declare function buildCreateTableSQL(meta: TableMeta, primaryKey: string): string[];
1182
+ interface BatchWriterOptions {
1183
+ maxBuffer?: number;
1184
+ flushIntervalMs?: number;
1185
+ }
1186
+ declare class BatchWriter<
1187
+ TInput,
1188
+ TRow extends Record<string, unknown>
1189
+ > {
1190
+ private buffer;
1191
+ private readonly maxBuffer;
1192
+ private readonly tableName;
1193
+ private readonly db;
1194
+ private readonly prepare;
1195
+ private readonly onFlush?;
1196
+ private timer?;
1197
+ constructor(tableName: string, db: BunDatabase, opts: BatchWriterOptions, callbacks: {
1198
+ prepare: (row: TInput) => TRow;
1199
+ onFlush?: (rows: TRow[]) => void;
1200
+ });
1201
+ insert(row: TInput): void;
1202
+ flush(): void;
1203
+ close(): void;
1204
+ }
717
1205
  /**
718
1206
  * Typed repository for a single table. Every entry in your `tables` config
719
1207
  * becomes one of these on the ORM object, fully typed to its schema.
@@ -736,8 +1224,13 @@ declare function buildCreateTableSQL(meta: TableMeta, primaryKey: string): strin
736
1224
  * ```
737
1225
  */
738
1226
  declare class Repository<
739
- T extends TObject4,
740
- PK extends ScalarKeys<T>,
1227
+ TWrite extends TSchema5 & {
1228
+ properties: Record<string, TSchema5>;
1229
+ },
1230
+ TQuery extends TSchema5 & {
1231
+ properties: Record<string, TSchema5>;
1232
+ },
1233
+ PK extends ScalarKeys<TWrite>,
741
1234
  Mat = never,
742
1235
  TS = {}
743
1236
  > {
@@ -752,17 +1245,31 @@ declare class Repository<
752
1245
  private _materialize?;
753
1246
  private _materializeMany?;
754
1247
  private _events?;
1248
+ private _executor;
1249
+ private readonly _codecs;
755
1250
  /** @internal */
756
1251
  setEventBus(bus: EventBus): void;
757
- constructor(tableName: string, config: TableConfig<T, PK>, db: BunDatabase);
1252
+ /** @internal */
1253
+ setMetricsHook(hook?: (meta: QueryMetrics) => void): void;
1254
+ constructor(tableName: string, config: TableConfig<TWrite, PK & string, TimestampConfig, GeneratedColumnConfig | undefined>, db: BunDatabase);
1255
+ /** Ensure PK is selected when include is requested */
1256
+ private _ensureSelectPk;
1257
+ /**
1258
+ * Two-phase row fetch: first get PKs via index, then fetch full rows.
1259
+ * Avoids reading all columns for rows that don't match the WHERE clause.
1260
+ */
1261
+ private _fetchRows;
758
1262
  /** Inject materializers after ORM two-pass init */
759
1263
  setMaterializer(single: (record: Record<string, unknown>) => Record<string, unknown>, many: (records: Record<string, unknown>[]) => Record<string, unknown>[]): void;
760
1264
  /** Wrap raw data in an entity object */
761
1265
  private _wrap;
762
1266
  /** Narrow a parsed schema value to a plain record for dynamic property access */
763
1267
  private _record;
1268
+ /** Validate that a value is a valid SQLite scalar for use as a primary key */
1269
+ private _assertPk;
764
1270
  private _emit;
765
1271
  private _migrate;
1272
+ private _runEviction;
766
1273
  /**
767
1274
  * Validate and coerce data against the schema. Throws on invalid input.
768
1275
  *
@@ -774,7 +1281,7 @@ declare class Repository<
774
1281
  * // user is typed as Infer<typeof UserSchema>
775
1282
  * ```
776
1283
  */
777
- parse(data: unknown): Infer<T>;
1284
+ parse(data: unknown): Infer<TWrite>;
778
1285
  /**
779
1286
  * Type-guard - returns true if data matches the schema.
780
1287
  *
@@ -787,7 +1294,7 @@ declare class Repository<
787
1294
  * }
788
1295
  * ```
789
1296
  */
790
- check(data: unknown): data is Infer<T>;
1297
+ check(data: unknown): data is Infer<TWrite>;
791
1298
  /**
792
1299
  * Insert a single record. Returns the inserted entity.
793
1300
  *
@@ -802,7 +1309,7 @@ declare class Repository<
802
1309
  * });
803
1310
  * ```
804
1311
  */
805
- insert(data: InsertData<T>): Entity<Infer<T>, Mat, TS>;
1312
+ insert(data: InsertData<TWrite>): Entity<Infer<TQuery>, Mat, TS>;
806
1313
  /**
807
1314
  * Insert many records in a single transaction.
808
1315
  *
@@ -816,8 +1323,20 @@ declare class Repository<
816
1323
  * ]);
817
1324
  * ```
818
1325
  */
819
- insertMany(records: InsertData<T>[]): Entity<Infer<T>, Mat, TS>[];
820
- private _insertParsed;
1326
+ insertMany(records: InsertData<TWrite>[]): Entity<Infer<TQuery>, Mat, TS>[];
1327
+ /**
1328
+ * Create a batch writer for high-throughput insert streaming.
1329
+ *
1330
+ * @group Writing
1331
+ *
1332
+ * @example
1333
+ * ```ts
1334
+ * const writer = orm.users.createBatchWriter({ maxBuffer: 500 });
1335
+ * writer.insert({ id: "u1", name: "alice" });
1336
+ * writer.close();
1337
+ * ```
1338
+ */
1339
+ createBatchWriter(opts?: BatchWriterOptions): BatchWriter<InsertData<TWrite>, Record<string, unknown>>;
821
1340
  /**
822
1341
  * Insert or update on conflict. If the record exists (by conflict target),
823
1342
  * it updates the specified columns instead.
@@ -832,7 +1351,25 @@ declare class Repository<
832
1351
  * });
833
1352
  * ```
834
1353
  */
835
- upsert(opts: UpsertOptions<T, PK>): Entity<Infer<T>, Mat, TS>;
1354
+ upsert(opts: UpsertOptions<TWrite, PK>): Entity<Infer<TQuery>, Mat, TS>;
1355
+ /**
1356
+ * Bulk upsert with conflict resolution.
1357
+ * Sub-table rows are reconciled by deleting old rows and re-inserting.
1358
+ *
1359
+ * @group Writing
1360
+ *
1361
+ * @example
1362
+ * ```ts
1363
+ * orm.users.upsertMany({
1364
+ * data: [
1365
+ * { id: "u1", name: "alice" },
1366
+ * { id: "u2", name: "bob" },
1367
+ * ],
1368
+ * conflictTarget: "id",
1369
+ * });
1370
+ * ```
1371
+ */
1372
+ upsertMany(opts: UpsertManyOptions<TWrite, PK>): number;
836
1373
  /**
837
1374
  * Find a record by its primary key.
838
1375
  *
@@ -844,7 +1381,7 @@ declare class Repository<
844
1381
  * if (user) console.log(user.name);
845
1382
  * ```
846
1383
  */
847
- findById(id: Infer<T>[PK]): Entity<Infer<T>, Mat, TS> | null;
1384
+ findById(id: Infer<TQuery>[PK]): Entity<Infer<TQuery>, Mat, TS> | null;
848
1385
  /** Internal findById without event emission - used by update() */
849
1386
  private _findByIdRaw;
850
1387
  /**
@@ -864,7 +1401,17 @@ declare class Repository<
864
1401
  * const orders = orm.orders.findMany({ include: ["lineItems"] });
865
1402
  * ```
866
1403
  */
867
- findMany(opts?: FindOptions<T>): Entity<Infer<T>, Mat, TS>[];
1404
+ findMany<
1405
+ const S extends readonly SelectableKeys<TQuery>[],
1406
+ const I extends readonly SubTableKeys<TQuery>[]
1407
+ >(opts: FindOptions<TQuery> & {
1408
+ select: S;
1409
+ include: I;
1410
+ }): (SelectShape<TQuery, S> & TS & { [K in I[number]] : SubTableItem<TQuery, K>[] })[];
1411
+ findMany<const S extends readonly SelectableKeys<TQuery>[]>(opts: FindOptions<TQuery> & {
1412
+ select: S;
1413
+ }): (SelectShape<TQuery, S> & TS)[];
1414
+ findMany(opts?: FindOptions<TQuery>): Entity<Infer<TQuery>, Mat, TS>[];
868
1415
  /**
869
1416
  * Find many with total count - useful for pagination.
870
1417
  *
@@ -882,7 +1429,43 @@ declare class Repository<
882
1429
  * // page.limit, page.offset - what you passed in
883
1430
  * ```
884
1431
  */
885
- findPage(opts?: FindOptions<T>): PageResult<Entity<Infer<T>, Mat, TS>>;
1432
+ findPage<
1433
+ const S extends readonly SelectableKeys<TQuery>[],
1434
+ const I extends readonly SubTableKeys<TQuery>[]
1435
+ >(opts: FindOptions<TQuery> & {
1436
+ select: S;
1437
+ include: I;
1438
+ }): PageResult<SelectShape<TQuery, S> & TS & { [K in I[number]] : SubTableItem<TQuery, K>[] }>;
1439
+ findPage<const S extends readonly SelectableKeys<TQuery>[]>(opts: FindOptions<TQuery> & {
1440
+ select: S;
1441
+ }): PageResult<SelectShape<TQuery, S> & TS>;
1442
+ findPage(opts?: FindOptions<TQuery>): PageResult<Entity<Infer<TQuery>, Mat, TS>>;
1443
+ /**
1444
+ * Cursor-based pagination (seek method). Avoids OFFSET degradation on
1445
+ * large tables by using a boundary value from the previous page.
1446
+ *
1447
+ * @group Reading
1448
+ *
1449
+ * @example
1450
+ * ```ts
1451
+ * const page = orm.orders.findCursorPage({
1452
+ * orderBy: { column: "DocumentDate", direction: "DESC" },
1453
+ * limit: 25,
1454
+ * });
1455
+ *
1456
+ * const next = orm.orders.findCursorPage({
1457
+ * orderBy: { column: "DocumentDate", direction: "DESC" },
1458
+ * cursor: page.nextCursor!,
1459
+ * limit: 25,
1460
+ * });
1461
+ * ```
1462
+ */
1463
+ findCursorPage(opts: {
1464
+ where?: WhereClause<TQuery>;
1465
+ orderBy: OrderByClause<TQuery>;
1466
+ cursor?: CursorInput;
1467
+ limit?: number;
1468
+ }): CursorPageResult<Entity<Infer<TQuery>, Mat, TS>>;
886
1469
  /**
887
1470
  * Find a single record matching the given filters. Equivalent to `findMany`
888
1471
  * with `limit: 1`, but returns the entity directly (or `null`).
@@ -896,7 +1479,45 @@ declare class Repository<
896
1479
  * });
897
1480
  * ```
898
1481
  */
899
- findOne(opts?: FindOptions<T>): Entity<Infer<T>, Mat, TS> | null;
1482
+ findOne<
1483
+ const S extends readonly SelectableKeys<TQuery>[],
1484
+ const I extends readonly SubTableKeys<TQuery>[]
1485
+ >(opts: FindOptions<TQuery> & {
1486
+ select: S;
1487
+ include: I;
1488
+ }): (SelectShape<TQuery, S> & TS & { [K in I[number]] : SubTableItem<TQuery, K>[] }) | null;
1489
+ findOne<const S extends readonly SelectableKeys<TQuery>[]>(opts: FindOptions<TQuery> & {
1490
+ select: S;
1491
+ }): (SelectShape<TQuery, S> & TS) | null;
1492
+ findOne(opts?: FindOptions<TQuery>): Entity<Infer<TQuery>, Mat, TS> | null;
1493
+ /**
1494
+ * Iterate over records matching the given filters, yielding one row at a time.
1495
+ * Sub-tables are hydrated in windows to keep memory stable.
1496
+ *
1497
+ * @group Reading
1498
+ *
1499
+ * @example
1500
+ * ```ts
1501
+ * for (const user of orm.users.iterate({ where: { active: { eq: true } } })) {
1502
+ * console.log(user.name);
1503
+ * }
1504
+ * ```
1505
+ */
1506
+ iterate<
1507
+ const S extends readonly SelectableKeys<TQuery>[],
1508
+ const I extends readonly SubTableKeys<TQuery>[]
1509
+ >(opts: FindOptions<TQuery> & {
1510
+ select: S;
1511
+ include: I;
1512
+ }): Generator<SelectShape<TQuery, S> & TS & { [K in I[number]] : SubTableItem<TQuery, K>[] }>;
1513
+ iterate<const I extends readonly SubTableKeys<TQuery>[]>(opts: FindOptions<TQuery> & {
1514
+ include: I;
1515
+ }): Generator<Entity<Infer<TQuery>, Mat, TS> & { [K in I[number]] : SubTableItem<TQuery, K>[] }>;
1516
+ iterate<const S extends readonly SelectableKeys<TQuery>[]>(opts: FindOptions<TQuery> & {
1517
+ select: S;
1518
+ }): Generator<SelectShape<TQuery, S> & TS>;
1519
+ iterate(opts?: FindOptions<TQuery>): Generator<Entity<Infer<TQuery>, Mat, TS>>;
1520
+ private _hydrateWindow;
900
1521
  /**
901
1522
  * Find many with resolved relations (n+1 safe). If you have cross-table
902
1523
  * relations configured, this eagerly loads them in a single batch query.
@@ -911,7 +1532,7 @@ declare class Repository<
911
1532
  * }
912
1533
  * ```
913
1534
  */
914
- findManyMaterialized(opts?: FindOptions<T>): Entity<Infer<T>, Mat, TS>[];
1535
+ findManyMaterialized(opts?: FindOptions<TQuery>): Entity<Infer<TQuery>, Mat, TS>[];
915
1536
  /**
916
1537
  * Count records matching the given filters.
917
1538
  *
@@ -923,7 +1544,54 @@ declare class Repository<
923
1544
  * const adults = orm.users.count({ age: { gte: 18 } });
924
1545
  * ```
925
1546
  */
926
- count(where?: WhereClause<T>): number;
1547
+ count(where?: WhereClause<TQuery>): number;
1548
+ /**
1549
+ * Run aggregate queries (sum, count, avg, min, max) with optional
1550
+ * grouping and filtering.
1551
+ *
1552
+ * @group Reading
1553
+ *
1554
+ * @example
1555
+ * ```ts
1556
+ * orm.orders.aggregate({
1557
+ * aggregations: { total: { sum: "amount" } },
1558
+ * });
1559
+ *
1560
+ * orm.orders.aggregate({
1561
+ * groupBy: ["status"],
1562
+ * aggregations: { count: { count: "*" }, avgAmount: { avg: "amount" } },
1563
+ * });
1564
+ * ```
1565
+ */
1566
+ aggregate<
1567
+ const A extends Record<string, AggregationOp<TQuery>>,
1568
+ const G extends readonly (ScalarKeys<TQuery> | ScalarJsonPath<TQuery>)[] | undefined = undefined
1569
+ >(opts: AggregateOptions<TQuery, A> & {
1570
+ groupBy?: G;
1571
+ }): AggregateResult<TQuery, A, G>;
1572
+ /**
1573
+ * Run window function queries (rowNumber, rank, denseRank, lead, lag)
1574
+ * with partitioning and ordering.
1575
+ *
1576
+ * @group Reading
1577
+ *
1578
+ * @example
1579
+ * ```ts
1580
+ * orm.orders.windowQuery({
1581
+ * partitionBy: ["Status__Group"],
1582
+ * orderBy: [{ column: "DocumentDate", direction: "DESC" }],
1583
+ * select: {
1584
+ * rowNumber: { rowNumber: true },
1585
+ * rank: { rank: true },
1586
+ * leadTotal: { lead: "TotalTurnover", offset: 1 },
1587
+ * },
1588
+ * limit: 100,
1589
+ * });
1590
+ * ```
1591
+ */
1592
+ windowQuery<const W extends Record<string, WindowFunction<TQuery>>>(opts: WindowQueryOptions<TQuery> & {
1593
+ select: W;
1594
+ }): WindowResult<TQuery, W>;
927
1595
  /**
928
1596
  * Update a record - must include the primary key. Returns the updated
929
1597
  * entity, or `null` if no record matched.
@@ -935,7 +1603,22 @@ declare class Repository<
935
1603
  * orm.users.update({ id: "u1", name: "alice smith" });
936
1604
  * ```
937
1605
  */
938
- update(data: UpdateData<T, PK>): Entity<Infer<T>, Mat, TS> | null;
1606
+ update(data: UpdateData<TWrite, PK>): Entity<Infer<TQuery>, Mat, TS> | null;
1607
+ /**
1608
+ * Update multiple records matching the given filters.
1609
+ * Returns the number of rows changed.
1610
+ *
1611
+ * @group Writing
1612
+ *
1613
+ * @example
1614
+ * ```ts
1615
+ * orm.users.updateWhere({
1616
+ * where: { status: { eq: "pending" } },
1617
+ * data: { status: { group: "completed" } },
1618
+ * });
1619
+ * ```
1620
+ */
1621
+ updateWhere(opts: UpdateWhereOptions<TWrite, PK>): number;
939
1622
  /**
940
1623
  * Delete a record by its primary key. Returns `true` if a record was deleted.
941
1624
  *
@@ -946,7 +1629,7 @@ declare class Repository<
946
1629
  * const deleted = orm.users.deleteById("u1");
947
1630
  * ```
948
1631
  */
949
- deleteById(id: Infer<T>[PK]): boolean;
1632
+ deleteById(id: Infer<TWrite>[PK]): boolean;
950
1633
  /**
951
1634
  * Delete records matching the given filters. Returns the number of rows deleted.
952
1635
  *
@@ -957,7 +1640,7 @@ declare class Repository<
957
1640
  * const removed = orm.users.deleteWhere({ status: { eq: "banned" } });
958
1641
  * ```
959
1642
  */
960
- deleteWhere(where: WhereClause<T>): number;
1643
+ deleteWhere(where: WhereClause<TQuery>): number;
961
1644
  /**
962
1645
  * Truncate the table and all sub-tables. Deletes all rows but keeps the schema.
963
1646
  *
@@ -993,9 +1676,9 @@ declare class Repository<
993
1676
  * );
994
1677
  * ```
995
1678
  */
996
- raw<R = unknown>(sql: string, ...params: unknown[]): R[];
1679
+ raw<R = DBRow>(sql: string, ...params: DBValue[]): R[];
997
1680
  }
998
- declare class RelationBuilder<Tables extends Record<string, TableConfig<any, any, any>>> {
1681
+ declare class RelationBuilder<Tables extends Record<string, TableDescriptor<any, any, any, any>>> {
999
1682
  private readonly tables;
1000
1683
  private readonly relations;
1001
1684
  constructor(tables: Tables);
@@ -1025,16 +1708,14 @@ declare class RelationBuilder<Tables extends Record<string, TableConfig<any, any
1025
1708
  build(): TypedRelation[];
1026
1709
  }
1027
1710
  /** @category Relations */
1028
- declare function createRelationBuilder<T extends Record<string, TableConfig<any, any, any>>>(tables: T): RelationBuilder<T>;
1711
+ declare function createRelationBuilder<T extends Record<string, TableDescriptor<any, any, any, any>>>(tables: T): RelationBuilder<T>;
1029
1712
  import { Static as Static2 } from "typebox";
1030
1713
  declare const SchemaHashSchema: unknown;
1031
- /** @category Database */
1032
1714
  declare const SchemaJSONSchema: unknown;
1033
1715
  declare const TablesSchema: unknown;
1034
1716
  declare const RelationsSchema: unknown;
1035
1717
  declare const VersionSchema: unknown;
1036
1718
  type SchemaHash = Static2<typeof SchemaHashSchema>;
1037
- /** @category Database */
1038
1719
  type SchemaJSON = Static2<typeof SchemaJSONSchema>;
1039
1720
  type TablesList = Static2<typeof TablesSchema>;
1040
1721
  type RelationsList = Static2<typeof RelationsSchema>;
@@ -1051,7 +1732,7 @@ declare class MetaStore {
1051
1732
  private getRow;
1052
1733
  private setRow;
1053
1734
  private getValidatedJSON;
1054
- private setValidatedJSON;
1735
+ private validateAndSetJSON;
1055
1736
  getString(key: string): string | null;
1056
1737
  setString(key: string, value: string): void;
1057
1738
  getJSON<T>(key: string): T | null;
@@ -1075,7 +1756,7 @@ declare class MetaStore {
1075
1756
  * @category Lifecycle
1076
1757
  */
1077
1758
  interface ORMContext<
1078
- T extends Record<string, TableConfig<any, any, any>> = Record<string, TableConfig<any, any, any>>,
1759
+ T extends Record<string, TableDescriptor<any, any, any, any>> = Record<string, TableDescriptor<any, any, any, any>>,
1079
1760
  Rels extends readonly TypedRelation[] = readonly TypedRelation[]
1080
1761
  > {
1081
1762
  orm: foxdb<T, Rels>;
@@ -1093,7 +1774,7 @@ interface ORMContext<
1093
1774
  * @category Lifecycle
1094
1775
  */
1095
1776
  type LifecycleHook<
1096
- T extends Record<string, TableConfig<any, any, any>> = Record<string, TableConfig<any, any, any>>,
1777
+ T extends Record<string, TableDescriptor<any, any, any, any>> = Record<string, TableDescriptor<any, any, any, any>>,
1097
1778
  Rels extends readonly TypedRelation[] = readonly TypedRelation[]
1098
1779
  > = (ctx: ORMContext<T, Rels>) => void | Promise<void>;
1099
1780
  /**
@@ -1101,7 +1782,7 @@ type LifecycleHook<
1101
1782
  * @category Lifecycle
1102
1783
  */
1103
1784
  declare class LifecycleManager<
1104
- T extends Record<string, TableConfig<any, any, any>> = Record<string, TableConfig<any, any, any>>,
1785
+ T extends Record<string, TableDescriptor<any, any, any, any>> = Record<string, TableDescriptor<any, any, any, any>>,
1105
1786
  Rels extends readonly TypedRelation[] = readonly TypedRelation[]
1106
1787
  > {
1107
1788
  private startHooks;
@@ -1142,6 +1823,10 @@ interface CreateORMBaseOptions {
1142
1823
  busyTimeout?: number;
1143
1824
  synchronous?: "OFF" | "NORMAL" | "FULL" | "EXTRA";
1144
1825
  mmapSize?: number;
1826
+ autoVacuum?: "incremental" | "full" | false;
1827
+ vacuumIntervalMs?: number;
1828
+ /** disable fsync during large initial loads */
1829
+ bulkLoadMode?: boolean;
1145
1830
  }
1146
1831
  /**
1147
1832
  * Options passed to `createORM`.
@@ -1172,7 +1857,7 @@ interface CreateORMBaseOptions {
1172
1857
  * ```
1173
1858
  */
1174
1859
  interface CreateORMOptions<
1175
- T extends Record<string, TableConfig<any, any, any>> = Record<string, TableConfig<any, any, any>>,
1860
+ T extends Record<string, TableDescriptor<any, any, any, any>> = Record<string, TableDescriptor<any, any, any, any>>,
1176
1861
  Rels extends readonly TypedRelation[] = readonly TypedRelation[]
1177
1862
  > extends CreateORMBaseOptions {
1178
1863
  /** table schemas */
@@ -1215,6 +1900,8 @@ interface CreateORMOptions<
1215
1900
  errorPolicy?: ErrorPolicy;
1216
1901
  /** delete db files on exit */
1217
1902
  unlinkDbFilesOnExit?: UnlinkPolicy;
1903
+ /** observability hooks */
1904
+ hooks?: QueryMetricsHook;
1218
1905
  }
1219
1906
  /**
1220
1907
  * The ORM object returned by `createORM`.
@@ -1266,15 +1953,19 @@ interface CreateORMOptions<
1266
1953
  * ```
1267
1954
  */
1268
1955
  type foxdb<
1269
- Tables extends Record<string, TableConfig<any, any, any>>,
1956
+ Tables extends Record<string, TableDescriptor<any, any, any, any>>,
1270
1957
  Rels extends readonly TypedRelation[] = readonly TypedRelation[]
1271
- > = { [K in keyof Tables] : Tables[K] extends TableConfig<infer T, infer PK, infer TS> ? Repository<T, PK extends ScalarKeys<T> ? PK : never, Materialized<T, Tables, Rels, K & string>, TimestampShape<TS>> : never } & {
1958
+ > = { [K in keyof Tables] : Tables[K] extends TableDescriptor<infer TWrite extends TSchema6 & {
1959
+ properties: Record<string, TSchema6>;
1960
+ }, infer PKName extends string, infer Timestamps, infer G extends GeneratedColumnConfig | undefined> ? Repository<TWrite, QuerySchema<TWrite, G>, PKName extends ScalarKeys<TWrite> ? PKName : never, Materialized<TWrite, Tables, Rels, K & string>, TimestampShape<Timestamps>> : never } & {
1272
1961
  /** run a transaction */
1273
1962
  _transaction<R>(fn: () => R): R;
1274
1963
  /** close the database */
1275
1964
  _close(): void;
1276
1965
  /** read-only metadata */
1277
1966
  _meta: MetaAccessors;
1967
+ /** toggle bulk-load mode (disables synchronous fsync) */
1968
+ _setBulkLoadMode(enabled: boolean): void;
1278
1969
  /** resolve relations for a single record */
1279
1970
  _materialize<Owner extends keyof Tables & string>(ownerTable: Owner, record: Record<string, unknown>): Record<string, unknown>;
1280
1971
  /** resolve relations for many records (n+1 safe) */
@@ -1290,69 +1981,9 @@ type foxdb<
1290
1981
  };
1291
1982
  /** create a typed orm instance backed by sqlite */
1292
1983
  declare function createORM<
1293
- const T extends Record<string, TableConfig<any, any, any>>,
1984
+ const T extends Record<string, TableDescriptor<any, any, any, any>>,
1294
1985
  const Rels extends readonly TypedRelation[] = readonly TypedRelation[]
1295
1986
  >(opts: CreateORMOptions<T, Rels>): foxdb<T, Rels>;
1296
- import { TObject as TObject5 } from "typebox";
1297
- /** @category Schema */
1298
- interface SubTableConfig {
1299
- indexes?: IndexDefinition[];
1300
- }
1301
- /** @category Schema */
1302
- interface TableDescriptor<
1303
- T extends TObject5,
1304
- PK extends string,
1305
- TS extends TimestampConfig = undefined
1306
- > extends TableConfig<T, PK, TS> {}
1307
- /** @category Schema */
1308
- interface TableConfigShape<
1309
- PK extends string,
1310
- TS extends TimestampConfig
1311
- > {
1312
- primaryKey: ColumnRef<PK>;
1313
- indexes?: IndexDefinition[];
1314
- subTables?: Partial<Record<string, SubTableConfig>>;
1315
- timestamps?: TS;
1316
- }
1317
- /**
1318
- * Describe a table schema + config for `createORM`.
1319
- *
1320
- * @example
1321
- * ```ts
1322
- * const UserSchema = Object({ id: String(), name: String(), email: String() });
1323
- *
1324
- * const users = table(UserSchema, (s) => ({
1325
- * primaryKey: s.id,
1326
- * indexes: [{ columns: [s.email], unique: true }],
1327
- * timestamps: true, // adds createdAt / updatedAt
1328
- * }));
1329
- * ```
1330
- * @category Schema
1331
- * @category Schema
1332
- */
1333
- declare function table<
1334
- T extends TObject5,
1335
- PK extends string,
1336
- const TS extends boolean
1337
- >(schema: T, configure: (columns: ColumnRefs<T>) => TableConfigShape<PK, TS> & {
1338
- timestamps: TS;
1339
- }): TableDescriptor<T, PK, TS>;
1340
- /** @category Schema */
1341
- declare function table<
1342
- T extends TObject5,
1343
- PK extends string,
1344
- const TS extends {
1345
- createdAt?: string;
1346
- updatedAt?: string;
1347
- }
1348
- >(schema: T, configure: (columns: ColumnRefs<T>) => TableConfigShape<PK, TS> & {
1349
- timestamps: TS;
1350
- }): TableDescriptor<T, PK, TS>;
1351
- /** @category Schema */
1352
- declare function table<
1353
- T extends TObject5,
1354
- PK extends string
1355
- >(schema: T, configure: (columns: ColumnRefs<T>) => TableConfigShape<PK, undefined>): TableDescriptor<T, PK, undefined>;
1356
1987
  declare function migrate(opts: MigrateOptions): Promise<void>;
1357
1988
  /** @category Migration */
1358
1989
  declare function createMigration(name: string, migrationsDir: string): string;
@@ -1460,4 +2091,4 @@ interface DesiredTable {
1460
2091
  declare function computeDiff(desired: DesiredTable[], actual: InspectorTable[]): SchemaDiff;
1461
2092
  /** @category Migration */
1462
2093
  declare function applySync(diff: SchemaDiff, db: BunDatabase, policy: SyncPolicy, desired: DesiredTable[]): void;
1463
- export { withTrace, table, resolveTimestampNames, raise, migrate, introspectTable, inspectSchema, inspectAllTables, foxdb, createRelationBuilder, createORM, createMigration, computeDiff, buildCreateTableSQL, applySync, WhereClause, UpsertOptions, UpdateData, UnlinkPolicy, TypedRelation, TraceEntry, TimestampShape, TimestampConfig2 as TimestampNamesConfig, TableOperation, TableMeta, TableEventPayload, TableEventOperation, TableDescriptor, TableConfigShape, TableConfig, TScalarSchema, SyncPolicy, SubTableScalarPath, SubTableMeta, SubTableKeys, SubTableConfig, SubMergeType, SubMergeNames, SubMerge, SqliteType, SchemaJSONSchema, SchemaJSON, SchemaDiff, SchemaChange, ScalarProperties, ScalarPath, ScalarMergeType, ScalarMergeNames, ScalarMerge, ScalarKeys, ScalarFilter, Repository, RelationsConfig, RelationEntry, RelationBuilder, PageResult, OrderByClause, ORMEvents, ORMErrorContext, ORMError, ORMContext, Migration, MigrateOptions, MetaStore, Materialized, Listener, LifecycleManager, LifecycleHook, LifecycleEventMap, InspectorTable, InspectorIndex, InspectorColumn, InsertData, Infer, IndexDefinition, FindOptions, EventBus, ErrorPolicy2 as ErrorPolicy, Entity, DesiredTable, DatabaseOptions, DEFAULT_TIMESTAMP_NAMES, CreateORMOptions, CreateORMBaseOptions, ColumnRefs, ColumnRef, ColumnMeta, BunStatement, BunDatabase, BroadOperation, ArrayOfObjectProperties };
2094
+ export { withTrace, table, resolveTimestampNames, raise, migrate, introspectTable, inspectSchema, inspectAllTables, foxdb, createRelationBuilder, createORM, createMigration, computeDiff, buildCreateTableSQL, applySync, WhereClause, UpsertOptions, UpdateData, UnlinkPolicy, TypedRelation, TraceEntry, TimestampShape, TimestampConfig2 as TimestampNamesConfig, TableOperation, TableMeta, TableEventPayload, TableEventOperation, TableDescriptor, TableConfigShape, TableConfig, TScalarSchema, SyncPolicy, SubTableScalarPath, SubTableMeta, SubTableKeys, SubTableConfig, SubMergeType, SubMergeNames, SubMerge, SqliteType, SchemaJSONSchema, SchemaJSON, SchemaDiff, SchemaChange, ScalarProperties, ScalarPath, ScalarMergeType, ScalarMergeNames, ScalarMerge, ScalarKeys, ScalarFilter, Repository, RelationsConfig, RelationEntry, RelationBuilder, QueryMetricsHook, QueryMetrics, PageResult, OrderByClause, ORMEvents, ORMErrorContext, ORMError, ORMContext, Migration, MigrateOptions, MetaStore, Materialized, Listener, LifecycleManager, LifecycleHook, LifecycleEventMap, InspectorTable, InspectorIndex, InspectorColumn, InsertData, Infer, IndexDefinition, GeneratedColumnConfig, FindOptions, EventBus, ErrorPolicy2 as ErrorPolicy, Entity, DesiredTable, DatabaseOptions, DEFAULT_TIMESTAMP_NAMES, CreateORMOptions, CreateORMBaseOptions, ColumnRefs, ColumnRef, ColumnMeta, BunStatement, BunDatabase, BroadOperation, BatchWriterOptions, BatchWriter, ArrayOfObjectProperties, AggregationOp, AggregateOptions };