@wiscale/velesdb-sdk 2.0.0 → 3.0.0
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 +17 -1
- package/dist/index.d.mts +74 -1
- package/dist/index.d.ts +74 -1
- package/dist/index.js +231 -7
- package/dist/index.mjs +224 -5
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Official TypeScript SDK for [VelesDB](https://github.com/cyberlife-coder/VelesDB) -- the local-first vector database for AI and RAG. Sub-millisecond semantic search in Browser and Node.js.
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**v3.0.0** | Node.js >= 18 | Browser (WASM) | VelesDB Core License 1.0
|
|
6
6
|
|
|
7
7
|
## What's New (unreleased)
|
|
8
8
|
|
|
9
|
+
- **Streaming ingestion enablement (2026-06-14)** (REST backend): `enableStreaming(collection, config?)` turns on the bounded streaming-ingestion channel before `streamInsert()`. The optional `StreamingConfig` (`bufferSize`, `batchSize`, `flushIntervalMs`) is camelCase; omitted fields fall back to the server defaults. See [`db.enableStreaming`](#dbenablestreamingcollection-config) below. The WASM backend throws `NOT_SUPPORTED`.
|
|
9
10
|
- **Relation + durable-TTL surface** (REST backend): `relate()`, `unrelate()`, `getRelations()`, `setTtlDurable()` — now fully tested and documented (see [Knowledge Graph API](#knowledge-graph-api) and [Agent Memory API](#agent-memory-api) below). The WASM backend throws `NOT_SUPPORTED` for these methods.
|
|
10
11
|
- The shipped example (`examples/hybrid_queries.ts`) was rewritten against the real API and is now compile-checked in CI.
|
|
11
12
|
|
|
@@ -332,6 +333,21 @@ await db.upsertBatch('docs', [
|
|
|
332
333
|
]);
|
|
333
334
|
```
|
|
334
335
|
|
|
336
|
+
#### `db.enableStreaming(collection, config?)`
|
|
337
|
+
|
|
338
|
+
Enable the bounded streaming-ingestion channel on a collection. Call this once before `streamInsert()`. The optional `config` is camelCase; every field is optional and omitted fields fall back to the server defaults (REST only; the WASM backend throws `NOT_SUPPORTED`).
|
|
339
|
+
|
|
340
|
+
| Option | Type | Default | Description |
|
|
341
|
+
|--------|------|---------|-------------|
|
|
342
|
+
| `bufferSize` | `number` | `10000` | Bounded ingestion channel capacity |
|
|
343
|
+
| `batchSize` | `number` | `128` | Points flushed to the index per batch |
|
|
344
|
+
| `flushIntervalMs` | `number` | `50` | Max milliseconds before a partial batch is flushed |
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
await db.enableStreaming('docs', { bufferSize: 4096, batchSize: 64 });
|
|
348
|
+
await db.streamInsert('docs', largeDocumentArray);
|
|
349
|
+
```
|
|
350
|
+
|
|
335
351
|
#### `db.streamInsert(collection, documents)`
|
|
336
352
|
|
|
337
353
|
Insert documents with server backpressure support. Sends documents sequentially, respecting 429 rate limits. Throws `BackpressureError` if the server pushes back.
|
package/dist/index.d.mts
CHANGED
|
@@ -1001,6 +1001,8 @@ interface CapabilityMap {
|
|
|
1001
1001
|
secondaryIndexes: boolean;
|
|
1002
1002
|
/** Agent Memory SDK (semantic, episodic, procedural). */
|
|
1003
1003
|
agentMemory: boolean;
|
|
1004
|
+
/** Enable the bounded streaming-ingestion channel (`enableStreaming`). */
|
|
1005
|
+
enableStreaming: boolean;
|
|
1004
1006
|
/** Streaming insert with backpressure (`streamInsert`). */
|
|
1005
1007
|
streamInsert: boolean;
|
|
1006
1008
|
/** Product quantization training (`trainPq`). */
|
|
@@ -1173,6 +1175,23 @@ interface AggregateResponse {
|
|
|
1173
1175
|
count: number;
|
|
1174
1176
|
};
|
|
1175
1177
|
}
|
|
1178
|
+
/**
|
|
1179
|
+
* Configuration for `POST /collections/{name}/stream/enable`.
|
|
1180
|
+
*
|
|
1181
|
+
* Enables the bounded streaming-ingestion channel on a collection so that
|
|
1182
|
+
* subsequent `streamInsert` calls are accepted. Every field is optional;
|
|
1183
|
+
* omitted fields fall back to the server defaults (`bufferSize` 10000,
|
|
1184
|
+
* `batchSize` 128, `flushIntervalMs` 50). camelCase here, converted to the
|
|
1185
|
+
* snake_case wire body by the backend.
|
|
1186
|
+
*/
|
|
1187
|
+
interface StreamingConfig {
|
|
1188
|
+
/** Bounded ingestion channel capacity (server default: 10000). */
|
|
1189
|
+
bufferSize?: number;
|
|
1190
|
+
/** Points flushed to the index per batch (server default: 128). */
|
|
1191
|
+
batchSize?: number;
|
|
1192
|
+
/** Max milliseconds before a partial batch is flushed (server default: 50). */
|
|
1193
|
+
flushIntervalMs?: number;
|
|
1194
|
+
}
|
|
1176
1195
|
/**
|
|
1177
1196
|
* Response from `POST /collections/{name}/points/stream` (NDJSON batch upsert).
|
|
1178
1197
|
*
|
|
@@ -1220,6 +1239,17 @@ interface IVelesDBBackend {
|
|
|
1220
1239
|
upsert(collection: string, doc: VectorDocument): Promise<void>;
|
|
1221
1240
|
/** Upsert (insert or replace) multiple vectors */
|
|
1222
1241
|
upsertBatch(collection: string, docs: VectorDocument[]): Promise<void>;
|
|
1242
|
+
/**
|
|
1243
|
+
* Bulk upsert multiple vectors via the binary wire format (REST only).
|
|
1244
|
+
*
|
|
1245
|
+
* Encodes `(id, vector)` pairs into the deterministic VRB1 binary layout
|
|
1246
|
+
* and POSTs them as `application/octet-stream`, avoiding per-point JSON
|
|
1247
|
+
* overhead. Payloads are not carried on this path. Not supported by the
|
|
1248
|
+
* WASM backend.
|
|
1249
|
+
*
|
|
1250
|
+
* @returns the number of points the server reports as inserted.
|
|
1251
|
+
*/
|
|
1252
|
+
upsertBatchRaw(collection: string, docs: VectorDocument[]): Promise<number>;
|
|
1223
1253
|
/** Search for similar vectors */
|
|
1224
1254
|
search(collection: string, query: number[] | Float32Array, options?: SearchOptions): Promise<SearchResult[]>;
|
|
1225
1255
|
/** Delete a vector by ID */
|
|
@@ -1257,6 +1287,11 @@ interface IVelesDBBackend {
|
|
|
1257
1287
|
collectionSanity(collection: string): Promise<CollectionSanityResponse>;
|
|
1258
1288
|
/** Multi-query fusion search */
|
|
1259
1289
|
multiQuerySearch(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
1290
|
+
/** Multi-query fusion search returning only IDs and scores */
|
|
1291
|
+
multiQuerySearchIds(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<Array<{
|
|
1292
|
+
id: number;
|
|
1293
|
+
score: number;
|
|
1294
|
+
}>>;
|
|
1260
1295
|
/** Check if collection is empty */
|
|
1261
1296
|
isEmpty(collection: string): Promise<boolean>;
|
|
1262
1297
|
/** Flush pending changes to disk */
|
|
@@ -1294,6 +1329,14 @@ interface IVelesDBBackend {
|
|
|
1294
1329
|
sparseSearchNamed(collection: string, query: SparseVector, indexName: string, options?: SparseSearchNamedOptions): Promise<SearchResult[]>;
|
|
1295
1330
|
/** Train Product Quantization on a collection */
|
|
1296
1331
|
trainPq(collection: string, options?: PqTrainOptions): Promise<string>;
|
|
1332
|
+
/**
|
|
1333
|
+
* Enable the bounded streaming-ingestion channel on a collection.
|
|
1334
|
+
*
|
|
1335
|
+
* POSTs an optional `StreamingConfig` to
|
|
1336
|
+
* `POST /collections/{name}/stream/enable`; omitted config fields fall
|
|
1337
|
+
* back to the server defaults. Must be called before `streamInsert`.
|
|
1338
|
+
*/
|
|
1339
|
+
enableStreaming(collection: string, config?: StreamingConfig): Promise<void>;
|
|
1297
1340
|
/** Stream-insert documents with backpressure support */
|
|
1298
1341
|
streamInsert(collection: string, docs: VectorDocument[]): Promise<void>;
|
|
1299
1342
|
/**
|
|
@@ -1490,6 +1533,18 @@ declare class VelesDB {
|
|
|
1490
1533
|
listCollections(): Promise<Collection[]>;
|
|
1491
1534
|
upsert(collection: string, doc: VectorDocument): Promise<void>;
|
|
1492
1535
|
upsertBatch(collection: string, docs: VectorDocument[]): Promise<void>;
|
|
1536
|
+
/**
|
|
1537
|
+
* Bulk upsert via the binary wire format (REST backend only).
|
|
1538
|
+
*
|
|
1539
|
+
* Encodes `(id, vector)` pairs into the deterministic VRB1 binary layout
|
|
1540
|
+
* and sends them as a single `application/octet-stream` request, avoiding
|
|
1541
|
+
* per-point JSON overhead. Payloads are not carried — use
|
|
1542
|
+
* {@link upsertBatch} when you need them. Throws a not-supported error on
|
|
1543
|
+
* the WASM backend.
|
|
1544
|
+
*
|
|
1545
|
+
* @returns the number of points the server reports as inserted.
|
|
1546
|
+
*/
|
|
1547
|
+
upsertBatchRaw(collection: string, docs: VectorDocument[]): Promise<number>;
|
|
1493
1548
|
delete(collection: string, id: string | number): Promise<boolean>;
|
|
1494
1549
|
get(collection: string, id: string | number): Promise<VectorDocument | null>;
|
|
1495
1550
|
isEmpty(collection: string): Promise<boolean>;
|
|
@@ -1512,6 +1567,11 @@ declare class VelesDB {
|
|
|
1512
1567
|
filter?: FilterInput;
|
|
1513
1568
|
}): Promise<SearchResult[]>;
|
|
1514
1569
|
multiQuerySearch(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
1570
|
+
/** Multi-query fusion search returning only IDs and scores (no payloads). */
|
|
1571
|
+
multiQuerySearchIds(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<Array<{
|
|
1572
|
+
id: number;
|
|
1573
|
+
score: number;
|
|
1574
|
+
}>>;
|
|
1515
1575
|
/**
|
|
1516
1576
|
* Pure sparse search against a named sparse index.
|
|
1517
1577
|
*
|
|
@@ -1526,6 +1586,7 @@ declare class VelesDB {
|
|
|
1526
1586
|
collectionSanity(collection: string): Promise<CollectionSanityResponse>;
|
|
1527
1587
|
scroll(collection: string, request?: ScrollRequest): Promise<ScrollResponse>;
|
|
1528
1588
|
trainPq(collection: string, options?: PqTrainOptions): Promise<string>;
|
|
1589
|
+
enableStreaming(collection: string, config?: StreamingConfig): Promise<void>;
|
|
1529
1590
|
streamInsert(collection: string, docs: VectorDocument[]): Promise<void>;
|
|
1530
1591
|
streamUpsertPoints(collection: string, docs: VectorDocument[]): Promise<StreamUpsertResponse>;
|
|
1531
1592
|
searchIds(collection: string, query: number[] | Float32Array, options?: SearchOptions): Promise<Array<{
|
|
@@ -1590,6 +1651,7 @@ declare class WasmBackend implements IVelesDBBackend {
|
|
|
1590
1651
|
listCollections(): Promise<Collection[]>;
|
|
1591
1652
|
upsert(collectionName: string, doc: VectorDocument): Promise<void>;
|
|
1592
1653
|
upsertBatch(collectionName: string, docs: VectorDocument[]): Promise<void>;
|
|
1654
|
+
upsertBatchRaw(c: string, d: VectorDocument[]): Promise<number>;
|
|
1593
1655
|
delete(collectionName: string, id: string | number): Promise<boolean>;
|
|
1594
1656
|
get(collectionName: string, id: string | number): Promise<VectorDocument | null>;
|
|
1595
1657
|
isEmpty(collectionName: string): Promise<boolean>;
|
|
@@ -1627,6 +1689,7 @@ declare class WasmBackend implements IVelesDBBackend {
|
|
|
1627
1689
|
traverseParallel(c: string, r: TraverseParallelRequest): Promise<TraverseResponse>;
|
|
1628
1690
|
getNodeDegree(c: string, n: number): Promise<DegreeResponse>;
|
|
1629
1691
|
trainPq(c: string, o?: PqTrainOptions): Promise<string>;
|
|
1692
|
+
enableStreaming(c: string, cfg?: StreamingConfig): Promise<void>;
|
|
1630
1693
|
streamInsert(c: string, d: VectorDocument[]): Promise<void>;
|
|
1631
1694
|
streamUpsertPoints(c: string, d: VectorDocument[]): Promise<StreamUpsertResponse>;
|
|
1632
1695
|
createGraphCollection(n: string, c?: GraphCollectionConfig): Promise<void>;
|
|
@@ -1637,6 +1700,10 @@ declare class WasmBackend implements IVelesDBBackend {
|
|
|
1637
1700
|
id: number;
|
|
1638
1701
|
score: number;
|
|
1639
1702
|
}>>;
|
|
1703
|
+
multiQuerySearchIds(c: string, v: Array<number[] | Float32Array>, o?: MultiQuerySearchOptions): Promise<Array<{
|
|
1704
|
+
id: number;
|
|
1705
|
+
score: number;
|
|
1706
|
+
}>>;
|
|
1640
1707
|
storeSemanticFact(c: string, e: SemanticEntry): Promise<void>;
|
|
1641
1708
|
searchSemanticMemory(c: string, e: number[], k?: number): Promise<SearchResult[]>;
|
|
1642
1709
|
recordEpisodicEvent(c: string, e: EpisodicEvent): Promise<string>;
|
|
@@ -1684,6 +1751,7 @@ declare class RestBackend implements IVelesDBBackend {
|
|
|
1684
1751
|
listCollections(): Promise<Collection[]>;
|
|
1685
1752
|
upsert(c: string, d: VectorDocument): Promise<void>;
|
|
1686
1753
|
upsertBatch(c: string, d: VectorDocument[]): Promise<void>;
|
|
1754
|
+
upsertBatchRaw(c: string, d: VectorDocument[]): Promise<number>;
|
|
1687
1755
|
delete(c: string, id: string | number): Promise<boolean>;
|
|
1688
1756
|
get(c: string, id: string | number): Promise<VectorDocument | null>;
|
|
1689
1757
|
isEmpty(c: string): Promise<boolean>;
|
|
@@ -1721,6 +1789,10 @@ declare class RestBackend implements IVelesDBBackend {
|
|
|
1721
1789
|
filter?: FilterInput;
|
|
1722
1790
|
}): Promise<SearchResult[]>;
|
|
1723
1791
|
multiQuerySearch(c: string, v: Array<number[] | Float32Array>, o?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
1792
|
+
multiQuerySearchIds(c: string, v: Array<number[] | Float32Array>, o?: MultiQuerySearchOptions): Promise<Array<{
|
|
1793
|
+
id: number;
|
|
1794
|
+
score: number;
|
|
1795
|
+
}>>;
|
|
1724
1796
|
searchIds(c: string, q: number[] | Float32Array, o?: SearchOptions): Promise<Array<{
|
|
1725
1797
|
id: number;
|
|
1726
1798
|
score: number;
|
|
@@ -1746,6 +1818,7 @@ declare class RestBackend implements IVelesDBBackend {
|
|
|
1746
1818
|
analyzeCollection(c: string): Promise<CollectionStatsResponse>;
|
|
1747
1819
|
getCollectionConfig(c: string): Promise<CollectionConfigResponse>;
|
|
1748
1820
|
trainPq(c: string, o?: PqTrainOptions): Promise<string>;
|
|
1821
|
+
enableStreaming(c: string, cfg?: StreamingConfig): Promise<void>;
|
|
1749
1822
|
streamInsert(c: string, d: VectorDocument[]): Promise<void>;
|
|
1750
1823
|
streamUpsertPoints(c: string, d: VectorDocument[]): Promise<StreamUpsertResponse>;
|
|
1751
1824
|
storeSemanticFact(c: string, e: SemanticEntry): Promise<void>;
|
|
@@ -2246,4 +2319,4 @@ declare class OpenAIEmbedder implements Embedder {
|
|
|
2246
2319
|
embed(texts: string[]): Promise<number[][]>;
|
|
2247
2320
|
}
|
|
2248
2321
|
|
|
2249
|
-
export { type ActualStats, type AddEdgeRequest, AgentMemoryClient, type AgentMemoryConfig, type AggregateQueryOptions, type AggregateResponse, type AggregationQueryResponse, AllocationFailedError, type AsyncIndexBuilderOptions, type BackendType, BackpressureError, type CapabilityMap, type Collection, type CollectionConfig, type CollectionConfigResponse, CollectionExistsError, CollectionNotFoundError, type CollectionSanityChecks, type CollectionSanityDiagnostics, type CollectionSanityResponse, type CollectionStatsResponse, type CollectionType, type ColumnStatsDetail, ColumnStoreError, type CompareOp, type Condition, ConfigError, ConnectionError, type CreateIndexOptions, DatabaseLockedError, type DeferredIndexerOptions, type DegreeResponse, DimensionMismatchError, type DistanceMetric, EdgeExistsError, EdgeNotFoundError, type EdgesResponse, type Embedder, type EpisodicEvent, type EpisodicRecord, EpochMismatchError, type ExplainCost, type ExplainFeatures, type ExplainPlanStep, type ExplainResponse, type Filter, type FilterInput, type FusionOptions, type FusionStrategy, type GetEdgesOptions, type GetNodeEdgesOptions, GpuError, type GraphCollectionConfig, type GraphEdge, type GraphNodeId, GraphNotSupportedError, type GraphSchemaMode, type GraphSearchRequest, type GraphSearchResponse, type GraphSearchResultItem, GuardRailError, type GuardRailsConfigResponse, type GuardRailsUpdateRequest, type HnswParams, type IVelesDBBackend, IncompatibleSchemaVersionError, IndexCorruptedError, IndexError, type IndexInfo, type IndexType, InternalError, InvalidCollectionNameError, InvalidDimensionError, InvalidEdgeLabelError, InvalidQuantizerConfigError, InvalidVectorError, IoError, type JsonValue, type ListNodesResponse, type MatchQueryOptions, type MatchQueryResponse, type MatchQueryResultItem, type MultiQuerySearchOptions, type NearVectorOptions, NodeNotFoundError, type NodePayloadResponse, type NodeStats, NotFoundError, OpenAIEmbedder, type OpenAIEmbedderOptions, OverflowError, PointNotFoundError, type PqTrainOptions, type ProceduralPattern, type QueryApiResponse, QueryError, type QueryOptions, type QueryResponse, type QueryResult, type QueryStats, REST_CAPABILITIES, type RebuildIndexResponse, type RelDirection, type RelOptions, type RelateRequest, type RelateResponse, type RelationEdge, type RelationsResponse, RestBackend, type RestPointId, SchemaValidationError, type ScrollRequest, type ScrollResponse, SearchNotSupportedError, type SearchOptions, type SearchQuality, type SearchQualityWire, type SearchResult, type SemanticEntry, SerializationError, SnapshotBuildFailedError, SparseIndexError, type SparseSearchNamedOptions, type SparseVector, StorageError, type StorageMode, type StreamUpsertResponse, TrainingFailedError, type TraversalResultItem, type TraversalStats, type TraverseParallelRequest, type TraverseRequest, type TraverseResponse, VELES_ERROR_CODES, ValidationError, type VectorDocument, VectorNotAllowedError, VectorRequiredError, VelesDB, type VelesDBConfig, VelesDBError, VelesError, type VelesErrorCode, VelesQLBuilder, WASM_CAPABILITIES, WasmBackend, f, isTypedFilter, normalizeFilter, parseVelesError, searchQualityToMode, velesql };
|
|
2322
|
+
export { type ActualStats, type AddEdgeRequest, AgentMemoryClient, type AgentMemoryConfig, type AggregateQueryOptions, type AggregateResponse, type AggregationQueryResponse, AllocationFailedError, type AsyncIndexBuilderOptions, type BackendType, BackpressureError, type CapabilityMap, type Collection, type CollectionConfig, type CollectionConfigResponse, CollectionExistsError, CollectionNotFoundError, type CollectionSanityChecks, type CollectionSanityDiagnostics, type CollectionSanityResponse, type CollectionStatsResponse, type CollectionType, type ColumnStatsDetail, ColumnStoreError, type CompareOp, type Condition, ConfigError, ConnectionError, type CreateIndexOptions, DatabaseLockedError, type DeferredIndexerOptions, type DegreeResponse, DimensionMismatchError, type DistanceMetric, EdgeExistsError, EdgeNotFoundError, type EdgesResponse, type Embedder, type EpisodicEvent, type EpisodicRecord, EpochMismatchError, type ExplainCost, type ExplainFeatures, type ExplainPlanStep, type ExplainResponse, type Filter, type FilterInput, type FusionOptions, type FusionStrategy, type GetEdgesOptions, type GetNodeEdgesOptions, GpuError, type GraphCollectionConfig, type GraphEdge, type GraphNodeId, GraphNotSupportedError, type GraphSchemaMode, type GraphSearchRequest, type GraphSearchResponse, type GraphSearchResultItem, GuardRailError, type GuardRailsConfigResponse, type GuardRailsUpdateRequest, type HnswParams, type IVelesDBBackend, IncompatibleSchemaVersionError, IndexCorruptedError, IndexError, type IndexInfo, type IndexType, InternalError, InvalidCollectionNameError, InvalidDimensionError, InvalidEdgeLabelError, InvalidQuantizerConfigError, InvalidVectorError, IoError, type JsonValue, type ListNodesResponse, type MatchQueryOptions, type MatchQueryResponse, type MatchQueryResultItem, type MultiQuerySearchOptions, type NearVectorOptions, NodeNotFoundError, type NodePayloadResponse, type NodeStats, NotFoundError, OpenAIEmbedder, type OpenAIEmbedderOptions, OverflowError, PointNotFoundError, type PqTrainOptions, type ProceduralPattern, type QueryApiResponse, QueryError, type QueryOptions, type QueryResponse, type QueryResult, type QueryStats, REST_CAPABILITIES, type RebuildIndexResponse, type RelDirection, type RelOptions, type RelateRequest, type RelateResponse, type RelationEdge, type RelationsResponse, RestBackend, type RestPointId, SchemaValidationError, type ScrollRequest, type ScrollResponse, SearchNotSupportedError, type SearchOptions, type SearchQuality, type SearchQualityWire, type SearchResult, type SemanticEntry, SerializationError, SnapshotBuildFailedError, SparseIndexError, type SparseSearchNamedOptions, type SparseVector, StorageError, type StorageMode, type StreamUpsertResponse, type StreamingConfig, TrainingFailedError, type TraversalResultItem, type TraversalStats, type TraverseParallelRequest, type TraverseRequest, type TraverseResponse, VELES_ERROR_CODES, ValidationError, type VectorDocument, VectorNotAllowedError, VectorRequiredError, VelesDB, type VelesDBConfig, VelesDBError, VelesError, type VelesErrorCode, VelesQLBuilder, WASM_CAPABILITIES, WasmBackend, f, isTypedFilter, normalizeFilter, parseVelesError, searchQualityToMode, velesql };
|
package/dist/index.d.ts
CHANGED
|
@@ -1001,6 +1001,8 @@ interface CapabilityMap {
|
|
|
1001
1001
|
secondaryIndexes: boolean;
|
|
1002
1002
|
/** Agent Memory SDK (semantic, episodic, procedural). */
|
|
1003
1003
|
agentMemory: boolean;
|
|
1004
|
+
/** Enable the bounded streaming-ingestion channel (`enableStreaming`). */
|
|
1005
|
+
enableStreaming: boolean;
|
|
1004
1006
|
/** Streaming insert with backpressure (`streamInsert`). */
|
|
1005
1007
|
streamInsert: boolean;
|
|
1006
1008
|
/** Product quantization training (`trainPq`). */
|
|
@@ -1173,6 +1175,23 @@ interface AggregateResponse {
|
|
|
1173
1175
|
count: number;
|
|
1174
1176
|
};
|
|
1175
1177
|
}
|
|
1178
|
+
/**
|
|
1179
|
+
* Configuration for `POST /collections/{name}/stream/enable`.
|
|
1180
|
+
*
|
|
1181
|
+
* Enables the bounded streaming-ingestion channel on a collection so that
|
|
1182
|
+
* subsequent `streamInsert` calls are accepted. Every field is optional;
|
|
1183
|
+
* omitted fields fall back to the server defaults (`bufferSize` 10000,
|
|
1184
|
+
* `batchSize` 128, `flushIntervalMs` 50). camelCase here, converted to the
|
|
1185
|
+
* snake_case wire body by the backend.
|
|
1186
|
+
*/
|
|
1187
|
+
interface StreamingConfig {
|
|
1188
|
+
/** Bounded ingestion channel capacity (server default: 10000). */
|
|
1189
|
+
bufferSize?: number;
|
|
1190
|
+
/** Points flushed to the index per batch (server default: 128). */
|
|
1191
|
+
batchSize?: number;
|
|
1192
|
+
/** Max milliseconds before a partial batch is flushed (server default: 50). */
|
|
1193
|
+
flushIntervalMs?: number;
|
|
1194
|
+
}
|
|
1176
1195
|
/**
|
|
1177
1196
|
* Response from `POST /collections/{name}/points/stream` (NDJSON batch upsert).
|
|
1178
1197
|
*
|
|
@@ -1220,6 +1239,17 @@ interface IVelesDBBackend {
|
|
|
1220
1239
|
upsert(collection: string, doc: VectorDocument): Promise<void>;
|
|
1221
1240
|
/** Upsert (insert or replace) multiple vectors */
|
|
1222
1241
|
upsertBatch(collection: string, docs: VectorDocument[]): Promise<void>;
|
|
1242
|
+
/**
|
|
1243
|
+
* Bulk upsert multiple vectors via the binary wire format (REST only).
|
|
1244
|
+
*
|
|
1245
|
+
* Encodes `(id, vector)` pairs into the deterministic VRB1 binary layout
|
|
1246
|
+
* and POSTs them as `application/octet-stream`, avoiding per-point JSON
|
|
1247
|
+
* overhead. Payloads are not carried on this path. Not supported by the
|
|
1248
|
+
* WASM backend.
|
|
1249
|
+
*
|
|
1250
|
+
* @returns the number of points the server reports as inserted.
|
|
1251
|
+
*/
|
|
1252
|
+
upsertBatchRaw(collection: string, docs: VectorDocument[]): Promise<number>;
|
|
1223
1253
|
/** Search for similar vectors */
|
|
1224
1254
|
search(collection: string, query: number[] | Float32Array, options?: SearchOptions): Promise<SearchResult[]>;
|
|
1225
1255
|
/** Delete a vector by ID */
|
|
@@ -1257,6 +1287,11 @@ interface IVelesDBBackend {
|
|
|
1257
1287
|
collectionSanity(collection: string): Promise<CollectionSanityResponse>;
|
|
1258
1288
|
/** Multi-query fusion search */
|
|
1259
1289
|
multiQuerySearch(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
1290
|
+
/** Multi-query fusion search returning only IDs and scores */
|
|
1291
|
+
multiQuerySearchIds(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<Array<{
|
|
1292
|
+
id: number;
|
|
1293
|
+
score: number;
|
|
1294
|
+
}>>;
|
|
1260
1295
|
/** Check if collection is empty */
|
|
1261
1296
|
isEmpty(collection: string): Promise<boolean>;
|
|
1262
1297
|
/** Flush pending changes to disk */
|
|
@@ -1294,6 +1329,14 @@ interface IVelesDBBackend {
|
|
|
1294
1329
|
sparseSearchNamed(collection: string, query: SparseVector, indexName: string, options?: SparseSearchNamedOptions): Promise<SearchResult[]>;
|
|
1295
1330
|
/** Train Product Quantization on a collection */
|
|
1296
1331
|
trainPq(collection: string, options?: PqTrainOptions): Promise<string>;
|
|
1332
|
+
/**
|
|
1333
|
+
* Enable the bounded streaming-ingestion channel on a collection.
|
|
1334
|
+
*
|
|
1335
|
+
* POSTs an optional `StreamingConfig` to
|
|
1336
|
+
* `POST /collections/{name}/stream/enable`; omitted config fields fall
|
|
1337
|
+
* back to the server defaults. Must be called before `streamInsert`.
|
|
1338
|
+
*/
|
|
1339
|
+
enableStreaming(collection: string, config?: StreamingConfig): Promise<void>;
|
|
1297
1340
|
/** Stream-insert documents with backpressure support */
|
|
1298
1341
|
streamInsert(collection: string, docs: VectorDocument[]): Promise<void>;
|
|
1299
1342
|
/**
|
|
@@ -1490,6 +1533,18 @@ declare class VelesDB {
|
|
|
1490
1533
|
listCollections(): Promise<Collection[]>;
|
|
1491
1534
|
upsert(collection: string, doc: VectorDocument): Promise<void>;
|
|
1492
1535
|
upsertBatch(collection: string, docs: VectorDocument[]): Promise<void>;
|
|
1536
|
+
/**
|
|
1537
|
+
* Bulk upsert via the binary wire format (REST backend only).
|
|
1538
|
+
*
|
|
1539
|
+
* Encodes `(id, vector)` pairs into the deterministic VRB1 binary layout
|
|
1540
|
+
* and sends them as a single `application/octet-stream` request, avoiding
|
|
1541
|
+
* per-point JSON overhead. Payloads are not carried — use
|
|
1542
|
+
* {@link upsertBatch} when you need them. Throws a not-supported error on
|
|
1543
|
+
* the WASM backend.
|
|
1544
|
+
*
|
|
1545
|
+
* @returns the number of points the server reports as inserted.
|
|
1546
|
+
*/
|
|
1547
|
+
upsertBatchRaw(collection: string, docs: VectorDocument[]): Promise<number>;
|
|
1493
1548
|
delete(collection: string, id: string | number): Promise<boolean>;
|
|
1494
1549
|
get(collection: string, id: string | number): Promise<VectorDocument | null>;
|
|
1495
1550
|
isEmpty(collection: string): Promise<boolean>;
|
|
@@ -1512,6 +1567,11 @@ declare class VelesDB {
|
|
|
1512
1567
|
filter?: FilterInput;
|
|
1513
1568
|
}): Promise<SearchResult[]>;
|
|
1514
1569
|
multiQuerySearch(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
1570
|
+
/** Multi-query fusion search returning only IDs and scores (no payloads). */
|
|
1571
|
+
multiQuerySearchIds(collection: string, vectors: Array<number[] | Float32Array>, options?: MultiQuerySearchOptions): Promise<Array<{
|
|
1572
|
+
id: number;
|
|
1573
|
+
score: number;
|
|
1574
|
+
}>>;
|
|
1515
1575
|
/**
|
|
1516
1576
|
* Pure sparse search against a named sparse index.
|
|
1517
1577
|
*
|
|
@@ -1526,6 +1586,7 @@ declare class VelesDB {
|
|
|
1526
1586
|
collectionSanity(collection: string): Promise<CollectionSanityResponse>;
|
|
1527
1587
|
scroll(collection: string, request?: ScrollRequest): Promise<ScrollResponse>;
|
|
1528
1588
|
trainPq(collection: string, options?: PqTrainOptions): Promise<string>;
|
|
1589
|
+
enableStreaming(collection: string, config?: StreamingConfig): Promise<void>;
|
|
1529
1590
|
streamInsert(collection: string, docs: VectorDocument[]): Promise<void>;
|
|
1530
1591
|
streamUpsertPoints(collection: string, docs: VectorDocument[]): Promise<StreamUpsertResponse>;
|
|
1531
1592
|
searchIds(collection: string, query: number[] | Float32Array, options?: SearchOptions): Promise<Array<{
|
|
@@ -1590,6 +1651,7 @@ declare class WasmBackend implements IVelesDBBackend {
|
|
|
1590
1651
|
listCollections(): Promise<Collection[]>;
|
|
1591
1652
|
upsert(collectionName: string, doc: VectorDocument): Promise<void>;
|
|
1592
1653
|
upsertBatch(collectionName: string, docs: VectorDocument[]): Promise<void>;
|
|
1654
|
+
upsertBatchRaw(c: string, d: VectorDocument[]): Promise<number>;
|
|
1593
1655
|
delete(collectionName: string, id: string | number): Promise<boolean>;
|
|
1594
1656
|
get(collectionName: string, id: string | number): Promise<VectorDocument | null>;
|
|
1595
1657
|
isEmpty(collectionName: string): Promise<boolean>;
|
|
@@ -1627,6 +1689,7 @@ declare class WasmBackend implements IVelesDBBackend {
|
|
|
1627
1689
|
traverseParallel(c: string, r: TraverseParallelRequest): Promise<TraverseResponse>;
|
|
1628
1690
|
getNodeDegree(c: string, n: number): Promise<DegreeResponse>;
|
|
1629
1691
|
trainPq(c: string, o?: PqTrainOptions): Promise<string>;
|
|
1692
|
+
enableStreaming(c: string, cfg?: StreamingConfig): Promise<void>;
|
|
1630
1693
|
streamInsert(c: string, d: VectorDocument[]): Promise<void>;
|
|
1631
1694
|
streamUpsertPoints(c: string, d: VectorDocument[]): Promise<StreamUpsertResponse>;
|
|
1632
1695
|
createGraphCollection(n: string, c?: GraphCollectionConfig): Promise<void>;
|
|
@@ -1637,6 +1700,10 @@ declare class WasmBackend implements IVelesDBBackend {
|
|
|
1637
1700
|
id: number;
|
|
1638
1701
|
score: number;
|
|
1639
1702
|
}>>;
|
|
1703
|
+
multiQuerySearchIds(c: string, v: Array<number[] | Float32Array>, o?: MultiQuerySearchOptions): Promise<Array<{
|
|
1704
|
+
id: number;
|
|
1705
|
+
score: number;
|
|
1706
|
+
}>>;
|
|
1640
1707
|
storeSemanticFact(c: string, e: SemanticEntry): Promise<void>;
|
|
1641
1708
|
searchSemanticMemory(c: string, e: number[], k?: number): Promise<SearchResult[]>;
|
|
1642
1709
|
recordEpisodicEvent(c: string, e: EpisodicEvent): Promise<string>;
|
|
@@ -1684,6 +1751,7 @@ declare class RestBackend implements IVelesDBBackend {
|
|
|
1684
1751
|
listCollections(): Promise<Collection[]>;
|
|
1685
1752
|
upsert(c: string, d: VectorDocument): Promise<void>;
|
|
1686
1753
|
upsertBatch(c: string, d: VectorDocument[]): Promise<void>;
|
|
1754
|
+
upsertBatchRaw(c: string, d: VectorDocument[]): Promise<number>;
|
|
1687
1755
|
delete(c: string, id: string | number): Promise<boolean>;
|
|
1688
1756
|
get(c: string, id: string | number): Promise<VectorDocument | null>;
|
|
1689
1757
|
isEmpty(c: string): Promise<boolean>;
|
|
@@ -1721,6 +1789,10 @@ declare class RestBackend implements IVelesDBBackend {
|
|
|
1721
1789
|
filter?: FilterInput;
|
|
1722
1790
|
}): Promise<SearchResult[]>;
|
|
1723
1791
|
multiQuerySearch(c: string, v: Array<number[] | Float32Array>, o?: MultiQuerySearchOptions): Promise<SearchResult[]>;
|
|
1792
|
+
multiQuerySearchIds(c: string, v: Array<number[] | Float32Array>, o?: MultiQuerySearchOptions): Promise<Array<{
|
|
1793
|
+
id: number;
|
|
1794
|
+
score: number;
|
|
1795
|
+
}>>;
|
|
1724
1796
|
searchIds(c: string, q: number[] | Float32Array, o?: SearchOptions): Promise<Array<{
|
|
1725
1797
|
id: number;
|
|
1726
1798
|
score: number;
|
|
@@ -1746,6 +1818,7 @@ declare class RestBackend implements IVelesDBBackend {
|
|
|
1746
1818
|
analyzeCollection(c: string): Promise<CollectionStatsResponse>;
|
|
1747
1819
|
getCollectionConfig(c: string): Promise<CollectionConfigResponse>;
|
|
1748
1820
|
trainPq(c: string, o?: PqTrainOptions): Promise<string>;
|
|
1821
|
+
enableStreaming(c: string, cfg?: StreamingConfig): Promise<void>;
|
|
1749
1822
|
streamInsert(c: string, d: VectorDocument[]): Promise<void>;
|
|
1750
1823
|
streamUpsertPoints(c: string, d: VectorDocument[]): Promise<StreamUpsertResponse>;
|
|
1751
1824
|
storeSemanticFact(c: string, e: SemanticEntry): Promise<void>;
|
|
@@ -2246,4 +2319,4 @@ declare class OpenAIEmbedder implements Embedder {
|
|
|
2246
2319
|
embed(texts: string[]): Promise<number[][]>;
|
|
2247
2320
|
}
|
|
2248
2321
|
|
|
2249
|
-
export { type ActualStats, type AddEdgeRequest, AgentMemoryClient, type AgentMemoryConfig, type AggregateQueryOptions, type AggregateResponse, type AggregationQueryResponse, AllocationFailedError, type AsyncIndexBuilderOptions, type BackendType, BackpressureError, type CapabilityMap, type Collection, type CollectionConfig, type CollectionConfigResponse, CollectionExistsError, CollectionNotFoundError, type CollectionSanityChecks, type CollectionSanityDiagnostics, type CollectionSanityResponse, type CollectionStatsResponse, type CollectionType, type ColumnStatsDetail, ColumnStoreError, type CompareOp, type Condition, ConfigError, ConnectionError, type CreateIndexOptions, DatabaseLockedError, type DeferredIndexerOptions, type DegreeResponse, DimensionMismatchError, type DistanceMetric, EdgeExistsError, EdgeNotFoundError, type EdgesResponse, type Embedder, type EpisodicEvent, type EpisodicRecord, EpochMismatchError, type ExplainCost, type ExplainFeatures, type ExplainPlanStep, type ExplainResponse, type Filter, type FilterInput, type FusionOptions, type FusionStrategy, type GetEdgesOptions, type GetNodeEdgesOptions, GpuError, type GraphCollectionConfig, type GraphEdge, type GraphNodeId, GraphNotSupportedError, type GraphSchemaMode, type GraphSearchRequest, type GraphSearchResponse, type GraphSearchResultItem, GuardRailError, type GuardRailsConfigResponse, type GuardRailsUpdateRequest, type HnswParams, type IVelesDBBackend, IncompatibleSchemaVersionError, IndexCorruptedError, IndexError, type IndexInfo, type IndexType, InternalError, InvalidCollectionNameError, InvalidDimensionError, InvalidEdgeLabelError, InvalidQuantizerConfigError, InvalidVectorError, IoError, type JsonValue, type ListNodesResponse, type MatchQueryOptions, type MatchQueryResponse, type MatchQueryResultItem, type MultiQuerySearchOptions, type NearVectorOptions, NodeNotFoundError, type NodePayloadResponse, type NodeStats, NotFoundError, OpenAIEmbedder, type OpenAIEmbedderOptions, OverflowError, PointNotFoundError, type PqTrainOptions, type ProceduralPattern, type QueryApiResponse, QueryError, type QueryOptions, type QueryResponse, type QueryResult, type QueryStats, REST_CAPABILITIES, type RebuildIndexResponse, type RelDirection, type RelOptions, type RelateRequest, type RelateResponse, type RelationEdge, type RelationsResponse, RestBackend, type RestPointId, SchemaValidationError, type ScrollRequest, type ScrollResponse, SearchNotSupportedError, type SearchOptions, type SearchQuality, type SearchQualityWire, type SearchResult, type SemanticEntry, SerializationError, SnapshotBuildFailedError, SparseIndexError, type SparseSearchNamedOptions, type SparseVector, StorageError, type StorageMode, type StreamUpsertResponse, TrainingFailedError, type TraversalResultItem, type TraversalStats, type TraverseParallelRequest, type TraverseRequest, type TraverseResponse, VELES_ERROR_CODES, ValidationError, type VectorDocument, VectorNotAllowedError, VectorRequiredError, VelesDB, type VelesDBConfig, VelesDBError, VelesError, type VelesErrorCode, VelesQLBuilder, WASM_CAPABILITIES, WasmBackend, f, isTypedFilter, normalizeFilter, parseVelesError, searchQualityToMode, velesql };
|
|
2322
|
+
export { type ActualStats, type AddEdgeRequest, AgentMemoryClient, type AgentMemoryConfig, type AggregateQueryOptions, type AggregateResponse, type AggregationQueryResponse, AllocationFailedError, type AsyncIndexBuilderOptions, type BackendType, BackpressureError, type CapabilityMap, type Collection, type CollectionConfig, type CollectionConfigResponse, CollectionExistsError, CollectionNotFoundError, type CollectionSanityChecks, type CollectionSanityDiagnostics, type CollectionSanityResponse, type CollectionStatsResponse, type CollectionType, type ColumnStatsDetail, ColumnStoreError, type CompareOp, type Condition, ConfigError, ConnectionError, type CreateIndexOptions, DatabaseLockedError, type DeferredIndexerOptions, type DegreeResponse, DimensionMismatchError, type DistanceMetric, EdgeExistsError, EdgeNotFoundError, type EdgesResponse, type Embedder, type EpisodicEvent, type EpisodicRecord, EpochMismatchError, type ExplainCost, type ExplainFeatures, type ExplainPlanStep, type ExplainResponse, type Filter, type FilterInput, type FusionOptions, type FusionStrategy, type GetEdgesOptions, type GetNodeEdgesOptions, GpuError, type GraphCollectionConfig, type GraphEdge, type GraphNodeId, GraphNotSupportedError, type GraphSchemaMode, type GraphSearchRequest, type GraphSearchResponse, type GraphSearchResultItem, GuardRailError, type GuardRailsConfigResponse, type GuardRailsUpdateRequest, type HnswParams, type IVelesDBBackend, IncompatibleSchemaVersionError, IndexCorruptedError, IndexError, type IndexInfo, type IndexType, InternalError, InvalidCollectionNameError, InvalidDimensionError, InvalidEdgeLabelError, InvalidQuantizerConfigError, InvalidVectorError, IoError, type JsonValue, type ListNodesResponse, type MatchQueryOptions, type MatchQueryResponse, type MatchQueryResultItem, type MultiQuerySearchOptions, type NearVectorOptions, NodeNotFoundError, type NodePayloadResponse, type NodeStats, NotFoundError, OpenAIEmbedder, type OpenAIEmbedderOptions, OverflowError, PointNotFoundError, type PqTrainOptions, type ProceduralPattern, type QueryApiResponse, QueryError, type QueryOptions, type QueryResponse, type QueryResult, type QueryStats, REST_CAPABILITIES, type RebuildIndexResponse, type RelDirection, type RelOptions, type RelateRequest, type RelateResponse, type RelationEdge, type RelationsResponse, RestBackend, type RestPointId, SchemaValidationError, type ScrollRequest, type ScrollResponse, SearchNotSupportedError, type SearchOptions, type SearchQuality, type SearchQualityWire, type SearchResult, type SemanticEntry, SerializationError, SnapshotBuildFailedError, SparseIndexError, type SparseSearchNamedOptions, type SparseVector, StorageError, type StorageMode, type StreamUpsertResponse, type StreamingConfig, TrainingFailedError, type TraversalResultItem, type TraversalStats, type TraverseParallelRequest, type TraverseRequest, type TraverseResponse, VELES_ERROR_CODES, ValidationError, type VectorDocument, VectorNotAllowedError, VectorRequiredError, VelesDB, type VelesDBConfig, VelesDBError, VelesError, type VelesErrorCode, VelesQLBuilder, WASM_CAPABILITIES, WasmBackend, f, isTypedFilter, normalizeFilter, parseVelesError, searchQualityToMode, velesql };
|
package/dist/index.js
CHANGED
|
@@ -5,8 +5,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __esm = (fn, res) => function __init() {
|
|
9
|
-
|
|
8
|
+
var __esm = (fn, res, err) => function __init() {
|
|
9
|
+
if (err) throw err[0];
|
|
10
|
+
try {
|
|
11
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
12
|
+
} catch (e) {
|
|
13
|
+
throw err = [e], e;
|
|
14
|
+
}
|
|
10
15
|
};
|
|
11
16
|
var __export = (target, all) => {
|
|
12
17
|
for (var name in all)
|
|
@@ -182,6 +187,7 @@ var REST_CAPABILITIES = Object.freeze({
|
|
|
182
187
|
graphTraversal: true,
|
|
183
188
|
secondaryIndexes: true,
|
|
184
189
|
agentMemory: true,
|
|
190
|
+
enableStreaming: true,
|
|
185
191
|
streamInsert: true,
|
|
186
192
|
pqTraining: true,
|
|
187
193
|
velesqlQuery: true,
|
|
@@ -197,6 +203,7 @@ var WASM_CAPABILITIES = Object.freeze({
|
|
|
197
203
|
graphTraversal: false,
|
|
198
204
|
secondaryIndexes: false,
|
|
199
205
|
agentMemory: false,
|
|
206
|
+
enableStreaming: false,
|
|
200
207
|
streamInsert: false,
|
|
201
208
|
pqTraining: false,
|
|
202
209
|
velesqlQuery: false,
|
|
@@ -891,6 +898,9 @@ function validateCollectionName(name) {
|
|
|
891
898
|
);
|
|
892
899
|
}
|
|
893
900
|
}
|
|
901
|
+
async function safeJsonParse(response) {
|
|
902
|
+
return response.json().catch(() => ({}));
|
|
903
|
+
}
|
|
894
904
|
function toNumberArray(v) {
|
|
895
905
|
return v instanceof Float32Array ? Array.from(v) : v;
|
|
896
906
|
}
|
|
@@ -944,12 +954,18 @@ async function wasmScroll(_collection, _request) {
|
|
|
944
954
|
async function wasmTrainPq(_collection, _options) {
|
|
945
955
|
wasmNotSupported("PQ training");
|
|
946
956
|
}
|
|
957
|
+
async function wasmEnableStreaming(_collection, _config) {
|
|
958
|
+
wasmNotSupported("Streaming enable");
|
|
959
|
+
}
|
|
947
960
|
async function wasmStreamInsert(_collection, _docs) {
|
|
948
961
|
wasmNotSupported("Streaming insert");
|
|
949
962
|
}
|
|
950
963
|
async function wasmStreamUpsertPoints(_collection, _docs) {
|
|
951
964
|
wasmNotSupported("Streaming batch upsert");
|
|
952
965
|
}
|
|
966
|
+
async function wasmUpsertBatchRaw(_collection, _docs) {
|
|
967
|
+
wasmNotSupported("Binary bulk upsert (upsertBatchRaw)");
|
|
968
|
+
}
|
|
953
969
|
async function wasmCreateGraphCollection(_name, _config) {
|
|
954
970
|
wasmNotSupported("Graph collections");
|
|
955
971
|
}
|
|
@@ -965,6 +981,9 @@ async function wasmGetCollectionConfig(_collection) {
|
|
|
965
981
|
async function wasmSearchIds(_collection, _query, _options) {
|
|
966
982
|
wasmNotSupported("searchIds");
|
|
967
983
|
}
|
|
984
|
+
async function wasmMultiQuerySearchIds(_collection, _vectors, _options) {
|
|
985
|
+
wasmNotSupported("multiQuerySearchIds");
|
|
986
|
+
}
|
|
968
987
|
async function wasmStoreSemanticFact(_collection, _entry) {
|
|
969
988
|
wasmNotSupported("Agent memory");
|
|
970
989
|
}
|
|
@@ -1221,6 +1240,9 @@ var WasmBackend = class {
|
|
|
1221
1240
|
}
|
|
1222
1241
|
}
|
|
1223
1242
|
}
|
|
1243
|
+
async upsertBatchRaw(c, d) {
|
|
1244
|
+
return wasmUpsertBatchRaw(c, d);
|
|
1245
|
+
}
|
|
1224
1246
|
async delete(collectionName, id) {
|
|
1225
1247
|
this.ensureInitialized();
|
|
1226
1248
|
const collection = this.collections.get(collectionName);
|
|
@@ -1352,6 +1374,10 @@ var WasmBackend = class {
|
|
|
1352
1374
|
this.ensureInitialized();
|
|
1353
1375
|
return wasmTrainPq(c, o);
|
|
1354
1376
|
}
|
|
1377
|
+
async enableStreaming(c, cfg) {
|
|
1378
|
+
this.ensureInitialized();
|
|
1379
|
+
return wasmEnableStreaming(c, cfg);
|
|
1380
|
+
}
|
|
1355
1381
|
async streamInsert(c, d) {
|
|
1356
1382
|
this.ensureInitialized();
|
|
1357
1383
|
return wasmStreamInsert(c, d);
|
|
@@ -1380,6 +1406,10 @@ var WasmBackend = class {
|
|
|
1380
1406
|
this.ensureInitialized();
|
|
1381
1407
|
return wasmSearchIds(c, q, o);
|
|
1382
1408
|
}
|
|
1409
|
+
async multiQuerySearchIds(c, v, o) {
|
|
1410
|
+
this.ensureInitialized();
|
|
1411
|
+
return wasmMultiQuerySearchIds(c, v, o);
|
|
1412
|
+
}
|
|
1383
1413
|
async storeSemanticFact(c, e) {
|
|
1384
1414
|
this.ensureInitialized();
|
|
1385
1415
|
return wasmStoreSemanticFact(c, e);
|
|
@@ -1484,6 +1514,9 @@ var WasmBackend = class {
|
|
|
1484
1514
|
};
|
|
1485
1515
|
|
|
1486
1516
|
// src/backends/crud-backend.ts
|
|
1517
|
+
var RAW_BULK_HEADER_LEN = 16;
|
|
1518
|
+
var RAW_BULK_MAGIC = [86, 82, 66, 49];
|
|
1519
|
+
var RAW_BULK_ID_WIDTH = 8;
|
|
1487
1520
|
var U64_MAX = 18446744073709551615n;
|
|
1488
1521
|
function coerceDecimalStringId(id) {
|
|
1489
1522
|
if (!/^\d+$/.test(id)) return NaN;
|
|
@@ -1634,6 +1667,105 @@ async function flush(transport, collection) {
|
|
|
1634
1667
|
);
|
|
1635
1668
|
throwOnError(response, `Collection '${collection}'`);
|
|
1636
1669
|
}
|
|
1670
|
+
function encodeRawBulk(ids, vectors, dim) {
|
|
1671
|
+
const count = ids.length;
|
|
1672
|
+
if (vectors.length !== count) {
|
|
1673
|
+
throw new ValidationError(
|
|
1674
|
+
`encodeRawBulk: ids length (${count}) must match vectors length (${vectors.length})`
|
|
1675
|
+
);
|
|
1676
|
+
}
|
|
1677
|
+
const buf = new Uint8Array(RAW_BULK_HEADER_LEN + count * 8 + count * dim * 4);
|
|
1678
|
+
const view = new DataView(buf.buffer);
|
|
1679
|
+
buf.set(RAW_BULK_MAGIC, 0);
|
|
1680
|
+
view.setUint32(4, count, true);
|
|
1681
|
+
view.setUint32(8, dim, true);
|
|
1682
|
+
buf[12] = RAW_BULK_ID_WIDTH;
|
|
1683
|
+
writeIds(view, ids);
|
|
1684
|
+
writeVectors(view, vectors, dim, count);
|
|
1685
|
+
return buf;
|
|
1686
|
+
}
|
|
1687
|
+
function writeIds(view, ids) {
|
|
1688
|
+
let off = RAW_BULK_HEADER_LEN;
|
|
1689
|
+
for (const id of ids) {
|
|
1690
|
+
view.setBigUint64(off, BigInt(id), true);
|
|
1691
|
+
off += 8;
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
function writeVectors(view, vectors, dim, count) {
|
|
1695
|
+
let off = RAW_BULK_HEADER_LEN + count * 8;
|
|
1696
|
+
for (const vec of vectors) {
|
|
1697
|
+
if (vec.length !== dim) {
|
|
1698
|
+
throw new ValidationError(
|
|
1699
|
+
`encodeRawBulk: vector length (${vec.length}) must match dim (${dim})`
|
|
1700
|
+
);
|
|
1701
|
+
}
|
|
1702
|
+
for (let i = 0; i < dim; i++) {
|
|
1703
|
+
view.setFloat32(off, vec[i] ?? 0, true);
|
|
1704
|
+
off += 4;
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
async function upsertBatchRaw(transport, collection, docs, dim) {
|
|
1709
|
+
const ids = docs.map((d) => coerceNumericId(d.id));
|
|
1710
|
+
const vectors = docs.map((d) => d.vector);
|
|
1711
|
+
const body = encodeRawBulk(ids, vectors, dim);
|
|
1712
|
+
return sendRawBulk(transport, collection, body);
|
|
1713
|
+
}
|
|
1714
|
+
function coerceNumericId(id) {
|
|
1715
|
+
const parsed = parseRestPointId(id);
|
|
1716
|
+
if (typeof parsed === "string") {
|
|
1717
|
+
throw new ValidationError(
|
|
1718
|
+
`upsertBatchRaw requires ids in the JS safe integer range; received: ${parsed}`
|
|
1719
|
+
);
|
|
1720
|
+
}
|
|
1721
|
+
return parsed;
|
|
1722
|
+
}
|
|
1723
|
+
async function sendRawBulk(transport, collection, body) {
|
|
1724
|
+
const url = `${transport.baseUrl}${collectionPath(collection)}/points/raw`;
|
|
1725
|
+
const headers = {
|
|
1726
|
+
"Content-Type": "application/octet-stream"
|
|
1727
|
+
};
|
|
1728
|
+
if (transport.apiKey) {
|
|
1729
|
+
headers["Authorization"] = `Bearer ${transport.apiKey}`;
|
|
1730
|
+
}
|
|
1731
|
+
const controller = new AbortController();
|
|
1732
|
+
const timeoutId = setTimeout(() => controller.abort(), transport.timeout);
|
|
1733
|
+
try {
|
|
1734
|
+
const response = await fetch(url, {
|
|
1735
|
+
method: "POST",
|
|
1736
|
+
headers,
|
|
1737
|
+
body,
|
|
1738
|
+
signal: controller.signal
|
|
1739
|
+
});
|
|
1740
|
+
clearTimeout(timeoutId);
|
|
1741
|
+
return await parseRawBulkResponse(response);
|
|
1742
|
+
} catch (error) {
|
|
1743
|
+
clearTimeout(timeoutId);
|
|
1744
|
+
throw wrapRawBulkError(error);
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
async function parseRawBulkResponse(response) {
|
|
1748
|
+
const data = await safeJsonParse(response);
|
|
1749
|
+
if (!response.ok) {
|
|
1750
|
+
const code = typeof data.code === "string" ? data.code : `HTTP_${response.status}`;
|
|
1751
|
+
const message = typeof data.error === "string" ? data.error : `HTTP ${response.status}`;
|
|
1752
|
+
throw new VelesDBError(message, code);
|
|
1753
|
+
}
|
|
1754
|
+
return typeof data.count === "number" ? data.count : 0;
|
|
1755
|
+
}
|
|
1756
|
+
function wrapRawBulkError(error) {
|
|
1757
|
+
if (error instanceof VelesDBError) {
|
|
1758
|
+
return error;
|
|
1759
|
+
}
|
|
1760
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
1761
|
+
return new ConnectionError("Request timeout");
|
|
1762
|
+
}
|
|
1763
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1764
|
+
return new ConnectionError(
|
|
1765
|
+
`Raw bulk upsert failed: ${message}`,
|
|
1766
|
+
error instanceof Error ? error : void 0
|
|
1767
|
+
);
|
|
1768
|
+
}
|
|
1637
1769
|
|
|
1638
1770
|
// src/backends/rest-http.ts
|
|
1639
1771
|
var STATUS_ERROR_CODES = {
|
|
@@ -1704,7 +1836,7 @@ async function request(config, method, path, body) {
|
|
|
1704
1836
|
signal: controller.signal
|
|
1705
1837
|
});
|
|
1706
1838
|
clearTimeout(timeoutId);
|
|
1707
|
-
const data = await response
|
|
1839
|
+
const data = await safeJsonParse(response);
|
|
1708
1840
|
if (!response.ok) {
|
|
1709
1841
|
const ep = extractErrorPayload(data);
|
|
1710
1842
|
return { error: {
|
|
@@ -1728,6 +1860,13 @@ function buildCrudTransport(config) {
|
|
|
1728
1860
|
requestJson: (m, p, b) => request(config, m, p, b)
|
|
1729
1861
|
};
|
|
1730
1862
|
}
|
|
1863
|
+
function buildRawBulkTransport(config) {
|
|
1864
|
+
return {
|
|
1865
|
+
baseUrl: config.baseUrl,
|
|
1866
|
+
apiKey: config.apiKey,
|
|
1867
|
+
timeout: config.timeout
|
|
1868
|
+
};
|
|
1869
|
+
}
|
|
1731
1870
|
function buildSearchTransport(config) {
|
|
1732
1871
|
return {
|
|
1733
1872
|
requestJson: (m, p, b) => request(config, m, p, b),
|
|
@@ -2215,6 +2354,22 @@ async function multiQuerySearch(transport, collection, vectors, options) {
|
|
|
2215
2354
|
throwOnError(response, `Collection '${collection}'`);
|
|
2216
2355
|
return response.data?.results ?? [];
|
|
2217
2356
|
}
|
|
2357
|
+
async function multiQuerySearchIds(transport, collection, vectors, options) {
|
|
2358
|
+
const formattedVectors = vectors.map(toNumberArray);
|
|
2359
|
+
const response = await transport.requestJson("POST", `${collectionPath(collection)}/search/multi/ids`, {
|
|
2360
|
+
vectors: formattedVectors,
|
|
2361
|
+
top_k: options?.k ?? 10,
|
|
2362
|
+
strategy: options?.fusion ?? "rrf",
|
|
2363
|
+
rrf_k: options?.fusionParams?.k ?? 60,
|
|
2364
|
+
avg_weight: options?.fusionParams?.avgWeight,
|
|
2365
|
+
max_weight: options?.fusionParams?.maxWeight,
|
|
2366
|
+
hit_weight: options?.fusionParams?.hitWeight,
|
|
2367
|
+
dense_weight: options?.fusionParams?.denseWeight,
|
|
2368
|
+
sparse_weight: options?.fusionParams?.sparseWeight
|
|
2369
|
+
});
|
|
2370
|
+
throwOnError(response, `Collection '${collection}'`);
|
|
2371
|
+
return response.data?.results ?? [];
|
|
2372
|
+
}
|
|
2218
2373
|
async function sparseSearchNamed(transport, collection, query3, indexName, options) {
|
|
2219
2374
|
const body = {
|
|
2220
2375
|
sparse_vectors: { [indexName]: transport.sparseToRest(query3) },
|
|
@@ -2432,7 +2587,7 @@ async function query(transport, collection, queryString, params, options) {
|
|
|
2432
2587
|
);
|
|
2433
2588
|
throwOnError(response, `Collection '${collection}'`);
|
|
2434
2589
|
const rawData = response.data;
|
|
2435
|
-
if (rawData && Object.prototype.hasOwnProperty.call(rawData, "result")) {
|
|
2590
|
+
if (rawData != null && Object.prototype.hasOwnProperty.call(rawData, "result")) {
|
|
2436
2591
|
return {
|
|
2437
2592
|
result: rawData.result,
|
|
2438
2593
|
stats: {
|
|
@@ -2702,7 +2857,7 @@ async function streamInsert(transport, collection, docs) {
|
|
|
2702
2857
|
throw new BackpressureError();
|
|
2703
2858
|
}
|
|
2704
2859
|
if (!response.ok && response.status !== 202) {
|
|
2705
|
-
const data = await response
|
|
2860
|
+
const data = await safeJsonParse(response);
|
|
2706
2861
|
const errorPayload = transport.extractErrorPayload(data);
|
|
2707
2862
|
throw new VelesDBError(
|
|
2708
2863
|
errorPayload.message ?? `HTTP ${response.status}`,
|
|
@@ -2724,6 +2879,24 @@ async function streamInsert(transport, collection, docs) {
|
|
|
2724
2879
|
}
|
|
2725
2880
|
}
|
|
2726
2881
|
}
|
|
2882
|
+
async function enableStreaming(transport, collection, config) {
|
|
2883
|
+
const body = {};
|
|
2884
|
+
if (config?.bufferSize !== void 0) {
|
|
2885
|
+
body.buffer_size = config.bufferSize;
|
|
2886
|
+
}
|
|
2887
|
+
if (config?.batchSize !== void 0) {
|
|
2888
|
+
body.batch_size = config.batchSize;
|
|
2889
|
+
}
|
|
2890
|
+
if (config?.flushIntervalMs !== void 0) {
|
|
2891
|
+
body.flush_interval_ms = config.flushIntervalMs;
|
|
2892
|
+
}
|
|
2893
|
+
const response = await transport.requestJson(
|
|
2894
|
+
"POST",
|
|
2895
|
+
`${collectionPath(collection)}/stream/enable`,
|
|
2896
|
+
body
|
|
2897
|
+
);
|
|
2898
|
+
throwOnError(response);
|
|
2899
|
+
}
|
|
2727
2900
|
function requireSafeRangeId(restId) {
|
|
2728
2901
|
if (typeof restId === "string") {
|
|
2729
2902
|
throw new ValidationError(
|
|
@@ -2768,14 +2941,14 @@ async function streamUpsertPoints(transport, collection, docs) {
|
|
|
2768
2941
|
throw new BackpressureError();
|
|
2769
2942
|
}
|
|
2770
2943
|
if (!response.ok) {
|
|
2771
|
-
const data2 = await response
|
|
2944
|
+
const data2 = await safeJsonParse(response);
|
|
2772
2945
|
const errorPayload = transport.extractErrorPayload(data2);
|
|
2773
2946
|
throw new VelesDBError(
|
|
2774
2947
|
errorPayload.message ?? `HTTP ${response.status}`,
|
|
2775
2948
|
errorPayload.code ?? transport.mapStatusToErrorCode(response.status)
|
|
2776
2949
|
);
|
|
2777
2950
|
}
|
|
2778
|
-
const data = await response
|
|
2951
|
+
const data = await safeJsonParse(response);
|
|
2779
2952
|
return {
|
|
2780
2953
|
message: typeof data.message === "string" ? data.message : "Stream processed",
|
|
2781
2954
|
inserted: typeof data.inserted === "number" ? data.inserted : 0,
|
|
@@ -2860,6 +3033,10 @@ var RestBackend = class {
|
|
|
2860
3033
|
this.ensureInitialized();
|
|
2861
3034
|
return upsertBatch(buildCrudTransport(this.httpConfig), c, d);
|
|
2862
3035
|
}
|
|
3036
|
+
async upsertBatchRaw(c, d) {
|
|
3037
|
+
this.ensureInitialized();
|
|
3038
|
+
return upsertBatchRaw(buildRawBulkTransport(this.httpConfig), c, d, d[0]?.vector.length ?? 0);
|
|
3039
|
+
}
|
|
2863
3040
|
async delete(c, id) {
|
|
2864
3041
|
this.ensureInitialized();
|
|
2865
3042
|
return deletePoint(buildCrudTransport(this.httpConfig), c, id);
|
|
@@ -2962,6 +3139,10 @@ var RestBackend = class {
|
|
|
2962
3139
|
this.ensureInitialized();
|
|
2963
3140
|
return multiQuerySearch(buildSearchTransport(this.httpConfig), c, v, o);
|
|
2964
3141
|
}
|
|
3142
|
+
async multiQuerySearchIds(c, v, o) {
|
|
3143
|
+
this.ensureInitialized();
|
|
3144
|
+
return multiQuerySearchIds(buildSearchTransport(this.httpConfig), c, v, o);
|
|
3145
|
+
}
|
|
2965
3146
|
async searchIds(c, q, o) {
|
|
2966
3147
|
this.ensureInitialized();
|
|
2967
3148
|
return searchIds(buildSearchTransport(this.httpConfig), c, q, o);
|
|
@@ -3048,6 +3229,10 @@ var RestBackend = class {
|
|
|
3048
3229
|
this.ensureInitialized();
|
|
3049
3230
|
return trainPq(buildStreamingTransport(this.httpConfig), c, o);
|
|
3050
3231
|
}
|
|
3232
|
+
async enableStreaming(c, cfg) {
|
|
3233
|
+
this.ensureInitialized();
|
|
3234
|
+
return enableStreaming(buildStreamingTransport(this.httpConfig), c, cfg);
|
|
3235
|
+
}
|
|
3051
3236
|
async streamInsert(c, d) {
|
|
3052
3237
|
this.ensureInitialized();
|
|
3053
3238
|
return streamInsert(buildStreamingTransport(this.httpConfig), c, d);
|
|
@@ -3230,9 +3415,21 @@ function multiQuerySearch2(backend, collection, vectors, options) {
|
|
|
3230
3415
|
}
|
|
3231
3416
|
return backend.multiQuerySearch(collection, vectors, options);
|
|
3232
3417
|
}
|
|
3418
|
+
function multiQuerySearchIds2(backend, collection, vectors, options) {
|
|
3419
|
+
if (!Array.isArray(vectors) || vectors.length === 0) {
|
|
3420
|
+
throw new ValidationError("Vectors must be a non-empty array");
|
|
3421
|
+
}
|
|
3422
|
+
for (const v of vectors) {
|
|
3423
|
+
requireVector(v, "Each vector");
|
|
3424
|
+
}
|
|
3425
|
+
return backend.multiQuerySearchIds(collection, vectors, options);
|
|
3426
|
+
}
|
|
3233
3427
|
function trainPq2(backend, collection, options) {
|
|
3234
3428
|
return backend.trainPq(collection, options);
|
|
3235
3429
|
}
|
|
3430
|
+
function enableStreaming2(backend, collection, config) {
|
|
3431
|
+
return backend.enableStreaming(collection, config);
|
|
3432
|
+
}
|
|
3236
3433
|
function streamInsert2(backend, config, collection, docs) {
|
|
3237
3434
|
validateDocsBatch(docs, (doc) => {
|
|
3238
3435
|
validateDocument(doc, config);
|
|
@@ -3501,6 +3698,24 @@ var VelesDB = class {
|
|
|
3501
3698
|
});
|
|
3502
3699
|
await this.backend.upsertBatch(collection, docs);
|
|
3503
3700
|
}
|
|
3701
|
+
/**
|
|
3702
|
+
* Bulk upsert via the binary wire format (REST backend only).
|
|
3703
|
+
*
|
|
3704
|
+
* Encodes `(id, vector)` pairs into the deterministic VRB1 binary layout
|
|
3705
|
+
* and sends them as a single `application/octet-stream` request, avoiding
|
|
3706
|
+
* per-point JSON overhead. Payloads are not carried — use
|
|
3707
|
+
* {@link upsertBatch} when you need them. Throws a not-supported error on
|
|
3708
|
+
* the WASM backend.
|
|
3709
|
+
*
|
|
3710
|
+
* @returns the number of points the server reports as inserted.
|
|
3711
|
+
*/
|
|
3712
|
+
async upsertBatchRaw(collection, docs) {
|
|
3713
|
+
this.ensureInitialized();
|
|
3714
|
+
validateDocsBatch(docs, (doc) => {
|
|
3715
|
+
validateDocument(doc, this.config);
|
|
3716
|
+
});
|
|
3717
|
+
return this.backend.upsertBatchRaw(collection, docs);
|
|
3718
|
+
}
|
|
3504
3719
|
async delete(collection, id) {
|
|
3505
3720
|
this.ensureInitialized();
|
|
3506
3721
|
validateRestPointId(id, this.config);
|
|
@@ -3548,6 +3763,11 @@ var VelesDB = class {
|
|
|
3548
3763
|
this.ensureInitialized();
|
|
3549
3764
|
return multiQuerySearch2(this.backend, collection, vectors, options);
|
|
3550
3765
|
}
|
|
3766
|
+
/** Multi-query fusion search returning only IDs and scores (no payloads). */
|
|
3767
|
+
async multiQuerySearchIds(collection, vectors, options) {
|
|
3768
|
+
this.ensureInitialized();
|
|
3769
|
+
return multiQuerySearchIds2(this.backend, collection, vectors, options);
|
|
3770
|
+
}
|
|
3551
3771
|
/**
|
|
3552
3772
|
* Pure sparse search against a named sparse index.
|
|
3553
3773
|
*
|
|
@@ -3578,6 +3798,10 @@ var VelesDB = class {
|
|
|
3578
3798
|
this.ensureInitialized();
|
|
3579
3799
|
return trainPq2(this.backend, collection, options);
|
|
3580
3800
|
}
|
|
3801
|
+
async enableStreaming(collection, config) {
|
|
3802
|
+
this.ensureInitialized();
|
|
3803
|
+
return enableStreaming2(this.backend, collection, config);
|
|
3804
|
+
}
|
|
3581
3805
|
async streamInsert(collection, docs) {
|
|
3582
3806
|
this.ensureInitialized();
|
|
3583
3807
|
return streamInsert2(this.backend, this.config, collection, docs);
|
package/dist/index.mjs
CHANGED
|
@@ -43,6 +43,7 @@ var REST_CAPABILITIES = Object.freeze({
|
|
|
43
43
|
graphTraversal: true,
|
|
44
44
|
secondaryIndexes: true,
|
|
45
45
|
agentMemory: true,
|
|
46
|
+
enableStreaming: true,
|
|
46
47
|
streamInsert: true,
|
|
47
48
|
pqTraining: true,
|
|
48
49
|
velesqlQuery: true,
|
|
@@ -58,6 +59,7 @@ var WASM_CAPABILITIES = Object.freeze({
|
|
|
58
59
|
graphTraversal: false,
|
|
59
60
|
secondaryIndexes: false,
|
|
60
61
|
agentMemory: false,
|
|
62
|
+
enableStreaming: false,
|
|
61
63
|
streamInsert: false,
|
|
62
64
|
pqTraining: false,
|
|
63
65
|
velesqlQuery: false,
|
|
@@ -752,6 +754,9 @@ function validateCollectionName(name) {
|
|
|
752
754
|
);
|
|
753
755
|
}
|
|
754
756
|
}
|
|
757
|
+
async function safeJsonParse(response) {
|
|
758
|
+
return response.json().catch(() => ({}));
|
|
759
|
+
}
|
|
755
760
|
function toNumberArray(v) {
|
|
756
761
|
return v instanceof Float32Array ? Array.from(v) : v;
|
|
757
762
|
}
|
|
@@ -805,12 +810,18 @@ async function wasmScroll(_collection, _request) {
|
|
|
805
810
|
async function wasmTrainPq(_collection, _options) {
|
|
806
811
|
wasmNotSupported("PQ training");
|
|
807
812
|
}
|
|
813
|
+
async function wasmEnableStreaming(_collection, _config) {
|
|
814
|
+
wasmNotSupported("Streaming enable");
|
|
815
|
+
}
|
|
808
816
|
async function wasmStreamInsert(_collection, _docs) {
|
|
809
817
|
wasmNotSupported("Streaming insert");
|
|
810
818
|
}
|
|
811
819
|
async function wasmStreamUpsertPoints(_collection, _docs) {
|
|
812
820
|
wasmNotSupported("Streaming batch upsert");
|
|
813
821
|
}
|
|
822
|
+
async function wasmUpsertBatchRaw(_collection, _docs) {
|
|
823
|
+
wasmNotSupported("Binary bulk upsert (upsertBatchRaw)");
|
|
824
|
+
}
|
|
814
825
|
async function wasmCreateGraphCollection(_name, _config) {
|
|
815
826
|
wasmNotSupported("Graph collections");
|
|
816
827
|
}
|
|
@@ -826,6 +837,9 @@ async function wasmGetCollectionConfig(_collection) {
|
|
|
826
837
|
async function wasmSearchIds(_collection, _query, _options) {
|
|
827
838
|
wasmNotSupported("searchIds");
|
|
828
839
|
}
|
|
840
|
+
async function wasmMultiQuerySearchIds(_collection, _vectors, _options) {
|
|
841
|
+
wasmNotSupported("multiQuerySearchIds");
|
|
842
|
+
}
|
|
829
843
|
async function wasmStoreSemanticFact(_collection, _entry) {
|
|
830
844
|
wasmNotSupported("Agent memory");
|
|
831
845
|
}
|
|
@@ -1082,6 +1096,9 @@ var WasmBackend = class {
|
|
|
1082
1096
|
}
|
|
1083
1097
|
}
|
|
1084
1098
|
}
|
|
1099
|
+
async upsertBatchRaw(c, d) {
|
|
1100
|
+
return wasmUpsertBatchRaw(c, d);
|
|
1101
|
+
}
|
|
1085
1102
|
async delete(collectionName, id) {
|
|
1086
1103
|
this.ensureInitialized();
|
|
1087
1104
|
const collection = this.collections.get(collectionName);
|
|
@@ -1213,6 +1230,10 @@ var WasmBackend = class {
|
|
|
1213
1230
|
this.ensureInitialized();
|
|
1214
1231
|
return wasmTrainPq(c, o);
|
|
1215
1232
|
}
|
|
1233
|
+
async enableStreaming(c, cfg) {
|
|
1234
|
+
this.ensureInitialized();
|
|
1235
|
+
return wasmEnableStreaming(c, cfg);
|
|
1236
|
+
}
|
|
1216
1237
|
async streamInsert(c, d) {
|
|
1217
1238
|
this.ensureInitialized();
|
|
1218
1239
|
return wasmStreamInsert(c, d);
|
|
@@ -1241,6 +1262,10 @@ var WasmBackend = class {
|
|
|
1241
1262
|
this.ensureInitialized();
|
|
1242
1263
|
return wasmSearchIds(c, q, o);
|
|
1243
1264
|
}
|
|
1265
|
+
async multiQuerySearchIds(c, v, o) {
|
|
1266
|
+
this.ensureInitialized();
|
|
1267
|
+
return wasmMultiQuerySearchIds(c, v, o);
|
|
1268
|
+
}
|
|
1244
1269
|
async storeSemanticFact(c, e) {
|
|
1245
1270
|
this.ensureInitialized();
|
|
1246
1271
|
return wasmStoreSemanticFact(c, e);
|
|
@@ -1345,6 +1370,9 @@ var WasmBackend = class {
|
|
|
1345
1370
|
};
|
|
1346
1371
|
|
|
1347
1372
|
// src/backends/crud-backend.ts
|
|
1373
|
+
var RAW_BULK_HEADER_LEN = 16;
|
|
1374
|
+
var RAW_BULK_MAGIC = [86, 82, 66, 49];
|
|
1375
|
+
var RAW_BULK_ID_WIDTH = 8;
|
|
1348
1376
|
var U64_MAX = 18446744073709551615n;
|
|
1349
1377
|
function coerceDecimalStringId(id) {
|
|
1350
1378
|
if (!/^\d+$/.test(id)) return NaN;
|
|
@@ -1495,6 +1523,105 @@ async function flush(transport, collection) {
|
|
|
1495
1523
|
);
|
|
1496
1524
|
throwOnError(response, `Collection '${collection}'`);
|
|
1497
1525
|
}
|
|
1526
|
+
function encodeRawBulk(ids, vectors, dim) {
|
|
1527
|
+
const count = ids.length;
|
|
1528
|
+
if (vectors.length !== count) {
|
|
1529
|
+
throw new ValidationError(
|
|
1530
|
+
`encodeRawBulk: ids length (${count}) must match vectors length (${vectors.length})`
|
|
1531
|
+
);
|
|
1532
|
+
}
|
|
1533
|
+
const buf = new Uint8Array(RAW_BULK_HEADER_LEN + count * 8 + count * dim * 4);
|
|
1534
|
+
const view = new DataView(buf.buffer);
|
|
1535
|
+
buf.set(RAW_BULK_MAGIC, 0);
|
|
1536
|
+
view.setUint32(4, count, true);
|
|
1537
|
+
view.setUint32(8, dim, true);
|
|
1538
|
+
buf[12] = RAW_BULK_ID_WIDTH;
|
|
1539
|
+
writeIds(view, ids);
|
|
1540
|
+
writeVectors(view, vectors, dim, count);
|
|
1541
|
+
return buf;
|
|
1542
|
+
}
|
|
1543
|
+
function writeIds(view, ids) {
|
|
1544
|
+
let off = RAW_BULK_HEADER_LEN;
|
|
1545
|
+
for (const id of ids) {
|
|
1546
|
+
view.setBigUint64(off, BigInt(id), true);
|
|
1547
|
+
off += 8;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
function writeVectors(view, vectors, dim, count) {
|
|
1551
|
+
let off = RAW_BULK_HEADER_LEN + count * 8;
|
|
1552
|
+
for (const vec of vectors) {
|
|
1553
|
+
if (vec.length !== dim) {
|
|
1554
|
+
throw new ValidationError(
|
|
1555
|
+
`encodeRawBulk: vector length (${vec.length}) must match dim (${dim})`
|
|
1556
|
+
);
|
|
1557
|
+
}
|
|
1558
|
+
for (let i = 0; i < dim; i++) {
|
|
1559
|
+
view.setFloat32(off, vec[i] ?? 0, true);
|
|
1560
|
+
off += 4;
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
async function upsertBatchRaw(transport, collection, docs, dim) {
|
|
1565
|
+
const ids = docs.map((d) => coerceNumericId(d.id));
|
|
1566
|
+
const vectors = docs.map((d) => d.vector);
|
|
1567
|
+
const body = encodeRawBulk(ids, vectors, dim);
|
|
1568
|
+
return sendRawBulk(transport, collection, body);
|
|
1569
|
+
}
|
|
1570
|
+
function coerceNumericId(id) {
|
|
1571
|
+
const parsed = parseRestPointId(id);
|
|
1572
|
+
if (typeof parsed === "string") {
|
|
1573
|
+
throw new ValidationError(
|
|
1574
|
+
`upsertBatchRaw requires ids in the JS safe integer range; received: ${parsed}`
|
|
1575
|
+
);
|
|
1576
|
+
}
|
|
1577
|
+
return parsed;
|
|
1578
|
+
}
|
|
1579
|
+
async function sendRawBulk(transport, collection, body) {
|
|
1580
|
+
const url = `${transport.baseUrl}${collectionPath(collection)}/points/raw`;
|
|
1581
|
+
const headers = {
|
|
1582
|
+
"Content-Type": "application/octet-stream"
|
|
1583
|
+
};
|
|
1584
|
+
if (transport.apiKey) {
|
|
1585
|
+
headers["Authorization"] = `Bearer ${transport.apiKey}`;
|
|
1586
|
+
}
|
|
1587
|
+
const controller = new AbortController();
|
|
1588
|
+
const timeoutId = setTimeout(() => controller.abort(), transport.timeout);
|
|
1589
|
+
try {
|
|
1590
|
+
const response = await fetch(url, {
|
|
1591
|
+
method: "POST",
|
|
1592
|
+
headers,
|
|
1593
|
+
body,
|
|
1594
|
+
signal: controller.signal
|
|
1595
|
+
});
|
|
1596
|
+
clearTimeout(timeoutId);
|
|
1597
|
+
return await parseRawBulkResponse(response);
|
|
1598
|
+
} catch (error) {
|
|
1599
|
+
clearTimeout(timeoutId);
|
|
1600
|
+
throw wrapRawBulkError(error);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
async function parseRawBulkResponse(response) {
|
|
1604
|
+
const data = await safeJsonParse(response);
|
|
1605
|
+
if (!response.ok) {
|
|
1606
|
+
const code = typeof data.code === "string" ? data.code : `HTTP_${response.status}`;
|
|
1607
|
+
const message = typeof data.error === "string" ? data.error : `HTTP ${response.status}`;
|
|
1608
|
+
throw new VelesDBError(message, code);
|
|
1609
|
+
}
|
|
1610
|
+
return typeof data.count === "number" ? data.count : 0;
|
|
1611
|
+
}
|
|
1612
|
+
function wrapRawBulkError(error) {
|
|
1613
|
+
if (error instanceof VelesDBError) {
|
|
1614
|
+
return error;
|
|
1615
|
+
}
|
|
1616
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
1617
|
+
return new ConnectionError("Request timeout");
|
|
1618
|
+
}
|
|
1619
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1620
|
+
return new ConnectionError(
|
|
1621
|
+
`Raw bulk upsert failed: ${message}`,
|
|
1622
|
+
error instanceof Error ? error : void 0
|
|
1623
|
+
);
|
|
1624
|
+
}
|
|
1498
1625
|
|
|
1499
1626
|
// src/backends/rest-http.ts
|
|
1500
1627
|
var STATUS_ERROR_CODES = {
|
|
@@ -1565,7 +1692,7 @@ async function request(config, method, path, body) {
|
|
|
1565
1692
|
signal: controller.signal
|
|
1566
1693
|
});
|
|
1567
1694
|
clearTimeout(timeoutId);
|
|
1568
|
-
const data = await response
|
|
1695
|
+
const data = await safeJsonParse(response);
|
|
1569
1696
|
if (!response.ok) {
|
|
1570
1697
|
const ep = extractErrorPayload(data);
|
|
1571
1698
|
return { error: {
|
|
@@ -1589,6 +1716,13 @@ function buildCrudTransport(config) {
|
|
|
1589
1716
|
requestJson: (m, p, b) => request(config, m, p, b)
|
|
1590
1717
|
};
|
|
1591
1718
|
}
|
|
1719
|
+
function buildRawBulkTransport(config) {
|
|
1720
|
+
return {
|
|
1721
|
+
baseUrl: config.baseUrl,
|
|
1722
|
+
apiKey: config.apiKey,
|
|
1723
|
+
timeout: config.timeout
|
|
1724
|
+
};
|
|
1725
|
+
}
|
|
1592
1726
|
function buildSearchTransport(config) {
|
|
1593
1727
|
return {
|
|
1594
1728
|
requestJson: (m, p, b) => request(config, m, p, b),
|
|
@@ -2076,6 +2210,22 @@ async function multiQuerySearch(transport, collection, vectors, options) {
|
|
|
2076
2210
|
throwOnError(response, `Collection '${collection}'`);
|
|
2077
2211
|
return response.data?.results ?? [];
|
|
2078
2212
|
}
|
|
2213
|
+
async function multiQuerySearchIds(transport, collection, vectors, options) {
|
|
2214
|
+
const formattedVectors = vectors.map(toNumberArray);
|
|
2215
|
+
const response = await transport.requestJson("POST", `${collectionPath(collection)}/search/multi/ids`, {
|
|
2216
|
+
vectors: formattedVectors,
|
|
2217
|
+
top_k: options?.k ?? 10,
|
|
2218
|
+
strategy: options?.fusion ?? "rrf",
|
|
2219
|
+
rrf_k: options?.fusionParams?.k ?? 60,
|
|
2220
|
+
avg_weight: options?.fusionParams?.avgWeight,
|
|
2221
|
+
max_weight: options?.fusionParams?.maxWeight,
|
|
2222
|
+
hit_weight: options?.fusionParams?.hitWeight,
|
|
2223
|
+
dense_weight: options?.fusionParams?.denseWeight,
|
|
2224
|
+
sparse_weight: options?.fusionParams?.sparseWeight
|
|
2225
|
+
});
|
|
2226
|
+
throwOnError(response, `Collection '${collection}'`);
|
|
2227
|
+
return response.data?.results ?? [];
|
|
2228
|
+
}
|
|
2079
2229
|
async function sparseSearchNamed(transport, collection, query3, indexName, options) {
|
|
2080
2230
|
const body = {
|
|
2081
2231
|
sparse_vectors: { [indexName]: transport.sparseToRest(query3) },
|
|
@@ -2293,7 +2443,7 @@ async function query(transport, collection, queryString, params, options) {
|
|
|
2293
2443
|
);
|
|
2294
2444
|
throwOnError(response, `Collection '${collection}'`);
|
|
2295
2445
|
const rawData = response.data;
|
|
2296
|
-
if (rawData && Object.prototype.hasOwnProperty.call(rawData, "result")) {
|
|
2446
|
+
if (rawData != null && Object.prototype.hasOwnProperty.call(rawData, "result")) {
|
|
2297
2447
|
return {
|
|
2298
2448
|
result: rawData.result,
|
|
2299
2449
|
stats: {
|
|
@@ -2563,7 +2713,7 @@ async function streamInsert(transport, collection, docs) {
|
|
|
2563
2713
|
throw new BackpressureError();
|
|
2564
2714
|
}
|
|
2565
2715
|
if (!response.ok && response.status !== 202) {
|
|
2566
|
-
const data = await response
|
|
2716
|
+
const data = await safeJsonParse(response);
|
|
2567
2717
|
const errorPayload = transport.extractErrorPayload(data);
|
|
2568
2718
|
throw new VelesDBError(
|
|
2569
2719
|
errorPayload.message ?? `HTTP ${response.status}`,
|
|
@@ -2585,6 +2735,24 @@ async function streamInsert(transport, collection, docs) {
|
|
|
2585
2735
|
}
|
|
2586
2736
|
}
|
|
2587
2737
|
}
|
|
2738
|
+
async function enableStreaming(transport, collection, config) {
|
|
2739
|
+
const body = {};
|
|
2740
|
+
if (config?.bufferSize !== void 0) {
|
|
2741
|
+
body.buffer_size = config.bufferSize;
|
|
2742
|
+
}
|
|
2743
|
+
if (config?.batchSize !== void 0) {
|
|
2744
|
+
body.batch_size = config.batchSize;
|
|
2745
|
+
}
|
|
2746
|
+
if (config?.flushIntervalMs !== void 0) {
|
|
2747
|
+
body.flush_interval_ms = config.flushIntervalMs;
|
|
2748
|
+
}
|
|
2749
|
+
const response = await transport.requestJson(
|
|
2750
|
+
"POST",
|
|
2751
|
+
`${collectionPath(collection)}/stream/enable`,
|
|
2752
|
+
body
|
|
2753
|
+
);
|
|
2754
|
+
throwOnError(response);
|
|
2755
|
+
}
|
|
2588
2756
|
function requireSafeRangeId(restId) {
|
|
2589
2757
|
if (typeof restId === "string") {
|
|
2590
2758
|
throw new ValidationError(
|
|
@@ -2629,14 +2797,14 @@ async function streamUpsertPoints(transport, collection, docs) {
|
|
|
2629
2797
|
throw new BackpressureError();
|
|
2630
2798
|
}
|
|
2631
2799
|
if (!response.ok) {
|
|
2632
|
-
const data2 = await response
|
|
2800
|
+
const data2 = await safeJsonParse(response);
|
|
2633
2801
|
const errorPayload = transport.extractErrorPayload(data2);
|
|
2634
2802
|
throw new VelesDBError(
|
|
2635
2803
|
errorPayload.message ?? `HTTP ${response.status}`,
|
|
2636
2804
|
errorPayload.code ?? transport.mapStatusToErrorCode(response.status)
|
|
2637
2805
|
);
|
|
2638
2806
|
}
|
|
2639
|
-
const data = await response
|
|
2807
|
+
const data = await safeJsonParse(response);
|
|
2640
2808
|
return {
|
|
2641
2809
|
message: typeof data.message === "string" ? data.message : "Stream processed",
|
|
2642
2810
|
inserted: typeof data.inserted === "number" ? data.inserted : 0,
|
|
@@ -2721,6 +2889,10 @@ var RestBackend = class {
|
|
|
2721
2889
|
this.ensureInitialized();
|
|
2722
2890
|
return upsertBatch(buildCrudTransport(this.httpConfig), c, d);
|
|
2723
2891
|
}
|
|
2892
|
+
async upsertBatchRaw(c, d) {
|
|
2893
|
+
this.ensureInitialized();
|
|
2894
|
+
return upsertBatchRaw(buildRawBulkTransport(this.httpConfig), c, d, d[0]?.vector.length ?? 0);
|
|
2895
|
+
}
|
|
2724
2896
|
async delete(c, id) {
|
|
2725
2897
|
this.ensureInitialized();
|
|
2726
2898
|
return deletePoint(buildCrudTransport(this.httpConfig), c, id);
|
|
@@ -2823,6 +2995,10 @@ var RestBackend = class {
|
|
|
2823
2995
|
this.ensureInitialized();
|
|
2824
2996
|
return multiQuerySearch(buildSearchTransport(this.httpConfig), c, v, o);
|
|
2825
2997
|
}
|
|
2998
|
+
async multiQuerySearchIds(c, v, o) {
|
|
2999
|
+
this.ensureInitialized();
|
|
3000
|
+
return multiQuerySearchIds(buildSearchTransport(this.httpConfig), c, v, o);
|
|
3001
|
+
}
|
|
2826
3002
|
async searchIds(c, q, o) {
|
|
2827
3003
|
this.ensureInitialized();
|
|
2828
3004
|
return searchIds(buildSearchTransport(this.httpConfig), c, q, o);
|
|
@@ -2909,6 +3085,10 @@ var RestBackend = class {
|
|
|
2909
3085
|
this.ensureInitialized();
|
|
2910
3086
|
return trainPq(buildStreamingTransport(this.httpConfig), c, o);
|
|
2911
3087
|
}
|
|
3088
|
+
async enableStreaming(c, cfg) {
|
|
3089
|
+
this.ensureInitialized();
|
|
3090
|
+
return enableStreaming(buildStreamingTransport(this.httpConfig), c, cfg);
|
|
3091
|
+
}
|
|
2912
3092
|
async streamInsert(c, d) {
|
|
2913
3093
|
this.ensureInitialized();
|
|
2914
3094
|
return streamInsert(buildStreamingTransport(this.httpConfig), c, d);
|
|
@@ -3091,9 +3271,21 @@ function multiQuerySearch2(backend, collection, vectors, options) {
|
|
|
3091
3271
|
}
|
|
3092
3272
|
return backend.multiQuerySearch(collection, vectors, options);
|
|
3093
3273
|
}
|
|
3274
|
+
function multiQuerySearchIds2(backend, collection, vectors, options) {
|
|
3275
|
+
if (!Array.isArray(vectors) || vectors.length === 0) {
|
|
3276
|
+
throw new ValidationError("Vectors must be a non-empty array");
|
|
3277
|
+
}
|
|
3278
|
+
for (const v of vectors) {
|
|
3279
|
+
requireVector(v, "Each vector");
|
|
3280
|
+
}
|
|
3281
|
+
return backend.multiQuerySearchIds(collection, vectors, options);
|
|
3282
|
+
}
|
|
3094
3283
|
function trainPq2(backend, collection, options) {
|
|
3095
3284
|
return backend.trainPq(collection, options);
|
|
3096
3285
|
}
|
|
3286
|
+
function enableStreaming2(backend, collection, config) {
|
|
3287
|
+
return backend.enableStreaming(collection, config);
|
|
3288
|
+
}
|
|
3097
3289
|
function streamInsert2(backend, config, collection, docs) {
|
|
3098
3290
|
validateDocsBatch(docs, (doc) => {
|
|
3099
3291
|
validateDocument(doc, config);
|
|
@@ -3362,6 +3554,24 @@ var VelesDB = class {
|
|
|
3362
3554
|
});
|
|
3363
3555
|
await this.backend.upsertBatch(collection, docs);
|
|
3364
3556
|
}
|
|
3557
|
+
/**
|
|
3558
|
+
* Bulk upsert via the binary wire format (REST backend only).
|
|
3559
|
+
*
|
|
3560
|
+
* Encodes `(id, vector)` pairs into the deterministic VRB1 binary layout
|
|
3561
|
+
* and sends them as a single `application/octet-stream` request, avoiding
|
|
3562
|
+
* per-point JSON overhead. Payloads are not carried — use
|
|
3563
|
+
* {@link upsertBatch} when you need them. Throws a not-supported error on
|
|
3564
|
+
* the WASM backend.
|
|
3565
|
+
*
|
|
3566
|
+
* @returns the number of points the server reports as inserted.
|
|
3567
|
+
*/
|
|
3568
|
+
async upsertBatchRaw(collection, docs) {
|
|
3569
|
+
this.ensureInitialized();
|
|
3570
|
+
validateDocsBatch(docs, (doc) => {
|
|
3571
|
+
validateDocument(doc, this.config);
|
|
3572
|
+
});
|
|
3573
|
+
return this.backend.upsertBatchRaw(collection, docs);
|
|
3574
|
+
}
|
|
3365
3575
|
async delete(collection, id) {
|
|
3366
3576
|
this.ensureInitialized();
|
|
3367
3577
|
validateRestPointId(id, this.config);
|
|
@@ -3409,6 +3619,11 @@ var VelesDB = class {
|
|
|
3409
3619
|
this.ensureInitialized();
|
|
3410
3620
|
return multiQuerySearch2(this.backend, collection, vectors, options);
|
|
3411
3621
|
}
|
|
3622
|
+
/** Multi-query fusion search returning only IDs and scores (no payloads). */
|
|
3623
|
+
async multiQuerySearchIds(collection, vectors, options) {
|
|
3624
|
+
this.ensureInitialized();
|
|
3625
|
+
return multiQuerySearchIds2(this.backend, collection, vectors, options);
|
|
3626
|
+
}
|
|
3412
3627
|
/**
|
|
3413
3628
|
* Pure sparse search against a named sparse index.
|
|
3414
3629
|
*
|
|
@@ -3439,6 +3654,10 @@ var VelesDB = class {
|
|
|
3439
3654
|
this.ensureInitialized();
|
|
3440
3655
|
return trainPq2(this.backend, collection, options);
|
|
3441
3656
|
}
|
|
3657
|
+
async enableStreaming(collection, config) {
|
|
3658
|
+
this.ensureInitialized();
|
|
3659
|
+
return enableStreaming2(this.backend, collection, config);
|
|
3660
|
+
}
|
|
3442
3661
|
async streamInsert(collection, docs) {
|
|
3443
3662
|
this.ensureInitialized();
|
|
3444
3663
|
return streamInsert2(this.backend, this.config, collection, docs);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wiscale/velesdb-sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "VelesDB TypeScript SDK: The Local Vector Database for AI & RAG. Microsecond semantic search in Browser & Node.js.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -69,12 +69,13 @@
|
|
|
69
69
|
"vitest": "^4.0.16"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@wiscale/velesdb-wasm": "^
|
|
72
|
+
"@wiscale/velesdb-wasm": "^2.0.0"
|
|
73
73
|
},
|
|
74
74
|
"engines": {
|
|
75
75
|
"node": ">=18.0.0"
|
|
76
76
|
},
|
|
77
77
|
"overrides": {
|
|
78
|
-
"minimatch": "^9.0.7"
|
|
78
|
+
"minimatch": "^9.0.7",
|
|
79
|
+
"esbuild": ">=0.28.1"
|
|
79
80
|
}
|
|
80
81
|
}
|