@lunora/hyperdrive 1.0.0-alpha.21 → 1.0.0-alpha.211
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/README.md +71 -13
- package/dist/global.d.mts +155 -46
- package/dist/global.d.ts +155 -46
- package/dist/global.mjs +1 -9
- package/dist/index.d.mts +124 -182
- package/dist/index.d.ts +124 -182
- package/dist/index.mjs +1 -2
- package/dist/packem_shared/buildMysqlExec-CjkrA5JG.mjs +1 -0
- package/dist/packem_shared/createHyperdrive-BeXs5Dr6.mjs +1 -0
- package/dist/packem_shared/createPgVectorIndex-CSNnG065.mjs +1 -0
- package/dist/packem_shared/mysqlDialect-BS1Sz60B.mjs +1 -0
- package/dist/packem_shared/projectSourceRow-DN8ywPRl.mjs +1 -0
- package/dist/packem_shared/types.d-B2JdXSms.d.mts +159 -0
- package/dist/packem_shared/types.d-B2JdXSms.d.ts +159 -0
- package/package.json +6 -4
- package/dist/packem_shared/buildMysqlExec-DBbCjyq3.mjs +0 -23
- package/dist/packem_shared/createHyperdrive-DD8GoDZo.mjs +0 -36
- package/dist/packem_shared/mysqlDialect-oNhZ58s8.mjs +0 -102
- package/dist/packem_shared/projectSourceRow-DtKuMRIm.mjs +0 -10
package/LICENSE.md
CHANGED
|
@@ -103,3 +103,9 @@ Unless required by applicable law or agreed to in writing, software distributed
|
|
|
103
103
|
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
104
|
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
105
|
specific language governing permissions and limitations under the License.
|
|
106
|
+
|
|
107
|
+
<!-- DEPENDENCIES -->
|
|
108
|
+
<!-- /DEPENDENCIES -->
|
|
109
|
+
|
|
110
|
+
<!-- TYPE_DEPENDENCIES -->
|
|
111
|
+
<!-- /TYPE_DEPENDENCIES -->
|
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ Part of the [Lunora](https://github.com/anolilab/lunora) framework — a type-sa
|
|
|
42
42
|
>
|
|
43
43
|
> Hyperdrive talks to a database **Lunora does not own**. That breaks two invariants the rest of Lunora relies on:
|
|
44
44
|
>
|
|
45
|
-
> 1. **Non-deterministic (action-only).** A SQL query over Hyperdrive is a network call with an external, mutable result — exactly like `fetch`. It is **forbidden in `query`/`mutation`** (which must be deterministic so the coordinator can re-run them on OCC
|
|
45
|
+
> 1. **Non-deterministic (action-only).** A SQL query over Hyperdrive is a network call with an external, mutable result — exactly like `fetch`. It is **forbidden in `query`/`mutation`** (which must be deterministic so the coordinator can re-run them on subscription re-evaluation; an OCC conflict surfaces as a `409` to the caller, not an internal retry) and allowed **only in `action`s**. The `hyperdrive_outside_action` advisor lint flags `ctx.sql` used in a query/mutation.
|
|
46
46
|
> 2. **Non-reactive.** External writes do **not** flow through the Durable-Object / SQLite change-feed, so **Lunora live queries and subscriptions will NOT re-run** when an external Postgres/MySQL row changes. There is no honest way to make external writes reactive here.
|
|
47
47
|
>
|
|
48
48
|
> Use Hyperdrive to _read/write your existing DB from an action_. It is the **wrong** tool for "make my Postgres reactive". If you want external data to be reactive, write a **projection** of it into a `defineSchema` DO/D1 table from the action — that write _is_ tracked.
|
|
@@ -67,35 +67,55 @@ pnpm add mysql2 # mysql2 → fromMysql2
|
|
|
67
67
|
|
|
68
68
|
## Setup
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
Importing `@lunora/hyperdrive` (or reading `ctx.sql`) is enough: `lunora dev` and `lunora deploy` add a `HYPERDRIVE` binding to `wrangler.jsonc` for you, with a placeholder `id`.
|
|
71
|
+
|
|
72
|
+
- **In dev**, `ctx.sql` runs against an embedded Postgres ([PGlite](https://pglite.dev)) with its data in `.wrangler/state/lunora-pglite`, under `lunora dev`, `vite dev` and `vite preview`. It needs two optional packages (`lunora dev` says so when they are missing):
|
|
71
73
|
|
|
72
74
|
```sh
|
|
73
|
-
|
|
75
|
+
pnpm add -D @electric-sql/pglite @electric-sql/pglite-socket
|
|
74
76
|
```
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
To use your own database, set `CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE` (the last part is the binding name) or `localConnectionString` on the binding. The embedded database speaks PostgreSQL: a project whose only SQL driver is `mysql2` gets a warning and must set that variable to a local MySQL of its own. A plain `wrangler dev` that Lunora does not start has no embedded database either: set the variable (or `localConnectionString`) there too.
|
|
79
|
+
|
|
80
|
+
- **On deploy**, set the origin's connection string and a token that may edit Hyperdrive (`CLOUDFLARE_API_TOKEN` with _Hyperdrive: Edit_, plus `CLOUDFLARE_ACCOUNT_ID`):
|
|
77
81
|
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
"hyperdrive": [{ "binding": "HYPERDRIVE", "id": "<id from step 1>", "localConnectionString": "postgres://user:pass@localhost:5432/db" }], // gitleaks:allow -- placeholder, not a real secret
|
|
81
|
-
}
|
|
82
|
+
```sh
|
|
83
|
+
LUNORA_HYPERDRIVE_URL="postgres://user:pass@host:5432/db" lunora deploy # gitleaks:allow -- placeholder, not a real secret
|
|
82
84
|
```
|
|
83
85
|
|
|
86
|
+
The variable is `LUNORA_<BINDING>_URL`. Lunora creates a config named after the deployed Worker (so `--env staging` gets its own) and the binding, or reuses one with that name that reaches the same database, and writes its `id` into `wrangler.jsonc`. A same-named config for another database stops the deploy. The connection string is only sent to Cloudflare, never written to a file or logged.
|
|
87
|
+
|
|
88
|
+
Prefer to manage it yourself? Run `wrangler hyperdrive create my-db --connection-string=...` and put the `id` in the binding; Lunora then leaves it alone.
|
|
89
|
+
|
|
84
90
|
## Usage
|
|
85
91
|
|
|
86
|
-
`ctx.sql` is wired by codegen onto `ActionCtx` only — never `QueryCtx`/`MutationCtx
|
|
92
|
+
`ctx.sql` is wired by codegen onto `ActionCtx` only — never `QueryCtx`/`MutationCtx`, and it is `readonly`, so it is built once at the app level rather than assigned in a handler. Codegen emits a `sql` config thunk for it (`createHyperdrive` returns connection info; only you know which driver wraps it):
|
|
87
93
|
|
|
88
94
|
```ts
|
|
95
|
+
// src/server/index.ts
|
|
96
|
+
import type { HyperdriveLike } from "@lunora/hyperdrive";
|
|
89
97
|
import { createHyperdrive, fromPostgresJs } from "@lunora/hyperdrive";
|
|
90
98
|
import postgres from "postgres";
|
|
91
99
|
|
|
100
|
+
import { defineApp } from "../../lunora/_generated/app";
|
|
101
|
+
|
|
102
|
+
const app = defineApp<Env>()
|
|
103
|
+
.shard((env) => env.SHARD)
|
|
104
|
+
.hyperdrive((env) => fromPostgresJs(postgres(createHyperdrive(env.HYPERDRIVE as HyperdriveLike).connectionString)))
|
|
105
|
+
.build();
|
|
106
|
+
|
|
107
|
+
export const ShardDO = app.ShardDO;
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Hand-composing the worker instead? The same thunk is `createShardDO({ sql: (env) => … })`. Without it, every `ctx.sql` method throws a message pointing back at this wiring.
|
|
111
|
+
|
|
112
|
+
Handlers then just read it. The procedure builders (`action`, `v`) and `api` come from your app-local generated modules:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
92
115
|
import { api } from "@/lunora/_generated/api";
|
|
93
116
|
import { action, v } from "@/lunora/_generated/server";
|
|
94
117
|
|
|
95
118
|
export const syncCustomer = action.input({ orgId: v.string() }).action(async ({ args: { orgId }, ctx }) => {
|
|
96
|
-
const { connectionString } = createHyperdrive(ctx.env.HYPERDRIVE);
|
|
97
|
-
ctx.sql = fromPostgresJs(postgres(connectionString));
|
|
98
|
-
|
|
99
119
|
const rows = await ctx.sql.query<{ id: string; name: string }>("select id, name from customers where org = $1", [orgId]);
|
|
100
120
|
|
|
101
121
|
// Want it reactive? Project it into a Lunora table — THIS write is tracked.
|
|
@@ -113,6 +133,44 @@ export const syncCustomer = action.input({ orgId: v.string() }).action(async ({
|
|
|
113
133
|
| `pg` (node-postgres) | `fromNodePg` | `$1, $2, …` |
|
|
114
134
|
| `mysql2/promise` | `fromMysql2` | `?` |
|
|
115
135
|
|
|
136
|
+
## Reactive reads over your schema: the `.source()` modifier
|
|
137
|
+
|
|
138
|
+
The projection above is the escape hatch. For the common case — an existing Postgres you are not going to move, and a read path that should feel live — declare the source on the table and Lunora runs the whole loop on the shard's alarm: pull, diff, materialize, poke subscribers. No action, no mutation, no cron to write:
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
// lunora/schema.ts
|
|
142
|
+
export default defineSchema({
|
|
143
|
+
messages: defineTable({ body: v.string(), channelId: v.string() })
|
|
144
|
+
.shardBy("channelId")
|
|
145
|
+
.source({
|
|
146
|
+
binding: "HYPERDRIVE_MESSAGES",
|
|
147
|
+
query: 'select id, body, channel_id as "channelId" from messages where channel_id = $1',
|
|
148
|
+
tenantBy: (shardKey) => [shardKey], // mandatory under .shardBy() — the tenant boundary
|
|
149
|
+
}),
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
export const channelMessages = defineShape({ table: "messages", where: () => ({}) });
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Supply the driver once, on the app builder — required, or every tick records `no sourceClient resolved for binding "…"` and the table stays empty. Lunora memoizes it per binding:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
export default defineApp<Env>()
|
|
159
|
+
.shard((env) => env.SHARD)
|
|
160
|
+
.sourceClient((env, binding) => fromPostgresJs(postgres((env[binding] as { connectionString: string }).connectionString)))
|
|
161
|
+
.build();
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Clients subscribe with the shape they would use over any table — external data stops being external once it is materialized.
|
|
165
|
+
|
|
166
|
+
Three things to know before you build on it:
|
|
167
|
+
|
|
168
|
+
- **It polls; it is not logical replication.** Freshness is the refresh cadence: every alarm tick by default, `refresh: { everyMs }` to throttle, `refresh: "manual"` to drive it yourself. Writes from other systems land on the next pull.
|
|
169
|
+
- **`tenantBy` is the isolation boundary.** `defineSchema` throws at load if a sourced `.shardBy()` table omits it, and the `external_source_unscoped` advisor lint catches it at build time. Without it, one tenant's DO pulls every tenant's rows.
|
|
170
|
+
- **`mode: "full-pull"` (the default) diffs the whole slice each tick**, so upstream deletes are detected for free, at a bench ceiling around 10k rows. Past that, `mode: "incremental"` pulls only rows past a durable watermark via a cursor column. An incremental slice cannot see a delete on its own — an absent row means "unchanged", not "deleted" — so it **requires** a delete-visibility path: either `reconcileEveryMs` (a periodic full-pull sweep) or `softDeleteColumn` (an upstream tombstone column the cursor query returns, so do not filter it out). `defineSchema` throws and the `external_source_incremental_no_delete_path` lint fails the build if an incremental source declares neither.
|
|
171
|
+
|
|
172
|
+
`.source()` cannot be combined with `.global()` — they are contradictory tiers, and `defineSchema` rejects it.
|
|
173
|
+
|
|
116
174
|
## Reactive `.global()` over Hyperdrive
|
|
117
175
|
|
|
118
176
|
The `@lunora/hyperdrive/global` subpath is the opposite trade-off: Lunora **owns** the schema and a `.global()` table gets a real column-per-field layout on your Postgres/MySQL, with every write routed through the shared store core. Live queries stay reactive — identical to D1 — because the writer drives the same broadcast hook. Build the writer inside the Durable Object that hosts the `.global()` store and inject it as `globalDb`:
|
|
@@ -127,7 +185,7 @@ const globalDb = createPostgresGlobalCtxDb({ query: (text, params) => sql.unsafe
|
|
|
127
185
|
|
|
128
186
|
For MySQL use `createMysqlGlobalCtxDb` with a `mysql2/promise` pool created with `flags: ["FOUND_ROWS"]` — without `CLIENT_FOUND_ROWS` the affected-rows OCC guard sees changed (not matched) rows and raises spurious conflicts. Lower-level building blocks (`buildPgExec`, `buildMysqlExec`, `postgresDialect`, `mysqlDialect`, `createHyperdriveGlobalCtxDb`) are exported for custom wiring.
|
|
129
187
|
|
|
130
|
-
> This README covers the basics. For the full API and the determinism/realtime rationale, see the **[documentation](https://lunora.sh/docs/
|
|
188
|
+
> This README covers the basics. For the full API and the determinism/realtime rationale, see the **[documentation](https://lunora.sh/docs/packages/hyperdrive)**.
|
|
131
189
|
|
|
132
190
|
## Non-goals
|
|
133
191
|
|
package/dist/global.d.mts
CHANGED
|
@@ -1,47 +1,160 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `@lunora/hyperdrive/global` — a Postgres/MySQL database reached through
|
|
3
|
+
* Cloudflare Hyperdrive (PlanetScale, Neon, RDS, …) as a **first-class,
|
|
4
|
+
* reactive** `.global()` storage backend for Lunora, alongside D1.
|
|
5
|
+
*
|
|
6
|
+
* Unlike the package's `ctx.sql` surface (an action-only, non-reactive escape
|
|
7
|
+
* hatch for an external DB), this makes Lunora the **owner** of the schema:
|
|
8
|
+
* `.global()` tables get a real column-per-field layout and all writes route
|
|
9
|
+
* through the shared store core (`createSqlCtxDb` from `@lunora/sql-store`) with
|
|
10
|
+
* a Postgres or MySQL {@link postgresDialect}/{@link mysqlDialect} and a
|
|
11
|
+
* Hyperdrive-backed {@link SqlExec}. The returned `DatabaseWriterLike` is
|
|
12
|
+
* injected as `globalDb` into `createShardCtxDb`, whose broadcast hook drives
|
|
13
|
+
* live queries — so subscriptions stay reactive with zero extra wiring,
|
|
14
|
+
* identical to D1.
|
|
15
|
+
*
|
|
16
|
+
* Drivers (`postgres`/`pg`/`mysql2`) are optional peer deps — bring your own,
|
|
17
|
+
* constructed from the `HYPERDRIVE` binding's connection string. The binding is
|
|
18
|
+
* reachable from inside the Durable Object that hosts the writer; cache the
|
|
19
|
+
* driver on the DO instance and rebuild it lazily after hibernation.
|
|
20
|
+
*
|
|
21
|
+
* **MySQL connections must enable `CLIENT_FOUND_ROWS`** (mysql2:
|
|
22
|
+
* `createPool({ flags: ["FOUND_ROWS"] })`) so the affected-rows OCC guard sees
|
|
23
|
+
* matched (not changed) rows — see {@link buildMysqlExec}.
|
|
24
|
+
*/
|
|
25
|
+
import { DatabaseWriterLike } from '@lunora/shard-engine';
|
|
2
26
|
import { SqlExec, SqlDialect, SqlCtxDbOptions } from '@lunora/sql-store';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
27
|
+
import { M as Mysql2Like, S as SqlClient } from "./packem_shared/types.d-B2JdXSms.mjs";
|
|
28
|
+
import { VectorMetric, VectorizeIndexLike } from '@lunora/platform';
|
|
29
|
+
/**
|
|
30
|
+
* Minimal row-returning client (e.g. `@lunora/hyperdrive`'s `fromPostgresJs`/`fromNodePg`
|
|
31
|
+
* result). Aliases {@link SqlClient} — the exec-facing name is kept so call sites read
|
|
32
|
+
* intent, but the shape is the single source of truth in `./types` (no drift).
|
|
33
|
+
*/
|
|
34
|
+
type RowClient = SqlClient;
|
|
11
35
|
/**
|
|
12
|
-
*
|
|
13
|
-
* `
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
|
|
36
|
+
* Minimal `mysql2/promise` connection/pool surface — `execute` resolves to
|
|
37
|
+
* `[rows | ResultSetHeader, fields]`. Aliases {@link Mysql2Like} so the /global
|
|
38
|
+
* entry's driver surface can never drift from the main entry's, widened with the
|
|
39
|
+
* (optional, structural) shape {@link assertFoundRows}'s `CLIENT_FOUND_ROWS`
|
|
40
|
+
* probe reads.
|
|
41
|
+
*
|
|
42
|
+
* A real `mysql2/promise` connection/pool exposes the merged client-flags
|
|
43
|
+
* bitmask synchronously, but at two different depths depending on which one it
|
|
44
|
+
* is, and NEITHER is in `mysql2`'s own `.d.ts` — its `Pool extends Connection`
|
|
45
|
+
* signature claims a top-level `config`, but at runtime a `mysql2/promise`
|
|
46
|
+
* `Pool` has none; the real value lives one level down, on the core pool it
|
|
47
|
+
* wraps:
|
|
48
|
+
*
|
|
49
|
+
* - a single `Connection`/`PoolConnection` → `connection.config.clientFlags`
|
|
50
|
+
* - a `Pool` (the `createPool({ flags: ["FOUND_ROWS"] })` example above) →
|
|
51
|
+
* `pool.pool.config.connectionConfig.clientFlags`
|
|
52
|
+
*
|
|
53
|
+
* Because those paths are undocumented driver internals, `global-dialect.test.ts`
|
|
54
|
+
* pins them against a REAL `mysql2` pool (built without connecting) rather than
|
|
55
|
+
* only against hand-written doubles — if a `mysql2` release relocates them, the
|
|
56
|
+
* probe would otherwise degrade silently to the warn branch and the OCC guard
|
|
57
|
+
* would go unchecked.
|
|
58
|
+
*
|
|
59
|
+
* The probe fields are typed `unknown` publicly: the paths are not in `mysql2`'s
|
|
60
|
+
* typings, so spelling them out made a real `createPool(...)` fail to type-check
|
|
61
|
+
* (TS2345, weak-type mismatch on `config`). {@link readMysqlClientFlags} reads
|
|
62
|
+
* them through the internal `FlagProbeShape` instead, and a minimal test double
|
|
63
|
+
* (only `execute`) resolves to "undeterminable" rather than a `TypeError`.
|
|
64
|
+
*/
|
|
65
|
+
type Mysql2Execute = Mysql2Like & {
|
|
66
|
+
config?: unknown;
|
|
67
|
+
pool?: unknown;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Wrap a Postgres row-client (from `@lunora/hyperdrive`'s `fromPostgresJs` /
|
|
71
|
+
* `fromNodePg`) as a {@link SqlExec}. The core already renders `$N` placeholders
|
|
72
|
+
* for Postgres, so `all`/`run` forward verbatim. Postgres uses `RETURNING` for
|
|
73
|
+
* OCC (read via `all`), so `run` reports no affected-row count.
|
|
74
|
+
*
|
|
75
|
+
* `batch` dispatches every statement concurrently (`Promise.all`) over `client`
|
|
76
|
+
* rather than awaiting each `query` call in turn — `RowClient` only exposes a
|
|
77
|
+
* single-statement `query`, so there is no wire-level multi-statement command
|
|
78
|
+
* to reach for. When `client` is backed by a pool (the common production
|
|
79
|
+
* shape), this genuinely spreads the statements across multiple physical
|
|
80
|
+
* connections instead of serializing one full round trip at a time; against a
|
|
81
|
+
* single connection it still removes the sequential *await*, though the
|
|
82
|
+
* underlying driver may itself queue the sends. Either way it stays
|
|
83
|
+
* non-atomic, at-least-once, and unordered between elements, same as the
|
|
84
|
+
* sequential fallback minus the ordering — safe only for statements whose
|
|
85
|
+
* effects don't depend on each other, which is what every current caller
|
|
86
|
+
* batches (distinct-keyed companion rows).
|
|
87
|
+
*/
|
|
17
88
|
declare const buildPgExec: (client: RowClient) => SqlExec;
|
|
18
89
|
/**
|
|
19
|
-
* Wrap a `mysql2/promise` connection/pool as a {@link SqlExec}. The core already
|
|
20
|
-
* renders backtick identifiers and `?` placeholders for MySQL, so `all`/`run`
|
|
21
|
-
* forward verbatim. MySQL has no `RETURNING`, so `run` surfaces `affectedRows`
|
|
22
|
-
* for the store's affected-rows OCC guard.
|
|
23
|
-
*
|
|
24
|
-
* **The connection MUST be created with the `CLIENT_FOUND_ROWS` flag**
|
|
25
|
-
* (mysql2: `createPool({ flags: ["FOUND_ROWS"] })`). Without it, `affectedRows`
|
|
26
|
-
* counts *changed* rows, so an idempotent `patch`/`replace` that re-writes the
|
|
27
|
-
* same values reports 0 and the OCC guard raises a spurious conflict.
|
|
28
|
-
|
|
90
|
+
* Wrap a `mysql2/promise` connection/pool as a {@link SqlExec}. The core already
|
|
91
|
+
* renders backtick identifiers and `?` placeholders for MySQL, so `all`/`run`
|
|
92
|
+
* forward verbatim. MySQL has no `RETURNING`, so `run` surfaces `affectedRows`
|
|
93
|
+
* for the store's affected-rows OCC guard.
|
|
94
|
+
*
|
|
95
|
+
* **The connection MUST be created with the `CLIENT_FOUND_ROWS` flag**
|
|
96
|
+
* (mysql2: `createPool({ flags: ["FOUND_ROWS"] })`). Without it, `affectedRows`
|
|
97
|
+
* counts *changed* rows, so an idempotent `patch`/`replace` that re-writes the
|
|
98
|
+
* same values reports 0 and the OCC guard raises a spurious conflict. Verified
|
|
99
|
+
* once here at construction — see {@link assertFoundRows} — never per statement.
|
|
100
|
+
*
|
|
101
|
+
* `batch` dispatches every statement concurrently (`Promise.all`), same
|
|
102
|
+
* rationale as {@link buildPgExec}'s `batch` — `Mysql2Like` only exposes a
|
|
103
|
+
* single-statement `execute`, so this is "spread across a pool's connections"
|
|
104
|
+
* rather than one wire-level multi-statement command; still non-atomic,
|
|
105
|
+
* at-least-once, and unordered between elements, safe only for statements
|
|
106
|
+
* with no cross-effect (what every current caller batches).
|
|
107
|
+
*/
|
|
29
108
|
declare const buildMysqlExec: (connection: Mysql2Execute) => SqlExec;
|
|
30
109
|
/**
|
|
31
|
-
* **Postgres** dialect. Differs from SQLite only in column types
|
|
32
|
-
* (`DOUBLE PRECISION`/`BYTEA`/`BIGSERIAL`), the `information_schema` catalog
|
|
33
|
-
* probe, and unique-violation detection (SQLSTATE `23505`).
|
|
34
|
-
*/
|
|
110
|
+
* **Postgres** dialect. Differs from SQLite only in column types
|
|
111
|
+
* (`DOUBLE PRECISION`/`BYTEA`/`BIGSERIAL`), the `information_schema` catalog
|
|
112
|
+
* probe, and unique-violation detection (SQLSTATE `23505`).
|
|
113
|
+
*/
|
|
35
114
|
declare const postgresDialect: SqlDialect;
|
|
36
115
|
/**
|
|
37
|
-
* **MySQL** dialect. Diverges in: **no `RETURNING`** (the store's OCC falls back
|
|
38
|
-
* to affected-rows — which requires the connection's `CLIENT_FOUND_ROWS` flag so
|
|
39
|
-
* a no-op update still reports a matched row, see `buildMysqlExec`); bounded
|
|
40
|
-
* `VARCHAR` keys (TEXT can't be a primary key / unindexed); a TEXT/BLOB index key
|
|
41
|
-
* prefix; and `ER_DUP_ENTRY` (errno 1062) unique violations. (Drizzle's MySQL
|
|
42
|
-
* dialect supplies the backtick identifiers + `ON DUPLICATE KEY` upserts.)
|
|
43
|
-
*/
|
|
116
|
+
* **MySQL** dialect. Diverges in: **no `RETURNING`** (the store's OCC falls back
|
|
117
|
+
* to affected-rows — which requires the connection's `CLIENT_FOUND_ROWS` flag so
|
|
118
|
+
* a no-op update still reports a matched row, see `buildMysqlExec`); bounded
|
|
119
|
+
* `VARCHAR` keys (TEXT can't be a primary key / unindexed); a TEXT/BLOB index key
|
|
120
|
+
* prefix; and `ER_DUP_ENTRY` (errno 1062) unique violations. (Drizzle's MySQL
|
|
121
|
+
* dialect supplies the backtick identifiers + `ON DUPLICATE KEY` upserts.)
|
|
122
|
+
*/
|
|
44
123
|
declare const mysqlDialect: SqlDialect;
|
|
124
|
+
/** Options for {@link createPgVectorIndex}. */
|
|
125
|
+
interface PgVectorIndexOptions {
|
|
126
|
+
/** Postgres client — the same `SqlClient` the Hyperdrive global store takes. */
|
|
127
|
+
client: SqlClient;
|
|
128
|
+
/**
|
|
129
|
+
* Vector width. Must match the embedder's output and the `dimensions` on the
|
|
130
|
+
* schema's `.vectorize(...)`; Postgres enforces it per row, so a mismatch
|
|
131
|
+
* surfaces as a write error rather than silently bad neighbours.
|
|
132
|
+
*/
|
|
133
|
+
dimensions: number;
|
|
134
|
+
/** Distance metric. Defaults to `"cosine"`, matching the common embedding case. */
|
|
135
|
+
metric?: VectorMetric;
|
|
136
|
+
/**
|
|
137
|
+
* Names the backing table (`__vec_<name>`), derived rather than configurable —
|
|
138
|
+
* a second name for one index is a way to lose data, not a feature.
|
|
139
|
+
*
|
|
140
|
+
* This is NOT required to equal the key in the shard's `vectors` map, and often
|
|
141
|
+
* cannot: that key mirrors the schema's `.vectorize({ index })`, which may carry
|
|
142
|
+
* hyphens (`"docs-body"`), while this must be a bare SQL identifier. Keep it
|
|
143
|
+
* stable — changing it points the index at a different, empty table.
|
|
144
|
+
*/
|
|
145
|
+
name: string;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Build a `pgvector`-backed vector index that satisfies {@link VectorizeIndexLike}.
|
|
149
|
+
*
|
|
150
|
+
* Requires the `vector` extension to be installable by the connecting role
|
|
151
|
+
* (`CREATE EXTENSION IF NOT EXISTS vector`). On a managed Postgres where the
|
|
152
|
+
* role cannot create extensions, install it once out-of-band; the statement is
|
|
153
|
+
* then a no-op.
|
|
154
|
+
* @param options See {@link PgVectorIndexOptions}.
|
|
155
|
+
* @returns An index object the shard's `vectors` map accepts as-is.
|
|
156
|
+
*/
|
|
157
|
+
declare const createPgVectorIndex: (options: PgVectorIndexOptions) => VectorizeIndexLike;
|
|
45
158
|
/** Which engine a Hyperdrive-backed `.global()` store targets. */
|
|
46
159
|
type HyperdriveEngine = "mysql" | "postgres";
|
|
47
160
|
/** Options for {@link createHyperdriveGlobalCtxDb}: the store options minus `exec`/`dialect`, plus the engine and a built `SqlExec`. */
|
|
@@ -52,18 +165,14 @@ interface CreateHyperdriveGlobalCtxDbOptions extends Omit<SqlCtxDbOptions, "dial
|
|
|
52
165
|
exec: SqlExec;
|
|
53
166
|
}
|
|
54
167
|
/**
|
|
55
|
-
* Build a reactive `.global()` writer backed by a Hyperdrive-reachable
|
|
56
|
-
* Postgres/MySQL database. Pass a built {@link SqlExec} (via {@link buildPgExec}/
|
|
57
|
-
* {@link buildMysqlExec}) and the matching `engine`; everything else mirrors the
|
|
58
|
-
* D1 store options.
|
|
59
|
-
*/
|
|
60
|
-
declare const createHyperdriveGlobalCtxDb: ({
|
|
61
|
-
engine,
|
|
62
|
-
exec,
|
|
63
|
-
...rest
|
|
64
|
-
}: CreateHyperdriveGlobalCtxDbOptions) => DatabaseWriterLike;
|
|
168
|
+
* Build a reactive `.global()` writer backed by a Hyperdrive-reachable
|
|
169
|
+
* Postgres/MySQL database. Pass a built {@link SqlExec} (via {@link buildPgExec}/
|
|
170
|
+
* {@link buildMysqlExec}) and the matching `engine`; everything else mirrors the
|
|
171
|
+
* D1 store options.
|
|
172
|
+
*/
|
|
173
|
+
declare const createHyperdriveGlobalCtxDb: ({ engine, exec, ...rest }: CreateHyperdriveGlobalCtxDbOptions) => DatabaseWriterLike;
|
|
65
174
|
/** Convenience: a **Postgres** `.global()` writer from a row-client (postgres.js/pg over Hyperdrive). */
|
|
66
175
|
declare const createPostgresGlobalCtxDb: (client: RowClient, options: Omit<CreateHyperdriveGlobalCtxDbOptions, "engine" | "exec">) => DatabaseWriterLike;
|
|
67
176
|
/** Convenience: a **MySQL** `.global()` writer from a `mysql2/promise` connection/pool (created with `flags: ["FOUND_ROWS"]`). */
|
|
68
177
|
declare const createMysqlGlobalCtxDb: (connection: Mysql2Execute, options: Omit<CreateHyperdriveGlobalCtxDbOptions, "engine" | "exec">) => DatabaseWriterLike;
|
|
69
|
-
export { CreateHyperdriveGlobalCtxDbOptions, HyperdriveEngine, type Mysql2Execute, type RowClient, buildMysqlExec, buildPgExec, createHyperdriveGlobalCtxDb, createMysqlGlobalCtxDb, createPostgresGlobalCtxDb, mysqlDialect, postgresDialect };
|
|
178
|
+
export { CreateHyperdriveGlobalCtxDbOptions, HyperdriveEngine, type Mysql2Execute, type PgVectorIndexOptions, type RowClient, buildMysqlExec, buildPgExec, createHyperdriveGlobalCtxDb, createMysqlGlobalCtxDb, createPgVectorIndex, createPostgresGlobalCtxDb, mysqlDialect, postgresDialect };
|
package/dist/global.d.ts
CHANGED
|
@@ -1,47 +1,160 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `@lunora/hyperdrive/global` — a Postgres/MySQL database reached through
|
|
3
|
+
* Cloudflare Hyperdrive (PlanetScale, Neon, RDS, …) as a **first-class,
|
|
4
|
+
* reactive** `.global()` storage backend for Lunora, alongside D1.
|
|
5
|
+
*
|
|
6
|
+
* Unlike the package's `ctx.sql` surface (an action-only, non-reactive escape
|
|
7
|
+
* hatch for an external DB), this makes Lunora the **owner** of the schema:
|
|
8
|
+
* `.global()` tables get a real column-per-field layout and all writes route
|
|
9
|
+
* through the shared store core (`createSqlCtxDb` from `@lunora/sql-store`) with
|
|
10
|
+
* a Postgres or MySQL {@link postgresDialect}/{@link mysqlDialect} and a
|
|
11
|
+
* Hyperdrive-backed {@link SqlExec}. The returned `DatabaseWriterLike` is
|
|
12
|
+
* injected as `globalDb` into `createShardCtxDb`, whose broadcast hook drives
|
|
13
|
+
* live queries — so subscriptions stay reactive with zero extra wiring,
|
|
14
|
+
* identical to D1.
|
|
15
|
+
*
|
|
16
|
+
* Drivers (`postgres`/`pg`/`mysql2`) are optional peer deps — bring your own,
|
|
17
|
+
* constructed from the `HYPERDRIVE` binding's connection string. The binding is
|
|
18
|
+
* reachable from inside the Durable Object that hosts the writer; cache the
|
|
19
|
+
* driver on the DO instance and rebuild it lazily after hibernation.
|
|
20
|
+
*
|
|
21
|
+
* **MySQL connections must enable `CLIENT_FOUND_ROWS`** (mysql2:
|
|
22
|
+
* `createPool({ flags: ["FOUND_ROWS"] })`) so the affected-rows OCC guard sees
|
|
23
|
+
* matched (not changed) rows — see {@link buildMysqlExec}.
|
|
24
|
+
*/
|
|
25
|
+
import { DatabaseWriterLike } from '@lunora/shard-engine';
|
|
2
26
|
import { SqlExec, SqlDialect, SqlCtxDbOptions } from '@lunora/sql-store';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
27
|
+
import { M as Mysql2Like, S as SqlClient } from "./packem_shared/types.d-B2JdXSms.js";
|
|
28
|
+
import { VectorMetric, VectorizeIndexLike } from '@lunora/platform';
|
|
29
|
+
/**
|
|
30
|
+
* Minimal row-returning client (e.g. `@lunora/hyperdrive`'s `fromPostgresJs`/`fromNodePg`
|
|
31
|
+
* result). Aliases {@link SqlClient} — the exec-facing name is kept so call sites read
|
|
32
|
+
* intent, but the shape is the single source of truth in `./types` (no drift).
|
|
33
|
+
*/
|
|
34
|
+
type RowClient = SqlClient;
|
|
11
35
|
/**
|
|
12
|
-
*
|
|
13
|
-
* `
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
|
|
36
|
+
* Minimal `mysql2/promise` connection/pool surface — `execute` resolves to
|
|
37
|
+
* `[rows | ResultSetHeader, fields]`. Aliases {@link Mysql2Like} so the /global
|
|
38
|
+
* entry's driver surface can never drift from the main entry's, widened with the
|
|
39
|
+
* (optional, structural) shape {@link assertFoundRows}'s `CLIENT_FOUND_ROWS`
|
|
40
|
+
* probe reads.
|
|
41
|
+
*
|
|
42
|
+
* A real `mysql2/promise` connection/pool exposes the merged client-flags
|
|
43
|
+
* bitmask synchronously, but at two different depths depending on which one it
|
|
44
|
+
* is, and NEITHER is in `mysql2`'s own `.d.ts` — its `Pool extends Connection`
|
|
45
|
+
* signature claims a top-level `config`, but at runtime a `mysql2/promise`
|
|
46
|
+
* `Pool` has none; the real value lives one level down, on the core pool it
|
|
47
|
+
* wraps:
|
|
48
|
+
*
|
|
49
|
+
* - a single `Connection`/`PoolConnection` → `connection.config.clientFlags`
|
|
50
|
+
* - a `Pool` (the `createPool({ flags: ["FOUND_ROWS"] })` example above) →
|
|
51
|
+
* `pool.pool.config.connectionConfig.clientFlags`
|
|
52
|
+
*
|
|
53
|
+
* Because those paths are undocumented driver internals, `global-dialect.test.ts`
|
|
54
|
+
* pins them against a REAL `mysql2` pool (built without connecting) rather than
|
|
55
|
+
* only against hand-written doubles — if a `mysql2` release relocates them, the
|
|
56
|
+
* probe would otherwise degrade silently to the warn branch and the OCC guard
|
|
57
|
+
* would go unchecked.
|
|
58
|
+
*
|
|
59
|
+
* The probe fields are typed `unknown` publicly: the paths are not in `mysql2`'s
|
|
60
|
+
* typings, so spelling them out made a real `createPool(...)` fail to type-check
|
|
61
|
+
* (TS2345, weak-type mismatch on `config`). {@link readMysqlClientFlags} reads
|
|
62
|
+
* them through the internal `FlagProbeShape` instead, and a minimal test double
|
|
63
|
+
* (only `execute`) resolves to "undeterminable" rather than a `TypeError`.
|
|
64
|
+
*/
|
|
65
|
+
type Mysql2Execute = Mysql2Like & {
|
|
66
|
+
config?: unknown;
|
|
67
|
+
pool?: unknown;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Wrap a Postgres row-client (from `@lunora/hyperdrive`'s `fromPostgresJs` /
|
|
71
|
+
* `fromNodePg`) as a {@link SqlExec}. The core already renders `$N` placeholders
|
|
72
|
+
* for Postgres, so `all`/`run` forward verbatim. Postgres uses `RETURNING` for
|
|
73
|
+
* OCC (read via `all`), so `run` reports no affected-row count.
|
|
74
|
+
*
|
|
75
|
+
* `batch` dispatches every statement concurrently (`Promise.all`) over `client`
|
|
76
|
+
* rather than awaiting each `query` call in turn — `RowClient` only exposes a
|
|
77
|
+
* single-statement `query`, so there is no wire-level multi-statement command
|
|
78
|
+
* to reach for. When `client` is backed by a pool (the common production
|
|
79
|
+
* shape), this genuinely spreads the statements across multiple physical
|
|
80
|
+
* connections instead of serializing one full round trip at a time; against a
|
|
81
|
+
* single connection it still removes the sequential *await*, though the
|
|
82
|
+
* underlying driver may itself queue the sends. Either way it stays
|
|
83
|
+
* non-atomic, at-least-once, and unordered between elements, same as the
|
|
84
|
+
* sequential fallback minus the ordering — safe only for statements whose
|
|
85
|
+
* effects don't depend on each other, which is what every current caller
|
|
86
|
+
* batches (distinct-keyed companion rows).
|
|
87
|
+
*/
|
|
17
88
|
declare const buildPgExec: (client: RowClient) => SqlExec;
|
|
18
89
|
/**
|
|
19
|
-
* Wrap a `mysql2/promise` connection/pool as a {@link SqlExec}. The core already
|
|
20
|
-
* renders backtick identifiers and `?` placeholders for MySQL, so `all`/`run`
|
|
21
|
-
* forward verbatim. MySQL has no `RETURNING`, so `run` surfaces `affectedRows`
|
|
22
|
-
* for the store's affected-rows OCC guard.
|
|
23
|
-
*
|
|
24
|
-
* **The connection MUST be created with the `CLIENT_FOUND_ROWS` flag**
|
|
25
|
-
* (mysql2: `createPool({ flags: ["FOUND_ROWS"] })`). Without it, `affectedRows`
|
|
26
|
-
* counts *changed* rows, so an idempotent `patch`/`replace` that re-writes the
|
|
27
|
-
* same values reports 0 and the OCC guard raises a spurious conflict.
|
|
28
|
-
|
|
90
|
+
* Wrap a `mysql2/promise` connection/pool as a {@link SqlExec}. The core already
|
|
91
|
+
* renders backtick identifiers and `?` placeholders for MySQL, so `all`/`run`
|
|
92
|
+
* forward verbatim. MySQL has no `RETURNING`, so `run` surfaces `affectedRows`
|
|
93
|
+
* for the store's affected-rows OCC guard.
|
|
94
|
+
*
|
|
95
|
+
* **The connection MUST be created with the `CLIENT_FOUND_ROWS` flag**
|
|
96
|
+
* (mysql2: `createPool({ flags: ["FOUND_ROWS"] })`). Without it, `affectedRows`
|
|
97
|
+
* counts *changed* rows, so an idempotent `patch`/`replace` that re-writes the
|
|
98
|
+
* same values reports 0 and the OCC guard raises a spurious conflict. Verified
|
|
99
|
+
* once here at construction — see {@link assertFoundRows} — never per statement.
|
|
100
|
+
*
|
|
101
|
+
* `batch` dispatches every statement concurrently (`Promise.all`), same
|
|
102
|
+
* rationale as {@link buildPgExec}'s `batch` — `Mysql2Like` only exposes a
|
|
103
|
+
* single-statement `execute`, so this is "spread across a pool's connections"
|
|
104
|
+
* rather than one wire-level multi-statement command; still non-atomic,
|
|
105
|
+
* at-least-once, and unordered between elements, safe only for statements
|
|
106
|
+
* with no cross-effect (what every current caller batches).
|
|
107
|
+
*/
|
|
29
108
|
declare const buildMysqlExec: (connection: Mysql2Execute) => SqlExec;
|
|
30
109
|
/**
|
|
31
|
-
* **Postgres** dialect. Differs from SQLite only in column types
|
|
32
|
-
* (`DOUBLE PRECISION`/`BYTEA`/`BIGSERIAL`), the `information_schema` catalog
|
|
33
|
-
* probe, and unique-violation detection (SQLSTATE `23505`).
|
|
34
|
-
*/
|
|
110
|
+
* **Postgres** dialect. Differs from SQLite only in column types
|
|
111
|
+
* (`DOUBLE PRECISION`/`BYTEA`/`BIGSERIAL`), the `information_schema` catalog
|
|
112
|
+
* probe, and unique-violation detection (SQLSTATE `23505`).
|
|
113
|
+
*/
|
|
35
114
|
declare const postgresDialect: SqlDialect;
|
|
36
115
|
/**
|
|
37
|
-
* **MySQL** dialect. Diverges in: **no `RETURNING`** (the store's OCC falls back
|
|
38
|
-
* to affected-rows — which requires the connection's `CLIENT_FOUND_ROWS` flag so
|
|
39
|
-
* a no-op update still reports a matched row, see `buildMysqlExec`); bounded
|
|
40
|
-
* `VARCHAR` keys (TEXT can't be a primary key / unindexed); a TEXT/BLOB index key
|
|
41
|
-
* prefix; and `ER_DUP_ENTRY` (errno 1062) unique violations. (Drizzle's MySQL
|
|
42
|
-
* dialect supplies the backtick identifiers + `ON DUPLICATE KEY` upserts.)
|
|
43
|
-
*/
|
|
116
|
+
* **MySQL** dialect. Diverges in: **no `RETURNING`** (the store's OCC falls back
|
|
117
|
+
* to affected-rows — which requires the connection's `CLIENT_FOUND_ROWS` flag so
|
|
118
|
+
* a no-op update still reports a matched row, see `buildMysqlExec`); bounded
|
|
119
|
+
* `VARCHAR` keys (TEXT can't be a primary key / unindexed); a TEXT/BLOB index key
|
|
120
|
+
* prefix; and `ER_DUP_ENTRY` (errno 1062) unique violations. (Drizzle's MySQL
|
|
121
|
+
* dialect supplies the backtick identifiers + `ON DUPLICATE KEY` upserts.)
|
|
122
|
+
*/
|
|
44
123
|
declare const mysqlDialect: SqlDialect;
|
|
124
|
+
/** Options for {@link createPgVectorIndex}. */
|
|
125
|
+
interface PgVectorIndexOptions {
|
|
126
|
+
/** Postgres client — the same `SqlClient` the Hyperdrive global store takes. */
|
|
127
|
+
client: SqlClient;
|
|
128
|
+
/**
|
|
129
|
+
* Vector width. Must match the embedder's output and the `dimensions` on the
|
|
130
|
+
* schema's `.vectorize(...)`; Postgres enforces it per row, so a mismatch
|
|
131
|
+
* surfaces as a write error rather than silently bad neighbours.
|
|
132
|
+
*/
|
|
133
|
+
dimensions: number;
|
|
134
|
+
/** Distance metric. Defaults to `"cosine"`, matching the common embedding case. */
|
|
135
|
+
metric?: VectorMetric;
|
|
136
|
+
/**
|
|
137
|
+
* Names the backing table (`__vec_<name>`), derived rather than configurable —
|
|
138
|
+
* a second name for one index is a way to lose data, not a feature.
|
|
139
|
+
*
|
|
140
|
+
* This is NOT required to equal the key in the shard's `vectors` map, and often
|
|
141
|
+
* cannot: that key mirrors the schema's `.vectorize({ index })`, which may carry
|
|
142
|
+
* hyphens (`"docs-body"`), while this must be a bare SQL identifier. Keep it
|
|
143
|
+
* stable — changing it points the index at a different, empty table.
|
|
144
|
+
*/
|
|
145
|
+
name: string;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Build a `pgvector`-backed vector index that satisfies {@link VectorizeIndexLike}.
|
|
149
|
+
*
|
|
150
|
+
* Requires the `vector` extension to be installable by the connecting role
|
|
151
|
+
* (`CREATE EXTENSION IF NOT EXISTS vector`). On a managed Postgres where the
|
|
152
|
+
* role cannot create extensions, install it once out-of-band; the statement is
|
|
153
|
+
* then a no-op.
|
|
154
|
+
* @param options See {@link PgVectorIndexOptions}.
|
|
155
|
+
* @returns An index object the shard's `vectors` map accepts as-is.
|
|
156
|
+
*/
|
|
157
|
+
declare const createPgVectorIndex: (options: PgVectorIndexOptions) => VectorizeIndexLike;
|
|
45
158
|
/** Which engine a Hyperdrive-backed `.global()` store targets. */
|
|
46
159
|
type HyperdriveEngine = "mysql" | "postgres";
|
|
47
160
|
/** Options for {@link createHyperdriveGlobalCtxDb}: the store options minus `exec`/`dialect`, plus the engine and a built `SqlExec`. */
|
|
@@ -52,18 +165,14 @@ interface CreateHyperdriveGlobalCtxDbOptions extends Omit<SqlCtxDbOptions, "dial
|
|
|
52
165
|
exec: SqlExec;
|
|
53
166
|
}
|
|
54
167
|
/**
|
|
55
|
-
* Build a reactive `.global()` writer backed by a Hyperdrive-reachable
|
|
56
|
-
* Postgres/MySQL database. Pass a built {@link SqlExec} (via {@link buildPgExec}/
|
|
57
|
-
* {@link buildMysqlExec}) and the matching `engine`; everything else mirrors the
|
|
58
|
-
* D1 store options.
|
|
59
|
-
*/
|
|
60
|
-
declare const createHyperdriveGlobalCtxDb: ({
|
|
61
|
-
engine,
|
|
62
|
-
exec,
|
|
63
|
-
...rest
|
|
64
|
-
}: CreateHyperdriveGlobalCtxDbOptions) => DatabaseWriterLike;
|
|
168
|
+
* Build a reactive `.global()` writer backed by a Hyperdrive-reachable
|
|
169
|
+
* Postgres/MySQL database. Pass a built {@link SqlExec} (via {@link buildPgExec}/
|
|
170
|
+
* {@link buildMysqlExec}) and the matching `engine`; everything else mirrors the
|
|
171
|
+
* D1 store options.
|
|
172
|
+
*/
|
|
173
|
+
declare const createHyperdriveGlobalCtxDb: ({ engine, exec, ...rest }: CreateHyperdriveGlobalCtxDbOptions) => DatabaseWriterLike;
|
|
65
174
|
/** Convenience: a **Postgres** `.global()` writer from a row-client (postgres.js/pg over Hyperdrive). */
|
|
66
175
|
declare const createPostgresGlobalCtxDb: (client: RowClient, options: Omit<CreateHyperdriveGlobalCtxDbOptions, "engine" | "exec">) => DatabaseWriterLike;
|
|
67
176
|
/** Convenience: a **MySQL** `.global()` writer from a `mysql2/promise` connection/pool (created with `flags: ["FOUND_ROWS"]`). */
|
|
68
177
|
declare const createMysqlGlobalCtxDb: (connection: Mysql2Execute, options: Omit<CreateHyperdriveGlobalCtxDbOptions, "engine" | "exec">) => DatabaseWriterLike;
|
|
69
|
-
export { CreateHyperdriveGlobalCtxDbOptions, HyperdriveEngine, type Mysql2Execute, type RowClient, buildMysqlExec, buildPgExec, createHyperdriveGlobalCtxDb, createMysqlGlobalCtxDb, createPostgresGlobalCtxDb, mysqlDialect, postgresDialect };
|
|
178
|
+
export { CreateHyperdriveGlobalCtxDbOptions, HyperdriveEngine, type Mysql2Execute, type PgVectorIndexOptions, type RowClient, buildMysqlExec, buildPgExec, createHyperdriveGlobalCtxDb, createMysqlGlobalCtxDb, createPgVectorIndex, createPostgresGlobalCtxDb, mysqlDialect, postgresDialect };
|
package/dist/global.mjs
CHANGED
|
@@ -1,9 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { postgresDialect, mysqlDialect } from './packem_shared/mysqlDialect-oNhZ58s8.mjs';
|
|
3
|
-
import { buildMysqlExec, buildPgExec } from './packem_shared/buildMysqlExec-DBbCjyq3.mjs';
|
|
4
|
-
|
|
5
|
-
const createHyperdriveGlobalCtxDb = ({ engine, exec, ...rest }) => createSqlCtxDb({ ...rest, dialect: engine === "postgres" ? postgresDialect : mysqlDialect, exec });
|
|
6
|
-
const createPostgresGlobalCtxDb = (client, options) => createHyperdriveGlobalCtxDb({ ...options, engine: "postgres", exec: buildPgExec(client) });
|
|
7
|
-
const createMysqlGlobalCtxDb = (connection, options) => createHyperdriveGlobalCtxDb({ ...options, engine: "mysql", exec: buildMysqlExec(connection) });
|
|
8
|
-
|
|
9
|
-
export { buildMysqlExec, buildPgExec, createHyperdriveGlobalCtxDb, createMysqlGlobalCtxDb, createPostgresGlobalCtxDb, mysqlDialect, postgresDialect };
|
|
1
|
+
import{createSqlCtxDb as c}from"@lunora/sql-store";import{postgresDialect as l,mysqlDialect as s}from"./packem_shared/mysqlDialect-BS1Sz60B.mjs";import{buildMysqlExec as a,buildPgExec as i}from"./packem_shared/buildMysqlExec-CjkrA5JG.mjs";import{createPgVectorIndex as d}from"./packem_shared/createPgVectorIndex-CSNnG065.mjs";const r=({engine:e,exec:t,...o})=>c({...o,dialect:e==="postgres"?l:s,exec:t}),p=(e,t)=>r({...t,engine:"postgres",exec:i(e)}),g=(e,t)=>r({...t,engine:"mysql",exec:a(e)});export{a as buildMysqlExec,i as buildPgExec,r as createHyperdriveGlobalCtxDb,g as createMysqlGlobalCtxDb,d as createPgVectorIndex,p as createPostgresGlobalCtxDb,s as mysqlDialect,l as postgresDialect};
|