@lancedb/lancedb 0.5.1 → 0.7.0
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/Cargo.toml +3 -3
- package/biome.json +19 -3
- package/dist/arrow.d.ts +42 -7
- package/dist/arrow.js +6 -5
- package/dist/connection.d.ts +55 -29
- package/dist/connection.js +22 -74
- package/dist/embedding/embedding_function.d.ts +11 -3
- package/dist/embedding/embedding_function.js +36 -12
- package/dist/embedding/openai.d.ts +6 -5
- package/dist/embedding/openai.js +4 -2
- package/dist/embedding/registry.d.ts +10 -11
- package/dist/embedding/registry.js +4 -0
- package/dist/index.d.ts +51 -3
- package/dist/index.js +28 -4
- package/dist/merge.d.ts +54 -0
- package/dist/merge.js +64 -0
- package/dist/native.d.ts +34 -7
- package/dist/native.js +26 -9
- package/dist/query.d.ts +51 -16
- package/dist/query.js +122 -21
- package/dist/remote/client.d.ts +28 -0
- package/dist/remote/client.js +172 -0
- package/dist/remote/connection.d.ts +25 -0
- package/dist/remote/connection.js +110 -0
- package/dist/remote/index.d.ts +3 -0
- package/dist/remote/index.js +9 -0
- package/dist/remote/table.d.ts +42 -0
- package/dist/remote/table.js +179 -0
- package/dist/sanitize.d.ts +3 -2
- package/dist/sanitize.js +55 -1
- package/dist/table.d.ts +116 -25
- package/dist/table.js +117 -233
- package/dist/util.d.ts +14 -0
- package/dist/util.js +65 -0
- package/examples/ann_indexes.ts +49 -0
- package/examples/basic.ts +149 -0
- package/examples/embedding.ts +83 -0
- package/examples/filtering.ts +34 -0
- package/examples/jsconfig.json +27 -0
- package/examples/package-lock.json +79 -0
- package/examples/package.json +18 -0
- package/examples/search.ts +37 -0
- package/lancedb/arrow.ts +87 -24
- package/lancedb/connection.ts +115 -92
- package/lancedb/embedding/embedding_function.ts +48 -16
- package/lancedb/embedding/openai.ts +11 -6
- package/lancedb/embedding/registry.ts +38 -22
- package/lancedb/index.ts +101 -2
- package/lancedb/merge.ts +70 -0
- package/lancedb/query.ts +168 -39
- package/lancedb/remote/client.ts +221 -0
- package/lancedb/remote/connection.ts +201 -0
- package/lancedb/remote/index.ts +3 -0
- package/lancedb/remote/table.ts +226 -0
- package/lancedb/sanitize.ts +73 -1
- package/lancedb/table.ts +344 -101
- package/lancedb/util.ts +69 -0
- package/native.d.ts +208 -0
- package/nodejs-artifacts/arrow.d.ts +42 -7
- package/nodejs-artifacts/arrow.js +6 -5
- package/nodejs-artifacts/connection.d.ts +55 -29
- package/nodejs-artifacts/connection.js +22 -74
- package/nodejs-artifacts/embedding/embedding_function.d.ts +11 -3
- package/nodejs-artifacts/embedding/embedding_function.js +36 -12
- package/nodejs-artifacts/embedding/openai.d.ts +6 -5
- package/nodejs-artifacts/embedding/openai.js +4 -2
- package/nodejs-artifacts/embedding/registry.d.ts +10 -11
- package/nodejs-artifacts/embedding/registry.js +4 -0
- package/nodejs-artifacts/index.d.ts +51 -3
- package/nodejs-artifacts/index.js +28 -4
- package/nodejs-artifacts/merge.d.ts +54 -0
- package/nodejs-artifacts/merge.js +64 -0
- package/nodejs-artifacts/native.d.ts +34 -7
- package/nodejs-artifacts/native.js +26 -9
- package/nodejs-artifacts/query.d.ts +51 -16
- package/nodejs-artifacts/query.js +122 -21
- package/nodejs-artifacts/remote/client.d.ts +28 -0
- package/nodejs-artifacts/remote/client.js +172 -0
- package/nodejs-artifacts/remote/connection.d.ts +25 -0
- package/nodejs-artifacts/remote/connection.js +110 -0
- package/nodejs-artifacts/remote/index.d.ts +3 -0
- package/nodejs-artifacts/remote/index.js +9 -0
- package/nodejs-artifacts/remote/table.d.ts +42 -0
- package/nodejs-artifacts/remote/table.js +179 -0
- package/nodejs-artifacts/sanitize.d.ts +3 -2
- package/nodejs-artifacts/sanitize.js +55 -1
- package/nodejs-artifacts/table.d.ts +116 -25
- package/nodejs-artifacts/table.js +117 -233
- package/nodejs-artifacts/util.d.ts +14 -0
- package/nodejs-artifacts/util.js +65 -0
- package/package.json +25 -11
package/dist/query.js
CHANGED
|
@@ -43,6 +43,18 @@ class RecordBatchIterator {
|
|
|
43
43
|
}
|
|
44
44
|
exports.RecordBatchIterator = RecordBatchIterator;
|
|
45
45
|
/* eslint-enable */
|
|
46
|
+
class RecordBatchIterable {
|
|
47
|
+
inner;
|
|
48
|
+
options;
|
|
49
|
+
constructor(inner, options) {
|
|
50
|
+
this.inner = inner;
|
|
51
|
+
this.options = options;
|
|
52
|
+
}
|
|
53
|
+
// biome-ignore lint/suspicious/noExplicitAny: skip
|
|
54
|
+
[Symbol.asyncIterator]() {
|
|
55
|
+
return new RecordBatchIterator(this.inner.execute(this.options?.maxBatchLength));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
46
58
|
/** Common methods supported by all query types */
|
|
47
59
|
class QueryBase {
|
|
48
60
|
inner;
|
|
@@ -50,6 +62,18 @@ class QueryBase {
|
|
|
50
62
|
this.inner = inner;
|
|
51
63
|
// intentionally empty
|
|
52
64
|
}
|
|
65
|
+
// call a function on the inner (either a promise or the actual object)
|
|
66
|
+
doCall(fn) {
|
|
67
|
+
if (this.inner instanceof Promise) {
|
|
68
|
+
this.inner = this.inner.then((inner) => {
|
|
69
|
+
fn(inner);
|
|
70
|
+
return inner;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
fn(this.inner);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
53
77
|
/**
|
|
54
78
|
* A filter statement to be applied to this query.
|
|
55
79
|
*
|
|
@@ -63,9 +87,17 @@ class QueryBase {
|
|
|
63
87
|
* on the filter column(s).
|
|
64
88
|
*/
|
|
65
89
|
where(predicate) {
|
|
66
|
-
this.inner.onlyIf(predicate);
|
|
90
|
+
this.doCall((inner) => inner.onlyIf(predicate));
|
|
67
91
|
return this;
|
|
68
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* A filter statement to be applied to this query.
|
|
95
|
+
* @alias where
|
|
96
|
+
* @deprecated Use `where` instead
|
|
97
|
+
*/
|
|
98
|
+
filter(predicate) {
|
|
99
|
+
return this.where(predicate);
|
|
100
|
+
}
|
|
69
101
|
/**
|
|
70
102
|
* Return only the specified columns.
|
|
71
103
|
*
|
|
@@ -98,6 +130,9 @@ class QueryBase {
|
|
|
98
130
|
*/
|
|
99
131
|
select(columns) {
|
|
100
132
|
let columnTuples;
|
|
133
|
+
if (typeof columns === "string") {
|
|
134
|
+
columns = [columns];
|
|
135
|
+
}
|
|
101
136
|
if (Array.isArray(columns)) {
|
|
102
137
|
columnTuples = columns.map((c) => [c, c]);
|
|
103
138
|
}
|
|
@@ -107,7 +142,9 @@ class QueryBase {
|
|
|
107
142
|
else {
|
|
108
143
|
columnTuples = Object.entries(columns);
|
|
109
144
|
}
|
|
110
|
-
this.inner
|
|
145
|
+
this.doCall((inner) => {
|
|
146
|
+
inner.select(columnTuples);
|
|
147
|
+
});
|
|
111
148
|
return this;
|
|
112
149
|
}
|
|
113
150
|
/**
|
|
@@ -117,11 +154,16 @@ class QueryBase {
|
|
|
117
154
|
* called then every valid row from the table will be returned.
|
|
118
155
|
*/
|
|
119
156
|
limit(limit) {
|
|
120
|
-
this.inner.limit(limit);
|
|
157
|
+
this.doCall((inner) => inner.limit(limit));
|
|
121
158
|
return this;
|
|
122
159
|
}
|
|
123
|
-
nativeExecute() {
|
|
124
|
-
|
|
160
|
+
nativeExecute(options) {
|
|
161
|
+
if (this.inner instanceof Promise) {
|
|
162
|
+
return this.inner.then((inner) => inner.execute(options?.maxBatchLength));
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
return this.inner.execute(options?.maxBatchLength);
|
|
166
|
+
}
|
|
125
167
|
}
|
|
126
168
|
/**
|
|
127
169
|
* Execute the query and return the results as an @see {@link AsyncIterator}
|
|
@@ -134,8 +176,8 @@ class QueryBase {
|
|
|
134
176
|
* single query)
|
|
135
177
|
*
|
|
136
178
|
*/
|
|
137
|
-
execute() {
|
|
138
|
-
return new RecordBatchIterator(this.nativeExecute());
|
|
179
|
+
execute(options) {
|
|
180
|
+
return new RecordBatchIterator(this.nativeExecute(options));
|
|
139
181
|
}
|
|
140
182
|
// biome-ignore lint/suspicious/noExplicitAny: skip
|
|
141
183
|
[Symbol.asyncIterator]() {
|
|
@@ -143,19 +185,48 @@ class QueryBase {
|
|
|
143
185
|
return new RecordBatchIterator(promise);
|
|
144
186
|
}
|
|
145
187
|
/** Collect the results as an Arrow @see {@link ArrowTable}. */
|
|
146
|
-
async toArrow() {
|
|
188
|
+
async toArrow(options) {
|
|
147
189
|
const batches = [];
|
|
148
|
-
|
|
190
|
+
let inner;
|
|
191
|
+
if (this.inner instanceof Promise) {
|
|
192
|
+
inner = await this.inner;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
inner = this.inner;
|
|
196
|
+
}
|
|
197
|
+
for await (const batch of new RecordBatchIterable(inner, options)) {
|
|
149
198
|
batches.push(batch);
|
|
150
199
|
}
|
|
151
200
|
return new arrow_1.Table(batches);
|
|
152
201
|
}
|
|
153
202
|
/** Collect the results as an array of objects. */
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
203
|
+
// biome-ignore lint/suspicious/noExplicitAny: arrow.toArrow() returns any[]
|
|
204
|
+
async toArray(options) {
|
|
205
|
+
const tbl = await this.toArrow(options);
|
|
157
206
|
return tbl.toArray();
|
|
158
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Generates an explanation of the query execution plan.
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* import * as lancedb from "@lancedb/lancedb"
|
|
213
|
+
* const db = await lancedb.connect("./.lancedb");
|
|
214
|
+
* const table = await db.createTable("my_table", [
|
|
215
|
+
* { vector: [1.1, 0.9], id: "1" },
|
|
216
|
+
* ]);
|
|
217
|
+
* const plan = await table.query().nearestTo([0.5, 0.2]).explainPlan();
|
|
218
|
+
*
|
|
219
|
+
* @param verbose - If true, provides a more detailed explanation. Defaults to false.
|
|
220
|
+
* @returns A Promise that resolves to a string containing the query execution plan explanation.
|
|
221
|
+
*/
|
|
222
|
+
async explainPlan(verbose = false) {
|
|
223
|
+
if (this.inner instanceof Promise) {
|
|
224
|
+
return this.inner.then((inner) => inner.explainPlan(verbose));
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
return this.inner.explainPlan(verbose);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
159
230
|
}
|
|
160
231
|
exports.QueryBase = QueryBase;
|
|
161
232
|
/**
|
|
@@ -190,7 +261,7 @@ class VectorQuery extends QueryBase {
|
|
|
190
261
|
* you the desired recall.
|
|
191
262
|
*/
|
|
192
263
|
nprobes(nprobes) {
|
|
193
|
-
|
|
264
|
+
super.doCall((inner) => inner.nprobes(nprobes));
|
|
194
265
|
return this;
|
|
195
266
|
}
|
|
196
267
|
/**
|
|
@@ -203,7 +274,7 @@ class VectorQuery extends QueryBase {
|
|
|
203
274
|
* whose data type is a fixed-size-list of floats.
|
|
204
275
|
*/
|
|
205
276
|
column(column) {
|
|
206
|
-
|
|
277
|
+
super.doCall((inner) => inner.column(column));
|
|
207
278
|
return this;
|
|
208
279
|
}
|
|
209
280
|
/**
|
|
@@ -221,7 +292,7 @@ class VectorQuery extends QueryBase {
|
|
|
221
292
|
* By default "l2" is used.
|
|
222
293
|
*/
|
|
223
294
|
distanceType(distanceType) {
|
|
224
|
-
|
|
295
|
+
super.doCall((inner) => inner.distanceType(distanceType));
|
|
225
296
|
return this;
|
|
226
297
|
}
|
|
227
298
|
/**
|
|
@@ -254,7 +325,7 @@ class VectorQuery extends QueryBase {
|
|
|
254
325
|
* distance between the query vector and the actual uncompressed vector.
|
|
255
326
|
*/
|
|
256
327
|
refineFactor(refineFactor) {
|
|
257
|
-
|
|
328
|
+
super.doCall((inner) => inner.refineFactor(refineFactor));
|
|
258
329
|
return this;
|
|
259
330
|
}
|
|
260
331
|
/**
|
|
@@ -278,7 +349,7 @@ class VectorQuery extends QueryBase {
|
|
|
278
349
|
* factor can often help restore some of the results lost by post filtering.
|
|
279
350
|
*/
|
|
280
351
|
postfilter() {
|
|
281
|
-
|
|
352
|
+
super.doCall((inner) => inner.postfilter());
|
|
282
353
|
return this;
|
|
283
354
|
}
|
|
284
355
|
/**
|
|
@@ -291,7 +362,7 @@ class VectorQuery extends QueryBase {
|
|
|
291
362
|
* calculate your recall to select an appropriate value for nprobes.
|
|
292
363
|
*/
|
|
293
364
|
bypassVectorIndex() {
|
|
294
|
-
|
|
365
|
+
super.doCall((inner) => inner.bypassVectorIndex());
|
|
295
366
|
return this;
|
|
296
367
|
}
|
|
297
368
|
}
|
|
@@ -339,9 +410,39 @@ class Query extends QueryBase {
|
|
|
339
410
|
* a default `limit` of 10 will be used. @see {@link Query#limit}
|
|
340
411
|
*/
|
|
341
412
|
nearestTo(vector) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
413
|
+
if (this.inner instanceof Promise) {
|
|
414
|
+
const nativeQuery = this.inner.then(async (inner) => {
|
|
415
|
+
if (vector instanceof Promise) {
|
|
416
|
+
const arr = await vector.then((v) => Float32Array.from(v));
|
|
417
|
+
return inner.nearestTo(arr);
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
return inner.nearestTo(Float32Array.from(vector));
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
return new VectorQuery(nativeQuery);
|
|
424
|
+
}
|
|
425
|
+
if (vector instanceof Promise) {
|
|
426
|
+
const res = (async () => {
|
|
427
|
+
try {
|
|
428
|
+
const v = await vector;
|
|
429
|
+
const arr = Float32Array.from(v);
|
|
430
|
+
//
|
|
431
|
+
// biome-ignore lint/suspicious/noExplicitAny: we need to get the `inner`, but js has no package scoping
|
|
432
|
+
const value = this.nearestTo(arr);
|
|
433
|
+
const inner = value.inner;
|
|
434
|
+
return inner;
|
|
435
|
+
}
|
|
436
|
+
catch (e) {
|
|
437
|
+
return Promise.reject(e);
|
|
438
|
+
}
|
|
439
|
+
})();
|
|
440
|
+
return new VectorQuery(res);
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
const vectorQuery = this.inner.nearestTo(Float32Array.from(vector));
|
|
444
|
+
return new VectorQuery(vectorQuery);
|
|
445
|
+
}
|
|
345
446
|
}
|
|
346
447
|
}
|
|
347
448
|
exports.Query = Query;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { type AxiosResponse } from "axios";
|
|
3
|
+
import { Table as ArrowTable } from "../arrow";
|
|
4
|
+
import { VectorQuery } from "../query";
|
|
5
|
+
export declare class RestfulLanceDBClient {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(dbName: string, apiKey: string, region: string, hostOverride?: string, connectionTimeout?: number, readTimeout?: number);
|
|
8
|
+
get session(): import("axios").AxiosInstance;
|
|
9
|
+
get url(): string;
|
|
10
|
+
get headers(): {
|
|
11
|
+
[key: string]: string;
|
|
12
|
+
};
|
|
13
|
+
isOpen(): boolean;
|
|
14
|
+
private checkNotClosed;
|
|
15
|
+
close(): void;
|
|
16
|
+
get(uri: string, params?: Record<string, any>): Promise<any>;
|
|
17
|
+
post(uri: string, body?: any): Promise<any>;
|
|
18
|
+
post(uri: string, body: any, additional: {
|
|
19
|
+
config?: {
|
|
20
|
+
responseType: "arraybuffer";
|
|
21
|
+
};
|
|
22
|
+
headers?: Record<string, string>;
|
|
23
|
+
params?: Record<string, string>;
|
|
24
|
+
}): Promise<Buffer>;
|
|
25
|
+
listTables(limit?: number, pageToken?: string): Promise<string[]>;
|
|
26
|
+
query(tableName: string, query: VectorQuery): Promise<ArrowTable>;
|
|
27
|
+
static checkStatus(response: AxiosResponse): void;
|
|
28
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2023 LanceDB Developers.
|
|
3
|
+
//
|
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.RestfulLanceDBClient = void 0;
|
|
17
|
+
const axios_1 = require("axios");
|
|
18
|
+
const arrow_1 = require("../arrow");
|
|
19
|
+
class RestfulLanceDBClient {
|
|
20
|
+
#dbName;
|
|
21
|
+
#region;
|
|
22
|
+
#apiKey;
|
|
23
|
+
#hostOverride;
|
|
24
|
+
#closed = false;
|
|
25
|
+
#connectionTimeout = 12 * 1000; // 12 seconds;
|
|
26
|
+
#readTimeout = 30 * 1000; // 30 seconds;
|
|
27
|
+
#session;
|
|
28
|
+
constructor(dbName, apiKey, region, hostOverride, connectionTimeout, readTimeout) {
|
|
29
|
+
this.#dbName = dbName;
|
|
30
|
+
this.#apiKey = apiKey;
|
|
31
|
+
this.#region = region;
|
|
32
|
+
this.#hostOverride = hostOverride ?? this.#hostOverride;
|
|
33
|
+
this.#connectionTimeout = connectionTimeout ?? this.#connectionTimeout;
|
|
34
|
+
this.#readTimeout = readTimeout ?? this.#readTimeout;
|
|
35
|
+
}
|
|
36
|
+
// todo: cache the session.
|
|
37
|
+
get session() {
|
|
38
|
+
if (this.#session !== undefined) {
|
|
39
|
+
return this.#session;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
return axios_1.default.create({
|
|
43
|
+
baseURL: this.url,
|
|
44
|
+
headers: {
|
|
45
|
+
// biome-ignore lint: external API
|
|
46
|
+
Authorization: `Bearer ${this.#apiKey}`,
|
|
47
|
+
},
|
|
48
|
+
transformResponse: decodeErrorData,
|
|
49
|
+
timeout: this.#connectionTimeout,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
get url() {
|
|
54
|
+
return (this.#hostOverride ??
|
|
55
|
+
`https://${this.#dbName}.${this.#region}.api.lancedb.com`);
|
|
56
|
+
}
|
|
57
|
+
get headers() {
|
|
58
|
+
const headers = {
|
|
59
|
+
"x-api-key": this.#apiKey,
|
|
60
|
+
"x-request-id": "na",
|
|
61
|
+
};
|
|
62
|
+
if (this.#region == "local") {
|
|
63
|
+
headers["Host"] = `${this.#dbName}.${this.#region}.api.lancedb.com`;
|
|
64
|
+
}
|
|
65
|
+
if (this.#hostOverride) {
|
|
66
|
+
headers["x-lancedb-database"] = this.#dbName;
|
|
67
|
+
}
|
|
68
|
+
return headers;
|
|
69
|
+
}
|
|
70
|
+
isOpen() {
|
|
71
|
+
return !this.#closed;
|
|
72
|
+
}
|
|
73
|
+
checkNotClosed() {
|
|
74
|
+
if (this.#closed) {
|
|
75
|
+
throw new Error("Connection is closed");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
close() {
|
|
79
|
+
this.#session = undefined;
|
|
80
|
+
this.#closed = true;
|
|
81
|
+
}
|
|
82
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
83
|
+
async get(uri, params) {
|
|
84
|
+
this.checkNotClosed();
|
|
85
|
+
uri = new URL(uri, this.url).toString();
|
|
86
|
+
let response;
|
|
87
|
+
try {
|
|
88
|
+
response = await this.session.get(uri, {
|
|
89
|
+
headers: this.headers,
|
|
90
|
+
params,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
if (e instanceof axios_1.AxiosError) {
|
|
95
|
+
response = e.response;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
throw e;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
RestfulLanceDBClient.checkStatus(response);
|
|
102
|
+
return response.data;
|
|
103
|
+
}
|
|
104
|
+
async post(uri,
|
|
105
|
+
// biome-ignore lint/suspicious/noExplicitAny: api request
|
|
106
|
+
body, additional) {
|
|
107
|
+
this.checkNotClosed();
|
|
108
|
+
uri = new URL(uri, this.url).toString();
|
|
109
|
+
additional = Object.assign({ config: { responseType: "json" } }, additional);
|
|
110
|
+
const headers = { ...this.headers, ...additional.headers };
|
|
111
|
+
if (!headers["Content-Type"]) {
|
|
112
|
+
headers["Content-Type"] = "application/json";
|
|
113
|
+
}
|
|
114
|
+
let response;
|
|
115
|
+
try {
|
|
116
|
+
response = await this.session.post(uri, body, {
|
|
117
|
+
headers,
|
|
118
|
+
responseType: additional.config.responseType,
|
|
119
|
+
params: new Map(Object.entries(additional.params ?? {})),
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
catch (e) {
|
|
123
|
+
if (e instanceof axios_1.AxiosError) {
|
|
124
|
+
response = e.response;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
throw e;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
RestfulLanceDBClient.checkStatus(response);
|
|
131
|
+
if (additional.config.responseType === "arraybuffer") {
|
|
132
|
+
return response.data;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
return JSON.parse(response.data);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async listTables(limit = 10, pageToken = "") {
|
|
139
|
+
const json = await this.get("/v1/table", { limit, pageToken });
|
|
140
|
+
return json.tables;
|
|
141
|
+
}
|
|
142
|
+
async query(tableName, query) {
|
|
143
|
+
const tbl = await this.post(`/v1/table/${tableName}/query`, query, {
|
|
144
|
+
config: {
|
|
145
|
+
responseType: "arraybuffer",
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
return (0, arrow_1.tableFromIPC)(tbl);
|
|
149
|
+
}
|
|
150
|
+
static checkStatus(response) {
|
|
151
|
+
if (response.status === 404) {
|
|
152
|
+
throw new Error(`Not found: ${response.data}`);
|
|
153
|
+
}
|
|
154
|
+
else if (response.status >= 400 && response.status < 500) {
|
|
155
|
+
throw new Error(`Bad Request: ${response.status}, error: ${response.data}`);
|
|
156
|
+
}
|
|
157
|
+
else if (response.status >= 500 && response.status < 600) {
|
|
158
|
+
throw new Error(`Internal Server Error: ${response.status}, error: ${response.data}`);
|
|
159
|
+
}
|
|
160
|
+
else if (response.status !== 200) {
|
|
161
|
+
throw new Error(`Unknown Error: ${response.status}, error: ${response.data}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
exports.RestfulLanceDBClient = RestfulLanceDBClient;
|
|
166
|
+
function decodeErrorData(data) {
|
|
167
|
+
if (Buffer.isBuffer(data)) {
|
|
168
|
+
const decoded = data.toString("utf-8");
|
|
169
|
+
return decoded;
|
|
170
|
+
}
|
|
171
|
+
return data;
|
|
172
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Data, SchemaLike } from "../arrow";
|
|
2
|
+
import { Connection, CreateTableOptions, OpenTableOptions, TableNamesOptions } from "../connection";
|
|
3
|
+
import { Table } from "../table";
|
|
4
|
+
export interface RemoteConnectionOptions {
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
region?: string;
|
|
7
|
+
hostOverride?: string;
|
|
8
|
+
connectionTimeout?: number;
|
|
9
|
+
readTimeout?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class RemoteConnection extends Connection {
|
|
12
|
+
#private;
|
|
13
|
+
constructor(url: string, { apiKey, region, hostOverride, connectionTimeout, readTimeout, }: RemoteConnectionOptions);
|
|
14
|
+
isOpen(): boolean;
|
|
15
|
+
close(): void;
|
|
16
|
+
display(): string;
|
|
17
|
+
tableNames(options?: Partial<TableNamesOptions>): Promise<string[]>;
|
|
18
|
+
openTable(name: string, _options?: Partial<OpenTableOptions> | undefined): Promise<Table>;
|
|
19
|
+
createTable(nameOrOptions: string | ({
|
|
20
|
+
name: string;
|
|
21
|
+
data: Data;
|
|
22
|
+
} & Partial<CreateTableOptions>), data?: Data, options?: Partial<CreateTableOptions> | undefined): Promise<Table>;
|
|
23
|
+
createEmptyTable(name: string, schema: SchemaLike, options?: Partial<CreateTableOptions> | undefined): Promise<Table>;
|
|
24
|
+
dropTable(name: string): Promise<void>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RemoteConnection = void 0;
|
|
4
|
+
const arrow_1 = require("../arrow");
|
|
5
|
+
const connection_1 = require("../connection");
|
|
6
|
+
const table_1 = require("../table");
|
|
7
|
+
const util_1 = require("../util");
|
|
8
|
+
const client_1 = require("./client");
|
|
9
|
+
const table_2 = require("./table");
|
|
10
|
+
class RemoteConnection extends connection_1.Connection {
|
|
11
|
+
#dbName;
|
|
12
|
+
#apiKey;
|
|
13
|
+
#region;
|
|
14
|
+
#client;
|
|
15
|
+
#tableCache = new util_1.TTLCache(300000);
|
|
16
|
+
constructor(url, { apiKey, region, hostOverride, connectionTimeout, readTimeout, }) {
|
|
17
|
+
super();
|
|
18
|
+
apiKey = apiKey ?? process.env.LANCEDB_API_KEY;
|
|
19
|
+
region = region ?? process.env.LANCEDB_REGION;
|
|
20
|
+
if (!apiKey) {
|
|
21
|
+
throw new Error("apiKey is required when connecting to LanceDB Cloud");
|
|
22
|
+
}
|
|
23
|
+
if (!region) {
|
|
24
|
+
throw new Error("region is required when connecting to LanceDB Cloud");
|
|
25
|
+
}
|
|
26
|
+
const parsed = new URL(url);
|
|
27
|
+
if (parsed.protocol !== "db:") {
|
|
28
|
+
throw new Error(`invalid protocol: ${parsed.protocol}, only accepts db://`);
|
|
29
|
+
}
|
|
30
|
+
this.#dbName = parsed.hostname;
|
|
31
|
+
this.#apiKey = apiKey;
|
|
32
|
+
this.#region = region;
|
|
33
|
+
this.#client = new client_1.RestfulLanceDBClient(this.#dbName, this.#apiKey, this.#region, hostOverride, connectionTimeout, readTimeout);
|
|
34
|
+
}
|
|
35
|
+
isOpen() {
|
|
36
|
+
return this.#client.isOpen();
|
|
37
|
+
}
|
|
38
|
+
close() {
|
|
39
|
+
return this.#client.close();
|
|
40
|
+
}
|
|
41
|
+
display() {
|
|
42
|
+
return `RemoteConnection(${this.#dbName})`;
|
|
43
|
+
}
|
|
44
|
+
async tableNames(options) {
|
|
45
|
+
const response = await this.#client.get("/v1/table/", {
|
|
46
|
+
limit: options?.limit ?? 10,
|
|
47
|
+
// biome-ignore lint/style/useNamingConvention: <explanation>
|
|
48
|
+
page_token: options?.startAfter ?? "",
|
|
49
|
+
});
|
|
50
|
+
const body = await response.body();
|
|
51
|
+
for (const table of body.tables) {
|
|
52
|
+
this.#tableCache.set(table, true);
|
|
53
|
+
}
|
|
54
|
+
return body.tables;
|
|
55
|
+
}
|
|
56
|
+
async openTable(name, _options) {
|
|
57
|
+
if (this.#tableCache.get(name) === undefined) {
|
|
58
|
+
await this.#client.post(`/v1/table/${encodeURIComponent(name)}/describe/`);
|
|
59
|
+
this.#tableCache.set(name, true);
|
|
60
|
+
}
|
|
61
|
+
return new table_2.RemoteTable(this.#client, name, this.#dbName);
|
|
62
|
+
}
|
|
63
|
+
async createTable(nameOrOptions, data, options) {
|
|
64
|
+
if (typeof nameOrOptions !== "string" && "name" in nameOrOptions) {
|
|
65
|
+
const { name, data, ...options } = nameOrOptions;
|
|
66
|
+
return this.createTable(name, data, options);
|
|
67
|
+
}
|
|
68
|
+
if (data === undefined) {
|
|
69
|
+
throw new Error("data is required");
|
|
70
|
+
}
|
|
71
|
+
if (options?.mode) {
|
|
72
|
+
console.warn("option 'mode' is not supported in LanceDB Cloud", "LanceDB Cloud only supports the default 'create' mode.", "If the table already exists, an error will be thrown.");
|
|
73
|
+
}
|
|
74
|
+
if (options?.embeddingFunction) {
|
|
75
|
+
console.warn("embedding_functions is not yet supported on LanceDB Cloud.", "Please vote https://github.com/lancedb/lancedb/issues/626 ", "for this feature.");
|
|
76
|
+
}
|
|
77
|
+
const { buf } = await table_1.Table.parseTableData(data, options, true /** streaming */);
|
|
78
|
+
await this.#client.post(`/v1/table/${encodeURIComponent(nameOrOptions)}/create/`, buf, {
|
|
79
|
+
config: {
|
|
80
|
+
responseType: "arraybuffer",
|
|
81
|
+
},
|
|
82
|
+
headers: { "Content-Type": "application/vnd.apache.arrow.stream" },
|
|
83
|
+
});
|
|
84
|
+
this.#tableCache.set(nameOrOptions, true);
|
|
85
|
+
return new table_2.RemoteTable(this.#client, nameOrOptions, this.#dbName);
|
|
86
|
+
}
|
|
87
|
+
async createEmptyTable(name, schema, options) {
|
|
88
|
+
if (options?.mode) {
|
|
89
|
+
console.warn(`mode is not supported on LanceDB Cloud`);
|
|
90
|
+
}
|
|
91
|
+
if (options?.embeddingFunction) {
|
|
92
|
+
console.warn("embeddingFunction is not yet supported on LanceDB Cloud.", "Please vote https://github.com/lancedb/lancedb/issues/626 ", "for this feature.");
|
|
93
|
+
}
|
|
94
|
+
const emptyTable = (0, arrow_1.makeEmptyTable)(schema);
|
|
95
|
+
const buf = await (0, arrow_1.fromTableToStreamBuffer)(emptyTable);
|
|
96
|
+
await this.#client.post(`/v1/table/${encodeURIComponent(name)}/create/`, buf, {
|
|
97
|
+
config: {
|
|
98
|
+
responseType: "arraybuffer",
|
|
99
|
+
},
|
|
100
|
+
headers: { "Content-Type": "application/vnd.apache.arrow.stream" },
|
|
101
|
+
});
|
|
102
|
+
this.#tableCache.set(name, true);
|
|
103
|
+
return new table_2.RemoteTable(this.#client, name, this.#dbName);
|
|
104
|
+
}
|
|
105
|
+
async dropTable(name) {
|
|
106
|
+
await this.#client.post(`/v1/table/${encodeURIComponent(name)}/drop/`);
|
|
107
|
+
this.#tableCache.delete(name);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.RemoteConnection = RemoteConnection;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RemoteTable = exports.RemoteConnection = exports.RestfulLanceDBClient = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "RestfulLanceDBClient", { enumerable: true, get: function () { return client_1.RestfulLanceDBClient; } });
|
|
6
|
+
var connection_1 = require("./connection");
|
|
7
|
+
Object.defineProperty(exports, "RemoteConnection", { enumerable: true, get: function () { return connection_1.RemoteConnection; } });
|
|
8
|
+
var table_1 = require("./table");
|
|
9
|
+
Object.defineProperty(exports, "RemoteTable", { enumerable: true, get: function () { return table_1.RemoteTable; } });
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Table as ArrowTable } from "apache-arrow";
|
|
2
|
+
import { Data, IntoVector } from "../arrow";
|
|
3
|
+
import { IndexStatistics } from "..";
|
|
4
|
+
import { IndexOptions } from "../indices";
|
|
5
|
+
import { MergeInsertBuilder } from "../merge";
|
|
6
|
+
import { VectorQuery } from "../query";
|
|
7
|
+
import { AddDataOptions, Table, UpdateOptions } from "../table";
|
|
8
|
+
import { IntoSql } from "../util";
|
|
9
|
+
import { RestfulLanceDBClient } from "./client";
|
|
10
|
+
export declare class RemoteTable extends Table {
|
|
11
|
+
#private;
|
|
12
|
+
get name(): string;
|
|
13
|
+
constructor(client: RestfulLanceDBClient, tableName: string, dbName: string);
|
|
14
|
+
isOpen(): boolean;
|
|
15
|
+
close(): void;
|
|
16
|
+
display(): string;
|
|
17
|
+
schema(): Promise<import("apache-arrow").Schema>;
|
|
18
|
+
add(data: Data, options?: Partial<AddDataOptions>): Promise<void>;
|
|
19
|
+
update(optsOrUpdates: (Map<string, string> | Record<string, string>) | ({
|
|
20
|
+
values: Map<string, IntoSql> | Record<string, IntoSql>;
|
|
21
|
+
} & Partial<UpdateOptions>) | ({
|
|
22
|
+
valuesSql: Map<string, string> | Record<string, string>;
|
|
23
|
+
} & Partial<UpdateOptions>), options?: Partial<UpdateOptions>): Promise<void>;
|
|
24
|
+
countRows(filter?: unknown): Promise<number>;
|
|
25
|
+
delete(predicate: unknown): Promise<void>;
|
|
26
|
+
createIndex(column: string, options?: Partial<IndexOptions>): Promise<void>;
|
|
27
|
+
query(): import("..").Query;
|
|
28
|
+
search(_query: string | IntoVector): VectorQuery;
|
|
29
|
+
vectorSearch(_vector: unknown): import("..").VectorQuery;
|
|
30
|
+
addColumns(_newColumnTransforms: unknown): Promise<void>;
|
|
31
|
+
alterColumns(_columnAlterations: unknown): Promise<void>;
|
|
32
|
+
dropColumns(_columnNames: unknown): Promise<void>;
|
|
33
|
+
version(): Promise<number>;
|
|
34
|
+
checkout(_version: unknown): Promise<void>;
|
|
35
|
+
checkoutLatest(): Promise<void>;
|
|
36
|
+
restore(): Promise<void>;
|
|
37
|
+
optimize(_options?: unknown): Promise<import("../native").OptimizeStats>;
|
|
38
|
+
listIndices(): Promise<import("../native").IndexConfig[]>;
|
|
39
|
+
toArrow(): Promise<ArrowTable>;
|
|
40
|
+
mergeInsert(_on: string | string[]): MergeInsertBuilder;
|
|
41
|
+
indexStats(_name: string): Promise<IndexStatistics | undefined>;
|
|
42
|
+
}
|