@meshagent/meshagent 0.38.4 → 0.39.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 (44) hide show
  1. package/CHANGELOG.md +9 -2
  2. package/dist/browser/datasets-client.d.ts +415 -0
  3. package/dist/{node/database-client.js → browser/datasets-client.js} +480 -234
  4. package/dist/browser/entrypoint.js +9 -17
  5. package/dist/browser/index.d.ts +1 -2
  6. package/dist/browser/index.js +1 -2
  7. package/dist/browser/meshagent-client.d.ts +109 -1
  8. package/dist/browser/meshagent-client.js +269 -3
  9. package/dist/browser/participant-token.d.ts +5 -5
  10. package/dist/browser/participant-token.js +14 -13
  11. package/dist/browser/room-client.d.ts +5 -3
  12. package/dist/browser/room-client.js +70 -4
  13. package/dist/esm/datasets-client.d.ts +415 -0
  14. package/dist/esm/{database-client.js → datasets-client.js} +473 -227
  15. package/dist/esm/entrypoint.js +6 -12
  16. package/dist/esm/index.d.ts +1 -2
  17. package/dist/esm/index.js +1 -2
  18. package/dist/esm/meshagent-client.d.ts +109 -1
  19. package/dist/esm/meshagent-client.js +269 -3
  20. package/dist/esm/participant-token.d.ts +5 -5
  21. package/dist/esm/participant-token.js +12 -11
  22. package/dist/esm/room-client.d.ts +5 -3
  23. package/dist/esm/room-client.js +70 -4
  24. package/dist/node/datasets-client.d.ts +415 -0
  25. package/dist/{browser/database-client.js → node/datasets-client.js} +480 -234
  26. package/dist/node/entrypoint.js +6 -12
  27. package/dist/node/index.d.ts +1 -2
  28. package/dist/node/index.js +1 -2
  29. package/dist/node/meshagent-client.d.ts +109 -1
  30. package/dist/node/meshagent-client.js +269 -3
  31. package/dist/node/participant-token.d.ts +5 -5
  32. package/dist/node/participant-token.js +14 -13
  33. package/dist/node/room-client.d.ts +5 -3
  34. package/dist/node/room-client.js +70 -4
  35. package/package.json +3 -2
  36. package/dist/browser/data-types.d.ts +0 -67
  37. package/dist/browser/data-types.js +0 -192
  38. package/dist/browser/database-client.d.ts +0 -281
  39. package/dist/esm/data-types.d.ts +0 -67
  40. package/dist/esm/data-types.js +0 -179
  41. package/dist/esm/database-client.d.ts +0 -281
  42. package/dist/node/data-types.d.ts +0 -67
  43. package/dist/node/data-types.js +0 -192
  44. package/dist/node/database-client.d.ts +0 -281
@@ -1,18 +1,19 @@
1
- import { DataType } from "./data-types";
1
+ import { Schema, Table, tableFromIPC, tableToIPC } from "apache-arrow";
2
2
  import { RoomServerException } from "./room-server-client";
