@meshagent/meshagent 0.36.3 → 0.37.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 +16 -0
- package/dist/browser/agent-client.d.ts +2 -10
- package/dist/browser/agent-client.js +2 -30
- package/dist/browser/agent.d.ts +22 -22
- package/dist/browser/agent.js +36 -16
- package/dist/browser/containers-client.d.ts +7 -19
- package/dist/browser/containers-client.js +27 -21
- package/dist/browser/data-types.d.ts +12 -0
- package/dist/browser/data-types.js +39 -1
- package/dist/browser/database-client.d.ts +134 -47
- package/dist/browser/database-client.js +359 -133
- package/dist/browser/index.d.ts +1 -0
- package/dist/browser/index.js +1 -0
- package/dist/browser/meshagent-client.js +12 -1
- package/dist/browser/participant-token.d.ts +189 -22
- package/dist/browser/participant-token.js +1001 -189
- package/dist/browser/room-client.d.ts +1 -1
- package/dist/browser/services-client.d.ts +1 -1
- package/dist/browser/version.d.ts +1 -0
- package/dist/browser/version.js +4 -0
- package/dist/esm/agent-client.d.ts +2 -10
- package/dist/esm/agent-client.js +1 -28
- package/dist/esm/agent.d.ts +22 -22
- package/dist/esm/agent.js +33 -14
- package/dist/esm/containers-client.d.ts +7 -19
- package/dist/esm/containers-client.js +27 -21
- package/dist/esm/data-types.d.ts +12 -0
- package/dist/esm/data-types.js +36 -0
- package/dist/esm/database-client.d.ts +134 -47
- package/dist/esm/database-client.js +352 -132
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/meshagent-client.js +12 -1
- package/dist/esm/participant-token.d.ts +189 -22
- package/dist/esm/participant-token.js +992 -188
- package/dist/esm/room-client.d.ts +1 -1
- package/dist/esm/services-client.d.ts +1 -1
- package/dist/esm/version.d.ts +1 -0
- package/dist/esm/version.js +1 -0
- package/dist/node/agent-client.d.ts +2 -10
- package/dist/node/agent-client.js +2 -30
- package/dist/node/agent.d.ts +22 -22
- package/dist/node/agent.js +36 -16
- package/dist/node/containers-client.d.ts +7 -19
- package/dist/node/containers-client.js +27 -21
- package/dist/node/data-types.d.ts +12 -0
- package/dist/node/data-types.js +39 -1
- package/dist/node/database-client.d.ts +134 -47
- package/dist/node/database-client.js +359 -133
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.js +1 -0
- package/dist/node/meshagent-client.js +12 -1
- package/dist/node/participant-token.d.ts +189 -22
- package/dist/node/participant-token.js +1001 -189
- package/dist/node/room-client.d.ts +1 -1
- package/dist/node/services-client.d.ts +1 -1
- package/dist/node/version.d.ts +1 -0
- package/dist/node/version.js +4 -0
- package/package.json +1 -1
|
@@ -1,7 +1,103 @@
|
|
|
1
1
|
import { DataType } from "./data-types";
|
|
2
2
|
import { RoomServerException } from "./room-server-client";
|
|
3
3
|
import { ControlContent, ErrorContent, JsonContent } from "./response";
|
|
4
|
+
export class DatabaseValueEncoder {
|
|
5
|
+
}
|
|
6
|
+
export class DatabaseExpression extends DatabaseValueEncoder {
|
|
7
|
+
constructor(expression) {
|
|
8
|
+
super();
|
|
9
|
+
const normalized = expression.trim();
|
|
10
|
+
if (normalized === "") {
|
|
11
|
+
throw new TypeError("database expression must not be empty");
|
|
12
|
+
}
|
|
13
|
+
this.expression = normalized;
|
|
14
|
+
}
|
|
15
|
+
encodeDatabaseValue() {
|
|
16
|
+
return {
|
|
17
|
+
expression: this.expression,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
toString() {
|
|
21
|
+
return this.expression;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export class DatabaseDate extends DatabaseValueEncoder {
|
|
25
|
+
constructor(value) {
|
|
26
|
+
super();
|
|
27
|
+
const normalized = value.trim();
|
|
28
|
+
const parsed = new Date(`${normalized}T00:00:00Z`);
|
|
29
|
+
if (!ISO_DATE_REGEX.test(normalized) || Number.isNaN(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== normalized) {
|
|
30
|
+
throw new TypeError("invalid database date format");
|
|
31
|
+
}
|
|
32
|
+
this.value = normalized;
|
|
33
|
+
}
|
|
34
|
+
encodeDatabaseValue() {
|
|
35
|
+
return {
|
|
36
|
+
date: this.value,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
toString() {
|
|
40
|
+
return this.value;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export class DatabaseStruct extends DatabaseValueEncoder {
|
|
44
|
+
constructor(fields) {
|
|
45
|
+
super();
|
|
46
|
+
this.fields = Object.fromEntries(Object.entries(fields).map(([key, value]) => {
|
|
47
|
+
if (typeof key !== "string") {
|
|
48
|
+
throw new TypeError("database struct keys must be strings");
|
|
49
|
+
}
|
|
50
|
+
return [key, value];
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
toJson() {
|
|
54
|
+
return Object.fromEntries(Object.entries(this.fields).map(([key, value]) => [key, encodeRecordValue(value)]));
|
|
55
|
+
}
|
|
56
|
+
encodeDatabaseValue() {
|
|
57
|
+
return {
|
|
58
|
+
struct: this.toJson(),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export class DatabaseJson extends DatabaseValueEncoder {
|
|
63
|
+
constructor(value) {
|
|
64
|
+
super();
|
|
65
|
+
this.value = normalizeDatabaseJsonValue(value);
|
|
66
|
+
}
|
|
67
|
+
toJson() {
|
|
68
|
+
return this.value;
|
|
69
|
+
}
|
|
70
|
+
encodeDatabaseValue() {
|
|
71
|
+
return {
|
|
72
|
+
json: this.value,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
4
76
|
const globalScope = globalThis;
|
|
77
|
+
const UUID_HEX_REGEX = /^[0-9a-f]{32}$/;
|
|
78
|
+
const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
79
|
+
function normalizeUuidHex(value) {
|
|
80
|
+
const normalized = value.trim().toLowerCase().replace(/-/g, "");
|
|
81
|
+
if (!UUID_HEX_REGEX.test(normalized)) {
|
|
82
|
+
throw new RoomServerException("invalid uuid format");
|
|
83
|
+
}
|
|
84
|
+
return normalized;
|
|
85
|
+
}
|
|
86
|
+
function formatUuidHex(value) {
|
|
87
|
+
return (`${value.substring(0, 8)}-` +
|
|
88
|
+
`${value.substring(8, 12)}-` +
|
|
89
|
+
`${value.substring(12, 16)}-` +
|
|
90
|
+
`${value.substring(16, 20)}-` +
|
|
91
|
+
`${value.substring(20)}`);
|
|
92
|
+
}
|
|
93
|
+
export class DatabaseUuid {
|
|
94
|
+
constructor(value) {
|
|
95
|
+
this.value = formatUuidHex(normalizeUuidHex(value));
|
|
96
|
+
}
|
|
97
|
+
toString() {
|
|
98
|
+
return this.value;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
5
101
|
function bytesToBase64(bytes) {
|
|
6
102
|
if (globalScope.Buffer) {
|
|
7
103
|
return globalScope.Buffer.from(bytes).toString("base64");
|
|
@@ -32,13 +128,32 @@ function base64ToBytes(base64) {
|
|
|
32
128
|
function isRecord(value) {
|
|
33
129
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
34
130
|
}
|
|
131
|
+
function isPlainRecord(value) {
|
|
132
|
+
return isRecord(value) && (Object.getPrototypeOf(value) === Object.prototype
|
|
133
|
+
|| Object.getPrototypeOf(value) === null);
|
|
134
|
+
}
|
|
135
|
+
function normalizeDatabaseJsonValue(value) {
|
|
136
|
+
if (value === null ||
|
|
137
|
+
typeof value === "boolean" ||
|
|
138
|
+
typeof value === "number" ||
|
|
139
|
+
typeof value === "string") {
|
|
140
|
+
return value;
|
|
141
|
+
}
|
|
142
|
+
if (Array.isArray(value)) {
|
|
143
|
+
return value.map((item) => normalizeDatabaseJsonValue(item));
|
|
144
|
+
}
|
|
145
|
+
if (isPlainRecord(value)) {
|
|
146
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, normalizeDatabaseJsonValue(item)]));
|
|
147
|
+
}
|
|
148
|
+
throw new TypeError("database json values must be valid JSON");
|
|
149
|
+
}
|
|
35
150
|
function metadataEntries(metadata) {
|
|
36
151
|
if (metadata == null) {
|
|
37
152
|
return null;
|
|
38
153
|
}
|
|
39
154
|
return Object.entries(metadata).map(([key, value]) => ({
|
|
40
155
|
key,
|
|
41
|
-
value: typeof value === "string" ? value : JSON.stringify(
|
|
156
|
+
value: typeof value === "string" ? value : JSON.stringify(value),
|
|
42
157
|
}));
|
|
43
158
|
}
|
|
44
159
|
function toolkitDataTypeJson(dataType) {
|
|
@@ -128,125 +243,124 @@ function publicDataTypeJson(value) {
|
|
|
128
243
|
}
|
|
129
244
|
return payload;
|
|
130
245
|
}
|
|
131
|
-
function
|
|
246
|
+
function encodeRecordValue(value) {
|
|
247
|
+
if (value instanceof DatabaseValueEncoder) {
|
|
248
|
+
return value.encodeDatabaseValue();
|
|
249
|
+
}
|
|
250
|
+
if (value instanceof DatabaseUuid) {
|
|
251
|
+
return {
|
|
252
|
+
uuid: value.toString(),
|
|
253
|
+
};
|
|
254
|
+
}
|
|
132
255
|
if (value instanceof Uint8Array) {
|
|
133
256
|
return {
|
|
134
|
-
|
|
135
|
-
data: bytesToBase64(value),
|
|
257
|
+
binary: bytesToBase64(value),
|
|
136
258
|
};
|
|
137
259
|
}
|
|
138
260
|
if (value instanceof Date) {
|
|
139
|
-
return
|
|
261
|
+
return {
|
|
262
|
+
timestamp: value.toISOString().replace("+00:00", "Z"),
|
|
263
|
+
};
|
|
140
264
|
}
|
|
141
265
|
if (Array.isArray(value)) {
|
|
142
|
-
return
|
|
266
|
+
return {
|
|
267
|
+
list: value.map((item) => encodeRecordValue(item)),
|
|
268
|
+
};
|
|
143
269
|
}
|
|
144
270
|
if (isRecord(value)) {
|
|
145
|
-
|
|
271
|
+
throw new RoomServerException("database object values must use DatabaseStruct or DatabaseJson");
|
|
146
272
|
}
|
|
147
273
|
return value;
|
|
148
274
|
}
|
|
149
|
-
function
|
|
150
|
-
if (value
|
|
151
|
-
return {
|
|
275
|
+
function databaseSqlLiteral(value) {
|
|
276
|
+
if (value instanceof DatabaseUuid) {
|
|
277
|
+
return `X'${normalizeUuidHex(value.toString())}'`;
|
|
152
278
|
}
|
|
153
|
-
if (
|
|
154
|
-
return
|
|
155
|
-
}
|
|
156
|
-
if (typeof value === "number") {
|
|
157
|
-
if (Number.isInteger(value)) {
|
|
158
|
-
return { type: "int", value };
|
|
159
|
-
}
|
|
160
|
-
return { type: "float", value };
|
|
279
|
+
if (value instanceof DatabaseDate) {
|
|
280
|
+
return JSON.stringify(value.toString());
|
|
161
281
|
}
|
|
162
|
-
if (
|
|
163
|
-
return
|
|
282
|
+
if (value instanceof Date) {
|
|
283
|
+
return JSON.stringify(value.toISOString().replace("+00:00", "Z"));
|
|
164
284
|
}
|
|
165
|
-
if (value instanceof
|
|
166
|
-
return
|
|
167
|
-
type: "binary",
|
|
168
|
-
data: bytesToBase64(value),
|
|
169
|
-
};
|
|
285
|
+
if (value instanceof DatabaseJson) {
|
|
286
|
+
return JSON.stringify(JSON.stringify(value.toJson()));
|
|
170
287
|
}
|
|
171
|
-
if (value instanceof
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
value: value.toISOString().replace("+00:00", "Z"),
|
|
175
|
-
};
|
|
288
|
+
if (value instanceof DatabaseStruct) {
|
|
289
|
+
const fields = Object.entries(value.fields).map(([key, fieldValue]) => (`${JSON.stringify(key)}, ${databaseSqlLiteral(fieldValue)}`));
|
|
290
|
+
return `named_struct(${fields.join(", ")})`;
|
|
176
291
|
}
|
|
292
|
+
return JSON.stringify(encodeRecordValue(value));
|
|
293
|
+
}
|
|
294
|
+
function decodeRecordValue(value) {
|
|
177
295
|
if (Array.isArray(value)) {
|
|
178
|
-
|
|
179
|
-
type: "list",
|
|
180
|
-
items: value.map((item) => encodeStreamValue(item)),
|
|
181
|
-
};
|
|
296
|
+
throw new RoomServerException("database list values must use a {'list': [...]} wrapper");
|
|
182
297
|
}
|
|
183
|
-
if (isRecord(value)) {
|
|
184
|
-
return
|
|
185
|
-
type: "struct",
|
|
186
|
-
fields: Object.entries(value).map(([name, fieldValue]) => ({
|
|
187
|
-
name,
|
|
188
|
-
value: encodeStreamValue(fieldValue),
|
|
189
|
-
})),
|
|
190
|
-
};
|
|
298
|
+
if (!isRecord(value)) {
|
|
299
|
+
return value;
|
|
191
300
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (!isRecord(value) || typeof value.type !== "string") {
|
|
196
|
-
throw new RoomServerException(`unexpected return type from database.${operation}`);
|
|
301
|
+
const entries = Object.entries(value);
|
|
302
|
+
if (entries.length !== 1) {
|
|
303
|
+
throw new RoomServerException("database object values must use a single-key type wrapper");
|
|
197
304
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
throw new RoomServerException(`unexpected return type from database.${operation}`);
|
|
305
|
+
const [wrapper, payload] = entries[0];
|
|
306
|
+
switch (wrapper) {
|
|
307
|
+
case "binary":
|
|
308
|
+
if (typeof payload !== "string") {
|
|
309
|
+
throw new RoomServerException("database binary values must be base64 strings");
|
|
204
310
|
}
|
|
205
|
-
return
|
|
206
|
-
case "
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
311
|
+
return base64ToBytes(payload);
|
|
312
|
+
case "uuid":
|
|
313
|
+
if (typeof payload !== "string") {
|
|
314
|
+
throw new RoomServerException("database uuid values must be strings");
|
|
315
|
+
}
|
|
316
|
+
return new DatabaseUuid(payload);
|
|
317
|
+
case "expression":
|
|
318
|
+
if (typeof payload !== "string") {
|
|
319
|
+
throw new RoomServerException("database expression values must be strings");
|
|
210
320
|
}
|
|
211
|
-
return
|
|
212
|
-
case "text":
|
|
321
|
+
return new DatabaseExpression(payload);
|
|
213
322
|
case "date":
|
|
323
|
+
if (typeof payload !== "string") {
|
|
324
|
+
throw new RoomServerException("database date values must be strings");
|
|
325
|
+
}
|
|
326
|
+
return new DatabaseDate(payload);
|
|
214
327
|
case "timestamp":
|
|
215
|
-
if (typeof
|
|
216
|
-
throw new RoomServerException(
|
|
328
|
+
if (typeof payload !== "string") {
|
|
329
|
+
throw new RoomServerException("database timestamp values must be strings");
|
|
217
330
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
331
|
+
{
|
|
332
|
+
const parsed = new Date(payload);
|
|
333
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
334
|
+
throw new RoomServerException("database timestamp value is not valid");
|
|
335
|
+
}
|
|
336
|
+
return parsed;
|
|
222
337
|
}
|
|
223
|
-
return base64ToBytes(value.data);
|
|
224
338
|
case "list":
|
|
225
|
-
if (!Array.isArray(
|
|
226
|
-
throw new RoomServerException(
|
|
339
|
+
if (!Array.isArray(payload)) {
|
|
340
|
+
throw new RoomServerException("database list values must be arrays");
|
|
227
341
|
}
|
|
228
|
-
return
|
|
342
|
+
return payload.map((item) => decodeRecordValue(item));
|
|
229
343
|
case "struct":
|
|
230
|
-
if (!
|
|
231
|
-
throw new RoomServerException(
|
|
344
|
+
if (!isRecord(payload)) {
|
|
345
|
+
throw new RoomServerException("database struct values must be objects");
|
|
232
346
|
}
|
|
233
|
-
return Object.fromEntries(
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
return [field.name, decodeStreamValue(field.value, operation)];
|
|
238
|
-
}));
|
|
347
|
+
return new DatabaseStruct(Object.fromEntries(Object.entries(payload).map(([key, item]) => [key, decodeRecordValue(item)])));
|
|
348
|
+
case "json":
|
|
349
|
+
return new DatabaseJson(normalizeDatabaseJsonValue(payload));
|
|
239
350
|
default:
|
|
240
|
-
throw new RoomServerException(`
|
|
351
|
+
throw new RoomServerException(`unsupported database value wrapper '${wrapper}'`);
|
|
241
352
|
}
|
|
242
353
|
}
|
|
354
|
+
function encodeDatabaseRecord(record) {
|
|
355
|
+
return Object.fromEntries(Object.entries(record).map(([key, value]) => [key, encodeRecordValue(value)]));
|
|
356
|
+
}
|
|
243
357
|
function rowsChunk(records) {
|
|
244
358
|
return {
|
|
245
359
|
kind: "rows",
|
|
246
360
|
rows: records.map((record) => ({
|
|
247
361
|
columns: Object.entries(record).map(([name, value]) => ({
|
|
248
362
|
name,
|
|
249
|
-
value:
|
|
363
|
+
value: encodeRecordValue(value),
|
|
250
364
|
})),
|
|
251
365
|
})),
|
|
252
366
|
};
|
|
@@ -263,7 +377,12 @@ function recordsFromRowsChunk(payload, operation) {
|
|
|
263
377
|
if (!isRecord(column) || typeof column.name !== "string") {
|
|
264
378
|
throw new RoomServerException(`unexpected return type from database.${operation}`);
|
|
265
379
|
}
|
|
266
|
-
|
|
380
|
+
try {
|
|
381
|
+
return [column.name, decodeRecordValue(column.value)];
|
|
382
|
+
}
|
|
383
|
+
catch {
|
|
384
|
+
throw new RoomServerException(`unexpected return type from database.${operation}`);
|
|
385
|
+
}
|
|
267
386
|
}));
|
|
268
387
|
});
|
|
269
388
|
}
|
|
@@ -291,7 +410,7 @@ async function* toAsyncIterable(chunks) {
|
|
|
291
410
|
function buildWhereClause(where) {
|
|
292
411
|
if (where != null && typeof where === "object" && !Array.isArray(where)) {
|
|
293
412
|
return Object.entries(where)
|
|
294
|
-
.map(([key, value]) => `${key} = ${
|
|
413
|
+
.map(([key, value]) => `${key} = ${databaseSqlLiteral(value)}`)
|
|
295
414
|
.join(" AND ");
|
|
296
415
|
}
|
|
297
416
|
if (typeof where === "string") {
|
|
@@ -341,6 +460,39 @@ function tableVersionFromJson(value) {
|
|
|
341
460
|
metadata,
|
|
342
461
|
};
|
|
343
462
|
}
|
|
463
|
+
function tableBranchFromJson(value) {
|
|
464
|
+
if (!isRecord(value) || typeof value.name !== "string") {
|
|
465
|
+
throw new RoomServerException("unexpected return type from database.list_branches");
|
|
466
|
+
}
|
|
467
|
+
if (value.parent_branch != null && typeof value.parent_branch !== "string") {
|
|
468
|
+
throw new RoomServerException("unexpected return type from database.list_branches");
|
|
469
|
+
}
|
|
470
|
+
if (value.parent_version != null
|
|
471
|
+
&& (typeof value.parent_version !== "number" || !Number.isInteger(value.parent_version))) {
|
|
472
|
+
throw new RoomServerException("unexpected return type from database.list_branches");
|
|
473
|
+
}
|
|
474
|
+
if (value.manifest_size != null
|
|
475
|
+
&& (typeof value.manifest_size !== "number" || !Number.isInteger(value.manifest_size))) {
|
|
476
|
+
throw new RoomServerException("unexpected return type from database.list_branches");
|
|
477
|
+
}
|
|
478
|
+
let createdAt = null;
|
|
479
|
+
if (value.created_at != null) {
|
|
480
|
+
if (typeof value.created_at !== "string") {
|
|
481
|
+
throw new RoomServerException("unexpected return type from database.list_branches");
|
|
482
|
+
}
|
|
483
|
+
createdAt = new Date(value.created_at);
|
|
484
|
+
if (Number.isNaN(createdAt.getTime())) {
|
|
485
|
+
throw new RoomServerException("unexpected return type from database.list_branches");
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return {
|
|
489
|
+
name: value.name,
|
|
490
|
+
parentBranch: value.parent_branch ?? null,
|
|
491
|
+
parentVersion: value.parent_version ?? null,
|
|
492
|
+
createdAt,
|
|
493
|
+
manifestSize: value.manifest_size ?? null,
|
|
494
|
+
};
|
|
495
|
+
}
|
|
344
496
|
class DatabaseWriteInputStream {
|
|
345
497
|
constructor(start, chunks) {
|
|
346
498
|
this.start = start;
|
|
@@ -521,61 +673,72 @@ export class DatabaseClient {
|
|
|
521
673
|
input.close();
|
|
522
674
|
}
|
|
523
675
|
}
|
|
524
|
-
async listTables({ namespace } = {}) {
|
|
525
|
-
const response = await this.invoke("list_tables", {
|
|
676
|
+
async listTables({ namespace, branch } = {}) {
|
|
677
|
+
const response = await this.invoke("list_tables", {
|
|
678
|
+
namespace: namespace ?? null,
|
|
679
|
+
branch: branch ?? null,
|
|
680
|
+
});
|
|
526
681
|
if (!(response instanceof JsonContent)) {
|
|
527
682
|
throw this._unexpectedResponseError("list_tables");
|
|
528
683
|
}
|
|
529
684
|
return Array.isArray(response.json.tables) ? response.json.tables : [];
|
|
530
685
|
}
|
|
531
|
-
async createTable({ name, data, schema, mode = "create", namespace, metadata, }) {
|
|
686
|
+
async createTable({ name, data, schema, mode = "create", namespace, branch, metadata, }) {
|
|
532
687
|
const input = new DatabaseWriteInputStream({
|
|
533
688
|
kind: "start",
|
|
534
689
|
name,
|
|
535
690
|
fields: schemaEntries(schema),
|
|
536
691
|
mode,
|
|
537
692
|
namespace: namespace ?? null,
|
|
693
|
+
branch: branch ?? null,
|
|
538
694
|
metadata: metadataEntries(metadata),
|
|
539
695
|
}, data ?? []);
|
|
540
696
|
await this.drainWriteStream("create_table", input);
|
|
541
697
|
}
|
|
542
|
-
async createTableWithSchema({ name, schema, data, mode = "create", namespace, metadata }) {
|
|
698
|
+
async createTableWithSchema({ name, schema, data, mode = "create", namespace, branch, metadata }) {
|
|
543
699
|
return this.createTable({
|
|
544
700
|
name,
|
|
545
701
|
schema,
|
|
546
702
|
data: data == null ? undefined : rowChunkList(data),
|
|
547
703
|
mode,
|
|
548
704
|
namespace,
|
|
705
|
+
branch,
|
|
549
706
|
metadata,
|
|
550
707
|
});
|
|
551
708
|
}
|
|
552
|
-
async createTableFromData({ name, data, mode = "create", namespace, metadata }) {
|
|
709
|
+
async createTableFromData({ name, data, mode = "create", namespace, branch, metadata }) {
|
|
553
710
|
return this.createTable({
|
|
554
711
|
name,
|
|
555
712
|
data: data == null ? undefined : rowChunkList(data),
|
|
556
713
|
mode,
|
|
557
714
|
namespace,
|
|
715
|
+
branch,
|
|
558
716
|
metadata,
|
|
559
717
|
});
|
|
560
718
|
}
|
|
561
|
-
async createTableFromDataStream({ name, chunks, schema, mode = "create", namespace, metadata }) {
|
|
562
|
-
return this.createTable({ name, data: chunks, schema, mode, namespace, metadata });
|
|
719
|
+
async createTableFromDataStream({ name, chunks, schema, mode = "create", namespace, branch, metadata }) {
|
|
720
|
+
return this.createTable({ name, data: chunks, schema, mode, namespace, branch, metadata });
|
|
563
721
|
}
|
|
564
|
-
async dropTable({ name, ignoreMissing = false, namespace }) {
|
|
722
|
+
async dropTable({ name, ignoreMissing = false, namespace, branch }) {
|
|
565
723
|
await this.room.invoke({
|
|
566
724
|
toolkit: "database",
|
|
567
725
|
tool: "drop_table",
|
|
568
|
-
input: {
|
|
726
|
+
input: {
|
|
727
|
+
name,
|
|
728
|
+
ignore_missing: ignoreMissing,
|
|
729
|
+
namespace: namespace ?? null,
|
|
730
|
+
branch: branch ?? null,
|
|
731
|
+
},
|
|
569
732
|
});
|
|
570
733
|
}
|
|
571
|
-
async dropIndex({ table, name, namespace }) {
|
|
734
|
+
async dropIndex({ table, name, namespace, branch }) {
|
|
572
735
|
await this.room.invoke({
|
|
573
736
|
toolkit: "database",
|
|
574
737
|
tool: "drop_index",
|
|
575
|
-
input: { table, name, namespace: namespace ?? null },
|
|
738
|
+
input: { table, name, namespace: namespace ?? null, branch: branch ?? null },
|
|
576
739
|
});
|
|
577
740
|
}
|
|
578
|
-
async addColumns({ table, newColumns, namespace }) {
|
|
741
|
+
async addColumns({ table, newColumns, namespace, branch }) {
|
|
579
742
|
await this.room.invoke({
|
|
580
743
|
toolkit: "database",
|
|
581
744
|
tool: "add_columns",
|
|
@@ -585,56 +748,59 @@ export class DatabaseClient {
|
|
|
585
748
|
? { name, value_sql: null, data_type: toolkitDataTypeJson(value) }
|
|
586
749
|
: { name, value_sql: value, data_type: null })),
|
|
587
750
|
namespace: namespace ?? null,
|
|
751
|
+
branch: branch ?? null,
|
|
588
752
|
},
|
|
589
753
|
});
|
|
590
754
|
}
|
|
591
|
-
async dropColumns({ table, columns, namespace }) {
|
|
755
|
+
async dropColumns({ table, columns, namespace, branch }) {
|
|
592
756
|
await this.room.invoke({
|
|
593
757
|
toolkit: "database",
|
|
594
758
|
tool: "drop_columns",
|
|
595
|
-
input: { table, columns, namespace: namespace ?? null },
|
|
759
|
+
input: { table, columns, namespace: namespace ?? null, branch: branch ?? null },
|
|
596
760
|
});
|
|
597
761
|
}
|
|
598
|
-
async insert({ table, records, namespace }) {
|
|
599
|
-
await this.insertStream({ table, chunks: rowChunkList(records), namespace });
|
|
762
|
+
async insert({ table, records, namespace, branch }) {
|
|
763
|
+
await this.insertStream({ table, chunks: rowChunkList(records), namespace, branch });
|
|
600
764
|
}
|
|
601
|
-
async insertStream({ table, chunks, namespace }) {
|
|
765
|
+
async insertStream({ table, chunks, namespace, branch }) {
|
|
602
766
|
const input = new DatabaseWriteInputStream({
|
|
603
767
|
kind: "start",
|
|
604
768
|
table,
|
|
605
769
|
namespace: namespace ?? null,
|
|
770
|
+
branch: branch ?? null,
|
|
606
771
|
}, chunks);
|
|
607
772
|
await this.drainWriteStream("insert", input);
|
|
608
773
|
}
|
|
609
|
-
async update({ table, where, values,
|
|
774
|
+
async update({ table, where, values, namespace, branch }) {
|
|
610
775
|
await this.room.invoke({
|
|
611
776
|
toolkit: "database",
|
|
612
777
|
tool: "update",
|
|
613
778
|
input: {
|
|
614
779
|
table,
|
|
615
780
|
where,
|
|
616
|
-
values:
|
|
617
|
-
values_sql: valuesSql == null ? null : Object.entries(valuesSql).map(([column, expression]) => ({ column, expression })),
|
|
781
|
+
values: Object.entries(values).map(([column, value]) => ({ column, value_json: JSON.stringify(encodeRecordValue(value)) })),
|
|
618
782
|
namespace: namespace ?? null,
|
|
783
|
+
branch: branch ?? null,
|
|
619
784
|
},
|
|
620
785
|
});
|
|
621
786
|
}
|
|
622
|
-
async delete({ table, where, namespace }) {
|
|
787
|
+
async delete({ table, where, namespace, branch }) {
|
|
623
788
|
await this.room.invoke({
|
|
624
789
|
toolkit: "database",
|
|
625
790
|
tool: "delete",
|
|
626
|
-
input: { table, where, namespace: namespace ?? null },
|
|
791
|
+
input: { table, where, namespace: namespace ?? null, branch: branch ?? null },
|
|
627
792
|
});
|
|
628
793
|
}
|
|
629
|
-
async merge({ table, on, records, namespace }) {
|
|
630
|
-
await this.mergeStream({ table, on, chunks: rowChunkList(records), namespace });
|
|
794
|
+
async merge({ table, on, records, namespace, branch }) {
|
|
795
|
+
await this.mergeStream({ table, on, chunks: rowChunkList(records), namespace, branch });
|
|
631
796
|
}
|
|
632
|
-
async mergeStream({ table, on, chunks, namespace }) {
|
|
797
|
+
async mergeStream({ table, on, chunks, namespace, branch }) {
|
|
633
798
|
const input = new DatabaseWriteInputStream({
|
|
634
799
|
kind: "start",
|
|
635
800
|
table,
|
|
636
801
|
on,
|
|
637
802
|
namespace: namespace ?? null,
|
|
803
|
+
branch: branch ?? null,
|
|
638
804
|
}, chunks);
|
|
639
805
|
await this.drainWriteStream("merge", input);
|
|
640
806
|
}
|
|
@@ -650,17 +816,28 @@ export class DatabaseClient {
|
|
|
650
816
|
kind: "start",
|
|
651
817
|
query,
|
|
652
818
|
tables: normalizeTableRefs(tables),
|
|
653
|
-
params_json: params == null ? null : JSON.stringify(
|
|
819
|
+
params_json: params == null ? null : JSON.stringify(encodeDatabaseRecord(params)),
|
|
654
820
|
});
|
|
655
821
|
}
|
|
656
|
-
async search({ table, text, vector, where, offset, limit, select, namespace }) {
|
|
822
|
+
async search({ table, text, vector, where, offset, limit, select, namespace, branch, version }) {
|
|
657
823
|
const rows = [];
|
|
658
|
-
for await (const chunk of this.searchStream({
|
|
824
|
+
for await (const chunk of this.searchStream({
|
|
825
|
+
table,
|
|
826
|
+
text,
|
|
827
|
+
vector,
|
|
828
|
+
where,
|
|
829
|
+
offset,
|
|
830
|
+
limit,
|
|
831
|
+
select,
|
|
832
|
+
namespace,
|
|
833
|
+
branch,
|
|
834
|
+
version,
|
|
835
|
+
})) {
|
|
659
836
|
rows.push(...chunk);
|
|
660
837
|
}
|
|
661
838
|
return rows;
|
|
662
839
|
}
|
|
663
|
-
async *searchStream({ table, text, vector, where, offset, limit, select, namespace }) {
|
|
840
|
+
async *searchStream({ table, text, vector, where, offset, limit, select, namespace, branch, version }) {
|
|
664
841
|
yield* this.streamRows("search", {
|
|
665
842
|
kind: "start",
|
|
666
843
|
table,
|
|
@@ -672,9 +849,11 @@ export class DatabaseClient {
|
|
|
672
849
|
limit: limit ?? null,
|
|
673
850
|
select: select ?? null,
|
|
674
851
|
namespace: namespace ?? null,
|
|
852
|
+
branch: branch ?? null,
|
|
853
|
+
version: version ?? null,
|
|
675
854
|
});
|
|
676
855
|
}
|
|
677
|
-
async count({ table, text, vector, where, namespace }) {
|
|
856
|
+
async count({ table, text, vector, where, namespace, branch, version }) {
|
|
678
857
|
const response = await this.invoke("count", {
|
|
679
858
|
table,
|
|
680
859
|
text: text ?? null,
|
|
@@ -682,14 +861,21 @@ export class DatabaseClient {
|
|
|
682
861
|
text_columns: null,
|
|
683
862
|
where: buildWhereClause(where),
|
|
684
863
|
namespace: namespace ?? null,
|
|
864
|
+
branch: branch ?? null,
|
|
865
|
+
version: version ?? null,
|
|
685
866
|
});
|
|
686
867
|
if (!(response instanceof JsonContent) || typeof response.json.count !== "number" || !Number.isInteger(response.json.count)) {
|
|
687
868
|
throw this._unexpectedResponseError("count");
|
|
688
869
|
}
|
|
689
870
|
return response.json.count;
|
|
690
871
|
}
|
|
691
|
-
async inspect({ table, namespace }) {
|
|
692
|
-
const response = await this.invoke("inspect", {
|
|
872
|
+
async inspect({ table, namespace, branch, version }) {
|
|
873
|
+
const response = await this.invoke("inspect", {
|
|
874
|
+
table,
|
|
875
|
+
namespace: namespace ?? null,
|
|
876
|
+
branch: branch ?? null,
|
|
877
|
+
version: version ?? null,
|
|
878
|
+
});
|
|
693
879
|
if (!(response instanceof JsonContent) || !Array.isArray(response.json.fields)) {
|
|
694
880
|
throw this._unexpectedResponseError("inspect");
|
|
695
881
|
}
|
|
@@ -703,55 +889,89 @@ export class DatabaseClient {
|
|
|
703
889
|
async optimize(tableOrParams) {
|
|
704
890
|
const table = typeof tableOrParams === "string" ? tableOrParams : tableOrParams.table;
|
|
705
891
|
const namespace = typeof tableOrParams === "string" ? undefined : tableOrParams.namespace;
|
|
706
|
-
|
|
707
|
-
}
|
|
708
|
-
async restore({ table, version, namespace }) {
|
|
892
|
+
const branch = typeof tableOrParams === "string" ? undefined : tableOrParams.branch;
|
|
709
893
|
await this.room.invoke({
|
|
710
894
|
toolkit: "database",
|
|
711
|
-
tool: "
|
|
712
|
-
input: { table,
|
|
895
|
+
tool: "optimize",
|
|
896
|
+
input: { table, namespace: namespace ?? null, branch: branch ?? null },
|
|
713
897
|
});
|
|
714
898
|
}
|
|
715
|
-
async
|
|
899
|
+
async restore({ table, version, namespace, branch }) {
|
|
716
900
|
await this.room.invoke({
|
|
717
901
|
toolkit: "database",
|
|
718
|
-
tool: "
|
|
719
|
-
input: { table, version, namespace: namespace ?? null },
|
|
902
|
+
tool: "restore",
|
|
903
|
+
input: { table, version, namespace: namespace ?? null, branch: branch ?? null },
|
|
720
904
|
});
|
|
721
905
|
}
|
|
722
|
-
async listVersions({ table, namespace }) {
|
|
723
|
-
const response = await this.invoke("list_versions", {
|
|
906
|
+
async listVersions({ table, namespace, branch }) {
|
|
907
|
+
const response = await this.invoke("list_versions", {
|
|
908
|
+
table,
|
|
909
|
+
namespace: namespace ?? null,
|
|
910
|
+
branch: branch ?? null,
|
|
911
|
+
});
|
|
724
912
|
if (!(response instanceof JsonContent) || !Array.isArray(response.json.versions)) {
|
|
725
913
|
throw this._unexpectedResponseError("list_versions");
|
|
726
914
|
}
|
|
727
915
|
return response.json.versions.map((version) => tableVersionFromJson(version));
|
|
728
916
|
}
|
|
729
|
-
async createVectorIndex({ table, column, replace = false, namespace }) {
|
|
917
|
+
async createVectorIndex({ table, column, replace = false, namespace, branch }) {
|
|
730
918
|
await this.room.invoke({
|
|
731
919
|
toolkit: "database",
|
|
732
920
|
tool: "create_vector_index",
|
|
733
|
-
input: { table, column, replace, namespace: namespace ?? null },
|
|
921
|
+
input: { table, column, replace, namespace: namespace ?? null, branch: branch ?? null },
|
|
734
922
|
});
|
|
735
923
|
}
|
|
736
|
-
async createScalarIndex({ table, column, replace = false, namespace }) {
|
|
924
|
+
async createScalarIndex({ table, column, replace = false, namespace, branch }) {
|
|
737
925
|
await this.room.invoke({
|
|
738
926
|
toolkit: "database",
|
|
739
927
|
tool: "create_scalar_index",
|
|
740
|
-
input: { table, column, replace, namespace: namespace ?? null },
|
|
928
|
+
input: { table, column, replace, namespace: namespace ?? null, branch: branch ?? null },
|
|
741
929
|
});
|
|
742
930
|
}
|
|
743
|
-
async createFullTextSearchIndex({ table, column, replace = false, namespace }) {
|
|
931
|
+
async createFullTextSearchIndex({ table, column, replace = false, namespace, branch }) {
|
|
744
932
|
await this.room.invoke({
|
|
745
933
|
toolkit: "database",
|
|
746
934
|
tool: "create_full_text_search_index",
|
|
747
|
-
input: { table, column, replace, namespace: namespace ?? null },
|
|
935
|
+
input: { table, column, replace, namespace: namespace ?? null, branch: branch ?? null },
|
|
748
936
|
});
|
|
749
937
|
}
|
|
750
|
-
async listIndexes({ table, namespace }) {
|
|
751
|
-
const response = await this.invoke("list_indexes", {
|
|
938
|
+
async listIndexes({ table, namespace, branch, version }) {
|
|
939
|
+
const response = await this.invoke("list_indexes", {
|
|
940
|
+
table,
|
|
941
|
+
namespace: namespace ?? null,
|
|
942
|
+
branch: branch ?? null,
|
|
943
|
+
version: version ?? null,
|
|
944
|
+
});
|
|
752
945
|
if (!(response instanceof JsonContent) || !Array.isArray(response.json.indexes)) {
|
|
753
946
|
throw this._unexpectedResponseError("list_indexes");
|
|
754
947
|
}
|
|
755
948
|
return response.json.indexes.map((index) => tableIndexFromJson(index));
|
|
756
949
|
}
|
|
950
|
+
async listBranches({ namespace } = {}) {
|
|
951
|
+
const response = await this.invoke("list_branches", {
|
|
952
|
+
namespace: namespace ?? null,
|
|
953
|
+
});
|
|
954
|
+
if (!(response instanceof JsonContent) || !Array.isArray(response.json.branches)) {
|
|
955
|
+
throw this._unexpectedResponseError("list_branches");
|
|
956
|
+
}
|
|
957
|
+
return response.json.branches.map((branch) => tableBranchFromJson(branch));
|
|
958
|
+
}
|
|
959
|
+
async createBranch({ branch, fromBranch, namespace }) {
|
|
960
|
+
await this.room.invoke({
|
|
961
|
+
toolkit: "database",
|
|
962
|
+
tool: "create_branch",
|
|
963
|
+
input: {
|
|
964
|
+
branch,
|
|
965
|
+
from_branch: fromBranch ?? null,
|
|
966
|
+
namespace: namespace ?? null,
|
|
967
|
+
},
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
async deleteBranch({ branch, namespace }) {
|
|
971
|
+
await this.room.invoke({
|
|
972
|
+
toolkit: "database",
|
|
973
|
+
tool: "delete_branch",
|
|
974
|
+
input: { branch, namespace: namespace ?? null },
|
|
975
|
+
});
|
|
976
|
+
}
|
|
757
977
|
}
|