@lunora/hyperdrive 1.0.0-alpha.18 → 1.0.0-alpha.180

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,187 +1,81 @@
1
+ import { H as HyperdriveLike, a as HyperdriveConnection, M as Mysql2Like, S as SqlClient, N as NodePgLike, P as PostgresJsLike } from "./packem_shared/types.d-B2JdXSms.mjs";
1
2
  /**
2
- * Public types for `@lunora/hyperdrive`.
3
- *
4
- * Hyperdrive points at a database **Lunora does not own**. Everything here is
5
- * deliberately structural (no hard dependency on `@cloudflare/workers-types` or
6
- * any SQL driver) so unit tests can pass plain-object doubles, exactly like the
7
- * `D1DatabaseLike` projection in `@lunora/d1`.
8
- *
9
- * The hard constraint, restated wherever this surface is used: Hyperdrive
10
- * queries are **non-deterministic** (forbidden in `query`/`mutation`, allowed
11
- * only in `action`s — see the `hyperdrive_outside_action` advisor lint), and
12
- * external writes are **invisible to Lunora live queries** — a subscription will
13
- * NOT re-run when an external Postgres/MySQL row changes.
14
- */
15
- /**
16
- * Structural projection of the Cloudflare `Hyperdrive` binding (`env.HYPERDRIVE`).
17
- *
18
- * Mirrors the fields of the real `Hyperdrive` from `@cloudflare/workers-types`
19
- * but stays structural so a unit test can pass a plain object. At runtime only
20
- * `connectionString` is needed to construct a driver; the discrete connection
21
- * parts are surfaced for drivers that prefer a config object over a DSN.
22
- */
23
- interface HyperdriveLike {
24
- /** A connection string Hyperdrive routes through its pooled, cached edge connection. */
25
- connectionString: string;
26
- /** Database name component of the connection. */
27
- database: string;
28
- /** Host Hyperdrive presents to the driver (the local proxy, not your origin DB). */
29
- host: string;
30
- /** Password component of the connection. */
31
- password: string;
32
- /** Port Hyperdrive presents to the driver. */
33
- port: number;
34
- /** User component of the connection. */
35
- user: string;
36
- }
37
- /**
38
- * The connection config surfaced by {@link import("./create-hyperdrive").createHyperdrive | createHyperdrive}: the raw
39
- * `connectionString` plus the discrete parts, ready to hand to a driver.
40
- */
41
- interface HyperdriveConnection {
42
- /** Database name. */
43
- database: string;
44
- /** Host (Hyperdrive's local proxy). */
45
- host: string;
46
- /** Password. */
47
- password: string;
48
- /** Port. */
49
- port: number;
50
- /** User. */
51
- user: string;
52
- }
53
- /**
54
- * The driver-agnostic SQL surface bound to `ctx.sql` on **`ActionCtx` only**.
55
- *
56
- * This is the exact type the generated ctx imports as
57
- * `import("@lunora/hyperdrive").SqlClient`. Keep the name and shape stable — the
58
- * codegen ctx wiring (Phase 1) depends on it.
59
- *
60
- * It is intentionally minimal — a single parameterised `query` — so it maps onto
61
- * `postgres` (postgres.js), `pg` (node-postgres) and `mysql2` alike via the
62
- * {@link import("./create-hyperdrive").fromPostgresJs | fromPostgresJs} /
63
- * {@link import("./create-hyperdrive").fromNodePg | fromNodePg} /
64
- * {@link import("./create-hyperdrive").fromMysql2 | fromMysql2} adapters. Use
65
- * positional placeholders that match your driver (`$1, $2` for Postgres, `?` for
66
- * MySQL); the package does not rewrite SQL.
67
- *
68
- * Reminder (also on the emitted JSDoc): non-deterministic, action-only,
69
- * non-reactive — writes here are not tracked by Lunora live queries.
70
- */
71
- interface SqlClient {
72
- /**
73
- * Run a parameterised SQL statement and return the result rows.
74
- *
75
- * SECURITY: `text` is executed verbatim — the package never rewrites or
76
- * escapes it. NEVER interpolate untrusted/user input into `text`; put every
77
- * value in `params` and reference it with a positional placeholder (`$1`/`?`).
78
- * Building `text` by string-concatenating request data is a SQL-injection
79
- * sink against your own Postgres/MySQL. Identifiers (table/column names) can't
80
- * be parameterised — allowlist them against a fixed set, don't interpolate.
81
- * @param text SQL text with driver-native positional placeholders.
82
- * @param params Bound parameter values, positionally matched to `text`.
83
- * @returns The rows the statement produced (empty for non-`SELECT`s that
84
- * return no rows).
85
- */
86
- query: <Row = Record<string, unknown>>(text: string, params?: ReadonlyArray<unknown>) => Promise<Row[]>;
87
- }
88
- /**
89
- * Structural projection of a `pg` (node-postgres) `Client`/`Pool`. Only the
90
- * `query` method `fromNodePg` calls is required, kept structural for testing.
91
- */
92
- interface NodePgLike {
93
- query: (text: string, params?: ReadonlyArray<unknown>) => Promise<{
94
- rows: unknown[];
95
- }>;
96
- }
97
- /**
98
- * Structural projection of a `postgres` (postgres.js) tagged-template client.
99
- * The adapter uses the `.unsafe(text, params)` escape hatch so callers keep
100
- * full control of the parameter list.
101
- */
102
- interface PostgresJsLike {
103
- unsafe: (text: string, params?: ReadonlyArray<unknown>) => Promise<unknown>;
104
- }
105
- /**
106
- * Structural projection of a `mysql2/promise` connection/pool. `mysql2`'s
107
- * `execute` resolves to a `[rows, fields]` tuple; the adapter takes the first
108
- * element as the rows.
109
- */
110
- interface Mysql2Like {
111
- execute: (text: string, params?: ReadonlyArray<unknown>) => Promise<[unknown, unknown]>;
112
- }
113
- /**
114
- * Surface a Cloudflare Hyperdrive binding as a connection ready to feed a
115
- * user-supplied SQL driver.
116
- *
117
- * `@lunora/hyperdrive` deliberately **bundles no driver** — `postgres`, `pg` and
118
- * `mysql2` are heavy and the choice is the user's (they are `optional`
119
- * `peerDependencies`, never `dependencies`). This factory's only job is to lift
120
- * the binding's connection details out; the user constructs their own driver
121
- * from `connectionString` and wraps it with one of the {@link fromPostgresJs} /
122
- * {@link fromNodePg} / {@link fromMysql2} adapters to get a {@link SqlClient}.
123
- * @example
124
- * ```ts
125
- * import { createHyperdrive, fromPostgresJs } from "@lunora/hyperdrive";
126
- * import postgres from "postgres";
127
- *
128
- * // inside an action (never a query/mutation):
129
- * const { connectionString } = createHyperdrive(env.HYPERDRIVE);
130
- * ctx.sql = fromPostgresJs(postgres(connectionString));
131
- * const rows = await ctx.sql.query("select id from users where org = $1", [orgId]);
132
- * ```
133
- * @remarks
134
- * Hyperdrive talks to an **external** database Lunora has no visibility into.
135
- * Queries through `ctx.sql` are non-deterministic (action-only — enforced by the
136
- * `hyperdrive_outside_action` advisor lint) and external writes are NOT tracked
137
- * by Lunora live queries: subscriptions will not re-run when external rows
138
- * change. Use Hyperdrive to *integrate* an existing DB from an action; if you
139
- * want that data to be reactive, write a projection of it into a `defineSchema`
140
- * DO/D1 table.
141
- * @param binding The `env.HYPERDRIVE` binding (or a structural double).
142
- * @returns The raw `connectionString` plus the discrete connection parts.
143
- */
3
+ * Surface a Cloudflare Hyperdrive binding as a connection ready to feed a
4
+ * user-supplied SQL driver.
5
+ *
6
+ * `@lunora/hyperdrive` deliberately **bundles no driver** — `postgres`, `pg` and
7
+ * `mysql2` are heavy and the choice is the user's (they are `optional`
8
+ * `peerDependencies`, never `dependencies`). This factory's only job is to lift
9
+ * the binding's connection details out; the user constructs their own driver
10
+ * from `connectionString` and wraps it with one of the {@link fromPostgresJs} /
11
+ * {@link fromNodePg} / {@link fromMysql2} adapters to get a {@link SqlClient}.
12
+ * @example
13
+ * ```ts
14
+ * import { createHyperdrive, fromPostgresJs } from "@lunora/hyperdrive";
15
+ * import postgres from "postgres";
16
+ *
17
+ * // Wire the client once, on the app builder — called per shard construction,
18
+ * // not per request. `ctx.sql` is emitted `readonly`; it is never assigned.
19
+ * const app = defineApp<Env>()
20
+ * .shard((env) => env.SHARD)
21
+ * .hyperdrive((env) => fromPostgresJs(postgres(createHyperdrive(env.HYPERDRIVE).connectionString)))
22
+ * .build();
23
+ *
24
+ * // Then, inside an action (never a query/mutation):
25
+ * const rows = await ctx.sql.query("select id from users where org = $1", [orgId]);
26
+ * ```
27
+ * @remarks
28
+ * Hyperdrive talks to an **external** database Lunora has no visibility into.
29
+ * Queries through `ctx.sql` are non-deterministic (action-only — enforced by the
30
+ * `hyperdrive_outside_action` advisor lint) and external writes are NOT tracked
31
+ * by Lunora live queries: subscriptions will not re-run when external rows
32
+ * change. Use Hyperdrive to *integrate* an existing DB from an action; if you
33
+ * want that data to be reactive, write a projection of it into a `defineSchema`
34
+ * DO/D1 table.
35
+ * @param binding The `env.HYPERDRIVE` binding (or a structural double).
36
+ * @returns The raw `connectionString` plus the discrete connection parts.
37
+ */
144
38
  declare const createHyperdrive: (binding: HyperdriveLike) => {
145
39
  config: HyperdriveConnection;
146
40
  connectionString: string;
147
41
  };
