@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.
Files changed (91) hide show
  1. package/Cargo.toml +3 -3
  2. package/biome.json +19 -3
  3. package/dist/arrow.d.ts +42 -7
  4. package/dist/arrow.js +6 -5
  5. package/dist/connection.d.ts +55 -29
  6. package/dist/connection.js +22 -74
  7. package/dist/embedding/embedding_function.d.ts +11 -3
  8. package/dist/embedding/embedding_function.js +36 -12
  9. package/dist/embedding/openai.d.ts +6 -5
  10. package/dist/embedding/openai.js +4 -2
  11. package/dist/embedding/registry.d.ts +10 -11
  12. package/dist/embedding/registry.js +4 -0
  13. package/dist/index.d.ts +51 -3
  14. package/dist/index.js +28 -4
  15. package/dist/merge.d.ts +54 -0
  16. package/dist/merge.js +64 -0
  17. package/dist/native.d.ts +34 -7
  18. package/dist/native.js +26 -9
  19. package/dist/query.d.ts +51 -16
  20. package/dist/query.js +122 -21
  21. package/dist/remote/client.d.ts +28 -0
  22. package/dist/remote/client.js +172 -0
  23. package/dist/remote/connection.d.ts +25 -0
  24. package/dist/remote/connection.js +110 -0
  25. package/dist/remote/index.d.ts +3 -0
  26. package/dist/remote/index.js +9 -0
  27. package/dist/remote/table.d.ts +42 -0
  28. package/dist/remote/table.js +179 -0
  29. package/dist/sanitize.d.ts +3 -2
  30. package/dist/sanitize.js +55 -1
  31. package/dist/table.d.ts +116 -25
  32. package/dist/table.js +117 -233
  33. package/dist/util.d.ts +14 -0
  34. package/dist/util.js +65 -0
  35. package/examples/ann_indexes.ts +49 -0
  36. package/examples/basic.ts +149 -0
  37. package/examples/embedding.ts +83 -0
  38. package/examples/filtering.ts +34 -0
  39. package/examples/jsconfig.json +27 -0
  40. package/examples/package-lock.json +79 -0
  41. package/examples/package.json +18 -0
  42. package/examples/search.ts +37 -0
  43. package/lancedb/arrow.ts +87 -24
  44. package/lancedb/connection.ts +115 -92
  45. package/lancedb/embedding/embedding_function.ts +48 -16
  46. package/lancedb/embedding/openai.ts +11 -6
  47. package/lancedb/embedding/registry.ts +38 -22
  48. package/lancedb/index.ts +101 -2
  49. package/lancedb/merge.ts +70 -0
  50. package/lancedb/query.ts +168 -39
  51. package/lancedb/remote/client.ts +221 -0
  52. package/lancedb/remote/connection.ts +201 -0
  53. package/lancedb/remote/index.ts +3 -0
  54. package/lancedb/remote/table.ts +226 -0
  55. package/lancedb/sanitize.ts +73 -1
  56. package/lancedb/table.ts +344 -101
  57. package/lancedb/util.ts +69 -0
  58. package/native.d.ts +208 -0
  59. package/nodejs-artifacts/arrow.d.ts +42 -7
  60. package/nodejs-artifacts/arrow.js +6 -5
  61. package/nodejs-artifacts/connection.d.ts +55 -29
  62. package/nodejs-artifacts/connection.js +22 -74
  63. package/nodejs-artifacts/embedding/embedding_function.d.ts +11 -3
  64. package/nodejs-artifacts/embedding/embedding_function.js +36 -12
  65. package/nodejs-artifacts/embedding/openai.d.ts +6 -5
  66. package/nodejs-artifacts/embedding/openai.js +4 -2
  67. package/nodejs-artifacts/embedding/registry.d.ts +10 -11
  68. package/nodejs-artifacts/embedding/registry.js +4 -0
  69. package/nodejs-artifacts/index.d.ts +51 -3
  70. package/nodejs-artifacts/index.js +28 -4
  71. package/nodejs-artifacts/merge.d.ts +54 -0
  72. package/nodejs-artifacts/merge.js +64 -0
  73. package/nodejs-artifacts/native.d.ts +34 -7
  74. package/nodejs-artifacts/native.js +26 -9
  75. package/nodejs-artifacts/query.d.ts +51 -16
  76. package/nodejs-artifacts/query.js +122 -21
  77. package/nodejs-artifacts/remote/client.d.ts +28 -0
  78. package/nodejs-artifacts/remote/client.js +172 -0
  79. package/nodejs-artifacts/remote/connection.d.ts +25 -0
  80. package/nodejs-artifacts/remote/connection.js +110 -0
  81. package/nodejs-artifacts/remote/index.d.ts +3 -0
  82. package/nodejs-artifacts/remote/index.js +9 -0
  83. package/nodejs-artifacts/remote/table.d.ts +42 -0
  84. package/nodejs-artifacts/remote/table.js +179 -0
  85. package/nodejs-artifacts/sanitize.d.ts +3 -2
  86. package/nodejs-artifacts/sanitize.js +55 -1
  87. package/nodejs-artifacts/table.d.ts +116 -25
  88. package/nodejs-artifacts/table.js +117 -233
  89. package/nodejs-artifacts/util.d.ts +14 -0
  90. package/nodejs-artifacts/util.js +65 -0
  91. 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.select(columnTuples);
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
- return this.inner.execute();
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
- for await (const batch of this) {
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
- async toArray() {
155
- const tbl = await this.toArrow();
156
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
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
- this.inner.nprobes(nprobes);
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
- this.inner.column(column);
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
- this.inner.distanceType(distanceType);
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
- this.inner.refineFactor(refineFactor);
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
- this.inner.postfilter();
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
- this.inner.bypassVectorIndex();
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
- // biome-ignore lint/suspicious/noExplicitAny: skip
343
- const vectorQuery = this.inner.nearestTo(Float32Array.from(vector));
344
- return new VectorQuery(vectorQuery);
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,3 @@
1
+ export { RestfulLanceDBClient } from "./client";
2
+ export { type RemoteConnectionOptions, RemoteConnection } from "./connection";
3
+ export { RemoteTable } from "./table";
@@ -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
+ }