@workglow/postgres 0.2.30 → 0.2.32
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/README.md +33 -0
- package/dist/job-queue/PostgresQueueStorage.d.ts +12 -19
- package/dist/job-queue/PostgresQueueStorage.d.ts.map +1 -1
- package/dist/job-queue/PostgresRateLimiterStorage.d.ts +9 -19
- package/dist/job-queue/PostgresRateLimiterStorage.d.ts.map +1 -1
- package/dist/job-queue/browser.js +331 -165
- package/dist/job-queue/browser.js.map +8 -5
- package/dist/job-queue/common.d.ts +3 -0
- package/dist/job-queue/common.d.ts.map +1 -1
- package/dist/job-queue/node.js +331 -165
- package/dist/job-queue/node.js.map +8 -5
- package/dist/migrations/PostgresMigrationRunner.d.ts +31 -0
- package/dist/migrations/PostgresMigrationRunner.d.ts.map +1 -0
- package/dist/migrations/common.d.ts +9 -0
- package/dist/migrations/common.d.ts.map +1 -0
- package/dist/migrations/postgresQueueMigrations.d.ts +18 -0
- package/dist/migrations/postgresQueueMigrations.d.ts.map +1 -0
- package/dist/migrations/postgresRateLimiterMigrations.d.ts +11 -0
- package/dist/migrations/postgresRateLimiterMigrations.d.ts.map +1 -0
- package/dist/storage/PostgresTabularStorage.d.ts +175 -10
- package/dist/storage/PostgresTabularStorage.d.ts.map +1 -1
- package/dist/storage/PostgresVectorStorage.d.ts +52 -2
- package/dist/storage/PostgresVectorStorage.d.ts.map +1 -1
- package/dist/storage/browser.js +454 -75
- package/dist/storage/browser.js.map +4 -4
- package/dist/storage/common.d.ts +1 -0
- package/dist/storage/common.d.ts.map +1 -1
- package/dist/storage/node.js +564 -75
- package/dist/storage/node.js.map +6 -5
- package/package.json +7 -7
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { Pool } from "@workglow/postgres/storage";
|
|
7
7
|
import { DataPortSchemaObject, FromSchema, JsonSchema, TypedArraySchemaOptions } from "@workglow/util/schema";
|
|
8
|
-
import { BaseSqlTabularStorage, ClientProvidedKeysOption, AnyTabularStorage, AutoGeneratedKeys, CoveringIndexQueryOptions, DeleteSearchCriteria, InsertEntity, QueryOptions, SearchCriteria, SimplifyPrimaryKey, TabularChangePayload, TabularSubscribeOptions, ValueOptionType } from "@workglow/storage";
|
|
8
|
+
import { BaseSqlTabularStorage, ClientProvidedKeysOption, AnyTabularStorage, AutoGeneratedKeys, CoveringIndexQueryOptions, DeleteSearchCriteria, InsertEntity, ITabularMigration, ITabularMigrationApplier, Page, PageRequest, QueryOptions, SearchCriteria, SimplifyPrimaryKey, TabularChangePayload, TabularSubscribeOptions, ValueOptionType, type VectorIndexOptions } from "@workglow/storage";
|
|
9
9
|
export declare const POSTGRES_TABULAR_REPOSITORY: import("@workglow/util").ServiceToken<AnyTabularStorage>;
|
|
10
10
|
/**
|
|
11
11
|
* A PostgreSQL-based tabular repository implementation that extends BaseSqlTabularStorage.
|
|
@@ -28,13 +28,29 @@ export declare class PostgresTabularStorage<Schema extends DataPortSchemaObject,
|
|
|
28
28
|
* while each array creates a compound index with columns in the specified order.
|
|
29
29
|
* @param clientProvidedKeys - How to handle client-provided values for auto-generated keys
|
|
30
30
|
*/
|
|
31
|
-
constructor(db: Pool, table: string | undefined, schema: Schema, primaryKeyNames: PrimaryKeyNames, indexes?: readonly (keyof NoInfer<Entity> | readonly (keyof NoInfer<Entity>)[])[], clientProvidedKeys?: ClientProvidedKeysOption);
|
|
31
|
+
constructor(db: Pool, table: string | undefined, schema: Schema, primaryKeyNames: PrimaryKeyNames, indexes?: readonly (keyof NoInfer<Entity> | readonly (keyof NoInfer<Entity>)[])[], clientProvidedKeys?: ClientProvidedKeysOption, tabularMigrations?: ReadonlyArray<ITabularMigration>);
|
|
32
32
|
/**
|
|
33
33
|
* Initializes the database table with the required schema.
|
|
34
34
|
* Creates the table if it doesn't exist with primary key and value columns.
|
|
35
35
|
* Must be called before using any other methods.
|
|
36
36
|
*/
|
|
37
37
|
setupDatabase(): Promise<void>;
|
|
38
|
+
private tableExistsAsync;
|
|
39
|
+
private createTableAndIndexes;
|
|
40
|
+
private createDeclaredIndexes;
|
|
41
|
+
/**
|
|
42
|
+
* Runs DDL inside the current transaction. Public so the `withTransaction`
|
|
43
|
+
* proxy can route the call to the tx-bound client by overriding `this.db`.
|
|
44
|
+
* Do not call directly; only via the applier's `executeSqlTx`.
|
|
45
|
+
*/
|
|
46
|
+
runMigrationDdl(sql: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Inserts a `(component, version)` row into the bookkeeping table on the
|
|
49
|
+
* current transaction's client. Public for the same reason as
|
|
50
|
+
* {@link runMigrationDdl}.
|
|
51
|
+
*/
|
|
52
|
+
recordMigrationApplied(component: string, version: number, description: string | null): Promise<void>;
|
|
53
|
+
getMigrationApplier(): ITabularMigrationApplier | null;
|
|
38
54
|
protected isVectorFormat(format?: string): boolean;
|
|
39
55
|
protected getVectorDimensions(typeDef: JsonSchema): number | undefined;
|
|
40
56
|
/**
|
|
@@ -80,28 +96,143 @@ export declare class PostgresTabularStorage<Schema extends DataPortSchemaObject,
|
|
|
80
96
|
dimension: number;
|
|
81
97
|
}>;
|
|
82
98
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
99
|
+
* Subclasses (e.g. {@link PostgresVectorStorage}) override this to tune the
|
|
100
|
+
* index built by {@link createVectorIndexes}. Returning `{}` (the default)
|
|
101
|
+
* requests HNSW with cosine distance and pgvector's built-in `m` /
|
|
102
|
+
* `efConstruction` defaults.
|
|
103
|
+
*/
|
|
104
|
+
protected getVectorIndexOptions(): VectorIndexOptions;
|
|
105
|
+
/**
|
|
106
|
+
* Creates vector-specific indexes for pgvector.
|
|
107
|
+
*
|
|
108
|
+
* Called after table creation if vector columns exist. Honours the options
|
|
109
|
+
* returned by {@link getVectorIndexOptions} — HNSW (default, with optional
|
|
110
|
+
* `m` / `efConstruction` build-time tuning) or IVFFlat (when `lists` is
|
|
111
|
+
* provided). See {@link VectorIndexOptions} for recall/latency trade-offs.
|
|
85
112
|
*/
|
|
86
113
|
protected createVectorIndexes(): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Builds the parameterized `INSERT … ON CONFLICT … RETURNING *` SQL for a
|
|
116
|
+
* single entity, applying the auto-generated-key policy. Extracted so
|
|
117
|
+
* {@link put} and {@link putBulk} can share the column/parameter logic
|
|
118
|
+
* while routing the actual query through different connections (the pool
|
|
119
|
+
* vs. a transaction-bound client).
|
|
120
|
+
*/
|
|
121
|
+
private buildPutSql;
|
|
122
|
+
/** Hydrate a row returned by Postgres back into entity-shaped JS values. */
|
|
123
|
+
private hydrateRow;
|
|
124
|
+
private acquireConnection;
|
|
125
|
+
/**
|
|
126
|
+
* Per-instance promise-chain mutex. Only meaningful on single-connection
|
|
127
|
+
* backends (PGlite / PGLitePool) — there `withTransaction` runs on the
|
|
128
|
+
* shared session and we need to keep external callers from slipping into
|
|
129
|
+
* the open transaction. On a real `pg.Pool` (anything exposing
|
|
130
|
+
* `connect()`) the mutex would serialize independent reads/writes that
|
|
131
|
+
* Postgres is happy to fan across separate pool clients, turning the
|
|
132
|
+
* pool's main benefit into a per-instance bottleneck — so we short-circuit
|
|
133
|
+
* to a no-op on that path. Real-pool isolation comes from
|
|
134
|
+
* `withTransaction` dedicating its own client via `pool.connect()`.
|
|
135
|
+
*
|
|
136
|
+
* The Proxy returned by {@link createTxView} routes back to the private
|
|
137
|
+
* `_*Internal` methods directly, so calls made *through* the `tx` handle
|
|
138
|
+
* inside `fn` do not deadlock against the mutex held by `withTransaction`.
|
|
139
|
+
*/
|
|
140
|
+
private mutexChain;
|
|
141
|
+
private get serializeOps();
|
|
142
|
+
private mutex;
|
|
143
|
+
/**
|
|
144
|
+
* True while the parent instance is between `BEGIN` and `COMMIT`/`ROLLBACK`.
|
|
145
|
+
* Used only to fail fast when `fn` captures the *original* storage instead
|
|
146
|
+
* of the `tx` handle and tries to recursively call `withTransaction` —
|
|
147
|
+
* that would deadlock against its own mutex on the PGlite path. Calls
|
|
148
|
+
* routed through `tx` hit the proxy's `withTransaction` override before
|
|
149
|
+
* reaching here.
|
|
150
|
+
*/
|
|
151
|
+
private inTransaction;
|
|
152
|
+
/**
|
|
153
|
+
* Emits a `put` event. Overridden on the {@link createTxView} proxy to
|
|
154
|
+
* push into a per-transaction buffer instead, so listeners never observe
|
|
155
|
+
* rows that are about to roll back.
|
|
156
|
+
*/
|
|
157
|
+
protected emitPut(entity: Entity): void;
|
|
87
158
|
/**
|
|
88
159
|
* Stores or updates a row in the database.
|
|
89
160
|
* Uses UPSERT (INSERT ... ON CONFLICT DO UPDATE) for atomic operations.
|
|
90
161
|
*
|
|
91
162
|
* @param entity - The entity to store (may be missing auto-generated keys)
|
|
92
163
|
* @returns The entity with any server-generated fields updated
|
|
93
|
-
* @emits "put" event with the updated entity when successful
|
|
164
|
+
* @emits "put" event with the updated entity when successful (deferred until
|
|
165
|
+
* commit if inside a {@link withTransaction})
|
|
94
166
|
*/
|
|
95
167
|
put(entity: InsertType): Promise<Entity>;
|
|
168
|
+
private _putInternal;
|
|
96
169
|
/**
|
|
97
|
-
* Stores multiple rows
|
|
98
|
-
*
|
|
170
|
+
* Stores multiple rows atomically inside a single `BEGIN` / `COMMIT`. All
|
|
171
|
+
* inserts share one connection, which (a) reduces pool churn vs. a
|
|
172
|
+
* `Promise.all` fan-out, (b) gives all-or-nothing semantics, and (c) lets
|
|
173
|
+
* Postgres group the writes into a single commit with one fsync rather than
|
|
174
|
+
* one per row.
|
|
99
175
|
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
176
|
+
* Per-row UPSERT — instead of a multi-VALUES insert — keeps the
|
|
177
|
+
* auto-generated key policy and `RETURNING *` shape identical to {@link put}
|
|
178
|
+
* and stays correct when a batch mixes rows that include the auto-gen key
|
|
179
|
+
* with rows that omit it.
|
|
180
|
+
*
|
|
181
|
+
* `put` events are deferred until after `COMMIT` so listeners do not see
|
|
182
|
+
* rows that are about to roll back. When this call is nested inside a
|
|
183
|
+
* {@link withTransaction}, deferral extends to that outer commit.
|
|
103
184
|
*/
|
|
104
185
|
putBulk(entities: InsertType[]): Promise<Entity[]>;
|
|
186
|
+
private _putBulkInternal;
|
|
187
|
+
/**
|
|
188
|
+
* Build a Proxy view of `this` for the `withTransaction` callback. The
|
|
189
|
+
* proxy:
|
|
190
|
+
*
|
|
191
|
+
* - Swaps `db` for the transaction-bound handle so every query inside
|
|
192
|
+
* `fn` runs on it: the dedicated client returned by `pool.connect()`
|
|
193
|
+
* for a real `pg.Pool`, or the shared session for PGlite/PGLitePool.
|
|
194
|
+
* - Routes any public method `foo` whose private sibling `_fooInternal`
|
|
195
|
+
* exists to that sibling, so calls made through `tx` bypass the
|
|
196
|
+
* mutex (PGlite path) and do not deadlock. The naming convention is
|
|
197
|
+
* the only sync mechanism — adding a public method with a matching
|
|
198
|
+
* `_fooInternal` is enough; no explicit map to keep in step.
|
|
199
|
+
* - Reports `inTransaction === true`, which is what
|
|
200
|
+
* {@link _putBulkInternal} keys off to skip its own BEGIN/COMMIT
|
|
201
|
+
* and run on the swapped `db` directly.
|
|
202
|
+
* - Overrides {@link emitPut} to queue events on a per-transaction
|
|
203
|
+
* buffer; the outer `withTransaction` flushes that buffer after
|
|
204
|
+
* `COMMIT` (or discards on `ROLLBACK`).
|
|
205
|
+
* - Throws on nested `withTransaction` — Postgres has no autonomous
|
|
206
|
+
* `BEGIN`. Use SAVEPOINT directly for nested rollback boundaries.
|
|
207
|
+
*/
|
|
208
|
+
private createTxView;
|
|
209
|
+
/**
|
|
210
|
+
* Runs `fn` inside a single Postgres transaction.
|
|
211
|
+
*
|
|
212
|
+
* **Real `pg.Pool`** — acquires a dedicated client via `pool.connect()`,
|
|
213
|
+
* runs `BEGIN`/`COMMIT`/`ROLLBACK` on that client, and routes every
|
|
214
|
+
* query inside `fn` through it. The parent storage instance keeps fanning
|
|
215
|
+
* external traffic across the pool, so external callers run *in parallel*
|
|
216
|
+
* with the open transaction (no per-instance mutex). This is the natural
|
|
217
|
+
* Postgres concurrency model.
|
|
218
|
+
*
|
|
219
|
+
* **PGlite / PGLitePool** — single underlying session: the parent's mutex
|
|
220
|
+
* is acquired for the duration of `fn` so external callers queue behind
|
|
221
|
+
* the transaction instead of slipping into it. `BEGIN`/`COMMIT` run on
|
|
222
|
+
* the shared `this.db`.
|
|
223
|
+
*
|
|
224
|
+
* `put` events emitted from inside `fn` (whether via `tx.put`,
|
|
225
|
+
* `tx.putBulk`, or any other writer) are buffered on a per-transaction
|
|
226
|
+
* queue and flushed to the parent's event emitter after `COMMIT`. If `fn`
|
|
227
|
+
* throws, the buffer is discarded along with the rolled-back rows so
|
|
228
|
+
* listeners never observe writes that did not actually commit.
|
|
229
|
+
*
|
|
230
|
+
* Recursive calls — either through the original instance or through `tx`
|
|
231
|
+
* — throw rather than reusing the outer transaction implicitly. Use
|
|
232
|
+
* SAVEPOINT directly for nested rollback boundaries.
|
|
233
|
+
*/
|
|
234
|
+
withTransaction<T>(fn: (tx: this) => Promise<T>): Promise<T>;
|
|
235
|
+
private runInTransaction;
|
|
105
236
|
/**
|
|
106
237
|
* Retrieves a value from the database by its primary key.
|
|
107
238
|
*
|
|
@@ -110,6 +241,7 @@ export declare class PostgresTabularStorage<Schema extends DataPortSchemaObject,
|
|
|
110
241
|
* @emits "get" event with the key when successful
|
|
111
242
|
*/
|
|
112
243
|
get(key: PrimaryKey): Promise<Entity | undefined>;
|
|
244
|
+
private _getInternal;
|
|
113
245
|
/**
|
|
114
246
|
* Deletes a row from the database.
|
|
115
247
|
*
|
|
@@ -117,27 +249,32 @@ export declare class PostgresTabularStorage<Schema extends DataPortSchemaObject,
|
|
|
117
249
|
* @emits "delete" event with the key when successful
|
|
118
250
|
*/
|
|
119
251
|
delete(value: PrimaryKey | Entity): Promise<void>;
|
|
252
|
+
private _deleteInternal;
|
|
120
253
|
/**
|
|
121
254
|
* Retrieves all entries from the database table, with optional ordering, offset, and limit.
|
|
122
255
|
* @param options - Optional ordering, limit, and offset options
|
|
123
256
|
* @returns Promise resolving to an array of entries or undefined if not found
|
|
124
257
|
*/
|
|
125
258
|
getAll(options?: QueryOptions<Entity>): Promise<Entity[] | undefined>;
|
|
259
|
+
private _getAllInternal;
|
|
126
260
|
/**
|
|
127
261
|
* Deletes all rows from the database table.
|
|
128
262
|
* @emits "clearall" event when successful
|
|
129
263
|
*/
|
|
130
264
|
deleteAll(): Promise<void>;
|
|
265
|
+
private _deleteAllInternal;
|
|
131
266
|
/**
|
|
132
267
|
* Returns the total number of rows in the database.
|
|
133
268
|
*
|
|
134
269
|
* @returns Promise resolving to the count of stored items
|
|
135
270
|
*/
|
|
136
271
|
size(): Promise<number>;
|
|
272
|
+
private _sizeInternal;
|
|
137
273
|
/**
|
|
138
274
|
* Counts rows matching the specified search criteria.
|
|
139
275
|
*/
|
|
140
276
|
count(criteria?: SearchCriteria<Entity>): Promise<number>;
|
|
277
|
+
private _countInternal;
|
|
141
278
|
/**
|
|
142
279
|
* Fetches a page of records from the repository.
|
|
143
280
|
* @param offset - Number of records to skip
|
|
@@ -145,6 +282,7 @@ export declare class PostgresTabularStorage<Schema extends DataPortSchemaObject,
|
|
|
145
282
|
* @returns Array of entities or undefined if no records found
|
|
146
283
|
*/
|
|
147
284
|
getBulk(offset: number, limit: number): Promise<Entity[] | undefined>;
|
|
285
|
+
private _getBulkInternal;
|
|
148
286
|
/**
|
|
149
287
|
* Builds WHERE clause conditions from delete search criteria.
|
|
150
288
|
* @param criteria - The search criteria object
|
|
@@ -154,6 +292,30 @@ export declare class PostgresTabularStorage<Schema extends DataPortSchemaObject,
|
|
|
154
292
|
whereClause: string;
|
|
155
293
|
params: ValueOptionType[];
|
|
156
294
|
};
|
|
295
|
+
/**
|
|
296
|
+
* Cursor-paginated read with keyset predicates pushed into SQL.
|
|
297
|
+
*
|
|
298
|
+
* Goes through {@link mutex} so on the single-connection PGlite path a
|
|
299
|
+
* `getPage` issued while a `withTransaction` is in flight queues behind
|
|
300
|
+
* the transaction's `BEGIN`/`COMMIT` instead of slipping in between them
|
|
301
|
+
* on the shared session. On a real `pg.Pool`, {@link mutex} is a no-op —
|
|
302
|
+
* page reads fan out to other pool clients in parallel as expected. The
|
|
303
|
+
* Proxy returned by {@link createTxView} auto-routes to
|
|
304
|
+
* {@link _getPageInternal} via the `_*Internal` naming convention, so
|
|
305
|
+
* calls made through `tx` bypass the mutex (which the transaction holds)
|
|
306
|
+
* and run on the transaction-bound `db`.
|
|
307
|
+
*/
|
|
308
|
+
getPage(request?: PageRequest<Entity>): Promise<Page<Entity>>;
|
|
309
|
+
private _getPageInternal;
|
|
310
|
+
queryPage(criteria: SearchCriteria<Entity>, request?: PageRequest<Entity>): Promise<Page<Entity>>;
|
|
311
|
+
private _queryPageInternal;
|
|
312
|
+
private postgresDialect;
|
|
313
|
+
/**
|
|
314
|
+
* Like {@link buildSearchWhere} but also reports the next free placeholder
|
|
315
|
+
* index — the cursor-pagination machinery needs to chain its own predicates
|
|
316
|
+
* after the criteria block, so it has to know what `$N` to start at.
|
|
317
|
+
*/
|
|
318
|
+
private buildSearchWhereWithIndex;
|
|
157
319
|
/**
|
|
158
320
|
* Deletes all entries matching the specified search criteria.
|
|
159
321
|
* Supports multiple columns with optional comparison operators.
|
|
@@ -161,6 +323,7 @@ export declare class PostgresTabularStorage<Schema extends DataPortSchemaObject,
|
|
|
161
323
|
* @param criteria - Object with column names as keys and values or SearchConditions
|
|
162
324
|
*/
|
|
163
325
|
deleteSearch(criteria: DeleteSearchCriteria<Entity>): Promise<void>;
|
|
326
|
+
private _deleteSearchInternal;
|
|
164
327
|
/**
|
|
165
328
|
* Queries entries matching the specified search criteria with optional ordering, limit, and offset.
|
|
166
329
|
*
|
|
@@ -169,6 +332,7 @@ export declare class PostgresTabularStorage<Schema extends DataPortSchemaObject,
|
|
|
169
332
|
* @returns Array of matching entities or undefined if no matches found
|
|
170
333
|
*/
|
|
171
334
|
query(criteria: SearchCriteria<Entity>, options?: QueryOptions<Entity>): Promise<Entity[] | undefined>;
|
|
335
|
+
private _queryInternal;
|
|
172
336
|
/**
|
|
173
337
|
* Queries entries matching the specified search criteria, returning only the selected columns.
|
|
174
338
|
* Requires a covering index that satisfies the criteria, orderBy, and select columns.
|
|
@@ -179,6 +343,7 @@ export declare class PostgresTabularStorage<Schema extends DataPortSchemaObject,
|
|
|
179
343
|
* @throws {CoveringIndexMissingError} when no registered index covers the query
|
|
180
344
|
*/
|
|
181
345
|
queryIndex<K extends keyof Entity & string>(criteria: SearchCriteria<Entity>, options: CoveringIndexQueryOptions<Entity, K>): Promise<Pick<Entity, K>[]>;
|
|
346
|
+
private _queryIndexInternal;
|
|
182
347
|
/**
|
|
183
348
|
* Subscribes to changes in the repository.
|
|
184
349
|
* NOT IMPLEMENTED for PostgreSQL storage.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostgresTabularStorage.d.ts","sourceRoot":"","sources":["../../src/storage/PostgresTabularStorage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAGvD,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,UAAU,EACV,uBAAuB,EACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,qBAAqB,
|
|
1
|
+
{"version":3,"file":"PostgresTabularStorage.d.ts","sourceRoot":"","sources":["../../src/storage/PostgresTabularStorage.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
import type { Pool } from "@workglow/postgres/storage";
|
|
7
7
|
import type { DataPortSchemaObject, FromSchema, TypedArray, TypedArrayConstructor, TypedArraySchemaOptions } from "@workglow/util/schema";
|
|
8
8
|
import { PostgresTabularStorage } from "./PostgresTabularStorage";
|
|
9
|
-
import type { HybridSearchOptions, IVectorStorage, VectorSearchOptions } from "@workglow/storage";
|
|
9
|
+
import type { HybridSearchOptions, IVectorStorage, VectorIndexOptions, VectorSearchOptions } from "@workglow/storage";
|
|
10
10
|
export declare class PostgresVectorStorage<Schema extends DataPortSchemaObject, PrimaryKeyNames extends ReadonlyArray<keyof Schema["properties"]>, Metadata extends Record<string, unknown> = Record<string, unknown>, Entity = FromSchema<Schema, TypedArraySchemaOptions>> extends PostgresTabularStorage<Schema, PrimaryKeyNames, Entity> implements IVectorStorage<Metadata, Schema, Entity, PrimaryKeyNames> {
|
|
11
11
|
private vectorDimensions;
|
|
12
12
|
private readonly vectorCtor;
|
|
13
13
|
private vectorPropertyName;
|
|
14
14
|
private metadataPropertyName;
|
|
15
|
+
private readonly indexOptions;
|
|
15
16
|
/**
|
|
16
17
|
* Creates a new PostgreSQL vector repository
|
|
17
18
|
* @param db - PostgreSQL connection pool
|
|
@@ -21,15 +22,64 @@ export declare class PostgresVectorStorage<Schema extends DataPortSchemaObject,
|
|
|
21
22
|
* @param indexes - Array of columns or column arrays to make searchable
|
|
22
23
|
* @param dimensions - The number of dimensions of the vector
|
|
23
24
|
* @param vectorCtor - TypedArray constructor used when hydrating vectors from SQL text (e.g. {@link Float32Array})
|
|
25
|
+
* @param indexOptions - Tuning for the pgvector index (HNSW vs IVFFlat,
|
|
26
|
+
* distance metric, m / efConstruction / lists / probes).
|
|
27
|
+
* See {@link VectorIndexOptions} for the recall/latency
|
|
28
|
+
* trade-offs. Defaults to HNSW with cosine distance and
|
|
29
|
+
* pgvector's built-in `m=16`, `efConstruction=64` defaults.
|
|
24
30
|
*/
|
|
25
|
-
constructor(db: Pool, table: string, schema: Schema, primaryKeyNames: PrimaryKeyNames, indexes: readonly (keyof NoInfer<Entity> | readonly (keyof NoInfer<Entity>)[])[] | undefined, dimensions: number, vectorCtor?: TypedArrayConstructor);
|
|
31
|
+
constructor(db: Pool, table: string, schema: Schema, primaryKeyNames: PrimaryKeyNames, indexes: readonly (keyof NoInfer<Entity> | readonly (keyof NoInfer<Entity>)[])[] | undefined, dimensions: number, vectorCtor?: TypedArrayConstructor, indexOptions?: VectorIndexOptions);
|
|
26
32
|
getVectorDimensions(): number;
|
|
33
|
+
/** Exposes tuning to {@link PostgresTabularStorage.createVectorIndexes}. */
|
|
34
|
+
protected getVectorIndexOptions(): VectorIndexOptions;
|
|
35
|
+
/** Resolved distance metric for this storage (defaults to cosine). */
|
|
36
|
+
private get distance();
|
|
37
|
+
/**
|
|
38
|
+
* pgvector distance operators per metric:
|
|
39
|
+
* - cosine: `<=>` → cosine distance ∈ [0, 2]
|
|
40
|
+
* - l2 (euclidean): `<->` → L2 distance ∈ [0, ∞)
|
|
41
|
+
* - ip (inner): `<#>` → negative inner product (pgvector negates so
|
|
42
|
+
* smaller = "more similar", matching the other ops)
|
|
43
|
+
*/
|
|
44
|
+
private get distanceOperator();
|
|
45
|
+
/**
|
|
46
|
+
* SQL fragment that converts the raw distance from {@link distanceOperator}
|
|
47
|
+
* into a "higher = more similar" score that the rest of the API exposes.
|
|
48
|
+
*
|
|
49
|
+
* - cosine: 1 - cosine_distance → similarity in [-1, 1]
|
|
50
|
+
* - l2: 1 / (1 + l2_distance) → ∈ (0, 1], 1 is exact match
|
|
51
|
+
* - ip: -(neg_inner_product) → the actual dot product
|
|
52
|
+
*/
|
|
53
|
+
private buildScoreExpr;
|
|
54
|
+
/**
|
|
55
|
+
* Returns the `efSearch` / `probes` values configured at construction time.
|
|
56
|
+
*
|
|
57
|
+
* NOTE: these are query-time GUCs and must be set on the active session.
|
|
58
|
+
* With a {@link Pool}, a connection is checked out per `pool.query()`, so a
|
|
59
|
+
* standalone `SET hnsw.ef_search = N` issued before a SELECT lands on a
|
|
60
|
+
* different client and has no effect. To apply them, callers should run
|
|
61
|
+
* search queries against a single checked-out client (using `pool.connect()`)
|
|
62
|
+
* inside a transaction with `SET LOCAL`, or set them at the role/database
|
|
63
|
+
* level via `ALTER ROLE ... SET hnsw.ef_search = N`.
|
|
64
|
+
*/
|
|
65
|
+
getQueryTuning(): {
|
|
66
|
+
efSearch?: number;
|
|
67
|
+
probes?: number;
|
|
68
|
+
};
|
|
27
69
|
similaritySearch(query: TypedArray, options?: VectorSearchOptions<Metadata>): Promise<Array<Entity & {
|
|
28
70
|
score: number;
|
|
29
71
|
}>>;
|
|
30
72
|
hybridSearch(query: TypedArray, options: HybridSearchOptions<Metadata>): Promise<(Entity & {
|
|
31
73
|
score: number;
|
|
32
74
|
})[]>;
|
|
75
|
+
/**
|
|
76
|
+
* Throws if the configured distance metric isn't cosine. The in-memory
|
|
77
|
+
* fallback paths below only know how to compute cosine similarity; if
|
|
78
|
+
* pgvector is unavailable for an `l2`/`ip` storage, falling back would
|
|
79
|
+
* silently return wrong scores. Callers using non-cosine distances must
|
|
80
|
+
* keep pgvector working.
|
|
81
|
+
*/
|
|
82
|
+
private assertFallbackSupportsDistance;
|
|
33
83
|
private searchFallback;
|
|
34
84
|
private hybridSearchFallback;
|
|
35
85
|
private getPrimaryKeyWhereClause;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostgresVectorStorage.d.ts","sourceRoot":"","sources":["../../src/storage/PostgresVectorStorage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,KAAK,EACV,oBAAoB,EACpB,UAAU,EACV,UAAU,EACV,qBAAqB,EACrB,uBAAuB,EACxB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"PostgresVectorStorage.d.ts","sourceRoot":"","sources":["../../src/storage/PostgresVectorStorage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,KAAK,EACV,oBAAoB,EACpB,UAAU,EACV,UAAU,EACV,qBAAqB,EACrB,uBAAuB,EACxB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAOlE,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EAEd,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,mBAAmB,CAAC;AAoB3B,qBAAa,qBAAqB,CAChC,MAAM,SAAS,oBAAoB,EACnC,eAAe,SAAS,aAAa,CAAC,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,EACjE,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAEpD,SAAQ,sBAAsB,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,CAC9D,YAAW,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC;IAEpE,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwB;IACnD,OAAO,CAAC,kBAAkB,CAAe;IACzC,OAAO,CAAC,oBAAoB,CAA2B;IACvD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAElD;;;;;;;;;;;;;;OAcG;IACH,YACE,EAAE,EAAE,IAAI,EACR,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,SAAS,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,YAAK,EACrF,UAAU,EAAE,MAAM,EAClB,UAAU,GAAE,qBAAoC,EAChD,YAAY,GAAE,kBAAuB,EAetC;IAEe,mBAAmB,IAAI,MAAM,CAE5C;IAED,4EAA4E;IAC5E,UAAmB,qBAAqB,IAAI,kBAAkB,CAE7D;IAED,sEAAsE;IACtE,OAAO,KAAK,QAAQ,GAEnB;IAED;;;;;;OAMG;IACH,OAAO,KAAK,gBAAgB,GAS3B;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAYtB;;;;;;;;;;OAUG;IACI,cAAc,IAAI;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAK9D;IAEY,gBAAgB,CAC3B,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,mBAAmB,CAAC,QAAQ,CAAM,GAC1C,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CA4F5C;IAEK,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,mBAAmB,CAAC,QAAQ,CAAC;eA9FzC,MAAM;UAyLxC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,8BAA8B;YAcxB,cAAc;YAiCd,oBAAoB;IA+ClC,OAAO,CAAC,wBAAwB;IAKhC,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,aAAa;CAQtB"}
|