@lunora/bindings 0.0.0 → 1.0.0-alpha.2
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 +105 -0
- package/README.md +39 -1
- package/__assets__/package-og.svg +14 -0
- package/dist/analytics/index.d.mts +148 -0
- package/dist/analytics/index.d.ts +148 -0
- package/dist/analytics/index.mjs +2 -0
- package/dist/images/index.d.mts +338 -0
- package/dist/images/index.d.ts +338 -0
- package/dist/images/index.mjs +3 -0
- package/dist/kv/index.d.mts +177 -0
- package/dist/kv/index.d.ts +177 -0
- package/dist/kv/index.mjs +1 -0
- package/dist/packem_shared/AnalyticsSqlError-CGTdsi4H.mjs +42 -0
- package/dist/packem_shared/R2SqlError-DlDd_SrE.mjs +67 -0
- package/dist/packem_shared/SelectBuilder-DHaXZwn_.mjs +167 -0
- package/dist/packem_shared/SetOperation-RDHcxccj.mjs +80 -0
- package/dist/packem_shared/Sql-DceGtcUd.mjs +68 -0
- package/dist/packem_shared/WindowExpression-Cg9s2xcr.mjs +44 -0
- package/dist/packem_shared/WindowFunction-DA3pGC3N.mjs +82 -0
- package/dist/packem_shared/asc-Cur-xO8v.mjs +16 -0
- package/dist/packem_shared/buildImageDeliveryUrl-D1sVfIOP.mjs +30 -0
- package/dist/packem_shared/buildSignedImageUrl-Otdgc_jO.mjs +113 -0
- package/dist/packem_shared/concurrent-Dj5sOibv.mjs +23 -0
- package/dist/packem_shared/createAnalytics-CEEI69o9.mjs +57 -0
- package/dist/packem_shared/createContextVectors-BSizpmu5.mjs +140 -0
- package/dist/packem_shared/createImages-CJrvqX0u.mjs +80 -0
- package/dist/packem_shared/createKv-DTiSt216.mjs +141 -0
- package/dist/packem_shared/createPipelines-CfyJ6VGu.mjs +10 -0
- package/dist/packem_shared/createVectorAdminIntrospector-BJUOM6VW.mjs +51 -0
- package/dist/packem_shared/createVectors-LSpGoKCd.mjs +91 -0
- package/dist/pipelines/index.d.mts +41 -0
- package/dist/pipelines/index.d.ts +41 -0
- package/dist/pipelines/index.mjs +1 -0
- package/dist/r2sql/index.d.mts +383 -0
- package/dist/r2sql/index.d.ts +383 -0
- package/dist/r2sql/index.mjs +7 -0
- package/dist/vectors/index.d.mts +285 -0
- package/dist/vectors/index.d.ts +285 -0
- package/dist/vectors/index.mjs +3 -0
- package/package.json +54 -4
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A composed SQL fragment. Carries the finished `text`; `toString()` returns it
|
|
3
|
+
* so a fragment can be dropped straight into a template or `String(...)`.
|
|
4
|
+
*/
|
|
5
|
+
declare class Sql {
|
|
6
|
+
readonly text: string;
|
|
7
|
+
constructor(text: string);
|
|
8
|
+
toString(): string;
|
|
9
|
+
}
|
|
10
|
+
/** True when `value` is a {@link Sql} fragment (an already-trusted, pre-escaped span). */
|
|
11
|
+
declare const isSql: (value: unknown) => value is Sql;
|
|
12
|
+
/**
|
|
13
|
+
* Wrap an already-trusted string as a {@link Sql} fragment so {@link sql}
|
|
14
|
+
* splices it **verbatim** (no escaping). Use ONLY for SQL you constructed
|
|
15
|
+
* yourself (identifiers, keywords, sub-fragments) — never for user input.
|
|
16
|
+
*/
|
|
17
|
+
declare const raw: (text: string) => Sql;
|
|
18
|
+
/** Resolve a `string | Sql` to its raw text. A bare string is taken as trusted SQL (callers pass identifiers/fragments here). */
|
|
19
|
+
declare const toText: (value: Sql | string) => string;
|
|
20
|
+
/**
|
|
21
|
+
* Render a JS value as an R2 SQL literal:
|
|
22
|
+
*
|
|
23
|
+
* - `null` / `undefined` → `NULL`
|
|
24
|
+
* - `boolean` → `true` / `false`
|
|
25
|
+
* - finite `number` / `bigint` → the numeric text (non-finite throws — `NaN`/`Infinity` have no SQL literal)
|
|
26
|
+
* - `Date` → an RFC3339 string literal (R2 SQL's `timestamp` form)
|
|
27
|
+
* - `string` → a single-quoted, escaped literal
|
|
28
|
+
* - `Array` → a parenthesised, comma-separated list of literals (for `IN (...)`)
|
|
29
|
+
*
|
|
30
|
+
* Anything else (object, symbol, function) throws — there is no safe SQL literal
|
|
31
|
+
* for it, and silently coercing would risk a malformed or injectable statement.
|
|
32
|
+
*/
|
|
33
|
+
declare const lit: (value: unknown) => string;
|
|
34
|
+
/**
|
|
35
|
+
* Tagged template producing a safe {@link Sql} fragment. Each interpolation is
|
|
36
|
+
* escaped with {@link lit} unless it is already a {@link Sql} (spliced
|
|
37
|
+
* verbatim), so user values can never break out of their literal.
|
|
38
|
+
*/
|
|
39
|
+
declare const sql: (strings: TemplateStringsArray, ...values: unknown[]) => Sql;
|
|
40
|
+
/** Join SQL fragments/strings with `separator` into one {@link Sql} (e.g. `AND`-ed conditions). */
|
|
41
|
+
declare const joinSql: (parts: ReadonlyArray<Sql | string>, separator: string) => Sql;
|
|
42
|
+
/** A single `ORDER BY` term: a bare column/expression (ASC) or one tagged via {@link asc} / {@link desc}. */
|
|
43
|
+
type OrderTerm = Sql | string | {
|
|
44
|
+
dir: "ASC" | "DESC";
|
|
45
|
+
expr: Sql | string;
|
|
46
|
+
};
|
|
47
|
+
/** Tag an order term ascending — `asc("total")` → `total ASC`. */
|
|
48
|
+
declare const asc: (expr: Sql | string) => OrderTerm;
|
|
49
|
+
/** Tag an order term descending — `desc("total")` → `total DESC`. */
|
|
50
|
+
declare const desc: (expr: Sql | string) => OrderTerm;
|
|
51
|
+
/** Render one {@link OrderTerm} to SQL. */
|
|
52
|
+
declare const renderOrderTerm: (term: OrderTerm) => string;
|
|
53
|
+
/**
|
|
54
|
+
* Public types for `@lunora/bindings/r2sql`.
|
|
55
|
+
*
|
|
56
|
+
* R2 SQL is Cloudflare's serverless, distributed query engine over **Apache
|
|
57
|
+
* Iceberg** tables in [R2 Data Catalog](https://developers.cloudflare.com/r2/data-catalog/).
|
|
58
|
+
* It has **no Workers binding** — every query is an HTTPS round-trip to the REST
|
|
59
|
+
* endpoint (`POST …/r2-sql/query/{bucket}`). So, like Hyperdrive's `ctx.sql`, the
|
|
60
|
+
* client is **non-deterministic external I/O**: it is wired onto `ActionCtx`
|
|
61
|
+
* only (see the `r2sql_outside_action` advisor lint) and its reads are NOT
|
|
62
|
+
* tracked by Lunora live queries.
|
|
63
|
+
*
|
|
64
|
+
* Everything here is deliberately structural (no hard dependency on
|
|
65
|
+
* `@cloudflare/workers-types`) so unit tests can inject a plain `fetch` double
|
|
66
|
+
* and never touch the network — mirroring `AnalyticsSqlConfig` in
|
|
67
|
+
* `@lunora/bindings/analytics`.
|
|
68
|
+
*/
|
|
69
|
+
/**
|
|
70
|
+
* Configuration for a {@link import("./client").R2SqlClient | R2SqlClient}.
|
|
71
|
+
*
|
|
72
|
+
* `apiToken` is a **secret** — a Cloudflare API token scoped to R2 SQL (read),
|
|
73
|
+
* R2 Data Catalog, and R2 storage. It is never a binding and must never be
|
|
74
|
+
* auto-scaffolded with a real value; the caller provides it from
|
|
75
|
+
* env/`.dev.vars`.
|
|
76
|
+
*/
|
|
77
|
+
interface R2SqlConfig {
|
|
78
|
+
/** Cloudflare account id that owns the bucket/catalog. */
|
|
79
|
+
accountId: string;
|
|
80
|
+
/** API token with R2 SQL read + R2 Data Catalog + R2 storage scope. A secret — never a binding. */
|
|
81
|
+
apiToken: string;
|
|
82
|
+
/** The R2 bucket (warehouse) whose Data Catalog the queries run against. */
|
|
83
|
+
bucket: string;
|
|
84
|
+
/**
|
|
85
|
+
* Override the REST base URL. Defaults to Cloudflare's public R2 SQL host
|
|
86
|
+
* (`https://api.sql.cloudflarestorage.com/api/v1/accounts`). Injected in
|
|
87
|
+
* tests, or pointed at a regional/preview host.
|
|
88
|
+
*/
|
|
89
|
+
endpoint?: string;
|
|
90
|
+
/**
|
|
91
|
+
* `fetch` implementation. Defaults to the global `fetch`; injected in tests
|
|
92
|
+
* so a query never touches the network.
|
|
93
|
+
*/
|
|
94
|
+
fetch?: typeof globalThis.fetch;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* One column descriptor in a result's schema: the column `name` and, when the
|
|
98
|
+
* engine reports it, the Iceberg storage `type` (`integer`, `string`,
|
|
99
|
+
* `timestamp`, …). R2 SQL does not always echo a schema block, so `type` is
|
|
100
|
+
* optional and `columns` may be derived from the first row's keys.
|
|
101
|
+
*/
|
|
102
|
+
interface R2SqlColumn {
|
|
103
|
+
name: string;
|
|
104
|
+
type?: string;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* A parsed R2 SQL result. R2 SQL returns a Cloudflare envelope
|
|
108
|
+
* (`{ success, result, errors }`); we surface the `rows` (the `result` array of
|
|
109
|
+
* column→value records), the inferred/echoed `columns`, and the `rowCount`.
|
|
110
|
+
*
|
|
111
|
+
* `Row` defaults to an open record; supply it (`from<MyRow>(…)` /
|
|
112
|
+
* `query<MyRow>(…)`) to get typed result fields — R2 SQL tables live in Iceberg,
|
|
113
|
+
* not `defineSchema`, so the row type is caller-declared rather than inferred.
|
|
114
|
+
*/
|
|
115
|
+
interface R2SqlResult<Row = Record<string, unknown>> {
|
|
116
|
+
/** Column descriptors, echoed by the engine or inferred from the first row. */
|
|
117
|
+
columns: R2SqlColumn[];
|
|
118
|
+
/** Total rows returned. */
|
|
119
|
+
rowCount: number;
|
|
120
|
+
/** The result rows. */
|
|
121
|
+
rows: Row[];
|
|
122
|
+
}
|
|
123
|
+
/** Options for {@link import("./client").R2SqlClient.explain | explain}. */
|
|
124
|
+
interface R2SqlExplainOptions {
|
|
125
|
+
/**
|
|
126
|
+
* `"json"` runs `EXPLAIN FORMAT JSON` (structured plan); `"text"` (default)
|
|
127
|
+
* runs a plain `EXPLAIN`.
|
|
128
|
+
*/
|
|
129
|
+
format?: "json" | "text";
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Executes a finished SQL string against R2 SQL and returns the parsed result.
|
|
133
|
+
* Deliberately non-generic (the row type is a caller-side concern) — the typed
|
|
134
|
+
* `run()` / `query()` boundaries cast the open result to the declared row.
|
|
135
|
+
*/
|
|
136
|
+
type QueryExecutor = (statement: string) => Promise<R2SqlResult>;
|
|
137
|
+
/** Anything that compiles to a statement and can run — a {@link import("./builder").SelectBuilder | SelectBuilder} or {@link import("./set-operation").SetOperation | SetOperation}. */
|
|
138
|
+
interface Queryable<Row = Record<string, unknown>> {
|
|
139
|
+
/**
|
|
140
|
+
* True when this query carries its own `ORDER BY`/`LIMIT`, so a set
|
|
141
|
+
* operation must parenthesise it (R2 SQL rejects a bare `LIMIT` before a set
|
|
142
|
+
* operator). Read structurally by the set-operation renderer to avoid an
|
|
143
|
+
* import cycle.
|
|
144
|
+
*/
|
|
145
|
+
readonly needsWrapForSetOperation?: boolean;
|
|
146
|
+
run: () => Promise<R2SqlResult<Row>>;
|
|
147
|
+
toSQL: () => string;
|
|
148
|
+
}
|
|
149
|
+
/** A `WHERE`/`HAVING`/`QUALIFY`/`ON` condition: trusted SQL text or a {@link Sql} fragment (use the `sql` tag to bind values safely). */
|
|
150
|
+
type Condition = Sql | string;
|
|
151
|
+
/** One member of a {@link SetOperation}: the leading query has no operator; each subsequent one carries the operator that joins it. */
|
|
152
|
+
interface SetMember {
|
|
153
|
+
operator?: string;
|
|
154
|
+
query: Queryable<unknown>;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* A composition of queries via set operations. Chain more operations, or apply a
|
|
158
|
+
* single `ORDER BY` / `LIMIT` to the combined result.
|
|
159
|
+
*/
|
|
160
|
+
declare class SetOperation<Row = Record<string, unknown>> implements Queryable<Row> {
|
|
161
|
+
/**
|
|
162
|
+
* Always `true`: a nested set operation must be parenthesised when it is a
|
|
163
|
+
* member of another set operation, or mixed operators mis-associate — e.g.
|
|
164
|
+
* `a.union(b.except(c))` must render `a UNION (b EXCEPT c)`, not the flat
|
|
165
|
+
* `a UNION b EXCEPT c`.
|
|
166
|
+
*/
|
|
167
|
+
readonly needsWrapForSetOperation = true;
|
|
168
|
+
private readonly exec;
|
|
169
|
+
private readonly members;
|
|
170
|
+
private readonly orderByItems;
|
|
171
|
+
private limitValue?;
|
|
172
|
+
constructor(exec: QueryExecutor, members: SetMember[]);
|
|
173
|
+
/** Append `UNION other`. */
|
|
174
|
+
union(other: Queryable<unknown>): this;
|
|
175
|
+
/** Append `UNION ALL other`. */
|
|
176
|
+
unionAll(other: Queryable<unknown>): this;
|
|
177
|
+
/** Append `INTERSECT other`. */
|
|
178
|
+
intersect(other: Queryable<unknown>): this;
|
|
179
|
+
/** Append `EXCEPT other`. */
|
|
180
|
+
except(other: Queryable<unknown>): this;
|
|
181
|
+
/** `ORDER BY` applied to the combined result. */
|
|
182
|
+
orderBy(...terms: OrderTerm[]): this;
|
|
183
|
+
/** `LIMIT` applied to the combined result. */
|
|
184
|
+
limit(n: number): this;
|
|
185
|
+
/** Re-type the combined result rows. */
|
|
186
|
+
returns<NextRow>(): SetOperation<NextRow>;
|
|
187
|
+
/** Render the combined statement. */
|
|
188
|
+
toSQL(): string;
|
|
189
|
+
/** Execute the combined query and return the typed result. */
|
|
190
|
+
run(): Promise<R2SqlResult<Row>>;
|
|
191
|
+
private add;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* A fluent `SELECT` over one Iceberg table (`namespace.table`), generic over the
|
|
195
|
+
* caller-declared `Row` result type.
|
|
196
|
+
*/
|
|
197
|
+
declare class SelectBuilder<Row = Record<string, unknown>> implements Queryable<Row> {
|
|
198
|
+
private readonly exec;
|
|
199
|
+
private readonly table;
|
|
200
|
+
private readonly selectItems;
|
|
201
|
+
private distinctFlag;
|
|
202
|
+
private readonly distinctOnItems;
|
|
203
|
+
private readonly joins;
|
|
204
|
+
private readonly whereConditions;
|
|
205
|
+
private readonly groupByItems;
|
|
206
|
+
private readonly havingConditions;
|
|
207
|
+
private qualifyCondition?;
|
|
208
|
+
private readonly orderByItems;
|
|
209
|
+
private limitValue?;
|
|
210
|
+
constructor(exec: QueryExecutor, table: string);
|
|
211
|
+
/** The `SELECT` list. Omit/empty for `SELECT *`. Items are columns, expressions, or aliased window fragments (`fn.rowNumber().over(...).as("rk")`). */
|
|
212
|
+
select(...items: (Sql | string)[]): this;
|
|
213
|
+
/** `SELECT DISTINCT` — unique rows. */
|
|
214
|
+
distinct(): this;
|
|
215
|
+
/** `DISTINCT ON (cols)` — the first row per distinct combination, ordered by {@link orderBy}. */
|
|
216
|
+
distinctOn(...columns: (Sql | string)[]): this;
|
|
217
|
+
/** `INNER JOIN table ON condition`. */
|
|
218
|
+
innerJoin(table: string, on: Condition): this;
|
|
219
|
+
/** `LEFT JOIN table ON condition`. */
|
|
220
|
+
leftJoin(table: string, on: Condition): this;
|
|
221
|
+
/** `RIGHT JOIN table ON condition`. */
|
|
222
|
+
rightJoin(table: string, on: Condition): this;
|
|
223
|
+
/** `FULL OUTER JOIN table ON condition`. */
|
|
224
|
+
fullJoin(table: string, on: Condition): this;
|
|
225
|
+
/** `CROSS JOIN table` (no `ON`). */
|
|
226
|
+
crossJoin(table: string): this;
|
|
227
|
+
/** Add `WHERE` condition(s). Multiple calls (and multiple args) are `AND`-ed. Bind values with the `sql` tag. */
|
|
228
|
+
where(...conditions: Condition[]): this;
|
|
229
|
+
/** `GROUP BY` column(s)/expression(s). */
|
|
230
|
+
groupBy(...columns: (Sql | string)[]): this;
|
|
231
|
+
/** Add `HAVING` condition(s) over aggregates; multiple are `AND`-ed. */
|
|
232
|
+
having(...conditions: Condition[]): this;
|
|
233
|
+
/**
|
|
234
|
+
* `QUALIFY` — filter on a window function without a subquery, e.g.
|
|
235
|
+
* `.qualify(fn.rowNumber().over({ partitionBy: "region", orderBy: desc("total") }).lte(3))`.
|
|
236
|
+
*/
|
|
237
|
+
qualify(condition: Condition): this;
|
|
238
|
+
/** `ORDER BY` term(s) — bare strings (ASC) or {@link import("./order").asc | asc}/{@link import("./order").desc | desc} tags. */
|
|
239
|
+
orderBy(...terms: OrderTerm[]): this;
|
|
240
|
+
/** `LIMIT n` (R2 SQL: 1–10,000, default 500). */
|
|
241
|
+
limit(n: number): this;
|
|
242
|
+
/** Re-type the result rows without changing the query (the builder carries no schema of its own). */
|
|
243
|
+
returns<NextRow>(): SelectBuilder<NextRow>;
|
|
244
|
+
/** `this UNION other` — all rows from both, duplicates removed. */
|
|
245
|
+
union(other: Queryable<unknown>): SetOperation<Row>;
|
|
246
|
+
/** `this UNION ALL other` — all rows from both, duplicates kept. */
|
|
247
|
+
unionAll(other: Queryable<unknown>): SetOperation<Row>;
|
|
248
|
+
/** `this INTERSECT other` — rows present in both. */
|
|
249
|
+
intersect(other: Queryable<unknown>): SetOperation<Row>;
|
|
250
|
+
/** `this EXCEPT other` — rows in `this` but not `other`. */
|
|
251
|
+
except(other: Queryable<unknown>): SetOperation<Row>;
|
|
252
|
+
/** True when this query carries its own `ORDER BY`/`LIMIT` — so a set operation must parenthesise it. */
|
|
253
|
+
get needsWrapForSetOperation(): boolean;
|
|
254
|
+
/** Render the `SELECT` statement (no trailing semicolon). */
|
|
255
|
+
toSQL(): string;
|
|
256
|
+
/** Execute the query and return the typed result. */
|
|
257
|
+
run(): Promise<R2SqlResult<Row>>;
|
|
258
|
+
/** The `SELECT [DISTINCT [ON (...)]]` head. */
|
|
259
|
+
private renderHead;
|
|
260
|
+
private addJoin;
|
|
261
|
+
private setOperation;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Thrown when R2 SQL responds with a non-2xx status, an `success: false`
|
|
265
|
+
* envelope, or an unparseable body; carries the HTTP `status` and the raw body
|
|
266
|
+
* for the caller to surface.
|
|
267
|
+
*/
|
|
268
|
+
declare class R2SqlError extends Error {
|
|
269
|
+
readonly status: number;
|
|
270
|
+
constructor(status: number, body: string);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* The typed R2 SQL surface bound to `ctx.r2sql` on **`ActionCtx` only**. This is
|
|
274
|
+
* the exact type the generated ctx imports as
|
|
275
|
+
* `import("@lunora/bindings/r2sql").R2SqlClient` — keep the name and shape stable.
|
|
276
|
+
*/
|
|
277
|
+
interface R2SqlClient {
|
|
278
|
+
/** Run `DESCRIBE namespace.table` — column names and Iceberg types. */
|
|
279
|
+
describe: (table: string) => Promise<R2SqlResult>;
|
|
280
|
+
/** Run `EXPLAIN [FORMAT JSON] sql` — the execution plan, without running the query. */
|
|
281
|
+
explain: (statement: Sql | string, options?: R2SqlExplainOptions) => Promise<R2SqlResult>;
|
|
282
|
+
/** Start a chainable `SELECT` over `table` (`namespace.table`), generic over the caller-declared `Row`. */
|
|
283
|
+
from: <Row = Record<string, unknown>>(table: string) => SelectBuilder<Row>;
|
|
284
|
+
/** Run a raw SQL statement (the escape hatch). Use the `sql` tag to bind values safely. */
|
|
285
|
+
query: <Row = Record<string, unknown>>(statement: Sql | string) => Promise<R2SqlResult<Row>>;
|
|
286
|
+
/** Run `SHOW DATABASES` — the available namespaces. */
|
|
287
|
+
showDatabases: () => Promise<R2SqlResult>;
|
|
288
|
+
/** Run `SHOW TABLES IN namespace` — the tables in a namespace. */
|
|
289
|
+
showTables: (namespace: string) => Promise<R2SqlResult>;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Build an {@link R2SqlClient}. Each query POSTs to the bucket's
|
|
293
|
+
* `r2-sql/query/{bucket}` endpoint with the bearer token, then normalises the
|
|
294
|
+
* envelope into {@link R2SqlResult}.
|
|
295
|
+
*/
|
|
296
|
+
declare const createR2Sql: (config: R2SqlConfig) => R2SqlClient;
|
|
297
|
+
/**
|
|
298
|
+
* A windowed expression. Extends {@link Sql}, so it is usable anywhere a raw
|
|
299
|
+
* fragment is; `.as(alias)` makes a `SELECT` item, and the comparison helpers
|
|
300
|
+
* (`.lte`, `.gt`, `.between`, …) make `QUALIFY` conditions.
|
|
301
|
+
*/
|
|
302
|
+
declare class WindowExpression extends Sql {
|
|
303
|
+
/** Alias the expression — `... AS alias` — for use in a `SELECT` list. */
|
|
304
|
+
as(alias: string): Sql;
|
|
305
|
+
/** `expr BETWEEN low AND high`. */
|
|
306
|
+
between(low: unknown, high: unknown): Sql;
|
|
307
|
+
/** `expr = value`. */
|
|
308
|
+
eq(value: unknown): Sql;
|
|
309
|
+
/** `expr > value`. */
|
|
310
|
+
gt(value: unknown): Sql;
|
|
311
|
+
/** `expr >= value`. */
|
|
312
|
+
gte(value: unknown): Sql;
|
|
313
|
+
/** `expr < value`. */
|
|
314
|
+
lt(value: unknown): Sql;
|
|
315
|
+
/** `expr <= value`. */
|
|
316
|
+
lte(value: unknown): Sql;
|
|
317
|
+
private compare;
|
|
318
|
+
}
|
|
319
|
+
/** The `OVER (...)` window specification. */
|
|
320
|
+
interface OverSpec {
|
|
321
|
+
/**
|
|
322
|
+
* A raw frame clause, e.g. `"ROWS BETWEEN 2 PRECEDING AND CURRENT ROW"`.
|
|
323
|
+
* Spliced verbatim — it is keyword-only SQL, not a value.
|
|
324
|
+
*/
|
|
325
|
+
frame?: string;
|
|
326
|
+
/** `ORDER BY` term(s) within the window. */
|
|
327
|
+
orderBy?: OrderTerm | OrderTerm[];
|
|
328
|
+
/** `PARTITION BY` column(s)/expression(s). */
|
|
329
|
+
partitionBy?: Sql | string | (Sql | string)[];
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* A window function awaiting its `OVER (...)`. Call {@link WindowFunction.over |
|
|
333
|
+
* .over} to bind a window and get a {@link WindowExpression}.
|
|
334
|
+
*/
|
|
335
|
+
declare class WindowFunction {
|
|
336
|
+
private readonly callText;
|
|
337
|
+
constructor(callText: string);
|
|
338
|
+
/** Attach the window frame, yielding a {@link WindowExpression}. */
|
|
339
|
+
over(spec?: OverSpec): WindowExpression;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Window-function builders. Each returns a {@link WindowFunction}; chain
|
|
343
|
+
* `.over(...)` to bind the window.
|
|
344
|
+
*
|
|
345
|
+
* Ranking: `rowNumber`, `rank`, `denseRank`, `percentRank`, `cumeDist`,
|
|
346
|
+
* `ntile`. Offset/value: `lag`, `lead`, `firstValue`, `lastValue`, `nthValue`.
|
|
347
|
+
* Aggregates used as windows: `sum`, `avg`, `count`, `min`, `max`.
|
|
348
|
+
*/
|
|
349
|
+
declare const fn: {
|
|
350
|
+
/** `AVG(column) OVER (...)`. */
|
|
351
|
+
avg: (column: Sql | string) => WindowFunction;
|
|
352
|
+
/** `COUNT(column) OVER (...)` — omit the column for `COUNT(*)`. */
|
|
353
|
+
count: (column?: Sql | string) => WindowFunction;
|
|
354
|
+
/** `CUME_DIST() OVER (...)`. */
|
|
355
|
+
cumeDist: () => WindowFunction;
|
|
356
|
+
/** `DENSE_RANK() OVER (...)`. */
|
|
357
|
+
denseRank: () => WindowFunction;
|
|
358
|
+
/** `FIRST_VALUE(column) OVER (...)`. */
|
|
359
|
+
firstValue: (column: Sql | string) => WindowFunction;
|
|
360
|
+
/** `LAG(column[, offset[, default]]) OVER (...)`. */
|
|
361
|
+
lag: (column: Sql | string, offset?: number, fallback?: unknown) => WindowFunction;
|
|
362
|
+
/** `LAST_VALUE(column) OVER (...)`. */
|
|
363
|
+
lastValue: (column: Sql | string) => WindowFunction;
|
|
364
|
+
/** `LEAD(column[, offset[, default]]) OVER (...)`. */
|
|
365
|
+
lead: (column: Sql | string, offset?: number, fallback?: unknown) => WindowFunction;
|
|
366
|
+
/** `MAX(column) OVER (...)`. */
|
|
367
|
+
max: (column: Sql | string) => WindowFunction;
|
|
368
|
+
/** `MIN(column) OVER (...)`. */
|
|
369
|
+
min: (column: Sql | string) => WindowFunction;
|
|
370
|
+
/** `NTH_VALUE(column, n) OVER (...)`. */
|
|
371
|
+
nthValue: (column: Sql | string, n: number) => WindowFunction;
|
|
372
|
+
/** `NTILE(buckets) OVER (...)`. */
|
|
373
|
+
ntile: (buckets: number) => WindowFunction;
|
|
374
|
+
/** `PERCENT_RANK() OVER (...)`. */
|
|
375
|
+
percentRank: () => WindowFunction;
|
|
376
|
+
/** `RANK() OVER (...)`. */
|
|
377
|
+
rank: () => WindowFunction;
|
|
378
|
+
/** `ROW_NUMBER() OVER (...)`. */
|
|
379
|
+
rowNumber: () => WindowFunction;
|
|
380
|
+
/** `SUM(column) OVER (...)`. */
|
|
381
|
+
sum: (column: Sql | string) => WindowFunction;
|
|
382
|
+
};
|
|
383
|
+
export { type Condition, type OrderTerm, type OverSpec, type QueryExecutor, type Queryable, type R2SqlClient, type R2SqlColumn, type R2SqlConfig, R2SqlError, type R2SqlExplainOptions, type R2SqlResult, SelectBuilder, SetOperation, Sql, WindowExpression, WindowFunction, asc, createR2Sql, desc, fn, isSql, joinSql, lit, raw, renderOrderTerm, sql, toText };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as SelectBuilder } from '../packem_shared/SelectBuilder-DHaXZwn_.mjs';
|
|
2
|
+
export { R2SqlError, createR2Sql } from '../packem_shared/R2SqlError-DlDd_SrE.mjs';
|
|
3
|
+
export { asc, desc, renderOrderTerm } from '../packem_shared/asc-Cur-xO8v.mjs';
|
|
4
|
+
export { default as SetOperation } from '../packem_shared/SetOperation-RDHcxccj.mjs';
|
|
5
|
+
export { Sql, isSql, joinSql, lit, raw, sql, toText } from '../packem_shared/Sql-DceGtcUd.mjs';
|
|
6
|
+
export { WindowFunction, fn } from '../packem_shared/WindowFunction-DA3pGC3N.mjs';
|
|
7
|
+
export { default as WindowExpression } from '../packem_shared/WindowExpression-Cg9s2xcr.mjs';
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal structural projection of `VectorizeIndex` so unit tests can pass a
|
|
3
|
+
* plain-object double and the real Cloudflare binding satisfies the same shape.
|
|
4
|
+
* Mirrors the surface documented at
|
|
5
|
+
* https://developers.cloudflare.com/vectorize/reference/client-api/.
|
|
6
|
+
*/
|
|
7
|
+
interface VectorizeIndexLike {
|
|
8
|
+
deleteByIds: (ids: ReadonlyArray<string>) => Promise<VectorizeDeleteMutation>;
|
|
9
|
+
describe?: () => Promise<VectorizeIndexDetails>;
|
|
10
|
+
getByIds: (ids: ReadonlyArray<string>) => Promise<ReadonlyArray<VectorizeVector>>;
|
|
11
|
+
insert: (vectors: ReadonlyArray<VectorizeVector>) => Promise<VectorizeUpsertMutation>;
|
|
12
|
+
query: (vector: ReadonlyArray<number>, options?: VectorizeQueryOptions) => Promise<VectorizeMatches>;
|
|
13
|
+
upsert: (vectors: ReadonlyArray<VectorizeVector>) => Promise<VectorizeUpsertMutation>;
|
|
14
|
+
}
|
|
15
|
+
type VectorMetric = "cosine" | "euclidean" | "dot-product";
|
|
16
|
+
interface VectorizeVector {
|
|
17
|
+
id: string;
|
|
18
|
+
metadata?: Record<string, unknown>;
|
|
19
|
+
namespace?: string;
|
|
20
|
+
values: ReadonlyArray<number>;
|
|
21
|
+
}
|
|
22
|
+
interface VectorizeQueryOptions {
|
|
23
|
+
filter?: Record<string, unknown>;
|
|
24
|
+
namespace?: string;
|
|
25
|
+
returnMetadata?: "none" | "indexed" | "all";
|
|
26
|
+
returnValues?: boolean;
|
|
27
|
+
topK?: number;
|
|
28
|
+
}
|
|
29
|
+
interface VectorizeMatch {
|
|
30
|
+
id: string;
|
|
31
|
+
metadata?: Record<string, unknown>;
|
|
32
|
+
namespace?: string;
|
|
33
|
+
score: number;
|
|
34
|
+
values?: ReadonlyArray<number>;
|
|
35
|
+
}
|
|
36
|
+
interface VectorizeMatches {
|
|
37
|
+
count: number;
|
|
38
|
+
matches: ReadonlyArray<VectorizeMatch>;
|
|
39
|
+
}
|
|
40
|
+
interface VectorizeUpsertMutation {
|
|
41
|
+
mutationId: string;
|
|
42
|
+
}
|
|
43
|
+
interface VectorizeDeleteMutation {
|
|
44
|
+
count?: number;
|
|
45
|
+
mutationId: string;
|
|
46
|
+
}
|
|
47
|
+
interface VectorizeIndexDetails {
|
|
48
|
+
dimensions: number;
|
|
49
|
+
processedUpToDatetime?: string;
|
|
50
|
+
processedUpToMutation?: string;
|
|
51
|
+
vectorsCount: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Bring-your-own-embedder: a user-supplied async fn that converts a single
|
|
55
|
+
* source value (a row, a chunk, an arbitrary string) into a numeric vector.
|
|
56
|
+
* The runtime calls this at upsert time so we don't couple to any provider.
|
|
57
|
+
*/
|
|
58
|
+
type EmbedFunction<TInput = unknown> = (input: TInput) => Promise<ReadonlyArray<number>> | ReadonlyArray<number>;
|
|
59
|
+
interface LunoraVectorsOptions {
|
|
60
|
+
/**
|
|
61
|
+
* Map of logical index name -> Vectorize binding. Most apps wire one
|
|
62
|
+
* binding per index; multi-index apps register all of them here so calls
|
|
63
|
+
* like `vectors.query("docs-body", ...)` can resolve to the right binding.
|
|
64
|
+
*/
|
|
65
|
+
indexes: Record<string, VectorizeIndexLike>;
|
|
66
|
+
}
|
|
67
|
+
interface UpsertInput<TInput = unknown> {
|
|
68
|
+
embed: EmbedFunction<TInput>;
|
|
69
|
+
id: string;
|
|
70
|
+
input: TInput;
|
|
71
|
+
metadata?: Record<string, unknown>;
|
|
72
|
+
namespace?: string;
|
|
73
|
+
}
|
|
74
|
+
interface QueryInput<TInput = unknown> {
|
|
75
|
+
embed?: EmbedFunction<TInput>;
|
|
76
|
+
filter?: Record<string, unknown>;
|
|
77
|
+
input?: TInput;
|
|
78
|
+
namespace?: string;
|
|
79
|
+
returnMetadata?: "none" | "indexed" | "all";
|
|
80
|
+
returnValues?: boolean;
|
|
81
|
+
topK?: number;
|
|
82
|
+
/** Either a precomputed vector or a value to embed via `embed`. */
|
|
83
|
+
vector?: ReadonlyArray<number>;
|
|
84
|
+
}
|
|
85
|
+
interface LunoraVectors {
|
|
86
|
+
deleteByIds: (indexName: string, ids: ReadonlyArray<string>) => Promise<VectorizeDeleteMutation>;
|
|
87
|
+
describe: (indexName: string) => Promise<VectorizeIndexDetails>;
|
|
88
|
+
getByIds: (indexName: string, ids: ReadonlyArray<string>) => Promise<ReadonlyArray<VectorizeVector>>;
|
|
89
|
+
query: <TInput>(indexName: string, input: QueryInput<TInput>) => Promise<VectorizeMatches>;
|
|
90
|
+
upsert: <TInput>(indexName: string, input: UpsertInput<TInput>) => Promise<VectorizeUpsertMutation>;
|
|
91
|
+
upsertMany: <TInput>(indexName: string, inputs: ReadonlyArray<UpsertInput<TInput>>) => Promise<VectorizeUpsertMutation>;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* `(input: string) => vector`. Matches `@lunora/server`'s `VectorEmbedder` so
|
|
95
|
+
* the bridged surface is assignable to the server's `VectorSearch` contract.
|
|
96
|
+
*/
|
|
97
|
+
type VectorEmbedderLike = (input: string) => Promise<ReadonlyArray<number>> | ReadonlyArray<number>;
|
|
98
|
+
interface VectorMatchLike {
|
|
99
|
+
id: string;
|
|
100
|
+
metadata?: Record<string, unknown>;
|
|
101
|
+
score: number;
|
|
102
|
+
}
|
|
103
|
+
interface VectorMatchesLike {
|
|
104
|
+
count: number;
|
|
105
|
+
matches: ReadonlyArray<VectorMatchLike>;
|
|
106
|
+
}
|
|
107
|
+
interface VectorRecordLike {
|
|
108
|
+
id: string;
|
|
109
|
+
metadata?: Record<string, unknown>;
|
|
110
|
+
values: ReadonlyArray<number>;
|
|
111
|
+
}
|
|
112
|
+
interface VectorQueryInputLike {
|
|
113
|
+
embed?: VectorEmbedderLike;
|
|
114
|
+
filter?: Record<string, unknown>;
|
|
115
|
+
input?: string;
|
|
116
|
+
namespace?: string;
|
|
117
|
+
/**
|
|
118
|
+
* How much stored metadata to return on matches. Defaults to `"indexed"`
|
|
119
|
+
* (only fields declared as index metadata) rather than `"all"`, so a query
|
|
120
|
+
* never leaks arbitrary stored fields by default. Callers that genuinely
|
|
121
|
+
* need every field opt in with `"all"`; pass `"none"` to drop metadata.
|
|
122
|
+
*/
|
|
123
|
+
returnMetadata?: "none" | "indexed" | "all";
|
|
124
|
+
topK?: number;
|
|
125
|
+
vector?: ReadonlyArray<number>;
|
|
126
|
+
}
|
|
127
|
+
interface VectorUpsertInputLike {
|
|
128
|
+
embed: VectorEmbedderLike;
|
|
129
|
+
id: string;
|
|
130
|
+
input: string;
|
|
131
|
+
metadata?: Record<string, unknown>;
|
|
132
|
+
namespace?: string;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Structural mirror of `@lunora/server`'s `VectorSearch`. Declared here so the
|
|
136
|
+
* adapter never imports `@lunora/server` (keeps the dependency edge one-way:
|
|
137
|
+
* the generated DO depends on both, neither depends on the other).
|
|
138
|
+
*/
|
|
139
|
+
interface VectorSearchLike {
|
|
140
|
+
deleteByIds: (indexName: string, ids: ReadonlyArray<string>) => Promise<void>;
|
|
141
|
+
getByIds: (indexName: string, ids: ReadonlyArray<string>) => Promise<ReadonlyArray<VectorRecordLike>>;
|
|
142
|
+
query: (indexName: string, input: VectorQueryInputLike) => Promise<VectorMatchesLike>;
|
|
143
|
+
upsert: (indexName: string, input: VectorUpsertInputLike) => Promise<void>;
|
|
144
|
+
upsertNow: (indexName: string, input: VectorUpsertInputLike) => Promise<void>;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Bridge `LunoraVectors` (returns Vectorize mutation receipts) to the server's
|
|
148
|
+
* `VectorSearch` contract (void mutations, server match/record shapes). Both
|
|
149
|
+
* `upsert` and `upsertNow` write inline — this design has no post-commit queue,
|
|
150
|
+
* so "now" and "deferred" collapse to the same synchronous call.
|
|
151
|
+
*/
|
|
152
|
+
declare const createContextVectors: (lunora: LunoraVectors) => VectorSearchLike;
|
|
153
|
+
/** A single row mutation observed by the ctx-db, fed to {@link createVectorSyncHook}. */
|
|
154
|
+
interface WriteEvent {
|
|
155
|
+
doc?: Record<string, unknown>;
|
|
156
|
+
id: string;
|
|
157
|
+
op: "delete" | "insert" | "update";
|
|
158
|
+
table: string;
|
|
159
|
+
}
|
|
160
|
+
type WriteHook = (event: WriteEvent) => Promise<void>;
|
|
161
|
+
/** Inline vector index declared via `.vectorize(field, ...)` (DSL Shape A). */
|
|
162
|
+
interface TableVectorIndexLike {
|
|
163
|
+
embed: VectorEmbedderLike;
|
|
164
|
+
field: string;
|
|
165
|
+
metadata?: ReadonlyArray<string>;
|
|
166
|
+
name: string;
|
|
167
|
+
}
|
|
168
|
+
interface TableDefinitionLike {
|
|
169
|
+
vectorIndexes?: ReadonlyArray<TableVectorIndexLike>;
|
|
170
|
+
}
|
|
171
|
+
/** Standalone vector index declared via `defineVectorIndex(...)` (DSL Shape B). */
|
|
172
|
+
interface VectorIndexDefinitionLike {
|
|
173
|
+
embed: VectorEmbedderLike;
|
|
174
|
+
metadata?: (row: Record<string, unknown>) => Record<string, unknown>;
|
|
175
|
+
select: (row: Record<string, unknown>) => string;
|
|
176
|
+
table: string;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Structural mirror of `@lunora/server`'s `Schema`, narrowed to the fields the
|
|
180
|
+
* sync hook reads. Carries live `embed`/`select` closures, so the hook must be
|
|
181
|
+
* built from the imported `schema` value — never a serialized descriptor.
|
|
182
|
+
*/
|
|
183
|
+
interface SchemaLike {
|
|
184
|
+
tables: Record<string, TableDefinitionLike>;
|
|
185
|
+
vectorIndexes: Record<string, VectorIndexDefinitionLike>;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Build a {@link WriteHook} that keeps Vectorize in sync with row writes. On
|
|
189
|
+
* insert/update it embeds each matching index's source (Shape A `row[field]`,
|
|
190
|
+
* Shape B `select(row)`) and upserts; on delete it removes the row's id from
|
|
191
|
+
* every index sourced from the table. Runs inline within the write path.
|
|
192
|
+
*
|
|
193
|
+
* Tenant isolation — IMPORTANT: Vectorize indexes are account-global and shared
|
|
194
|
+
* by every shard DO. Without a `namespace`, a multi-tenant sharded app has NO
|
|
195
|
+
* isolation between tenants in the vector index — one tenant's vectors are
|
|
196
|
+
* queryable by another (ids/scores leak existence + semantic similarity even
|
|
197
|
+
* when no metadata is indexed). The caller MUST pass `options.namespace` (the
|
|
198
|
+
* shard / tenant key) so upserts are scoped, and MUST apply the same namespace
|
|
199
|
+
* on the query side — query-side namespace filtering is mandatory, not optional.
|
|
200
|
+
* The namespace is threaded onto upserts here; pass it from the shard DO that
|
|
201
|
+
* owns this hook. Any namespace-less sync emits a one-time-per-index dev warning
|
|
202
|
+
* (regardless of whether metadata is present); a genuinely single-tenant app
|
|
203
|
+
* suppresses it with `allowSharedNamespace: true`.
|
|
204
|
+
*
|
|
205
|
+
* Consistency — IMPORTANT: this hook runs inline within the mutation but talks
|
|
206
|
+
* to Vectorize, which is external and non-transactional. The per-index calls
|
|
207
|
+
* fan out; if one fails after others have already applied, the SQLite write may
|
|
208
|
+
* roll back while the applied Vectorize mutations cannot — leaving SQLite and
|
|
209
|
+
* Vectorize diverged. We mitigate, not eliminate: upserts/deletes are
|
|
210
|
+
* idempotent (keyed by row id), so a retry of the same write converges; and on
|
|
211
|
+
* a fan-out failure we attempt a best-effort compensating delete of the row's
|
|
212
|
+
* id from every affected index before re-throwing. A delete after a failed
|
|
213
|
+
* upsert can itself fail — this is best-effort, the authoritative recovery is
|
|
214
|
+
* re-running the (idempotent) write.
|
|
215
|
+
*/
|
|
216
|
+
declare const createVectorSyncHook: (options: {
|
|
217
|
+
allowSharedNamespace?: boolean;
|
|
218
|
+
namespace?: string;
|
|
219
|
+
schema: SchemaLike;
|
|
220
|
+
vectors: VectorSearchLike;
|
|
221
|
+
}) => WriteHook;
|
|
222
|
+
/**
|
|
223
|
+
* One vector index as the generated `LUNORA_VECTOR_INDEXES` registry describes
|
|
224
|
+
* it — the static schema shape, independent of any live binding. Structurally
|
|
225
|
+
* the codegen `LunoraVectorIndex`, restated here so this package stays free of a
|
|
226
|
+
* dependency on `@lunora/codegen`.
|
|
227
|
+
*/
|
|
228
|
+
interface VectorIndexRegistryEntry {
|
|
229
|
+
dimensions?: number;
|
|
230
|
+
field?: string;
|
|
231
|
+
metadata?: ReadonlyArray<string>;
|
|
232
|
+
metric?: VectorMetric;
|
|
233
|
+
name: string;
|
|
234
|
+
table: string;
|
|
235
|
+
}
|
|
236
|
+
/** A registry entry merged with the live `describe()` stats (when the binding is reachable). */
|
|
237
|
+
interface VectorAdminIndexSummary extends VectorIndexRegistryEntry {
|
|
238
|
+
processedUpToMutation?: string;
|
|
239
|
+
vectorsCount?: number;
|
|
240
|
+
}
|
|
241
|
+
/** One nearest-neighbour hit from an admin similarity query. */
|
|
242
|
+
interface VectorAdminQueryMatch {
|
|
243
|
+
id: string;
|
|
244
|
+
metadata?: Record<string, unknown>;
|
|
245
|
+
score: number;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* The admin introspector the worker passes to `createWorker({ vectorIntrospector })`.
|
|
249
|
+
* `queryIndex` is present only when at least one embedder is wired.
|
|
250
|
+
*/
|
|
251
|
+
interface VectorAdminIntrospector {
|
|
252
|
+
listIndexes: () => Promise<VectorAdminIndexSummary[]>;
|
|
253
|
+
queryIndex?: (options: {
|
|
254
|
+
name: string;
|
|
255
|
+
text: string;
|
|
256
|
+
topK?: number;
|
|
257
|
+
}) => Promise<{
|
|
258
|
+
matches: VectorAdminQueryMatch[];
|
|
259
|
+
}>;
|
|
260
|
+
}
|
|
261
|
+
interface VectorAdminIntrospectorOptions {
|
|
262
|
+
/**
|
|
263
|
+
* Per-index embedder (text → vector), keyed by index name. Supply the
|
|
264
|
+
* schema's embedders to enable studio similarity queries; omit it (or leave
|
|
265
|
+
* an index out) and that index lists read-only — `queryIndex` is withheld
|
|
266
|
+
* entirely when no embedder is provided.
|
|
267
|
+
*/
|
|
268
|
+
embedders?: Record<string, EmbedFunction<string>>;
|
|
269
|
+
/** Live Vectorize bindings keyed by index name, from `env`. */
|
|
270
|
+
indexes: Record<string, VectorizeIndexLike>;
|
|
271
|
+
/** The generated `LUNORA_VECTOR_INDEXES` registry (Vectorize can't enumerate at runtime). */
|
|
272
|
+
registry: ReadonlyArray<VectorIndexRegistryEntry>;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Build the read-only Vectorize introspector backing the studio's vector
|
|
276
|
+
* browser. `listIndexes` returns the static registry, enriching each entry with
|
|
277
|
+
* live `describe()` stats when the matching binding is present (a binding that
|
|
278
|
+
* throws or lacks `describe` degrades to the static shape rather than failing
|
|
279
|
+
* the whole list). `queryIndex` embeds the query text via the index's embedder
|
|
280
|
+
* and runs an ANN search; it is omitted when no embedders are configured, so the
|
|
281
|
+
* worker reports `VECTOR_QUERY_UNSUPPORTED` rather than half-answering.
|
|
282
|
+
*/
|
|
283
|
+
declare const createVectorAdminIntrospector: (options: VectorAdminIntrospectorOptions) => VectorAdminIntrospector;
|
|
284
|
+
declare const createVectors: (options: LunoraVectorsOptions) => LunoraVectors;
|
|
285
|
+
export { type EmbedFunction, type LunoraVectors, type LunoraVectorsOptions, type QueryInput, type SchemaLike, type TableDefinitionLike, type TableVectorIndexLike, type UpsertInput, type VectorAdminIndexSummary, type VectorAdminIntrospector, type VectorAdminIntrospectorOptions, type VectorAdminQueryMatch, type VectorEmbedderLike, type VectorIndexDefinitionLike, type VectorIndexRegistryEntry, type VectorMatchLike, type VectorMatchesLike, type VectorMetric, type VectorQueryInputLike, type VectorRecordLike, type VectorSearchLike, type VectorUpsertInputLike, type VectorizeDeleteMutation, type VectorizeIndexDetails, type VectorizeIndexLike, type VectorizeMatch, type VectorizeMatches, type VectorizeQueryOptions, type VectorizeUpsertMutation, type VectorizeVector, type WriteEvent, type WriteHook, createContextVectors, createVectorAdminIntrospector, createVectorSyncHook, createVectors };
|