148
42
  /**
149
- * Wrap a `postgres` (postgres.js) client as a {@link SqlClient}.
150
- *
151
- * Uses the driver's `.unsafe(text, params)` escape hatch so the caller supplies
152
- * a plain SQL string with `$1, $2, …` placeholders and a positional params
153
- * array. postgres.js's `.unsafe` resolves to a row array.
154
- */
43
+ * Wrap a `postgres` (postgres.js) client as a {@link SqlClient}.
44
+ *
45
+ * Uses the driver's `.unsafe(text, params)` escape hatch so the caller supplies
46
+ * a plain SQL string with `$1, $2, …` placeholders and a positional params
47
+ * array. postgres.js's `.unsafe` resolves to a row array.
48
+ */
155
49
  declare const fromPostgresJs: (client: PostgresJsLike) => SqlClient;
156
50
  /**
157
- * Wrap a `pg` (node-postgres) `Client` or `Pool` as a {@link SqlClient}.
158
- *
159
- * node-postgres returns a result object whose `rows` field holds the row array.
160
- */
51
+ * Wrap a `pg` (node-postgres) `Client` or `Pool` as a {@link SqlClient}.
52
+ *
53
+ * node-postgres returns a result object whose `rows` field holds the row array.
54
+ */
161
55
  declare const fromNodePg: (client: NodePgLike) => SqlClient;
