hyperspace-sdk-ts 2.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 ADDED
@@ -0,0 +1,117 @@
1
+ # HyperspaceDB TypeScript SDK
2
+
3
+ Official TypeScript client for HyperspaceDB gRPC API.
4
+
5
+ Use this SDK for:
6
+ - collection lifecycle management
7
+ - vector insert and search
8
+ - high-throughput batched search (`searchBatch`)
9
+ - bulk insertion (`batchInsert`)
10
+ - advanced filtering and hybrid search
11
+ - multi-tenant authentication headers (`x-api-key`, `x-hyperspace-user-id`)
12
+
13
+ ## Requirements
14
+
15
+ - Node.js 18+
16
+ - Running HyperspaceDB server (default gRPC endpoint: `localhost:50051`)
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install hyperspace-sdk-ts
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ```ts
27
+ import { HyperspaceClient } from "hyperspace-sdk-ts";
28
+
29
+ async function main() {
30
+ const client = new HyperspaceClient("localhost:50051", "I_LOVE_HYPERSPACEDB");
31
+ const collection = "docs_ts";
32
+
33
+ await client.deleteCollection(collection).catch(() => {});
34
+ await client.createCollection(collection, 3, "cosine");
35
+
36
+ await client.insert(1, [0.1, 0.2, 0.3], { source: "demo" }, collection);
37
+ await client.insert(2, [0.2, 0.1, 0.4], { source: "demo" }, collection);
38
+
39
+ const results = await client.search([0.1, 0.2, 0.3], 5, collection);
40
+ console.log(results);
41
+
42
+ client.close();
43
+ }
44
+
45
+ main().catch(console.error);
46
+ ```
47
+
48
+ ## API Overview
49
+
50
+ ### `new HyperspaceClient(host?, apiKey?, userId?)`
51
+
52
+ - `host`: gRPC endpoint, default `localhost:50051`
53
+ - `apiKey`: optional API key
54
+ - `userId`: optional tenant/user ID
55
+
56
+ ### `createCollection(name, dimension, metric)`
57
+
58
+ Create a new collection.
59
+
60
+ - `metric`: `"l2" | "cosine" | "poincare"`
61
+
62
+ ### `deleteCollection(name)`
63
+
64
+ Delete collection and all its data.
65
+
66
+ ### `insert(id, vector, meta?, collection?, durability?)`
67
+
68
+ Insert one vector. Accepts `number[]`, `Float32Array`, `Float64Array`.
69
+
70
+ ### `batchInsert(items, collection?, durability?)`
71
+
72
+ Efficient bulk insertion.
73
+ ```ts
74
+ await client.batchInsert([
75
+ { id: 10, vector: [0.1, 0.1, 0.1], metadata: { tag: "a" } },
76
+ { id: 11, vector: [0.2, 0.2, 0.2], metadata: { tag: "b" } }
77
+ ], "my_collection");
78
+ ```
79
+
80
+ ### `search(vector, topK, collection?, options?)`
81
+
82
+ Run nearest-neighbor search.
83
+ Options include `filters`, `hybridQuery`, and `hybridAlpha`.
84
+
85
+ ```ts
86
+ const results = await client.search(vector, 10, "coll", {
87
+ filters: [
88
+ { match: { key: "category", value: "electronics" } },
89
+ { range: { key: "price", gte: 100, lte: 500 } }
90
+ ],
91
+ hybridQuery: "latest smartphone",
92
+ hybridAlpha: 0.5
93
+ });
94
+ ```
95
+
96
+ ### `searchBatch(vectors, topK, collection?)`
97
+
98
+ Run multiple searches in one gRPC request to reduce RPC overhead.
99
+
100
+ ### `getDigest(collection?)`
101
+
102
+ Retrieve collection stats and logical clock.
103
+
104
+ ### `close()`
105
+
106
+ Close underlying gRPC channel.
107
+
108
+ ## Performance Notes
109
+
110
+ - Prefer `searchBatch` and `batchInsert` for throughput-heavy services.
111
+ - Reuse one client instance per process or worker.
112
+
113
+ ## Error Handling
114
+
115
+ All methods reject on transport/protocol errors. Targets gRPC data plane operations.
116
+ For control plane endpoints (`/api/*`), use regular HTTP requests to the server's HTTP port.
117
+
@@ -0,0 +1,50 @@
1
+ import { DurabilityLevel } from './proto/hyperspace_pb';
2
+ export { DurabilityLevel };
3
+ export interface Filter {
4
+ match?: {
5
+ key: string;
6
+ value: string;
7
+ };
8
+ range?: {
9
+ key: string;
10
+ gte?: number;
11
+ lte?: number;
12
+ };
13
+ }
14
+ export interface SearchResult {
15
+ id: number;
16
+ distance: number;
17
+ metadata: {
18
+ [key: string]: string;
19
+ };
20
+ }
21
+ export declare class HyperspaceClient {
22
+ private client;
23
+ private metadata;
24
+ private static toVectorList;
25
+ constructor(host?: string, apiKey?: string, userId?: string);
26
+ createCollection(name: string, dimension: number, metric: string): Promise<boolean>;
27
+ deleteCollection(name: string): Promise<boolean>;
28
+ insert(id: number, vector: number[] | Float32Array | Float64Array, meta?: {
29
+ [key: string]: string;
30
+ }, collection?: string, durability?: DurabilityLevel): Promise<boolean>;
31
+ batchInsert(items: {
32
+ id: number;
33
+ vector: number[] | Float32Array | Float64Array;
34
+ metadata?: {
35
+ [key: string]: string;
36
+ };
37
+ }[], collection?: string, durability?: DurabilityLevel): Promise<boolean>;
38
+ search(vector: number[] | Float32Array | Float64Array, topK: number, collection?: string, options?: {
39
+ filters?: Filter[];
40
+ hybridQuery?: string;
41
+ hybridAlpha?: number;
42
+ }): Promise<SearchResult[]>;
43
+ searchBatch(vectors: Array<number[] | Float32Array | Float64Array>, topK: number, collection?: string): Promise<SearchResult[][]>;
44
+ getDigest(collection?: string): Promise<{
45
+ logicalClock: number;
46
+ stateHash: number;
47
+ count: number;
48
+ }>;
49
+ close(): void;
50
+ }
package/dist/client.js ADDED
@@ -0,0 +1,241 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.HyperspaceClient = exports.DurabilityLevel = void 0;
37
+ const grpc = __importStar(require("@grpc/grpc-js"));
38
+ const hyperspace_grpc_pb_1 = require("./proto/hyperspace_grpc_pb");
39
+ const hyperspace_pb_1 = require("./proto/hyperspace_pb");
40
+ Object.defineProperty(exports, "DurabilityLevel", { enumerable: true, get: function () { return hyperspace_pb_1.DurabilityLevel; } });
41
+ const hyperspace_pb = __importStar(require("./proto/hyperspace_pb")); // New, for direct access to types
42
+ class HyperspaceClient {
43
+ static toVectorList(vector) {
44
+ if (Array.isArray(vector)) {
45
+ return vector;
46
+ }
47
+ return Array.from(vector);
48
+ }
49
+ constructor(host = 'localhost:50051', apiKey, userId) {
50
+ const options = {
51
+ 'grpc.max_send_message_length': 64 * 1024 * 1024,
52
+ 'grpc.max_receive_message_length': 64 * 1024 * 1024,
53
+ 'grpc.keepalive_time_ms': 10000,
54
+ 'grpc.keepalive_timeout_ms': 5000,
55
+ 'grpc.keepalive_permit_without_calls': 1,
56
+ 'grpc.http2.min_time_between_pings_ms': 10000,
57
+ 'grpc.http2.min_ping_interval_without_data_ms': 5000,
58
+ };
59
+ this.client = new hyperspace_grpc_pb_1.DatabaseClient(host, grpc.credentials.createInsecure(), options);
60
+ this.metadata = new grpc.Metadata();
61
+ if (apiKey) {
62
+ this.metadata.add('x-api-key', apiKey);
63
+ }
64
+ if (userId) {
65
+ this.metadata.add('x-hyperspace-user-id', userId);
66
+ }
67
+ }
68
+ // ... (create/delete unchanged) ...
69
+ createCollection(name, dimension, metric) {
70
+ return new Promise((resolve, reject) => {
71
+ const req = new hyperspace_pb_1.CreateCollectionRequest();
72
+ req.setName(name);
73
+ req.setDimension(dimension);
74
+ req.setMetric(metric);
75
+ this.client.createCollection(req, this.metadata, (err, resp) => {
76
+ if (err)
77
+ return reject(err);
78
+ resolve(true);
79
+ });
80
+ });
81
+ }
82
+ deleteCollection(name) {
83
+ return new Promise((resolve, reject) => {
84
+ const req = new hyperspace_pb_1.DeleteCollectionRequest();
85
+ req.setName(name);
86
+ this.client.deleteCollection(req, this.metadata, (err, resp) => {
87
+ if (err)
88
+ return reject(err);
89
+ resolve(true);
90
+ });
91
+ });
92
+ }
93
+ insert(id, vector, meta, collection = '', durability = hyperspace_pb_1.DurabilityLevel.DEFAULT_LEVEL) {
94
+ return new Promise((resolve, reject) => {
95
+ const req = new hyperspace_pb_1.InsertRequest();
96
+ req.setId(id);
97
+ req.setVectorList(HyperspaceClient.toVectorList(vector));
98
+ if (meta) {
99
+ const map = req.getMetadataMap();
100
+ for (const k in meta)
101
+ map.set(k, meta[k]);
102
+ }
103
+ req.setCollection(collection);
104
+ req.setOriginNodeId('');
105
+ req.setLogicalClock(0);
106
+ req.setDurability(durability);
107
+ this.client.insert(req, this.metadata, (err, resp) => {
108
+ if (err)
109
+ return reject(err);
110
+ resolve(resp.getSuccess());
111
+ });
112
+ });
113
+ }
114
+ batchInsert(items, collection = '', durability = hyperspace_pb_1.DurabilityLevel.DEFAULT_LEVEL) {
115
+ return new Promise((resolve, reject) => {
116
+ const req = new hyperspace_pb_1.BatchInsertRequest();
117
+ req.setCollection(collection);
118
+ req.setDurability(durability);
119
+ const vectors = items.map(item => {
120
+ const v = new hyperspace_pb_1.VectorData();
121
+ v.setId(item.id);
122
+ v.setVectorList(HyperspaceClient.toVectorList(item.vector));
123
+ if (item.metadata) {
124
+ const map = v.getMetadataMap();
125
+ for (const k in item.metadata)
126
+ map.set(k, item.metadata[k]);
127
+ }
128
+ return v;
129
+ });
130
+ req.setVectorsList(vectors);
131
+ this.client.batchInsert(req, this.metadata, (err, resp) => {
132
+ if (err)
133
+ return reject(err);
134
+ resolve(resp.getSuccess());
135
+ });
136
+ });
137
+ }
138
+ search(vector, topK, collection = '', options) {
139
+ return new Promise((resolve, reject) => {
140
+ const req = new hyperspace_pb_1.SearchRequest();
141
+ req.setVectorList(HyperspaceClient.toVectorList(vector));
142
+ req.setTopK(topK);
143
+ req.setCollection(collection);
144
+ if (options === null || options === void 0 ? void 0 : options.filters) {
145
+ const protoFilters = options.filters.map(f => {
146
+ const pf = new hyperspace_pb.Filter();
147
+ if (f.match) {
148
+ const m = new hyperspace_pb.Match();
149
+ m.setKey(f.match.key);
150
+ m.setValue(f.match.value);
151
+ pf.setMatch(m);
152
+ }
153
+ else if (f.range) {
154
+ const r = new hyperspace_pb.Range();
155
+ r.setKey(f.range.key);
156
+ if (f.range.gte !== undefined)
157
+ r.setGte(f.range.gte);
158
+ if (f.range.lte !== undefined)
159
+ r.setLte(f.range.lte);
160
+ pf.setRange(r);
161
+ }
162
+ return pf;
163
+ });
164
+ req.setFiltersList(protoFilters);
165
+ }
166
+ if (options === null || options === void 0 ? void 0 : options.hybridQuery)
167
+ req.setHybridQuery(options.hybridQuery);
168
+ if ((options === null || options === void 0 ? void 0 : options.hybridAlpha) !== undefined)
169
+ req.setHybridAlpha(options.hybridAlpha);
170
+ this.client.search(req, this.metadata, (err, resp) => {
171
+ if (err)
172
+ return reject(err);
173
+ const results = resp.getResultsList().map(r => {
174
+ const metaMap = r.getMetadataMap();
175
+ const meta = {};
176
+ if (metaMap.getLength() > 0) {
177
+ metaMap.forEach((entry, key) => {
178
+ meta[key] = entry;
179
+ });
180
+ }
181
+ return {
182
+ id: r.getId(),
183
+ distance: r.getDistance(),
184
+ metadata: meta
185
+ };
186
+ });
187
+ resolve(results);
188
+ });
189
+ });
190
+ }
191
+ searchBatch(vectors, topK, collection = '') {
192
+ return new Promise((resolve, reject) => {
193
+ const req = new hyperspace_pb_1.BatchSearchRequest();
194
+ req.setSearchesList(vectors.map((vector) => {
195
+ const s = new hyperspace_pb_1.SearchRequest();
196
+ s.setVectorList(HyperspaceClient.toVectorList(vector));
197
+ s.setTopK(topK);
198
+ s.setCollection(collection);
199
+ return s;
200
+ }));
201
+ this.client.searchBatch(req, this.metadata, (err, resp) => {
202
+ if (err)
203
+ return reject(err);
204
+ const batch = resp.getResponsesList().map((searchResp) => searchResp.getResultsList().map((r) => {
205
+ const metaMap = r.getMetadataMap();
206
+ const meta = {};
207
+ if (metaMap.getLength() > 0) {
208
+ metaMap.forEach((entry, key) => {
209
+ meta[key] = entry;
210
+ });
211
+ }
212
+ return {
213
+ id: r.getId(),
214
+ distance: r.getDistance(),
215
+ metadata: meta
216
+ };
217
+ }));
218
+ resolve(batch);
219
+ });
220
+ });
221
+ }
222
+ getDigest(collection = '') {
223
+ return new Promise((resolve, reject) => {
224
+ const req = new hyperspace_pb.DigestRequest();
225
+ req.setCollection(collection);
226
+ this.client.getDigest(req, this.metadata, (err, resp) => {
227
+ if (err)
228
+ return reject(err);
229
+ resolve({
230
+ logicalClock: resp.getLogicalClock(),
231
+ stateHash: resp.getStateHash(),
232
+ count: resp.getCount()
233
+ });
234
+ });
235
+ });
236
+ }
237
+ close() {
238
+ this.client.close();
239
+ }
240
+ }
241
+ exports.HyperspaceClient = HyperspaceClient;