@functional-systems/lambdadb 0.4.3 → 0.5.0-rc.1
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/CHANGELOG.md +71 -0
- package/FUNCTIONS.md +7 -2
- package/README.md +60 -2
- package/RUNTIMES.md +7 -0
- package/USAGE.md +20 -0
- package/dist/commonjs/client.d.ts +25 -10
- package/dist/commonjs/client.d.ts.map +1 -1
- package/dist/commonjs/client.js +182 -56
- package/dist/commonjs/client.js.map +1 -1
- package/dist/commonjs/compat/qdrant/client.d.ts +3 -6
- package/dist/commonjs/compat/qdrant/client.d.ts.map +1 -1
- package/dist/commonjs/compat/qdrant/client.js +17 -11
- package/dist/commonjs/compat/qdrant/client.js.map +1 -1
- package/dist/commonjs/funcs/collectionsCreate.js +1 -1
- package/dist/commonjs/funcs/collectionsDelete.js +1 -1
- package/dist/commonjs/funcs/collectionsDocsGetBulkUpsert.js +4 -0
- package/dist/commonjs/funcs/collectionsDocsGetBulkUpsert.js.map +1 -1
- package/dist/commonjs/funcs/collectionsDocsListDocs.js +2 -0
- package/dist/commonjs/funcs/collectionsDocsListDocs.js.map +1 -1
- package/dist/commonjs/index.d.ts +4 -1
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +15 -1
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/lib/config.d.ts +2 -2
- package/dist/commonjs/lib/config.js +2 -2
- package/dist/commonjs/lib/config.js.map +1 -1
- package/dist/commonjs/lib/queryInput.d.ts +3 -11
- package/dist/commonjs/lib/queryInput.d.ts.map +1 -1
- package/dist/commonjs/lib/queryInput.js.map +1 -1
- package/dist/commonjs/models/collectionresponse.d.ts +12 -21
- package/dist/commonjs/models/collectionresponse.d.ts.map +1 -1
- package/dist/commonjs/models/collectionresponse.js +5 -6
- package/dist/commonjs/models/collectionresponse.js.map +1 -1
- package/dist/commonjs/models/index.d.ts +1 -0
- package/dist/commonjs/models/index.d.ts.map +1 -1
- package/dist/commonjs/models/index.js +1 -0
- package/dist/commonjs/models/index.js.map +1 -1
- package/dist/commonjs/models/operations/bulkupsertdocs.d.ts +6 -0
- package/dist/commonjs/models/operations/bulkupsertdocs.d.ts.map +1 -1
- package/dist/commonjs/models/operations/bulkupsertdocs.js +2 -0
- package/dist/commonjs/models/operations/bulkupsertdocs.js.map +1 -1
- package/dist/commonjs/models/operations/createcollection.d.ts +20 -13
- package/dist/commonjs/models/operations/createcollection.d.ts.map +1 -1
- package/dist/commonjs/models/operations/createcollection.js +15 -7
- package/dist/commonjs/models/operations/createcollection.js.map +1 -1
- package/dist/commonjs/models/operations/deletedocs.d.ts +3 -0
- package/dist/commonjs/models/operations/deletedocs.d.ts.map +1 -1
- package/dist/commonjs/models/operations/deletedocs.js +1 -0
- package/dist/commonjs/models/operations/deletedocs.js.map +1 -1
- package/dist/commonjs/models/operations/fetchdocs.d.ts +3 -0
- package/dist/commonjs/models/operations/fetchdocs.d.ts.map +1 -1
- package/dist/commonjs/models/operations/fetchdocs.js +9 -0
- package/dist/commonjs/models/operations/fetchdocs.js.map +1 -1
- package/dist/commonjs/models/operations/getbulkupsertdocs.d.ts +5 -0
- package/dist/commonjs/models/operations/getbulkupsertdocs.d.ts.map +1 -1
- package/dist/commonjs/models/operations/getbulkupsertdocs.js +5 -3
- package/dist/commonjs/models/operations/getbulkupsertdocs.js.map +1 -1
- package/dist/commonjs/models/operations/listdocs.d.ts +9 -0
- package/dist/commonjs/models/operations/listdocs.d.ts.map +1 -1
- package/dist/commonjs/models/operations/listdocs.js +11 -0
- package/dist/commonjs/models/operations/listdocs.js.map +1 -1
- package/dist/commonjs/models/operations/querycollection.d.ts +3 -0
- package/dist/commonjs/models/operations/querycollection.d.ts.map +1 -1
- package/dist/commonjs/models/operations/querycollection.js +9 -0
- package/dist/commonjs/models/operations/querycollection.js.map +1 -1
- package/dist/commonjs/models/operations/updatecollection.d.ts +10 -4
- package/dist/commonjs/models/operations/updatecollection.d.ts.map +1 -1
- package/dist/commonjs/models/operations/updatecollection.js +8 -1
- package/dist/commonjs/models/operations/updatecollection.js.map +1 -1
- package/dist/commonjs/models/operations/updatedocs.d.ts +3 -0
- package/dist/commonjs/models/operations/updatedocs.d.ts.map +1 -1
- package/dist/commonjs/models/operations/updatedocs.js +1 -0
- package/dist/commonjs/models/operations/updatedocs.js.map +1 -1
- package/dist/commonjs/models/operations/upsertdocs.d.ts +3 -0
- package/dist/commonjs/models/operations/upsertdocs.d.ts.map +1 -1
- package/dist/commonjs/models/operations/upsertdocs.js +1 -0
- package/dist/commonjs/models/operations/upsertdocs.js.map +1 -1
- package/dist/commonjs/models/versioning.d.ts +100 -0
- package/dist/commonjs/models/versioning.d.ts.map +1 -0
- package/dist/commonjs/models/versioning.js +93 -0
- package/dist/commonjs/models/versioning.js.map +1 -0
- package/dist/commonjs/types/public.d.ts +80 -6
- package/dist/commonjs/types/public.d.ts.map +1 -1
- package/dist/commonjs/types/public.js +30 -7
- package/dist/commonjs/types/public.js.map +1 -1
- package/dist/commonjs/versioning.d.ts +63 -0
- package/dist/commonjs/versioning.d.ts.map +1 -0
- package/dist/commonjs/versioning.js +390 -0
- package/dist/commonjs/versioning.js.map +1 -0
- package/dist/esm/client.d.ts +25 -10
- package/dist/esm/client.d.ts.map +1 -1
- package/dist/esm/client.js +183 -58
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/compat/qdrant/client.d.ts +3 -6
- package/dist/esm/compat/qdrant/client.d.ts.map +1 -1
- package/dist/esm/compat/qdrant/client.js +17 -11
- package/dist/esm/compat/qdrant/client.js.map +1 -1
- package/dist/esm/funcs/collectionsCreate.js +1 -1
- package/dist/esm/funcs/collectionsDelete.js +1 -1
- package/dist/esm/funcs/collectionsDocsGetBulkUpsert.js +5 -1
- package/dist/esm/funcs/collectionsDocsGetBulkUpsert.js.map +1 -1
- package/dist/esm/funcs/collectionsDocsListDocs.js +2 -0
- package/dist/esm/funcs/collectionsDocsListDocs.js.map +1 -1
- package/dist/esm/index.d.ts +4 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/config.d.ts +2 -2
- package/dist/esm/lib/config.js +2 -2
- package/dist/esm/lib/config.js.map +1 -1
- package/dist/esm/lib/queryInput.d.ts +3 -11
- package/dist/esm/lib/queryInput.d.ts.map +1 -1
- package/dist/esm/lib/queryInput.js.map +1 -1
- package/dist/esm/models/collectionresponse.d.ts +12 -21
- package/dist/esm/models/collectionresponse.d.ts.map +1 -1
- package/dist/esm/models/collectionresponse.js +5 -6
- package/dist/esm/models/collectionresponse.js.map +1 -1
- package/dist/esm/models/index.d.ts +1 -0
- package/dist/esm/models/index.d.ts.map +1 -1
- package/dist/esm/models/index.js +1 -0
- package/dist/esm/models/index.js.map +1 -1
- package/dist/esm/models/operations/bulkupsertdocs.d.ts +6 -0
- package/dist/esm/models/operations/bulkupsertdocs.d.ts.map +1 -1
- package/dist/esm/models/operations/bulkupsertdocs.js +2 -0
- package/dist/esm/models/operations/bulkupsertdocs.js.map +1 -1
- package/dist/esm/models/operations/createcollection.d.ts +20 -13
- package/dist/esm/models/operations/createcollection.d.ts.map +1 -1
- package/dist/esm/models/operations/createcollection.js +15 -7
- package/dist/esm/models/operations/createcollection.js.map +1 -1
- package/dist/esm/models/operations/deletedocs.d.ts +3 -0
- package/dist/esm/models/operations/deletedocs.d.ts.map +1 -1
- package/dist/esm/models/operations/deletedocs.js +1 -0
- package/dist/esm/models/operations/deletedocs.js.map +1 -1
- package/dist/esm/models/operations/fetchdocs.d.ts +3 -0
- package/dist/esm/models/operations/fetchdocs.d.ts.map +1 -1
- package/dist/esm/models/operations/fetchdocs.js +9 -0
- package/dist/esm/models/operations/fetchdocs.js.map +1 -1
- package/dist/esm/models/operations/getbulkupsertdocs.d.ts +5 -0
- package/dist/esm/models/operations/getbulkupsertdocs.d.ts.map +1 -1
- package/dist/esm/models/operations/getbulkupsertdocs.js +6 -4
- package/dist/esm/models/operations/getbulkupsertdocs.js.map +1 -1
- package/dist/esm/models/operations/listdocs.d.ts +9 -0
- package/dist/esm/models/operations/listdocs.d.ts.map +1 -1
- package/dist/esm/models/operations/listdocs.js +11 -0
- package/dist/esm/models/operations/listdocs.js.map +1 -1
- package/dist/esm/models/operations/querycollection.d.ts +3 -0
- package/dist/esm/models/operations/querycollection.d.ts.map +1 -1
- package/dist/esm/models/operations/querycollection.js +9 -0
- package/dist/esm/models/operations/querycollection.js.map +1 -1
- package/dist/esm/models/operations/updatecollection.d.ts +10 -4
- package/dist/esm/models/operations/updatecollection.d.ts.map +1 -1
- package/dist/esm/models/operations/updatecollection.js +8 -1
- package/dist/esm/models/operations/updatecollection.js.map +1 -1
- package/dist/esm/models/operations/updatedocs.d.ts +3 -0
- package/dist/esm/models/operations/updatedocs.d.ts.map +1 -1
- package/dist/esm/models/operations/updatedocs.js +1 -0
- package/dist/esm/models/operations/updatedocs.js.map +1 -1
- package/dist/esm/models/operations/upsertdocs.d.ts +3 -0
- package/dist/esm/models/operations/upsertdocs.d.ts.map +1 -1
- package/dist/esm/models/operations/upsertdocs.js +1 -0
- package/dist/esm/models/operations/upsertdocs.js.map +1 -1
- package/dist/esm/models/versioning.d.ts +100 -0
- package/dist/esm/models/versioning.d.ts.map +1 -0
- package/dist/esm/models/versioning.js +57 -0
- package/dist/esm/models/versioning.js.map +1 -0
- package/dist/esm/types/public.d.ts +80 -6
- package/dist/esm/types/public.d.ts.map +1 -1
- package/dist/esm/types/public.js +26 -7
- package/dist/esm/types/public.js.map +1 -1
- package/dist/esm/versioning.d.ts +63 -0
- package/dist/esm/versioning.d.ts.map +1 -0
- package/dist/esm/versioning.js +344 -0
- package/dist/esm/versioning.js.map +1 -0
- package/jsr.json +3 -1
- package/package.json +14 -2
- package/src/client.ts +300 -61
- package/src/compat/qdrant/client.ts +28 -16
- package/src/funcs/collectionsCreate.ts +1 -1
- package/src/funcs/collectionsDelete.ts +1 -1
- package/src/funcs/collectionsDocsGetBulkUpsert.ts +6 -1
- package/src/funcs/collectionsDocsListDocs.ts +2 -0
- package/src/index.ts +17 -0
- package/src/lib/config.ts +2 -2
- package/src/lib/queryInput.ts +3 -10
- package/src/models/collectionresponse.ts +17 -26
- package/src/models/index.ts +1 -0
- package/src/models/operations/bulkupsertdocs.ts +8 -0
- package/src/models/operations/createcollection.ts +39 -18
- package/src/models/operations/deletedocs.ts +4 -0
- package/src/models/operations/fetchdocs.ts +12 -0
- package/src/models/operations/getbulkupsertdocs.ts +11 -4
- package/src/models/operations/listdocs.ts +20 -0
- package/src/models/operations/querycollection.ts +12 -0
- package/src/models/operations/updatecollection.ts +21 -3
- package/src/models/operations/updatedocs.ts +4 -0
- package/src/models/operations/upsertdocs.ts +4 -0
- package/src/models/versioning.ts +118 -0
- package/src/types/public.ts +127 -14
- package/src/versioning.ts +490 -0
- package/examples/collectionScoped.example.ts +0 -38
- package/examples/collectionsList.example.ts +0 -25
- package/examples/package-lock.json +0 -612
- package/examples/package.json +0 -18
- package/test/integration/qdrant-compat-external.test.mjs +0 -351
- package/test/integration/qdrant-compat-live.test.mjs +0 -122
- package/test/null-response.test.mjs +0 -73
- package/test/public-api.test.mjs +0 -540
- package/test/qdrant-compat.test.mjs +0 -547
- package/tsconfig.json +0 -39
package/src/client.ts
CHANGED
|
@@ -12,6 +12,12 @@
|
|
|
12
12
|
|
|
13
13
|
import { LambdaDBCore } from "./core.js";
|
|
14
14
|
import type { SDKOptions } from "./lib/config.js";
|
|
15
|
+
import {
|
|
16
|
+
HTTPClient,
|
|
17
|
+
isAbortError,
|
|
18
|
+
isConnectionError,
|
|
19
|
+
isTimeoutError,
|
|
20
|
+
} from "./lib/http.js";
|
|
15
21
|
import { collectionsCreate } from "./funcs/collectionsCreate.js";
|
|
16
22
|
import { collectionsDelete } from "./funcs/collectionsDelete.js";
|
|
17
23
|
import { collectionsGet } from "./funcs/collectionsGet.js";
|
|
@@ -27,14 +33,26 @@ import { collectionsDocsListDocsExtended } from "./funcs/collectionsDocsListDocs
|
|
|
27
33
|
import { collectionsDocsUpdate } from "./funcs/collectionsDocsUpdate.js";
|
|
28
34
|
import { collectionsDocsUpsert } from "./funcs/collectionsDocsUpsert.js";
|
|
29
35
|
import type { RequestOptions } from "./lib/sdks.js";
|
|
30
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
ConnectionError,
|
|
38
|
+
RequestAbortedError,
|
|
39
|
+
RequestTimeoutError,
|
|
40
|
+
UnexpectedClientError,
|
|
41
|
+
} from "./models/errors/httpclienterrors.js";
|
|
42
|
+
import {
|
|
43
|
+
CollectionAliases,
|
|
44
|
+
CollectionBranches,
|
|
45
|
+
CollectionTags,
|
|
46
|
+
} from "./versioning.js";
|
|
31
47
|
import { unwrapAsync, OK, ERR } from "./types/fp.js";
|
|
32
48
|
import type { Result } from "./types/fp.js";
|
|
33
49
|
import type * as operations from "./models/operations/index.js";
|
|
34
50
|
import type * as models from "./models/index.js";
|
|
35
51
|
import {
|
|
36
52
|
listCollectionsResponseWithDates,
|
|
53
|
+
createCollectionResponseWithDates,
|
|
37
54
|
getCollectionResponseWithDates,
|
|
55
|
+
updateCollectionResponseWithDates,
|
|
38
56
|
type CreateCollectionInput,
|
|
39
57
|
type UpdateCollectionInput,
|
|
40
58
|
type QueryCollectionInput,
|
|
@@ -46,17 +64,18 @@ import {
|
|
|
46
64
|
type ListCollectionsInput,
|
|
47
65
|
type ListCollectionsResponseWithDates,
|
|
48
66
|
type GetCollectionResponseWithDates,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
67
|
+
type CreateCollectionResponseWithDates,
|
|
68
|
+
type UpdateCollectionResponseWithDates,
|
|
69
|
+
type GetBulkUpsertInput,
|
|
70
|
+
type UpsertDocsInput,
|
|
71
|
+
type UpdateDocsInput,
|
|
72
|
+
type DeleteDocsInput,
|
|
73
|
+
type FetchDocsInput,
|
|
74
|
+
type FetchDocsResponse,
|
|
75
|
+
type FetchDocsDoc,
|
|
76
|
+
type BulkUpsertInput,
|
|
77
|
+
type MessageResponse,
|
|
78
|
+
type GetBulkUpsertDocsResponse,
|
|
60
79
|
} from "./types/public.js";
|
|
61
80
|
import type {
|
|
62
81
|
ListCollectionsError,
|
|
@@ -87,15 +106,95 @@ export type { operations, models };
|
|
|
87
106
|
/**
|
|
88
107
|
* Fetches documents from a presigned docsUrl. Response must be { docs: [...] }.
|
|
89
108
|
*/
|
|
90
|
-
|
|
91
|
-
const
|
|
109
|
+
function transferSignal(options?: RequestOptions): AbortSignal | undefined {
|
|
110
|
+
const signal = options?.signal ?? options?.fetchOptions?.signal;
|
|
111
|
+
if (signal != null) return signal;
|
|
112
|
+
if (options?.timeoutMs != null && options.timeoutMs > 0) {
|
|
113
|
+
return AbortSignal.timeout(options.timeoutMs);
|
|
114
|
+
}
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function withTransferSignal(
|
|
119
|
+
init: RequestInit,
|
|
120
|
+
options?: RequestOptions,
|
|
121
|
+
): RequestInit {
|
|
122
|
+
const signal = transferSignal(options);
|
|
123
|
+
return signal === undefined ? init : { ...init, signal };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function serializeBulkUpsertPayload(
|
|
127
|
+
docs: UpsertDocsInput["docs"],
|
|
128
|
+
): { jsonString: string; sizeBytes: number } {
|
|
129
|
+
try {
|
|
130
|
+
const jsonString = JSON.stringify({ docs });
|
|
131
|
+
if (jsonString === undefined) {
|
|
132
|
+
throw new TypeError("JSON.stringify returned undefined");
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
jsonString,
|
|
136
|
+
sizeBytes: new TextEncoder().encode(jsonString).length,
|
|
137
|
+
};
|
|
138
|
+
} catch (cause) {
|
|
139
|
+
throw new UnexpectedClientError(
|
|
140
|
+
"Failed to serialize bulk upsert payload",
|
|
141
|
+
{ cause },
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function classifyTransferError(
|
|
147
|
+
message: string,
|
|
148
|
+
cause: unknown,
|
|
149
|
+
): ConnectionError | RequestAbortedError | RequestTimeoutError | UnexpectedClientError {
|
|
150
|
+
if (isAbortError(cause)) {
|
|
151
|
+
return new RequestAbortedError("Request aborted by client", { cause });
|
|
152
|
+
}
|
|
153
|
+
if (isTimeoutError(cause)) {
|
|
154
|
+
return new RequestTimeoutError("Request timed out", { cause });
|
|
155
|
+
}
|
|
156
|
+
if (isConnectionError(cause)) {
|
|
157
|
+
return new ConnectionError("Unable to make request", { cause });
|
|
158
|
+
}
|
|
159
|
+
return new UnexpectedClientError(message, { cause });
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function readTransferText(
|
|
163
|
+
response: Response,
|
|
164
|
+
errorMessage: string,
|
|
165
|
+
): Promise<string> {
|
|
166
|
+
try {
|
|
167
|
+
return await response.text();
|
|
168
|
+
} catch (cause) {
|
|
169
|
+
throw classifyTransferError(errorMessage, cause);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async function fetchDocsFromUrl<T>(
|
|
174
|
+
transferClient: HTTPClient,
|
|
175
|
+
docsUrl: string,
|
|
176
|
+
options?: RequestOptions,
|
|
177
|
+
): Promise<T[]> {
|
|
178
|
+
let res: Response;
|
|
179
|
+
try {
|
|
180
|
+
res = await transferClient.request(
|
|
181
|
+
new Request(
|
|
182
|
+
docsUrl,
|
|
183
|
+
withTransferSignal({ method: "GET" }, options),
|
|
184
|
+
),
|
|
185
|
+
);
|
|
186
|
+
} catch (cause) {
|
|
187
|
+
throw classifyTransferError("Failed to fetch documents from URL", cause);
|
|
188
|
+
}
|
|
189
|
+
const text = await readTransferText(
|
|
190
|
+
res,
|
|
191
|
+
"Failed to read documents from URL",
|
|
192
|
+
);
|
|
92
193
|
if (!res.ok) {
|
|
93
|
-
const text = await res.text();
|
|
94
194
|
throw new UnexpectedClientError(
|
|
95
195
|
`Failed to fetch documents from URL: ${res.status} ${res.statusText}${text ? ` - ${text}` : ""}`,
|
|
96
196
|
);
|
|
97
197
|
}
|
|
98
|
-
const text = await res.text();
|
|
99
198
|
if (text.trim() === "") {
|
|
100
199
|
return [];
|
|
101
200
|
}
|
|
@@ -146,6 +245,11 @@ export type LambdaDBClientOptions = SDKOptions & {
|
|
|
146
245
|
* Project name (path segment under /projects/). Default: "playground"
|
|
147
246
|
*/
|
|
148
247
|
projectName?: string;
|
|
248
|
+
/**
|
|
249
|
+
* Separate unauthenticated transport for presigned uploads and downloads.
|
|
250
|
+
* API authentication and API request headers are never copied to it.
|
|
251
|
+
*/
|
|
252
|
+
transferClient?: HTTPClient;
|
|
149
253
|
};
|
|
150
254
|
|
|
151
255
|
function normalizeClientOptions(
|
|
@@ -156,8 +260,10 @@ function normalizeClientOptions(
|
|
|
156
260
|
projectName = DEFAULT_PROJECT_NAME,
|
|
157
261
|
serverURL,
|
|
158
262
|
projectHost,
|
|
263
|
+
transferClient: _transferClient,
|
|
159
264
|
...rest
|
|
160
265
|
} = options;
|
|
266
|
+
void _transferClient;
|
|
161
267
|
|
|
162
268
|
if (serverURL !== undefined && serverURL !== null) {
|
|
163
269
|
return { ...rest, serverURL };
|
|
@@ -176,8 +282,11 @@ function normalizeClientOptions(
|
|
|
176
282
|
* `LambdaDB` when you want to avoid passing collectionName on every call.
|
|
177
283
|
*/
|
|
178
284
|
export class LambdaDBClient extends LambdaDBCore {
|
|
179
|
-
|
|
285
|
+
readonly #transferClient: HTTPClient;
|
|
286
|
+
|
|
287
|
+
constructor(options: LambdaDBClientOptions = {}) {
|
|
180
288
|
super(normalizeClientOptions(options));
|
|
289
|
+
this.#transferClient = options.transferClient ?? new HTTPClient();
|
|
181
290
|
}
|
|
182
291
|
|
|
183
292
|
/**
|
|
@@ -185,7 +294,7 @@ export class LambdaDBClient extends LambdaDBCore {
|
|
|
185
294
|
* use this collection name; you do not pass it again.
|
|
186
295
|
*/
|
|
187
296
|
collection(collectionName: string): CollectionHandle {
|
|
188
|
-
return new CollectionHandle(this, collectionName);
|
|
297
|
+
return new CollectionHandle(this, collectionName, this.#transferClient);
|
|
189
298
|
}
|
|
190
299
|
|
|
191
300
|
/**
|
|
@@ -257,8 +366,10 @@ export class LambdaDBClient extends LambdaDBCore {
|
|
|
257
366
|
async createCollection(
|
|
258
367
|
request: CreateCollectionInput,
|
|
259
368
|
options?: RequestOptions,
|
|
260
|
-
) {
|
|
261
|
-
return
|
|
369
|
+
): Promise<CreateCollectionResponseWithDates> {
|
|
370
|
+
return createCollectionResponseWithDates(
|
|
371
|
+
await unwrapAsync(collectionsCreate(this, request, options)),
|
|
372
|
+
);
|
|
262
373
|
}
|
|
263
374
|
|
|
264
375
|
/**
|
|
@@ -267,8 +378,10 @@ export class LambdaDBClient extends LambdaDBCore {
|
|
|
267
378
|
async createCollectionSafe(
|
|
268
379
|
request: CreateCollectionInput,
|
|
269
380
|
options?: RequestOptions,
|
|
270
|
-
): Promise<Result<
|
|
271
|
-
|
|
381
|
+
): Promise<Result<CreateCollectionResponseWithDates, CreateCollectionError>> {
|
|
382
|
+
const result = await collectionsCreate(this, request, options);
|
|
383
|
+
if (!result.ok) return result;
|
|
384
|
+
return OK(createCollectionResponseWithDates(result.value));
|
|
272
385
|
}
|
|
273
386
|
}
|
|
274
387
|
|
|
@@ -279,8 +392,13 @@ export class CollectionHandle {
|
|
|
279
392
|
constructor(
|
|
280
393
|
private readonly client: LambdaDBCore,
|
|
281
394
|
readonly collectionName: string,
|
|
395
|
+
private readonly transferClient: HTTPClient = new HTTPClient(),
|
|
282
396
|
) {}
|
|
283
397
|
|
|
398
|
+
readonly branches = new CollectionBranches(this.client, this.collectionName);
|
|
399
|
+
readonly tags = new CollectionTags(this.client, this.collectionName);
|
|
400
|
+
readonly aliases = new CollectionAliases(this.client, this.collectionName);
|
|
401
|
+
|
|
284
402
|
/**
|
|
285
403
|
* Get metadata of this collection. Timestamp fields are returned as Date.
|
|
286
404
|
*/
|
|
@@ -312,8 +430,8 @@ export class CollectionHandle {
|
|
|
312
430
|
async update(
|
|
313
431
|
requestBody: UpdateCollectionInput,
|
|
314
432
|
options?: RequestOptions,
|
|
315
|
-
) {
|
|
316
|
-
|
|
433
|
+
): Promise<UpdateCollectionResponseWithDates> {
|
|
434
|
+
const response = await unwrapAsync(
|
|
317
435
|
collectionsUpdate(
|
|
318
436
|
this.client,
|
|
319
437
|
{
|
|
@@ -323,6 +441,7 @@ export class CollectionHandle {
|
|
|
323
441
|
options,
|
|
324
442
|
),
|
|
325
443
|
);
|
|
444
|
+
return updateCollectionResponseWithDates(response);
|
|
326
445
|
}
|
|
327
446
|
|
|
328
447
|
/**
|
|
@@ -331,12 +450,14 @@ export class CollectionHandle {
|
|
|
331
450
|
async updateSafe(
|
|
332
451
|
requestBody: UpdateCollectionInput,
|
|
333
452
|
options?: RequestOptions,
|
|
334
|
-
): Promise<Result<
|
|
335
|
-
|
|
453
|
+
): Promise<Result<UpdateCollectionResponseWithDates, UpdateCollectionError>> {
|
|
454
|
+
const result = await collectionsUpdate(
|
|
336
455
|
this.client,
|
|
337
456
|
{ collectionName: this.collectionName, requestBody },
|
|
338
457
|
options,
|
|
339
458
|
);
|
|
459
|
+
if (!result.ok) return result;
|
|
460
|
+
return OK(updateCollectionResponseWithDates(result.value));
|
|
340
461
|
}
|
|
341
462
|
|
|
342
463
|
/**
|
|
@@ -386,7 +507,9 @@ export class CollectionHandle {
|
|
|
386
507
|
);
|
|
387
508
|
if (!result.isDocsInline && result.docsUrl) {
|
|
388
509
|
const docs = await fetchDocsFromUrl<QueryCollectionDoc>(
|
|
510
|
+
this.transferClient,
|
|
389
511
|
result.docsUrl,
|
|
512
|
+
options,
|
|
390
513
|
);
|
|
391
514
|
return { ...result, docs, isDocsInline: true };
|
|
392
515
|
}
|
|
@@ -409,7 +532,11 @@ export class CollectionHandle {
|
|
|
409
532
|
if (!result.ok) return result;
|
|
410
533
|
if (!result.value.isDocsInline && result.value.docsUrl) {
|
|
411
534
|
try {
|
|
412
|
-
const docs = await fetchDocsFromUrl<QueryCollectionDoc>(
|
|
535
|
+
const docs = await fetchDocsFromUrl<QueryCollectionDoc>(
|
|
536
|
+
this.transferClient,
|
|
537
|
+
result.value.docsUrl,
|
|
538
|
+
options,
|
|
539
|
+
);
|
|
413
540
|
return OK({ ...result.value, docs, isDocsInline: true });
|
|
414
541
|
} catch (e) {
|
|
415
542
|
return ERR(e as QueryCollectionError);
|
|
@@ -418,16 +545,21 @@ export class CollectionHandle {
|
|
|
418
545
|
return result;
|
|
419
546
|
}
|
|
420
547
|
|
|
421
|
-
readonly docs: CollectionDocs = new CollectionDocs(
|
|
548
|
+
readonly docs: CollectionDocs = new CollectionDocs(
|
|
549
|
+
this.client,
|
|
550
|
+
this.collectionName,
|
|
551
|
+
this.transferClient,
|
|
552
|
+
);
|
|
422
553
|
}
|
|
423
554
|
|
|
424
555
|
/**
|
|
425
556
|
* Document operations scoped to a collection.
|
|
426
557
|
*/
|
|
427
|
-
class CollectionDocs {
|
|
558
|
+
export class CollectionDocs {
|
|
428
559
|
constructor(
|
|
429
560
|
private readonly client: LambdaDBCore,
|
|
430
561
|
private readonly collectionName: string,
|
|
562
|
+
private readonly transferClient: HTTPClient,
|
|
431
563
|
) {}
|
|
432
564
|
|
|
433
565
|
/**
|
|
@@ -455,6 +587,7 @@ class CollectionDocs {
|
|
|
455
587
|
partitionFilter: params?.partitionFilter,
|
|
456
588
|
fields: params?.fields,
|
|
457
589
|
includeVectors: params?.includeVectors,
|
|
590
|
+
ref: params?.ref,
|
|
458
591
|
},
|
|
459
592
|
},
|
|
460
593
|
options,
|
|
@@ -466,12 +599,18 @@ class CollectionDocs {
|
|
|
466
599
|
size: params?.size,
|
|
467
600
|
pageToken: params?.pageToken,
|
|
468
601
|
includeVectors: params?.includeVectors,
|
|
602
|
+
refKind: params?.ref?.kind,
|
|
603
|
+
refName: params?.ref?.name,
|
|
469
604
|
},
|
|
470
605
|
options,
|
|
471
606
|
),
|
|
472
607
|
);
|
|
473
608
|
if (!result.isDocsInline && result.docsUrl) {
|
|
474
|
-
const docs = await fetchDocsFromUrl<ListDocsDoc>(
|
|
609
|
+
const docs = await fetchDocsFromUrl<ListDocsDoc>(
|
|
610
|
+
this.transferClient,
|
|
611
|
+
result.docsUrl,
|
|
612
|
+
options,
|
|
613
|
+
);
|
|
475
614
|
return { ...result, docs, isDocsInline: true };
|
|
476
615
|
}
|
|
477
616
|
return result;
|
|
@@ -500,6 +639,7 @@ class CollectionDocs {
|
|
|
500
639
|
partitionFilter: params?.partitionFilter,
|
|
501
640
|
fields: params?.fields,
|
|
502
641
|
includeVectors: params?.includeVectors,
|
|
642
|
+
ref: params?.ref,
|
|
503
643
|
},
|
|
504
644
|
},
|
|
505
645
|
options,
|
|
@@ -511,13 +651,19 @@ class CollectionDocs {
|
|
|
511
651
|
size: params?.size,
|
|
512
652
|
pageToken: params?.pageToken,
|
|
513
653
|
includeVectors: params?.includeVectors,
|
|
654
|
+
refKind: params?.ref?.kind,
|
|
655
|
+
refName: params?.ref?.name,
|
|
514
656
|
},
|
|
515
657
|
options,
|
|
516
658
|
);
|
|
517
659
|
if (!result.ok) return result;
|
|
518
660
|
if (!result.value.isDocsInline && result.value.docsUrl) {
|
|
519
661
|
try {
|
|
520
|
-
const docs = await fetchDocsFromUrl<ListDocsDoc>(
|
|
662
|
+
const docs = await fetchDocsFromUrl<ListDocsDoc>(
|
|
663
|
+
this.transferClient,
|
|
664
|
+
result.value.docsUrl,
|
|
665
|
+
options,
|
|
666
|
+
);
|
|
521
667
|
return OK({ ...result.value, docs, isDocsInline: true });
|
|
522
668
|
} catch (e) {
|
|
523
669
|
return ERR(e as ListDocsError);
|
|
@@ -550,6 +696,7 @@ class CollectionDocs {
|
|
|
550
696
|
partitionFilter: params?.partitionFilter,
|
|
551
697
|
fields: params?.fields,
|
|
552
698
|
includeVectors: params?.includeVectors,
|
|
699
|
+
ref: params?.ref,
|
|
553
700
|
};
|
|
554
701
|
while (true) {
|
|
555
702
|
const page = await this.list({ ...baseParams, pageToken }, options);
|
|
@@ -698,7 +845,9 @@ class CollectionDocs {
|
|
|
698
845
|
);
|
|
699
846
|
if (!result.isDocsInline && result.docsUrl) {
|
|
700
847
|
const docs = await fetchDocsFromUrl<FetchDocsDoc>(
|
|
848
|
+
this.transferClient,
|
|
701
849
|
result.docsUrl,
|
|
850
|
+
options,
|
|
702
851
|
);
|
|
703
852
|
return { ...result, docs, isDocsInline: true };
|
|
704
853
|
}
|
|
@@ -721,7 +870,11 @@ class CollectionDocs {
|
|
|
721
870
|
if (!result.ok) return result;
|
|
722
871
|
if (!result.value.isDocsInline && result.value.docsUrl) {
|
|
723
872
|
try {
|
|
724
|
-
const docs = await fetchDocsFromUrl<FetchDocsDoc>(
|
|
873
|
+
const docs = await fetchDocsFromUrl<FetchDocsDoc>(
|
|
874
|
+
this.transferClient,
|
|
875
|
+
result.value.docsUrl,
|
|
876
|
+
options,
|
|
877
|
+
);
|
|
725
878
|
return OK({ ...result.value, docs, isDocsInline: true });
|
|
726
879
|
} catch (e) {
|
|
727
880
|
return ERR(e as FetchDocsError);
|
|
@@ -733,12 +886,28 @@ class CollectionDocs {
|
|
|
733
886
|
/**
|
|
734
887
|
* Get presigned URL and metadata for bulk upload (up to 200MB). Not supported for collections with managed embedding vector fields.
|
|
735
888
|
*/
|
|
736
|
-
async getBulkUpsert(
|
|
889
|
+
async getBulkUpsert(
|
|
890
|
+
options?: RequestOptions,
|
|
891
|
+
): Promise<GetBulkUpsertDocsResponse>;
|
|
892
|
+
async getBulkUpsert(
|
|
893
|
+
input: GetBulkUpsertInput,
|
|
894
|
+
options?: RequestOptions,
|
|
895
|
+
): Promise<GetBulkUpsertDocsResponse>;
|
|
896
|
+
async getBulkUpsert(
|
|
897
|
+
inputOrOptions?: GetBulkUpsertInput | RequestOptions,
|
|
898
|
+
options?: RequestOptions,
|
|
899
|
+
): Promise<GetBulkUpsertDocsResponse> {
|
|
900
|
+
const hasInput = options !== undefined
|
|
901
|
+
|| (inputOrOptions != null && "branch" in inputOrOptions);
|
|
902
|
+
const input = hasInput ? inputOrOptions as GetBulkUpsertInput : {};
|
|
903
|
+
const requestOptions = hasInput
|
|
904
|
+
? options
|
|
905
|
+
: inputOrOptions as RequestOptions | undefined;
|
|
737
906
|
return unwrapAsync(
|
|
738
907
|
collectionsDocsGetBulkUpsert(
|
|
739
908
|
this.client,
|
|
740
|
-
{ collectionName: this.collectionName },
|
|
741
|
-
|
|
909
|
+
{ collectionName: this.collectionName, branch: input.branch },
|
|
910
|
+
requestOptions,
|
|
742
911
|
),
|
|
743
912
|
);
|
|
744
913
|
}
|
|
@@ -748,11 +917,25 @@ class CollectionDocs {
|
|
|
748
917
|
*/
|
|
749
918
|
async getBulkUpsertSafe(
|
|
750
919
|
options?: RequestOptions,
|
|
920
|
+
): Promise<Result<GetBulkUpsertDocsResponse, GetBulkUpsertDocsError>>;
|
|
921
|
+
async getBulkUpsertSafe(
|
|
922
|
+
input: GetBulkUpsertInput,
|
|
923
|
+
options?: RequestOptions,
|
|
924
|
+
): Promise<Result<GetBulkUpsertDocsResponse, GetBulkUpsertDocsError>>;
|
|
925
|
+
async getBulkUpsertSafe(
|
|
926
|
+
inputOrOptions?: GetBulkUpsertInput | RequestOptions,
|
|
927
|
+
options?: RequestOptions,
|
|
751
928
|
): Promise<Result<GetBulkUpsertDocsResponse, GetBulkUpsertDocsError>> {
|
|
929
|
+
const hasInput = options !== undefined
|
|
930
|
+
|| (inputOrOptions != null && "branch" in inputOrOptions);
|
|
931
|
+
const input = hasInput ? inputOrOptions as GetBulkUpsertInput : {};
|
|
932
|
+
const requestOptions = hasInput
|
|
933
|
+
? options
|
|
934
|
+
: inputOrOptions as RequestOptions | undefined;
|
|
752
935
|
return await collectionsDocsGetBulkUpsert(
|
|
753
936
|
this.client,
|
|
754
|
-
{ collectionName: this.collectionName },
|
|
755
|
-
|
|
937
|
+
{ collectionName: this.collectionName, branch: input.branch },
|
|
938
|
+
requestOptions,
|
|
756
939
|
);
|
|
757
940
|
}
|
|
758
941
|
|
|
@@ -798,36 +981,50 @@ class CollectionDocs {
|
|
|
798
981
|
body: UpsertDocsInput,
|
|
799
982
|
options?: RequestOptions,
|
|
800
983
|
): Promise<MessageResponse> {
|
|
801
|
-
const { url, type, httpMethod, objectKey, sizeLimitBytes } =
|
|
984
|
+
const { url, type, httpMethod, objectKey, sizeLimitBytes, headers } =
|
|
985
|
+
await this.getBulkUpsert({ branch: body.branch }, options);
|
|
802
986
|
|
|
803
|
-
const
|
|
804
|
-
const jsonString = JSON.stringify(payload);
|
|
805
|
-
const sizeBytes = new TextEncoder().encode(jsonString).length;
|
|
987
|
+
const { jsonString, sizeBytes } = serializeBulkUpsertPayload(body.docs);
|
|
806
988
|
if (sizeBytes > sizeLimitBytes) {
|
|
807
989
|
throw new Error(
|
|
808
990
|
`Bulk upsert payload size (${sizeBytes} bytes) exceeds limit (${sizeLimitBytes} bytes)`,
|
|
809
991
|
);
|
|
810
992
|
}
|
|
811
993
|
|
|
812
|
-
const
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
994
|
+
const uploadHeaders = new Headers(headers);
|
|
995
|
+
uploadHeaders.set("Content-Type", type);
|
|
996
|
+
let putResponse: Response;
|
|
997
|
+
try {
|
|
998
|
+
putResponse = await this.transferClient.request(
|
|
999
|
+
new Request(
|
|
1000
|
+
url,
|
|
1001
|
+
withTransferSignal({
|
|
1002
|
+
method: httpMethod,
|
|
1003
|
+
headers: uploadHeaders,
|
|
1004
|
+
body: jsonString,
|
|
1005
|
+
}, options),
|
|
1006
|
+
),
|
|
1007
|
+
);
|
|
1008
|
+
} catch (cause) {
|
|
1009
|
+
throw classifyTransferError("Bulk upsert upload failed", cause);
|
|
1010
|
+
}
|
|
817
1011
|
|
|
818
1012
|
if (!putResponse.ok) {
|
|
819
|
-
const text = await
|
|
1013
|
+
const text = await readTransferText(
|
|
1014
|
+
putResponse,
|
|
1015
|
+
"Failed to read bulk upsert upload response",
|
|
1016
|
+
);
|
|
820
1017
|
throw new Error(
|
|
821
1018
|
`Bulk upsert upload failed: ${putResponse.status} ${putResponse.statusText}${text ? ` - ${text}` : ""}`,
|
|
822
1019
|
);
|
|
823
1020
|
}
|
|
824
1021
|
|
|
825
|
-
return this.bulkUpsert({ objectKey }, options);
|
|
1022
|
+
return this.bulkUpsert({ objectKey, type, branch: body.branch }, options);
|
|
826
1023
|
}
|
|
827
1024
|
|
|
828
1025
|
/**
|
|
829
1026
|
* Bulk upsert documents in one call (Safe: returns Result instead of throwing). Not supported for collections with managed embedding vector fields.
|
|
830
|
-
* May return Error for local failures (payload size, upload). API errors use GetBulkUpsertDocsError or BulkUpsertDocsError.
|
|
1027
|
+
* May return Error for local failures (serialization, payload size, upload). API errors use GetBulkUpsertDocsError or BulkUpsertDocsError.
|
|
831
1028
|
*/
|
|
832
1029
|
async bulkUpsertDocsSafe(
|
|
833
1030
|
body: UpsertDocsInput,
|
|
@@ -838,13 +1035,28 @@ class CollectionDocs {
|
|
|
838
1035
|
GetBulkUpsertDocsError | BulkUpsertDocsError | Error
|
|
839
1036
|
>
|
|
840
1037
|
> {
|
|
841
|
-
const getResult = await this.getBulkUpsertSafe(
|
|
1038
|
+
const getResult = await this.getBulkUpsertSafe(
|
|
1039
|
+
{ branch: body.branch },
|
|
1040
|
+
options,
|
|
1041
|
+
);
|
|
842
1042
|
if (!getResult.ok) return getResult;
|
|
843
|
-
const { url, type, httpMethod, objectKey, sizeLimitBytes } =
|
|
1043
|
+
const { url, type, httpMethod, objectKey, sizeLimitBytes, headers } =
|
|
1044
|
+
getResult.value;
|
|
844
1045
|
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
1046
|
+
let jsonString: string;
|
|
1047
|
+
let sizeBytes: number;
|
|
1048
|
+
try {
|
|
1049
|
+
({ jsonString, sizeBytes } = serializeBulkUpsertPayload(body.docs));
|
|
1050
|
+
} catch (cause) {
|
|
1051
|
+
return ERR(
|
|
1052
|
+
cause instanceof Error
|
|
1053
|
+
? cause
|
|
1054
|
+
: new UnexpectedClientError(
|
|
1055
|
+
"Failed to serialize bulk upsert payload",
|
|
1056
|
+
{ cause },
|
|
1057
|
+
),
|
|
1058
|
+
);
|
|
1059
|
+
}
|
|
848
1060
|
if (sizeBytes > sizeLimitBytes) {
|
|
849
1061
|
return ERR(
|
|
850
1062
|
new Error(
|
|
@@ -853,14 +1065,41 @@ class CollectionDocs {
|
|
|
853
1065
|
);
|
|
854
1066
|
}
|
|
855
1067
|
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
1068
|
+
let putResponse: Response;
|
|
1069
|
+
try {
|
|
1070
|
+
const uploadHeaders = new Headers(headers);
|
|
1071
|
+
uploadHeaders.set("Content-Type", type);
|
|
1072
|
+
putResponse = await this.transferClient.request(
|
|
1073
|
+
new Request(
|
|
1074
|
+
url,
|
|
1075
|
+
withTransferSignal({
|
|
1076
|
+
method: httpMethod,
|
|
1077
|
+
headers: uploadHeaders,
|
|
1078
|
+
body: jsonString,
|
|
1079
|
+
}, options),
|
|
1080
|
+
),
|
|
1081
|
+
);
|
|
1082
|
+
} catch (cause) {
|
|
1083
|
+
return ERR(classifyTransferError("Bulk upsert upload failed", cause));
|
|
1084
|
+
}
|
|
861
1085
|
|
|
862
1086
|
if (!putResponse.ok) {
|
|
863
|
-
|
|
1087
|
+
let text: string;
|
|
1088
|
+
try {
|
|
1089
|
+
text = await readTransferText(
|
|
1090
|
+
putResponse,
|
|
1091
|
+
"Failed to read bulk upsert upload response",
|
|
1092
|
+
);
|
|
1093
|
+
} catch (cause) {
|
|
1094
|
+
return ERR(
|
|
1095
|
+
cause instanceof Error
|
|
1096
|
+
? cause
|
|
1097
|
+
: new UnexpectedClientError(
|
|
1098
|
+
"Failed to read bulk upsert upload response",
|
|
1099
|
+
{ cause },
|
|
1100
|
+
),
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
864
1103
|
return ERR(
|
|
865
1104
|
new Error(
|
|
866
1105
|
`Bulk upsert upload failed: ${putResponse.status} ${putResponse.statusText}${text ? ` - ${text}` : ""}`,
|
|
@@ -868,6 +1107,6 @@ class CollectionDocs {
|
|
|
868
1107
|
);
|
|
869
1108
|
}
|
|
870
1109
|
|
|
871
|
-
return this.bulkUpsertSafe({ objectKey }, options);
|
|
1110
|
+
return this.bulkUpsertSafe({ objectKey, type, branch: body.branch }, options);
|
|
872
1111
|
}
|
|
873
1112
|
}
|