162
56
  /**
163
- * Wrap a `mysql2/promise` connection or pool as a {@link SqlClient}.
164
- *
165
- * Use `?` placeholders (MySQL positional syntax). `mysql2`'s `execute` resolves
166
- * to a `[rows, fields]` tuple; the adapter returns the first element. For a
167
- * non-`SELECT` (DML), `mysql2` yields a `ResultSetHeader` object rather than a
168
- * row array, so the adapter normalises that to `[]` — matching the empty-array
169
- * contract the postgres.js / node-postgres adapters already honour.
170
- */
57
+ * Wrap a `mysql2/promise` connection or pool as a {@link SqlClient}.
58
+ *
59
+ * Use `?` placeholders (MySQL positional syntax). `mysql2`'s `execute` resolves
60
+ * to a `[rows, fields]` tuple; the adapter returns the first element. For a
61
+ * non-`SELECT` (DML), `mysql2` yields a `ResultSetHeader` object rather than a
62
+ * row array, so the adapter normalises that to `[]` — matching the empty-array
63
+ * contract the postgres.js / node-postgres adapters already honour.
64
+ */
171
65
  declare const fromMysql2: (connection: Mysql2Like) => SqlClient;
172
66
  /** How an external row maps to a Lunora document. */
173
67
  interface ProjectOptions {
174
68
  /**
175
- * Column whose value becomes the Lunora `_id` (stringified). Defaults to `"id"`.
176
- * With no `map`, this column is dropped from the document body (it lives on as
177
- * `_id`); with a `map`, the mapper owns the body and `_id` is added from here.
178
- */
69
+ * Column whose value becomes the Lunora `_id` (stringified). Defaults to `"id"`.
70
+ * With no `map`, this column is dropped from the document body (it lives on as
71
+ * `_id`); with a `map`, the mapper owns the body and `_id` is added from here.
72
+ */
179
73
  idColumn?: string;
180
74
  /**
181
- * Transform an external row into the stored document body. Omit for the default:
182
- * every selected column except `idColumn` is copied verbatim. The returned object
183
- * must not include `_id` — it is set from `idColumn`.
184
- */
75
+ * Transform an external row into the stored document body. Omit for the default:
76
+ * every selected column except `idColumn` is copied verbatim. The returned object
77
+ * must not include `_id` — it is set from `idColumn`.
78
+ */
185
79
  map?: (row: Record<string, unknown>) => Record<string, unknown>;
186
80
  }
