@lunora/sql-store 1.0.0-alpha.8 → 1.0.0-alpha.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +6 -0
- package/dist/dialect.d.mts +136 -38
- package/dist/dialect.d.ts +136 -38
- package/dist/dialect.mjs +0 -1
- package/dist/index.d.mts +185 -107
- package/dist/index.d.ts +185 -107
- package/dist/index.mjs +1 -2
- package/dist/packem_shared/SEARCH_STATE_TABLE-DA3LgCT0.mjs +1 -0
- package/dist/packem_shared/backfillSqlSearchIndexes-BRlUTReN.mjs +1 -0
- package/dist/packem_shared/createSqlCtxDb-CRX3OS05.mjs +1 -0
- package/dist/packem_shared/ctx-db-search-Cl6zlJ11.mjs +1 -0
- package/dist/packem_shared/decodeBigint-B4wY6fcF.mjs +1 -0
- package/dist/packem_shared/decodeGlobalRow-BKIjk_Zk.mjs +1 -0
- package/package.json +3 -2
- package/dist/packem_shared/createSqlCtxDb-DYqDyPq8.mjs +0 -1754
- package/dist/packem_shared/decodeBigint-Dedu92k4.mjs +0 -69
package/dist/index.d.mts
CHANGED
|
@@ -1,121 +1,150 @@
|
|
|
1
|
-
import { ServerDefaultContextLike, DatabaseWriterLike,
|
|
2
|
-
import {
|
|
1
|
+
import { TableDefinitionLike, SchemaLike, ServerDefaultContextLike, DatabaseWriterLike, CrossShardReadArgs, QueryPage, SchedulerLike, ValidatorLike } from '@lunora/shard-engine';
|
|
2
|
+
import { SqlRunResult, SqlDialect } from "./dialect.mjs";
|
|
3
3
|
export type { SqlExec } from "./dialect.mjs";
|
|
4
4
|
import 'drizzle-orm';
|
|
5
5
|
/**
|
|
6
|
-
* Async SQL surface the D1 ORM needs: `all` for reads, `run` for writes.
|
|
7
|
-
* Satisfied by a `D1Session`/`D1Client` in production and a `node:sqlite`
|
|
8
|
-
* adapter in tests, so the query logic runs against a real SQLite engine.
|
|
9
|
-
*/
|
|
6
|
+
* Async SQL surface the D1 ORM needs: `all` for reads, `run` for writes.
|
|
7
|
+
* Satisfied by a `D1Session`/`D1Client` in production and a `node:sqlite`
|
|
8
|
+
* adapter in tests, so the query logic runs against a real SQLite engine.
|
|
9
|
+
*/
|
|
10
10
|
interface SqlCtxExec {
|
|
11
11
|
all: (sql: string, parameters: ReadonlyArray<unknown>) => Promise<Record<string, unknown>[]>;
|
|
12
|
+
batch?: (statements: ReadonlyArray<{
|
|
13
|
+
params: ReadonlyArray<unknown>;
|
|
14
|
+
sql: string;
|
|
15
|
+
}>) => Promise<void>;
|
|
12
16
|
run: (sql: string, parameters: ReadonlyArray<unknown>) => Promise<SqlRunResult | void>;
|
|
13
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Decode a SELECTed row back into a document: `id` → `_id`, `_creationTime`
|
|
20
|
+
* preserved, and every column run through the shared {@link sqliteDecode} so the
|
|
21
|
+
* stored form is reversed back into its JS shape. Exported so the data-browser
|
|
22
|
+
* (`introspect.ts`) and admin export/import paths share the exact same decode.
|
|
23
|
+
*
|
|
24
|
+
* The decode is engine-agnostic: every backend stores SQLite-shaped values
|
|
25
|
+
* (boolean → 1/0, JSON → text, bigint → decimal string), and `sqliteDecode` is
|
|
26
|
+
* robust to a driver returning either the stored string OR a natively-parsed
|
|
27
|
+
* value (e.g. mysql2 returns JSON columns pre-parsed) — so the same decoder is
|
|
28
|
+
* correct on SQLite, Postgres and MySQL.
|
|
29
|
+
*/
|
|
30
|
+
declare const decodeGlobalRow: (definition: TableDefinitionLike, row: Record<string, unknown>) => Record<string, unknown>;
|
|
31
|
+
/**
|
|
32
|
+
* Provision the search companions, then index one bounded page of the rows that
|
|
33
|
+
* predate each index — unless it is declared `staged: true`, which leaves the
|
|
34
|
+
* whole backfill to {@link backfillSqlSearchIndexes}.
|
|
35
|
+
*
|
|
36
|
+
* Idempotent (`CREATE … IF NOT EXISTS` throughout, and the backfill resumes
|
|
37
|
+
* from recorded progress).
|
|
38
|
+
*/
|
|
39
|
+
declare const runSqlSearchMigrations: (exec: SqlCtxExec, schema: SchemaLike, dialect: SqlDialect) => Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Run every declared search index — including the `staged: true` ones the
|
|
42
|
+
* migration pass skips — through to completion. The entry point a host calls
|
|
43
|
+
* out-of-band after deploying a search index over a table too large to index a
|
|
44
|
+
* page at a time.
|
|
45
|
+
*
|
|
46
|
+
* Idempotent and resumable: an index recorded as complete is skipped, and an
|
|
47
|
+
* interrupted run picks up from its cursor.
|
|
48
|
+
*/
|
|
49
|
+
declare const backfillSqlSearchIndexes: (exec: SqlCtxExec, schema: SchemaLike, dialect: SqlDialect) => Promise<void>;
|
|
14
50
|
interface SqlCtxDbOptions {
|
|
15
51
|
/**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
52
|
+
* Resolved request auth handed to `.serverDefault(fn)` column factories so
|
|
53
|
+
* server-trusted columns (owner/tenant ids) stamp from the verified caller,
|
|
54
|
+
* never the client. The generated worker passes the per-request identity;
|
|
55
|
+
* absent it, server-trusted columns stamp the anonymous slice (`userId: null`).
|
|
56
|
+
*/
|
|
21
57
|
auth?: ServerDefaultContextLike["auth"];
|
|
22
58
|
/**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
59
|
+
* Opt into change-data-capture: when `true`, every committed write appends a
|
|
60
|
+
* post-image to the `__cdc_log` table (created lazily alongside the other
|
|
61
|
+
* companion tables). Backs CDC streaming export for `.global()` tables — the
|
|
62
|
+
* log is for export/CDC consumers, NOT point-in-time recovery: D1's PITR is
|
|
63
|
+
* the platform's own Time Travel (`wrangler d1 time-travel restore`), an
|
|
64
|
+
* atomic restore, not a changelog replay. Leave undefined for zero-cost
|
|
65
|
+
* legacy behaviour.
|
|
66
|
+
*/
|
|
31
67
|
cdc?: boolean;
|
|
32
68
|
clock?: () => number;
|
|
33
69
|
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
70
|
+
* Cross-shard counter for **reverse cross-backend relations** — the `_count`
|
|
71
|
+
* mirror of the `crossShardReader` option below.
|
|
72
|
+
*/
|
|
37
73
|
crossShardCounter?: DatabaseWriterLike["count"];
|
|
38
74
|
/**
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
75
|
+
* Optional cross-shard reader for **reverse cross-backend relations**: a
|
|
76
|
+
* `.global()` (D1) parent loading a shard-local (`.shardBy()`/root) child.
|
|
77
|
+
* Such a child's rows are partitioned across every shard DO, so the local D1
|
|
78
|
+
* writer can't resolve it. When provided, the relation loader routes the
|
|
79
|
+
* child's read through this (the host wires it to the Query Coordinator's
|
|
80
|
+
* RLS-correct `fanOut`, with identity forwarded so each shard applies its own
|
|
81
|
+
* RLS). Absent it, loading such a relation throws a clear "not supported"
|
|
82
|
+
* error (legacy behaviour). The forward direction (shard-local parent →
|
|
83
|
+
* global child) and same-backend relations never touch this.
|
|
84
|
+
*
|
|
85
|
+
* Takes {@link CrossShardReadArgs}, not `QueryArgs`: the hop is JSON, so the
|
|
86
|
+
* RLS filters are handed over as data (see that type's docblock).
|
|
87
|
+
*/
|
|
88
|
+
crossShardReader?: (table: string, args: CrossShardReadArgs) => Promise<QueryPage>;
|
|
50
89
|
/**
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
90
|
+
* The SQL dialect that shapes every statement (identifier quoting, value
|
|
91
|
+
* encode/decode, column types, upserts, RETURNING vs affected-rows).
|
|
92
|
+
* `@lunora/d1` passes its `sqliteDialect`; the PlanetScale/Hyperdrive backend
|
|
93
|
+
* passes its Postgres/MySQL dialect. Required — the core is engine-blind.
|
|
94
|
+
*/
|
|
56
95
|
dialect: SqlDialect;
|
|
57
96
|
exec: SqlCtxExec;
|
|
58
97
|
idGenerator?: () => string;
|
|
59
98
|
/**
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
99
|
+
* Ceiling on the number of child join keys a relation-crossing `where`
|
|
100
|
+
* predicate may materialize before the semijoin pre-resolver fails closed
|
|
101
|
+
* (`relation predicate … exceeding the N-key limit`). D1 has no EXISTS
|
|
102
|
+
* push-down, so an overflow here can only fail closed — never truncate the
|
|
103
|
+
* `IN (...)` and silently mis-match. Defaults to the pre-resolver's shared
|
|
104
|
+
* key cap when omitted.
|
|
105
|
+
*/
|
|
67
106
|
maxRelationKeys?: number;
|
|
68
107
|
/**
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
108
|
+
* Scheduler exposed to global-table trigger handlers as `ctx.scheduler`.
|
|
109
|
+
* Absent it, `ctx.scheduler` is a stub that throws on use — pass one when
|
|
110
|
+
* triggers on `.global()` tables need to enqueue follow-up work.
|
|
111
|
+
*/
|
|
73
112
|
scheduler?: SchedulerLike;
|
|
74
113
|
schema: SchemaLike;
|
|
75
114
|
}
|
|
76
115
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
|
|
88
|
-
|
|
116
|
+
* Auto-provision every `.global()` table from the schema: `CREATE TABLE IF NOT
|
|
117
|
+
* EXISTS` with the physical `id`/`_creationTime` columns plus a typed column per
|
|
118
|
+
* declared field, then its secondary and `.unique()` indexes. This is the D1
|
|
119
|
+
* twin of `@lunora/do`'s `runShardMigrations` (which self-creates shard-local
|
|
120
|
+
* tables) — it makes the schema the single source of truth for global tables
|
|
121
|
+
* too, so a fresh database serves them without a hand-applied migration. The
|
|
122
|
+
* column set and dialect match exactly what this module reads and writes
|
|
123
|
+
* (`columnRef`, `serializeColumnValue`, `decodeGlobalRow`).
|
|
124
|
+
*
|
|
125
|
+
* Idempotent (`CREATE TABLE/INDEX IF NOT EXISTS`); additive only — it never
|
|
126
|
+
* drops or retypes an existing column, so destructive schema changes still need
|
|
127
|
+
* an explicit migration.
|
|
128
|
+
*/
|
|
89
129
|
declare const runSqlGlobalTableMigrations: (exec: SqlCtxExec, schema: SchemaLike, dialect: SqlDialect) => Promise<void>;
|
|
90
130
|
/**
|
|
91
|
-
* Materialize the `__agg_
|
|
92
|
-
* `aggregateIndex` on a global table. Global tables in Lunora ship their own
|
|
93
|
-
* DDL — counter tables are opt-in so production hosts can decide where they
|
|
94
|
-
* live. Tests and dev hosts can call this once after their schema migration to
|
|
95
|
-
* unlock O(1) counts.
|
|
96
|
-
*
|
|
97
|
-
* Idempotent (`CREATE TABLE IF NOT EXISTS`).
|
|
98
|
-
*/
|
|
131
|
+
* Materialize the `__agg_<index>` companion tables for every declared
|
|
132
|
+
* `aggregateIndex` on a global table. Global tables in Lunora ship their own
|
|
133
|
+
* DDL — counter tables are opt-in so production hosts can decide where they
|
|
134
|
+
* live. Tests and dev hosts can call this once after their schema migration to
|
|
135
|
+
* unlock O(1) counts.
|
|
136
|
+
*
|
|
137
|
+
* Idempotent (`CREATE TABLE IF NOT EXISTS`).
|
|
138
|
+
*/
|
|
99
139
|
declare const runSqlAggregateMigrations: (exec: SqlCtxExec, schema: SchemaLike, dialect: SqlDialect) => Promise<void>;
|
|
100
140
|
/**
|
|
101
|
-
* Materialize the `__rank_
|
|
102
|
-
* `rankIndex` on a global table. Mirrors `runSqlAggregateMigrations` — same
|
|
103
|
-
* opt-in pattern so production hosts decide whether to spend the DDL.
|
|
104
|
-
*
|
|
105
|
-
* Idempotent (`CREATE TABLE IF NOT EXISTS` + `createIndexIfNotExists`).
|
|
106
|
-
*/
|
|
141
|
+
* Materialize the `__rank_<index>` companion tables for every declared
|
|
142
|
+
* `rankIndex` on a global table. Mirrors `runSqlAggregateMigrations` — same
|
|
143
|
+
* opt-in pattern so production hosts decide whether to spend the DDL.
|
|
144
|
+
*
|
|
145
|
+
* Idempotent (`CREATE TABLE IF NOT EXISTS` + `createIndexIfNotExists`).
|
|
146
|
+
*/
|
|
107
147
|
declare const runSqlRankMigrations: (exec: SqlCtxExec, schema: SchemaLike, dialect: SqlDialect) => Promise<void>;
|
|
108
|
-
/**
|
|
109
|
-
* Materialize the `__fts_<index>` FTS5 shadow tables for every declared
|
|
110
|
-
* `.searchIndex()` on a global table. Mirrors `runSqlAggregateMigrations` — same
|
|
111
|
-
* opt-in pattern so production hosts decide whether to spend the DDL. Only runs
|
|
112
|
-
* on engines that ship FTS5 (D1 does; the `node:sqlite` test runner doesn't,
|
|
113
|
-
* where `.search()` transparently falls back to a scan). `__text__` holds the
|
|
114
|
-
* indexed field; `__id__` (UNINDEXED) joins back to the row.
|
|
115
|
-
*
|
|
116
|
-
* Idempotent (`CREATE VIRTUAL TABLE IF NOT EXISTS`).
|
|
117
|
-
*/
|
|
118
|
-
declare const runSqlSearchMigrations: (exec: SqlCtxExec, schema: SchemaLike, dialect: SqlDialect) => Promise<void>;
|
|
119
148
|
/** One change-data-capture entry: a committed mutation, in monotonic `seq` order. Mirrors the DO twin. */
|
|
120
149
|
interface CdcChange {
|
|
121
150
|
/** Post-image document for insert/update; absent for delete (the `id` identifies the removed row). */
|
|
@@ -131,9 +160,9 @@ interface CdcChange {
|
|
|
131
160
|
/** Create the `__cdc_log` table. Idempotent; only run when CDC is enabled. */
|
|
132
161
|
declare const runSqlCdcMigration: (exec: SqlCtxExec, dialect: SqlDialect) => Promise<void>;
|
|
133
162
|
/**
|
|
134
|
-
* Read changelog entries newer than `sinceSeq` in commit order, up to `limit`
|
|
135
|
-
* (clamped to [1, 10000]); plus the cursor to resume from.
|
|
136
|
-
*/
|
|
163
|
+
* Read changelog entries newer than `sinceSeq` in commit order, up to `limit`
|
|
164
|
+
* (clamped to [1, 10000]); plus the cursor to resume from.
|
|
165
|
+
*/
|
|
137
166
|
declare const readSqlCdcChanges: (exec: SqlCtxExec, options: {
|
|
138
167
|
limit?: number;
|
|
139
168
|
sinceSeq?: number;
|
|
@@ -144,6 +173,10 @@ declare const readSqlCdcChanges: (exec: SqlCtxExec, options: {
|
|
|
144
173
|
/** Drop changelog entries at or below a checkpointed `throughSeq` (retention). */
|
|
145
174
|
declare const trimSqlCdcChanges: (exec: SqlCtxExec, throughSeq: number, dialect: SqlDialect) => Promise<void>;
|
|
146
175
|
declare const createSqlCtxDb: (options: SqlCtxDbOptions) => DatabaseWriterLike;
|
|
176
|
+
/** Reserved table holding one backfill-progress row per search companion. */
|
|
177
|
+
declare const SEARCH_STATE_TABLE = "__lunora_search_state";
|
|
178
|
+
/** Create the progress table. Idempotent; runs alongside the companion DDL. */
|
|
179
|
+
declare const migrateSearchState: (exec: SqlCtxExec, dialect: SqlDialect) => Promise<void>;
|
|
147
180
|
/** Map a JS value onto its SQLite storage form — SQLite has no boolean, so true/false → 1/0. */
|
|
148
181
|
declare const sqliteEncode: (value: unknown) => unknown;
|
|
149
182
|
/** Parse `raw` as JSON, returning `raw` unchanged when it is not valid JSON. */
|
|
@@ -151,24 +184,69 @@ declare const tryJsonParse: (raw: string) => unknown;
|
|
|
151
184
|
/** Decode a `bigint` column: a decimal string back into a `BigInt`, else verbatim. */
|
|
152
185
|
declare const decodeBigint: (raw: unknown) => unknown;
|
|
153
186
|
/**
|
|
154
|
-
* Resolve the *effective* storage kind of a column validator.
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
|
|
187
|
+
* Resolve the *effective* storage kind of a column validator: `v.optional(inner)`
|
|
188
|
+
* unwrapped to `inner`'s kind, since encoding keys off the runtime value's JS
|
|
189
|
+
* type and the validator's own `kind` of `"optional"` hides that.
|
|
190
|
+
*
|
|
191
|
+
* A thin alias over `shared/effective-kind`, which is where the rule lives so
|
|
192
|
+
* the DO row store applies the identical one — it reads the same validators and
|
|
193
|
+
* has the same failure mode, and two copies drifted the last time.
|
|
194
|
+
*/
|
|
161
195
|
declare const effectiveColumnKind: (validator: ValidatorLike) => string | undefined;
|
|
162
196
|
/**
|
|
163
|
-
* Inverse of {@link sqliteEncode}: map a SQLite storage value back onto its JS
|
|
164
|
-
* form, driven by the field's effective validator `kind`:
|
|
165
|
-
*
|
|
166
|
-
* - `boolean`: 1/0 → true/false (SQLite has no boolean type).
|
|
167
|
-
* - `bigint`: decimal string → `BigInt`.
|
|
168
|
-
* - `
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
|
|
197
|
+
* Inverse of {@link sqliteEncode}: map a SQLite storage value back onto its JS
|
|
198
|
+
* form, driven by the field's effective validator `kind`:
|
|
199
|
+
*
|
|
200
|
+
* - `boolean`: 1/0 → true/false (SQLite has no boolean type).
|
|
201
|
+
* - `bigint`: decimal string → `BigInt`.
|
|
202
|
+
* - `bytes`: normalizes any driver return shape to a genuine `ArrayBuffer` — a
|
|
203
|
+
* view (`Uint8Array`/`Buffer`/…) is sliced to its own byte window, a plain
|
|
204
|
+
* `ArrayBuffer` passes through. Required because `v.bytes()` validates
|
|
205
|
+
* `value instanceof ArrayBuffer` and different backends return different BLOB
|
|
206
|
+
* shapes (workerd D1 `ArrayBuffer`, node:sqlite `Uint8Array`, pg/mysql2 `Buffer`).
|
|
207
|
+
* - `object`/`array`/`record`: JSON string → parsed value.
|
|
208
|
+
* - `union`/`any`/`from`: parsed back only when the stored string is a JSON
|
|
209
|
+
* non-scalar (a scalar member round-trips through SQLite's native column type).
|
|
210
|
+
* `from` belongs to THIS group, not to `object`/`array`/`record`: an external
|
|
211
|
+
* Standard Schema can describe a string just as easily as an object, and
|
|
212
|
+
* {@link sqliteEncode} keys off the runtime JS type — so a `v.from(z.string())`
|
|
213
|
+
* column holding `"123"` is stored verbatim, and unconditional parsing would
|
|
214
|
+
* read it back as the NUMBER 123.
|
|
215
|
+
* CAVEAT: a union/any/from member is stored verbatim by {@link sqliteEncode}, so
|
|
216
|
+
* a legitimate *string* value that itself looks like JSON (`'{"a":1}'`, `'[1,2]'`)
|
|
217
|
+
* is ambiguous on read and decodes back to the parsed object/array, not the
|
|
218
|
+
* original string. This is inherent to sharing one TEXT column between a string
|
|
219
|
+
* and an object member; disambiguating would require a breaking storage-format
|
|
220
|
+
* change (tagging encoded non-scalars), so it is documented rather than fixed.
|
|
221
|
+
* - everything else (string/number/date/timestamp/id/literal): verbatim.
|
|
222
|
+
*/
|
|
173
223
|
declare const sqliteDecode: (raw: unknown, kind: string | undefined) => unknown;
|
|
174
|
-
export {
|
|
224
|
+
export { SEARCH_STATE_TABLE,
|
|
225
|
+
/**
|
|
226
|
+
* `@lunora/sql-store` — the internal, dialect-parameterized SQL store core
|
|
227
|
+
* shared by Lunora's `.global()` table backends.
|
|
228
|
+
*
|
|
229
|
+
* One ORM implementation (`createSqlCtxDb`) drives any SQL engine through a
|
|
230
|
+
* `SqlDialect`: SQLite via `@lunora/d1`, and Postgres/MySQL (PlanetScale, Neon,
|
|
231
|
+
* any Hyperdrive-reachable database) via `@lunora/hyperdrive`. Reactivity is
|
|
232
|
+
* unaffected — the writer is injected as `globalDb` into `createShardCtxDb`,
|
|
233
|
+
* whose `broadcast` hook drives live queries regardless of engine.
|
|
234
|
+
*
|
|
235
|
+
* This package is internal: consumers depend on `@lunora/d1` or
|
|
236
|
+
* `@lunora/hyperdrive`, which assemble the concrete dialect and wrap the core.
|
|
237
|
+
*/
|
|
238
|
+
type SqlCtxDbOptions,
|
|
239
|
+
/**
|
|
240
|
+
* `@lunora/sql-store` — the internal, dialect-parameterized SQL store core
|
|
241
|
+
* shared by Lunora's `.global()` table backends.
|
|
242
|
+
*
|
|
243
|
+
* One ORM implementation (`createSqlCtxDb`) drives any SQL engine through a
|
|
244
|
+
* `SqlDialect`: SQLite via `@lunora/d1`, and Postgres/MySQL (PlanetScale, Neon,
|
|
245
|
+
* any Hyperdrive-reachable database) via `@lunora/hyperdrive`. Reactivity is
|
|
246
|
+
* unaffected — the writer is injected as `globalDb` into `createShardCtxDb`,
|
|
247
|
+
* whose `broadcast` hook drives live queries regardless of engine.
|
|
248
|
+
*
|
|
249
|
+
* This package is internal: consumers depend on `@lunora/d1` or
|
|
250
|
+
* `@lunora/hyperdrive`, which assemble the concrete dialect and wrap the core.
|
|
251
|
+
*/
|
|
252
|
+
type SqlCtxExec, type SqlDialect, type SqlRunResult, backfillSqlSearchIndexes, createSqlCtxDb, decodeBigint, decodeGlobalRow, effectiveColumnKind, migrateSearchState, readSqlCdcChanges, runSqlAggregateMigrations, runSqlCdcMigration, runSqlGlobalTableMigrations, runSqlRankMigrations, runSqlSearchMigrations, sqliteDecode, sqliteEncode, trimSqlCdcChanges, tryJsonParse };
|