@minnowdb/core 0.0.1 → 0.1.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.
Files changed (218) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +27 -1
  3. package/dist/block-format/block.d.ts +46 -0
  4. package/dist/block-format/block.d.ts.map +1 -0
  5. package/dist/block-format/block.js +244 -0
  6. package/dist/block-format/block.js.map +1 -0
  7. package/dist/block-format/checksum.d.ts +7 -0
  8. package/dist/block-format/checksum.d.ts.map +1 -0
  9. package/dist/block-format/checksum.js +56 -0
  10. package/dist/block-format/checksum.js.map +1 -0
  11. package/dist/block-format/codecs.d.ts +24 -0
  12. package/dist/block-format/codecs.d.ts.map +1 -0
  13. package/dist/block-format/codecs.js +102 -0
  14. package/dist/block-format/codecs.js.map +1 -0
  15. package/dist/block-format/column.d.ts +8 -0
  16. package/dist/block-format/column.d.ts.map +1 -0
  17. package/dist/block-format/column.js +166 -0
  18. package/dist/block-format/column.js.map +1 -0
  19. package/dist/block-format/index.d.ts +7 -0
  20. package/dist/block-format/index.d.ts.map +1 -0
  21. package/dist/block-format/index.js +7 -0
  22. package/dist/block-format/index.js.map +1 -0
  23. package/dist/block-format/physical.d.ts +20 -0
  24. package/dist/block-format/physical.d.ts.map +1 -0
  25. package/dist/block-format/physical.js +439 -0
  26. package/dist/block-format/physical.js.map +1 -0
  27. package/dist/block-format/types.d.ts +93 -0
  28. package/dist/block-format/types.d.ts.map +1 -0
  29. package/dist/block-format/types.js +2 -0
  30. package/dist/block-format/types.js.map +1 -0
  31. package/dist/engine/artifact-cache.d.ts +22 -0
  32. package/dist/engine/artifact-cache.d.ts.map +1 -0
  33. package/dist/engine/artifact-cache.js +68 -0
  34. package/dist/engine/artifact-cache.js.map +1 -0
  35. package/dist/engine/batch.d.ts +28 -0
  36. package/dist/engine/batch.d.ts.map +1 -0
  37. package/dist/engine/batch.js +38 -0
  38. package/dist/engine/batch.js.map +1 -0
  39. package/dist/engine/buffered-writer.d.ts +43 -0
  40. package/dist/engine/buffered-writer.d.ts.map +1 -0
  41. package/dist/engine/buffered-writer.js +158 -0
  42. package/dist/engine/buffered-writer.js.map +1 -0
  43. package/dist/engine/catalog.d.ts +82 -0
  44. package/dist/engine/catalog.d.ts.map +1 -0
  45. package/dist/engine/catalog.js +47 -0
  46. package/dist/engine/catalog.js.map +1 -0
  47. package/dist/engine/client.d.ts +211 -0
  48. package/dist/engine/client.d.ts.map +1 -0
  49. package/dist/engine/client.js +538 -0
  50. package/dist/engine/client.js.map +1 -0
  51. package/dist/engine/coordinator.d.ts +17 -0
  52. package/dist/engine/coordinator.d.ts.map +1 -0
  53. package/dist/engine/coordinator.js +60 -0
  54. package/dist/engine/coordinator.js.map +1 -0
  55. package/dist/engine/database.d.ts +661 -0
  56. package/dist/engine/database.d.ts.map +1 -0
  57. package/dist/engine/database.js +10313 -0
  58. package/dist/engine/database.js.map +1 -0
  59. package/dist/engine/defaults.d.ts +33 -0
  60. package/dist/engine/defaults.d.ts.map +1 -0
  61. package/dist/engine/defaults.js +87 -0
  62. package/dist/engine/defaults.js.map +1 -0
  63. package/dist/engine/dsl/db.d.ts +137 -0
  64. package/dist/engine/dsl/db.d.ts.map +1 -0
  65. package/dist/engine/dsl/db.js +161 -0
  66. package/dist/engine/dsl/db.js.map +1 -0
  67. package/dist/engine/dsl/expression.d.ts +172 -0
  68. package/dist/engine/dsl/expression.d.ts.map +1 -0
  69. package/dist/engine/dsl/expression.js +397 -0
  70. package/dist/engine/dsl/expression.js.map +1 -0
  71. package/dist/engine/dsl/index.d.ts +8 -0
  72. package/dist/engine/dsl/index.d.ts.map +1 -0
  73. package/dist/engine/dsl/index.js +7 -0
  74. package/dist/engine/dsl/index.js.map +1 -0
  75. package/dist/engine/dsl/live-query.d.ts +45 -0
  76. package/dist/engine/dsl/live-query.d.ts.map +1 -0
  77. package/dist/engine/dsl/live-query.js +116 -0
  78. package/dist/engine/dsl/live-query.js.map +1 -0
  79. package/dist/engine/dsl/mutations.d.ts +123 -0
  80. package/dist/engine/dsl/mutations.d.ts.map +1 -0
  81. package/dist/engine/dsl/mutations.js +241 -0
  82. package/dist/engine/dsl/mutations.js.map +1 -0
  83. package/dist/engine/dsl/select-query-builder.d.ts +148 -0
  84. package/dist/engine/dsl/select-query-builder.d.ts.map +1 -0
  85. package/dist/engine/dsl/select-query-builder.js +377 -0
  86. package/dist/engine/dsl/select-query-builder.js.map +1 -0
  87. package/dist/engine/dsl/sql-tag.d.ts +46 -0
  88. package/dist/engine/dsl/sql-tag.d.ts.map +1 -0
  89. package/dist/engine/dsl/sql-tag.js +85 -0
  90. package/dist/engine/dsl/sql-tag.js.map +1 -0
  91. package/dist/engine/dsl/types.d.ts +133 -0
  92. package/dist/engine/dsl/types.d.ts.map +1 -0
  93. package/dist/engine/dsl/types.js +9 -0
  94. package/dist/engine/dsl/types.js.map +1 -0
  95. package/dist/engine/errors.d.ts +55 -0
  96. package/dist/engine/errors.d.ts.map +1 -0
  97. package/dist/engine/errors.js +81 -0
  98. package/dist/engine/errors.js.map +1 -0
  99. package/dist/engine/fts.d.ts +93 -0
  100. package/dist/engine/fts.d.ts.map +1 -0
  101. package/dist/engine/fts.js +273 -0
  102. package/dist/engine/fts.js.map +1 -0
  103. package/dist/engine/group-index.d.ts +32 -0
  104. package/dist/engine/group-index.d.ts.map +1 -0
  105. package/dist/engine/group-index.js +366 -0
  106. package/dist/engine/group-index.js.map +1 -0
  107. package/dist/engine/index.d.ts +13 -0
  108. package/dist/engine/index.d.ts.map +1 -0
  109. package/dist/engine/index.js +12 -0
  110. package/dist/engine/index.js.map +1 -0
  111. package/dist/engine/join-index.d.ts +12 -0
  112. package/dist/engine/join-index.d.ts.map +1 -0
  113. package/dist/engine/join-index.js +217 -0
  114. package/dist/engine/join-index.js.map +1 -0
  115. package/dist/engine/live.d.ts +86 -0
  116. package/dist/engine/live.d.ts.map +1 -0
  117. package/dist/engine/live.js +289 -0
  118. package/dist/engine/live.js.map +1 -0
  119. package/dist/engine/memory.d.ts +37 -0
  120. package/dist/engine/memory.d.ts.map +1 -0
  121. package/dist/engine/memory.js +119 -0
  122. package/dist/engine/memory.js.map +1 -0
  123. package/dist/engine/optimizer.d.ts +20 -0
  124. package/dist/engine/optimizer.d.ts.map +1 -0
  125. package/dist/engine/optimizer.js +1170 -0
  126. package/dist/engine/optimizer.js.map +1 -0
  127. package/dist/engine/query-cache.d.ts +10 -0
  128. package/dist/engine/query-cache.d.ts.map +1 -0
  129. package/dist/engine/query-cache.js +58 -0
  130. package/dist/engine/query-cache.js.map +1 -0
  131. package/dist/engine/query.d.ts +844 -0
  132. package/dist/engine/query.d.ts.map +1 -0
  133. package/dist/engine/query.js +7450 -0
  134. package/dist/engine/query.js.map +1 -0
  135. package/dist/engine/schema-wire.d.ts +92 -0
  136. package/dist/engine/schema-wire.d.ts.map +1 -0
  137. package/dist/engine/schema-wire.js +115 -0
  138. package/dist/engine/schema-wire.js.map +1 -0
  139. package/dist/engine/schema.d.ts +394 -0
  140. package/dist/engine/schema.d.ts.map +1 -0
  141. package/dist/engine/schema.js +709 -0
  142. package/dist/engine/schema.js.map +1 -0
  143. package/dist/engine/sort-keys.d.ts +36 -0
  144. package/dist/engine/sort-keys.d.ts.map +1 -0
  145. package/dist/engine/sort-keys.js +60 -0
  146. package/dist/engine/sort-keys.js.map +1 -0
  147. package/dist/engine/sql-json.d.ts +30 -0
  148. package/dist/engine/sql-json.d.ts.map +1 -0
  149. package/dist/engine/sql-json.js +120 -0
  150. package/dist/engine/sql-json.js.map +1 -0
  151. package/dist/engine/sql-semantics.d.ts +31 -0
  152. package/dist/engine/sql-semantics.d.ts.map +1 -0
  153. package/dist/engine/sql-semantics.js +121 -0
  154. package/dist/engine/sql-semantics.js.map +1 -0
  155. package/dist/engine/vector.d.ts +87 -0
  156. package/dist/engine/vector.d.ts.map +1 -0
  157. package/dist/engine/vector.js +4227 -0
  158. package/dist/engine/vector.js.map +1 -0
  159. package/dist/engine/worker-host.d.ts +48 -0
  160. package/dist/engine/worker-host.d.ts.map +1 -0
  161. package/dist/engine/worker-host.js +501 -0
  162. package/dist/engine/worker-host.js.map +1 -0
  163. package/dist/engine/worker.d.ts +2 -0
  164. package/dist/engine/worker.d.ts.map +1 -0
  165. package/dist/engine/worker.js +14 -0
  166. package/dist/engine/worker.js.map +1 -0
  167. package/dist/index.d.ts +2 -0
  168. package/dist/index.d.ts.map +1 -0
  169. package/dist/index.js +2 -0
  170. package/dist/index.js.map +1 -0
  171. package/dist/plan/index.d.ts +17 -0
  172. package/dist/plan/index.d.ts.map +1 -0
  173. package/dist/plan/index.js +17 -0
  174. package/dist/plan/index.js.map +1 -0
  175. package/dist/storage/fixture-shape.d.ts +42 -0
  176. package/dist/storage/fixture-shape.d.ts.map +1 -0
  177. package/dist/storage/fixture-shape.js +146 -0
  178. package/dist/storage/fixture-shape.js.map +1 -0
  179. package/dist/storage/index.d.ts +5 -0
  180. package/dist/storage/index.d.ts.map +1 -0
  181. package/dist/storage/index.js +5 -0
  182. package/dist/storage/index.js.map +1 -0
  183. package/dist/storage/indexeddb.d.ts +139 -0
  184. package/dist/storage/indexeddb.d.ts.map +1 -0
  185. package/dist/storage/indexeddb.js +3161 -0
  186. package/dist/storage/indexeddb.js.map +1 -0
  187. package/dist/storage/memory.d.ts +121 -0
  188. package/dist/storage/memory.d.ts.map +1 -0
  189. package/dist/storage/memory.js +1455 -0
  190. package/dist/storage/memory.js.map +1 -0
  191. package/dist/storage/snapshot.d.ts +108 -0
  192. package/dist/storage/snapshot.d.ts.map +1 -0
  193. package/dist/storage/snapshot.js +276 -0
  194. package/dist/storage/snapshot.js.map +1 -0
  195. package/dist/storage/types.d.ts +895 -0
  196. package/dist/storage/types.d.ts.map +1 -0
  197. package/dist/storage/types.js +1549 -0
  198. package/dist/storage/types.js.map +1 -0
  199. package/dist/testing/index.d.ts +76 -0
  200. package/dist/testing/index.d.ts.map +1 -0
  201. package/dist/testing/index.js +233 -0
  202. package/dist/testing/index.js.map +1 -0
  203. package/dist/testing/seeds.d.ts +11 -0
  204. package/dist/testing/seeds.d.ts.map +1 -0
  205. package/dist/testing/seeds.js +50 -0
  206. package/dist/testing/seeds.js.map +1 -0
  207. package/dist/transactions/index.d.ts +148 -0
  208. package/dist/transactions/index.d.ts.map +1 -0
  209. package/dist/transactions/index.js +662 -0
  210. package/dist/transactions/index.js.map +1 -0
  211. package/dist/worker-protocol/index.d.ts +84 -0
  212. package/dist/worker-protocol/index.d.ts.map +1 -0
  213. package/dist/worker-protocol/index.js +117 -0
  214. package/dist/worker-protocol/index.js.map +1 -0
  215. package/package.json +66 -16
  216. package/sql-feature-matrix.json +1275 -0
  217. package/index.d.ts +0 -1
  218. package/index.js +0 -1
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Write-time default filling. For a default-bearing column (always non-nullable), a null or
3
+ * absent slot means "generate" and an explicit value passes through untouched. Pure defaults
4
+ * (now, literals) are filled here before validation; auto-increment slots stay null until the
5
+ * write path reserves a range from storage, keeping generation atomic across concurrent
6
+ * writers. Function defaults never reach the engine — the typed facade fills them before the
7
+ * batch crosses the boundary.
8
+ */
9
+ import type { RowIdRange, TableColumnRecord, TableRecord } from "../storage/types.js";
10
+ import type { BatchValue, ColumnarBatch } from "./batch.js";
11
+ /** The deferred part of a fill: slots that need storage-reserved auto-increment values. */
12
+ export interface AutoIncrementFill {
13
+ readonly column: TableColumnRecord;
14
+ /** Row indexes whose value must come from the reserved range, in row order. */
15
+ readonly missingIndexes: readonly number[];
16
+ /** One past the largest explicit value in the batch, so generated keys never collide with it. */
17
+ readonly atLeast: bigint;
18
+ }
19
+ export interface FilledBatch {
20
+ readonly batch: ColumnarBatch;
21
+ /** Full written vectors, input row order, for columns where at least one slot was generated. */
22
+ readonly generated: Map<string, BatchValue[]>;
23
+ /** Present whenever the table has an auto-increment column, even if every value is explicit —
24
+ * the counter still bumps past the explicit maximum in the same atomic step. */
25
+ readonly autoIncrement?: AutoIncrementFill;
26
+ }
27
+ export declare function fillColumnDefaults(table: TableRecord, input: ColumnarBatch, now: () => Date, knownRowCount?: number): FilledBatch;
28
+ /**
29
+ * Writes the reserved range into the batch's null slots. The vector is the fresh array
30
+ * `fillColumnDefaults` created for this fill, never a caller-owned one.
31
+ */
32
+ export declare function patchAutoIncrementValues(input: ColumnarBatch, fill: AutoIncrementFill, range: RowIdRange): void;
33
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/engine/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE5D,2FAA2F;AAC3F,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,+EAA+E;IAC/E,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,iGAAiG;IACjG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,gGAAgG;IAChG,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IAC9C;oFACgF;IAChF,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC;CAC5C;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,MAAM,IAAI,EACf,aAAa,CAAC,EAAE,MAAM,GACrB,WAAW,CA8Db;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,UAAU,GAChB,IAAI,CASN"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Write-time default filling. For a default-bearing column (always non-nullable), a null or
3
+ * absent slot means "generate" and an explicit value passes through untouched. Pure defaults
4
+ * (now, literals) are filled here before validation; auto-increment slots stay null until the
5
+ * write path reserves a range from storage, keeping generation atomic across concurrent
6
+ * writers. Function defaults never reach the engine — the typed facade fills them before the
7
+ * batch crosses the boundary.
8
+ */
9
+ export function fillColumnDefaults(table, input, now, knownRowCount) {
10
+ const defaultColumns = table.columns.filter((column) => column.defaultValue !== undefined);
11
+ if (defaultColumns.length === 0)
12
+ return { batch: input, generated: new Map() };
13
+ const rowCount = knownRowCount ?? Object.values(input.columns).find((values) => values.length > 0)?.length ?? 0;
14
+ if (rowCount === 0)
15
+ return { batch: input, generated: new Map() };
16
+ const columns = { ...input.columns };
17
+ const generated = new Map();
18
+ let autoIncrement;
19
+ let nowValue;
20
+ for (const column of defaultColumns) {
21
+ const defaultValue = column.defaultValue;
22
+ if (defaultValue === undefined)
23
+ continue;
24
+ const provided = input.columns[column.name];
25
+ if (defaultValue.kind === "autoincrement") {
26
+ const missingIndexes = [];
27
+ let maxExplicit = 0n;
28
+ for (let index = 0; index < rowCount; index += 1) {
29
+ const value = provided?.[index] ?? null;
30
+ if (value === null) {
31
+ missingIndexes.push(index);
32
+ continue;
33
+ }
34
+ if (typeof value !== "number" || !Number.isSafeInteger(value)) {
35
+ throw new TypeError(`${column.name}[${String(index)}] must be a whole number in the safe integer range`);
36
+ }
37
+ if (BigInt(value) > maxExplicit)
38
+ maxExplicit = BigInt(value);
39
+ }
40
+ if (missingIndexes.length > 0) {
41
+ columns[column.name] =
42
+ provided === undefined ? new Array(rowCount).fill(null) : [...provided];
43
+ }
44
+ autoIncrement = { column, missingIndexes, atLeast: maxExplicit + 1n };
45
+ continue;
46
+ }
47
+ const values = provided === undefined ? new Array(rowCount).fill(null) : [...provided];
48
+ let filled = false;
49
+ for (let index = 0; index < rowCount; index += 1) {
50
+ if ((values[index] ?? null) !== null)
51
+ continue;
52
+ filled = true;
53
+ switch (defaultValue.kind) {
54
+ case "now":
55
+ values[index] = nowValue ??= now();
56
+ break;
57
+ case "literal":
58
+ values[index] = defaultValue.value;
59
+ break;
60
+ }
61
+ }
62
+ if (filled) {
63
+ columns[column.name] = values;
64
+ generated.set(column.name, values);
65
+ }
66
+ }
67
+ return {
68
+ batch: { columns },
69
+ generated,
70
+ ...(autoIncrement === undefined ? {} : { autoIncrement }),
71
+ };
72
+ }
73
+ /**
74
+ * Writes the reserved range into the batch's null slots. The vector is the fresh array
75
+ * `fillColumnDefaults` created for this fill, never a caller-owned one.
76
+ */
77
+ export function patchAutoIncrementValues(input, fill, range) {
78
+ const vector = input.columns[fill.column.name];
79
+ fill.missingIndexes.forEach((rowIndex, offset) => {
80
+ const value = range.start + BigInt(offset);
81
+ if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
82
+ throw new RangeError(`Auto-increment exhausted the safe integer range: ${fill.column.name}`);
83
+ }
84
+ vector[rowIndex] = Number(value);
85
+ });
86
+ }
87
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/engine/defaults.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,137 @@
1
+ import { type CompiledQuery, type CompiledStatement, type QueryResult, type QueryRow, type QueryValue } from "../query.js";
2
+ import { type AnyTable, type SchemaDefinition } from "../schema.js";
3
+ import { type LiveSubscriptionHandle } from "./live-query.js";
4
+ import { DeleteQueryBuilder, InsertQueryBuilder, UpdateQueryBuilder } from "./mutations.js";
5
+ import { SelectQueryBuilder, type AliasedSelectQuery, type CteDefinition } from "./select-query-builder.js";
6
+ import { type AnyRow, type ContextWithTable, type InferDatabase, type TableExpression } from "./types.js";
7
+ /**
8
+ * The Kysely-style facade. `Minnow<DB>` wraps either the in-worker `MinnowDatabase` or the
9
+ * main-thread `MinnowDatabaseClient` (both satisfy `DslDriver` structurally) and hands out
10
+ * typed builders: `selectFrom`, `insertInto`, `updateTable`, `deleteFrom`, `with`, and live
11
+ * queries through the builders' `.live()`. `DB` is derived from the runtime schema with
12
+ * `InferDatabase<typeof appSchema>`; migrations stay on the driver (`driver.migrate(schema)`).
13
+ */
14
+ export interface DriverLiveSet {
15
+ subscribe(query: string | {
16
+ kind: "typed-query";
17
+ plan: CompiledQuery;
18
+ }, options: {
19
+ onChange(result: QueryResult): void;
20
+ onError?(error: unknown): void;
21
+ onComplete?(): void;
22
+ }): Promise<LiveSubscriptionHandle>;
23
+ close(): void | Promise<void>;
24
+ }
25
+ export interface DslLiveOptions {
26
+ /** BroadcastChannel name for cross-tab commit hints (worker client). */
27
+ channelName?: string;
28
+ pollIntervalMs?: number;
29
+ }
30
+ /** The slice of MinnowDatabase / MinnowDatabaseClient the facade drives. */
31
+ export interface DslDriver {
32
+ run<TRow>(query: {
33
+ kind: "typed-query";
34
+ plan: CompiledQuery;
35
+ __row?: TRow;
36
+ }): Promise<TRow[]>;
37
+ insertBatch(tableName: string, rows: ReadonlyArray<Readonly<Record<string, QueryValue>>>): Promise<{
38
+ rowCount: number;
39
+ generatedColumns?: Record<string, QueryValue[]>;
40
+ }>;
41
+ upsertBatch(tableName: string, rows: ReadonlyArray<Readonly<Record<string, QueryValue>>>): Promise<{
42
+ rowCount: number;
43
+ generatedColumns?: Record<string, QueryValue[]>;
44
+ }>;
45
+ runStatement(statement: CompiledStatement, options?: {
46
+ returning?: readonly string[] | "*";
47
+ }): Promise<{
48
+ kind: string;
49
+ rowCount?: number;
50
+ returnedRows?: QueryRow[];
51
+ }>;
52
+ execute(sql: string, params?: readonly QueryValue[]): Promise<{
53
+ kind: string;
54
+ result?: {
55
+ rows: QueryRow[];
56
+ };
57
+ }>;
58
+ liveQueries(options?: DslLiveOptions): DriverLiveSet;
59
+ }
60
+ export interface MinnowOptions {
61
+ /**
62
+ * The runtime schema the database was migrated with. Inserts then pad omitted nullable
63
+ * columns with null (the engine's batch API takes every column); without it, an insert must
64
+ * list every column itself.
65
+ */
66
+ schema?: SchemaDefinition<readonly AnyTable[]>;
67
+ /** Options for the shared live-query set behind `.live()`; created lazily on first use. */
68
+ live?: DslLiveOptions;
69
+ }
70
+ type EmptyContext = Record<never, AnyRow>;
71
+ /**
72
+ * Creates the typed facade. The recommended form names the database type once, so every hover,
73
+ * error, and emitted declaration prints `Minnow<DB>` instead of the fully expanded schema —
74
+ * which matters as soon as the schema has more than a table or two:
75
+ *
76
+ * ```ts
77
+ * interface DB extends InferDatabase<typeof appSchema> {}
78
+ * const db = createMinnow<DB>(database, { schema: appSchema });
79
+ * ```
80
+ *
81
+ * Without the type argument, `DB` is inferred from the runtime schema value — fine for
82
+ * scratch code and small scripts, at the cost of expanded types in tooling:
83
+ *
84
+ * ```ts
85
+ * const db = createMinnow(database, { schema: appSchema });
86
+ * ```
87
+ */
88
+ export declare function createMinnow<TTables extends readonly AnyTable[]>(driver: DslDriver, options: Omit<MinnowOptions, "schema"> & {
89
+ schema: SchemaDefinition<TTables>;
90
+ }): Minnow<InferDatabase<SchemaDefinition<TTables>>>;
91
+ export declare function createMinnow<DB>(driver: DslDriver, options?: MinnowOptions): Minnow<DB>;
92
+ interface SharedLiveSet {
93
+ set?: DriverLiveSet | undefined;
94
+ }
95
+ /** One db.search hit: the owning table, the row (without the score alias), and its BM25 score. */
96
+ export interface SearchHit<DB> {
97
+ table: keyof DB & string;
98
+ row: Record<string, QueryValue>;
99
+ score: number;
100
+ }
101
+ export declare class Minnow<in out DB> {
102
+ #private;
103
+ constructor(driver: DslDriver, options?: MinnowOptions, ctes?: readonly CteDefinition[], liveBox?: SharedLiveSet);
104
+ /**
105
+ * The driver this facade was created with — the `MinnowDatabase` or `MinnowDatabaseClient`
106
+ * behind it. Tools handed only the facade (devtools, inspectors, schema browsers) reach the
107
+ * catalog and the raw SQL entry points through here; application code should keep its own
108
+ * reference to the driver rather than reaching back through the facade.
109
+ */
110
+ get driver(): DslDriver;
111
+ selectFrom<TE extends TableExpression<DB>>(table: TE): SelectQueryBuilder<DB, ContextWithTable<DB, EmptyContext, TE>, EmptyContext>;
112
+ selectFrom<TDerivedRow extends AnyRow, TAlias extends string>(derived: AliasedSelectQuery<TDerivedRow, TAlias>): SelectQueryBuilder<DB, Record<TAlias, TDerivedRow>, EmptyContext>;
113
+ insertInto<TTable extends keyof DB & string>(table: TTable): InsertQueryBuilder<DB, TTable>;
114
+ updateTable<TTable extends keyof DB & string>(table: TTable): UpdateQueryBuilder<DB, TTable>;
115
+ deleteFrom<TTable extends keyof DB & string>(table: TTable): DeleteQueryBuilder<DB, TTable>;
116
+ /**
117
+ * Declares a common table expression usable in `selectFrom`/joins of queries created from the
118
+ * returned facade, exactly as SQL `WITH name AS (...)`.
119
+ */
120
+ with<TName extends string, TCteCtx, TCteRow extends AnyRow>(name: TName, factory: (creator: Minnow<DB>) => SelectQueryBuilder<DB, TCteCtx, TCteRow>): Minnow<DB & Record<TName, TCteRow>>;
121
+ /**
122
+ * Zero-ceremony document search across tables: every searched table (all schema tables by
123
+ * default; `options.tables` narrows the set) runs a MATCH(*)-filtered, BM25-ordered scan,
124
+ * and the per-table hits merge into one relevance-ranked list. The facade must be created
125
+ * with `{ schema }` — the per-table column lists come from it.
126
+ */
127
+ search(query: string, options?: {
128
+ tables?: ReadonlyArray<keyof DB & string>;
129
+ limit?: number;
130
+ }): Promise<Array<SearchHit<DB>>>;
131
+ /** @internal Raw-SQL escape hatch used by the `sql` template tag. */
132
+ $executeRaw(sqlText: string, params?: readonly QueryValue[]): Promise<QueryRow[]>;
133
+ /** Closes the shared live-query set, if one was created. */
134
+ close(): Promise<void>;
135
+ }
136
+ export {};
137
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../src/engine/dsl/db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,161 @@
1
+ import { DeleteQueryBuilder, InsertQueryBuilder, UpdateQueryBuilder, } from "./mutations.js";
2
+ import { isAliasedSelectQuery, parseTableExpression, SelectQueryBuilder, } from "./select-query-builder.js";
3
+ export function createMinnow(driver, options = {}) {
4
+ return new Minnow(driver, options);
5
+ }
6
+ export class Minnow {
7
+ #driver;
8
+ #options;
9
+ #ctes;
10
+ #liveBox;
11
+ constructor(driver, options = {}, ctes = [], liveBox = {}) {
12
+ this.#driver = driver;
13
+ this.#options = options;
14
+ this.#ctes = ctes;
15
+ this.#liveBox = liveBox;
16
+ }
17
+ /**
18
+ * The driver this facade was created with — the `MinnowDatabase` or `MinnowDatabaseClient`
19
+ * behind it. Tools handed only the facade (devtools, inspectors, schema browsers) reach the
20
+ * catalog and the raw SQL entry points through here; application code should keep its own
21
+ * reference to the driver rather than reaching back through the facade.
22
+ */
23
+ get driver() {
24
+ return this.#driver;
25
+ }
26
+ #liveServices() {
27
+ return {
28
+ subscribe: async (query, handlers) => {
29
+ this.#liveBox.set ??= this.#driver.liveQueries(this.#options.live ?? {});
30
+ return this.#liveBox.set.subscribe(query, handlers);
31
+ },
32
+ };
33
+ }
34
+ #services() {
35
+ return {
36
+ run: (query) => this.#driver.run(query),
37
+ live: this.#liveServices(),
38
+ };
39
+ }
40
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return --
41
+ the implementation signature erases the context; the overloads above carry precise types. */
42
+ selectFrom(table) {
43
+ if (isAliasedSelectQuery(table)) {
44
+ return SelectQueryBuilder.create({ kind: "derived", builder: table.builder, alias: table.alias }, this.#ctes, this.#services());
45
+ }
46
+ const { table: name, alias } = parseTableExpression(table);
47
+ return SelectQueryBuilder.create({ kind: "table", table: name, alias }, this.#ctes, this.#services());
48
+ }
49
+ /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return */
50
+ #mutationServices() {
51
+ const schemaTables = this.#options.schema?.tables;
52
+ return {
53
+ insertBatch: (tableName, rows) => this.#driver.insertBatch(tableName, rows),
54
+ upsertBatch: (tableName, rows) => this.#driver.upsertBatch(tableName, rows),
55
+ runStatement: (statement, options) => this.#driver.runStatement(statement, options),
56
+ tableColumns: (tableName) => {
57
+ const definition = schemaTables?.find(({ name }) => name === tableName);
58
+ return definition === undefined ? undefined : Object.keys(definition.columns);
59
+ },
60
+ columnDefaultFns: (tableName) => {
61
+ const definition = schemaTables?.find(({ name }) => name === tableName);
62
+ if (definition === undefined)
63
+ return undefined;
64
+ let fns;
65
+ for (const [name, columnDefinition] of Object.entries(definition.columns)) {
66
+ const fill = columnDefinition.defaultFn;
67
+ if (fill !== undefined)
68
+ (fns ??= {})[name] = fill;
69
+ }
70
+ return fns;
71
+ },
72
+ };
73
+ }
74
+ insertInto(table) {
75
+ return new InsertQueryBuilder(this.#mutationServices(), table);
76
+ }
77
+ updateTable(table) {
78
+ return new UpdateQueryBuilder(this.#mutationServices(), table);
79
+ }
80
+ deleteFrom(table) {
81
+ return new DeleteQueryBuilder(this.#mutationServices(), table);
82
+ }
83
+ /**
84
+ * Declares a common table expression usable in `selectFrom`/joins of queries created from the
85
+ * returned facade, exactly as SQL `WITH name AS (...)`.
86
+ */
87
+ with(name, factory) {
88
+ const builder = factory(this);
89
+ return new Minnow(this.#driver, this.#options, [...this.#ctes, { name, builder }], this.#liveBox);
90
+ }
91
+ /**
92
+ * Zero-ceremony document search across tables: every searched table (all schema tables by
93
+ * default; `options.tables` narrows the set) runs a MATCH(*)-filtered, BM25-ordered scan,
94
+ * and the per-table hits merge into one relevance-ranked list. The facade must be created
95
+ * with `{ schema }` — the per-table column lists come from it.
96
+ */
97
+ async search(query, options = {}) {
98
+ const schemaTables = this.#options.schema?.tables;
99
+ if (schemaTables === undefined) {
100
+ throw new TypeError("search() needs the table columns: create the facade with { schema }");
101
+ }
102
+ const tableNames = options.tables ?? schemaTables.map(({ name }) => name);
103
+ const limit = options.limit ?? 10;
104
+ const perTable = await Promise.all(tableNames.map(async (tableName) => {
105
+ const definition = schemaTables.find(({ name }) => name === tableName);
106
+ if (definition === undefined) {
107
+ throw new TypeError(`search() needs the table's schema: ${tableName}`);
108
+ }
109
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any --
110
+ per-table column lists are only known at runtime; hits erase the row type anyway. */
111
+ const builder = this.selectFrom(tableName);
112
+ // The score is selected under an internal alias so hits can rank across tables, then
113
+ // stripped from the row; user-facing rows never carry a synthetic column. The alias
114
+ // grows parentheses until it collides with no real column name.
115
+ const columnNames = Object.keys(definition.columns);
116
+ let scoreAlias = "(search score)";
117
+ while (columnNames.includes(scoreAlias))
118
+ scoreAlias = `(${scoreAlias})`;
119
+ let rows;
120
+ try {
121
+ rows = await builder
122
+ .select((eb) => [...columnNames, eb.fn.bm25("*", query).as(scoreAlias)])
123
+ .search(query)
124
+ .limit(limit)
125
+ .execute();
126
+ }
127
+ catch (error) {
128
+ // A schema can list tables that don't exist yet or hold nothing searchable; those
129
+ // tables simply contribute no hits. Anything else is a real failure.
130
+ const message = error instanceof Error ? error.message : "";
131
+ if (message.startsWith("Table not found:") ||
132
+ message.startsWith("Unknown table:") ||
133
+ message.includes("no searchable columns")) {
134
+ return [];
135
+ }
136
+ throw error;
137
+ }
138
+ return rows.map((row) => {
139
+ const { [scoreAlias]: score, ...rest } = row;
140
+ return { table: tableName, row: rest, score: typeof score === "number" ? score : 0 };
141
+ });
142
+ }));
143
+ return perTable
144
+ .flat()
145
+ .sort((left, right) => right.score - left.score)
146
+ .slice(0, limit);
147
+ }
148
+ /** @internal Raw-SQL escape hatch used by the `sql` template tag. */
149
+ async $executeRaw(sqlText, params) {
150
+ const result = await this.#driver.execute(sqlText, params);
151
+ return result.result?.rows ?? [];
152
+ }
153
+ /** Closes the shared live-query set, if one was created. */
154
+ async close() {
155
+ const set = this.#liveBox.set;
156
+ this.#liveBox.set = undefined;
157
+ if (set !== undefined)
158
+ await set.close();
159
+ }
160
+ }
161
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/engine/dsl/db.ts"],"names":[],"mappings":"AASA,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,GAEnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,GAInB,MAAM,2BAA2B,CAAC;AA6FnC,MAAM,UAAU,YAAY,CAAK,MAAiB,EAAE,UAAyB,EAAE;IAC7E,OAAO,IAAI,MAAM,CAAK,MAAM,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAaD,MAAM,OAAO,MAAM;IACR,OAAO,CAAY;IACnB,QAAQ,CAAgB;IACxB,KAAK,CAA2B;IAChC,QAAQ,CAAgB;IAEjC,YACE,MAAiB,EACjB,UAAyB,EAAE,EAC3B,OAAiC,EAAE,EACnC,UAAyB,EAAE;QAE3B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED;;;;;OAKG;IACH,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,aAAa;QACX,OAAO;YACL,SAAS,EAAE,KAAK,EAAE,KAAkC,EAAE,QAAQ,EAAE,EAAE;gBAChE,IAAI,CAAC,QAAQ,CAAC,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;gBACzE,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YACtD,CAAC;SACF,CAAC;IACJ,CAAC;IAED,SAAS;QACP,OAAO;YACL,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YACvC,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE;SAC3B,CAAC;IACJ,CAAC;IAQD;mGAC+F;IAC/F,UAAU,CACR,KAAmD;QAEnD,IAAI,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,kBAAkB,CAAC,MAAM,CAC9B,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAC/D,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,SAAS,EAAE,CACjB,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAC3D,OAAO,kBAAkB,CAAC,MAAM,CAC9B,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EACrC,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,SAAS,EAAE,CACjB,CAAC;IACJ,CAAC;IACD,2FAA2F;IAE3F,iBAAiB;QACf,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAClD,OAAO;YACL,WAAW,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC;YAC3E,WAAW,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC;YAC3E,YAAY,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC;YACnF,YAAY,EAAE,CAAC,SAAS,EAAE,EAAE;gBAC1B,MAAM,UAAU,GAAG,YAAY,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;gBACxE,OAAO,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAChF,CAAC;YACD,gBAAgB,EAAE,CAAC,SAAS,EAAE,EAAE;gBAC9B,MAAM,UAAU,GAAG,YAAY,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;gBACxE,IAAI,UAAU,KAAK,SAAS;oBAAE,OAAO,SAAS,CAAC;gBAC/C,IAAI,GAAiD,CAAC;gBACtD,KAAK,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC1E,MAAM,IAAI,GAAG,gBAAgB,CAAC,SAAS,CAAC;oBACxC,IAAI,IAAI,KAAK,SAAS;wBAAE,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;gBACpD,CAAC;gBACD,OAAO,GAAG,CAAC;YACb,CAAC;SACF,CAAC;IACJ,CAAC;IAED,UAAU,CAAmC,KAAa;QACxD,OAAO,IAAI,kBAAkB,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,KAAK,CAAC,CAAC;IACjE,CAAC;IAED,WAAW,CAAmC,KAAa;QACzD,OAAO,IAAI,kBAAkB,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,KAAK,CAAC,CAAC;IACjE,CAAC;IAED,UAAU,CAAmC,KAAa;QACxD,OAAO,IAAI,kBAAkB,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,KAAK,CAAC,CAAC;IACjE,CAAC;IAED;;;OAGG;IACH,IAAI,CACF,IAAW,EACX,OAA0E;QAE1E,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAoB,CAAC;QACjD,OAAO,IAAI,MAAM,CACf,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,QAAQ,EACb,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAClC,IAAI,CAAC,QAAQ,CACd,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CACV,KAAa,EACb,UAAyE,EAAE;QAE3E,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAClD,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,IAAI,SAAS,CAAC,qEAAqE,CAAC,CAAC;QAC7F,CAAC;QACD,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAyB,CAAC,CAAC;QAC/F,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;YACjC,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;YACvE,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,MAAM,IAAI,SAAS,CAAC,sCAAsC,SAAS,EAAE,CAAC,CAAC;YACzE,CAAC;YACD;mGACuF;YACvF,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,SAAgB,CAI/C,CAAC;YACF,qFAAqF;YACrF,oFAAoF;YACpF,gEAAgE;YAChE,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACpD,IAAI,UAAU,GAAG,gBAAgB,CAAC;YAClC,OAAO,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC;gBAAE,UAAU,GAAG,IAAI,UAAU,GAAG,CAAC;YACxE,IAAI,IAAuC,CAAC;YAC5C,IAAI,CAAC;gBACH,IAAI,GAAG,MAAM,OAAO;qBACjB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;qBACvE,MAAM,CAAC,KAAK,CAAC;qBACb,KAAK,CAAC,KAAK,CAAC;qBACZ,OAAO,EAAE,CAAC;YACf,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,kFAAkF;gBAClF,qEAAqE;gBACrE,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,IACE,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC;oBACtC,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC;oBACpC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EACzC,CAAC;oBACD,OAAO,EAAE,CAAC;gBACZ,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;YACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBACtB,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,CAAC;gBAC7C,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACvF,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CACH,CAAC;QACF,OAAO,QAAQ;aACZ,IAAI,EAAE;aACN,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;aAC/C,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACrB,CAAC;IAED,qEAAqE;IACrE,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,MAA8B;QAC/D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3D,OAAO,MAAM,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;IACnC,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,KAAK;QACT,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,SAAS,CAAC;QAC9B,IAAI,GAAG,KAAK,SAAS;YAAE,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;IAC3C,CAAC;CACF"}
@@ -0,0 +1,172 @@
1
+ import { type AggregateName, type Expression, type QueryValue, type WindowFunctionName } from "../query.js";
2
+ import { type AliasedExpression, type BlockCompilable, type ColumnReference, type ColumnReferenceOf, type ContextWithTable, type ExpressionSource, type ReferencedValue, type TableExpression } from "./types.js";
3
+ import type { SelectQueryBuilder } from "./select-query-builder.js";
4
+ /**
5
+ * Kysely-style expression building. `eb(lhs, op, rhs)` plus `eb.and/or/not/fn/case/exists/...`
6
+ * assemble the same Expression trees the SQL parser produces — string left-hand sides are column
7
+ * references, right-hand sides are values (use `eb.ref` to compare columns). Everything holds an
8
+ * ExpressionSource so subqueries compile under the enclosing query's shared derived-source
9
+ * sequence, keeping builder plans byte-identical to parsed SQL.
10
+ */
11
+ export type SqlBool = boolean;
12
+ export type ComparisonOperatorToken = "=" | "!=" | "<>" | ">" | ">=" | "<" | "<=";
13
+ export type LikeOperatorToken = "like" | "not like";
14
+ export type InOperatorToken = "in" | "not in";
15
+ export type IsOperatorToken = "is" | "is not";
16
+ export type ArithmeticOperatorToken = "+" | "-" | "*" | "/";
17
+ export type BinaryOperatorToken = ComparisonOperatorToken | LikeOperatorToken | InOperatorToken | IsOperatorToken | ArithmeticOperatorToken;
18
+ export declare class ExpressionWrapper<out TValue> {
19
+ readonly source: ExpressionSource;
20
+ readonly kind: "dsl-expression";
21
+ constructor(source: ExpressionSource);
22
+ /** Names this expression's output column, as SQL `AS alias` does. */
23
+ as<TAlias extends string>(alias: TAlias): AliasedExpression<TValue, TAlias>;
24
+ }
25
+ export declare function isExpressionWrapper(value: unknown): value is ExpressionWrapper<unknown>;
26
+ /**
27
+ * A subquery usable where a scalar `TValue` is expected: its row must be a single column whose
28
+ * value fits. Only the value side is checked structurally — the builder's `DB`/context do not
29
+ * matter here, hence the `any`s.
30
+ */
31
+ export type ScalarSubquery<TValue> = SelectQueryBuilder<any, any, Record<string, TValue | null>>;
32
+ /** A value operand: a literal, a wrapped expression, or a scalar subquery of the same type. */
33
+ export type ValueOperand<TValue> = TValue | null | ExpressionWrapper<TValue | null> | ScalarSubquery<TValue>;
34
+ type ArithmeticOperand<TCtx> = ColumnReferenceOf<TCtx, number> | number | ExpressionWrapper<number | null>;
35
+ export declare function literalExpression(value: unknown): Expression;
36
+ /** Shared with the query builders: `lhs op rhs` where lhs is a reference and rhs a value. */
37
+ export declare function buildBinaryCondition(lhs: unknown, operator: string, rhs: unknown): ExpressionSource;
38
+ interface OverClauseState {
39
+ partitionBy: ExpressionSource[];
40
+ orderBy: Array<{
41
+ source: ExpressionSource;
42
+ direction: "asc" | "desc";
43
+ }>;
44
+ }
45
+ export declare class OverBuilder<in out TCtx> {
46
+ private readonly state;
47
+ constructor(state?: OverClauseState);
48
+ partitionBy(...references: ReadonlyArray<ColumnReference<TCtx> | ExpressionWrapper<unknown>>): OverBuilder<TCtx>;
49
+ orderBy(reference: ColumnReference<TCtx> | ExpressionWrapper<unknown>, direction?: "asc" | "desc"): OverBuilder<TCtx>;
50
+ /** @internal */
51
+ get clause(): OverClauseState;
52
+ }
53
+ type OverConfigure<TCtx> = (over: OverBuilder<TCtx>) => OverBuilder<TCtx>;
54
+ /** A ranking window function; SQL requires OVER, so only `.over()` yields an expression. */
55
+ export declare class WindowFunctionBuilder<in out TCtx> {
56
+ private readonly name;
57
+ constructor(name: WindowFunctionName);
58
+ over(configure?: OverConfigure<TCtx>): ExpressionWrapper<number>;
59
+ }
60
+ export declare class AggregateExpressionWrapper<in out TCtx, out TValue> extends ExpressionWrapper<TValue> {
61
+ private readonly name;
62
+ private readonly argument;
63
+ private readonly isDistinct;
64
+ constructor(name: AggregateName, argument: ExpressionSource, isDistinct?: boolean);
65
+ /** COUNT(DISTINCT e); the engine restricts DISTINCT to COUNT over one scalar argument. */
66
+ distinct(): AggregateExpressionWrapper<TCtx, TValue>;
67
+ /** Turns the aggregate into a window over the given partition and ordering. */
68
+ over(configure?: OverConfigure<TCtx>): ExpressionWrapper<TValue>;
69
+ }
70
+ /** A COALESCE argument: a column reference or any wrapped expression. */
71
+ type CoalesceArg<TCtx> = ColumnReference<TCtx> | ExpressionWrapper<unknown>;
72
+ type CoalesceArgValue<TCtx, TArg> = TArg extends ExpressionWrapper<infer TValue> ? TValue : TArg extends string ? ReferencedValue<TCtx, TArg> : never;
73
+ /**
74
+ * The union of the operand value types; null stays only when the final fallback is itself
75
+ * nullable, matching COALESCE's first-non-null semantics.
76
+ */
77
+ type CoalesceValue<TCtx, TArgs extends readonly unknown[]> = TArgs extends readonly [
78
+ ...unknown[],
79
+ infer TLast
80
+ ] ? Exclude<CoalesceArgValue<TCtx, TArgs[number]>, null> | Extract<CoalesceArgValue<TCtx, TLast>, null> : CoalesceArgValue<TCtx, TArgs[number]>;
81
+ export interface FunctionModule<in out TCtx> {
82
+ /** COUNT(argument); counts non-null values. */
83
+ count(reference: ColumnReference<TCtx> | ExpressionWrapper<unknown>): AggregateExpressionWrapper<TCtx, number>;
84
+ /** COUNT(*). */
85
+ countAll(): AggregateExpressionWrapper<TCtx, number>;
86
+ sum(reference: ColumnReferenceOf<TCtx, number> | ExpressionWrapper<number | null>): AggregateExpressionWrapper<TCtx, number | null>;
87
+ avg(reference: ColumnReferenceOf<TCtx, number> | ExpressionWrapper<number | null>): AggregateExpressionWrapper<TCtx, number | null>;
88
+ min<TRef extends ColumnReference<TCtx>>(reference: TRef): AggregateExpressionWrapper<TCtx, ReferencedValue<TCtx, TRef & string> | null>;
89
+ min<TValue>(expression: ExpressionWrapper<TValue>): AggregateExpressionWrapper<TCtx, TValue | null>;
90
+ max<TRef extends ColumnReference<TCtx>>(reference: TRef): AggregateExpressionWrapper<TCtx, ReferencedValue<TCtx, TRef & string> | null>;
91
+ max<TValue>(expression: ExpressionWrapper<TValue>): AggregateExpressionWrapper<TCtx, TValue | null>;
92
+ round(value: ArithmeticOperand<TCtx>, digits?: number): ExpressionWrapper<number | null>;
93
+ coalesce<TArgs extends readonly [CoalesceArg<TCtx>, ...Array<CoalesceArg<TCtx>>]>(...values: TArgs): ExpressionWrapper<CoalesceValue<TCtx, TArgs>>;
94
+ dateTrunc(unit: "year" | "month" | "day" | "hour" | "minute" | "second", value: ColumnReferenceOf<TCtx, Date> | Date | ExpressionWrapper<Date | null>): ExpressionWrapper<Date | null>;
95
+ /**
96
+ * Document-level BM25 relevance of the query against the listed columns ("*" = every
97
+ * non-boolean column of the scanned table), compiling to the same node as SQL
98
+ * `BM25(col, ...) AGAINST 'query'`. 0 when no term matches; null when every column is null.
99
+ */
100
+ bm25(columns: "*" | ReadonlyArray<ColumnReferenceOf<TCtx, string | number | Date> & string>, query: string): ExpressionWrapper<number | null>;
101
+ }
102
+ /** Shared by eb.match and fn.bm25: validates and assembles the full-text plan node. */
103
+ export declare function buildFtsExpression(op: "match" | "bm25", columns: "*" | readonly string[], query: string): Expression;
104
+ interface CaseBranch {
105
+ when: ExpressionSource;
106
+ then: ExpressionSource;
107
+ }
108
+ export declare class CaseThenBuilder<in out TCtx, out TValue> {
109
+ private readonly branches;
110
+ private readonly pendingWhen;
111
+ constructor(branches: readonly CaseBranch[], pendingWhen: ExpressionSource);
112
+ then<TNext extends QueryValue>(value: TNext | ExpressionWrapper<TNext>): CaseBuilder<TCtx, TValue | TNext>;
113
+ }
114
+ export declare class CaseBuilder<in out TCtx, out TValue = never> {
115
+ private readonly branches;
116
+ constructor(branches?: readonly CaseBranch[]);
117
+ when(condition: ExpressionWrapper<SqlBool>): CaseThenBuilder<TCtx, TValue>;
118
+ when<TRef extends ColumnReference<TCtx>>(lhs: TRef, operator: ComparisonOperatorToken | LikeOperatorToken, rhs: ValueOperand<ReferencedValue<TCtx, TRef & string>>): CaseThenBuilder<TCtx, TValue>;
119
+ else<TNext extends QueryValue>(value: TNext | ExpressionWrapper<TNext>): CaseEndBuilder<TValue | TNext>;
120
+ end(): ExpressionWrapper<TValue | null>;
121
+ }
122
+ export declare class CaseEndBuilder<out TValue> {
123
+ private readonly branches;
124
+ private readonly otherwise;
125
+ constructor(branches: readonly CaseBranch[], otherwise: ExpressionSource);
126
+ end(): ExpressionWrapper<TValue>;
127
+ }
128
+ export interface ExpressionBuilder<in out DB, in out TCtx> {
129
+ /** Compares a column (or expression) to a value; string left-hand sides are references. */
130
+ <TRef extends ColumnReference<TCtx> & string>(lhs: TRef, operator: ComparisonOperatorToken, rhs: ValueOperand<ReferencedValue<TCtx, TRef>>): ExpressionWrapper<SqlBool>;
131
+ (lhs: ExpressionWrapper<unknown>, operator: ComparisonOperatorToken, rhs: QueryValue | ExpressionWrapper<unknown> | ScalarSubquery<unknown>): ExpressionWrapper<SqlBool>;
132
+ (lhs: ColumnReference<TCtx> | ExpressionWrapper<string | null>, operator: LikeOperatorToken, rhs: string | ExpressionWrapper<string | null>): ExpressionWrapper<SqlBool>;
133
+ <TRef extends ColumnReference<TCtx> & string>(lhs: TRef, operator: InOperatorToken, rhs: ReadonlyArray<ReferencedValue<TCtx, TRef> | ExpressionWrapper<unknown>> | ScalarSubquery<ReferencedValue<TCtx, TRef>>): ExpressionWrapper<SqlBool>;
134
+ (lhs: ColumnReference<TCtx> | ExpressionWrapper<unknown>, operator: IsOperatorToken, rhs: null): ExpressionWrapper<SqlBool>;
135
+ (lhs: ArithmeticOperand<TCtx>, operator: ArithmeticOperatorToken, rhs: ArithmeticOperand<TCtx>): ExpressionWrapper<number>;
136
+ /** ANDs conditions left to right. */
137
+ and(conditions: ReadonlyArray<ExpressionWrapper<SqlBool>>): ExpressionWrapper<SqlBool>;
138
+ /** ORs conditions left to right. */
139
+ or(conditions: ReadonlyArray<ExpressionWrapper<SqlBool>>): ExpressionWrapper<SqlBool>;
140
+ not(condition: ExpressionWrapper<SqlBool>): ExpressionWrapper<SqlBool>;
141
+ /** `lhs BETWEEN lower AND upper`, desugared exactly as the parser does. */
142
+ between<TRef extends ColumnReference<TCtx>>(reference: TRef | ExpressionWrapper<unknown>, lower: ValueOperand<ReferencedValue<TCtx, TRef & string>>, upper: ValueOperand<ReferencedValue<TCtx, TRef & string>>): ExpressionWrapper<SqlBool>;
143
+ notBetween<TRef extends ColumnReference<TCtx>>(reference: TRef | ExpressionWrapper<unknown>, lower: ValueOperand<ReferencedValue<TCtx, TRef & string>>, upper: ValueOperand<ReferencedValue<TCtx, TRef & string>>): ExpressionWrapper<SqlBool>;
144
+ exists(subquery: BlockCompilable): ExpressionWrapper<SqlBool>;
145
+ /**
146
+ * Document-level full-text MATCH, compiling to the same node as SQL
147
+ * `MATCH(col, ...) AGAINST 'query'`: every query term must appear in some listed column
148
+ * ("*" searches every non-boolean column of the scanned table); a term ending in `*`
149
+ * matches prefixes. Rows whose listed columns are all null are unknown, like LIKE on null.
150
+ */
151
+ match(columns: "*" | ReadonlyArray<ColumnReferenceOf<TCtx, string | number | Date> & string>, query: string): ExpressionWrapper<SqlBool>;
152
+ /** A column reference as an expression, for the rare value-position column comparison. */
153
+ ref<TRef extends ColumnReference<TCtx>>(reference: TRef): ExpressionWrapper<ReferencedValue<TCtx, TRef & string>>;
154
+ /** A literal value as an expression. */
155
+ val<TValue extends QueryValue>(value: TValue): ExpressionWrapper<TValue>;
156
+ /** Arithmetic negation. */
157
+ neg(value: ArithmeticOperand<TCtx>): ExpressionWrapper<number>;
158
+ case(): CaseBuilder<TCtx>;
159
+ rowNumber(): WindowFunctionBuilder<TCtx>;
160
+ rank(): WindowFunctionBuilder<TCtx>;
161
+ denseRank(): WindowFunctionBuilder<TCtx>;
162
+ /** Starts a correlated or uncorrelated subquery over the database plus the outer scope. */
163
+ selectFrom<TE extends TableExpression<DB>>(table: TE): SelectQueryBuilder<DB, ContextWithTable<DB, TCtx, TE>, Record<never, unknown>>;
164
+ fn: FunctionModule<TCtx>;
165
+ }
166
+ /**
167
+ * Creates the callable expression builder. The subquery factory is injected by the select
168
+ * builder module, which owns both sides of that recursion.
169
+ */
170
+ export declare function createExpressionBuilder<DB, TCtx>(createSubquery: (table: string) => unknown): ExpressionBuilder<DB, TCtx>;
171
+ export {};
172
+ //# sourceMappingURL=expression.d.ts.map