3
- import { ControlContent, ErrorContent, JsonContent } from "./response";
4
- export class DatabaseValueEncoder {
3
+ import { BinaryContent, ControlContent, EmptyContent, ErrorContent, JsonContent } from "./response";
4
+ const ARROW_IPC_STREAM_MIME_TYPE = "application/vnd.apache.arrow.stream";
5
+ export class DatasetValueEncoder {
5
6
  }
6
- export class DatabaseExpression extends DatabaseValueEncoder {
7
+ export class DatasetExpression extends DatasetValueEncoder {
7
8
  constructor(expression) {
8
9
  super();
9
10
  const normalized = expression.trim();
10
11
  if (normalized === "") {
11
- throw new TypeError("database expression must not be empty");
12
+ throw new TypeError("dataset expression must not be empty");
12
13
  }
13
14
  this.expression = normalized;
14
15
  }
15
- encodeDatabaseValue() {
16
+ encodeDatasetValue() {
16
17
  return {
17
18
  expression: this.expression,
18
19
  };
@@ -21,17 +22,17 @@ export class DatabaseExpression extends DatabaseValueEncoder {
21
22
  return this.expression;
22
23
  }
23
24
  }
24
- export class DatabaseDate extends DatabaseValueEncoder {
25
+ export class DatasetDate extends DatasetValueEncoder {
25
26
  constructor(value) {
26
27
  super();
27
28
  const normalized = value.trim();
28
29
  const parsed = new Date(`${normalized}T00:00:00Z`);
29
30
  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
+ throw new TypeError("invalid dataset date format");
31
32
  }
32
33
  this.value = normalized;
33
34
  }
34
- encodeDatabaseValue() {
35
+ encodeDatasetValue() {
35
36
  return {
36
37
  date: this.value,
37
38
  };
@@ -40,12 +41,12 @@ export class DatabaseDate extends DatabaseValueEncoder {
40
41
  return this.value;
41
42
  }
42
43
  }
43
- export class DatabaseStruct extends DatabaseValueEncoder {
44
+ export class DatasetStruct extends DatasetValueEncoder {
44
45
  constructor(fields) {
45
46
  super();
46
47
  this.fields = Object.fromEntries(Object.entries(fields).map(([key, value]) => {
47
48
  if (typeof key !== "string") {
48
- throw new TypeError("database struct keys must be strings");
49
+ throw new TypeError("dataset struct keys must be strings");
49
50
  }
50
51
  return [key, value];
51
52
  }));
@@ -53,21 +54,21 @@ export class DatabaseStruct extends DatabaseValueEncoder {
53
54
  toJson() {
54
55
  return Object.fromEntries(Object.entries(this.fields).map(([key, value]) => [key, encodeRecordValue(value)]));
55
56
  }
56
- encodeDatabaseValue() {
57
+ encodeDatasetValue() {
57
58
  return {
58
59
  struct: this.toJson(),
59
60
  };
60
61
  }
61
62
  }
62
- export class DatabaseJson extends DatabaseValueEncoder {
63
+ export class DatasetJson extends DatasetValueEncoder {
63
64
  constructor(value) {
64
65
  super();
65
- this.value = normalizeDatabaseJsonValue(value);
66
+ this.value = normalizeDatasetJsonValue(value);
66
67
  }
67
68
  toJson() {
68
69
  return this.value;
69
70
  }
70
- encodeDatabaseValue() {
71
+ encodeDatasetValue() {
71
72
  return {
72
73
  json: this.value,
73
74
  };
@@ -90,7 +91,7 @@ function formatUuidHex(value) {
90
91
  `${value.substring(16, 20)}-` +
91
92
  `${value.substring(20)}`);
92
93
  }
93
- export class DatabaseUuid {
94
+ export class DatasetUuid {
94
95
  constructor(value) {
95
96
  this.value = formatUuidHex(normalizeUuidHex(value));
96
97
  }
@@ -132,7 +133,7 @@ function isPlainRecord(value) {
132
133
  return isRecord(value) && (Object.getPrototypeOf(value) === Object.prototype
133
134
  || Object.getPrototypeOf(value) === null);
134
135
  }
135
- function normalizeDatabaseJsonValue(value) {
136
+ function normalizeDatasetJsonValue(value) {
136
137
  if (value === null ||
137
138
  typeof value === "boolean" ||
138
139
  typeof value === "number" ||
@@ -140,12 +141,12 @@ function normalizeDatabaseJsonValue(value) {
140
141
  return value;
141
142
  }
142
143
  if (Array.isArray(value)) {
143
- return value.map((item) => normalizeDatabaseJsonValue(item));
144
+ return value.map((item) => normalizeDatasetJsonValue(item));
144
145
  }
145
146
  if (isPlainRecord(value)) {
146
- return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, normalizeDatabaseJsonValue(item)]));
147
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, normalizeDatasetJsonValue(item)]));
147
148
  }
148
- throw new TypeError("database json values must be valid JSON");
149
+ throw new TypeError("dataset json values must be valid JSON");
149
150
  }
150
151
  function metadataEntries(metadata) {
151
152
  if (metadata == null) {
@@ -156,98 +157,11 @@ function metadataEntries(metadata) {
156
157
  value: typeof value === "string" ? value : JSON.stringify(value),
157
158
  }));
158
159
  }
159
- function toolkitDataTypeJson(dataType) {
160
- const json = dataType.toJson();
161
- const payload = {
162
- type: json.type,
163
- nullable: json.nullable ?? null,
164
- metadata: metadataEntries(json.metadata),
165
- };
166
- if (json.type === "vector" || json.type === "list") {
167
- payload.element_type = toolkitDataTypeJson(DataType.fromJson(json.element_type));
168
- }
169
- else if (json.type === "struct") {
170
- const fields = json.fields;
171
- if (!Array.isArray(fields)) {
172
- throw new RoomServerException("unexpected return type from database.inspect");
173
- }
174
- payload.fields = fields.map((field) => {
175
- if (!isRecord(field) || typeof field.name !== "string" || !isRecord(field.data_type)) {
176
- throw new RoomServerException("unexpected return type from database.inspect");
177
- }
178
- return {
179
- name: field.name,
180
- data_type: toolkitDataTypeJson(DataType.fromJson(field.data_type)),
181
- };
182
- });
183
- }
184
- if (json.type === "vector") {
185
- payload.size = json.size;
186
- }
187
- return payload;
188
- }
189
- function schemaEntries(schema) {
190
- if (schema == null) {
191
- return null;
192
- }
193
- return Object.entries(schema).map(([name, dataType]) => ({
194
- name,
195
- data_type: toolkitDataTypeJson(dataType),
196
- }));
197
- }
198
- function publicDataTypeJson(value) {
199
- if (!isRecord(value)) {
200
- throw new RoomServerException("unexpected return type from database.inspect");
201
- }
202
- const type = value.type;
203
- if (typeof type !== "string") {
204
- throw new RoomServerException("unexpected return type from database.inspect");
205
- }
206
- const metadataList = value.metadata;
207
- let metadata;
208
- if (metadataList != null) {
209
- if (!Array.isArray(metadataList)) {
210
- throw new RoomServerException("unexpected return type from database.inspect");
211
- }
212
- metadata = {};
213
- for (const entry of metadataList) {
214
- if (!isRecord(entry) || typeof entry.key !== "string" || typeof entry.value !== "string") {
215
- throw new RoomServerException("unexpected return type from database.inspect");
216
- }
217
- metadata[entry.key] = entry.value;
218
- }
219
- }
220
- const payload = {
221
- type,
222
- nullable: value.nullable,
223
- metadata,
224
- };
225
- if (type === "vector") {
226
- payload.size = value.size;
227
- payload.element_type = publicDataTypeJson(value.element_type);
228
- }
229
- else if (type === "list") {
230
- payload.element_type = publicDataTypeJson(value.element_type);
231
- }
232
- else if (type === "struct") {
233
- const rawFields = value.fields;
234
- if (!Array.isArray(rawFields)) {
235
- throw new RoomServerException("unexpected return type from database.inspect");
236
- }
237
- payload.fields = Object.fromEntries(rawFields.map((field) => {
238
- if (!isRecord(field) || typeof field.name !== "string") {
239
- throw new RoomServerException("unexpected return type from database.inspect");
240
- }
241
- return [field.name, publicDataTypeJson(field.data_type)];
242
- }));
243
- }
244
- return payload;
245
- }
246
160
  function encodeRecordValue(value) {
247
- if (value instanceof DatabaseValueEncoder) {
248
- return value.encodeDatabaseValue();
161
+ if (value instanceof DatasetValueEncoder) {
162
+ return value.encodeDatasetValue();
249
163
  }
250
- if (value instanceof DatabaseUuid) {
164
+ if (value instanceof DatasetUuid) {
251
165
  return {
252
166
  uuid: value.toString(),
253
167
  };
@@ -268,90 +182,90 @@ function encodeRecordValue(value) {
268
182
  };
269
183
  }
270
184
  if (isRecord(value)) {
271
- throw new RoomServerException("database object values must use DatabaseStruct or DatabaseJson");
185
+ throw new RoomServerException("dataset object values must use DatasetStruct or DatasetJson");
272
186
  }
273
187
  return value;
274
188
  }
275
- function databaseSqlLiteral(value) {
276
- if (value instanceof DatabaseUuid) {
189
+ function datasetSqlLiteral(value) {
190
+ if (value instanceof DatasetUuid) {
277
191
  return `X'${normalizeUuidHex(value.toString())}'`;
278
192
  }
279
- if (value instanceof DatabaseDate) {
193
+ if (value instanceof DatasetDate) {
280
194
  return JSON.stringify(value.toString());
281
195
  }
282
196
  if (value instanceof Date) {
283
197
  return JSON.stringify(value.toISOString().replace("+00:00", "Z"));
284
198
  }
285
- if (value instanceof DatabaseJson) {
199
+ if (value instanceof DatasetJson) {
286
200
  return JSON.stringify(JSON.stringify(value.toJson()));
287
201
  }
288
- if (value instanceof DatabaseStruct) {
289
- const fields = Object.entries(value.fields).map(([key, fieldValue]) => (`${JSON.stringify(key)}, ${databaseSqlLiteral(fieldValue)}`));
202
+ if (value instanceof DatasetStruct) {
203
+ const fields = Object.entries(value.fields).map(([key, fieldValue]) => (`${JSON.stringify(key)}, ${datasetSqlLiteral(fieldValue)}`));
290
204
  return `named_struct(${fields.join(", ")})`;
291
205
  }
292
206
  return JSON.stringify(encodeRecordValue(value));
293
207
  }
294
208
  function decodeRecordValue(value) {
295
209
  if (Array.isArray(value)) {
296
- throw new RoomServerException("database list values must use a {'list': [...]} wrapper");
210
+ throw new RoomServerException("dataset list values must use a {'list': [...]} wrapper");
297
211
  }
298
212
  if (!isRecord(value)) {
299
213
  return value;
300
214
  }
301
215
  const entries = Object.entries(value);
302
216
  if (entries.length !== 1) {
303
- throw new RoomServerException("database object values must use a single-key type wrapper");
217
+ throw new RoomServerException("dataset object values must use a single-key type wrapper");
304
218
  }
305
219
  const [wrapper, payload] = entries[0];
306
220
  switch (wrapper) {
307
221
  case "binary":
308
222
  if (typeof payload !== "string") {
309
- throw new RoomServerException("database binary values must be base64 strings");
223
+ throw new RoomServerException("dataset binary values must be base64 strings");
310
224
  }
311
225
  return base64ToBytes(payload);
312
226
  case "uuid":
313
227
  if (typeof payload !== "string") {
314
- throw new RoomServerException("database uuid values must be strings");
228
+ throw new RoomServerException("dataset uuid values must be strings");
315
229
  }
316
- return new DatabaseUuid(payload);
230
+ return new DatasetUuid(payload);
317
231
  case "expression":
318
232
  if (typeof payload !== "string") {
319
- throw new RoomServerException("database expression values must be strings");
233
+ throw new RoomServerException("dataset expression values must be strings");
320
234
  }
321
- return new DatabaseExpression(payload);
235
+ return new DatasetExpression(payload);
322
236
  case "date":
323
237
  if (typeof payload !== "string") {
324
- throw new RoomServerException("database date values must be strings");
238
+ throw new RoomServerException("dataset date values must be strings");
325
239
  }
326
- return new DatabaseDate(payload);
240
+ return new DatasetDate(payload);
327
241
  case "timestamp":
328
242
  if (typeof payload !== "string") {
329
- throw new RoomServerException("database timestamp values must be strings");
243
+ throw new RoomServerException("dataset timestamp values must be strings");
330
244
  }
331
245
  {
332
246
  const parsed = new Date(payload);
333
247
  if (Number.isNaN(parsed.getTime())) {
334
- throw new RoomServerException("database timestamp value is not valid");
248
+ throw new RoomServerException("dataset timestamp value is not valid");
335
249
  }
336
250
  return parsed;
337
251
  }
338
252
  case "list":
339
253
  if (!Array.isArray(payload)) {
340
- throw new RoomServerException("database list values must be arrays");
254
+ throw new RoomServerException("dataset list values must be arrays");
341
255
  }
342
256
  return payload.map((item) => decodeRecordValue(item));
343
257
  case "struct":
344
258
  if (!isRecord(payload)) {
345
- throw new RoomServerException("database struct values must be objects");
259
+ throw new RoomServerException("dataset struct values must be objects");
346
260
  }
347
- return new DatabaseStruct(Object.fromEntries(Object.entries(payload).map(([key, item]) => [key, decodeRecordValue(item)])));
261
+ return new DatasetStruct(Object.fromEntries(Object.entries(payload).map(([key, item]) => [key, decodeRecordValue(item)])));
348
262
  case "json":
349
- return new DatabaseJson(normalizeDatabaseJsonValue(payload));
263
+ return new DatasetJson(normalizeDatasetJsonValue(payload));
350
264
  default:
351
- throw new RoomServerException(`unsupported database value wrapper '${wrapper}'`);
265
+ throw new RoomServerException(`unsupported dataset value wrapper '${wrapper}'`);
352
266
  }
353
267
  }
354
- function encodeDatabaseRecord(record) {
268
+ function encodeDatasetRecord(record) {
355
269
  return Object.fromEntries(Object.entries(record).map(([key, value]) => [key, encodeRecordValue(value)]));
356
270
  }
357
271
  function rowsChunk(records) {
@@ -367,21 +281,21 @@ function rowsChunk(records) {
367
281
  }
368
282
  function recordsFromRowsChunk(payload, operation) {
369
283
  if (!isRecord(payload) || payload.kind !== "rows" || !Array.isArray(payload.rows)) {
370
- throw new RoomServerException(`unexpected return type from database.${operation}`);
284
+ throw new RoomServerException(`unexpected return type from datasets.${operation}`);
371
285
  }
372
286
  return payload.rows.map((row) => {
373
287
  if (!isRecord(row) || !Array.isArray(row.columns)) {
374
- throw new RoomServerException(`unexpected return type from database.${operation}`);
288
+ throw new RoomServerException(`unexpected return type from datasets.${operation}`);
375
289
  }
376
290
  return Object.fromEntries(row.columns.map((column) => {
377
291
  if (!isRecord(column) || typeof column.name !== "string") {
378
- throw new RoomServerException(`unexpected return type from database.${operation}`);
292
+ throw new RoomServerException(`unexpected return type from datasets.${operation}`);
379
293
  }
380
294
  try {
381
295
  return [column.name, decodeRecordValue(column.value)];
382
296
  }
383
297
  catch {
384
- throw new RoomServerException(`unexpected return type from database.${operation}`);
298
+ throw new RoomServerException(`unexpected return type from datasets.${operation}`);
385
299
  }
386
300
  }));
387
301
  });
@@ -410,7 +324,7 @@ async function* toAsyncIterable(chunks) {
410
324
  function buildWhereClause(where) {
411
325
  if (where != null && typeof where === "object" && !Array.isArray(where)) {
412
326
  return Object.entries(where)
413
- .map(([key, value]) => `${key} = ${databaseSqlLiteral(value)}`)
327
+ .map(([key, value]) => `${key} = ${datasetSqlLiteral(value)}`)
414
328
  .join(" AND ");
415
329
  }
416
330
  if (typeof where === "string") {
@@ -423,36 +337,64 @@ function normalizeTableRefs(tables) {
423
337
  }
424
338
  function tableIndexFromJson(value) {
425
339
  if (!isRecord(value) || typeof value.name !== "string" || typeof value.type !== "string" || !Array.isArray(value.columns)) {
426
- throw new RoomServerException("unexpected return type from database.list_indexes");
340
+ throw new RoomServerException("unexpected return type from datasets.list_indexes");
427
341
  }
428
342
  return {
429
343
  name: value.name,
430
344
  type: value.type,
431
345
  columns: value.columns.map((column) => {
432
346
  if (typeof column !== "string") {
433
- throw new RoomServerException("unexpected return type from database.list_indexes");
347
+ throw new RoomServerException("unexpected return type from datasets.list_indexes");
434
348
  }
435
349
  return column;
436
350
  }),
351
+ fields: Array.isArray(value.fields) ? value.fields.map((field) => Number(field)) : [],
352
+ typeUrl: typeof value.type_url === "string" ? value.type_url : null,
353
+ numRowsIndexed: typeof value.num_rows_indexed === "number" ? value.num_rows_indexed : null,
354
+ numSegments: typeof value.num_segments === "number" ? value.num_segments : null,
355
+ totalSizeBytes: typeof value.total_size_bytes === "number" ? value.total_size_bytes : null,
356
+ details: typeof value.details_json === "string" ? JSON.parse(value.details_json) : isRecord(value.details) ? value.details : {},
357
+ statistics: typeof value.statistics_json === "string" ? JSON.parse(value.statistics_json) : isRecord(value.statistics) ? value.statistics : {},
437
358
  };
438
359
  }
360
+ function optimizeResultFromJson(value) {
361
+ if (!isRecord(value)) {
362
+ throw new RoomServerException("unexpected return type from datasets.optimize");
363
+ }
364
+ return {
365
+ compaction: typeof value.compaction_json === "string" ? JSON.parse(value.compaction_json) : isRecord(value.compaction) ? value.compaction : null,
366
+ optimizedIndices: value.optimized_indices === true,
367
+ cleanup: typeof value.cleanup_json === "string" ? JSON.parse(value.cleanup_json) : isRecord(value.cleanup) ? value.cleanup : null,
368
+ };
369
+ }
370
+ function tableStatsFromJson(value) {
371
+ if (!isRecord(value)) {
372
+ throw new RoomServerException("unexpected return type from datasets.stats");
373
+ }
374
+ const dataset = typeof value.dataset_json === "string" ? JSON.parse(value.dataset_json) : value.dataset;
375
+ const data = typeof value.data_json === "string" ? JSON.parse(value.data_json) : value.data;
376
+ if (!isRecord(dataset) || !isRecord(data)) {
377
+ throw new RoomServerException("unexpected return type from datasets.stats");
378
+ }
379
+ return { dataset, data };
380
+ }
439
381
  function tableVersionFromJson(value) {
440
382
  if (!isRecord(value) || typeof value.metadata_json !== "string" || typeof value.timestamp !== "string" || typeof value.version !== "number") {
441
- throw new RoomServerException("unexpected return type from database.list_versions");
383
+ throw new RoomServerException("unexpected return type from datasets.list_versions");
442
384
  }
443
385
  const timestamp = new Date(value.timestamp);
444
386
  if (Number.isNaN(timestamp.getTime())) {
445
- throw new RoomServerException("unexpected return type from database.list_versions");
387
+ throw new RoomServerException("unexpected return type from datasets.list_versions");
446
388
  }
447
389
  let metadata;
448
390
  try {
449
391
  metadata = JSON.parse(value.metadata_json);
450
392
  }
451
393
  catch (_) {
452
- throw new RoomServerException("unexpected return type from database.list_versions");
394
+ throw new RoomServerException("unexpected return type from datasets.list_versions");
453
395
  }
454
396
  if (!isRecord(metadata)) {
455
- throw new RoomServerException("unexpected return type from database.list_versions");
397
+ throw new RoomServerException("unexpected return type from datasets.list_versions");
456
398
  }
457
399
  return {
458
400
  version: value.version,
@@ -462,27 +404,27 @@ function tableVersionFromJson(value) {
462
404
  }
463
405
  function tableBranchFromJson(value) {
464
406
  if (!isRecord(value) || typeof value.name !== "string") {
465
- throw new RoomServerException("unexpected return type from database.list_branches");
407
+ throw new RoomServerException("unexpected return type from datasets.list_branches");
466
408
  }
467
409
  if (value.parent_branch != null && typeof value.parent_branch !== "string") {
468
- throw new RoomServerException("unexpected return type from database.list_branches");
410
+ throw new RoomServerException("unexpected return type from datasets.list_branches");
469
411
  }
470
412
  if (value.parent_version != null
471
413
  && (typeof value.parent_version !== "number" || !Number.isInteger(value.parent_version))) {
472
- throw new RoomServerException("unexpected return type from database.list_branches");
414
+ throw new RoomServerException("unexpected return type from datasets.list_branches");
473
415
  }
474
416
  if (value.manifest_size != null
475
417
  && (typeof value.manifest_size !== "number" || !Number.isInteger(value.manifest_size))) {
476
- throw new RoomServerException("unexpected return type from database.list_branches");
418
+ throw new RoomServerException("unexpected return type from datasets.list_branches");
477
419
  }
478
420
  let createdAt = null;
479
421
  if (value.created_at != null) {
480
422
  if (typeof value.created_at !== "string") {
481
- throw new RoomServerException("unexpected return type from database.list_branches");
423
+ throw new RoomServerException("unexpected return type from datasets.list_branches");
482
424
  }
483
425
  createdAt = new Date(value.created_at);
484
426
  if (Number.isNaN(createdAt.getTime())) {
485
- throw new RoomServerException("unexpected return type from database.list_branches");
427
+ throw new RoomServerException("unexpected return type from datasets.list_branches");
486
428
  }
487
429
  }
488
430
  return {
@@ -493,7 +435,7 @@ function tableBranchFromJson(value) {
493
435
  manifestSize: value.manifest_size ?? null,
494
436
  };
495
437
  }
496
- class DatabaseWriteInputStream {
438
+ class DatasetWriteInputStream {
497
439
  constructor(start, chunks) {
498
440
  this.start = start;
499
441
  this.pulls = [];
@@ -553,7 +495,98 @@ class DatabaseWriteInputStream {
553
495
  }
554
496
  }
555
497
  }
556
- class DatabaseReadInputStream {
498
+ async function* toAsyncArrowIterable(chunks) {
499
+ if (Symbol.asyncIterator in chunks) {
500
+ for await (const chunk of chunks) {
501
+ yield chunk;
502
+ }
503
+ return;
504
+ }
505
+ for (const chunk of chunks) {
506
+ yield chunk;
507
+ }
508
+ }
509
+ function schemaToIPC(schema) {
510
+ return tableToIPC(new Table(schema, []), "stream");
511
+ }
512
+ function tableFromIPCBytes(data) {
513
+ const table = tableFromIPC(data);
514
+ if (table instanceof Promise) {
515
+ throw new RoomServerException("unexpected async Arrow IPC result");
516
+ }
517
+ return table;
518
+ }
519
+ function schemaFromIPCBytes(data) {
520
+ return tableFromIPCBytes(data).schema;
521
+ }
522
+ class DatasetArrowWriteInputStream {
523
+ constructor(start, chunks, schema) {
524
+ this.start = start;
525
+ this.schema = schema;
526
+ this.pulls = [];
527
+ this.closed = false;
528
+ this.source = toAsyncArrowIterable(chunks)[Symbol.asyncIterator]();
529
+ }
530
+ requestNext() {
531
+ if (this.closed) {
532
+ return;
533
+ }
534
+ const waiter = this.pulls.shift();
535
+ if (waiter) {
536
+ waiter();
537
+ return;
538
+ }
539
+ this.pulls.push(() => undefined);
540
+ }
541
+ close() {
542
+ if (this.closed) {
543
+ return;
544
+ }
545
+ this.closed = true;
546
+ while (this.pulls.length > 0) {
547
+ const waiter = this.pulls.shift();
548
+ waiter?.();
549
+ }
550
+ void this.source.return?.();
551
+ }
552
+ async waitForPull() {
553
+ if (this.closed) {
554
+ return;
555
+ }
556
+ const waiter = this.pulls.shift();
557
+ if (waiter) {
558
+ waiter();
559
+ return;
560
+ }
561
+ await new Promise((resolve) => {
562
+ this.pulls.push(resolve);
563
+ });
564
+ }
565
+ async *stream() {
566
+ yield new BinaryContent({
567
+ data: this.schema == null ? new Uint8Array() : schemaToIPC(this.schema),
568
+ headers: this.start,
569
+ });
570
+ while (!this.closed) {
571
+ await this.waitForPull();
572
+ if (this.closed) {
573
+ return;
574
+ }
575
+ const nextChunk = await this.source.next();
576
+ if (nextChunk.done) {
577
+ return;
578
+ }
579
+ if (nextChunk.value.numRows === 0) {
580
+ continue;
581
+ }
582
+ yield new BinaryContent({
583
+ data: tableToIPC(nextChunk.value, "stream"),
584
+ headers: { kind: "data", content_type: ARROW_IPC_STREAM_MIME_TYPE },
585
+ });
586
+ }
587
+ }
588
+ }
589
+ class DatasetReadInputStream {
557
590
  constructor(start) {
558
591
  this.start = start;
559
592
  this.pulls = [];
@@ -604,15 +637,66 @@ class DatabaseReadInputStream {
604
637
  }
605
638
  }
606
639
  }
607
- export class DatabaseClient {
640
+ class DatasetArrowReadInputStream {
641
+ constructor(start) {
642
+ this.start = start;
643
+ this.pulls = [];
644
+ this.closed = false;
645
+ }
646
+ requestNext() {
647
+ if (this.closed) {
648
+ return;
649
+ }
650
+ const waiter = this.pulls.shift();
651
+ if (waiter) {
652
+ waiter();
653
+ return;
654
+ }
655
+ this.pulls.push(() => undefined);
656
+ }
657
+ close() {
658
+ if (this.closed) {
659
+ return;
660
+ }
661
+ this.closed = true;
662
+ while (this.pulls.length > 0) {
663
+ const waiter = this.pulls.shift();
664
+ waiter?.();
665
+ }
666
+ }
667
+ async waitForPull() {
668
+ if (this.closed) {
669
+ return;
670
+ }
671
+ const waiter = this.pulls.shift();
672
+ if (waiter) {
673
+ waiter();
674
+ return;
675
+ }
676
+ await new Promise((resolve) => {
677
+ this.pulls.push(resolve);
678
+ });
679
+ }
680
+ async *stream() {
681
+ yield new BinaryContent({ data: new Uint8Array(), headers: this.start });
682
+ while (!this.closed) {
683
+ await this.waitForPull();
684
+ if (this.closed) {
685
+ return;
686
+ }
687
+ yield new BinaryContent({ data: new Uint8Array(), headers: { kind: "pull" } });
688
+ }
689
+ }
690
+ }
691
+ export class DatasetsClient {
608
692
  constructor({ room }) {
609
693
  this.room = room;
610
694
  }
611
695
  _unexpectedResponseError(operation) {
612
- return new RoomServerException(`unexpected return type from database.${operation}`);
696
+ return new RoomServerException(`unexpected return type from datasets.${operation}`);
613
697
  }
614
698
  async invoke(operation, input) {
615
- const response = await this.room.invoke({ toolkit: "database", tool: operation, input });
699
+ const response = await this.room.invoke({ toolkit: "dataset", tool: operation, input });
616
700
  if (response instanceof JsonContent) {
617
701
  return response;
618
702
  }
@@ -621,8 +705,11 @@ export class DatabaseClient {
621
705
  }
622
706
  return null;
623
707
  }
708
+ async invokeContent(operation, input) {
709
+ return await this.room.invoke({ toolkit: "dataset", tool: operation, input });
710
+ }
624
711
  async invokeStream(operation, input) {
625
- return await this.room.invokeStream({ toolkit: "database", tool: operation, input });
712
+ return await this.room.invokeStream({ toolkit: "dataset", tool: operation, input });
626
713
  }
627
714
  async drainWriteStream(operation, input) {
628
715
  const response = await this.invokeStream(operation, input.stream());
@@ -637,6 +724,13 @@ export class DatabaseClient {
637
724
  }
638
725
  throw this._unexpectedResponseError(operation);
639
726
  }
727
+ if (chunk instanceof BinaryContent) {
728
+ if (chunk.headers.kind !== "pull") {
729
+ throw this._unexpectedResponseError(operation);
730
+ }
731
+ input.requestNext();
732
+ continue;
733
+ }
640
734
  if (!(chunk instanceof JsonContent) || chunk.json.kind !== "pull") {
641
735
  throw this._unexpectedResponseError(operation);
642
736
  }
@@ -648,7 +742,7 @@ export class DatabaseClient {
648
742
  }
649
743
  }
650
744
  async *streamRows(operation, start) {
651
- const input = new DatabaseReadInputStream(start);
745
+ const input = new DatasetReadInputStream(start);
652
746
  const response = await this.invokeStream(operation, input.stream());
653
747
  input.requestNext();
654
748
  try {
@@ -673,6 +767,32 @@ export class DatabaseClient {
673
767
  input.close();
674
768
  }
675
769
  }
770
+ async *streamArrow(operation, start) {
771
+ const input = new DatasetArrowReadInputStream(start);
772
+ const response = await this.invokeStream(operation, input.stream());
773
+ input.requestNext();
774
+ try {
775
+ for await (const chunk of response) {
776
+ if (chunk instanceof ErrorContent) {
777
+ throw new RoomServerException(chunk.text, chunk.code);
778
+ }
779
+ if (chunk instanceof ControlContent) {
780
+ if (chunk.method === "close") {
781
+ return;
782
+ }
783
+ throw this._unexpectedResponseError(operation);
784
+ }
785
+ if (!(chunk instanceof BinaryContent) || chunk.headers.kind !== "data") {
786
+ throw this._unexpectedResponseError(operation);
787
+ }
788
+ yield tableFromIPCBytes(chunk.data);
789
+ input.requestNext();
790
+ }
791
+ }
792
+ finally {
793
+ input.close();
794
+ }
795
+ }
676
796
  async listTables({ namespace, branch } = {}) {
677
797
  const response = await this.invoke("list_tables", {
678
798
  namespace: namespace ?? null,
@@ -684,22 +804,21 @@ export class DatabaseClient {
684
804
  return Array.isArray(response.json.tables) ? response.json.tables : [];
685
805
  }
686
806
  async createTable({ name, data, schema, mode = "create", namespace, branch, metadata, }) {
687
- const input = new DatabaseWriteInputStream({
807
+ const input = new DatasetArrowWriteInputStream({
688
808
  kind: "start",
689
809
  name,
690
- fields: schemaEntries(schema),
691
810
  mode,
692
811
  namespace: namespace ?? null,
693
812
  branch: branch ?? null,
694
813
  metadata: metadataEntries(metadata),
695
- }, data ?? []);
814
+ }, data ?? [], schema);
696
815
  await this.drainWriteStream("create_table", input);
697
816
  }
698
817
  async createTableWithSchema({ name, schema, data, mode = "create", namespace, branch, metadata }) {
699
818
  return this.createTable({
700
819
  name,
701
820
  schema,
702
- data: data == null ? undefined : rowChunkList(data),
821
+ data: data == null ? undefined : data instanceof Table ? [data] : data,
703
822
  mode,
704
823
  namespace,
705
824
  branch,
@@ -709,7 +828,7 @@ export class DatabaseClient {
709
828
  async createTableFromData({ name, data, mode = "create", namespace, branch, metadata }) {
710
829
  return this.createTable({
711
830
  name,
712
- data: data == null ? undefined : rowChunkList(data),
831
+ data: data == null ? undefined : data instanceof Table ? [data] : data,
713
832
  mode,
714
833
  namespace,
715
834
  branch,
@@ -719,9 +838,20 @@ export class DatabaseClient {
719
838
  async createTableFromDataStream({ name, chunks, schema, mode = "create", namespace, branch, metadata }) {
720
839
  return this.createTable({ name, data: chunks, schema, mode, namespace, branch, metadata });
721
840
  }
841
+ async createTableFromJsonData({ name, data, mode = "create", namespace, branch, metadata }) {
842
+ const input = new DatasetWriteInputStream({
843
+ kind: "start",
844
+ name,
845
+ mode,
846
+ namespace: namespace ?? null,
847
+ branch: branch ?? null,
848
+ metadata: metadataEntries(metadata),
849
+ }, data == null ? [] : rowChunkList(data));
850
+ await this.drainWriteStream("create_table", input);
851
+ }
722
852
  async dropTable({ name, ignoreMissing = false, namespace, branch }) {
723
853
  await this.room.invoke({
724
- toolkit: "database",
854
+ toolkit: "dataset",
725
855
  tool: "drop_table",
726
856
  input: {
727
857
  name,
@@ -733,20 +863,30 @@ export class DatabaseClient {
733
863
  }
734
864
  async dropIndex({ table, name, namespace, branch }) {
735
865
  await this.room.invoke({
736
- toolkit: "database",
866
+ toolkit: "dataset",
737
867
  tool: "drop_index",
738
868
  input: { table, name, namespace: namespace ?? null, branch: branch ?? null },
739
869
  });
740
870
  }
741
871
  async addColumns({ table, newColumns, namespace, branch }) {
872
+ if (newColumns instanceof Schema) {
873
+ await this.invokeContent("add_columns", new BinaryContent({
874
+ data: schemaToIPC(newColumns),
875
+ headers: {
876
+ table,
877
+ namespace: namespace ?? null,
878
+ branch: branch ?? null,
879
+ content_type: ARROW_IPC_STREAM_MIME_TYPE,
880
+ },
881
+ }));
882
+ return;
883
+ }
742
884
  await this.room.invoke({
743
- toolkit: "database",
885
+ toolkit: "dataset",
744
886
  tool: "add_columns",
745
887
  input: {
746
888
  table,
747
- columns: Object.entries(newColumns).map(([name, value]) => (value instanceof DataType
748
- ? { name, value_sql: null, data_type: toolkitDataTypeJson(value) }
749
- : { name, value_sql: value, data_type: null })),
889
+ columns: Object.entries(newColumns).map(([name, value]) => ({ name, value_sql: value })),
750
890
  namespace: namespace ?? null,
751
891
  branch: branch ?? null,
752
892
  },
@@ -754,16 +894,16 @@ export class DatabaseClient {
754
894
  }
755
895
  async dropColumns({ table, columns, namespace, branch }) {
756
896
  await this.room.invoke({
757
- toolkit: "database",
897
+ toolkit: "dataset",
758
898
  tool: "drop_columns",
759
899
  input: { table, columns, namespace: namespace ?? null, branch: branch ?? null },
760
900
  });
761
901
  }
762
902
  async insert({ table, records, namespace, branch }) {
763
- await this.insertStream({ table, chunks: rowChunkList(records), namespace, branch });
903
+ await this.insertStream({ table, chunks: [records], namespace, branch });
764
904
  }
765
905
  async insertStream({ table, chunks, namespace, branch }) {
766
- const input = new DatabaseWriteInputStream({
906
+ const input = new DatasetArrowWriteInputStream({
767
907
  kind: "start",
768
908
  table,
769
909
  namespace: namespace ?? null,
@@ -773,7 +913,7 @@ export class DatabaseClient {
773
913
  }
774
914
  async update({ table, where, values, namespace, branch }) {
775
915
  await this.room.invoke({
776
- toolkit: "database",
916
+ toolkit: "dataset",
777
917
  tool: "update",
778
918
  input: {
779
919
  table,
@@ -786,16 +926,16 @@ export class DatabaseClient {
786
926
  }
787
927
  async delete({ table, where, namespace, branch }) {
788
928
  await this.room.invoke({
789
- toolkit: "database",
929
+ toolkit: "dataset",
790
930
  tool: "delete",
791
931
  input: { table, where, namespace: namespace ?? null, branch: branch ?? null },
792
932
  });
793
933
  }
794
934
  async merge({ table, on, records, namespace, branch }) {
795
- await this.mergeStream({ table, on, chunks: rowChunkList(records), namespace, branch });
935
+ await this.mergeStream({ table, on, chunks: [records], namespace, branch });
796
936
  }
797
937
  async mergeStream({ table, on, chunks, namespace, branch }) {
798
- const input = new DatabaseWriteInputStream({
938
+ const input = new DatasetArrowWriteInputStream({
799
939
  kind: "start",
800
940
  table,
801
941
  on,
@@ -804,23 +944,125 @@ export class DatabaseClient {
804
944
  }, chunks);
805
945
  await this.drainWriteStream("merge", input);
806
946
  }
807
- async sql({ query, tables, params }) {
808
- const rows = [];
809
- for await (const chunk of this.sqlStream({ query, tables, params })) {
810
- rows.push(...chunk);
947
+ async sql({ query, tables, params, namespace, branch }) {
948
+ const results = [];
949
+ for await (const chunk of this.sqlStream({ query, tables, params, namespace, branch })) {
950
+ results.push(chunk);
951
+ }
952
+ return results;
953
+ }
954
+ async openSqlQuery({ query, tables, params, namespace, branch }) {
955
+ const response = await this.invokeContent("open_sql_query", new BinaryContent({
956
+ data: params == null ? new Uint8Array() : tableToIPC(params, "stream"),
957
+ headers: {
958
+ query,
959
+ tables: normalizeTableRefs(tables ?? []),
960
+ namespace: namespace ?? null,
961
+ branch: branch ?? null,
962
+ },
963
+ }));
964
+ if (!(response instanceof BinaryContent)) {
965
+ throw this._unexpectedResponseError("open_sql_query");
966
+ }
967
+ const queryId = response.headers.query_id;
968
+ if (typeof queryId !== "string" || queryId === "") {
969
+ throw this._unexpectedResponseError("open_sql_query");
970
+ }
971
+ return {
972
+ schema: schemaFromIPCBytes(response.data),
973
+ kind: "query",
974
+ queryId,
975
+ };
976
+ }
977
+ async executeSql({ query, tables, params, namespace, branch }) {
978
+ const response = await this.invokeContent("execute_sql", new BinaryContent({
979
+ data: params == null ? new Uint8Array() : tableToIPC(params, "stream"),
980
+ headers: {
981
+ query,
982
+ tables: normalizeTableRefs(tables ?? []),
983
+ namespace: namespace ?? null,
984
+ branch: branch ?? null,
985
+ },
986
+ }));
987
+ if (response instanceof BinaryContent) {
988
+ if (response.headers.kind !== "query") {
989
+ throw this._unexpectedResponseError("execute_sql");
990
+ }
991
+ const queryId = response.headers.query_id;
992
+ if (typeof queryId !== "string" || queryId === "") {
993
+ throw this._unexpectedResponseError("execute_sql");
994
+ }
995
+ return {
996
+ kind: "query",
997
+ schema: schemaFromIPCBytes(response.data),
998
+ queryId,
999
+ };
1000
+ }
1001
+ if (response instanceof JsonContent) {
1002
+ if (response.json.kind !== "statement"
1003
+ || typeof response.json.rows_affected !== "number"
1004
+ || !Number.isInteger(response.json.rows_affected)) {
1005
+ throw this._unexpectedResponseError("execute_sql");
1006
+ }
1007
+ return {
1008
+ kind: "statement",
1009
+ rowsAffected: response.json.rows_affected,
1010
+ };
1011
+ }
1012
+ throw this._unexpectedResponseError("execute_sql");
1013
+ }
1014
+ async *sqlStream({ query, tables, params, namespace, branch }) {
1015
+ const result = await this.executeSql({ query, tables, params, namespace, branch });
1016
+ if (result.kind === "statement") {
1017
+ throw new RoomServerException(`SQL statement did not return rows; rows_affected=${result.rowsAffected}`);
1018
+ }
1019
+ const opened = result;
1020
+ try {
1021
+ yield* this.readSqlQuery({ queryId: opened.queryId });
1022
+ }
1023
+ finally {
1024
+ await this.closeSqlQuery({ queryId: opened.queryId });
811
1025
  }
812
- return rows;
813
1026
  }
814
- async *sqlStream({ query, tables, params }) {
815
- yield* this.streamRows("sql", {
1027
+ async *readSqlQuery({ queryId }) {
1028
+ yield* this.streamArrow("read_sql_query", {
816
1029
  kind: "start",
817
- query,
818
- tables: normalizeTableRefs(tables),
819
- params_json: params == null ? null : JSON.stringify(encodeDatabaseRecord(params)),
1030
+ query_id: queryId,
820
1031
  });
821
1032
  }
1033
+ async closeSqlQuery({ queryId }) {
1034
+ const response = await this.room.invoke({ toolkit: "dataset", tool: "close_sql_query", input: { query_id: queryId } });
1035
+ if (!(response instanceof EmptyContent)) {
1036
+ throw this._unexpectedResponseError("close_sql_query");
1037
+ }
1038
+ }
1039
+ async cancelSqlQuery({ queryId }) {
1040
+ const response = await this.room.invoke({ toolkit: "dataset", tool: "cancel_sql_query", input: { query_id: queryId } });
1041
+ if (!(response instanceof JsonContent)
1042
+ || !["cancelled", "cancelling", "not_cancellable"].includes(response.json.status)) {
1043
+ throw this._unexpectedResponseError("cancel_sql_query");
1044
+ }
1045
+ return { status: response.json.status };
1046
+ }
1047
+ async executeSqlStatement({ query, tables, params, namespace, branch }) {
1048
+ const response = await this.invokeContent("execute_sql_statement", new BinaryContent({
1049
+ data: params == null ? new Uint8Array() : tableToIPC(params, "stream"),
1050
+ headers: {
1051
+ query,
1052
+ tables: normalizeTableRefs(tables ?? []),
1053
+ namespace: namespace ?? null,
1054
+ branch: branch ?? null,
1055
+ },
1056
+ }));
1057
+ if (!(response instanceof JsonContent)
1058
+ || typeof response.json.rows_affected !== "number"
1059
+ || !Number.isInteger(response.json.rows_affected)) {
1060
+ throw this._unexpectedResponseError("execute_sql_statement");
1061
+ }
1062
+ return response.json.rows_affected;
1063
+ }
822
1064
  async search({ table, text, vector, where, offset, limit, select, namespace, branch, version }) {
823
- const rows = [];
1065
+ const results = [];
824
1066
  for await (const chunk of this.searchStream({
825
1067
  table,
826
1068
  text,
@@ -833,12 +1075,12 @@ export class DatabaseClient {
833
1075
  branch,
834
1076
  version,
835
1077
  })) {
836
- rows.push(...chunk);
1078
+ results.push(chunk);
837
1079
  }
838
- return rows;
1080
+ return results;
839
1081
  }
840
1082
  async *searchStream({ table, text, vector, where, offset, limit, select, namespace, branch, version }) {
841
- yield* this.streamRows("search", {
1083
+ yield* this.streamArrow("search", {
842
1084
  kind: "start",
843
1085
  table,
844
1086
  text: text ?? null,
@@ -870,35 +1112,53 @@ export class DatabaseClient {
870
1112
  return response.json.count;
871
1113
  }
872
1114
  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,
1115
+ const response = await this.room.invoke({
1116
+ toolkit: "dataset",
1117
+ tool: "inspect",
1118
+ input: {
1119
+ table,
1120
+ namespace: namespace ?? null,
1121
+ branch: branch ?? null,
1122
+ version: version ?? null,
1123
+ },
878
1124
  });
879
- if (!(response instanceof JsonContent) || !Array.isArray(response.json.fields)) {
1125
+ if (!(response instanceof BinaryContent)) {
880
1126
  throw this._unexpectedResponseError("inspect");
881
1127
  }
882
- return Object.fromEntries(response.json.fields.map((field) => {
883
- if (!isRecord(field) || typeof field.name !== "string") {
884
- throw this._unexpectedResponseError("inspect");
885
- }
886
- return [field.name, DataType.fromJson(publicDataTypeJson(field.data_type))];
887
- }));
1128
+ return tableFromIPCBytes(response.data).schema;
888
1129
  }
889
1130
  async optimize(tableOrParams) {
890
1131
  const table = typeof tableOrParams === "string" ? tableOrParams : tableOrParams.table;
891
1132
  const namespace = typeof tableOrParams === "string" ? undefined : tableOrParams.namespace;
892
1133
  const branch = typeof tableOrParams === "string" ? undefined : tableOrParams.branch;
893
- await this.room.invoke({
894
- toolkit: "database",
895
- tool: "optimize",
896
- input: { table, namespace: namespace ?? null, branch: branch ?? null },
1134
+ const config = typeof tableOrParams === "string" ? undefined : tableOrParams.config;
1135
+ const response = await this.invoke("optimize", {
1136
+ table,
1137
+ namespace: namespace ?? null,
1138
+ branch: branch ?? null,
1139
+ config: config ?? null,
897
1140
  });
1141
+ if (!(response instanceof JsonContent)) {
1142
+ throw this._unexpectedResponseError("optimize");
1143
+ }
1144
+ return optimizeResultFromJson(response.json);
1145
+ }
1146
+ async stats({ table, namespace, branch, version, maxRowsPerGroup }) {
1147
+ const response = await this.invoke("stats", {
1148
+ table,
1149
+ namespace: namespace ?? null,
1150
+ branch: branch ?? null,
1151
+ version: version ?? null,
1152
+ max_rows_per_group: maxRowsPerGroup ?? null,
1153
+ });
1154
+ if (!(response instanceof JsonContent)) {
1155
+ throw this._unexpectedResponseError("stats");
1156
+ }
1157
+ return tableStatsFromJson(response.json);
898
1158
  }
899
1159
  async restore({ table, version, namespace, branch }) {
900
1160
  await this.room.invoke({
901
- toolkit: "database",
1161
+ toolkit: "dataset",
902
1162
  tool: "restore",
903
1163
  input: { table, version, namespace: namespace ?? null, branch: branch ?? null },
904
1164
  });
@@ -914,25 +1174,11 @@ export class DatabaseClient {
914
1174
  }
915
1175
  return response.json.versions.map((version) => tableVersionFromJson(version));
916
1176
  }
917
- async createVectorIndex({ table, column, replace = false, namespace, branch }) {
918
- await this.room.invoke({
919
- toolkit: "database",
920
- tool: "create_vector_index",
921
- input: { table, column, replace, namespace: namespace ?? null, branch: branch ?? null },
922
- });
923
- }
924
- async createScalarIndex({ table, column, replace = false, namespace, branch }) {
925
- await this.room.invoke({
926
- toolkit: "database",
927
- tool: "create_scalar_index",
928
- input: { table, column, replace, namespace: namespace ?? null, branch: branch ?? null },
929
- });
930
- }
931
- async createFullTextSearchIndex({ table, column, replace = false, namespace, branch }) {
1177
+ async createIndex({ table, config, namespace, branch }) {
932
1178
  await this.room.invoke({
933
- toolkit: "database",
934
- tool: "create_full_text_search_index",
935
- input: { table, column, replace, namespace: namespace ?? null, branch: branch ?? null },
1179
+ toolkit: "dataset",
1180
+ tool: "create_index",
1181
+ input: { table, config, namespace: namespace ?? null, branch: branch ?? null },
936
1182
  });
937
1183
  }
938
1184
  async listIndexes({ table, namespace, branch, version }) {
@@ -958,7 +1204,7 @@ export class DatabaseClient {
958
1204
  }
959
1205
  async createBranch({ branch, fromBranch, namespace }) {
960
1206
  await this.room.invoke({
961
- toolkit: "database",
1207
+ toolkit: "dataset",
962
1208
  tool: "create_branch",
963
1209
  input: {
964
1210
  branch,
@@ -969,7 +1215,7 @@ export class DatabaseClient {
969
1215
  }
970
1216
  async deleteBranch({ branch, namespace }) {
971
1217
  await this.room.invoke({
972
- toolkit: "database",
1218
+ toolkit: "dataset",
973
1219
  tool: "delete_branch",
974
1220
  input: { branch, namespace: namespace ?? null },
975
1221
  });