hyperspace-sdk-ts 2.0.0 → 2.2.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # HyperspaceDB TypeScript SDK
2
2
 
3
- Official TypeScript client for HyperspaceDB gRPC API.
3
+ Official TypeScript client for HyperspaceDB gRPC API (v2.2.1).
4
4
 
5
5
  Use this SDK for:
6
6
  - collection lifecycle management
@@ -8,6 +8,9 @@ Use this SDK for:
8
8
  - high-throughput batched search (`searchBatch`)
9
9
  - bulk insertion (`batchInsert`)
10
10
  - advanced filtering and hybrid search
11
+ - typed metadata (`string | number | boolean`)
12
+ - graph traversal APIs (`getNode`, `getNeighbors`, `getConceptParents`, `traverse`, `findSemanticClusters`)
13
+ - rebuild with metadata pruning (`rebuildIndexWithFilter`)
11
14
  - multi-tenant authentication headers (`x-api-key`, `x-hyperspace-user-id`)
12
15
 
13
16
  ## Requirements
@@ -66,6 +69,7 @@ Delete collection and all its data.
66
69
  ### `insert(id, vector, meta?, collection?, durability?)`
67
70
 
68
71
  Insert one vector. Accepts `number[]`, `Float32Array`, `Float64Array`.
72
+ Optional `typedMetadata` supports typed values for range/boolean filters.
69
73
 
70
74
  ### `batchInsert(items, collection?, durability?)`
71
75
 
