@lunora/d1 1.0.0-alpha.32 → 1.0.0-alpha.33

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.
@@ -1,40 +1,40 @@
1
1
  /**
2
- * Canonical SQL identifier quoter shared by `@lunora/d1` and `@lunora/do`.
3
- *
4
- * Double-quotes a SQL identifier and escapes any embedded double quotes by
5
- * doubling them (`"` → `""`) — the ANSI/SQLite/Postgres rule. This is a
6
- * security-relevant primitive (it is the sole defense against identifier
7
- * injection wherever a table/column name is spliced into raw SQL), so it must
8
- * have exactly ONE definition rather than byte-identical copies that can drift.
9
- *
10
- * Like `shared/stable-key.ts`, it is deliberately **not** a package: `@lunora/d1`
11
- * and `@lunora/do` sit on the same tier with no lower-level package to host it,
12
- * so each imports this file by relative path and the bundler (packem/rollup)
13
- * inlines it — no runtime dependency edge, duplicated only in emitted output.
14
- * Keep it genuinely zero-dependency (relative/built-in imports only) or inlining
15
- * breaks. Consumers must drop `outDir`/`rootDir` from their `tsconfig.json` (a
16
- * set `rootDir` raises TS6059 for this out-of-package file under `tsc --noEmit`).
17
- */
2
+ * Canonical SQL identifier quoter shared by `@lunora/d1` and `@lunora/do`.
3
+ *
4
+ * Double-quotes a SQL identifier and escapes any embedded double quotes by
5
+ * doubling them (`"` → `""`) — the ANSI/SQLite/Postgres rule. This is a
6
+ * security-relevant primitive (it is the sole defense against identifier
7
+ * injection wherever a table/column name is spliced into raw SQL), so it must
8
+ * have exactly ONE definition rather than byte-identical copies that can drift.
9
+ *
10
+ * Like `shared/stable-key.ts`, it is deliberately **not** a package: `@lunora/d1`
11
+ * and `@lunora/do` sit on the same tier with no lower-level package to host it,
12
+ * so each imports this file by relative path and the bundler (packem/rollup)
13
+ * inlines it — no runtime dependency edge, duplicated only in emitted output.
14
+ * Keep it genuinely zero-dependency (relative/built-in imports only) or inlining
15
+ * breaks. Consumers must drop `outDir`/`rootDir` from their `tsconfig.json` (a
16
+ * set `rootDir` raises TS6059 for this out-of-package file under `tsc --noEmit`).
17
+ */
18
18
  declare const quoteIdentifier: (name: string) => string;
19
19
  /** SQLite column type affinities Lunora emits. */
20
20
  type SqlAffinity = "BLOB" | "INTEGER" | "REAL" | "TEXT";
21
21
  /**
22
- * SQLite affinity for a column by its validator `kind`, chosen so the value the
23
- * D1 layer serializes round-trips intact:
24
- * - `boolean` → INTEGER (stored as 1/0)
25
- * - `number`/`timestamp`/`date` → REAL (numeric, never coerced to text)
26
- * - `bytes` → BLOB
27
- * - everything else → TEXT — string/id/literal, `bigint` (serialized as a
28
- * decimal string), and object/array/record/union/any (JSON). A numeric affinity
29
- * would coerce a numeric-looking string and corrupt the decode.
30
- */
22
+ * SQLite affinity for a column by its validator `kind`, chosen so the value the
23
+ * D1 layer serializes round-trips intact:
24
+ * - `boolean` → INTEGER (stored as 1/0)
25
+ * - `number`/`timestamp`/`date` → REAL (numeric, never coerced to text)
26
+ * - `bytes` → BLOB
27
+ * - everything else → TEXT — string/id/literal, `bigint` (serialized as a
28
+ * decimal string), and object/array/record/union/any (JSON). A numeric affinity
29
+ * would coerce a numeric-looking string and corrupt the decode.
30
+ */
31
31
  declare const sqlAffinityForKind: (kind: string | undefined) => SqlAffinity;
32
32
  /** Framework columns every global table carries: the physical `id` (exposed as `_id`) and `_creationTime`. */
33
33
  declare const frameworkColumnDdl: () => ReadonlyArray<string>;
34
34
  /**
35
- * Resolve a schema field to its physical D1 column: `_id`/`id` both map to the
36
- * physical `id` column, `_creationTime` to its own, every other field to itself.
37
- */
35
+ * Resolve a schema field to its physical D1 column: `_id`/`id` both map to the
36
+ * physical `id` column, `_creationTime` to its own, every other field to itself.
37
+ */
38
38
  declare const columnRef: (field: string) => string;
39
39
  /** Physical index identifier — `&lt;table>_&lt;name>`, so two tables' like-named indexes don't collide in SQLite's flat index namespace. */
40
40
  declare const physicalIndexName: (tableName: string, indexName: string) => string;
package/dist/dialect.d.ts CHANGED
@@ -1,40 +1,40 @@
1
1
  /**
2
- * Canonical SQL identifier quoter shared by `@lunora/d1` and `@lunora/do`.
3
- *
4
- * Double-quotes a SQL identifier and escapes any embedded double quotes by
5
- * doubling them (`"` → `""`) — the ANSI/SQLite/Postgres rule. This is a
6
- * security-relevant primitive (it is the sole defense against identifier
7
- * injection wherever a table/column name is spliced into raw SQL), so it must
8
- * have exactly ONE definition rather than byte-identical copies that can drift.
9
- *
10
- * Like `shared/stable-key.ts`, it is deliberately **not** a package: `@lunora/d1`
11
- * and `@lunora/do` sit on the same tier with no lower-level package to host it,
12
- * so each imports this file by relative path and the bundler (packem/rollup)
13
- * inlines it — no runtime dependency edge, duplicated only in emitted output.
14
- * Keep it genuinely zero-dependency (relative/built-in imports only) or inlining
15
- * breaks. Consumers must drop `outDir`/`rootDir` from their `tsconfig.json` (a
16
- * set `rootDir` raises TS6059 for this out-of-package file under `tsc --noEmit`).
17
- */
2
+ * Canonical SQL identifier quoter shared by `@lunora/d1` and `@lunora/do`.
3
+ *
4
+ * Double-quotes a SQL identifier and escapes any embedded double quotes by
5
+ * doubling them (`"` → `""`) — the ANSI/SQLite/Postgres rule. This is a
6
+ * security-relevant primitive (it is the sole defense against identifier
7
+ * injection wherever a table/column name is spliced into raw SQL), so it must
8
+ * have exactly ONE definition rather than byte-identical copies that can drift.
9
+ *
10
+ * Like `shared/stable-key.ts`, it is deliberately **not** a package: `@lunora/d1`
11
+ * and `@lunora/do` sit on the same tier with no lower-level package to host it,
12
+ * so each imports this file by relative path and the bundler (packem/rollup)
13
+ * inlines it — no runtime dependency edge, duplicated only in emitted output.
14
+ * Keep it genuinely zero-dependency (relative/built-in imports only) or inlining
15
+ * breaks. Consumers must drop `outDir`/`rootDir` from their `tsconfig.json` (a
16
+ * set `rootDir` raises TS6059 for this out-of-package file under `tsc --noEmit`).
17
+ */
18
18
  declare const quoteIdentifier: (name: string) => string;