187
81
  /** Options for {@link pullSourceRows}: the parameterised tenant query plus the row projection. */
@@ -192,20 +86,68 @@ interface PullSourceOptions extends ProjectOptions {
192
86
  query: string;
193
87
  }
194
88
  /**
195
- * Project one external row to a Lunora document: lift `idColumn` to a stringified
196
- * `_id`, then either apply `map` or copy every other column verbatim. Throws when
197
- * the id column is missing/nullish so a misconfigured query fails loudly rather than
198
- * materializing rows under an `"undefined"` id.
199
- *
200
- * Delegates to `@lunora/do`'s `liftSourceId` — the single id-lift the declarative
201
- * `.source()` poll loop also uses — so the manual bridge and the codegen path can
202
- * never diverge in their missing-id handling.
203
- */
89
+ * Project one external row to a Lunora document: lift `idColumn` to a stringified
90
+ * `_id`, then either apply `map` or copy every other column verbatim. Throws when
91
+ * the id column is missing/nullish so a misconfigured query fails loudly rather than
92
+ * materializing rows under an `"undefined"` id.
93
+ *
94
+ * Delegates to `@lunora/shard-engine`'s `liftSourceId` — the single id-lift the declarative
95
+ * `.source()` poll loop also uses — so the manual bridge and the codegen path can
96
+ * never diverge in their missing-id handling.
97
+ */
204
98
  declare const projectSourceRow: (row: Record<string, unknown>, options?: ProjectOptions) => Record<string, unknown>;