@@ -81,6 +85,7 @@ await client.batchInsert([
81
85
 
82
86
  Run nearest-neighbor search.
83
87
  Options include `filters`, `hybridQuery`, and `hybridAlpha`.
88
+ Decimal range values are supported and sent as `gte_f64/lte_f64` in gRPC payload.
84
89
 
85
90
  ```ts
86
91
  const results = await client.search(vector, 10, "coll", {
@@ -105,6 +110,50 @@ Retrieve collection stats and logical clock.
105
110
 
106
111
  Close underlying gRPC channel.
107
112
 
113
+ ### `subscribeToEvents(options, onEvent, onError?)`
114
+
115
+ Subscribe to CDC stream events from server:
116
+
117
+ ```ts
118
+ const stream = client.subscribeToEvents(
119
+ { types: ["insert", "delete"], collection: "docs_ts" },
120
+ (event) => console.log("event:", event.toObject()),
121
+ (err) => console.error(err),
122
+ );
123
+ ```
124
+
125
+ ### `rebuildIndex(collection)`
126
+
127
+ Trigger index rebuild/vacuum for a collection.
128
+
129
+ ### `rebuildIndexWithFilter(collection, filter)`
130
+
131
+ Rebuild with metadata pruning for sleep/reconsolidation workflows.
132
+
133
+ ```ts
134
+ await client.rebuildIndexWithFilter("docs_ts", {
135
+ key: "energy",
136
+ op: "lt",
137
+ value: 0.1,
138
+ });
139
+ ```
140
+
141
+ ### `HyperbolicMath`
142
+
143
+ ```ts
144
+ import { HyperbolicMath } from "hyperspace-sdk-ts";
145
+
146
+ const z = HyperbolicMath.mobiusAdd([0.1, 0.0], [0.2, 0.0]);
147
+ ```
148
+
149
+ Provided utilities:
150
+ - `mobiusAdd(x, y, c?)`
151
+ - `expMap(x, v, c?)`
152
+ - `logMap(x, y, c?)`
153
+ - `riemannianGradient(x, euclideanGrad, c?)`
154
+ - `parallelTransport(x, y, v, c?)`
155
+ - `frechetMean(points, c?, maxIter?, tol?)`
156
+
108
157
  ## Performance Notes
109
158
 
110
159
  - Prefer `searchBatch` and `batchInsert` for throughput-heavy services.
package/dist/client.d.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { DurabilityLevel } from './proto/hyperspace_pb';
1
+ import * as grpc from '@grpc/grpc-js';
2
+ import { DurabilityLevel, EventMessage } from './proto/hyperspace_pb';
2
3
  export { DurabilityLevel };
4
+ export type TypedMetadataValue = string | number | boolean;
3
5
  export interface Filter {
4
6
  match?: {
5
7
  key: string;
@@ -17,23 +19,63 @@ export interface SearchResult {
17
19
  metadata: {
18
20
  [key: string]: string;
19
21
  };
22
+ typedMetadata: {
23
+ [key: string]: TypedMetadataValue;
24
+ };
25
+ }
26
+ export interface GraphNode {
27
+ id: number;
28
+ layer: number;
29
+ neighbors: number[];
30
+ metadata: {
31
+ [key: string]: string;
32
+ };
33
+ typedMetadata: {
34
+ [key: string]: TypedMetadataValue;
35
+ };
20
36
  }
37
+ export interface VacuumFilter {
38
+ key: string;
39
+ op: 'lt' | 'lte' | 'gt' | 'gte' | 'eq' | 'ne';
40
+ value: number;
41
+ }
42
+ export type EventTypeName = 'insert' | 'delete';
43
+ export interface SubscribeOptions {
44
+ types?: EventTypeName[];
45
+ collection?: string;
46
+ }
47
+ export declare const HyperbolicMath: {
48
+ projectToBall(x: number[], c?: number): number[];
49
+ mobiusAdd(x: number[], y: number[], c?: number): number[];
50
+ expMap(x: number[], v: number[], c?: number): number[];
51
+ logMap(x: number[], y: number[], c?: number): number[];
52
+ riemannianGradient(x: number[], euclideanGrad: number[], c?: number): number[];
53
+ parallelTransport(x: number[], y: number[], v: number[], c?: number): number[];
54
+ frechetMean(points: number[][], c?: number, maxIter?: number, tol?: number): number[];
55
+ };
21
56
  export declare class HyperspaceClient {
22
57
  private client;
23
58
  private metadata;
24
59
  private static toVectorList;
60
+ private static toProtoMetadataValue;
61
+ private static parseTypedMetadata;
25
62
  constructor(host?: string, apiKey?: string, userId?: string);
26
63
  createCollection(name: string, dimension: number, metric: string): Promise<boolean>;
27
64
  deleteCollection(name: string): Promise<boolean>;
28
65
  insert(id: number, vector: number[] | Float32Array | Float64Array, meta?: {
29
66
  [key: string]: string;
30
- }, collection?: string, durability?: DurabilityLevel): Promise<boolean>;
67
+ }, collection?: string, durability?: DurabilityLevel, typedMetadata?: {
68
+ [key: string]: TypedMetadataValue;
69
+ }): Promise<boolean>;
31
70
  batchInsert(items: {
32
71
  id: number;
33
72
  vector: number[] | Float32Array | Float64Array;
34
73
  metadata?: {
35
74
  [key: string]: string;
36
75
  };
76
+ typedMetadata?: {
77
+ [key: string]: TypedMetadataValue;
78
+ };
37
79
  }[], collection?: string, durability?: DurabilityLevel): Promise<boolean>;
38
80
  search(vector: number[] | Float32Array | Float64Array, topK: number, collection?: string, options?: {
39
81
  filters?: Filter[];
@@ -46,5 +88,18 @@ export declare class HyperspaceClient {
46
88
  stateHash: number;
47
89
  count: number;
48
90
  }>;
91
+ rebuildIndex(collection: string): Promise<boolean>;
92
+ rebuildIndexWithFilter(collection: string, filter: VacuumFilter): Promise<boolean>;
93
+ getNode(id: number, layer?: number, collection?: string): Promise<GraphNode>;
94
+ getNeighbors(id: number, layer?: number, limit?: number, offset?: number, collection?: string): Promise<GraphNode[]>;
95
+ getConceptParents(id: number, layer?: number, limit?: number, collection?: string): Promise<GraphNode[]>;
96
+ traverse(startId: number, layer?: number, maxDepth?: number, maxNodes?: number, collection?: string, options?: {
97
+ filter?: {
98
+ [key: string]: string;
99
+ };
100
+ filters?: Filter[];
101
+ }): Promise<GraphNode[]>;
102
+ findSemanticClusters(layer?: number, minClusterSize?: number, maxClusters?: number, maxNodes?: number, collection?: string): Promise<number[][]>;
103
+ subscribeToEvents(options: SubscribeOptions, onEvent: (event: EventMessage) => void, onError?: (err: Error) => void): grpc.ClientReadableStream<EventMessage>;
49
104
  close(): void;
50
105
  }
package/dist/client.js CHANGED
@@ -33,12 +33,124 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.HyperspaceClient = exports.DurabilityLevel = void 0;
36
+ exports.HyperspaceClient = exports.HyperbolicMath = exports.DurabilityLevel = void 0;
37
37
  const grpc = __importStar(require("@grpc/grpc-js"));
38
38
  const hyperspace_grpc_pb_1 = require("./proto/hyperspace_grpc_pb");
39
39
  const hyperspace_pb_1 = require("./proto/hyperspace_pb");
40
40
  Object.defineProperty(exports, "DurabilityLevel", { enumerable: true, get: function () { return hyperspace_pb_1.DurabilityLevel; } });
41
41
  const hyperspace_pb = __importStar(require("./proto/hyperspace_pb")); // New, for direct access to types
42
+ exports.HyperbolicMath = {
43
+ projectToBall(x, c = 1.0) {
44
+ if (c <= 0)
45
+ throw new Error('Curvature c must be > 0');
46
+ const normSq = (u) => u.reduce((s, z) => s + z * z, 0);
47
+ const n = Math.sqrt(Math.max(normSq(x), 0));
48
+ const maxN = (1 / Math.sqrt(c)) - 1e-9;
49
+ if (n <= maxN || n <= 1e-15)
50
+ return [...x];
51
+ const scale = maxN / n;
52
+ return x.map((v) => v * scale);
53
+ },
54
+ mobiusAdd(x, y, c = 1.0) {
55
+ if (x.length !== y.length)
56
+ throw new Error('Dimension mismatch');
57
+ if (c <= 0)
58
+ throw new Error('Curvature c must be > 0');
59
+ const dot = (a, b) => a.reduce((s, v, i) => s + v * b[i], 0);
60
+ const x2 = dot(x, x);
61
+ const y2 = dot(y, y);
62
+ const xy = dot(x, y);
63
+ const left = 1 + 2 * c * xy + c * y2;
64
+ const right = 1 - c * x2;
65
+ const den = 1 + 2 * c * xy + c * c * x2 * y2;
66
+ if (Math.abs(den) < 1e-15)
67
+ throw new Error('Mobius denominator too small');
68
+ return x.map((xi, i) => (left * xi + right * y[i]) / den);
69
+ },
70
+ expMap(x, v, c = 1.0) {
71
+ if (x.length !== v.length)
72
+ throw new Error('Dimension mismatch');
73
+ if (c <= 0)
74
+ throw new Error('Curvature c must be > 0');
75
+ const normSq = (u) => u.reduce((s, z) => s + z * z, 0);
76
+ const vNorm = Math.sqrt(Math.max(normSq(v), 0));
77
+ if (vNorm < 1e-15)
78
+ return [...x];
79
+ const lambdaX = 2 / Math.max(1 - c * normSq(x), 1e-15);
80
+ const scale = Math.tanh(Math.sqrt(c) * lambdaX * vNorm / 2) / (Math.sqrt(c) * vNorm);
81
+ return exports.HyperbolicMath.mobiusAdd(x, v.map((vi) => scale * vi), c);
82
+ },
83
+ logMap(x, y, c = 1.0) {
84
+ if (x.length !== y.length)
85
+ throw new Error('Dimension mismatch');
86
+ if (c <= 0)
87
+ throw new Error('Curvature c must be > 0');
88
+ const normSq = (u) => u.reduce((s, z) => s + z * z, 0);
89
+ const delta = exports.HyperbolicMath.mobiusAdd(x.map((xi) => -xi), y, c);
90
+ const deltaNorm = Math.sqrt(Math.max(normSq(delta), 0));
91
+ if (deltaNorm < 1e-15)
92
+ return new Array(x.length).fill(0);
93
+ const lambdaX = 2 / Math.max(1 - c * normSq(x), 1e-15);
94
+ const arg = Math.min(Math.sqrt(c) * deltaNorm, 1 - 1e-15);
95
+ const factor = (2 / (lambdaX * Math.sqrt(c))) * Math.atanh(arg);
96
+ return delta.map((di) => factor * di / deltaNorm);
97
+ },
98
+ riemannianGradient(x, euclideanGrad, c = 1.0) {
99
+ if (x.length !== euclideanGrad.length)
100
+ throw new Error('Dimension mismatch');
101
+ if (c <= 0)
102
+ throw new Error('Curvature c must be > 0');
103
+ const normSq = (u) => u.reduce((s, z) => s + z * z, 0);
104
+ const lambdaX = 2 / Math.max(1 - c * normSq(x), 1e-15);
105
+ const scale = 1 / (lambdaX * lambdaX);
106
+ return euclideanGrad.map((g) => scale * g);
107
+ },
108
+ parallelTransport(x, y, v, c = 1.0) {
109
+ if (x.length !== y.length || x.length !== v.length)
110
+ throw new Error('Dimension mismatch');
111
+ if (c <= 0)
112
+ throw new Error('Curvature c must be > 0');
113
+ const normSq = (u) => u.reduce((s, z) => s + z * z, 0);
114
+ const gyro = (u, w, z) => {
115
+ const uw = exports.HyperbolicMath.mobiusAdd(u, w, c);
116
+ const wz = exports.HyperbolicMath.mobiusAdd(w, z, c);
117
+ const left = exports.HyperbolicMath.mobiusAdd(u, wz, c);
118
+ return exports.HyperbolicMath.mobiusAdd(uw.map((k) => -k), left, c);
119
+ };
120
+ const g = gyro(y, x.map((xi) => -xi), v);
121
+ const lambdaX = 2 / Math.max(1 - c * normSq(x), 1e-15);
122
+ const lambdaY = 2 / Math.max(1 - c * normSq(y), 1e-15);
123
+ const scale = lambdaX / lambdaY;
124
+ return g.map((gi) => scale * gi);
125
+ },
126
+ frechetMean(points, c = 1.0, maxIter = 64, tol = 1e-8) {
127
+ if (!points.length)
128
+ throw new Error('Points set cannot be empty');
129
+ if (c <= 0)
130
+ throw new Error('Curvature c must be > 0');
131
+ const dim = points[0].length;
132
+ if (points.some((p) => p.length !== dim))
133
+ throw new Error('Dimension mismatch');
134
+ const normSq = (u) => u.reduce((s, z) => s + z * z, 0);
135
+ let mu = exports.HyperbolicMath.projectToBall(points[0], c);
136
+ for (let iter = 0; iter < Math.max(1, maxIter); iter++) {
137
+ const grad = new Array(dim).fill(0);
138
+ for (const p of points) {
139
+ const lg = exports.HyperbolicMath.logMap(mu, p, c);
140
+ for (let i = 0; i < dim; i++)
141
+ grad[i] += lg[i];
142
+ }
143
+ for (let i = 0; i < dim; i++)
144
+ grad[i] /= points.length;
145
+ const gNorm = Math.sqrt(Math.max(normSq(grad), 0));
146
+ if (gNorm <= Math.max(tol, 1e-15))
147
+ break;
148
+ mu = exports.HyperbolicMath.expMap(mu, grad, c);
149
+ mu = exports.HyperbolicMath.projectToBall(mu, c);
150
+ }
151
+ return mu;
152
+ }
153
+ };
42
154
  class HyperspaceClient {
43
155
  static toVectorList(vector) {
44
156
  if (Array.isArray(vector)) {
@@ -46,6 +158,42 @@ class HyperspaceClient {
46
158
  }
47
159
  return Array.from(vector);
48
160
  }
161
+ static toProtoMetadataValue(value) {
162
+ const out = new hyperspace_pb.MetadataValue();
163
+ if (typeof value === 'string')
164
+ out.setStringValue(value);
165
+ else if (typeof value === 'boolean')
166
+ out.setBoolValue(value);
167
+ else if (Number.isInteger(value))
168
+ out.setIntValue(Number(value));
169
+ else
170
+ out.setDoubleValue(Number(value));
171
+ return out;
172
+ }
173
+ static parseTypedMetadata(metaMap) {
174
+ const out = {};
175
+ if (metaMap.getLength() === 0)
176
+ return out;
177
+ metaMap.forEach((value, key) => {
178
+ switch (value.getKindCase()) {
179
+ case hyperspace_pb.MetadataValue.KindCase.STRING_VALUE:
180
+ out[key] = value.getStringValue();
181
+ break;
182
+ case hyperspace_pb.MetadataValue.KindCase.INT_VALUE:
183
+ out[key] = value.getIntValue();
184
+ break;
185
+ case hyperspace_pb.MetadataValue.KindCase.DOUBLE_VALUE:
186
+ out[key] = value.getDoubleValue();
187
+ break;
188
+ case hyperspace_pb.MetadataValue.KindCase.BOOL_VALUE:
189
+ out[key] = value.getBoolValue();
190
+ break;
191
+ default:
192
+ break;
193
+ }
194
+ });
195
+ return out;
196
+ }
49
197
  constructor(host = 'localhost:50051', apiKey, userId) {
50
198
  const options = {
51
199
  'grpc.max_send_message_length': 64 * 1024 * 1024,
@@ -90,7 +238,7 @@ class HyperspaceClient {
90
238
  });
91
239
  });
92
240
  }
93
- insert(id, vector, meta, collection = '', durability = hyperspace_pb_1.DurabilityLevel.DEFAULT_LEVEL) {
241
+ insert(id, vector, meta, collection = '', durability = hyperspace_pb_1.DurabilityLevel.DEFAULT_LEVEL, typedMetadata) {
94
242
  return new Promise((resolve, reject) => {
95
243
  const req = new hyperspace_pb_1.InsertRequest();
96
244
  req.setId(id);
@@ -100,6 +248,11 @@ class HyperspaceClient {
100
248
  for (const k in meta)
101
249
  map.set(k, meta[k]);
102
250
  }
251
+ if (typedMetadata) {
252
+ const map = req.getTypedMetadataMap();
253
+ for (const k in typedMetadata)
254
+ map.set(k, HyperspaceClient.toProtoMetadataValue(typedMetadata[k]));
255
+ }
103
256
  req.setCollection(collection);
104
257
  req.setOriginNodeId('');
105
258
  req.setLogicalClock(0);
@@ -125,6 +278,11 @@ class HyperspaceClient {
125
278
  for (const k in item.metadata)
126
279
  map.set(k, item.metadata[k]);
127
280
  }
281
+ if (item.typedMetadata) {
282
+ const map = v.getTypedMetadataMap();
283
+ for (const k in item.typedMetadata)
284
+ map.set(k, HyperspaceClient.toProtoMetadataValue(item.typedMetadata[k]));
285
+ }
128
286
  return v;
129
287
  });
130
288
  req.setVectorsList(vectors);
@@ -153,10 +311,18 @@ class HyperspaceClient {
153
311
  else if (f.range) {
154
312
  const r = new hyperspace_pb.Range();
155
313
  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);
314
+ if (f.range.gte !== undefined) {
315
+ if (Number.isInteger(f.range.gte))
316
+ r.setGte(f.range.gte);
317
+ else
318
+ r.setGteF64(f.range.gte);
319
+ }
320
+ if (f.range.lte !== undefined) {
321
+ if (Number.isInteger(f.range.lte))
322
+ r.setLte(f.range.lte);
323
+ else
324
+ r.setLteF64(f.range.lte);
325
+ }
160
326
  pf.setRange(r);
161
327
  }
162
328
  return pf;
@@ -181,7 +347,8 @@ class HyperspaceClient {
181
347
  return {
182
348
  id: r.getId(),
183
349
  distance: r.getDistance(),
184
- metadata: meta
350
+ metadata: meta,
351
+ typedMetadata: HyperspaceClient.parseTypedMetadata(r.getTypedMetadataMap())
185
352
  };
186
353
  });
187
354
  resolve(results);
@@ -212,7 +379,8 @@ class HyperspaceClient {
212
379
  return {
213
380
  id: r.getId(),
214
381
  distance: r.getDistance(),
215
- metadata: meta
382
+ metadata: meta,
383
+ typedMetadata: HyperspaceClient.parseTypedMetadata(r.getTypedMetadataMap())
216
384
  };
217
385
  }));
218
386
  resolve(batch);
@@ -234,6 +402,219 @@ class HyperspaceClient {
234
402
  });
235
403
  });
236
404
  }
405
+ rebuildIndex(collection) {
406
+ return new Promise((resolve, reject) => {
407
+ const req = new hyperspace_pb_1.RebuildIndexRequest();
408
+ req.setName(collection);
409
+ this.client.rebuildIndex(req, this.metadata, (err) => {
410
+ if (err)
411
+ return reject(err);
412
+ resolve(true);
413
+ });
414
+ });
415
+ }
416
+ rebuildIndexWithFilter(collection, filter) {
417
+ return new Promise((resolve, reject) => {
418
+ const req = new hyperspace_pb_1.RebuildIndexRequest();
419
+ req.setName(collection);
420
+ const fq = new hyperspace_pb_1.VacuumFilterQuery();
421
+ fq.setKey(filter.key);
422
+ fq.setOp(filter.op);
423
+ fq.setValue(filter.value);
424
+ req.setFilterQuery(fq);
425
+ this.client.rebuildIndex(req, this.metadata, (err) => {
426
+ if (err)
427
+ return reject(err);
428
+ resolve(true);
429
+ });
430
+ });
431
+ }
432
+ getNode(id, layer = 0, collection = '') {
433
+ return new Promise((resolve, reject) => {
434
+ const req = new hyperspace_pb_1.GetNodeRequest();
435
+ req.setCollection(collection);
436
+ req.setId(id);
437
+ req.setLayer(layer);
438
+ this.client.getNode(req, this.metadata, (err, resp) => {
439
+ if (err)
440
+ return reject(err);
441
+ const metaMap = resp.getMetadataMap();
442
+ const metadata = {};
443
+ if (metaMap.getLength() > 0) {
444
+ metaMap.forEach((entry, key) => {
445
+ metadata[key] = entry;
446
+ });
447
+ }
448
+ resolve({
449
+ id: resp.getId(),
450
+ layer: resp.getLayer(),
451
+ neighbors: resp.getNeighborsList(),
452
+ metadata,
453
+ typedMetadata: HyperspaceClient.parseTypedMetadata(resp.getTypedMetadataMap())
454
+ });
455
+ });
456
+ });
457
+ }
458
+ getNeighbors(id, layer = 0, limit = 64, offset = 0, collection = '') {
459
+ return new Promise((resolve, reject) => {
460
+ const req = new hyperspace_pb_1.GetNeighborsRequest();
461
+ req.setCollection(collection);
462
+ req.setId(id);
463
+ req.setLayer(layer);
464
+ req.setLimit(limit);
465
+ req.setOffset(offset);
466
+ this.client.getNeighbors(req, this.metadata, (err, resp) => {
467
+ if (err)
468
+ return reject(err);
469
+ const nodes = resp.getNeighborsList().map((n) => {
470
+ const metaMap = n.getMetadataMap();
471
+ const metadata = {};
472
+ if (metaMap.getLength() > 0) {
473
+ metaMap.forEach((entry, key) => {
474
+ metadata[key] = entry;
475
+ });
476
+ }
477
+ return {
478
+ id: n.getId(),
479
+ layer: n.getLayer(),
480
+ neighbors: n.getNeighborsList(),
481
+ metadata,
482
+ typedMetadata: HyperspaceClient.parseTypedMetadata(n.getTypedMetadataMap())
483
+ };
484
+ });
485
+ resolve(nodes);
486
+ });
487
+ });
488
+ }
489
+ getConceptParents(id, layer = 0, limit = 32, collection = '') {
490
+ return new Promise((resolve, reject) => {
491
+ const req = new hyperspace_pb_1.GetConceptParentsRequest();
492
+ req.setCollection(collection);
493
+ req.setId(id);
494
+ req.setLayer(layer);
495
+ req.setLimit(limit);
496
+ this.client.getConceptParents(req, this.metadata, (err, resp) => {
497
+ if (err)
498
+ return reject(err);
499
+ const nodes = resp.getParentsList().map((n) => {
500
+ const metaMap = n.getMetadataMap();
501
+ const metadata = {};
502
+ if (metaMap.getLength() > 0) {
503
+ metaMap.forEach((entry, key) => {
504
+ metadata[key] = entry;
505
+ });
506
+ }
507
+ return {
508
+ id: n.getId(),
509
+ layer: n.getLayer(),
510
+ neighbors: n.getNeighborsList(),
511
+ metadata,
512
+ typedMetadata: HyperspaceClient.parseTypedMetadata(n.getTypedMetadataMap())
513
+ };
514
+ });
515
+ resolve(nodes);
516
+ });
517
+ });
518
+ }
519
+ traverse(startId, layer = 0, maxDepth = 2, maxNodes = 256, collection = '', options) {
520
+ return new Promise((resolve, reject) => {
521
+ const req = new hyperspace_pb_1.TraverseRequest();
522
+ req.setCollection(collection);
523
+ req.setStartId(startId);
524
+ req.setLayer(layer);
525
+ req.setMaxDepth(maxDepth);
526
+ req.setMaxNodes(maxNodes);
527
+ if (options === null || options === void 0 ? void 0 : options.filter) {
528
+ const map = req.getFilterMap();
529
+ for (const k in options.filter) {
530
+ map.set(k, options.filter[k]);
531
+ }
532
+ }
533
+ if (options === null || options === void 0 ? void 0 : options.filters) {
534
+ const protoFilters = options.filters.map(f => {
535
+ const pf = new hyperspace_pb.Filter();
536
+ if (f.match) {
537
+ const m = new hyperspace_pb.Match();
538
+ m.setKey(f.match.key);
539
+ m.setValue(f.match.value);
540
+ pf.setMatch(m);
541
+ }
542
+ else if (f.range) {
543
+ const r = new hyperspace_pb.Range();
544
+ r.setKey(f.range.key);
545
+ if (f.range.gte !== undefined) {
546
+ if (Number.isInteger(f.range.gte))
547
+ r.setGte(f.range.gte);
548
+ else
549
+ r.setGteF64(f.range.gte);
550
+ }
551
+ if (f.range.lte !== undefined) {
552
+ if (Number.isInteger(f.range.lte))
553
+ r.setLte(f.range.lte);
554
+ else
555
+ r.setLteF64(f.range.lte);
556
+ }
557
+ pf.setRange(r);
558
+ }
559
+ return pf;
560
+ });
561
+ req.setFiltersList(protoFilters);
562
+ }
563
+ this.client.traverse(req, this.metadata, (err, resp) => {
564
+ if (err)
565
+ return reject(err);
566
+ const nodes = resp.getNodesList().map((n) => {
567
+ const metaMap = n.getMetadataMap();
568
+ const metadata = {};
569
+ if (metaMap.getLength() > 0) {
570
+ metaMap.forEach((entry, key) => {
571
+ metadata[key] = entry;
572
+ });
573
+ }
574
+ return {
575
+ id: n.getId(),
576
+ layer: n.getLayer(),
577
+ neighbors: n.getNeighborsList(),
578
+ metadata,
579
+ typedMetadata: HyperspaceClient.parseTypedMetadata(n.getTypedMetadataMap())
580
+ };
581
+ });
582
+ resolve(nodes);
583
+ });
584
+ });
585
+ }
586
+ findSemanticClusters(layer = 0, minClusterSize = 3, maxClusters = 32, maxNodes = 10000, collection = '') {
587
+ return new Promise((resolve, reject) => {
588
+ const req = new hyperspace_pb_1.FindSemanticClustersRequest();
589
+ req.setCollection(collection);
590
+ req.setLayer(layer);
591
+ req.setMinClusterSize(minClusterSize);
592
+ req.setMaxClusters(maxClusters);
593
+ req.setMaxNodes(maxNodes);
594
+ this.client.findSemanticClusters(req, this.metadata, (err, resp) => {
595
+ if (err)
596
+ return reject(err);
597
+ resolve(resp.getClustersList().map((c) => c.getNodeIdsList()));
598
+ });
599
+ });
600
+ }
601
+ subscribeToEvents(options, onEvent, onError) {
602
+ const req = new hyperspace_pb_1.EventSubscriptionRequest();
603
+ if (options.collection) {
604
+ req.setCollection(options.collection);
605
+ }
606
+ const requested = options.types || [];
607
+ if (requested.length > 0) {
608
+ const mapped = requested.map((t) => t === 'insert' ? hyperspace_pb_1.EventType.VECTOR_INSERTED : hyperspace_pb_1.EventType.VECTOR_DELETED);
609
+ req.setTypesList(mapped);
610
+ }
611
+ const stream = this.client.subscribeToEvents(req, this.metadata);
612
+ stream.on('data', onEvent);
613
+ if (onError) {
614
+ stream.on('error', onError);
615
+ }
616
+ return stream;
617
+ }
237
618
  close() {
238
619
  this.client.close();
239
620
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyperspace-sdk-ts",
3
- "version": "2.0.0",
3
+ "version": "2.2.1",
4
4
  "description": "Official TypeScript SDK for HyperspaceDB gRPC API",
5
5
  "main": "dist/client.js",
6
6
  "types": "dist/client.d.ts",