@meshagent/meshagent 0.36.2 → 0.37.0

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