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