@upstash/vector 1.1.6 → 1.1.7

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
@@ -1 +1,839 @@
1
- "use strict";var U=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var Q=Object.getOwnPropertyNames;var q=Object.prototype.hasOwnProperty;var O=(r,e)=>{for(var t in e)U(r,t,{get:e[t],enumerable:!0})},I=(r,e,t,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Q(e))!q.call(r,s)&&s!==t&&U(r,s,{get:()=>e[s],enumerable:!(a=_(e,s))||a.enumerable});return r};var $=r=>I(U({},"__esModule",{value:!0}),r);var k={};O(k,{Index:()=>w});module.exports=$(k);var i=class extends Error{constructor(e){super(e),this.name="UpstashError"}};var f=class{baseUrl;headers;options;retry;constructor(e){this.options={cache:e.cache,signal:e.signal},this.baseUrl=e.baseUrl.replace(/\/$/,""),this.headers={"Content-Type":"application/json",...e.headers},this.retry=typeof e?.retry=="boolean"&&e?.retry===!1?{attempts:1,backoff:()=>0}:{attempts:e?.retry?.retries??5,backoff:e?.retry?.backoff??(t=>Math.exp(t)*50)}}async request(e){let t={cache:this.options.cache,method:"POST",headers:this.headers,body:JSON.stringify(e.body),keepalive:!0,signal:this.options.signal},a=null,s=null;for(let T=0;T<=this.retry.attempts;T++)try{a=await fetch([this.baseUrl,...e.path??[]].join("/"),t);break}catch(N){if(this.options.signal?.aborted){let A=new Blob([JSON.stringify({result:this.options.signal.reason??"Aborted"})]),D={status:200,statusText:this.options.signal.reason??"Aborted"};a=new Response(A,D);break}s=N,await new Promise(A=>setTimeout(A,this.retry.backoff(T)))}if(!a)throw s??new Error("Exhausted all retries");let o=await a.json();if(!a.ok)throw new i(`${o.error}`);return{result:o.result,error:o.error}}};var n=class{payload;endpoint;constructor(e,t){this.payload=e,this.endpoint=t}async exec(e){let{result:t,error:a}=await e.request({body:this.payload,path:[this.endpoint]});if(a)throw new i(a);if(t===void 0)throw new TypeError("Request did not return a result");return t}};var m=class extends n{constructor(e,t){let a="delete";t?.namespace&&(a=`${a}/${t.namespace}`);let s=[];Array.isArray(e)?s.push(...e):s.push(e),super(s,a)}};var h=class extends n{constructor(e,t){let a="query";a=e.some(o=>o.data)?"query-data":"query",t?.namespace&&(a=`${a}/${t.namespace}`),super(e,a)}};var p=class extends n{constructor(e,t){let a="query";"data"in e&&(a="query-data"),t?.namespace&&(a=`${a}/${t.namespace}`),super(e,a)}};var d=class extends n{constructor(e,t){let a="upsert";Array.isArray(e)?a=e.some(o=>V(o))?"upsert":"upsert-data":a=V(e)?"upsert":"upsert-data",t?.namespace&&(a=`${a}/${t.namespace}`),super(e,a)}},V=r=>"vector"in r;var c=class extends n{constructor([e,t]){let a="fetch";t?.namespace&&(a=`${a}/${t.namespace}`,delete t.namespace),super({ids:e,...t},a)}};var u=class extends n{constructor(e,t){let a="range";t?.namespace&&(a=`${a}/${t.namespace}`),super(e,a)}};var l=class extends n{constructor(e){let t="reset";e?.namespace?t=`${t}/${e.namespace}`:e?.all&&(t=`${t}?all`),super([],t)}};var C=class extends n{constructor(){super([],"info")}};var x=class{client;namespace;constructor(e,t){this.client=e,this.namespace=t}upsert=e=>new d(e,{namespace:this.namespace}).exec(this.client);update=e=>new y(e,{namespace:this.namespace}).exec(this.client);fetch=(...e)=>(e[1]?e[1].namespace=this.namespace:e[1]={namespace:this.namespace},new c(e).exec(this.client));query=e=>new p(e,{namespace:this.namespace}).exec(this.client);delete=e=>new m(e,{namespace:this.namespace}).exec(this.client);range=e=>new u(e,{namespace:this.namespace}).exec(this.client);reset=()=>new l({namespace:this.namespace}).exec(this.client)};var y=class extends n{constructor(e,t){let a="update";t?.namespace&&(a=`${a}/${t.namespace}`),super(e,a)}};var R=class extends n{constructor(e){super(e,"resumable-query-next")}};var E=class extends n{constructor(e,t){let a="resumable-query";"data"in e&&(a="resumable-query-data"),t&&(a=`${a}/${t}`),super(e,a)}};var M=class extends n{constructor(e){super(e,"resumable-query-end")}};var b=class{uuid;start;fetchNext;stop;constructor(e,t,a){this.start=async()=>{let s=await new E(e,a).exec(t);return this.uuid=s.uuid,s},this.fetchNext=s=>{if(!this.uuid)throw new Error("The resumable query has already been stopped. Please start another resumable query.");return new R({uuid:this.uuid,additionalK:s}).exec(t)},this.stop=async()=>{if(!this.uuid)throw new Error("Resumable query has not been started. Call start() first.");let s=await new M({uuid:this.uuid}).exec(t);return this.uuid="",s}}};var g=class extends n{constructor(){super([],"list-namespaces")}};var P=class extends n{constructor(e){let t=`delete-namespace/${e}`;super([],t)}};var S=class{client;constructor(e){this.client=e}namespace=e=>new x(this.client,e);delete=(e,t)=>new m(e,t).exec(this.client);query=(e,t)=>new p(e,t).exec(this.client);queryMany=(e,t)=>new h(e,t).exec(this.client);resumableQuery=async(e,t)=>{let a=new b(e,this.client,t?.namespace),s=await a.start(),{fetchNext:o,stop:T}=a;return{fetchNext:o,stop:T,result:s.scores}};upsert=(e,t)=>new d(e,t).exec(this.client);update=(e,t)=>new y(e,t).exec(this.client);fetch=(...e)=>new c(e).exec(this.client);reset=e=>new l(e).exec(this.client);range=(e,t)=>new u(e,t).exec(this.client);info=()=>new C().exec(this.client);listNamespaces=()=>new g().exec(this.client);deleteNamespace=e=>new P(e).exec(this.client)};var w=class r extends S{constructor(e){if(e!==void 0&&"request"in e){super(e);return}let t=e?.token??process.env.NEXT_PUBLIC_UPSTASH_VECTOR_REST_TOKEN??process.env.UPSTASH_VECTOR_REST_TOKEN,a=e?.url??process.env.NEXT_PUBLIC_UPSTASH_VECTOR_REST_URL??process.env.UPSTASH_VECTOR_REST_URL;if(!t)throw new Error("UPSTASH_VECTOR_REST_TOKEN is missing!");if(!a)throw new Error("UPSTASH_VECTOR_REST_URL is missing!");(a.startsWith(" ")||a.endsWith(" ")||/\r|\n/.test(a))&&console.warn("The vector url contains whitespace or newline, which can cause errors!"),(t.startsWith(" ")||t.endsWith(" ")||/\r|\n/.test(t))&&console.warn("The vector token contains whitespace or newline, which can cause errors!");let s=new f({baseUrl:a,retry:e?.retry,headers:{authorization:`Bearer ${t}`},cache:e?.cache===!1?void 0:e?.cache||"no-store",signal:e?.signal});super(s)}static fromEnv(e,t){let a=e?.UPSTASH_VECTOR_REST_URL||process?.env.UPSTASH_VECTOR_REST_URL,s=e?.UPSTASH_VECTOR_REST_TOKEN||process?.env.UPSTASH_VECTOR_REST_TOKEN;if(!a)throw new Error("Unable to find environment variable: `UPSTASH_VECTOR_REST_URL`");if(!s)throw new Error("Unable to find environment variable: `UPSTASH_VECTOR_REST_TOKEN`");return new r({...t,url:a,token:s})}};0&&(module.exports={Index});
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/platforms/nodejs.ts
21
+ var nodejs_exports = {};
22
+ __export(nodejs_exports, {
23
+ Index: () => Index2
24
+ });
25
+ module.exports = __toCommonJS(nodejs_exports);
26
+
27
+ // src/error/index.ts
28
+ var UpstashError = class extends Error {
29
+ constructor(message) {
30
+ super(message);
31
+ this.name = "UpstashError";
32
+ }
33
+ };
34
+
35
+ // src/http/index.ts
36
+ var HttpClient = class {
37
+ baseUrl;
38
+ headers;
39
+ options;
40
+ retry;
41
+ constructor(config) {
42
+ this.options = {
43
+ cache: config.cache,
44
+ signal: config.signal
45
+ };
46
+ this.baseUrl = config.baseUrl.replace(/\/$/, "");
47
+ this.headers = {
48
+ "Content-Type": "application/json",
49
+ ...config.headers
50
+ };
51
+ this.retry = typeof config?.retry === "boolean" && config?.retry === false ? {
52
+ attempts: 1,
53
+ backoff: () => 0
54
+ } : {
55
+ attempts: config?.retry?.retries ?? 5,
56
+ backoff: config?.retry?.backoff ?? ((retryCount) => Math.exp(retryCount) * 50)
57
+ };
58
+ }
59
+ async request(req) {
60
+ const requestOptions = {
61
+ cache: this.options.cache,
62
+ method: "POST",
63
+ headers: this.headers,
64
+ body: JSON.stringify(req.body),
65
+ keepalive: true,
66
+ signal: this.options.signal
67
+ };
68
+ let res = null;
69
+ let error = null;
70
+ for (let i = 0; i <= this.retry.attempts; i++) {
71
+ try {
72
+ res = await fetch([this.baseUrl, ...req.path ?? []].join("/"), requestOptions);
73
+ break;
74
+ } catch (error_) {
75
+ if (this.options.signal?.aborted) {
76
+ const myBlob = new Blob([
77
+ JSON.stringify({ result: this.options.signal.reason ?? "Aborted" })
78
+ ]);
79
+ const myOptions = {
80
+ status: 200,
81
+ statusText: this.options.signal.reason ?? "Aborted"
82
+ };
83
+ res = new Response(myBlob, myOptions);
84
+ break;
85
+ }
86
+ error = error_;
87
+ await new Promise((r) => setTimeout(r, this.retry.backoff(i)));
88
+ }
89
+ }
90
+ if (!res) {
91
+ throw error ?? new Error("Exhausted all retries");
92
+ }
93
+ const body = await res.json();
94
+ if (!res.ok) {
95
+ throw new UpstashError(`${body.error}`);
96
+ }
97
+ return { result: body.result, error: body.error };
98
+ }
99
+ };
100
+
101
+ // src/commands/command.ts
102
+ var Command = class {
103
+ payload;
104
+ endpoint;
105
+ constructor(command, endpoint) {
106
+ this.payload = command;
107
+ this.endpoint = endpoint;
108
+ }
109
+ /**
110
+ * Execute the command using a client.
111
+ */
112
+ async exec(client) {
113
+ const { result, error } = await client.request({
114
+ body: this.payload,
115
+ path: [this.endpoint]
116
+ });
117
+ if (error) {
118
+ throw new UpstashError(error);
119
+ }
120
+ if (result === void 0) {
121
+ throw new TypeError("Request did not return a result");
122
+ }
123
+ return result;
124
+ }
125
+ };
126
+
127
+ // src/commands/client/delete/index.ts
128
+ var DeleteCommand = class extends Command {
129
+ constructor(id, options) {
130
+ let endpoint = "delete";
131
+ if (options?.namespace) {
132
+ endpoint = `${endpoint}/${options.namespace}`;
133
+ }
134
+ const finalArr = [];
135
+ if (Array.isArray(id)) {
136
+ finalArr.push(...id);
137
+ } else {
138
+ finalArr.push(id);
139
+ }
140
+ super(finalArr, endpoint);
141
+ }
142
+ };
143
+
144
+ // src/commands/client/query/query-many/index.ts
145
+ var QueryManyCommand = class extends Command {
146
+ constructor(payload, options) {
147
+ let endpoint = "query";
148
+ const hasData = payload.some((p) => p.data);
149
+ endpoint = hasData ? "query-data" : "query";
150
+ if (options?.namespace) {
151
+ endpoint = `${endpoint}/${options.namespace}`;
152
+ }
153
+ super(payload, endpoint);
154
+ }
155
+ };
156
+
157
+ // src/commands/client/query/query-single/index.ts
158
+ var QueryCommand = class extends Command {
159
+ constructor(payload, options) {
160
+ let endpoint = "query";
161
+ if ("data" in payload) {
162
+ endpoint = "query-data";
163
+ }
164
+ if (options?.namespace) {
165
+ endpoint = `${endpoint}/${options.namespace}`;
166
+ }
167
+ super(payload, endpoint);
168
+ }
169
+ };
170
+
171
+ // src/commands/client/upsert/index.ts
172
+ var UpsertCommand = class extends Command {
173
+ constructor(payload, opts) {
174
+ let endpoint = "upsert";
175
+ if (Array.isArray(payload)) {
176
+ const isUpsert = payload.some((p) => isVectorPayload(p));
177
+ endpoint = isUpsert ? "upsert" : "upsert-data";
178
+ } else {
179
+ endpoint = isVectorPayload(payload) ? "upsert" : "upsert-data";
180
+ }
181
+ if (opts?.namespace) {
182
+ endpoint = `${endpoint}/${opts.namespace}`;
183
+ }
184
+ super(payload, endpoint);
185
+ }
186
+ };
187
+ var isVectorPayload = (payload) => {
188
+ return "vector" in payload;
189
+ };
190
+
191
+ // src/commands/client/fetch/index.ts
192
+ var FetchCommand = class extends Command {
193
+ constructor([ids, opts]) {
194
+ let endpoint = "fetch";
195
+ if (opts?.namespace) {
196
+ endpoint = `${endpoint}/${opts.namespace}`;
197
+ delete opts.namespace;
198
+ }
199
+ super({ ids, ...opts }, endpoint);
200
+ }
201
+ };
202
+
203
+ // src/commands/client/range/index.ts
204
+ var RangeCommand = class extends Command {
205
+ constructor(payload, options) {
206
+ let endpoint = "range";
207
+ if (options?.namespace) {
208
+ endpoint = `${endpoint}/${options.namespace}`;
209
+ }
210
+ super(payload, endpoint);
211
+ }
212
+ };
213
+
214
+ // src/commands/client/reset/index.ts
215
+ var ResetCommand = class extends Command {
216
+ constructor(options) {
217
+ let endpoint = "reset";
218
+ if (options?.namespace) {
219
+ endpoint = `${endpoint}/${options.namespace}`;
220
+ } else if (options?.all) {
221
+ endpoint = `${endpoint}?all`;
222
+ }
223
+ super([], endpoint);
224
+ }
225
+ };
226
+
227
+ // src/commands/client/info/index.ts
228
+ var InfoCommand = class extends Command {
229
+ constructor() {
230
+ const endpoint = "info";
231
+ super([], endpoint);
232
+ }
233
+ };
234
+
235
+ // src/commands/client/namespace/index.ts
236
+ var Namespace = class {
237
+ client;
238
+ namespace;
239
+ /**
240
+ * Create a new index namespace client
241
+ *
242
+ * @example
243
+ * ```typescript
244
+ * const index = new Index({
245
+ * url: "<UPSTASH_VECTOR_REST_URL>",
246
+ * token: "<UPSTASH_VECTOR_REST_TOKEN>",
247
+ * });
248
+ *
249
+ * const namespace = index.namespace("ns");
250
+ * ```
251
+ */
252
+ constructor(client, namespace) {
253
+ this.client = client;
254
+ this.namespace = namespace;
255
+ }
256
+ /**
257
+ * Upserts (Updates and Inserts) specific items into the index namespace.
258
+ * It's used for adding new items to the index namespace or updating existing ones.
259
+ *
260
+ * @example
261
+ * ```js
262
+ * const upsertArgs = {
263
+ * id: '123',
264
+ * vector: [0.42, 0.87, ...],
265
+ * metadata: { property1: 'value1', property2: 'value2' }
266
+ * };
267
+ * const upsertResult = await index.namespace("ns").upsert(upsertArgs);
268
+ * console.log(upsertResult); // Outputs the result of the upsert operation
269
+ * ```
270
+ *
271
+ * @param {CommandArgs<typeof UpsertCommand>} args - The arguments for the upsert command.
272
+ * @param {number|string} args.id - The unique identifier for the item being upserted.
273
+ * @param {number[]} args.vector - The feature vector associated with the item.
274
+ * @param {Dict} [args.metadata] - Optional metadata to be associated with the item.
275
+ *
276
+ * @returns {string} A promise that resolves with the result of the upsert operation after the command is executed.
277
+ */
278
+ upsert = (args) => new UpsertCommand(args, { namespace: this.namespace }).exec(this.client);
279
+ /*
280
+ * Updates specific items in the index.
281
+ * It's used for updating existing items in the index.
282
+ *
283
+ * @example
284
+ * ```js
285
+ * const updateArgs = {
286
+ * id: '123',
287
+ * metadata: { updatedProperty: 'value1' }
288
+ * };
289
+ * const updateResult = await index.update(updateArgs);
290
+ * console.log(updateResult); // Outputs the result of the update operation
291
+ * ```
292
+ *
293
+ * @param {CommandArgs<typeof UpdateCommand>} args - The arguments for the update command.
294
+ * @param {number|string} args.id - The unique identifier for the item being updated.
295
+ * @param {number[]} args.vector - The feature vector associated with the item.
296
+ * @param {Record<string, unknown>} [args.metadata] - Optional metadata to be associated with the item.
297
+ *
298
+ * @returns {Promise<{updated: number}>} A promise that returns the number of items successfully updated.
299
+ */
300
+ update = (args) => new UpdateCommand(args, { namespace: this.namespace }).exec(this.client);
301
+ /**
302
+ * It's used for retrieving specific items from the index namespace, optionally including
303
+ * their metadata and feature vectors.
304
+ *
305
+ * @example
306
+ * ```js
307
+ * const fetchIds = ['123', '456'];
308
+ * const fetchOptions = { includeMetadata: true, includeVectors: false };
309
+ * const fetchResults = await index.namespace("ns").fetch(fetchIds, fetchOptions);
310
+ * console.log(fetchResults); // Outputs the fetched items
311
+ * ```
312
+ *
313
+ * @param {...CommandArgs<typeof FetchCommand>} args - The arguments for the fetch command.
314
+ * @param {(number[]|string[])} args[0] - An array of IDs of the items to be fetched.
315
+ * @param {FetchCommandOptions} args[1] - Options for the fetch operation.
316
+ * @param {boolean} [args[1].includeMetadata=false] - Optionally include metadata of the fetched items.
317
+ * @param {boolean} [args[1].includeVectors=false] - Optionally include feature vectors of the fetched items.
318
+ * @param {string} [args[1].namespace = ""] - The namespace of the index to fetch items from.
319
+ *
320
+ * @returns {Promise<FetchReturnResponse<TMetadata>[]>} A promise that resolves with an array of fetched items or null if not found, after the command is executed.
321
+ */
322
+ fetch = (...args) => {
323
+ if (args[1]) {
324
+ args[1].namespace = this.namespace;
325
+ } else {
326
+ args[1] = { namespace: this.namespace };
327
+ }
328
+ return new FetchCommand(args).exec(this.client);
329
+ };
330
+ /**
331
+ * Queries an index namespace with specified parameters.
332
+ * This method creates and executes a query command on an index based on the provided arguments.
333
+ *
334
+ * @example
335
+ * ```js
336
+ * await index.namespace("ns").query({
337
+ * topK: 3,
338
+ * vector: [ 0.22, 0.66 ],
339
+ * filter: "age >= 23 and (type = \'turtle\' OR type = \'cat\')"
340
+ * });
341
+ * ```
342
+ *
343
+ * @param {Object} args - The arguments for the query command.
344
+ * @param {number[]} args.vector - An array of numbers representing the feature vector for the query.
345
+ * This vector is utilized to find the most relevant items in the index.
346
+ * @param {number} args.topK - The desired number of top results to be returned, based on relevance or similarity to the query vector.
347
+ * @param {string} [args.filter] - An optional filter string to be used in the query. The filter string is used to narrow down the query results.
348
+ * @param {boolean} [args.includeVectors=false] - When set to true, includes the feature vectors of the returned items in the response.
349
+ * @param {boolean} [args.includeMetadata=false] - When set to true, includes additional metadata of the returned items in the response.
350
+ *
351
+ * @returns A promise that resolves with an array of query result objects when the request to query the index is completed.
352
+ */
353
+ query = (args) => new QueryCommand(args, { namespace: this.namespace }).exec(this.client);
354
+ /**
355
+ * Deletes a specific item or items from the index namespace by their ID(s). *
356
+ *
357
+ * @example
358
+ * ```js
359
+ * await index.namespace("ns").delete('test-id')
360
+ * // { deleted: 1 }
361
+ * ```
362
+ *
363
+ * @param id - List of ids or single id
364
+ * @returns Number of deleted vectors like `{ deleted: number }`. The number will be 0 if no vectors are deleted.
365
+ */
366
+ delete = (args) => new DeleteCommand(args, { namespace: this.namespace }).exec(this.client);
367
+ /**
368
+ * Retrieves a range of items from the index.
369
+ *
370
+ * @example
371
+ * ```js
372
+ * const rangeArgs = {
373
+ * cursor: 0,
374
+ * limit: 10,
375
+ * includeVectors: true,
376
+ * includeMetadata: false
377
+ * };
378
+ * const rangeResults = await index.namespace("ns").range(rangeArgs);
379
+ * console.log(rangeResults); // Outputs the result of the range operation
380
+ * ```
381
+ *
382
+ * @param {CommandArgs<typeof RangeCommand>} args - The arguments for the range command.
383
+ * @param {number|string} args.cursor - The starting point (cursor) for the range query.
384
+ * @param {number} args.limit - The maximum number of items to return in this range.
385
+ * @param {boolean} [args.includeVectors=false] - Optionally include the feature vectors of the items in the response.
386
+ * @param {boolean} [args.includeMetadata=false] - Optionally include additional metadata of the items in the response.
387
+ *
388
+ * @returns {Promise<RangeReturnResponse<TMetadata>>} A promise that resolves with the response containing the next cursor and an array of vectors, after the command is executed.
389
+ */
390
+ range = (args) => new RangeCommand(args, { namespace: this.namespace }).exec(this.client);
391
+ /**
392
+ * It's used for wiping all the vectors in a index namespace.
393
+ *
394
+ * @example
395
+ * ```js
396
+ * await index.namespace("ns").reset();
397
+ * console.log('Index namespace has been reset');
398
+ * ```
399
+ *
400
+ * @returns {Promise<string>} A promise that resolves with the result of the reset operation after the command is executed.
401
+ */
402
+ reset = () => new ResetCommand({ namespace: this.namespace }).exec(this.client);
403
+ };
404
+
405
+ // src/commands/client/update/index.ts
406
+ var UpdateCommand = class extends Command {
407
+ constructor(payload, opts) {
408
+ let endpoint = "update";
409
+ if (opts?.namespace) {
410
+ endpoint = `${endpoint}/${opts.namespace}`;
411
+ }
412
+ super(payload, endpoint);
413
+ }
414
+ };
415
+
416
+ // src/commands/client/resumable-query/resume.ts
417
+ var ResumeQueryCommand = class extends Command {
418
+ constructor(payload) {
419
+ super(payload, "resumable-query-next");
420
+ }
421
+ };
422
+
423
+ // src/commands/client/resumable-query/start.ts
424
+ var StartResumableQueryCommand = class extends Command {
425
+ constructor(payload, namespace) {
426
+ let endpoint = "resumable-query";
427
+ if ("data" in payload) {
428
+ endpoint = "resumable-query-data";
429
+ }
430
+ if (namespace) {
431
+ endpoint = `${endpoint}/${namespace}`;
432
+ }
433
+ super(payload, endpoint);
434
+ }
435
+ };
436
+
437
+ // src/commands/client/resumable-query/stop.ts
438
+ var StopResumableQueryCommand = class extends Command {
439
+ constructor(payload) {
440
+ super(payload, "resumable-query-end");
441
+ }
442
+ };
443
+
444
+ // src/commands/client/resumable-query/index.ts
445
+ var ResumableQuery = class {
446
+ uuid;
447
+ start;
448
+ fetchNext;
449
+ stop;
450
+ constructor(payload, client, namespace) {
451
+ this.start = async () => {
452
+ const result = await new StartResumableQueryCommand(payload, namespace).exec(
453
+ client
454
+ );
455
+ this.uuid = result.uuid;
456
+ return result;
457
+ };
458
+ this.fetchNext = (additionalK) => {
459
+ if (!this.uuid) {
460
+ throw new Error(
461
+ "The resumable query has already been stopped. Please start another resumable query."
462
+ );
463
+ }
464
+ return new ResumeQueryCommand({ uuid: this.uuid, additionalK }).exec(client);
465
+ };
466
+ this.stop = async () => {
467
+ if (!this.uuid) {
468
+ throw new Error("Resumable query has not been started. Call start() first.");
469
+ }
470
+ const result = await new StopResumableQueryCommand({ uuid: this.uuid }).exec(client);
471
+ this.uuid = "";
472
+ return result;
473
+ };
474
+ }
475
+ };
476
+
477
+ // src/commands/management/namespaces/list/index.ts
478
+ var ListNamespacesCommand = class extends Command {
479
+ constructor() {
480
+ const endpoint = "list-namespaces";
481
+ super([], endpoint);
482
+ }
483
+ };
484
+
485
+ // src/commands/management/namespaces/delete/index.ts
486
+ var DeleteNamespaceCommand = class extends Command {
487
+ constructor(namespace) {
488
+ const endpoint = `delete-namespace/${namespace}`;
489
+ super([], endpoint);
490
+ }
491
+ };
492
+
493
+ // src/vector.ts
494
+ var Index = class {
495
+ client;
496
+ /**
497
+ * Create a new vector db client
498
+ *
499
+ * @example
500
+ * ```typescript
501
+ * const index = new Index({
502
+ * url: "<UPSTASH_VECTOR_REST_URL>",
503
+ * token: "<UPSTASH_VECTOR_REST_TOKEN>",
504
+ * });
505
+ * ```
506
+ */
507
+ constructor(client) {
508
+ this.client = client;
509
+ }
510
+ namespace = (namespace) => new Namespace(this.client, namespace);
511
+ /**
512
+ * Deletes a specific item or items from the index by their ID(s). *
513
+ *
514
+ * @example
515
+ * ```js
516
+ * const result = await index.delete('test-id');
517
+ * // { deleted: 1 }
518
+ * ```
519
+ *
520
+ * @param id - List of ids or single id
521
+ * @returns Number of deleted vectors like `{ deleted: number }`. The number will be 0 if no vectors are deleted.
522
+ */
523
+ delete = (args, options) => new DeleteCommand(args, options).exec(this.client);
524
+ /**
525
+ * Queries an index with specified parameters.
526
+ * This method creates and executes a query command on an index based on the provided arguments.
527
+ *
528
+ * @example
529
+ * ```js
530
+ * await index.query({
531
+ * topK: 3,
532
+ * vector: [ 0.22, 0.66 ],
533
+ * filter: "age >= 23 and (type = \'turtle\' OR type = \'cat\')"
534
+ * });
535
+ * ```
536
+ *
537
+ * @param {Object} args - The arguments for the query command.
538
+ * @param {number[]} args.vector - An array of numbers representing the feature vector for the query.
539
+ * This vector is utilized to find the most relevant items in the index.
540
+ * @param {number} args.topK - The desired number of top results to be returned, based on relevance or similarity to the query vector.
541
+ * @param {string} [args.filter] - An optional filter string to be used in the query. The filter string is used to narrow down the query results.
542
+ * @param {boolean} [args.includeVectors=false] - When set to true, includes the feature vectors of the returned items in the response.
543
+ * @param {boolean} [args.includeMetadata=false] - When set to true, includes additional metadata of the returned items in the response.
544
+ * @param {boolean} [args.includeData=false] - When set to true, includes data - string - of the returned items in the response.
545
+ *
546
+ * A promise that resolves with an array of query result objects when the request to query the index is completed.
547
+ */
548
+ query = (args, options) => new QueryCommand(args, options).exec(this.client);
549
+ /**
550
+ * Queries an index with specified parameters.
551
+ * This method creates and executes a query command on an index based on the provided arguments.
552
+ *
553
+ * @example
554
+ * ```js
555
+ * await index.queryMany([
556
+ * {
557
+ * topK: 3,
558
+ * vector: [0.22, 0.66],
559
+ * filter: "age >= 23 and (type = 'turtle' OR type = 'cat')",
560
+ * },
561
+ * {
562
+ * topK: 3,
563
+ * vector: [0.45, 0.52],
564
+ * filter: "age >= 27 and (type = 'rabbit' OR type = 'dog')",
565
+ * },
566
+ * ]);
567
+ *
568
+ * ```
569
+ *
570
+ * @param {Object} args - The arguments for the query command.
571
+ * @param {number[]} args.vector - An array of numbers representing the feature vector for the query.
572
+ * This vector is utilized to find the most relevant items in the index.
573
+ * @param {number} args.topK - The desired number of top results to be returned, based on relevance or similarity to the query vector.
574
+ * @param {string} [args.filter] - An optional filter string to be used in the query. The filter string is used to narrow down the query results.
575
+ * @param {boolean} [args.includeVectors=false] - When set to true, includes the feature vectors of the returned items in the response.
576
+ * @param {boolean} [args.includeMetadata=false] - When set to true, includes additional metadata of the returned items in the response.
577
+ * @param {boolean} [args.includeData=false] - When set to true, includes data - string - of the returned items in the response.
578
+ *
579
+ * A promise that resolves with an array of arrays of query result objects,
580
+ * where each inner array represents a group of results matching a specific query condition.
581
+ */
582
+ queryMany = (args, options) => new QueryManyCommand(args, options).exec(this.client);
583
+ /**
584
+ * Initializes a resumable query operation on the vector database.
585
+ * This method allows for querying large result sets in multiple chunks or implementing pagination.
586
+ *
587
+ * @template TMetadata
588
+ * @param {ResumableQueryPayload} args - The arguments for the resumable query.
589
+ * @param {number} args.maxIdle - The maximum idle time in seconds before the query session expires.
590
+ * @param {number} args.topK - The number of top results to return in each fetch operation.
591
+ * @param {number[]} args.vector - The query vector used for similarity search.
592
+ * @param {boolean} [args.includeMetadata] - Whether to include metadata in the query results.
593
+ * @param {boolean} [args.includeVectors] - Whether to include vectors in the query results.
594
+ * @param {Object} [options] - Additional options for the query.
595
+ * @param {string} [options.namespace] - The namespace to query within.
596
+ * @returns {Promise<ResumableQuery<TMetadata>>} A promise that resolves to a ResumableQuery object.
597
+ * @example
598
+ * const { result, fetchNext, stop } = await index.resumableQuery({
599
+ * maxIdle: 3600,
600
+ * topK: 50,
601
+ * vector: [0.1, 0.2, 0.3, ...],
602
+ * includeMetadata: true,
603
+ * includeVectors: true
604
+ * }, { namespace: 'my-namespace' });
605
+ *
606
+ * const firstBatch = await fetchNext(10);
607
+ * const secondBatch = await fetchNext(10);
608
+ * await stop(); // End the query session
609
+ */
610
+ resumableQuery = async (args, options) => {
611
+ const resumableQuery = new ResumableQuery(args, this.client, options?.namespace);
612
+ const initialQuery = await resumableQuery.start();
613
+ const { fetchNext, stop } = resumableQuery;
614
+ return { fetchNext, stop, result: initialQuery.scores };
615
+ };
616
+ /**
617
+ * Upserts (Updates and Inserts) specific items into the index.
618
+ * It's used for adding new items to the index or updating existing ones.
619
+ *
620
+ * @example
621
+ * ```js
622
+ * const upsertArgs = {
623
+ * id: '123',
624
+ * vector: [0.42, 0.87, ...],
625
+ * metadata: { property1: 'value1', property2: 'value2' }
626
+ * };
627
+ * const upsertResult = await index.upsert(upsertArgs);
628
+ * console.log(upsertResult); // Outputs the result of the upsert operation
629
+ * ```
630
+ *
631
+ * @param {CommandArgs<typeof UpsertCommand>} args - The arguments for the upsert command.
632
+ * @param {number|string} args.id - The unique identifier for the item being upserted.
633
+ * @param {number[]} args.vector - The feature vector associated with the item.
634
+ * @param {Record<string, unknown>} [args.metadata] - Optional metadata to be associated with the item.
635
+ *
636
+ * @returns {string} A promise that resolves with the result of the upsert operation after the command is executed.
637
+ */
638
+ upsert = (args, options) => new UpsertCommand(args, options).exec(this.client);
639
+ /*
640
+ * Updates specific items in the index.
641
+ * It's used for updating existing items in the index.
642
+ *
643
+ * @example
644
+ * ```js
645
+ * const updateArgs = {
646
+ * id: '123',
647
+ * vector: [0.42, 0.87, ...],
648
+ * metadata: { property1: 'value1', property2: 'value2' }
649
+ * };
650
+ * const updateResult = await index.update(updateArgs);
651
+ * console.log(updateResult); // Outputs the result of the update operation
652
+ * ```
653
+ *
654
+ * @param {CommandArgs<typeof UpdateCommand>} args - The arguments for the update command.
655
+ * @param {number|string} args.id - The unique identifier for the item being updated.
656
+ * @param {number[]} args.vector - The feature vector associated with the item.
657
+ * @param {Record<string, unknown>} [args.metadata] - Optional metadata to be associated with the item.
658
+ * @param {string} [args.namespace] - The namespace to update the item in.
659
+ *
660
+ * @returns {Promise<{updated: number}>} A promise that returns the number of items successfully updated.
661
+ */
662
+ update = (args, options) => new UpdateCommand(args, options).exec(this.client);
663
+ /**
664
+ * It's used for retrieving specific items from the index, optionally including
665
+ * their metadata and feature vectors.
666
+ *
667
+ * @example
668
+ * ```js
669
+ * const fetchIds = ['123', '456'];
670
+ * const fetchOptions = { includeMetadata: true, includeVectors: false };
671
+ * const fetchResults = await index.fetch(fetchIds, fetchOptions);
672
+ * console.log(fetchResults); // Outputs the fetched items
673
+ * ```
674
+ *
675
+ * @param {...CommandArgs<typeof FetchCommand>} args - The arguments for the fetch command.
676
+ * @param {(number[]|string[])} args - An array of IDs of the items to be fetched.
677
+ * @param {FetchCommandOptions} args - Options for the fetch operation.
678
+ * @param {boolean} [args.includeMetadata=false] - Optionally include metadata of the fetched items.
679
+ * @param {boolean} [args.includeVectors=false] - Optionally include feature vectors of the fetched items.
680
+ * @param {boolean} [args.metadataUpdateMode="OVERWRITE"] - Specifies whether to overwrite or patch the metadata values.
681
+ *
682
+ * @returns {Promise<FetchReturnResponse<TMetadata>[]>} A promise that resolves with an array of fetched items or null if not found, after the command is executed.
683
+ */
684
+ fetch = (...args) => new FetchCommand(args).exec(this.client);
685
+ /**
686
+ * It's used for wiping the index.
687
+ *
688
+ * By default, resets the default namespace:
689
+ *
690
+ * @example
691
+ * ```js
692
+ * await index.reset();
693
+ * console.log('Default namespace has been reset');
694
+ * ```
695
+ *
696
+ * To reset a namespace, call reset like:
697
+ *
698
+ * @example
699
+ * ```js
700
+ * await index.reset({ namespace: "ns" });
701
+ * console.log('Namespace ns has been reset');
702
+ * ```
703
+ *
704
+ * If you want to reset all namespaces, call reset like:
705
+ *
706
+ * @example
707
+ * ```js
708
+ * await index.reset({ all: true });
709
+ * console.log('All namespaces have been reset');
710
+ * ```
711
+ *
712
+ * @returns {Promise<string>} A promise that resolves with the result of the reset operation after the command is executed.
713
+ */
714
+ reset = (options) => new ResetCommand(options).exec(this.client);
715
+ /**
716
+ * Retrieves a range of items from the index.
717
+ *
718
+ * @example
719
+ * ```js
720
+ * const rangeArgs = {
721
+ * cursor: 0,
722
+ * limit: 10,
723
+ * includeVectors: true,
724
+ * includeMetadata: false
725
+ * };
726
+ * const rangeResults = await index.range(rangeArgs);
727
+ * console.log(rangeResults); // Outputs the result of the range operation
728
+ * ```
729
+ *
730
+ * You can also pass a namespace like:
731
+ *
732
+ * ```js
733
+ * const rangeResults = await index.range(rangeArgs, { namespace: "ns" });
734
+ * ```
735
+ *
736
+ * @param {CommandArgs<typeof RangeCommand>} args - The arguments for the range command.
737
+ * @param {number|string} args.cursor - The starting point (cursor) for the range query.
738
+ * @param {number} args.limit - The maximum number of items to return in this range.
739
+ * @param {boolean} [args.includeVectors=false] - Optionally include the feature vectors of the items in the response.
740
+ * @param {boolean} [args.includeMetadata=false] - Optionally include additional metadata of the items in the response.
741
+ *
742
+ * @returns {Promise<RangeReturnResponse<TMetadata>>} A promise that resolves with the response containing the next cursor and an array of vectors, after the command is executed.
743
+ */
744
+ range = (args, options) => new RangeCommand(args, options).exec(this.client);
745
+ /**
746
+ * Retrieves info from the index.
747
+ *
748
+ * @example
749
+ * ```js
750
+ * const infoResults = await index.info();
751
+ * console.log(infoResults); // Outputs the result of the info operation
752
+ * ```
753
+ *
754
+ * @returns {Promise<InfoResult>} A promise that resolves with the response containing the vectorCount, pendingVectorCount, indexSize, dimension count and similarity algorithm after the command is executed.
755
+ */
756
+ info = () => new InfoCommand().exec(this.client);
757
+ /**
758
+ * List all namespaces in the vector database.
759
+ *
760
+ * @example
761
+ * ```js
762
+ * const namespaces = await index.listNamespaces();
763
+ * console.log(namespaces); // Outputs the list of namespaces
764
+ * ```
765
+ *
766
+ * @returns {Promise<string[]>} A promise that resolves with an array of namespaces after the command is executed.
767
+ */
768
+ listNamespaces = () => new ListNamespacesCommand().exec(this.client);
769
+ /**
770
+ * Deletes a namespace from the vector database.
771
+ *
772
+ * @example
773
+ * ```js
774
+ * await index.deleteNamespace('namespace');
775
+ * console.log('Namespace has been deleted');
776
+ * ```
777
+ *
778
+ * @param {string} namespace - The name of the namespace to be deleted.
779
+ * @returns {Promise<string>} A promise that resolves with the result of the delete operation after the command is executed.
780
+ */
781
+ deleteNamespace = (namespace) => new DeleteNamespaceCommand(namespace).exec(this.client);
782
+ };
783
+
784
+ // src/platforms/nodejs.ts
785
+ var Index2 = class _Index extends Index {
786
+ constructor(configOrRequester) {
787
+ if (configOrRequester !== void 0 && "request" in configOrRequester) {
788
+ super(configOrRequester);
789
+ return;
790
+ }
791
+ const token = configOrRequester?.token ?? process.env.NEXT_PUBLIC_UPSTASH_VECTOR_REST_TOKEN ?? process.env.UPSTASH_VECTOR_REST_TOKEN;
792
+ const url = configOrRequester?.url ?? process.env.NEXT_PUBLIC_UPSTASH_VECTOR_REST_URL ?? process.env.UPSTASH_VECTOR_REST_URL;
793
+ if (!token) {
794
+ throw new Error("UPSTASH_VECTOR_REST_TOKEN is missing!");
795
+ }
796
+ if (!url) {
797
+ throw new Error("UPSTASH_VECTOR_REST_URL is missing!");
798
+ }
799
+ if (url.startsWith(" ") || url.endsWith(" ") || /\r|\n/.test(url)) {
800
+ console.warn("The vector url contains whitespace or newline, which can cause errors!");
801
+ }
802
+ if (token.startsWith(" ") || token.endsWith(" ") || /\r|\n/.test(token)) {
803
+ console.warn("The vector token contains whitespace or newline, which can cause errors!");
804
+ }
805
+ const client = new HttpClient({
806
+ baseUrl: url,
807
+ retry: configOrRequester?.retry,
808
+ headers: { authorization: `Bearer ${token}` },
809
+ cache: configOrRequester?.cache === false ? void 0 : configOrRequester?.cache || "no-store",
810
+ signal: configOrRequester?.signal
811
+ });
812
+ super(client);
813
+ }
814
+ /**
815
+ * Create a new Upstash Vector instance from environment variables.
816
+ *
817
+ * Use this to automatically load connection secrets from your environment
818
+ * variables. For instance when using the Vercel integration.
819
+ *
820
+ * When used on the Cloudflare Workers, you can just pass the "env" context provided by Cloudflare.
821
+ * Else, this tries to load `UPSTASH_VECTOR_REST_URL` and `UPSTASH_VECTOR_REST_TOKEN` from
822
+ * your environment using `process.env`.
823
+ */
824
+ static fromEnv(env, config) {
825
+ const url = env?.UPSTASH_VECTOR_REST_URL || process?.env.UPSTASH_VECTOR_REST_URL;
826
+ const token = env?.UPSTASH_VECTOR_REST_TOKEN || process?.env.UPSTASH_VECTOR_REST_TOKEN;
827
+ if (!url) {
828
+ throw new Error("Unable to find environment variable: `UPSTASH_VECTOR_REST_URL`");
829
+ }
830
+ if (!token) {
831
+ throw new Error("Unable to find environment variable: `UPSTASH_VECTOR_REST_TOKEN`");
832
+ }
833
+ return new _Index({ ...config, url, token });
834
+ }
835
+ };
836
+ // Annotate the CommonJS export names for ESM import in node:
837
+ 0 && (module.exports = {
838
+ Index
839
+ });