19
19
  /** SQLite column type affinities Lunora emits. */
20
20
  type SqlAffinity = "BLOB" | "INTEGER" | "REAL" | "TEXT";
21
21
  /**
22
- * SQLite affinity for a column by its validator `kind`, chosen so the value the
23
- * D1 layer serializes round-trips intact:
24
- * - `boolean` → INTEGER (stored as 1/0)
25
- * - `number`/`timestamp`/`date` → REAL (numeric, never coerced to text)
26
- * - `bytes` → BLOB
27
- * - everything else → TEXT — string/id/literal, `bigint` (serialized as a
28
- * decimal string), and object/array/record/union/any (JSON). A numeric affinity
29
- * would coerce a numeric-looking string and corrupt the decode.
30
- */
22
+ * SQLite affinity for a column by its validator `kind`, chosen so the value the
23
+ * D1 layer serializes round-trips intact:
24
+ * - `boolean` → INTEGER (stored as 1/0)
25
+ * - `number`/`timestamp`/`date` → REAL (numeric, never coerced to text)
26
+ * - `bytes` → BLOB
27
+ * - everything else → TEXT — string/id/literal, `bigint` (serialized as a
28
+ * decimal string), and object/array/record/union/any (JSON). A numeric affinity
29
+ * would coerce a numeric-looking string and corrupt the decode.
30
+ */
31
31
  declare const sqlAffinityForKind: (kind: string | undefined) => SqlAffinity;
32
32
  /** Framework columns every global table carries: the physical `id` (exposed as `_id`) and `_creationTime`. */
33
33
  declare const frameworkColumnDdl: () => ReadonlyArray<string>;
34
34
  /**
35
- * Resolve a schema field to its physical D1 column: `_id`/`id` both map to the
36
- * physical `id` column, `_creationTime` to its own, every other field to itself.
37
- */
35
+ * Resolve a schema field to its physical D1 column: `_id`/`id` both map to the
36
+ * physical `id` column, `_creationTime` to its own, every other field to itself.
37
+ */
38
38
  declare const columnRef: (field: string) => string;
39
39
  /** Physical index identifier — `&lt;table>_&lt;name>`, so two tables' like-named indexes don't collide in SQLite's flat index namespace. */
40
40
  declare const physicalIndexName: (tableName: string, indexName: string) => string;
package/dist/index.d.mts CHANGED
@@ -42,42 +42,42 @@ interface ImportResult {
42
42
  inserted: Record<string, number>;
43
43
  }
44
44
  /**
45
- * Return every `.global()` table in the schema, optionally narrowed by an
46
- * allowlist. Shard-local tables are skipped here — they're handled by the DO
47
- * helpers — so callers get a clean separation between the two storage planes.
48
- */
45
+ * Return every `.global()` table in the schema, optionally narrowed by an
46
+ * allowlist. Shard-local tables are skipped here — they're handled by the DO
47
+ * helpers — so callers get a clean separation between the two storage planes.
48
+ */
49
49
  declare const selectGlobalTables: (schema: SchemaLike, requested?: ReadonlyArray<string>) => string[];
50
50
  interface ExportGlobalArgs {
51
51
  batchSize?: number;
52
52
  tables?: ReadonlyArray<string>;
53
53
  }
54
54
  /**
55
- * Yield rows from every requested `.global()` table in batches.
56
- *
57
- * Keyset-paginates on the physical primary key (`id` — every `.global()` table
58
- * carries it, see `frameworkColumnDdl`): `WHERE "id" > ? ORDER BY "id" LIMIT ?`,
59
- * carrying the last id forward. A plain `LIMIT/OFFSET` scan would be wrong here —
60
- * SQLite gives no ordering guarantee for an unordered SELECT and each page is a
61
- * separate query, so pages could overlap or skip rows (and any concurrent
62
- * insert/delete would shift offsets and silently drop/duplicate rows in the
63
- * snapshot). Keyset paging is deterministic under concurrent writes and avoids
64
- * O(n^2) OFFSET scans on large tables.
65
- *
66
- * Tables are provisioned first (idempotent `CREATE … IF NOT EXISTS`): `.global()`
67
- * tables are created lazily on first write, so a fresh deployment — or any table
68
- * never written — would otherwise abort the stream with a raw `no such table`
69
- * instead of exporting it as empty.
70
- */
55
+ * Yield rows from every requested `.global()` table in batches.
56
+ *
57
+ * Keyset-paginates on the physical primary key (`id` — every `.global()` table
58
+ * carries it, see `frameworkColumnDdl`): `WHERE "id" > ? ORDER BY "id" LIMIT ?`,
59
+ * carrying the last id forward. A plain `LIMIT/OFFSET` scan would be wrong here —
60
+ * SQLite gives no ordering guarantee for an unordered SELECT and each page is a
61
+ * separate query, so pages could overlap or skip rows (and any concurrent
62
+ * insert/delete would shift offsets and silently drop/duplicate rows in the
63
+ * snapshot). Keyset paging is deterministic under concurrent writes and avoids
64
+ * O(n^2) OFFSET scans on large tables.
65
+ *
66
+ * Tables are provisioned first (idempotent `CREATE … IF NOT EXISTS`): `.global()`
67
+ * tables are created lazily on first write, so a fresh deployment — or any table
68
+ * never written — would otherwise abort the stream with a raw `no such table`
69
+ * instead of exporting it as empty.
70
+ */
71
71
  declare const exportGlobalRows: (exec: SqlCtxExec, schema: SchemaLike, args: ExportGlobalArgs) => AsyncGenerator<ExportRow, void, undefined>;
