@lunora/bindings 1.0.0-alpha.2 → 1.0.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +6 -0
- package/dist/analytics/index.d.mts +66 -87
- package/dist/analytics/index.d.ts +66 -87
- package/dist/analytics/index.mjs +1 -2
- package/dist/images/index.d.mts +148 -148
- package/dist/images/index.d.ts +148 -148
- package/dist/images/index.mjs +1 -3
- package/dist/kv/index.d.mts +130 -113
- package/dist/kv/index.d.ts +130 -113
- package/dist/kv/index.mjs +1 -1
- package/dist/packem_shared/AnalyticsSqlError-B-JcsUhX.mjs +1 -0
- package/dist/packem_shared/R2SqlError-Uaz0RJTR.mjs +1 -0
- package/dist/packem_shared/SelectBuilder-WMBQ2b4q.mjs +1 -0
- package/dist/packem_shared/SetOperation-BrzMB1Tb.mjs +1 -0
- package/dist/packem_shared/Sql-CwhZl1Q5.mjs +1 -0
- package/dist/packem_shared/WindowExpression-CxCuEy8V.mjs +1 -0
- package/dist/packem_shared/WindowFunction-rzl4CzYE.mjs +1 -0
- package/dist/packem_shared/asc-BsbdtIQU.mjs +1 -0
- package/dist/packem_shared/buildImageDeliveryUrl-CMUkVJfB.mjs +1 -0
- package/dist/packem_shared/buildSignedImageUrl-BzgCHIu6.mjs +4 -0
- package/dist/packem_shared/concurrent-DMFQCILU.mjs +1 -0
- package/dist/packem_shared/createAnalytics-HRPCzT1M.mjs +1 -0
- package/dist/packem_shared/createContextVectors-D-ae1wWO.mjs +6 -0
- package/dist/packem_shared/createImages-TW6ircG2.mjs +1 -0
- package/dist/packem_shared/createKv-CKeFDFuG.mjs +1 -0
- package/dist/packem_shared/createKvIntrospector-Bz0nqUjD.mjs +1 -0
- package/dist/packem_shared/createPipelines-n0Bf_p8Y.mjs +1 -0
- package/dist/packem_shared/createVectorAdminIntrospector-B9Yt09yj.mjs +1 -0
- package/dist/packem_shared/createVectors-jb8fAY6R.mjs +1 -0
- package/dist/pipelines/index.d.mts +24 -24
- package/dist/pipelines/index.d.ts +24 -24
- package/dist/pipelines/index.mjs +1 -1
- package/dist/r2sql/index.d.mts +124 -124
- package/dist/r2sql/index.d.ts +124 -124
- package/dist/r2sql/index.mjs +1 -7
- package/dist/vectors/index.d.mts +185 -134
- package/dist/vectors/index.d.ts +185 -134
- package/dist/vectors/index.mjs +1 -3
- package/package.json +5 -1
- package/dist/packem_shared/AnalyticsSqlError-CGTdsi4H.mjs +0 -42
- package/dist/packem_shared/R2SqlError-DlDd_SrE.mjs +0 -67
- package/dist/packem_shared/SelectBuilder-DHaXZwn_.mjs +0 -167
- package/dist/packem_shared/SetOperation-RDHcxccj.mjs +0 -80
- package/dist/packem_shared/Sql-DceGtcUd.mjs +0 -68
- package/dist/packem_shared/WindowExpression-Cg9s2xcr.mjs +0 -44
- package/dist/packem_shared/WindowFunction-DA3pGC3N.mjs +0 -82
- package/dist/packem_shared/asc-Cur-xO8v.mjs +0 -16
- package/dist/packem_shared/buildImageDeliveryUrl-D1sVfIOP.mjs +0 -30
- package/dist/packem_shared/buildSignedImageUrl-Otdgc_jO.mjs +0 -113
- package/dist/packem_shared/concurrent-Dj5sOibv.mjs +0 -23
- package/dist/packem_shared/createAnalytics-CEEI69o9.mjs +0 -57
- package/dist/packem_shared/createContextVectors-BSizpmu5.mjs +0 -140
- package/dist/packem_shared/createImages-CJrvqX0u.mjs +0 -80
- package/dist/packem_shared/createKv-DTiSt216.mjs +0 -141
- package/dist/packem_shared/createPipelines-CfyJ6VGu.mjs +0 -10
- package/dist/packem_shared/createVectorAdminIntrospector-BJUOM6VW.mjs +0 -51
- package/dist/packem_shared/createVectors-LSpGoKCd.mjs +0 -91
package/dist/vectors/index.d.mts
CHANGED
|
@@ -1,67 +1,17 @@
|
|
|
1
|
+
import { VectorizeDeleteMutation, VectorizeIndexDetails, VectorizeVector, VectorizeMatches, VectorizeUpsertMutation, VectorizeIndexLike, VectorMetric } from '@lunora/platform';
|
|
2
|
+
export type { VectorMetric, VectorizeDeleteMutation, VectorizeIndexDetails, VectorizeIndexLike, VectorizeMatch, VectorizeMatches, VectorizeQueryOptions, VectorizeUpsertMutation, VectorizeVector } from '@lunora/platform';
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
|
|
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
|
-
*/
|
|
4
|
+
* Bring-your-own-embedder: a user-supplied async fn that converts a single
|
|
5
|
+
* source value (a row, a chunk, an arbitrary string) into a numeric vector.
|
|
6
|
+
* The runtime calls this at upsert time so we don't couple to any provider.
|
|
7
|
+
*/
|
|
58
8
|
type EmbedFunction<TInput = unknown> = (input: TInput) => Promise<ReadonlyArray<number>> | ReadonlyArray<number>;
|
|
59
9
|
interface LunoraVectorsOptions {
|
|
60
10
|
/**
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
11
|
+
* Map of logical index name -> Vectorize binding. Most apps wire one
|
|
12
|
+
* binding per index; multi-index apps register all of them here so calls
|
|
13
|
+
* like `vectors.query("docs-body", ...)` can resolve to the right binding.
|
|
14
|
+
*/
|
|
65
15
|
indexes: Record<string, VectorizeIndexLike>;
|
|
66
16
|
}
|
|
67
17
|
interface UpsertInput<TInput = unknown> {
|
|
@@ -91,9 +41,9 @@ interface LunoraVectors {
|
|
|
91
41
|
upsertMany: <TInput>(indexName: string, inputs: ReadonlyArray<UpsertInput<TInput>>) => Promise<VectorizeUpsertMutation>;
|
|
92
42
|
}
|
|
93
43
|
/**
|
|
94
|
-
* `(input: string) => vector`. Matches `@lunora/server`'s `VectorEmbedder` so
|
|
95
|
-
* the bridged surface is assignable to the server's `VectorSearch` contract.
|
|
96
|
-
*/
|
|
44
|
+
* `(input: string) => vector`. Matches `@lunora/server`'s `VectorEmbedder` so
|
|
45
|
+
* the bridged surface is assignable to the server's `VectorSearch` contract.
|
|
46
|
+
*/
|
|
97
47
|
type VectorEmbedderLike = (input: string) => Promise<ReadonlyArray<number>> | ReadonlyArray<number>;
|
|
98
48
|
interface VectorMatchLike {
|
|
99
49
|
id: string;
|
|
@@ -107,6 +57,7 @@ interface VectorMatchesLike {
|
|
|
107
57
|
interface VectorRecordLike {
|
|
108
58
|
id: string;
|
|
109
59
|
metadata?: Record<string, unknown>;
|
|
60
|
+
namespace?: string;
|
|
110
61
|
values: ReadonlyArray<number>;
|
|
111
62
|
}
|
|
112
63
|
interface VectorQueryInputLike {
|
|
@@ -115,11 +66,11 @@ interface VectorQueryInputLike {
|
|
|
115
66
|
input?: string;
|
|
116
67
|
namespace?: string;
|
|
117
68
|
/**
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
69
|
+
* How much stored metadata to return on matches. Defaults to `"indexed"`
|
|
70
|
+
* (only fields declared as index metadata) rather than `"all"`, so a query
|
|
71
|
+
* never leaks arbitrary stored fields by default. Callers that genuinely
|
|
72
|
+
* need every field opt in with `"all"`; pass `"none"` to drop metadata.
|
|
73
|
+
*/
|
|
123
74
|
returnMetadata?: "none" | "indexed" | "all";
|
|
124
75
|
topK?: number;
|
|
125
76
|
vector?: ReadonlyArray<number>;
|
|
@@ -132,24 +83,107 @@ interface VectorUpsertInputLike {
|
|
|
132
83
|
namespace?: string;
|
|
133
84
|
}
|
|
134
85
|
/**
|
|
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
|
-
|
|
86
|
+
* Structural mirror of `@lunora/server`'s `VectorSearch`. Declared here so the
|
|
87
|
+
* adapter never imports `@lunora/server` (keeps the dependency edge one-way:
|
|
88
|
+
* the generated DO depends on both, neither depends on the other). `getByIds`/
|
|
89
|
+
* `deleteByIds` carry an optional trailing `namespace` — a pure addition (more
|
|
90
|
+
* general, not narrower) that stays assignable to `@lunora/server`'s
|
|
91
|
+
* `VectorSearchReader`/`VectorSearch`, whose own two-argument signatures are
|
|
92
|
+
* unchanged: a function accepting an extra OPTIONAL parameter is assignable
|
|
93
|
+
* wherever a function taking fewer parameters is expected.
|
|
94
|
+
*/
|
|
139
95
|
interface VectorSearchLike {
|
|
140
|
-
deleteByIds: (indexName: string, ids: ReadonlyArray<string
|
|
141
|
-
getByIds: (indexName: string, ids: ReadonlyArray<string
|
|
96
|
+
deleteByIds: (indexName: string, ids: ReadonlyArray<string>, namespace?: string) => Promise<void>;
|
|
97
|
+
getByIds: (indexName: string, ids: ReadonlyArray<string>, namespace?: string) => Promise<ReadonlyArray<VectorRecordLike>>;
|
|
142
98
|
query: (indexName: string, input: VectorQueryInputLike) => Promise<VectorMatchesLike>;
|
|
143
99
|
upsert: (indexName: string, input: VectorUpsertInputLike) => Promise<void>;
|
|
144
100
|
upsertNow: (indexName: string, input: VectorUpsertInputLike) => Promise<void>;
|
|
145
101
|
}
|
|
102
|
+
/** Options for {@link createContextVectors}. */
|
|
103
|
+
interface CreateContextVectorsOptions {
|
|
104
|
+
/**
|
|
105
|
+
* The DO's own shard/tenant key, applied as the default `namespace` for
|
|
106
|
+
* an operation against an index in `shardedIndexNames` that doesn't pass
|
|
107
|
+
* one explicitly. `undefined` means this instance HAS no shard key —
|
|
108
|
+
* always true for the root/default DO instance, since only a per-tenant
|
|
109
|
+
* instance owns one. See `shardedIndexNames` for what that implies per
|
|
110
|
+
* index, and {@link createContextVectors}'s docblock for the full
|
|
111
|
+
* root-instance rule.
|
|
112
|
+
*/
|
|
113
|
+
namespace?: string;
|
|
114
|
+
/**
|
|
115
|
+
* Vector index names sourced from a `.shardBy()`'d table — the ones
|
|
116
|
+
* `namespace` is a meaningful tenant scope for. `ctx.vectors` is a single
|
|
117
|
+
* flat facade over EVERY declared index (root-scoped and sharded tables
|
|
118
|
+
* alike — Vectorize indexes are account-global and `config.vectors(env)`
|
|
119
|
+
* registers them all in one flat map), reachable from ANY DO instance —
|
|
120
|
+
* so `namespace` can only be a safe default for the indexes actually
|
|
121
|
+
* listed here.
|
|
122
|
+
*
|
|
123
|
+
* An index NOT in this set (sourced from a root-scoped table) always
|
|
124
|
+
* stays namespace-less, regardless of `namespace` or which DO instance
|
|
125
|
+
* calls it — it has no tenant identity to begin with, so scoping it would
|
|
126
|
+
* silently return nothing for legitimate, intentionally shared data (and,
|
|
127
|
+
* called from a per-tenant instance, would wrongly search under that
|
|
128
|
+
* tenant's namespace even though nothing was ever written there under
|
|
129
|
+
* it). An index IN this set, called from a per-tenant DO instance
|
|
130
|
+
* (`namespace` is set), defaults to `namespace`, scoping correctly. An
|
|
131
|
+
* index IN this set, called from the root/default DO instance
|
|
132
|
+
* (`namespace` is `undefined`) with no explicit override, is unsafe to
|
|
133
|
+
* default at all — see {@link createContextVectors}'s docblock.
|
|
134
|
+
*
|
|
135
|
+
* Omitted (or empty) → no index is ever treated as sharded, i.e.
|
|
136
|
+
* `namespace` never applies as a default on any call — the unsharded-app,
|
|
137
|
+
* byte-identical-to-today case.
|
|
138
|
+
*/
|
|
139
|
+
shardedIndexNames?: ReadonlyArray<string>;
|
|
140
|
+
}
|
|
146
141
|
/**
|
|
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
|
-
|
|
142
|
+
* Bridge `LunoraVectors` (returns Vectorize mutation receipts) to the server's
|
|
143
|
+
* `VectorSearch` contract (void mutations, server match/record shapes). Both
|
|
144
|
+
* `upsert` and `upsertNow` write inline — this design has no post-commit queue,
|
|
145
|
+
* so "now" and "deferred" collapse to the same synchronous call.
|
|
146
|
+
*
|
|
147
|
+
* Tenant isolation (read side) — IMPORTANT: an explicit `namespace` argument
|
|
148
|
+
* on any call (`input.namespace` for `query`/`upsert`/`upsertNow`, the
|
|
149
|
+
* trailing `namespace` parameter for `getByIds`/`deleteByIds`) ALWAYS wins —
|
|
150
|
+
* this is a deliberate soft default, not a hard boundary: `ctx.vectors` is
|
|
151
|
+
* trusted server-side app code (the same trust level that lets `ctx.db` read
|
|
152
|
+
* any table), so a caller that explicitly names a namespace is trusted to
|
|
153
|
+
* mean it, including a legitimate cross-tenant admin read/write. Absent an
|
|
154
|
+
* explicit namespace, `options.namespace` (this DO instance's own shard key)
|
|
155
|
+
* is the DEFAULT for any index in `options.shardedIndexNames` — see that
|
|
156
|
+
* option's docblock for why the default is index-scoped rather than global.
|
|
157
|
+
*
|
|
158
|
+
* Root-instance rule — IMPORTANT: when an operation targets a sharded index
|
|
159
|
+
* (one in `shardedIndexNames`) and BOTH the explicit argument and
|
|
160
|
+
* `options.namespace` are absent (this is the root/default DO instance, which
|
|
161
|
+
* owns no shard key), there is no safe default and no override — this THROWS
|
|
162
|
+
* rather than silently resolving to "no namespace". A namespace-less
|
|
163
|
+
* query/getByIds/deleteByIds/upsert against a sharded index would reach or
|
|
164
|
+
* mutate EVERY tenant's vectors (Vectorize indexes are account-global), which
|
|
165
|
+
* is the exact cross-tenant leak this file exists to close; returning an
|
|
166
|
+
* empty result set instead would masquerade that same configuration problem
|
|
167
|
+
* as "no data", which is worse — a caller debugging it sees nothing rather
|
|
168
|
+
* than a directed error. This case is reachable in a MIXED schema (some
|
|
169
|
+
* vectorized tables `.shardBy()`'d, others root-scoped) whenever application
|
|
170
|
+
* code queries a sharded index's name from the root DO instance without an
|
|
171
|
+
* explicit namespace; it is not reachable from `createVectorSyncHook`'s own
|
|
172
|
+
* internal calls, which only ever process a table this DO instance owns (so
|
|
173
|
+
* a sharded table's write never reaches a root instance in the first place).
|
|
174
|
+
*
|
|
175
|
+
* Id path, unrelated axis — IMPORTANT: independent of the override/root rules
|
|
176
|
+
* above, `getByIds`/`deleteByIds` can't ask Vectorize to filter by namespace
|
|
177
|
+
* remotely at all (its id-based operations take no `namespace` option), so
|
|
178
|
+
* once a namespace IS resolved (explicit or defaulted) for these two methods,
|
|
179
|
+
* isolation is enforced client-side: `getByIds` drops any returned record
|
|
180
|
+
* whose `namespace` doesn't match (fail closed: a record with no `namespace`
|
|
181
|
+
* field is treated as a mismatch, never as "belongs to everyone"), and
|
|
182
|
+
* `deleteByIds` resolves ids via `getByIds` first and only deletes the subset
|
|
183
|
+
* that belongs to the resolved namespace — silently, by design (see the
|
|
184
|
+
* `deleteByIds` implementation for the no-signal tradeoff this makes).
|
|
185
|
+
*/
|
|
186
|
+
declare const createContextVectors: (lunora: LunoraVectors, options?: CreateContextVectorsOptions) => VectorSearchLike;
|
|
153
187
|
/** A single row mutation observed by the ctx-db, fed to {@link createVectorSyncHook}. */
|
|
154
188
|
interface WriteEvent {
|
|
155
189
|
doc?: Record<string, unknown>;
|
|
@@ -176,43 +210,60 @@ interface VectorIndexDefinitionLike {
|
|
|
176
210
|
table: string;
|
|
177
211
|
}
|
|
178
212
|
/**
|
|
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
|
-
*/
|
|
213
|
+
* Structural mirror of `@lunora/server`'s `Schema`, narrowed to the fields the
|
|
214
|
+
* sync hook reads. Carries live `embed`/`select` closures, so the hook must be
|
|
215
|
+
* built from the imported `schema` value — never a serialized descriptor.
|
|
216
|
+
*/
|
|
183
217
|
interface SchemaLike {
|
|
184
218
|
tables: Record<string, TableDefinitionLike>;
|
|
185
219
|
vectorIndexes: Record<string, VectorIndexDefinitionLike>;
|
|
186
220
|
}
|
|
187
221
|
/**
|
|
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
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
* upsert
|
|
214
|
-
*
|
|
215
|
-
|
|
222
|
+
* Build a {@link WriteHook} that keeps Vectorize in sync with row writes. On
|
|
223
|
+
* insert/update it embeds each matching index's source (Shape A `row[field]`,
|
|
224
|
+
* Shape B `select(row)`) and upserts; on delete it removes the row's id from
|
|
225
|
+
* every index sourced from the table. Runs inline within the write path.
|
|
226
|
+
*
|
|
227
|
+
* Tenant isolation — IMPORTANT: Vectorize indexes are account-global and shared
|
|
228
|
+
* by every shard DO. Without a `namespace`, a multi-tenant sharded app has NO
|
|
229
|
+
* isolation between tenants in the vector index — one tenant's vectors are
|
|
230
|
+
* queryable by another (ids/scores leak existence + semantic similarity even
|
|
231
|
+
* when no metadata is indexed). The caller MUST pass `options.namespace` (the
|
|
232
|
+
* shard / tenant key) so upserts are scoped, and MUST apply the same namespace
|
|
233
|
+
* on the query side — query-side namespace filtering is mandatory, not optional.
|
|
234
|
+
* The namespace is threaded onto upserts here; pass it from the shard DO that
|
|
235
|
+
* owns this hook. Any namespace-less sync emits a one-time-per-index dev warning
|
|
236
|
+
* (regardless of whether metadata is present); a genuinely single-tenant app
|
|
237
|
+
* suppresses it with `allowSharedNamespace: true`.
|
|
238
|
+
*
|
|
239
|
+
* Since plan 255, codegen satisfies the query-side requirement automatically
|
|
240
|
+
* for a `.shardBy()`'d vectorized table: the `vectors` instance passed in
|
|
241
|
+
* `options` here is the SAME `createContextVectors(...)` instance exposed as
|
|
242
|
+
* `ctx.vectors`, constructed with the identical shard-key `namespace` default
|
|
243
|
+
* AND the identical `shardedIndexNames` — so `ctx.vectors.query`/`getByIds`/
|
|
244
|
+
* `deleteByIds` are scoped without any app code changes. One consequence of
|
|
245
|
+
* sharing that instance: this hook's own internal `deleteByIds` calls (on row
|
|
246
|
+
* delete, on a cleared inline field, and on compensation after a failed
|
|
247
|
+
* upsert) now also go through the namespace-verifying path described on
|
|
248
|
+
* {@link createContextVectors} — an extra `getByIds` subrequest per
|
|
249
|
+
* delete-shaped write, not a behavior change (the row being deleted was
|
|
250
|
+
* written under this same shard's namespace, so the verification passes).
|
|
251
|
+
* This never hits {@link createContextVectors}'s root-instance throw: a write
|
|
252
|
+
* event only ever fires for a table THIS DO instance owns, so if this hook
|
|
253
|
+
* processes a write for a sharded index, this instance IS a real per-tenant
|
|
254
|
+
* shard (not root) — `namespace` here is never `undefined` for that index.
|
|
255
|
+
*
|
|
256
|
+
* Consistency — IMPORTANT: this hook runs inline within the mutation but talks
|
|
257
|
+
* to Vectorize, which is external and non-transactional. The per-index calls
|
|
258
|
+
* fan out; if one fails after others have already applied, the SQLite write may
|
|
259
|
+
* roll back while the applied Vectorize mutations cannot — leaving SQLite and
|
|
260
|
+
* Vectorize diverged. We mitigate, not eliminate: upserts/deletes are
|
|
261
|
+
* idempotent (keyed by row id), so a retry of the same write converges; and on
|
|
262
|
+
* a fan-out failure we attempt a best-effort compensating delete of the row's
|
|
263
|
+
* id from every affected index before re-throwing. A delete after a failed
|
|
264
|
+
* upsert can itself fail — this is best-effort, the authoritative recovery is
|
|
265
|
+
* re-running the (idempotent) write.
|
|
266
|
+
*/
|
|
216
267
|
declare const createVectorSyncHook: (options: {
|
|
217
268
|
allowSharedNamespace?: boolean;
|
|
218
269
|
namespace?: string;
|
|
@@ -220,11 +271,11 @@ declare const createVectorSyncHook: (options: {
|
|
|
220
271
|
vectors: VectorSearchLike;
|
|
221
272
|
}) => WriteHook;
|
|
222
273
|
/**
|
|
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
|
-
*/
|
|
274
|
+
* One vector index as the generated `LUNORA_VECTOR_INDEXES` registry describes
|
|
275
|
+
* it — the static schema shape, independent of any live binding. Structurally
|
|
276
|
+
* the codegen `LunoraVectorIndex`, restated here so this package stays free of a
|
|
277
|
+
* dependency on `@lunora/codegen`.
|
|
278
|
+
*/
|
|
228
279
|
interface VectorIndexRegistryEntry {
|
|
229
280
|
dimensions?: number;
|
|
230
281
|
field?: string;
|
|
@@ -245,9 +296,9 @@ interface VectorAdminQueryMatch {
|
|
|
245
296
|
score: number;
|
|
246
297
|
}
|
|
247
298
|
/**
|
|
248
|
-
* The admin introspector the worker passes to `createWorker({ vectorIntrospector })`.
|
|
249
|
-
* `queryIndex` is present only when at least one embedder is wired.
|
|
250
|
-
*/
|
|
299
|
+
* The admin introspector the worker passes to `createWorker({ vectorIntrospector })`.
|
|
300
|
+
* `queryIndex` is present only when at least one embedder is wired.
|
|
301
|
+
*/
|
|
251
302
|
interface VectorAdminIntrospector {
|
|
252
303
|
listIndexes: () => Promise<VectorAdminIndexSummary[]>;
|
|
253
304
|
queryIndex?: (options: {
|
|
@@ -260,11 +311,11 @@ interface VectorAdminIntrospector {
|
|
|
260
311
|
}
|
|
261
312
|
interface VectorAdminIntrospectorOptions {
|
|
262
313
|
/**
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
314
|
+
* Per-index embedder (text → vector), keyed by index name. Supply the
|
|
315
|
+
* schema's embedders to enable studio similarity queries; omit it (or leave
|
|
316
|
+
* an index out) and that index lists read-only — `queryIndex` is withheld
|
|
317
|
+
* entirely when no embedder is provided.
|
|
318
|
+
*/
|
|
268
319
|
embedders?: Record<string, EmbedFunction<string>>;
|
|
269
320
|
/** Live Vectorize bindings keyed by index name, from `env`. */
|
|
270
321
|
indexes: Record<string, VectorizeIndexLike>;
|
|
@@ -272,14 +323,14 @@ interface VectorAdminIntrospectorOptions {
|
|
|
272
323
|
registry: ReadonlyArray<VectorIndexRegistryEntry>;
|
|
273
324
|
}
|
|
274
325
|
/**
|
|
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
|
-
*/
|
|
326
|
+
* Build the read-only Vectorize introspector backing the studio's vector
|
|
327
|
+
* browser. `listIndexes` returns the static registry, enriching each entry with
|
|
328
|
+
* live `describe()` stats when the matching binding is present (a binding that
|
|
329
|
+
* throws or lacks `describe` degrades to the static shape rather than failing
|
|
330
|
+
* the whole list). `queryIndex` embeds the query text via the index's embedder
|
|
331
|
+
* and runs an ANN search; it is omitted when no embedders are configured, so the
|
|
332
|
+
* worker reports `VECTOR_QUERY_UNSUPPORTED` rather than half-answering.
|
|
333
|
+
*/
|
|
283
334
|
declare const createVectorAdminIntrospector: (options: VectorAdminIntrospectorOptions) => VectorAdminIntrospector;
|
|
284
335
|
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
|
|
336
|
+
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 VectorQueryInputLike, type VectorRecordLike, type VectorSearchLike, type VectorUpsertInputLike, type WriteEvent, type WriteHook, createContextVectors, createVectorAdminIntrospector, createVectorSyncHook, createVectors };
|