@upstash/vector 1.2.0 → 1.2.2

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
@@ -258,6 +258,22 @@ await namespace.fetch(["id-1", "id-2"]);
258
258
 
259
259
  If you wanna learn more about filtering check: [Metadata Filtering](https://upstash.com/docs/vector/features/filtering)
260
260
 
261
+ ## Telemetry
262
+
263
+ This sdk sends anonymous telemetry data to help us improve your experience.
264
+ We collect the following:
265
+
266
+ - SDK version
267
+ - Platform (Cloudflare, AWS or Vercel)
268
+ - Runtime version (node@18.x)
269
+
270
+ You can opt out by setting the `UPSTASH_DISABLE_TELEMETRY` environment variable
271
+ to any truthy value.
272
+
273
+ ```sh
274
+ UPSTASH_DISABLE_TELEMETRY=1
275
+ ```
276
+
261
277
  ## Troubleshooting
262
278
 
263
279
  We have a [Discord](upstash.com/discord) for common problems. If you can't find a solution, please [open an issue](https://github.com/upstash/vector-js/issues/new).
@@ -31,13 +31,15 @@ var HttpClient = class {
31
31
  };
32
32
  }
33
33
  async request(req) {
34
+ const signal = this.options.signal;
35
+ const isSignalFunction = typeof signal === "function";
34
36
  const requestOptions = {
35
37
  cache: this.options.cache,
36
38
  method: "POST",
37
39
  headers: this.headers,
38
40
  body: JSON.stringify(req.body),
39
41
  keepalive: true,
40
- signal: this.options.signal
42
+ signal: isSignalFunction ? signal() : signal
41
43
  };
42
44
  let res = null;
43
45
  let error = null;
@@ -46,13 +48,15 @@ var HttpClient = class {
46
48
  res = await fetch([this.baseUrl, ...req.path ?? []].join("/"), requestOptions);
47
49
  break;
48
50
  } catch (error_) {
49
- if (this.options.signal?.aborted) {
51
+ if (requestOptions.signal?.aborted && isSignalFunction) {
52
+ throw error_;
53
+ } else if (requestOptions.signal?.aborted) {
50
54
  const myBlob = new Blob([
51
- JSON.stringify({ result: this.options.signal.reason ?? "Aborted" })
55
+ JSON.stringify({ result: requestOptions.signal.reason ?? "Aborted" })
52
56
  ]);
53
57
  const myOptions = {
54
58
  status: 200,
55
- statusText: this.options.signal.reason ?? "Aborted"
59
+ statusText: requestOptions.signal.reason ?? "Aborted"
56
60
  };
57
61
  res = new Response(myBlob, myOptions);
58
62
  break;
@@ -148,18 +152,28 @@ var QueryCommand = class extends Command {
148
152
 
149
153
  // src/commands/client/delete/index.ts
150
154
  var DeleteCommand = class extends Command {
151
- constructor(id, options) {
155
+ constructor(payload, options) {
152
156
  let endpoint = "delete";
153
157
  if (options?.namespace) {
154
158
  endpoint = `${endpoint}/${options.namespace}`;
155
159
  }
156
- const finalArr = [];
157
- if (Array.isArray(id)) {
158
- finalArr.push(...id);
159
- } else {
160
- finalArr.push(id);
160
+ if (typeof payload === "string" || typeof payload === "number") {
161
+ super(
162
+ {
163
+ ids: [payload]
164
+ },
165
+ endpoint
166
+ );
167
+ } else if (Array.isArray(payload)) {
168
+ super(
169
+ {
170
+ ids: payload
171
+ },
172
+ endpoint
173
+ );
174
+ } else if (typeof payload === "object") {
175
+ super(payload, endpoint);
161
176
  }
162
- super(finalArr, endpoint);
163
177
  }
164
178
  };
165
179
 
@@ -185,13 +199,19 @@ var isVectorPayload = (payload) => {
185
199
 
186
200
  // src/commands/client/fetch/index.ts
187
201
  var FetchCommand = class extends Command {
188
- constructor([ids, opts]) {
202
+ constructor([payload, opts]) {
189
203
  let endpoint = "fetch";
190
204
  if (opts?.namespace) {
191
205
  endpoint = `${endpoint}/${opts.namespace}`;
192
206
  delete opts.namespace;
193
207
  }
194
- super({ ids, ...opts }, endpoint);
208
+ if (Array.isArray(payload)) {
209
+ super({ ids: payload, ...opts }, endpoint);
210
+ } else if (typeof payload === "object") {
211
+ super({ ...payload, ...opts }, endpoint);
212
+ } else {
213
+ throw new Error("Invalid payload");
214
+ }
195
215
  }
196
216
  };
197
217
 
@@ -227,6 +247,67 @@ var InfoCommand = class extends Command {
227
247
  }
228
248
  };
229
249
 
250
+ // src/commands/client/resumable-query/resume.ts
251
+ var ResumeQueryCommand = class extends Command {
252
+ constructor(payload) {
253
+ super(payload, "resumable-query-next");
254
+ }
255
+ };
256
+
257
+ // src/commands/client/resumable-query/start.ts
258
+ var StartResumableQueryCommand = class extends Command {
259
+ constructor(payload, namespace) {
260
+ let endpoint = "resumable-query";
261
+ if ("data" in payload) {
262
+ endpoint = "resumable-query-data";
263
+ }
264
+ if (namespace) {
265
+ endpoint = `${endpoint}/${namespace}`;
266
+ }
267
+ super(payload, endpoint);
268
+ }
269
+ };
270
+
271
+ // src/commands/client/resumable-query/stop.ts
272
+ var StopResumableQueryCommand = class extends Command {
273
+ constructor(payload) {
274
+ super(payload, "resumable-query-end");
275
+ }
276
+ };
277
+
278
+ // src/commands/client/resumable-query/index.ts
279
+ var ResumableQuery = class {
280
+ uuid;
281
+ start;
282
+ fetchNext;
283
+ stop;
284
+ constructor(payload, client, namespace) {
285
+ this.start = async () => {
286
+ const result = await new StartResumableQueryCommand(payload, namespace).exec(
287
+ client
288
+ );
289
+ this.uuid = result.uuid;
290
+ return result;
291
+ };
292
+ this.fetchNext = (additionalK) => {
293
+ if (!this.uuid) {
294
+ throw new Error(
295
+ "The resumable query has already been stopped. Please start another resumable query."
296
+ );
297
+ }
298
+ return new ResumeQueryCommand({ uuid: this.uuid, additionalK }).exec(client);
299
+ };
300
+ this.stop = async () => {
301
+ if (!this.uuid) {
302
+ throw new Error("Resumable query has not been started. Call start() first.");
303
+ }
304
+ const result = await new StopResumableQueryCommand({ uuid: this.uuid }).exec(client);
305
+ this.uuid = "";
306
+ return result;
307
+ };
308
+ }
309
+ };
310
+
230
311
  // src/commands/client/namespace/index.ts
231
312
  var Namespace = class {
232
313
  client;
@@ -294,19 +375,21 @@ var Namespace = class {
294
375
  */
295
376
  update = (args) => new UpdateCommand(args, { namespace: this.namespace }).exec(this.client);
296
377
  /**
297
- * It's used for retrieving specific items from the index namespace, optionally including
298
- * their metadata and feature vectors.
378
+ * Fetches specific items from the index by their IDs or by an id prefix.
379
+ *
380
+ * Note: While using id prefix, the paginated `range` command is recommended to prevent timeouts on large result sets.
299
381
  *
300
382
  * @example
301
383
  * ```js
302
- * const fetchIds = ['123', '456'];
303
- * const fetchOptions = { includeMetadata: true, includeVectors: false };
304
- * const fetchResults = await index.namespace("ns").fetch(fetchIds, fetchOptions);
305
- * console.log(fetchResults); // Outputs the fetched items
384
+ * // Using ids
385
+ * await index.namespace("ns").fetch(["test-1", "test-2"], { includeMetadata: true });
386
+ *
387
+ * // Using id prefix
388
+ * await index.namespace("ns").fetch({ prefix: "test-" });
306
389
  * ```
307
390
  *
308
391
  * @param {...CommandArgs<typeof FetchCommand>} args - The arguments for the fetch command.
309
- * @param {(number[]|string[])} args[0] - An array of IDs of the items to be fetched.
392
+ * @param {FetchPayload} args[0] - An array of IDs or the id prefix of the items to be fetched.
310
393
  * @param {FetchCommandOptions} args[1] - Options for the fetch operation.
311
394
  * @param {boolean} [args[1].includeMetadata=false] - Optionally include metadata of the fetched items.
312
395
  * @param {boolean} [args[1].includeVectors=false] - Optionally include feature vectors of the fetched items.
@@ -347,34 +430,82 @@ var Namespace = class {
347
430
  */
348
431
  query = (args) => new QueryCommand(args, { namespace: this.namespace }).exec(this.client);
349
432
  /**
350
- * Deletes a specific item or items from the index namespace by their ID(s). *
433
+ * Initializes a resumable query operation on the vector database.
434
+ * This method allows for querying large result sets in multiple chunks or implementing pagination.
351
435
  *
436
+ * @template TMetadata
437
+ * @param {ResumableQueryPayload} args - The arguments for the resumable query.
438
+ * @param {number} args.maxIdle - The maximum idle time in seconds before the query session expires.
439
+ * @param {number} args.topK - The number of top results to return in each fetch operation.
440
+ * @param {number[]} args.vector - The query vector used for similarity search.
441
+ * @param {boolean} [args.includeMetadata] - Whether to include metadata in the query results.
442
+ * @param {boolean} [args.includeVectors] - Whether to include vectors in the query results.
443
+ * @param {Object} [options] - Additional options for the query.
444
+ * @returns {Promise<ResumableQuery<TMetadata>>} A promise that resolves to a ResumableQuery object.
352
445
  * @example
353
- * ```js
354
- * await index.namespace("ns").delete('test-id')
355
- * // { deleted: 1 }
356
- * ```
446
+ * const { result, fetchNext, stop } = await index.namespace("ns").resumableQuery({
447
+ * maxIdle: 3600,
448
+ * topK: 50,
449
+ * vector: [0.1, 0.2, 0.3, ...],
450
+ * includeMetadata: true,
451
+ * includeVectors: true
452
+ * }, { namespace: 'my-namespace' });
357
453
  *
358
- * @param id - List of ids or single id
359
- * @returns Number of deleted vectors like `{ deleted: number }`. The number will be 0 if no vectors are deleted.
454
+ * const firstBatch = await fetchNext(10);
455
+ * const secondBatch = await fetchNext(10);
456
+ * await stop(); // End the query session
360
457
  */
458
+ resumableQuery = async (args) => {
459
+ const resumableQuery = new ResumableQuery(args, this.client, this.namespace);
460
+ const initialQuery = await resumableQuery.start();
461
+ const { fetchNext, stop } = resumableQuery;
462
+ return { fetchNext, stop, result: initialQuery.scores };
463
+ };
464
+ /**
465
+ * Deletes items from the index namespace by id, by id prefix, or by filter.
466
+ *
467
+ * @example
468
+ * ```js
469
+ * // Delete by id
470
+ * await index.namespace("ns").delete("test-id");
471
+
472
+ * // Delete by ids
473
+ * await index.namespace("ns").delete(["test-id1", "test-id2"]);
474
+
475
+ * // Delete by id prefix
476
+ * await index.namespace("ns").delete({ prefix: "test-" });
477
+
478
+ * // Delete by filter
479
+ * await index.namespace("ns").delete({ filter: "age >= 23" });
480
+ * ```
481
+ *
482
+ * @param args - A single id, an array of ids, a prefix, or a filter to delete items from the index.
483
+ * @returns Number of deleted vectors in the format `{ deleted: number }`.If no vectors are deleted, returns `{ deleted: 0 }`.
484
+ */
361
485
  delete = (args) => new DeleteCommand(args, { namespace: this.namespace }).exec(this.client);
362
486
  /**
363
- * Retrieves a range of items from the index.
487
+ * Retrieves a paginated range of items from the index. Optionally filter results by an id prefix.
488
+ * Returns items in batches with a cursor for pagination.
364
489
  *
365
490
  * @example
366
491
  * ```js
367
- * const rangeArgs = {
368
- * cursor: 0,
492
+ * const args = {
369
493
  * limit: 10,
370
494
  * includeVectors: true,
371
495
  * includeMetadata: false
372
496
  * };
373
- * const rangeResults = await index.namespace("ns").range(rangeArgs);
374
- * console.log(rangeResults); // Outputs the result of the range operation
497
+ * await index.namespace("ns").range(args);
498
+ *
499
+ * // Use the cursor to get the next page of results
500
+ * const nextPage = await index.namespace("ns").range({
501
+ * // You have to pass the arguments from the first call
502
+ * ...args,
503
+ * cursor: rangeResult.nextCursor,
504
+ * });
375
505
  * ```
376
506
  *
377
507
  * @param {CommandArgs<typeof RangeCommand>} args - The arguments for the range command.
508
+ * @param {string} [args.prefix] - The prefix of the items to be fetched.
378
509
  * @param {number|string} args.cursor - The starting point (cursor) for the range query.
379
510
  * @param {number} args.limit - The maximum number of items to return in this range.
380
511
  * @param {boolean} [args.includeVectors=false] - Optionally include the feature vectors of the items in the response.
@@ -408,67 +539,6 @@ var UpdateCommand = class extends Command {
408
539
  }
409
540
  };
410
541
 
411
- // src/commands/client/resumable-query/resume.ts
412
- var ResumeQueryCommand = class extends Command {
413
- constructor(payload) {
414
- super(payload, "resumable-query-next");
415
- }
416
- };
417
-
418
- // src/commands/client/resumable-query/start.ts
419
- var StartResumableQueryCommand = class extends Command {
420
- constructor(payload, namespace) {
421
- let endpoint = "resumable-query";
422
- if ("data" in payload) {
423
- endpoint = "resumable-query-data";
424
- }
425
- if (namespace) {
426
- endpoint = `${endpoint}/${namespace}`;
427
- }
428
- super(payload, endpoint);
429
- }
430
- };
431
-
432
- // src/commands/client/resumable-query/stop.ts
433
- var StopResumableQueryCommand = class extends Command {
434
- constructor(payload) {
435
- super(payload, "resumable-query-end");
436
- }
437
- };
438
-
439
- // src/commands/client/resumable-query/index.ts
440
- var ResumableQuery = class {
441
- uuid;
442
- start;
443
- fetchNext;
444
- stop;
445
- constructor(payload, client, namespace) {
446
- this.start = async () => {
447
- const result = await new StartResumableQueryCommand(payload, namespace).exec(
448
- client
449
- );
450
- this.uuid = result.uuid;
451
- return result;
452
- };
453
- this.fetchNext = (additionalK) => {
454
- if (!this.uuid) {
455
- throw new Error(
456
- "The resumable query has already been stopped. Please start another resumable query."
457
- );
458
- }
459
- return new ResumeQueryCommand({ uuid: this.uuid, additionalK }).exec(client);
460
- };
461
- this.stop = async () => {
462
- if (!this.uuid) {
463
- throw new Error("Resumable query has not been started. Call start() first.");
464
- }
465
- const result = await new StopResumableQueryCommand({ uuid: this.uuid }).exec(client);
466
- this.uuid = "";
467
- return result;
468
- };
469
- }
470
- };
471
-
472
542
  // src/commands/management/namespaces/list/index.ts
473
543
  var ListNamespacesCommand = class extends Command {
474
544
  constructor() {
@@ -504,17 +574,26 @@ var Index = class {
504
574
  }
505
575
  namespace = (namespace) => new Namespace(this.client, namespace);
506
576
  /**
507
- * Deletes a specific item or items from the index by their ID(s). *
508
- *
509
- * @example
510
- * ```js
511
- * const result = await index.delete('test-id');
512
- * // { deleted: 1 }
513
- * ```
514
- *
515
- * @param id - List of ids or single id
516
- * @returns Number of deleted vectors like `{ deleted: number }`. The number will be 0 if no vectors are deleted.
517
- */
577
+ * Deletes items from the index by id, by id prefix, or by filter.
578
+ *
579
+ * @example
580
+ * ```js
581
+ * // Delete by id
582
+ * await index.delete("test-id");
583
+
584
+ * // Delete by ids
585
+ * await index.delete(["test-id1", "test-id2"]);
586
+
587
+ * // Delete by id prefix
588
+ * await index.delete({ prefix: "test-" });
589
+
590
+ * // Delete by filter
591
+ * await index.delete({ filter: "age >= 23" });
592
+ * ```
593
+ *
594
+ * @param args - A single id, an array of ids, a prefix, or a filter to delete items from the index.
595
+ * @returns Number of deleted vectors in the format `{ deleted: number }`.If no vectors are deleted, returns `{ deleted: 0 }`.
596
+ */
518
597
  delete = (args, options) => new DeleteCommand(args, options).exec(this.client);
519
598
  /**
520
599
  * Queries an index with specified parameters.
@@ -656,23 +735,25 @@ var Index = class {
656
735
  */
657
736
  update = (args, options) => new UpdateCommand(args, options).exec(this.client);
658
737
  /**
659
- * It's used for retrieving specific items from the index, optionally including
660
- * their metadata and feature vectors.
738
+ * Fetches specific items from the index by their IDs or by an id prefix.
739
+ *
740
+ * Note: While using id prefix, the paginated `range` command is recommended to prevent timeouts on large result sets.
661
741
  *
662
742
  * @example
663
743
  * ```js
664
- * const fetchIds = ['123', '456'];
665
- * const fetchOptions = { includeMetadata: true, includeVectors: false };
666
- * const fetchResults = await index.fetch(fetchIds, fetchOptions);
667
- * console.log(fetchResults); // Outputs the fetched items
744
+ * // Using ids
745
+ * await index.fetch(["test-1", "test-2"], { includeMetadata: true });
746
+ *
747
+ * // Using id prefix
748
+ * await index.fetch({ prefix: "test-" });
668
749
  * ```
669
750
  *
670
751
  * @param {...CommandArgs<typeof FetchCommand>} args - The arguments for the fetch command.
671
- * @param {(number[]|string[])} args - An array of IDs of the items to be fetched.
672
- * @param {FetchCommandOptions} args - Options for the fetch operation.
673
- * @param {boolean} [args.includeMetadata=false] - Optionally include metadata of the fetched items.
674
- * @param {boolean} [args.includeVectors=false] - Optionally include feature vectors of the fetched items.
675
- * @param {boolean} [args.metadataUpdateMode="OVERWRITE"] - Specifies whether to overwrite or patch the metadata values.
752
+ * @param {FetchPayload} args[0] - An array of IDs or the id prefix of the items to be fetched.
753
+ * @param {FetchCommandOptions} args[1] - Options for the fetch operation.
754
+ * @param {boolean} [args[1].includeMetadata=false] - Optionally include metadata of the fetched items.
755
+ * @param {boolean} [args[1].includeVectors=false] - Optionally include feature vectors of the fetched items.
756
+ * @param {string} [args[1].namespace = ""] - The namespace of the index to fetch items from.
676
757
  *
677
758
  * @returns {Promise<FetchReturnResponse<TMetadata>[]>} A promise that resolves with an array of fetched items or null if not found, after the command is executed.
678
759
  */
@@ -708,27 +789,28 @@ var Index = class {
708
789
  */
709
790
  reset = (options) => new ResetCommand(options).exec(this.client);
710
791
  /**
711
- * Retrieves a range of items from the index.
792
+ * Retrieves a paginated range of items from the index. Optionally filter results by an id prefix.
793
+ * Returns items in batches with a cursor for pagination.
712
794
  *
713
795
  * @example
714
796
  * ```js
715
- * const rangeArgs = {
716
- * cursor: 0,
797
+ * const args = {
717
798
  * limit: 10,
718
799
  * includeVectors: true,
719
800
  * includeMetadata: false
720
801
  * };
721
- * const rangeResults = await index.range(rangeArgs);
722
- * console.log(rangeResults); // Outputs the result of the range operation
723
- * ```
724
- *
725
- * You can also pass a namespace like:
802
+ * await index.range(args);
726
803
  *
727
- * ```js
728
- * const rangeResults = await index.range(rangeArgs, { namespace: "ns" });
804
+ * // Use the cursor to get the next page of results
805
+ * const nextPage = await index.range({
806
+ * // You have to pass the arguments from the first call
807
+ * ...args,
808
+ * cursor: rangeResult.nextCursor,
809
+ * });
729
810
  * ```
730
811
  *
731
812
  * @param {CommandArgs<typeof RangeCommand>} args - The arguments for the range command.
813
+ * @param {string} [args.prefix] - The prefix of the items to be fetched.
732
814
  * @param {number|string} args.cursor - The starting point (cursor) for the range query.
733
815
  * @param {number} args.limit - The maximum number of items to return in this range.
734
816
  * @param {boolean} [args.includeVectors=false] - Optionally include the feature vectors of the items in the response.
@@ -776,10 +858,14 @@ var Index = class {
776
858
  deleteNamespace = (namespace) => new DeleteNamespaceCommand(namespace).exec(this.client);
777
859
  };
778
860
 
861
+ // version.ts
862
+ var VERSION = "v1.2.2";
863
+
779
864
  export {
780
865
  HttpClient,
781
866
  WeightingStrategy,
782
867
  FusionAlgorithm,
783
868
  QueryMode,
784
- Index
869
+ Index,
870
+ VERSION
785
871
  };
@@ -1,5 +1,5 @@
1
- import { R as RequesterConfig, D as Dict, I as Index$1 } from './vector-FeePts30.mjs';
2
- export { d as FetchResult, F as FusionAlgorithm, f as InfoResult, Q as QueryMode, e as QueryResult, c as RangeResult, a as Requester, S as SparseVector, U as UpstashRequest, b as UpstashResponse, V as Vector, W as WeightingStrategy } from './vector-FeePts30.mjs';
1
+ import { H as HttpClientConfig, R as RequesterConfig, D as Dict, I as Index$1 } from './vector-7jBuY6ad.mjs';
2
+ export { d as FetchResult, F as FusionAlgorithm, f as InfoResult, Q as QueryMode, e as QueryResult, c as RangeResult, a as Requester, S as SparseVector, U as UpstashRequest, b as UpstashResponse, V as Vector, W as WeightingStrategy } from './vector-7jBuY6ad.mjs';
3
3
 
4
4
  /**
5
5
  * Connection credentials for upstash vector.
@@ -18,7 +18,14 @@ type IndexConfig = {
18
18
  * The signal will allow aborting requests on the fly.
19
19
  * For more check: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
20
20
  */
21
- signal?: AbortSignal;
21
+ signal?: HttpClientConfig["signal"];
22
+ /**
23
+ * Enable telemetry to help us improve the SDK.
24
+ * The sdk will send the sdk version, platform and node version as telemetry headers.
25
+ *
26
+ * @default true
27
+ */
28
+ enableTelemetry?: boolean;
22
29
  } & RequesterConfig;
23
30
  /**
24
31
  * Serverless vector client for upstash.
@@ -1,5 +1,5 @@
1
- import { R as RequesterConfig, D as Dict, I as Index$1 } from './vector-FeePts30.js';
2
- export { d as FetchResult, F as FusionAlgorithm, f as InfoResult, Q as QueryMode, e as QueryResult, c as RangeResult, a as Requester, S as SparseVector, U as UpstashRequest, b as UpstashResponse, V as Vector, W as WeightingStrategy } from './vector-FeePts30.js';
1
+ import { H as HttpClientConfig, R as RequesterConfig, D as Dict, I as Index$1 } from './vector-7jBuY6ad.js';
2
+ export { d as FetchResult, F as FusionAlgorithm, f as InfoResult, Q as QueryMode, e as QueryResult, c as RangeResult, a as Requester, S as SparseVector, U as UpstashRequest, b as UpstashResponse, V as Vector, W as WeightingStrategy } from './vector-7jBuY6ad.js';
3
3
 
4
4
  /**
5
5
  * Connection credentials for upstash vector.
@@ -18,7 +18,14 @@ type IndexConfig = {
18
18
  * The signal will allow aborting requests on the fly.
19
19
  * For more check: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
20
20
  */
21
- signal?: AbortSignal;
21
+ signal?: HttpClientConfig["signal"];
22
+ /**
23
+ * Enable telemetry to help us improve the SDK.
24
+ * The sdk will send the sdk version, platform and node version as telemetry headers.
25
+ *
26
+ * @default true
27
+ */
28
+ enableTelemetry?: boolean;
22
29
  } & RequesterConfig;
23
30
  /**
24
31
  * Serverless vector client for upstash.