72
72
  interface ImportGlobalArgs {
73
73
  /**
74
- * Optional direct exec handle to the same D1 database the writer targets.
75
- * When supplied, the conflict pre-probe issues a single
76
- * `SELECT 1 FROM &lt;table> WHERE id = ? LIMIT 1` against the row's declared
77
- * table instead of falling back to `writer.get(id)`, which scans every
78
- * global table looking for the id. Strongly recommended for large schemas
79
- * — the writer-fallback is O(N tables) per row.
80
- */
74
+ * Optional direct exec handle to the same D1 database the writer targets.
75
+ * When supplied, the conflict pre-probe issues a single
76
+ * `SELECT 1 FROM &lt;table> WHERE id = ? LIMIT 1` against the row's declared
77
+ * table instead of falling back to `writer.get(id)`, which scans every
78
+ * global table looking for the id. Strongly recommended for large schemas
79
+ * — the writer-fallback is O(N tables) per row.
80
+ */
81
81
  exec?: D1ExecLike;
82
82
  rows: ReadonlyArray<ExportRow>;
83
83
  startLine?: number;
@@ -87,17 +87,17 @@ interface D1ExecLike {
87
87
  all: (sql: string, parameters: ReadonlyArray<unknown>) => Promise<Record<string, unknown>[]>;
88
88
  }
89
89
  /**
90
- * Import rows into `.global()` tables via the schema-aware D1 writer. The
91
- * writer rejects unknown ids on `insert` (the writer assigns one when `_id` is
92
- * absent); we pre-probe each row's `_id` so a collision is reported as a
93
- * conflict instead of bubbled as a UNIQUE error. Schema-failed rows surface in
94
- * `errors`; the rest land.
95
- */
90
+ * Import rows into `.global()` tables via the schema-aware D1 writer. The
91
+ * writer rejects unknown ids on `insert` (the writer assigns one when `_id` is
92
+ * absent); we pre-probe each row's `_id` so a collision is reported as a
93
+ * conflict instead of bubbled as a UNIQUE error. Schema-failed rows surface in
94
+ * `errors`; the rest land.
95
+ */
96
96
  declare const importGlobalRows: (writer: DatabaseWriterLike, schema: SchemaLike, args: ImportGlobalArgs) => Promise<ImportResult>;
97
97
  /**
98
- * Minimal structural projection of `D1Database` to keep the adapter
99
- * compatible with the real workers-types value as well as unit-test doubles.
100
- */
98
+ * Minimal structural projection of `D1Database` to keep the adapter
99
+ * compatible with the real workers-types value as well as unit-test doubles.
100
+ */
101
101
  interface D1DatabaseLike {
102
102
  batch?: (statements: D1PreparedStatementLike[]) => Promise<unknown[]>;
103
103
  prepare: (sql: string) => D1PreparedStatementLike;
@@ -140,67 +140,67 @@ declare class D1Session {
140
140
  }>;
141
141
  first<T = unknown>(sql: string, ...binds: unknown[]): Promise<T | null>;
142
142
  /**
143
- * Returns the most recent bookmark known to the session, or `undefined`
144
- * when D1 has not issued one yet.
145
- */
143
+ * Returns the most recent bookmark known to the session, or `undefined`
144
+ * when D1 has not issued one yet.
145
+ */
146
146
  getBookmark(): string | undefined;
147
147
  }
148
148
  declare class D1Client {
149
149
  private readonly db;
150
150
  /**
151
- * SQL string -> prepared statement. Prepared statements are reusable in
152
- * D1; preparing the same SQL twice forces the worker to round-trip the
153
- * statement plan. Caching is per-instance so unit-test isolation holds.
154
- * Bounded to {@link STMT_CACHE_CAPACITY} via LRU eviction.
155
- */
151
+ * SQL string -> prepared statement. Prepared statements are reusable in
152
+ * D1; preparing the same SQL twice forces the worker to round-trip the
153
+ * statement plan. Caching is per-instance so unit-test isolation holds.
154
+ * Bounded to {@link STMT_CACHE_CAPACITY} via LRU eviction.
155
+ */
156
156
  private readonly stmtCache;
157
157
  /**
158
- * Lazily-built drizzle handle over the bare binding. Memoised so a single
159
- * `D1Client` reuses the same dialect/session machinery across calls.
160
- */
158
+ * Lazily-built drizzle handle over the bare binding. Memoised so a single
159
+ * `D1Client` reuses the same dialect/session machinery across calls.
160
+ */
161
161
  private drizzleHandle;
162
162
  constructor(database: D1DatabaseLike);
163
163
  /**
164
- * Open a Sessions-API scoped session. Pass the bookmark forwarded by
165
- * the client to opt into read-your-writes consistency.
166
- *
167
- * With no bookmark this is the first request of a session — there is no
168
- * prior write to read, so we open with the explicit `"first-unconstrained"`
169
- * constraint (Cloudflare's lowest-latency default: the first read may serve
170
- * from any replica). Read-your-writes for sequenced requests still flows
171
- * through the forwarded bookmark; a caller needing a strongly-consistent
172
- * very-first read should pass `"first-primary"` as the bookmark instead.
173
- */
164
+ * Open a Sessions-API scoped session. Pass the bookmark forwarded by
165
+ * the client to opt into read-your-writes consistency.
166
+ *
167
+ * With no bookmark this is the first request of a session — there is no
168
+ * prior write to read, so we open with the explicit `"first-unconstrained"`
169
+ * constraint (Cloudflare's lowest-latency default: the first read may serve
170
+ * from any replica). Read-your-writes for sequenced requests still flows
171
+ * through the forwarded bookmark; a caller needing a strongly-consistent
172
+ * very-first read should pass `"first-primary"` as the bookmark instead.
173
+ */
174
174
  withSession(bookmark?: string): D1Session;
175
175
  /**
176
- * Prepare a statement, reusing a cached one when the SQL text matches.
177
- * `bind()` on a prepared statement returns a new bound statement and
178
- * leaves the underlying prepared plan reusable, so cache hits are safe
179
- * even when the previous caller already called `.bind(...).run()`.
180
- */
176
+ * Prepare a statement, reusing a cached one when the SQL text matches.
177
+ * `bind()` on a prepared statement returns a new bound statement and
178
+ * leaves the underlying prepared plan reusable, so cache hits are safe
179
+ * even when the previous caller already called `.bind(...).run()`.
180
+ */
181
181
  prepare(sql: string): D1PreparedStatementLike;
182
182
  /**
183
- * Drizzle handle over the bare `env.DB` binding. Used for typed queries
184
- * against generated `sqliteTable` schemas; does **not** participate in the
185
- * D1 Sessions API (no bookmark pinning). For bookmark-scoped reads, use
186
- * {@link drizzleSession} instead.
187
- */
183
+ * Drizzle handle over the bare `env.DB` binding. Used for typed queries
184
+ * against generated `sqliteTable` schemas; does **not** participate in the
185
+ * D1 Sessions API (no bookmark pinning). For bookmark-scoped reads, use
186
+ * {@link drizzleSession} instead.
187
+ */
188
188
  get drizzle(): DrizzleD1Database<Record<string, unknown>>;
189
189
  /**
190
- * Drizzle handle scoped to a D1 Sessions-API session. The bookmark, when
191
- * supplied, opts into read-your-writes consistency for follow-up reads on
192
- * the same session.
193
- *
194
- * A `D1DatabaseSession` exposes the same `prepare` / `batch` surface
195
- * drizzle calls into, so a single `unknown` cast lets us treat the session
196
- * as a `D1Database` for driver-construction purposes.
197
- */
190
+ * Drizzle handle scoped to a D1 Sessions-API session. The bookmark, when
191
+ * supplied, opts into read-your-writes consistency for follow-up reads on
192
+ * the same session.
193
+ *
194
+ * A `D1DatabaseSession` exposes the same `prepare` / `batch` surface
195
+ * drizzle calls into, so a single `unknown` cast lets us treat the session
196
+ * as a `D1Database` for driver-construction purposes.
197
+ */
198
198
  drizzleSession(bookmark?: string): DrizzleD1Database<Record<string, unknown>>;
199
199
  /**
200
- * Atomic batch over the drizzle d1 driver. Mirrors `db.batch([...])`
201
- * exactly; exposed on the client so callers don't need to hold a drizzle
202
- * handle just to run a typed batch.
203
- */
200
+ * Atomic batch over the drizzle d1 driver. Mirrors `db.batch([...])`
201
+ * exactly; exposed on the client so callers don't need to hold a drizzle
202
+ * handle just to run a typed batch.
203
+ */
204
204
  batch<U extends BatchItem<"sqlite">, T extends Readonly<[U, ...U[]]>>(items: T): Promise<BatchResponse<T>>;
205
205
  /** Direct access to the underlying binding (advanced use only). */
206
206
  get raw(): D1DatabaseLike;
@@ -214,24 +214,24 @@ interface GlobalTableInfo {
214
214
  interface GlobalTablePage {
215
215
  columns: string[];
216
216
  /**
217
- * Foreign-key columns (local column → referenced table) for tables that carry
218
- * real SQL `REFERENCES` constraints — recovered from `PRAGMA foreign_key_list`.
219
- * Schema `.global()` tables omit this (their refs come from `describeTables`);
220
- * external tables (e.g. better-auth's `session`/`twoFactor`) expose it so the
221
- * schema diagram can draw their global→global FK edges.
222
- */
217
+ * Foreign-key columns (local column → referenced table) for tables that carry
218
+ * real SQL `REFERENCES` constraints — recovered from `PRAGMA foreign_key_list`.
219
+ * Schema `.global()` tables omit this (their refs come from `describeTables`);
220
+ * external tables (e.g. better-auth's `session`/`twoFactor`) expose it so the
221
+ * schema diagram can draw their global→global FK edges.
222
+ */
223
223
  refs?: Record<string, string>;
224
224
  rows: Record<string, unknown>[];
225
225
  total: number;
226
226
  }
227
227
  /**
228
- * One equality constraint a facet-value click adds to the global browser's view:
229
- * `column = value` (or `column IS NULL` when `value` is nullish). `column` is a
230
- * displayed column name, validated against the table's columns and mapped to its
231
- * physical column (`_id` → `id`) before it is quoted; `value` is the **raw stored
232
- * value** the facet returned (a SQLite scalar), bound as a parameter and never
233
- * interpolated. AND-combined with the other clauses.
234
- */
228
+ * One equality constraint a facet-value click adds to the global browser's view:
229
+ * `column = value` (or `column IS NULL` when `value` is nullish). `column` is a
230
+ * displayed column name, validated against the table's columns and mapped to its
231
+ * physical column (`_id` → `id`) before it is quoted; `value` is the **raw stored
232
+ * value** the facet returned (a SQLite scalar), bound as a parameter and never
233
+ * interpolated. AND-combined with the other clauses.
234
+ */
235
235
  interface GlobalFilterClause {
236
236
  column: string;
237
237
  value: unknown;
@@ -243,13 +243,13 @@ interface ReadGlobalTablePageOptions {
243
243
  table: string;
244
244
  }
245
245
  /**
246
- * Options for {@link facetGlobalColumn} — the read-only "what values does this
247
- * column hold?" summary for the global (D1) browser. `column` is the displayed
248
- * column to group by (validated and mapped to its physical column, never
249
- * interpolated); `filters` mirrors {@link ReadGlobalTablePageOptions}'s eq
250
- * constraints so the facet reflects the **active view** (the same rows the
251
- * browser is previewing); `limit` caps the distinct values returned (clamped).
252
- */
246
+ * Options for {@link facetGlobalColumn} — the read-only "what values does this
247
+ * column hold?" summary for the global (D1) browser. `column` is the displayed
248
+ * column to group by (validated and mapped to its physical column, never
249
+ * interpolated); `filters` mirrors {@link ReadGlobalTablePageOptions}'s eq
250
+ * constraints so the facet reflects the **active view** (the same rows the
251
+ * browser is previewing); `limit` caps the distinct values returned (clamped).
252
+ */
253
253
  interface FacetGlobalColumnOptions {
254
254
  column: string;
255
255
  filters?: GlobalFilterClause[];
@@ -262,43 +262,43 @@ interface GlobalFacetValue {
262
262
  value: unknown;
263
263
  }
264
264
  /**
265
- * Payload of a {@link facetGlobalColumn} call: the top-N distinct `values` (each
266
- * with a `count`) ordered by frequency, plus `truncated` — `true` when more
267
- * distinct values existed beyond the cap, so the UI can say so rather than imply
268
- * the list is exhaustive. Mirrors the shard browser's `FacetColumnResult`.
269
- */
265
+ * Payload of a {@link facetGlobalColumn} call: the top-N distinct `values` (each
266
+ * with a `count`) ordered by frequency, plus `truncated` — `true` when more
267
+ * distinct values existed beyond the cap, so the UI can say so rather than imply
268
+ * the list is exhaustive. Mirrors the shard browser's `FacetColumnResult`.
269
+ */
270
270
  interface GlobalFacetResult {
271
271
  truncated: boolean;
272
272
  values: GlobalFacetValue[];
273
273
  }
274
274
  /**
275
- * List every browsable D1 table with its row count, ordered by name. Surfaces
276
- * both the schema's `.global()` tables (provisioned first) and external tables
277
- * (auth, etc.); internal/companion tables are excluded.
278
- */
275
+ * List every browsable D1 table with its row count, ordered by name. Surfaces
276
+ * both the schema's `.global()` tables (provisioned first) and external tables
277
+ * (auth, etc.); internal/companion tables are excluded.
278
+ */
279
279
  declare const listGlobalTables: (exec: SqlCtxExec, schema: SchemaLike) => Promise<GlobalTableInfo[]>;
280
280
  /**
281
- * Read a page of rows from one D1 table. The table is validated against the live
282
- * browsable-table list before its name is interpolated, so this can't be coerced
283
- * into reading an internal table or injecting SQL. `limit` is clamped to
284
- * `[1, 500]`; `offset` floors at `0`. `filters` AND-narrows the page to rows
285
- * matching each `column = value` eq constraint (a facet-value drill-down), bound
286
- * through {@link buildEqPredicate} so they never inject SQL.
287
- */
281
+ * Read a page of rows from one D1 table. The table is validated against the live
282
+ * browsable-table list before its name is interpolated, so this can't be coerced
283
+ * into reading an internal table or injecting SQL. `limit` is clamped to
284
+ * `[1, 500]`; `offset` floors at `0`. `filters` AND-narrows the page to rows
285
+ * matching each `column = value` eq constraint (a facet-value drill-down), bound
286
+ * through {@link buildEqPredicate} so they never inject SQL.
287
+ */
288
288
  declare const readGlobalTablePage: (exec: SqlCtxExec, schema: SchemaLike, options: ReadGlobalTablePageOptions) => Promise<GlobalTablePage>;
289
289
  /**
290
- * Summarise the distinct values of one displayed column over the **active view**
291
- * (the same eq `filters` the global browser is previewing) — the D1 twin of the
292
- * shard browser's `facetColumn`. Read-only: a `SELECT col AS value, COUNT(*) AS
293
- * count … GROUP BY col ORDER BY count DESC LIMIT N+1`, with the column validated
294
- * against the table's displayed columns (typed 404 if unknown), mapped to its
295
- * physical column, and quoted — never interpolated from caller input. The extra
296
- * over-fetched row is dropped and surfaced as `truncated`. A sensitive column on
297
- * an external (non-schema) table is never grouped — it collapses to a single
298
- * redacted `•••` bucket — mirroring the page browser's value redaction so the
299
- * facet can't leak credentials. The returned `value` is the raw stored scalar, so
300
- * a click feeds it straight back as an eq filter.
301
- */
290
+ * Summarise the distinct values of one displayed column over the **active view**
291
+ * (the same eq `filters` the global browser is previewing) — the D1 twin of the
292
+ * shard browser's `facetColumn`. Read-only: a `SELECT col AS value, COUNT(*) AS
293
+ * count … GROUP BY col ORDER BY count DESC LIMIT N+1`, with the column validated
294
+ * against the table's displayed columns (typed 404 if unknown), mapped to its
295
+ * physical column, and quoted — never interpolated from caller input. The extra
296
+ * over-fetched row is dropped and surfaced as `truncated`. A sensitive column on
297
+ * an external (non-schema) table is never grouped — it collapses to a single
298
+ * redacted `•••` bucket — mirroring the page browser's value redaction so the
299
+ * facet can't leak credentials. The returned `value` is the raw stored scalar, so
300
+ * a click feeds it straight back as an eq filter.
301
+ */
302
302
  declare const facetGlobalColumn: (exec: SqlCtxExec, schema: SchemaLike, options: FacetGlobalColumnOptions) => Promise<GlobalFacetResult>;
303
303
  interface Migration {
304
304
  /** Human-readable name, e.g. `001_init` (used in logs). */
@@ -319,20 +319,20 @@ interface MigrationRunnerResult {
319
319
  }[];
320
320
  }
321
321
  /**
322
- * Sequentially applies pending migrations against a D1 database via the
323
- * drizzle-orm/d1 driver. Each migration is hashed (SHA-256 over its SQL
324
- * text); the hash is stored in `__drizzle_migrations`, so re-applying the
325
- * same SQL under a different `version` is rejected and identical migrations
326
- * are skipped idempotently.
327
- */
322
+ * Sequentially applies pending migrations against a D1 database via the
323
+ * drizzle-orm/d1 driver. Each migration is hashed (SHA-256 over its SQL
324
+ * text); the hash is stored in `__drizzle_migrations`, so re-applying the
325
+ * same SQL under a different `version` is rejected and identical migrations
326
+ * are skipped idempotently.
327
+ */
328
328
  declare class MigrationRunner {
329
329
  private readonly client;
330
330
  private readonly migrations;
331
331
  /**
332
- * Accepts either a {@link D1Client} (preferred — gets typed batches +
333
- * drizzle handle for free) or a raw `D1DatabaseLike` binding (wrapped on
334
- * the caller's behalf so existing `@lunora/cli` callers keep working).
335
- */
332
+ * Accepts either a {@link D1Client} (preferred — gets typed batches +
333
+ * drizzle handle for free) or a raw `D1DatabaseLike` binding (wrapped on
334
+ * the caller's behalf so existing `@lunora/cli` callers keep working).
335
+ */
336
336
  constructor(database: D1Client | D1DatabaseLike, migrations: Migration[]);
337
337
  run(): Promise<MigrationRunnerResult>;
338
338
  private applyOne;
@@ -340,9 +340,9 @@ declare class MigrationRunner {
340
340
  private assertUniqueSql;
341
341
  }
342
342
  /**
343
- * The canonical SQLite dialect: column affinities, the shared SQLite value
344
- * codec, `RETURNING` support (both D1 and `node:sqlite`), and `sqlite_master`
345
- * table probing. The rest of the per-statement shaping is drizzle's.
346
- */
343
+ * The canonical SQLite dialect: column affinities, the shared SQLite value
344
+ * codec, `RETURNING` support (both D1 and `node:sqlite`), and `sqlite_master`
345
+ * table probing. The rest of the per-statement shaping is drizzle's.
346
+ */
347
347
  declare const sqliteDialect: SqlDialect;
348
348
  export { D1Client, type D1ContextDatabaseOptions as D1CtxDbOptions, type D1DatabaseLike, type D1PreparedStatementLike, D1Session, type D1SessionLike, type ExportGlobalArgs, type FacetGlobalColumnOptions, type ExportRow as GlobalExportRow, type GlobalFacetResult, type GlobalFacetValue, type GlobalFilterClause, type ImportError as GlobalImportError, type ImportResult as GlobalImportResult, type GlobalTableInfo, type GlobalTablePage, type ImportGlobalArgs, type Migration, MigrationRunner, type MigrationRunnerResult, type ReadGlobalTablePageOptions, createD1ContextDatabase as createD1CtxDb, exportGlobalRows, facetGlobalColumn, importGlobalRows, listGlobalTables, readD1CdcChanges, readGlobalTablePage, runD1AggregateMigrations, runD1CdcMigration, runD1GlobalTableMigrations, runD1RankMigrations, runD1SearchMigrations, selectGlobalTables, sqliteDialect, trimD1CdcChanges };
package/dist/index.d.ts CHANGED
@@ -42,42 +42,42 @@ interface ImportResult {
42
42
  inserted: Record<string, number>;
43
43
  }
44
44
  /**
45
- * Return every `.global()` table in the schema, optionally narrowed by an
46
- * allowlist. Shard-local tables are skipped here — they're handled by the DO
47
- * helpers — so callers get a clean separation between the two storage planes.
48
- */
45
+ * Return every `.global()` table in the schema, optionally narrowed by an
46
+ * allowlist. Shard-local tables are skipped here — they're handled by the DO
47
+ * helpers — so callers get a clean separation between the two storage planes.
48
+ */
49
49
  declare const selectGlobalTables: (schema: SchemaLike, requested?: ReadonlyArray<string>) => string[];
50
50
  interface ExportGlobalArgs {
51
51
  batchSize?: number;
52
52
  tables?: ReadonlyArray<string>;
53
53
  }
54
54
  /**
55
- * Yield rows from every requested `.global()` table in batches.
56
- *
57
- * Keyset-paginates on the physical primary key (`id` — every `.global()` table
58
- * carries it, see `frameworkColumnDdl`): `WHERE "id" > ? ORDER BY "id" LIMIT ?`,
59
- * carrying the last id forward. A plain `LIMIT/OFFSET` scan would be wrong here —
60
- * SQLite gives no ordering guarantee for an unordered SELECT and each page is a
61
- * separate query, so pages could overlap or skip rows (and any concurrent
62
- * insert/delete would shift offsets and silently drop/duplicate rows in the
63
- * snapshot). Keyset paging is deterministic under concurrent writes and avoids
64
- * O(n^2) OFFSET scans on large tables.
65
- *
66
- * Tables are provisioned first (idempotent `CREATE … IF NOT EXISTS`): `.global()`
67
- * tables are created lazily on first write, so a fresh deployment — or any table
68
- * never written — would otherwise abort the stream with a raw `no such table`
69
- * instead of exporting it as empty.
70
- */
55
+ * Yield rows from every requested `.global()` table in batches.
56
+ *
57
+ * Keyset-paginates on the physical primary key (`id` — every `.global()` table
58
+ * carries it, see `frameworkColumnDdl`): `WHERE "id" > ? ORDER BY "id" LIMIT ?`,
59
+ * carrying the last id forward. A plain `LIMIT/OFFSET` scan would be wrong here —
60
+ * SQLite gives no ordering guarantee for an unordered SELECT and each page is a
61
+ * separate query, so pages could overlap or skip rows (and any concurrent
62
+ * insert/delete would shift offsets and silently drop/duplicate rows in the
63
+ * snapshot). Keyset paging is deterministic under concurrent writes and avoids
64
+ * O(n^2) OFFSET scans on large tables.
65
+ *
66
+ * Tables are provisioned first (idempotent `CREATE … IF NOT EXISTS`): `.global()`
67
+ * tables are created lazily on first write, so a fresh deployment — or any table
68
+ * never written — would otherwise abort the stream with a raw `no such table`
69
+ * instead of exporting it as empty.
70
+ */
71
71
  declare const exportGlobalRows: (exec: SqlCtxExec, schema: SchemaLike, args: ExportGlobalArgs) => AsyncGenerator<ExportRow, void, undefined>;
72
72
  interface ImportGlobalArgs {
73
73
  /**
74
- * Optional direct exec handle to the same D1 database the writer targets.
75
- * When supplied, the conflict pre-probe issues a single
76
- * `SELECT 1 FROM &lt;table> WHERE id = ? LIMIT 1` against the row's declared
77
- * table instead of falling back to `writer.get(id)`, which scans every
78
- * global table looking for the id. Strongly recommended for large schemas
79
- * — the writer-fallback is O(N tables) per row.
80
- */
74
+ * Optional direct exec handle to the same D1 database the writer targets.
75
+ * When supplied, the conflict pre-probe issues a single
76
+ * `SELECT 1 FROM &lt;table> WHERE id = ? LIMIT 1` against the row's declared
77
+ * table instead of falling back to `writer.get(id)`, which scans every
78
+ * global table looking for the id. Strongly recommended for large schemas
79
+ * — the writer-fallback is O(N tables) per row.
80
+ */
81
81
  exec?: D1ExecLike;
82
82
  rows: ReadonlyArray<ExportRow>;
83
83
  startLine?: number;
@@ -87,17 +87,17 @@ interface D1ExecLike {
87
87
  all: (sql: string, parameters: ReadonlyArray<unknown>) => Promise<Record<string, unknown>[]>;
88
88
  }
89
89
  /**
90
- * Import rows into `.global()` tables via the schema-aware D1 writer. The
91
- * writer rejects unknown ids on `insert` (the writer assigns one when `_id` is
92
- * absent); we pre-probe each row's `_id` so a collision is reported as a
93
- * conflict instead of bubbled as a UNIQUE error. Schema-failed rows surface in
94
- * `errors`; the rest land.
95
- */
90
+ * Import rows into `.global()` tables via the schema-aware D1 writer. The
91
+ * writer rejects unknown ids on `insert` (the writer assigns one when `_id` is
92
+ * absent); we pre-probe each row's `_id` so a collision is reported as a
93
+ * conflict instead of bubbled as a UNIQUE error. Schema-failed rows surface in
94
+ * `errors`; the rest land.
95
+ */
96
96
  declare const importGlobalRows: (writer: DatabaseWriterLike, schema: SchemaLike, args: ImportGlobalArgs) => Promise<ImportResult>;
97
97
  /**
98
- * Minimal structural projection of `D1Database` to keep the adapter
99
- * compatible with the real workers-types value as well as unit-test doubles.
100
- */
98
+ * Minimal structural projection of `D1Database` to keep the adapter
99
+ * compatible with the real workers-types value as well as unit-test doubles.
100
+ */
101
101
  interface D1DatabaseLike {
102
102
  batch?: (statements: D1PreparedStatementLike[]) => Promise<unknown[]>;
103
103
  prepare: (sql: string) => D1PreparedStatementLike;
@@ -140,67 +140,67 @@ declare class D1Session {
140
140
  }>;
141
141
  first<T = unknown>(sql: string, ...binds: unknown[]): Promise<T | null>;
142
142
  /**
143
- * Returns the most recent bookmark known to the session, or `undefined`
144
- * when D1 has not issued one yet.
145
- */
143
+ * Returns the most recent bookmark known to the session, or `undefined`
144
+ * when D1 has not issued one yet.
145
+ */
146
146
  getBookmark(): string | undefined;
147
147
  }
148
148
  declare class D1Client {
149
149
  private readonly db;
150
150
  /**
151
- * SQL string -> prepared statement. Prepared statements are reusable in
152
- * D1; preparing the same SQL twice forces the worker to round-trip the
153
- * statement plan. Caching is per-instance so unit-test isolation holds.
154
- * Bounded to {@link STMT_CACHE_CAPACITY} via LRU eviction.
155
- */
151
+ * SQL string -> prepared statement. Prepared statements are reusable in
152
+ * D1; preparing the same SQL twice forces the worker to round-trip the
153
+ * statement plan. Caching is per-instance so unit-test isolation holds.
154
+ * Bounded to {@link STMT_CACHE_CAPACITY} via LRU eviction.
155
+ */
156
156
  private readonly stmtCache;
157
157
  /**
158
- * Lazily-built drizzle handle over the bare binding. Memoised so a single
159
- * `D1Client` reuses the same dialect/session machinery across calls.
160
- */
158
+ * Lazily-built drizzle handle over the bare binding. Memoised so a single
159
+ * `D1Client` reuses the same dialect/session machinery across calls.
160
+ */
161
161
  private drizzleHandle;
162
162
  constructor(database: D1DatabaseLike);
163
163
  /**
164
- * Open a Sessions-API scoped session. Pass the bookmark forwarded by
165
- * the client to opt into read-your-writes consistency.
166
- *
167
- * With no bookmark this is the first request of a session — there is no
168
- * prior write to read, so we open with the explicit `"first-unconstrained"`
169
- * constraint (Cloudflare's lowest-latency default: the first read may serve
170
- * from any replica). Read-your-writes for sequenced requests still flows
171
- * through the forwarded bookmark; a caller needing a strongly-consistent
172
- * very-first read should pass `"first-primary"` as the bookmark instead.
173
- */
164
+ * Open a Sessions-API scoped session. Pass the bookmark forwarded by
165
+ * the client to opt into read-your-writes consistency.
166
+ *
167
+ * With no bookmark this is the first request of a session — there is no
168
+ * prior write to read, so we open with the explicit `"first-unconstrained"`
169
+ * constraint (Cloudflare's lowest-latency default: the first read may serve
170
+ * from any replica). Read-your-writes for sequenced requests still flows
171
+ * through the forwarded bookmark; a caller needing a strongly-consistent
172
+ * very-first read should pass `"first-primary"` as the bookmark instead.
173
+ */
174
174
  withSession(bookmark?: string): D1Session;
175
175
  /**
176
- * Prepare a statement, reusing a cached one when the SQL text matches.
177
- * `bind()` on a prepared statement returns a new bound statement and
178
- * leaves the underlying prepared plan reusable, so cache hits are safe
179
- * even when the previous caller already called `.bind(...).run()`.
180
- */
176
+ * Prepare a statement, reusing a cached one when the SQL text matches.
177
+ * `bind()` on a prepared statement returns a new bound statement and
178
+ * leaves the underlying prepared plan reusable, so cache hits are safe
179
+ * even when the previous caller already called `.bind(...).run()`.
180
+ */
181
181
  prepare(sql: string): D1PreparedStatementLike;
182
182
  /**
183
- * Drizzle handle over the bare `env.DB` binding. Used for typed queries
184
- * against generated `sqliteTable` schemas; does **not** participate in the
185
- * D1 Sessions API (no bookmark pinning). For bookmark-scoped reads, use
186
- * {@link drizzleSession} instead.
187
- */
183
+ * Drizzle handle over the bare `env.DB` binding. Used for typed queries
184
+ * against generated `sqliteTable` schemas; does **not** participate in the
185
+ * D1 Sessions API (no bookmark pinning). For bookmark-scoped reads, use
186
+ * {@link drizzleSession} instead.
187
+ */
188
188
  get drizzle(): DrizzleD1Database<Record<string, unknown>>;
189
189
  /**
190
- * Drizzle handle scoped to a D1 Sessions-API session. The bookmark, when
191
- * supplied, opts into read-your-writes consistency for follow-up reads on
192
- * the same session.
193
- *
194
- * A `D1DatabaseSession` exposes the same `prepare` / `batch` surface
195
- * drizzle calls into, so a single `unknown` cast lets us treat the session
196
- * as a `D1Database` for driver-construction purposes.
197
- */
190
+ * Drizzle handle scoped to a D1 Sessions-API session. The bookmark, when
191
+ * supplied, opts into read-your-writes consistency for follow-up reads on
192
+ * the same session.
193
+ *
194
+ * A `D1DatabaseSession` exposes the same `prepare` / `batch` surface
195
+ * drizzle calls into, so a single `unknown` cast lets us treat the session
196
+ * as a `D1Database` for driver-construction purposes.
197
+ */
198
198
  drizzleSession(bookmark?: string): DrizzleD1Database<Record<string, unknown>>;
199
199
  /**
200
- * Atomic batch over the drizzle d1 driver. Mirrors `db.batch([...])`
201
- * exactly; exposed on the client so callers don't need to hold a drizzle
202
- * handle just to run a typed batch.
203
- */
200
+ * Atomic batch over the drizzle d1 driver. Mirrors `db.batch([...])`
201
+ * exactly; exposed on the client so callers don't need to hold a drizzle
202
+ * handle just to run a typed batch.
203
+ */
204
204
  batch<U extends BatchItem<"sqlite">, T extends Readonly<[U, ...U[]]>>(items: T): Promise<BatchResponse<T>>;
205
205
  /** Direct access to the underlying binding (advanced use only). */
206
206
  get raw(): D1DatabaseLike;
@@ -214,24 +214,24 @@ interface GlobalTableInfo {
214
214
  interface GlobalTablePage {
215
215
  columns: string[];
216
216
  /**
217
- * Foreign-key columns (local column → referenced table) for tables that carry
218
- * real SQL `REFERENCES` constraints — recovered from `PRAGMA foreign_key_list`.
219
- * Schema `.global()` tables omit this (their refs come from `describeTables`);
220
- * external tables (e.g. better-auth's `session`/`twoFactor`) expose it so the
221
- * schema diagram can draw their global→global FK edges.
222
- */
217
+ * Foreign-key columns (local column → referenced table) for tables that carry
218
+ * real SQL `REFERENCES` constraints — recovered from `PRAGMA foreign_key_list`.
219
+ * Schema `.global()` tables omit this (their refs come from `describeTables`);
220
+ * external tables (e.g. better-auth's `session`/`twoFactor`) expose it so the
221
+ * schema diagram can draw their global→global FK edges.
222
+ */
223
223
  refs?: Record<string, string>;
224
224
  rows: Record<string, unknown>[];
225
225
  total: number;
226
226
  }
227
227
  /**
228
- * One equality constraint a facet-value click adds to the global browser's view:
229
- * `column = value` (or `column IS NULL` when `value` is nullish). `column` is a
230
- * displayed column name, validated against the table's columns and mapped to its
231
- * physical column (`_id` → `id`) before it is quoted; `value` is the **raw stored
232
- * value** the facet returned (a SQLite scalar), bound as a parameter and never
233
- * interpolated. AND-combined with the other clauses.
234
- */
228
+ * One equality constraint a facet-value click adds to the global browser's view:
229
+ * `column = value` (or `column IS NULL` when `value` is nullish). `column` is a
230
+ * displayed column name, validated against the table's columns and mapped to its
231
+ * physical column (`_id` → `id`) before it is quoted; `value` is the **raw stored
232
+ * value** the facet returned (a SQLite scalar), bound as a parameter and never
233
+ * interpolated. AND-combined with the other clauses.
234
+ */
235
235
  interface GlobalFilterClause {
236
236
  column: string;
237
237
  value: unknown;
@@ -243,13 +243,13 @@ interface ReadGlobalTablePageOptions {
243
243
  table: string;
244
244
  }
245
245
  /**
246
- * Options for {@link facetGlobalColumn} — the read-only "what values does this
247
- * column hold?" summary for the global (D1) browser. `column` is the displayed
248
- * column to group by (validated and mapped to its physical column, never
249
- * interpolated); `filters` mirrors {@link ReadGlobalTablePageOptions}'s eq
250
- * constraints so the facet reflects the **active view** (the same rows the
251
- * browser is previewing); `limit` caps the distinct values returned (clamped).
252
- */
246
+ * Options for {@link facetGlobalColumn} — the read-only "what values does this
247
+ * column hold?" summary for the global (D1) browser. `column` is the displayed
248
+ * column to group by (validated and mapped to its physical column, never
249
+ * interpolated); `filters` mirrors {@link ReadGlobalTablePageOptions}'s eq
250
+ * constraints so the facet reflects the **active view** (the same rows the
251
+ * browser is previewing); `limit` caps the distinct values returned (clamped).
252
+ */
253
253
  interface FacetGlobalColumnOptions {
254
254
  column: string;
255
255
  filters?: GlobalFilterClause[];
@@ -262,43 +262,43 @@ interface GlobalFacetValue {
262
262
  value: unknown;
263
263
  }
264
264
  /**
265
- * Payload of a {@link facetGlobalColumn} call: the top-N distinct `values` (each
266
- * with a `count`) ordered by frequency, plus `truncated` — `true` when more
267
- * distinct values existed beyond the cap, so the UI can say so rather than imply
268
- * the list is exhaustive. Mirrors the shard browser's `FacetColumnResult`.
269
- */
265
+ * Payload of a {@link facetGlobalColumn} call: the top-N distinct `values` (each
266
+ * with a `count`) ordered by frequency, plus `truncated` — `true` when more
267
+ * distinct values existed beyond the cap, so the UI can say so rather than imply
268
+ * the list is exhaustive. Mirrors the shard browser's `FacetColumnResult`.
269
+ */
270
270
  interface GlobalFacetResult {
271
271
  truncated: boolean;
272
272
  values: GlobalFacetValue[];
273
273
  }
274
274
  /**
275
- * List every browsable D1 table with its row count, ordered by name. Surfaces
276
- * both the schema's `.global()` tables (provisioned first) and external tables
277
- * (auth, etc.); internal/companion tables are excluded.
278
- */
275
+ * List every browsable D1 table with its row count, ordered by name. Surfaces
276
+ * both the schema's `.global()` tables (provisioned first) and external tables
277
+ * (auth, etc.); internal/companion tables are excluded.
278
+ */
279
279
  declare const listGlobalTables: (exec: SqlCtxExec, schema: SchemaLike) => Promise<GlobalTableInfo[]>;
280
280
  /**
281
- * Read a page of rows from one D1 table. The table is validated against the live
282
- * browsable-table list before its name is interpolated, so this can't be coerced
283
- * into reading an internal table or injecting SQL. `limit` is clamped to
284
- * `[1, 500]`; `offset` floors at `0`. `filters` AND-narrows the page to rows
285
- * matching each `column = value` eq constraint (a facet-value drill-down), bound
286
- * through {@link buildEqPredicate} so they never inject SQL.
287
- */
281
+ * Read a page of rows from one D1 table. The table is validated against the live
282
+ * browsable-table list before its name is interpolated, so this can't be coerced
283
+ * into reading an internal table or injecting SQL. `limit` is clamped to
284
+ * `[1, 500]`; `offset` floors at `0`. `filters` AND-narrows the page to rows
285
+ * matching each `column = value` eq constraint (a facet-value drill-down), bound
286
+ * through {@link buildEqPredicate} so they never inject SQL.
287
+ */
288
288
  declare const readGlobalTablePage: (exec: SqlCtxExec, schema: SchemaLike, options: ReadGlobalTablePageOptions) => Promise<GlobalTablePage>;
289
289
  /**
290
- * Summarise the distinct values of one displayed column over the **active view**
291
- * (the same eq `filters` the global browser is previewing) — the D1 twin of the
292
- * shard browser's `facetColumn`. Read-only: a `SELECT col AS value, COUNT(*) AS
293
- * count … GROUP BY col ORDER BY count DESC LIMIT N+1`, with the column validated
294
- * against the table's displayed columns (typed 404 if unknown), mapped to its
295
- * physical column, and quoted — never interpolated from caller input. The extra
296
- * over-fetched row is dropped and surfaced as `truncated`. A sensitive column on
297
- * an external (non-schema) table is never grouped — it collapses to a single
298
- * redacted `•••` bucket — mirroring the page browser's value redaction so the
299
- * facet can't leak credentials. The returned `value` is the raw stored scalar, so
300
- * a click feeds it straight back as an eq filter.
301
- */
290
+ * Summarise the distinct values of one displayed column over the **active view**
291
+ * (the same eq `filters` the global browser is previewing) — the D1 twin of the
292
+ * shard browser's `facetColumn`. Read-only: a `SELECT col AS value, COUNT(*) AS
293
+ * count … GROUP BY col ORDER BY count DESC LIMIT N+1`, with the column validated
294
+ * against the table's displayed columns (typed 404 if unknown), mapped to its
295
+ * physical column, and quoted — never interpolated from caller input. The extra
296
+ * over-fetched row is dropped and surfaced as `truncated`. A sensitive column on
297
+ * an external (non-schema) table is never grouped — it collapses to a single
298
+ * redacted `•••` bucket — mirroring the page browser's value redaction so the
299
+ * facet can't leak credentials. The returned `value` is the raw stored scalar, so
300
+ * a click feeds it straight back as an eq filter.
301
+ */
302
302
  declare const facetGlobalColumn: (exec: SqlCtxExec, schema: SchemaLike, options: FacetGlobalColumnOptions) => Promise<GlobalFacetResult>;
303
303
  interface Migration {
304
304
  /** Human-readable name, e.g. `001_init` (used in logs). */
@@ -319,20 +319,20 @@ interface MigrationRunnerResult {
319
319
  }[];
320
320
  }
321
321
  /**
322
- * Sequentially applies pending migrations against a D1 database via the
323
- * drizzle-orm/d1 driver. Each migration is hashed (SHA-256 over its SQL
324
- * text); the hash is stored in `__drizzle_migrations`, so re-applying the
325
- * same SQL under a different `version` is rejected and identical migrations
326
- * are skipped idempotently.
327
- */
322
+ * Sequentially applies pending migrations against a D1 database via the
323
+ * drizzle-orm/d1 driver. Each migration is hashed (SHA-256 over its SQL
324
+ * text); the hash is stored in `__drizzle_migrations`, so re-applying the
325
+ * same SQL under a different `version` is rejected and identical migrations
326
+ * are skipped idempotently.
327
+ */
328
328
  declare class MigrationRunner {
329
329
  private readonly client;
330
330
  private readonly migrations;
331
331
  /**
332
- * Accepts either a {@link D1Client} (preferred — gets typed batches +
333
- * drizzle handle for free) or a raw `D1DatabaseLike` binding (wrapped on
334
- * the caller's behalf so existing `@lunora/cli` callers keep working).
335
- */
332
+ * Accepts either a {@link D1Client} (preferred — gets typed batches +
333
+ * drizzle handle for free) or a raw `D1DatabaseLike` binding (wrapped on
334
+ * the caller's behalf so existing `@lunora/cli` callers keep working).
335
+ */
336
336
  constructor(database: D1Client | D1DatabaseLike, migrations: Migration[]);
337
337
  run(): Promise<MigrationRunnerResult>;
338
338
  private applyOne;
@@ -340,9 +340,9 @@ declare class MigrationRunner {
340
340
  private assertUniqueSql;
341
341
  }
342
342
  /**
343
- * The canonical SQLite dialect: column affinities, the shared SQLite value
344
- * codec, `RETURNING` support (both D1 and `node:sqlite`), and `sqlite_master`
345
- * table probing. The rest of the per-statement shaping is drizzle's.
346
- */
343
+ * The canonical SQLite dialect: column affinities, the shared SQLite value
344
+ * codec, `RETURNING` support (both D1 and `node:sqlite`), and `sqlite_master`
345
+ * table probing. The rest of the per-statement shaping is drizzle's.
346
+ */
347
347
  declare const sqliteDialect: SqlDialect;
348
348
  export { D1Client, type D1ContextDatabaseOptions as D1CtxDbOptions, type D1DatabaseLike, type D1PreparedStatementLike, D1Session, type D1SessionLike, type ExportGlobalArgs, type FacetGlobalColumnOptions, type ExportRow as GlobalExportRow, type GlobalFacetResult, type GlobalFacetValue, type GlobalFilterClause, type ImportError as GlobalImportError, type ImportResult as GlobalImportResult, type GlobalTableInfo, type GlobalTablePage, type ImportGlobalArgs, type Migration, MigrationRunner, type MigrationRunnerResult, type ReadGlobalTablePageOptions, createD1ContextDatabase as createD1CtxDb, exportGlobalRows, facetGlobalColumn, importGlobalRows, listGlobalTables, readD1CdcChanges, readGlobalTablePage, runD1AggregateMigrations, runD1CdcMigration, runD1GlobalTableMigrations, runD1RankMigrations, runD1SearchMigrations, selectGlobalTables, sqliteDialect, trimD1CdcChanges };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/d1",
3
- "version": "1.0.0-alpha.32",
3
+ "version": "1.0.0-alpha.33",
4
4
  "description": "D1 adapter for Lunora .global() tables, wrapping the Sessions API for read-your-writes",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -50,9 +50,9 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "@lunora/do": "1.0.0-alpha.33",
54
- "@lunora/errors": "1.0.0-alpha.5",
55
- "@lunora/sql-store": "1.0.0-alpha.33",
53
+ "@lunora/do": "1.0.0-alpha.34",
54
+ "@lunora/errors": "1.0.0-alpha.6",
55
+ "@lunora/sql-store": "1.0.0-alpha.34",
56
56
  "drizzle-orm": "^0.45.2"
57
57
  },
58
58
  "engines": {