mirror of
https://github.com/lancedb/lancedb.git
synced 2026-09-11 15:52:17 +00:00
A 1M-row column refresh over 200 fragments produced no visible result,
and the client could only ever say `"running"`. Everything needed to
diagnose it already existed server-side — the job registry records a
`claim`/`claim_complete` pair per fragment carrying `rows_processed` —
but none of it was reachable.
## Before
Four ways to ask about a job, none of which told you much.
```python
job = table.refresh_column_async("embedding")
job.status() # "running". That was the entire debug surface.
db.get_job(job_id) # state, and a spec. No result, no progress.
db.job_history(job_id) # raw record batches, no limit, no filter
db.job(job_id) # a handle that knew nothing
```
## After
Open a job the way you open a table; the handle answers everything.
```python
job = db.open_job(job_id) # raises JobNotFoundError if there is no such job
```
```python
>>> print(job)
Job(
id='job-1',
state='failed',
job_type='refresh_column',
creation_ms=1757000000000,
spec={
"column": "embedding",
"num_workers": 4
},
failure=JobFailureInfo(phase='execute', message='worker died', retryable=True),
)
```
Individual fields are there too — `job.state`, `job.job_type`,
`job.creation_ms`, `job.spec`, `job.result`, `job.failure` — and
`job.result` carries `rows_assigned` / `rows_failed` as soon as the job
succeeds, with no `wait()` required.
Per-fragment progress *while it is still running*:
```python
done = job.events(filter="state = 'claim_complete'", limit=10_000)
done.column("rows_processed").to_pylist() # [5000, 5000, ...]
```
The handle an async action returns is the same object, one `refresh()`
away:
```python
job = table.refresh_column_async("embedding")
job.refresh()
job.state, job.result
```
TypeScript is the same experience, down to `console.log`:
```ts
const job = await db.openJob(jobId); // rejects if there is no such job
console.log(job); // same multi-line layout
job.state; job.jobType; job.spec; job.result; job.failure;
const done = await job.events({ filter: "state = 'claim_complete'", limit: 10_000 });
```
## Why each piece matters
- **A result without waiting.** `rows_assigned` / `rows_failed` used to
live only on the terminal result, so a job that never terminated
reported nothing at all.
- **`limit`.** The server caps event rows at 1000 and truncates without
saying so, which silently hid most of a 200-fragment job's history.
- **`filter`.** `claim_complete` rows carry per-claim `rows_processed` —
the only progress signal that exists mid-flight.
- **Events outlive the worker.** They live in the job registry, not in
pod logs that vanish with the pod.
- **One place to ask.** `open_job` replaces `describe_job`,
`query_job_events` and `job`, so a question about a job has one answer
instead of one per calling location.
- **A missing job is an error, not a `None`.** The common case is a job
id copied out of a log, where absence is the surprise worth raising —
and it matches `open_table`.
- **Printing is the debug surface.** Every field on its own line, JSON
payloads keeping their structure. An unrefreshed handle stays on one
line, because there is nothing to lay out.
- **In-process jobs say so.** A local refresh reports `state` and leaves
the rest null rather than inventing fields it has no record for.
`list_jobs` and `cancel_job` stay as they were: one lists, the other is
a one-shot action that should not need a describe first.
## Breaking
All shipped in 0.38.0. No deprecated aliases.
| Was | Now |
| --- | --- |
| `Connection.get_job` → `describe_job` | `Connection.open_job` returns
a populated `Job`, or raises |
| `Connection.job_history` → `query_job_events` | `job.events(...)` |
| `Connection.job` | `Connection.open_job` |
| Python events → `List[pa.RecordBatch]` | `pa.Table` |
| `JobDescription.spec_json` / `.result_json` | internal; use `job.spec`
/ `job.result` |
Node's `Job` is now a TypeScript class wrapping the native handle, so it
returns an Arrow table and parsed values like Python does. New
`Error::JobNotFound` / `JobNotFoundError`; the three job exceptions are
now in the Python API reference.
620 lines
16 KiB
TypeScript
620 lines
16 KiB
TypeScript
// SPDX-License-Identifier: Apache-2.0
|
|
// SPDX-FileCopyrightText: Copyright The LanceDB Authors
|
|
|
|
import {
|
|
Connection,
|
|
LocalConnection,
|
|
cleanseStorageOptions,
|
|
} from "./connection";
|
|
|
|
import {
|
|
ConnectNamespaceOptions,
|
|
ConnectionOptions,
|
|
Connection as LanceDbConnection,
|
|
JsHeaderProvider as NativeJsHeaderProvider,
|
|
Session,
|
|
tokenize as nativeTokenize,
|
|
} from "./native.js";
|
|
|
|
import { HeaderProvider } from "./header";
|
|
import type { BaseTokenizer } from "./indices";
|
|
import type { FtsToken } from "./table";
|
|
|
|
// Re-export native header provider for use with connectWithHeaderProvider
|
|
export {
|
|
MaterializedView,
|
|
MaterializedViewDefinition,
|
|
MaterializedViewSelect,
|
|
} from "./materialized_view";
|
|
export { JsHeaderProvider as NativeJsHeaderProvider } from "./native.js";
|
|
|
|
// OpenTelemetry metrics bridge. Only the high-level entry point is public; the
|
|
// underlying recorder/catalog/snapshot functions remain internal plumbing that
|
|
// `otel.ts` consumes from the native module.
|
|
export { instrumentLanceDbMetrics } from "./otel";
|
|
|
|
export {
|
|
AddColumnsSql,
|
|
ConnectionOptions,
|
|
ConnectNamespaceOptions,
|
|
IndexStatistics,
|
|
IndexConfig,
|
|
ClientConfig,
|
|
TimeoutConfig,
|
|
RetryConfig,
|
|
TlsConfig,
|
|
OptimizeStats,
|
|
CompactionStats,
|
|
RemovalStats,
|
|
TableStatistics,
|
|
FragmentStatistics,
|
|
FragmentSummaryStats,
|
|
Tags,
|
|
TagContents,
|
|
BranchContents,
|
|
MergeResult,
|
|
AddResult,
|
|
AddColumnsResult,
|
|
RefreshColumnResult,
|
|
RefreshMaterializedViewResult,
|
|
AlterColumnsResult,
|
|
UpdateFieldMetadataResult,
|
|
DeleteResult,
|
|
DropColumnsResult,
|
|
UpdateResult,
|
|
SplitCalculatedOptions,
|
|
SplitRandomOptions,
|
|
SplitHashOptions,
|
|
SplitSequentialOptions,
|
|
ShuffleOptions,
|
|
OAuthConfig as NativeOAuthConfig,
|
|
} from "./native.js";
|
|
|
|
export {
|
|
makeArrowTable,
|
|
MakeArrowTableOptions,
|
|
Data,
|
|
VectorColumnOptions,
|
|
} from "./arrow";
|
|
|
|
export {
|
|
Connection,
|
|
CreateTableOptions,
|
|
TableNamesOptions,
|
|
ListTablesOptions,
|
|
OpenTableOptions,
|
|
ListNamespacesOptions,
|
|
CreateNamespaceOptions,
|
|
DropNamespaceOptions,
|
|
ListNamespacesResponse,
|
|
ListTablesResponse,
|
|
CreateNamespaceResponse,
|
|
DropNamespaceResponse,
|
|
DescribeNamespaceResponse,
|
|
RenameTableOptions,
|
|
} from "./connection";
|
|
|
|
export { JobFailureInfo, JobInfo, Session } from "./native.js";
|
|
|
|
export { Job, JobEventsOptions } from "./job";
|
|
|
|
export {
|
|
AutoQuery,
|
|
ExecutableQuery,
|
|
Query,
|
|
QueryBase,
|
|
VectorQuery,
|
|
TakeQuery,
|
|
AnalyzePlanDistributedMetrics,
|
|
QueryExecutionOptions,
|
|
ColumnOrdering,
|
|
FullTextSearchOptions,
|
|
RecordBatchIterator,
|
|
FullTextQuery,
|
|
MatchQuery,
|
|
PhraseQuery,
|
|
BoostQuery,
|
|
MultiMatchQuery,
|
|
BooleanQuery,
|
|
FullTextQueryType,
|
|
Operator,
|
|
Occur,
|
|
} from "./query";
|
|
|
|
export {
|
|
Index,
|
|
IndexOptions,
|
|
IvfPqOptions,
|
|
IvfRqOptions,
|
|
IvfFlatOptions,
|
|
HnswPqOptions,
|
|
HnswSqOptions,
|
|
FtsOptions,
|
|
BaseTokenizer,
|
|
} from "./indices";
|
|
|
|
export {
|
|
Table,
|
|
Branches,
|
|
BranchColumnSummary,
|
|
BranchColumnChange,
|
|
BranchIndexSummary,
|
|
BranchRowCountSummary,
|
|
CherryPickError,
|
|
BranchDiff,
|
|
CherryPickPreview,
|
|
CherryPickResult,
|
|
AddDataOptions,
|
|
UpdateOptions,
|
|
OptimizeOptions,
|
|
Version,
|
|
WriteProgress,
|
|
FtsToken,
|
|
TokenizeTableOptions,
|
|
LsmWriteSpec,
|
|
LsmStats,
|
|
BucketStats,
|
|
GenerationStats,
|
|
MemtableStats,
|
|
ColumnAlteration,
|
|
FieldMetadataUpdate,
|
|
} from "./table";
|
|
|
|
export {
|
|
HeaderProvider,
|
|
StaticHeaderProvider,
|
|
OAuthHeaderProvider,
|
|
TokenResponse,
|
|
} from "./header";
|
|
|
|
export { OAuthConfig, OAuthFlowType } from "./oauth";
|
|
|
|
export { MergeInsertBuilder, WriteExecutionOptions } from "./merge";
|
|
|
|
export * as embedding from "./embedding";
|
|
export { permutationBuilder, PermutationBuilder } from "./permutation";
|
|
export { Scannable, ScannableOptions } from "./scannable";
|
|
export * as rerankers from "./rerankers";
|
|
export {
|
|
SchemaLike,
|
|
TableLike,
|
|
FieldLike,
|
|
RecordBatchLike,
|
|
DataLike,
|
|
IntoVector,
|
|
MultiVector,
|
|
} from "./arrow";
|
|
export { IntoSql, packBits } from "./util";
|
|
|
|
/**
|
|
* Options for tokenizing a full-text search query without a table index.
|
|
*/
|
|
export interface TokenizeOptions {
|
|
/**
|
|
* The tokenizer to use. The default is "simple".
|
|
*/
|
|
baseTokenizer?: BaseTokenizer;
|
|
|
|
/** Language for stemming and stop words. */
|
|
language?: string;
|
|
|
|
/** Maximum token length; tokens longer than this are ignored. */
|
|
maxTokenLength?: number;
|
|
|
|
/** Whether to lowercase tokens. */
|
|
lowercase?: boolean;
|
|
|
|
/** Whether to stem tokens. */
|
|
stem?: boolean;
|
|
|
|
/** Whether to remove stop words. */
|
|
removeStopWords?: boolean;
|
|
|
|
/**
|
|
* Custom stop words that replace the built-in list for `language`.
|
|
*
|
|
* This option only affects tokenization when `removeStopWords` is true.
|
|
*
|
|
* `undefined` keeps the built-in language list. An empty array explicitly
|
|
* replaces it with no stop words.
|
|
*/
|
|
customStopWords?: string[];
|
|
|
|
/** Whether to fold ASCII characters. */
|
|
asciiFolding?: boolean;
|
|
|
|
/** N-gram minimum length. */
|
|
ngramMinLength?: number;
|
|
|
|
/** N-gram maximum length. */
|
|
ngramMaxLength?: number;
|
|
|
|
/** Whether to only emit token prefixes for the n-gram tokenizer. */
|
|
prefixOnly?: boolean;
|
|
}
|
|
|
|
/**
|
|
* Tokenize a full-text search query using an explicit tokenizer.
|
|
*
|
|
* This does not require a table or FTS index. The tokenizer options match
|
|
* {@link Index.fts}.
|
|
*/
|
|
export async function tokenize(
|
|
query: string,
|
|
options?: Partial<TokenizeOptions>,
|
|
): Promise<FtsToken[]> {
|
|
return await nativeTokenize(
|
|
query,
|
|
options?.baseTokenizer,
|
|
options?.language,
|
|
options?.maxTokenLength,
|
|
options?.lowercase,
|
|
options?.stem,
|
|
options?.removeStopWords,
|
|
options?.customStopWords,
|
|
options?.asciiFolding,
|
|
options?.ngramMinLength,
|
|
options?.ngramMaxLength,
|
|
options?.prefixOnly,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Connect to a LanceDB instance at the given URI.
|
|
*
|
|
* Accepted formats:
|
|
*
|
|
* - `/path/to/database` - local database
|
|
* - `s3://bucket/path/to/database` or `gs://bucket/path/to/database` - database on cloud storage
|
|
* - `db://host:port` - remote database (LanceDB cloud)
|
|
* @param {string} uri - The uri of the database. If the database uri starts
|
|
* with `db://` then it connects to a remote database.
|
|
* @see {@link ConnectionOptions} for more details on the URI format.
|
|
* @param options - The options to use when connecting to the database
|
|
* @example
|
|
* ```ts
|
|
* const conn = await connect("/path/to/database");
|
|
* ```
|
|
* @example
|
|
* ```ts
|
|
* const conn = await connect(
|
|
* "s3://bucket/path/to/database",
|
|
* {storageOptions: {timeout: "60s"}
|
|
* });
|
|
* ```
|
|
* @example
|
|
* Using with a header provider for per-request authentication:
|
|
* ```ts
|
|
* const provider = new StaticHeaderProvider({
|
|
* "X-API-Key": "my-key"
|
|
* });
|
|
* const conn = await connectWithHeaderProvider(
|
|
* "db://host:port",
|
|
* options,
|
|
* provider
|
|
* );
|
|
* ```
|
|
*/
|
|
export async function connect(
|
|
uri: string,
|
|
options?: Partial<ConnectionOptions>,
|
|
session?: Session,
|
|
headerProvider?:
|
|
| HeaderProvider
|
|
| (() => Record<string, string>)
|
|
| (() => Promise<Record<string, string>>),
|
|
): Promise<Connection>;
|
|
/**
|
|
* Connect to a LanceDB instance at the given URI.
|
|
*
|
|
* Accepted formats:
|
|
*
|
|
* - `/path/to/database` - local database
|
|
* - `s3://bucket/path/to/database` or `gs://bucket/path/to/database` - database on cloud storage
|
|
* - `db://host:port` - remote database (LanceDB cloud)
|
|
* @param options - The options to use when connecting to the database
|
|
* @see {@link ConnectionOptions} for more details on the URI format.
|
|
* @example
|
|
* ```ts
|
|
* const conn = await connect({
|
|
* uri: "/path/to/database",
|
|
* storageOptions: {timeout: "60s"}
|
|
* });
|
|
* ```
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* const session = Session.default();
|
|
* const conn = await connect({
|
|
* uri: "/path/to/database",
|
|
* session: session
|
|
* });
|
|
* ```
|
|
*/
|
|
export async function connect(
|
|
options: Partial<ConnectionOptions> & { uri: string },
|
|
): Promise<Connection>;
|
|
export async function connect(
|
|
uriOrOptions: string | (Partial<ConnectionOptions> & { uri: string }),
|
|
optionsOrSession?: Partial<ConnectionOptions> | Session,
|
|
sessionOrHeaderProvider?:
|
|
| Session
|
|
| HeaderProvider
|
|
| (() => Record<string, string>)
|
|
| (() => Promise<Record<string, string>>),
|
|
headerProvider?:
|
|
| HeaderProvider
|
|
| (() => Record<string, string>)
|
|
| (() => Promise<Record<string, string>>),
|
|
): Promise<Connection> {
|
|
let uri: string | undefined;
|
|
let finalOptions: Partial<ConnectionOptions> = {};
|
|
let finalHeaderProvider:
|
|
| HeaderProvider
|
|
| (() => Record<string, string>)
|
|
| (() => Promise<Record<string, string>>)
|
|
| undefined;
|
|
|
|
if (typeof uriOrOptions !== "string") {
|
|
// First overload: connect(options)
|
|
const { uri: uri_, ...opts } = uriOrOptions;
|
|
uri = uri_;
|
|
finalOptions = opts;
|
|
} else {
|
|
// Second overload: connect(uri, options?, session?, headerProvider?)
|
|
uri = uriOrOptions;
|
|
|
|
// Handle optionsOrSession parameter
|
|
if (optionsOrSession && "inner" in optionsOrSession) {
|
|
// Second param is session, so no options provided
|
|
finalOptions = {};
|
|
} else {
|
|
// Second param is options
|
|
finalOptions = (optionsOrSession as Partial<ConnectionOptions>) || {};
|
|
}
|
|
|
|
// Handle sessionOrHeaderProvider parameter
|
|
if (
|
|
sessionOrHeaderProvider &&
|
|
(typeof sessionOrHeaderProvider === "function" ||
|
|
"getHeaders" in sessionOrHeaderProvider)
|
|
) {
|
|
// Third param is header provider
|
|
finalHeaderProvider = sessionOrHeaderProvider as
|
|
| HeaderProvider
|
|
| (() => Record<string, string>)
|
|
| (() => Promise<Record<string, string>>);
|
|
} else {
|
|
// Third param is session, header provider is fourth param
|
|
finalHeaderProvider = headerProvider;
|
|
}
|
|
}
|
|
|
|
if (!uri) {
|
|
throw new Error("uri is required");
|
|
}
|
|
|
|
finalOptions = (finalOptions as ConnectionOptions) ?? {};
|
|
(<ConnectionOptions>finalOptions).storageOptions = cleanseStorageOptions(
|
|
(<ConnectionOptions>finalOptions).storageOptions,
|
|
);
|
|
|
|
// Create native header provider if one was provided
|
|
let nativeProvider: NativeJsHeaderProvider | undefined;
|
|
if (finalHeaderProvider) {
|
|
if (typeof finalHeaderProvider === "function") {
|
|
nativeProvider = new NativeJsHeaderProvider(async () =>
|
|
finalHeaderProvider(),
|
|
);
|
|
} else if (
|
|
finalHeaderProvider &&
|
|
typeof finalHeaderProvider.getHeaders === "function"
|
|
) {
|
|
nativeProvider = new NativeJsHeaderProvider(async () =>
|
|
finalHeaderProvider.getHeaders(),
|
|
);
|
|
}
|
|
}
|
|
|
|
const nativeConn = await LanceDbConnection.new(
|
|
uri,
|
|
finalOptions,
|
|
nativeProvider,
|
|
);
|
|
return new LocalConnection(nativeConn);
|
|
}
|
|
|
|
/**
|
|
* Configuration for the built-in directory namespace (`"dir"`).
|
|
*
|
|
* The directory namespace stores tables under a single root path (local
|
|
* filesystem or object storage URI). See
|
|
* {@link https://docs.lancedb.com/namespaces} for the documented surface;
|
|
* less-common knobs live under {@link DirNamespaceConfig.extraProperties}.
|
|
*/
|
|
export interface DirNamespaceConfig {
|
|
/** Root path or URI containing the LanceDB tables. */
|
|
root: string;
|
|
/**
|
|
* Whether to maintain a namespace manifest at the root. Required for
|
|
* child namespaces. Defaults to true on the impl side.
|
|
*/
|
|
manifestEnabled?: boolean;
|
|
/**
|
|
* Additional raw properties passed verbatim to the namespace
|
|
* implementation (e.g. `storage.*`, `credential_vendor.*`). Typed
|
|
* fields above take precedence on key collision.
|
|
*/
|
|
extraProperties?: Record<string, string>;
|
|
}
|
|
|
|
/**
|
|
* Configuration for the built-in REST namespace (`"rest"`).
|
|
*
|
|
* The REST namespace talks to a remote catalog server over HTTP. See
|
|
* {@link https://docs.lancedb.com/namespaces} for the documented surface;
|
|
* less-common knobs (TLS, metrics) live under
|
|
* {@link RestNamespaceConfig.extraProperties}.
|
|
*/
|
|
export interface RestNamespaceConfig {
|
|
/** Catalog endpoint URL. */
|
|
uri: string;
|
|
/**
|
|
* HTTP headers forwarded with each request. Keys are passed through
|
|
* as-is (e.g. `"x-api-key"`, `"Authorization"`).
|
|
*/
|
|
headers?: Record<string, string>;
|
|
/**
|
|
* Additional raw properties passed verbatim to the namespace
|
|
* implementation (e.g. `tls.*`, `ops_metrics_enabled`, `delimiter`).
|
|
* Typed fields above take precedence on key collision.
|
|
*/
|
|
extraProperties?: Record<string, string>;
|
|
}
|
|
|
|
function dirConfigToProperties(
|
|
config: DirNamespaceConfig,
|
|
): Record<string, string> {
|
|
// Spread the whole input so that unknown keys (e.g. a raw `manifest_enabled`
|
|
// passed via the dynamic-impl path) flow through instead of being dropped.
|
|
// Typed transformations layer on top.
|
|
const { manifestEnabled, extraProperties, ...rest } = config;
|
|
const properties: Record<string, string> = {
|
|
...(extraProperties ?? {}),
|
|
...(rest as Record<string, string>),
|
|
};
|
|
if (manifestEnabled !== undefined) {
|
|
properties.manifest_enabled = String(manifestEnabled);
|
|
}
|
|
return properties;
|
|
}
|
|
|
|
function restConfigToProperties(
|
|
config: RestNamespaceConfig,
|
|
): Record<string, string> {
|
|
const { headers, extraProperties, ...rest } = config;
|
|
const properties: Record<string, string> = {
|
|
...(extraProperties ?? {}),
|
|
...(rest as Record<string, string>),
|
|
};
|
|
if (headers) {
|
|
for (const [name, value] of Object.entries(headers)) {
|
|
properties[`headers.${name}`] = value;
|
|
}
|
|
}
|
|
return properties;
|
|
}
|
|
|
|
/**
|
|
* Connect to a LanceDB database through a namespace.
|
|
*
|
|
* Unlike {@link connect}, which routes by URI scheme (local path vs.
|
|
* `db://` cloud), `connectNamespace` always returns a namespace-backed
|
|
* connection. The `implName` selects the namespace implementation:
|
|
*
|
|
* - `"dir"` — directory namespace, configured with {@link DirNamespaceConfig}.
|
|
* - `"rest"` — remote REST catalog, configured with {@link RestNamespaceConfig}.
|
|
* - Any other string — full module path for a custom implementation,
|
|
* configured with a free-form string-keyed `properties` map.
|
|
*
|
|
* @example Typed dir namespace
|
|
* ```ts
|
|
* const db = await connectNamespace("dir", { root: "/path/to/db" });
|
|
* await db.createTable("users", [{ id: 1 }]);
|
|
* ```
|
|
*
|
|
* @example Typed REST namespace with auth headers
|
|
* ```ts
|
|
* const db = await connectNamespace("rest", {
|
|
* uri: "https://catalog.example.com",
|
|
* headers: { "x-api-key": process.env.CATALOG_KEY ?? "" },
|
|
* });
|
|
* ```
|
|
*
|
|
* @example Custom implementation with raw properties
|
|
* ```ts
|
|
* const db = await connectNamespace("my.custom.Namespace", {
|
|
* endpoint: "...",
|
|
* });
|
|
* ```
|
|
*/
|
|
export function connectNamespace(
|
|
implName: "dir",
|
|
config: DirNamespaceConfig,
|
|
options?: Partial<ConnectNamespaceOptions>,
|
|
): Promise<Connection>;
|
|
/**
|
|
* Connect through the built-in REST namespace.
|
|
*
|
|
* Configured with {@link RestNamespaceConfig}. See the function-level
|
|
* documentation above for the full surface, examples, and how this
|
|
* relates to {@link connect}.
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* const db = await connectNamespace("rest", {
|
|
* uri: "https://catalog.example.com",
|
|
* headers: { "x-api-key": process.env.CATALOG_KEY ?? "" },
|
|
* });
|
|
* ```
|
|
*/
|
|
export function connectNamespace(
|
|
implName: "rest",
|
|
config: RestNamespaceConfig,
|
|
options?: Partial<ConnectNamespaceOptions>,
|
|
): Promise<Connection>;
|
|
/**
|
|
* Connect through a custom namespace implementation by full module path,
|
|
* configured with a free-form string-keyed `properties` map. Use the
|
|
* typed overloads above for the built-in `"dir"` and `"rest"` impls.
|
|
*
|
|
* See the function-level documentation above for examples and how this
|
|
* relates to {@link connect}.
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* const db = await connectNamespace("my.custom.Namespace", {
|
|
* endpoint: "...",
|
|
* });
|
|
* ```
|
|
*/
|
|
export function connectNamespace(
|
|
implName: string,
|
|
properties: Record<string, string>,
|
|
options?: Partial<ConnectNamespaceOptions>,
|
|
): Promise<Connection>;
|
|
export async function connectNamespace(
|
|
implName: string,
|
|
configOrProperties:
|
|
| DirNamespaceConfig
|
|
| RestNamespaceConfig
|
|
| Record<string, string>,
|
|
options?: Partial<ConnectNamespaceOptions>,
|
|
): Promise<Connection> {
|
|
let properties: Record<string, string>;
|
|
if (implName === "dir") {
|
|
properties = dirConfigToProperties(
|
|
configOrProperties as DirNamespaceConfig,
|
|
);
|
|
} else if (implName === "rest") {
|
|
properties = restConfigToProperties(
|
|
configOrProperties as RestNamespaceConfig,
|
|
);
|
|
} else {
|
|
properties = configOrProperties as Record<string, string>;
|
|
}
|
|
|
|
const finalOptions: ConnectNamespaceOptions = (options ??
|
|
{}) as ConnectNamespaceOptions;
|
|
finalOptions.storageOptions = cleanseStorageOptions(
|
|
finalOptions.storageOptions,
|
|
);
|
|
|
|
const nativeConn = await LanceDbConnection.newWithNamespace(
|
|
implName,
|
|
properties,
|
|
finalOptions,
|
|
);
|
|
return new LocalConnection(nativeConn);
|
|
}
|