@upstash/vector 1.2.0 → 1.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/dist/nodejs.js CHANGED
@@ -131,18 +131,28 @@ var Command = class {
131
131
 
132
132
  // src/commands/client/delete/index.ts
133
133
  var DeleteCommand = class extends Command {
134
- constructor(id, options) {
134
+ constructor(payload, options) {
135
135
  let endpoint = "delete";
136
136
  if (options?.namespace) {
137
137
  endpoint = `${endpoint}/${options.namespace}`;
138
138
  }
139
- const finalArr = [];
140
- if (Array.isArray(id)) {
141
- finalArr.push(...id);
142
- } else {
143
- finalArr.push(id);
139
+ if (typeof payload === "string" || typeof payload === "number") {
140
+ super(
141
+ {
142
+ ids: [payload]
143
+ },
144
+ endpoint
145
+ );
146
+ } else if (Array.isArray(payload)) {
147
+ super(
148
+ {
149
+ ids: payload
150
+ },
151
+ endpoint
152
+ );
153
+ } else if (typeof payload === "object") {
154
+ super(payload, endpoint);
144
155
  }
145
- super(finalArr, endpoint);
146
156
  }
147
157
  };
148
158
 
@@ -214,13 +224,19 @@ var isVectorPayload = (payload) => {
214
224
 
215
225
  // src/commands/client/fetch/index.ts
216
226
  var FetchCommand = class extends Command {
217
- constructor([ids, opts]) {
227
+ constructor([payload, opts]) {
218
228
  let endpoint = "fetch";
219
229
  if (opts?.namespace) {
220
230
  endpoint = `${endpoint}/${opts.namespace}`;
221
231
  delete opts.namespace;
222
232
  }
223
- super({ ids, ...opts }, endpoint);
233
+ if (Array.isArray(payload)) {
234
+ super({ ids: payload, ...opts }, endpoint);
235
+ } else if (typeof payload === "object") {
236
+ super({ ...payload, ...opts }, endpoint);
237
+ } else {
238
+ throw new Error("Invalid payload");
239
+ }
224
240
  }
225
241
  };
226
242
 
@@ -256,6 +272,67 @@ var InfoCommand = class extends Command {
256
272
  }
257
273
  };
258
274
 
275
+ // src/commands/client/resumable-query/resume.ts
276
+ var ResumeQueryCommand = class extends Command {
277
+ constructor(payload) {
278
+ super(payload, "resumable-query-next");
279
+ }
280
+ };
281
+
282
+ // src/commands/client/resumable-query/start.ts
283
+ var StartResumableQueryCommand = class extends Command {
284
+ constructor(payload, namespace) {
285
+ let endpoint = "resumable-query";
286
+ if ("data" in payload) {
287
+ endpoint = "resumable-query-data";
288
+ }
289
+ if (namespace) {
290
+ endpoint = `${endpoint}/${namespace}`;
291
+ }
292
+ super(payload, endpoint);
293
+ }
294
+ };
295
+
296
+ // src/commands/client/resumable-query/stop.ts
297
+ var StopResumableQueryCommand = class extends Command {
298
+ constructor(payload) {
299
+ super(payload, "resumable-query-end");
300
+ }
301
+ };
302
+
303
+ // src/commands/client/resumable-query/index.ts
304
+ var ResumableQuery = class {
305
+ uuid;
306
+ start;
307
+ fetchNext;
308
+ stop;
309
+ constructor(payload, client, namespace) {
310
+ this.start = async () => {
311
+ const result = await new StartResumableQueryCommand(payload, namespace).exec(
312
+ client
313
+ );
314
+ this.uuid = result.uuid;
315
+ return result;
316
+ };
317
+ this.fetchNext = (additionalK) => {
318
+ if (!this.uuid) {
319
+ throw new Error(
320
+ "The resumable query has already been stopped. Please start another resumable query."
321
+ );
322
+ }
323
+ return new ResumeQueryCommand({ uuid: this.uuid, additionalK }).exec(client);
324
+ };
325
+ this.stop = async () => {
326
+ if (!this.uuid) {
327
+ throw new Error("Resumable query has not been started. Call start() first.");
328
+ }
329
+ const result = await new StopResumableQueryCommand({ uuid: this.uuid }).exec(client);
330
+ this.uuid = "";
331
+ return result;
332
+ };
333
+ }
334
+ };
335
+
259
336
  // src/commands/client/namespace/index.ts
260
337
  var Namespace = class {
261
338
  client;
@@ -323,19 +400,21 @@ var Namespace = class {
323
400
  */
324
401
  update = (args) => new UpdateCommand(args, { namespace: this.namespace }).exec(this.client);
325
402
  /**
326
- * It's used for retrieving specific items from the index namespace, optionally including
327
- * their metadata and feature vectors.
403
+ * Fetches specific items from the index by their IDs or by an id prefix.
404
+ *
405
+ * Note: While using id prefix, the paginated `range` command is recommended to prevent timeouts on large result sets.
328
406
  *
329
407
  * @example
330
408
  * ```js
331
- * const fetchIds = ['123', '456'];
332
- * const fetchOptions = { includeMetadata: true, includeVectors: false };
333
- * const fetchResults = await index.namespace("ns").fetch(fetchIds, fetchOptions);
334
- * console.log(fetchResults); // Outputs the fetched items
409
+ * // Using ids
410
+ * await index.namespace("ns").fetch(["test-1", "test-2"], { includeMetadata: true });
411
+ *
412
+ * // Using id prefix
413
+ * await index.namespace("ns").fetch({ prefix: "test-" });
335
414
  * ```
336
415
  *
337
416
  * @param {...CommandArgs<typeof FetchCommand>} args - The arguments for the fetch command.
338
- * @param {(number[]|string[])} args[0] - An array of IDs of the items to be fetched.
417
+ * @param {FetchPayload} args[0] - An array of IDs or the id prefix of the items to be fetched.
339
418
  * @param {FetchCommandOptions} args[1] - Options for the fetch operation.
340
419
  * @param {boolean} [args[1].includeMetadata=false] - Optionally include metadata of the fetched items.
341
420
  * @param {boolean} [args[1].includeVectors=false] - Optionally include feature vectors of the fetched items.
@@ -376,34 +455,82 @@ var Namespace = class {
376
455
  */
377
456
  query = (args) => new QueryCommand(args, { namespace: this.namespace }).exec(this.client);
378
457
  /**
379
- * Deletes a specific item or items from the index namespace by their ID(s). *
458
+ * Initializes a resumable query operation on the vector database.
459
+ * This method allows for querying large result sets in multiple chunks or implementing pagination.
380
460
  *
461
+ * @template TMetadata
462
+ * @param {ResumableQueryPayload} args - The arguments for the resumable query.
463
+ * @param {number} args.maxIdle - The maximum idle time in seconds before the query session expires.
464
+ * @param {number} args.topK - The number of top results to return in each fetch operation.
465
+ * @param {number[]} args.vector - The query vector used for similarity search.
466
+ * @param {boolean} [args.includeMetadata] - Whether to include metadata in the query results.
467
+ * @param {boolean} [args.includeVectors] - Whether to include vectors in the query results.
468
+ * @param {Object} [options] - Additional options for the query.
469
+ * @returns {Promise<ResumableQuery<TMetadata>>} A promise that resolves to a ResumableQuery object.
381
470
  * @example
382
- * ```js
383
- * await index.namespace("ns").delete('test-id')
384
- * // { deleted: 1 }
385
- * ```
471
+ * const { result, fetchNext, stop } = await index.namespace("ns").resumableQuery({
472
+ * maxIdle: 3600,
473
+ * topK: 50,
474
+ * vector: [0.1, 0.2, 0.3, ...],
475
+ * includeMetadata: true,
476
+ * includeVectors: true
477
+ * }, { namespace: 'my-namespace' });
386
478
  *
387
- * @param id - List of ids or single id
388
- * @returns Number of deleted vectors like `{ deleted: number }`. The number will be 0 if no vectors are deleted.
479
+ * const firstBatch = await fetchNext(10);
480
+ * const secondBatch = await fetchNext(10);
481
+ * await stop(); // End the query session
389
482
  */
483
+ resumableQuery = async (args) => {
484
+ const resumableQuery = new ResumableQuery(args, this.client, this.namespace);
485
+ const initialQuery = await resumableQuery.start();
486
+ const { fetchNext, stop } = resumableQuery;
487
+ return { fetchNext, stop, result: initialQuery.scores };
488
+ };
489
+ /**
490
+ * Deletes items from the index namespace by id, by id prefix, or by filter.
491
+ *
492
+ * @example
493
+ * ```js
494
+ * // Delete by id
495
+ * await index.namespace("ns").delete("test-id");
496
+
497
+ * // Delete by ids
498
+ * await index.namespace("ns").delete(["test-id1", "test-id2"]);
499
+
500
+ * // Delete by id prefix
501
+ * await index.namespace("ns").delete({ prefix: "test-" });
502
+
503
+ * // Delete by filter
504
+ * await index.namespace("ns").delete({ filter: "age >= 23" });
505
+ * ```
506
+ *
507
+ * @param args - A single id, an array of ids, a prefix, or a filter to delete items from the index.
508
+ * @returns Number of deleted vectors in the format `{ deleted: number }`.If no vectors are deleted, returns `{ deleted: 0 }`.
509
+ */
390
510
  delete = (args) => new DeleteCommand(args, { namespace: this.namespace }).exec(this.client);
391
511
  /**
392
- * Retrieves a range of items from the index.
512
+ * Retrieves a paginated range of items from the index. Optionally filter results by an id prefix.
513
+ * Returns items in batches with a cursor for pagination.
393
514
  *
394
515
  * @example
395
516
  * ```js
396
- * const rangeArgs = {
397
- * cursor: 0,
517
+ * const args = {
398
518
  * limit: 10,
399
519
  * includeVectors: true,
400
520
  * includeMetadata: false
401
521
  * };
402
- * const rangeResults = await index.namespace("ns").range(rangeArgs);
403
- * console.log(rangeResults); // Outputs the result of the range operation
522
+ * await index.namespace("ns").range(args);
523
+ *
524
+ * // Use the cursor to get the next page of results
525
+ * const nextPage = await index.namespace("ns").range({
526
+ * // You have to pass the arguments from the first call
527
+ * ...args,
528
+ * cursor: rangeResult.nextCursor,
529
+ * });
404
530
  * ```
405
531
  *
406
532
  * @param {CommandArgs<typeof RangeCommand>} args - The arguments for the range command.
533
+ * @param {string} [args.prefix] - The prefix of the items to be fetched.
407
534
  * @param {number|string} args.cursor - The starting point (cursor) for the range query.
408
535
  * @param {number} args.limit - The maximum number of items to return in this range.
409
536
  * @param {boolean} [args.includeVectors=false] - Optionally include the feature vectors of the items in the response.
@@ -437,67 +564,6 @@ var UpdateCommand = class extends Command {
437
564
  }
438
565
  };
439
566
 
440
- // src/commands/client/resumable-query/resume.ts
441
- var ResumeQueryCommand = class extends Command {
442
- constructor(payload) {
443
- super(payload, "resumable-query-next");
444
- }
445
- };
446
-
447
- // src/commands/client/resumable-query/start.ts
448
- var StartResumableQueryCommand = class extends Command {
449
- constructor(payload, namespace) {
450
- let endpoint = "resumable-query";
451
- if ("data" in payload) {
452
- endpoint = "resumable-query-data";
453
- }
454
- if (namespace) {
455
- endpoint = `${endpoint}/${namespace}`;
456
- }
457
- super(payload, endpoint);
458
- }
459
- };
460
-
461
- // src/commands/client/resumable-query/stop.ts
462
- var StopResumableQueryCommand = class extends Command {
463
- constructor(payload) {
464
- super(payload, "resumable-query-end");
465
- }
466
- };
467
-
468
- // src/commands/client/resumable-query/index.ts
469
- var ResumableQuery = class {
470
- uuid;
471
- start;
472
- fetchNext;
473
- stop;
474
- constructor(payload, client, namespace) {
475
- this.start = async () => {
476
- const result = await new StartResumableQueryCommand(payload, namespace).exec(
477
- client
478
- );
479
- this.uuid = result.uuid;
480
- return result;
481
- };
482
- this.fetchNext = (additionalK) => {
483
- if (!this.uuid) {
484
- throw new Error(
485
- "The resumable query has already been stopped. Please start another resumable query."
486
- );
487
- }
488
- return new ResumeQueryCommand({ uuid: this.uuid, additionalK }).exec(client);
489
- };
490
- this.stop = async () => {
491
- if (!this.uuid) {
492
- throw new Error("Resumable query has not been started. Call start() first.");
493
- }
494
- const result = await new StopResumableQueryCommand({ uuid: this.uuid }).exec(client);
495
- this.uuid = "";
496
- return result;
497
- };
498
- }
499
- };
500
-
501
567
  // src/commands/management/namespaces/list/index.ts
502
568
  var ListNamespacesCommand = class extends Command {
503
569
  constructor() {
@@ -533,17 +599,26 @@ var Index = class {
533
599
  }
534
600
  namespace = (namespace) => new Namespace(this.client, namespace);
535
601
  /**
536
- * Deletes a specific item or items from the index by their ID(s). *
537
- *
538
- * @example
539
- * ```js
540
- * const result = await index.delete('test-id');
541
- * // { deleted: 1 }
542
- * ```
543
- *
544
- * @param id - List of ids or single id
545
- * @returns Number of deleted vectors like `{ deleted: number }`. The number will be 0 if no vectors are deleted.
546
- */
602
+ * Deletes items from the index by id, by id prefix, or by filter.
603
+ *
604
+ * @example
605
+ * ```js
606
+ * // Delete by id
607
+ * await index.delete("test-id");
608
+
609
+ * // Delete by ids
610
+ * await index.delete(["test-id1", "test-id2"]);
611
+
612
+ * // Delete by id prefix
613
+ * await index.delete({ prefix: "test-" });
614
+
615
+ * // Delete by filter
616
+ * await index.delete({ filter: "age >= 23" });
617
+ * ```
618
+ *
619
+ * @param args - A single id, an array of ids, a prefix, or a filter to delete items from the index.
620
+ * @returns Number of deleted vectors in the format `{ deleted: number }`.If no vectors are deleted, returns `{ deleted: 0 }`.
621
+ */
547
622
  delete = (args, options) => new DeleteCommand(args, options).exec(this.client);
548
623
  /**
549
624
  * Queries an index with specified parameters.
@@ -685,23 +760,25 @@ var Index = class {
685
760
  */
686
761
  update = (args, options) => new UpdateCommand(args, options).exec(this.client);
687
762
  /**
688
- * It's used for retrieving specific items from the index, optionally including
689
- * their metadata and feature vectors.
763
+ * Fetches specific items from the index by their IDs or by an id prefix.
764
+ *
765
+ * Note: While using id prefix, the paginated `range` command is recommended to prevent timeouts on large result sets.
690
766
  *
691
767
  * @example
692
768
  * ```js
693
- * const fetchIds = ['123', '456'];
694
- * const fetchOptions = { includeMetadata: true, includeVectors: false };
695
- * const fetchResults = await index.fetch(fetchIds, fetchOptions);
696
- * console.log(fetchResults); // Outputs the fetched items
769
+ * // Using ids
770
+ * await index.fetch(["test-1", "test-2"], { includeMetadata: true });
771
+ *
772
+ * // Using id prefix
773
+ * await index.fetch({ prefix: "test-" });
697
774
  * ```
698
775
  *
699
776
  * @param {...CommandArgs<typeof FetchCommand>} args - The arguments for the fetch command.
700
- * @param {(number[]|string[])} args - An array of IDs of the items to be fetched.
701
- * @param {FetchCommandOptions} args - Options for the fetch operation.
702
- * @param {boolean} [args.includeMetadata=false] - Optionally include metadata of the fetched items.
703
- * @param {boolean} [args.includeVectors=false] - Optionally include feature vectors of the fetched items.
704
- * @param {boolean} [args.metadataUpdateMode="OVERWRITE"] - Specifies whether to overwrite or patch the metadata values.
777
+ * @param {FetchPayload} args[0] - An array of IDs or the id prefix of the items to be fetched.
778
+ * @param {FetchCommandOptions} args[1] - Options for the fetch operation.
779
+ * @param {boolean} [args[1].includeMetadata=false] - Optionally include metadata of the fetched items.
780
+ * @param {boolean} [args[1].includeVectors=false] - Optionally include feature vectors of the fetched items.
781
+ * @param {string} [args[1].namespace = ""] - The namespace of the index to fetch items from.
705
782
  *
706
783
  * @returns {Promise<FetchReturnResponse<TMetadata>[]>} A promise that resolves with an array of fetched items or null if not found, after the command is executed.
707
784
  */
@@ -737,27 +814,28 @@ var Index = class {
737
814
  */
738
815
  reset = (options) => new ResetCommand(options).exec(this.client);
739
816
  /**
740
- * Retrieves a range of items from the index.
817
+ * Retrieves a paginated range of items from the index. Optionally filter results by an id prefix.
818
+ * Returns items in batches with a cursor for pagination.
741
819
  *
742
820
  * @example
743
821
  * ```js
744
- * const rangeArgs = {
745
- * cursor: 0,
822
+ * const args = {
746
823
  * limit: 10,
747
824
  * includeVectors: true,
748
825
  * includeMetadata: false
749
826
  * };
750
- * const rangeResults = await index.range(rangeArgs);
751
- * console.log(rangeResults); // Outputs the result of the range operation
752
- * ```
827
+ * await index.range(args);
753
828
  *
754
- * You can also pass a namespace like:
755
- *
756
- * ```js
757
- * const rangeResults = await index.range(rangeArgs, { namespace: "ns" });
829
+ * // Use the cursor to get the next page of results
830
+ * const nextPage = await index.range({
831
+ * // You have to pass the arguments from the first call
832
+ * ...args,
833
+ * cursor: rangeResult.nextCursor,
834
+ * });
758
835
  * ```
759
836
  *
760
837
  * @param {CommandArgs<typeof RangeCommand>} args - The arguments for the range command.
838
+ * @param {string} [args.prefix] - The prefix of the items to be fetched.
761
839
  * @param {number|string} args.cursor - The starting point (cursor) for the range query.
762
840
  * @param {number} args.limit - The maximum number of items to return in this range.
763
841
  * @param {boolean} [args.includeVectors=false] - Optionally include the feature vectors of the items in the response.
@@ -805,6 +883,16 @@ var Index = class {
805
883
  deleteNamespace = (namespace) => new DeleteNamespaceCommand(namespace).exec(this.client);
806
884
  };
807
885
 
886
+ // version.ts
887
+ var VERSION = "v1.2.1";
888
+
889
+ // src/utils/get-runtime.ts
890
+ function getRuntime() {
891
+ if (typeof process === "object" && typeof process.versions == "object" && process.versions.bun)
892
+ return `bun@${process.versions.bun}`;
893
+ return typeof EdgeRuntime === "string" ? "edge-light" : `node@${process.version}`;
894
+ }
895
+
808
896
  // src/platforms/nodejs.ts
809
897
  var Index2 = class _Index extends Index {
810
898
  constructor(configOrRequester) {
@@ -826,10 +914,16 @@ var Index2 = class _Index extends Index {
826
914
  if (token.startsWith(" ") || token.endsWith(" ") || /\r|\n/.test(token)) {
827
915
  console.warn("The vector token contains whitespace or newline, which can cause errors!");
828
916
  }
917
+ const enableTelemetry = process.env.UPSTASH_DISABLE_TELEMETRY ? false : configOrRequester?.enableTelemetry ?? true;
918
+ const telemetryHeaders = enableTelemetry ? {
919
+ "Upstash-Telemetry-Sdk": `upstash-vector-js@${VERSION}`,
920
+ "Upstash-Telemetry-Platform": process.env.VERCEL ? "vercel" : process.env.AWS_REGION ? "aws" : "unknown",
921
+ "Upstash-Telemetry-Runtime": getRuntime()
922
+ } : {};
829
923
  const client = new HttpClient({
830
924
  baseUrl: url,
831
925
  retry: configOrRequester?.retry,
832
- headers: { authorization: `Bearer ${token}` },
926
+ headers: { authorization: `Bearer ${token}`, ...telemetryHeaders },
833
927
  cache: configOrRequester?.cache === false ? void 0 : configOrRequester?.cache || "no-store",
834
928
  signal: configOrRequester?.signal
835
929
  });
package/dist/nodejs.mjs CHANGED
@@ -3,8 +3,16 @@ import {
3
3
  HttpClient,
4
4
  Index,
5
5
  QueryMode,
6
+ VERSION,
6
7
  WeightingStrategy
7
- } from "./chunk-4AKSNQD7.mjs";
8
+ } from "./chunk-HESEGT2A.mjs";
9
+
10
+ // src/utils/get-runtime.ts
11
+ function getRuntime() {
12
+ if (typeof process === "object" && typeof process.versions == "object" && process.versions.bun)
13
+ return `bun@${process.versions.bun}`;
14
+ return typeof EdgeRuntime === "string" ? "edge-light" : `node@${process.version}`;
15
+ }
8
16
 
9
17
  // src/platforms/nodejs.ts
10
18
  var Index2 = class _Index extends Index {
@@ -27,10 +35,16 @@ var Index2 = class _Index extends Index {
27
35
  if (token.startsWith(" ") || token.endsWith(" ") || /\r|\n/.test(token)) {
28
36
  console.warn("The vector token contains whitespace or newline, which can cause errors!");
29
37
  }
38
+ const enableTelemetry = process.env.UPSTASH_DISABLE_TELEMETRY ? false : configOrRequester?.enableTelemetry ?? true;
39
+ const telemetryHeaders = enableTelemetry ? {
40
+ "Upstash-Telemetry-Sdk": `upstash-vector-js@${VERSION}`,
41
+ "Upstash-Telemetry-Platform": process.env.VERCEL ? "vercel" : process.env.AWS_REGION ? "aws" : "unknown",
42
+ "Upstash-Telemetry-Runtime": getRuntime()
43
+ } : {};
30
44
  const client = new HttpClient({
31
45
  baseUrl: url,
32
46
  retry: configOrRequester?.retry,
33
- headers: { authorization: `Bearer ${token}` },
47
+ headers: { authorization: `Bearer ${token}`, ...telemetryHeaders },
34
48
  cache: configOrRequester?.cache === false ? void 0 : configOrRequester?.cache || "no-store",
35
49
  signal: configOrRequester?.signal
36
50
  });