@upstash/vector 1.0.3 → 1.0.5-canary
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 +26 -0
- package/dist/index.d.mts +24 -5
- package/dist/index.d.ts +24 -5
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Upstash Vector Node.js Client ·  [](https://github.com/upstash/vector-js/actions/workflows/tests.yaml)   
|
|
2
2
|
|
|
3
|
+
> [!NOTE] > **This project is in GA Stage.**
|
|
4
|
+
>
|
|
5
|
+
> The Upstash Professional Support fully covers this project. It receives regular updates, and bug fixes. The Upstash team is committed to maintaining and improving its functionality.
|
|
6
|
+
|
|
3
7
|
`@upstash/vector` is an HTTP/REST based client for Typescript, built on top of [Upstash REST API](https://upstash.com/docs/vector/api/endpoints/).
|
|
4
8
|
|
|
5
9
|
It is the only connectionless (HTTP based) Vector client and designed for:
|
|
@@ -64,8 +68,11 @@ const results = await index.query<Metadata>({
|
|
|
64
68
|
includeVectors: true,
|
|
65
69
|
includeMetadata: true
|
|
66
70
|
topK: 1,
|
|
71
|
+
filter: "genre = 'fantasy' and title = 'Lord of the Rings'"
|
|
67
72
|
})
|
|
68
73
|
|
|
74
|
+
// If you wanna learn more about filtering check: [Metadata Filtering](https://upstash.com/docs/vector/features/filtering)
|
|
75
|
+
|
|
69
76
|
//Update Data
|
|
70
77
|
await index.upsert({
|
|
71
78
|
id: "upstash-rocks",
|
|
@@ -102,6 +109,10 @@ await index.info();
|
|
|
102
109
|
await index.random();
|
|
103
110
|
```
|
|
104
111
|
|
|
112
|
+
## Metadata Filtering
|
|
113
|
+
|
|
114
|
+
If you wanna learn more about filtering check: [Metadata Filtering](https://upstash.com/docs/vector/features/filtering)
|
|
115
|
+
|
|
105
116
|
## Troubleshooting
|
|
106
117
|
|
|
107
118
|
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).
|
|
@@ -129,3 +140,18 @@ bun run test
|
|
|
129
140
|
```sh
|
|
130
141
|
bun run build
|
|
131
142
|
```
|
|
143
|
+
|
|
144
|
+
### Contributing
|
|
145
|
+
|
|
146
|
+
Make sure you have Bun.js installed and have those relevant keys with specific vector dimensions:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
|
|
150
|
+
## Vector dimension should be 2
|
|
151
|
+
UPSTASH_VECTOR_REST_URL="XXXXX"
|
|
152
|
+
UPSTASH_VECTOR_REST_TOKEN="XXXXX"
|
|
153
|
+
|
|
154
|
+
## Vector dimension should be 384
|
|
155
|
+
EMBEDDING_UPSTASH_VECTOR_REST_URL="XXXXX"
|
|
156
|
+
EMBEDDING_UPSTASH_VECTOR_REST_TOKEN="XXXXX"
|
|
157
|
+
```
|
package/dist/index.d.mts
CHANGED
|
@@ -42,7 +42,7 @@ type RequesterConfig = {
|
|
|
42
42
|
cache?: CacheSetting;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
declare const ENDPOINTS: readonly ["upsert", "query", "delete", "fetch", "reset", "range", "info"];
|
|
45
|
+
declare const ENDPOINTS: readonly ["upsert", "query", "delete", "fetch", "reset", "range", "info", "upsert-data", "query-data"];
|
|
46
46
|
type EndpointVariants = (typeof ENDPOINTS)[number];
|
|
47
47
|
/**
|
|
48
48
|
* TResult is the raw data returned from upstash, which may need to be transformed or parsed.
|
|
@@ -72,11 +72,17 @@ type Vector<TMetadata = Record<string, unknown>> = {
|
|
|
72
72
|
type FetchResult<TMetadata = Record<string, unknown>> = Vector<TMetadata> | null;
|
|
73
73
|
|
|
74
74
|
type QueryCommandPayload = {
|
|
75
|
-
vector: number[];
|
|
76
75
|
topK: number;
|
|
76
|
+
filter?: string;
|
|
77
77
|
includeVectors?: boolean;
|
|
78
78
|
includeMetadata?: boolean;
|
|
79
|
-
}
|
|
79
|
+
} & ({
|
|
80
|
+
vector: number[];
|
|
81
|
+
data?: never;
|
|
82
|
+
} | {
|
|
83
|
+
data: string;
|
|
84
|
+
vector?: never;
|
|
85
|
+
});
|
|
80
86
|
type QueryResult<TMetadata = Record<string, unknown>> = {
|
|
81
87
|
id: number | string;
|
|
82
88
|
score: number;
|
|
@@ -147,13 +153,18 @@ declare class Index$1<TIndexMetadata extends Record<string, unknown> = Record<st
|
|
|
147
153
|
*
|
|
148
154
|
* @example
|
|
149
155
|
* ```js
|
|
150
|
-
* await index.query({
|
|
156
|
+
* await index.query({
|
|
157
|
+
* topK: 3,
|
|
158
|
+
* vector: [ 0.22, 0.66 ],
|
|
159
|
+
* filter: "age >= 23 and (type = \'turtle\' OR type = \'cat\')"
|
|
160
|
+
* });
|
|
151
161
|
* ```
|
|
152
162
|
*
|
|
153
163
|
* @param {Object} args - The arguments for the query command.
|
|
154
164
|
* @param {number[]} args.vector - An array of numbers representing the feature vector for the query.
|
|
155
165
|
* This vector is utilized to find the most relevant items in the index.
|
|
156
166
|
* @param {number} args.topK - The desired number of top results to be returned, based on relevance or similarity to the query vector.
|
|
167
|
+
* @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.
|
|
157
168
|
* @param {boolean} [args.includeVectors=false] - When set to true, includes the feature vectors of the returned items in the response.
|
|
158
169
|
* @param {boolean} [args.includeMetadata=false] - When set to true, includes additional metadata of the returned items in the response.
|
|
159
170
|
*
|
|
@@ -187,10 +198,18 @@ declare class Index$1<TIndexMetadata extends Record<string, unknown> = Record<st
|
|
|
187
198
|
vector: number[];
|
|
188
199
|
metadata?: (TMetadata extends infer U ? U : never) | undefined;
|
|
189
200
|
} | {
|
|
201
|
+
id: string | number;
|
|
202
|
+
data: string;
|
|
203
|
+
metadata?: (TMetadata extends infer U ? U : never) | undefined;
|
|
204
|
+
} | ({
|
|
190
205
|
id: string | number;
|
|
191
206
|
vector: number[];
|
|
192
207
|
metadata?: (TMetadata extends infer U ? U : never) | undefined;
|
|
193
|
-
}[]
|
|
208
|
+
}[] | {
|
|
209
|
+
id: string | number;
|
|
210
|
+
data: string;
|
|
211
|
+
metadata?: (TMetadata extends infer U ? U : never) | undefined;
|
|
212
|
+
}[])) => Promise<string>;
|
|
194
213
|
/**
|
|
195
214
|
* It's used for retrieving specific items from the index, optionally including
|
|
196
215
|
* their metadata and feature vectors.
|
package/dist/index.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ type RequesterConfig = {
|
|
|
42
42
|
cache?: CacheSetting;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
declare const ENDPOINTS: readonly ["upsert", "query", "delete", "fetch", "reset", "range", "info"];
|
|
45
|
+
declare const ENDPOINTS: readonly ["upsert", "query", "delete", "fetch", "reset", "range", "info", "upsert-data", "query-data"];
|
|
46
46
|
type EndpointVariants = (typeof ENDPOINTS)[number];
|
|
47
47
|
/**
|
|
48
48
|
* TResult is the raw data returned from upstash, which may need to be transformed or parsed.
|
|
@@ -72,11 +72,17 @@ type Vector<TMetadata = Record<string, unknown>> = {
|
|
|
72
72
|
type FetchResult<TMetadata = Record<string, unknown>> = Vector<TMetadata> | null;
|
|
73
73
|
|
|
74
74
|
type QueryCommandPayload = {
|
|
75
|
-
vector: number[];
|
|
76
75
|
topK: number;
|
|
76
|
+
filter?: string;
|
|
77
77
|
includeVectors?: boolean;
|
|
78
78
|
includeMetadata?: boolean;
|
|
79
|
-
}
|
|
79
|
+
} & ({
|
|
80
|
+
vector: number[];
|
|
81
|
+
data?: never;
|
|
82
|
+
} | {
|
|
83
|
+
data: string;
|
|
84
|
+
vector?: never;
|
|
85
|
+
});
|
|
80
86
|
type QueryResult<TMetadata = Record<string, unknown>> = {
|
|
81
87
|
id: number | string;
|
|
82
88
|
score: number;
|
|
@@ -147,13 +153,18 @@ declare class Index$1<TIndexMetadata extends Record<string, unknown> = Record<st
|
|
|
147
153
|
*
|
|
148
154
|
* @example
|
|
149
155
|
* ```js
|
|
150
|
-
* await index.query({
|
|
156
|
+
* await index.query({
|
|
157
|
+
* topK: 3,
|
|
158
|
+
* vector: [ 0.22, 0.66 ],
|
|
159
|
+
* filter: "age >= 23 and (type = \'turtle\' OR type = \'cat\')"
|
|
160
|
+
* });
|
|
151
161
|
* ```
|
|
152
162
|
*
|
|
153
163
|
* @param {Object} args - The arguments for the query command.
|
|
154
164
|
* @param {number[]} args.vector - An array of numbers representing the feature vector for the query.
|
|
155
165
|
* This vector is utilized to find the most relevant items in the index.
|
|
156
166
|
* @param {number} args.topK - The desired number of top results to be returned, based on relevance or similarity to the query vector.
|
|
167
|
+
* @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.
|
|
157
168
|
* @param {boolean} [args.includeVectors=false] - When set to true, includes the feature vectors of the returned items in the response.
|
|
158
169
|
* @param {boolean} [args.includeMetadata=false] - When set to true, includes additional metadata of the returned items in the response.
|
|
159
170
|
*
|
|
@@ -187,10 +198,18 @@ declare class Index$1<TIndexMetadata extends Record<string, unknown> = Record<st
|
|
|
187
198
|
vector: number[];
|
|
188
199
|
metadata?: (TMetadata extends infer U ? U : never) | undefined;
|
|
189
200
|
} | {
|
|
201
|
+
id: string | number;
|
|
202
|
+
data: string;
|
|
203
|
+
metadata?: (TMetadata extends infer U ? U : never) | undefined;
|
|
204
|
+
} | ({
|
|
190
205
|
id: string | number;
|
|
191
206
|
vector: number[];
|
|
192
207
|
metadata?: (TMetadata extends infer U ? U : never) | undefined;
|
|
193
|
-
}[]
|
|
208
|
+
}[] | {
|
|
209
|
+
id: string | number;
|
|
210
|
+
data: string;
|
|
211
|
+
metadata?: (TMetadata extends infer U ? U : never) | undefined;
|
|
212
|
+
}[])) => Promise<string>;
|
|
194
213
|
/**
|
|
195
214
|
* It's used for retrieving specific items from the index, optionally including
|
|
196
215
|
* their metadata and feature vectors.
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var x=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var
|
|
1
|
+
"use strict";var x=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var M=Object.prototype.hasOwnProperty;var S=(n,e)=>{for(var t in e)x(n,t,{get:e[t],enumerable:!0})},U=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of E(e))!M.call(n,a)&&a!==t&&x(n,a,{get:()=>e[a],enumerable:!(r=w(e,a))||r.enumerable});return n};var _=n=>U(x({},"__esModule",{value:!0}),n);var P={};S(P,{Index:()=>g});module.exports=_(P);var s=class extends Error{constructor(e){super(e),this.name="UpstashError"}};var i=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},typeof e?.retry=="boolean"&&e?.retry===!1?this.retry={attempts:1,backoff:()=>0}:this.retry={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},r=null,a=null;for(let f=0;f<=this.retry.attempts;f++)try{r=await fetch([this.baseUrl,...e.path??[]].join("/"),t);break}catch(b){if(this.options.signal?.aborted){let R=new Blob([JSON.stringify({result:this.options.signal.reason??"Aborted"})]),C={status:200,statusText:this.options.signal.reason??"Aborted"};r=new Response(R,C);break}a=b,await new Promise(R=>setTimeout(R,this.retry.backoff(f)))}if(!r)throw a??new Error("Exhausted all retries");let T=await r.json();if(!r.ok)throw new s(`${T.error}`);return{result:T.result,error:T.error}}};var o=class{payload;endpoint;constructor(e,t){this.payload=e,this.endpoint=t}async exec(e){let{result:t,error:r}=await e.request({body:this.payload,path:[this.endpoint]});if(r)throw new s(r);if(typeof t>"u")throw new Error("Request did not return a result");return t}};var d=class extends o{constructor(e){let t=[];Array.isArray(e)?t.push(...e):t.push(e),super(t,"delete")}};var p=class extends o{constructor(e){let t="query";"data"in e&&(t="query-data"),super(e,t)}};var c=class extends o{constructor(e){let t="upsert";Array.isArray(e)?e.some(a=>"data"in a&&a.data)&&(t="upsert-data"):"data"in e&&(t="upsert-data"),super(e,t)}};var u=class extends o{constructor([e,t]){super({ids:e,...t},"fetch")}};var l=class extends o{constructor(e){super(e,"range")}};var m=class extends o{constructor(){super([],"reset")}};var h=class extends o{constructor(){super([],"info")}};var y=class{client;constructor(e){this.client=e}delete=e=>new d(e).exec(this.client);query=e=>new p(e).exec(this.client);upsert=e=>new c(e).exec(this.client);fetch=(...e)=>new u(e).exec(this.client);reset=()=>new m().exec(this.client);range=e=>new l(e).exec(this.client);info=()=>new h().exec(this.client)};var g=class n extends y{constructor(e){if(typeof e<"u"&&"request"in e){super(e);return}let t=e?.token??process.env.NEXT_PUBLIC_UPSTASH_VECTOR_REST_TOKEN??process.env.UPSTASH_VECTOR_REST_TOKEN,r=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(!r)throw new Error("UPSTASH_VECTOR_REST_URL is missing!");(r.startsWith(" ")||r.endsWith(" ")||/\r|\n/.test(r))&&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 a=new i({baseUrl:r,retry:e?.retry,headers:{authorization:`Bearer ${t}`},cache:e?.cache||"no-store",signal:e?.signal});super(a)}static fromEnv(e){let t=process?.env.UPSTASH_VECTOR_REST_URL;if(!t)throw new Error("Unable to find environment variable: `UPSTASH_VECTOR_REST_URL`");let r=process?.env.UPSTASH_VECTOR_REST_TOKEN;if(!r)throw new Error("Unable to find environment variable: `UPSTASH_VECTOR_REST_TOKEN`");return new n({...e,url:t,token:r})}};0&&(module.exports={Index});
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var s=class extends Error{constructor(e){super(e),this.name="UpstashError"}};var i=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},typeof e?.retry=="boolean"&&e?.retry===!1?this.retry={attempts:1,backoff:()=>0}:this.retry={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},r=null,a=null;for(let
|
|
1
|
+
var s=class extends Error{constructor(e){super(e),this.name="UpstashError"}};var i=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},typeof e?.retry=="boolean"&&e?.retry===!1?this.retry={attempts:1,backoff:()=>0}:this.retry={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},r=null,a=null;for(let f=0;f<=this.retry.attempts;f++)try{r=await fetch([this.baseUrl,...e.path??[]].join("/"),t);break}catch(g){if(this.options.signal?.aborted){let R=new Blob([JSON.stringify({result:this.options.signal.reason??"Aborted"})]),b={status:200,statusText:this.options.signal.reason??"Aborted"};r=new Response(R,b);break}a=g,await new Promise(R=>setTimeout(R,this.retry.backoff(f)))}if(!r)throw a??new Error("Exhausted all retries");let T=await r.json();if(!r.ok)throw new s(`${T.error}`);return{result:T.result,error:T.error}}};var n=class{payload;endpoint;constructor(e,t){this.payload=e,this.endpoint=t}async exec(e){let{result:t,error:r}=await e.request({body:this.payload,path:[this.endpoint]});if(r)throw new s(r);if(typeof t>"u")throw new Error("Request did not return a result");return t}};var d=class extends n{constructor(e){let t=[];Array.isArray(e)?t.push(...e):t.push(e),super(t,"delete")}};var p=class extends n{constructor(e){let t="query";"data"in e&&(t="query-data"),super(e,t)}};var c=class extends n{constructor(e){let t="upsert";Array.isArray(e)?e.some(a=>"data"in a&&a.data)&&(t="upsert-data"):"data"in e&&(t="upsert-data"),super(e,t)}};var u=class extends n{constructor([e,t]){super({ids:e,...t},"fetch")}};var l=class extends n{constructor(e){super(e,"range")}};var m=class extends n{constructor(){super([],"reset")}};var h=class extends n{constructor(){super([],"info")}};var y=class{client;constructor(e){this.client=e}delete=e=>new d(e).exec(this.client);query=e=>new p(e).exec(this.client);upsert=e=>new c(e).exec(this.client);fetch=(...e)=>new u(e).exec(this.client);reset=()=>new m().exec(this.client);range=e=>new l(e).exec(this.client);info=()=>new h().exec(this.client)};var x=class o extends y{constructor(e){if(typeof e<"u"&&"request"in e){super(e);return}let t=e?.token??process.env.NEXT_PUBLIC_UPSTASH_VECTOR_REST_TOKEN??process.env.UPSTASH_VECTOR_REST_TOKEN,r=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(!r)throw new Error("UPSTASH_VECTOR_REST_URL is missing!");(r.startsWith(" ")||r.endsWith(" ")||/\r|\n/.test(r))&&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 a=new i({baseUrl:r,retry:e?.retry,headers:{authorization:`Bearer ${t}`},cache:e?.cache||"no-store",signal:e?.signal});super(a)}static fromEnv(e){let t=process?.env.UPSTASH_VECTOR_REST_URL;if(!t)throw new Error("Unable to find environment variable: `UPSTASH_VECTOR_REST_URL`");let r=process?.env.UPSTASH_VECTOR_REST_TOKEN;if(!r)throw new Error("Unable to find environment variable: `UPSTASH_VECTOR_REST_TOKEN`");return new o({...e,url:t,token:r})}};export{x as Index};
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{ "name": "@upstash/vector", "version": "v1.0.
|
|
1
|
+
{ "name": "@upstash/vector", "version": "v1.0.5-canary", "author": "Oguzhan Olguncu <oguzhan@upstash.com>", "repository": { "type": "git", "url": "https://github.com/upstash/vector-js" }, "main": "./dist/index.js", "module": "./dist/index.mjs", "devDependencies": { "@biomejs/biome": "^1.4.1", "@commitlint/cli": "^18.6.0", "@commitlint/config-conventional": "^18.6.0", "bun-types": "latest", "husky": "^8.0.3", "tsup": "latest", "typescript": "^5.0.0", "vitest": "^1.2.2" }, "bugs": { "url": "https://github.com/upstash/vector/issues" }, "description": "An HTTP/REST based Vector DB client built on top of Upstash REST API.", "files": [ "dist" ], "homepage": "https://upstash.com/vector", "keywords": [ "vector", "upstash", "db" ], "license": "MIT", "scripts": { "test": "bun test src --coverage --bail --coverageSkipTestFiles=[test-utils.ts] && vitest run --typecheck", "fmt": "bunx biome check --apply ./src", "build": "tsup", "prepare": "husky install" }, "types": "./dist/index.d.ts" }
|