205
99
  /**
206
- * Run a parameterised tenant query against Hyperdrive and project every row to a
207
- * Lunora document ready to hand to `materializeExternalRows`. Call this inside an
208
- * **action** (where `ctx.sql` lives); pass the result to a mutation for the write.
209
- */
100
+ * Run a parameterised tenant query against Hyperdrive and project every row to a
101
+ * Lunora document ready to hand to `materializeExternalRows`. Call this inside an
102
+ * **action** (where `ctx.sql` lives); pass the result to a mutation for the write.
103
+ */
210
104
  declare const pullSourceRows: (sql: SqlClient, options: PullSourceOptions) => Promise<Record<string, unknown>[]>;
211
- export { type HyperdriveConnection, type HyperdriveLike, type Mysql2Like, type NodePgLike, type PostgresJsLike, type ProjectOptions, type PullSourceOptions, type SqlClient, createHyperdrive, fromMysql2, fromNodePg, fromPostgresJs, projectSourceRow, pullSourceRows };
105
+ export { type HyperdriveConnection, type HyperdriveLike, type Mysql2Like, type NodePgLike, type PostgresJsLike, type ProjectOptions, type PullSourceOptions, type SqlClient,
106
+ /**
107
+ * `@lunora/hyperdrive` — bring-your-own Postgres/MySQL for Lunora via Cloudflare
108
+ * Hyperdrive.
109
+ *
110
+ * Surfaces a Hyperdrive binding's connection string and a driver-agnostic
111
+ * {@link import("./types").SqlClient | SqlClient} bound to `ctx.sql` on
112
+ * **`ActionCtx` only**. External SQL is non-deterministic (action-only) and
113
+ * non-reactive (live queries do not track external writes) — integrate an
114
+ * existing DB, do not replace the Lunora data layer. See the README and
115
+ * {@link import("./create-hyperdrive").createHyperdrive | createHyperdrive} JSDoc.
116
+ */
117
+ createHyperdrive,
118
+ /**
119
+ * `@lunora/hyperdrive` — bring-your-own Postgres/MySQL for Lunora via Cloudflare
120
+ * Hyperdrive.
121
+ *
122
+ * Surfaces a Hyperdrive binding's connection string and a driver-agnostic
123
+ * {@link import("./types").SqlClient | SqlClient} bound to `ctx.sql` on
124
+ * **`ActionCtx` only**. External SQL is non-deterministic (action-only) and
125
+ * non-reactive (live queries do not track external writes) — integrate an
126
+ * existing DB, do not replace the Lunora data layer. See the README and
127
+ * {@link import("./create-hyperdrive").createHyperdrive | createHyperdrive} JSDoc.
128
+ */
129
+ fromMysql2,
130
+ /**
131
+ * `@lunora/hyperdrive` — bring-your-own Postgres/MySQL for Lunora via Cloudflare
132
+ * Hyperdrive.
133
+ *
134
+ * Surfaces a Hyperdrive binding's connection string and a driver-agnostic
135
+ * {@link import("./types").SqlClient | SqlClient} bound to `ctx.sql` on
136
+ * **`ActionCtx` only**. External SQL is non-deterministic (action-only) and
137
+ * non-reactive (live queries do not track external writes) — integrate an
138
+ * existing DB, do not replace the Lunora data layer. See the README and
139
+ * {@link import("./create-hyperdrive").createHyperdrive | createHyperdrive} JSDoc.
140
+ */
141
+ fromNodePg,
142
+ /**
143
+ * `@lunora/hyperdrive` — bring-your-own Postgres/MySQL for Lunora via Cloudflare
144
+ * Hyperdrive.
145
+ *
146
+ * Surfaces a Hyperdrive binding's connection string and a driver-agnostic
147
+ * {@link import("./types").SqlClient | SqlClient} bound to `ctx.sql` on
148
+ * **`ActionCtx` only**. External SQL is non-deterministic (action-only) and
149
+ * non-reactive (live queries do not track external writes) — integrate an
150
+ * existing DB, do not replace the Lunora data layer. See the README and
151
+ * {@link import("./create-hyperdrive").createHyperdrive | createHyperdrive} JSDoc.
152
+ */
153
+ fromPostgresJs, projectSourceRow, pullSourceRows };