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 +117 -0
- package/dist/client.d.ts +50 -0
- package/dist/client.js +241 -0
- package/dist/proto/hyperspace_grpc_pb.js +482 -0
- package/dist/proto/hyperspace_pb.js +7424 -0
- package/package.json +32 -0
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
|
+
|
package/dist/client.d.ts
ADDED
|
@@ -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;
|