@meshagent/meshagent 0.39.8 → 0.40.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 +8 -0
- package/dist/browser/containers-client.d.ts +9 -1
- package/dist/browser/containers-client.js +10 -1
- package/dist/browser/datasets-client.d.ts +19 -0
- package/dist/browser/datasets-client.js +79 -0
- package/dist/browser/protocol.js +3 -1
- package/dist/esm/containers-client.d.ts +9 -1
- package/dist/esm/containers-client.js +10 -1
- package/dist/esm/datasets-client.d.ts +19 -0
- package/dist/esm/datasets-client.js +79 -0
- package/dist/esm/protocol.js +3 -1
- package/dist/node/containers-client.d.ts +9 -1
- package/dist/node/containers-client.js +10 -1
- package/dist/node/datasets-client.d.ts +19 -0
- package/dist/node/datasets-client.js +79 -0
- package/dist/node/protocol.js +3 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [0.40.0]
|
|
2
|
+
- Enabled websocket compression for Node protocol connections while preserving the browser path.
|
|
3
|
+
- Aligned the JS and TS protocol surface with realtime model selection and output-modality negotiation.
|
|
4
|
+
- Refreshed the generated Node entrypoint to match the updated realtime protocol flow.
|
|
5
|
+
|
|
6
|
+
## [0.39.9]
|
|
7
|
+
- Added streaming `watchTable` support to the TypeScript DatasetsClient to receive dataset table change events with versioning metadata.
|
|
8
|
+
|
|
1
9
|
## [0.39.8]
|
|
2
10
|
- TypeScript API: `RoomContainer` now includes a required `ports: number[]` field (and validation) in container listings
|
|
3
11
|
- TypeScript API: `ContainerSpec` now supports optional fields `private`, `on_demand`, and `writable_root_fs`
|
|
@@ -62,7 +62,14 @@ export interface RoomContainer {
|
|
|
62
62
|
private: boolean;
|
|
63
63
|
serviceId?: string;
|
|
64
64
|
}
|
|
65
|
+
export interface LogProgress {
|
|
66
|
+
layer?: string | null;
|
|
67
|
+
message: string;
|
|
68
|
+
current?: number | null;
|
|
69
|
+
total?: number | null;
|
|
70
|
+
}
|
|
65
71
|
export interface ContainerLogsSession {
|
|
72
|
+
progress: AsyncIterable<LogProgress>;
|
|
66
73
|
stream: AsyncIterable<string>;
|
|
67
74
|
result: Promise<void>;
|
|
68
75
|
cancel(): Promise<void>;
|
|
@@ -167,7 +174,8 @@ export declare class ContainersClient {
|
|
|
167
174
|
private?: boolean;
|
|
168
175
|
}): Promise<string>;
|
|
169
176
|
build(params: {
|
|
170
|
-
|
|
177
|
+
tags?: string[];
|
|
178
|
+
tag?: string;
|
|
171
179
|
mountPath: string;
|
|
172
180
|
contextPath: string;
|
|
173
181
|
chunks: AsyncIterable<Uint8Array>;
|
|
@@ -251,11 +251,15 @@ function parseBuildJob(data, operation) {
|
|
|
251
251
|
};
|
|
252
252
|
}
|
|
253
253
|
async function* buildInputStream(params) {
|
|
254
|
+
const tags = params.tags ?? (params.tag === undefined ? [] : [params.tag]);
|
|
255
|
+
if (tags.length === 0) {
|
|
256
|
+
throw new room_server_client_1.RoomServerException("containers.build requires at least one tag");
|
|
257
|
+
}
|
|
254
258
|
yield new response_1.BinaryContent({
|
|
255
259
|
data: new Uint8Array(0),
|
|
256
260
|
headers: {
|
|
257
261
|
kind: "start",
|
|
258
|
-
|
|
262
|
+
tags,
|
|
259
263
|
mount_path: params.mountPath,
|
|
260
264
|
context_path: params.contextPath,
|
|
261
265
|
dockerfile_path: params.dockerfilePath ?? null,
|
|
@@ -630,6 +634,7 @@ class ContainersClient {
|
|
|
630
634
|
logs(params) {
|
|
631
635
|
const requestId = (0, uuid_1.v4)();
|
|
632
636
|
const closeInput = new completer_1.Completer();
|
|
637
|
+
const progressController = new stream_controller_1.StreamController();
|
|
633
638
|
const streamController = new stream_controller_1.StreamController();
|
|
634
639
|
const result = new completer_1.Completer();
|
|
635
640
|
let inputClosed = false;
|
|
@@ -668,6 +673,7 @@ class ContainersClient {
|
|
|
668
673
|
if (chunk instanceof response_1.ControlContent) {
|
|
669
674
|
if (chunk.method === "close") {
|
|
670
675
|
closeInputStream();
|
|
676
|
+
progressController.close();
|
|
671
677
|
streamController.close();
|
|
672
678
|
if (!result.completed) {
|
|
673
679
|
result.complete();
|
|
@@ -689,6 +695,7 @@ class ContainersClient {
|
|
|
689
695
|
streamController.add(decodeUtf8(chunk.data, "logs"));
|
|
690
696
|
}
|
|
691
697
|
closeInputStream();
|
|
698
|
+
progressController.close();
|
|
692
699
|
streamController.close();
|
|
693
700
|
if (!result.completed) {
|
|
694
701
|
result.complete();
|
|
@@ -696,6 +703,7 @@ class ContainersClient {
|
|
|
696
703
|
})
|
|
697
704
|
.catch((error) => {
|
|
698
705
|
closeInputStream();
|
|
706
|
+
progressController.close();
|
|
699
707
|
streamController.close();
|
|
700
708
|
if (!result.completed) {
|
|
701
709
|
result.completeError(error);
|
|
@@ -723,6 +731,7 @@ class ContainersClient {
|
|
|
723
731
|
},
|
|
724
732
|
};
|
|
725
733
|
return {
|
|
734
|
+
progress: progressController.stream,
|
|
726
735
|
stream: outputStream,
|
|
727
736
|
result: result.fut,
|
|
728
737
|
cancel: async () => {
|
|
@@ -123,6 +123,19 @@ export type DatasetSqlCancelStatus = "cancelled" | "cancelling" | "not_cancellab
|
|
|
123
123
|
export interface DatasetSqlCancelResult {
|
|
124
124
|
status: DatasetSqlCancelStatus;
|
|
125
125
|
}
|
|
126
|
+
export interface DatasetWatchEvent {
|
|
127
|
+
kind: string;
|
|
128
|
+
phase?: string;
|
|
129
|
+
table?: Table;
|
|
130
|
+
version?: number;
|
|
131
|
+
changeType?: string;
|
|
132
|
+
beginVersion?: number;
|
|
133
|
+
endVersion?: number;
|
|
134
|
+
watchEvent?: string;
|
|
135
|
+
transactions?: Record<string, unknown>[];
|
|
136
|
+
deletePredicate?: string;
|
|
137
|
+
transaction?: Record<string, unknown>;
|
|
138
|
+
}
|
|
126
139
|
export declare abstract class DatasetValueEncoder {
|
|
127
140
|
abstract encodeDatasetValue(): unknown;
|
|
128
141
|
}
|
|
@@ -368,6 +381,12 @@ export declare class DatasetsClient {
|
|
|
368
381
|
branch?: string;
|
|
369
382
|
version?: number;
|
|
370
383
|
}): AsyncIterable<Table>;
|
|
384
|
+
watchTable({ table, namespace, branch, pollIntervalSeconds }: {
|
|
385
|
+
table: string;
|
|
386
|
+
namespace?: string[];
|
|
387
|
+
branch?: string;
|
|
388
|
+
pollIntervalSeconds?: number;
|
|
389
|
+
}): AsyncIterable<DatasetWatchEvent>;
|
|
371
390
|
count({ table, text, vector, where, namespace, branch, version }: {
|
|
372
391
|
table: string;
|
|
373
392
|
text?: string;
|
|
@@ -444,6 +444,18 @@ function tableBranchFromJson(value) {
|
|
|
444
444
|
manifestSize: value.manifest_size ?? null,
|
|
445
445
|
};
|
|
446
446
|
}
|
|
447
|
+
function optionalDatasetInt(value) {
|
|
448
|
+
if (typeof value === "number" && Number.isInteger(value)) {
|
|
449
|
+
return value;
|
|
450
|
+
}
|
|
451
|
+
if (typeof value === "string" && /^-?\d+$/.test(value)) {
|
|
452
|
+
return Number.parseInt(value, 10);
|
|
453
|
+
}
|
|
454
|
+
return undefined;
|
|
455
|
+
}
|
|
456
|
+
function optionalDatasetString(value) {
|
|
457
|
+
return typeof value === "string" ? value : undefined;
|
|
458
|
+
}
|
|
447
459
|
class DatasetWriteInputStream {
|
|
448
460
|
constructor(start, chunks) {
|
|
449
461
|
this.start = start;
|
|
@@ -1130,6 +1142,73 @@ class DatasetsClient {
|
|
|
1130
1142
|
version: version ?? null,
|
|
1131
1143
|
});
|
|
1132
1144
|
}
|
|
1145
|
+
async *watchTable({ table, namespace, branch, pollIntervalSeconds = 0.5 }) {
|
|
1146
|
+
const input = new DatasetArrowReadInputStream({
|
|
1147
|
+
kind: "start",
|
|
1148
|
+
table,
|
|
1149
|
+
namespace: namespace ?? null,
|
|
1150
|
+
branch: branch ?? null,
|
|
1151
|
+
poll_interval_seconds: pollIntervalSeconds,
|
|
1152
|
+
});
|
|
1153
|
+
const response = await this.invokeStream("watch_table", input.stream());
|
|
1154
|
+
input.requestNext();
|
|
1155
|
+
try {
|
|
1156
|
+
for await (const chunk of response) {
|
|
1157
|
+
if (chunk instanceof response_1.ErrorContent) {
|
|
1158
|
+
throw new room_server_client_1.RoomServerException(chunk.text, chunk.code);
|
|
1159
|
+
}
|
|
1160
|
+
if (chunk instanceof response_1.ControlContent) {
|
|
1161
|
+
if (chunk.method === "close") {
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
throw this._unexpectedResponseError("watch_table");
|
|
1165
|
+
}
|
|
1166
|
+
if (chunk instanceof response_1.BinaryContent) {
|
|
1167
|
+
if (chunk.headers.kind !== "data") {
|
|
1168
|
+
throw this._unexpectedResponseError("watch_table");
|
|
1169
|
+
}
|
|
1170
|
+
const watchEvent = optionalDatasetString(chunk.headers.watch_event);
|
|
1171
|
+
yield {
|
|
1172
|
+
kind: watchEvent ?? "data",
|
|
1173
|
+
phase: optionalDatasetString(chunk.headers.phase),
|
|
1174
|
+
table: tableFromIPCBytes(chunk.data),
|
|
1175
|
+
version: optionalDatasetInt(chunk.headers.version),
|
|
1176
|
+
changeType: optionalDatasetString(chunk.headers.change_type),
|
|
1177
|
+
beginVersion: optionalDatasetInt(chunk.headers.begin_version),
|
|
1178
|
+
endVersion: optionalDatasetInt(chunk.headers.end_version),
|
|
1179
|
+
watchEvent,
|
|
1180
|
+
};
|
|
1181
|
+
input.requestNext();
|
|
1182
|
+
continue;
|
|
1183
|
+
}
|
|
1184
|
+
if (chunk instanceof response_1.JsonContent) {
|
|
1185
|
+
if (!isRecord(chunk.json)) {
|
|
1186
|
+
throw this._unexpectedResponseError("watch_table");
|
|
1187
|
+
}
|
|
1188
|
+
const rawTransactions = chunk.json.transactions;
|
|
1189
|
+
const rawTransaction = chunk.json.transaction;
|
|
1190
|
+
yield {
|
|
1191
|
+
kind: typeof chunk.json.kind === "string" ? chunk.json.kind : "event",
|
|
1192
|
+
phase: optionalDatasetString(chunk.json.phase),
|
|
1193
|
+
version: optionalDatasetInt(chunk.json.version),
|
|
1194
|
+
beginVersion: optionalDatasetInt(chunk.json.begin_version),
|
|
1195
|
+
endVersion: optionalDatasetInt(chunk.json.end_version),
|
|
1196
|
+
transactions: Array.isArray(rawTransactions)
|
|
1197
|
+
? rawTransactions.filter(isRecord)
|
|
1198
|
+
: undefined,
|
|
1199
|
+
deletePredicate: optionalDatasetString(chunk.json.predicate),
|
|
1200
|
+
transaction: isRecord(rawTransaction) ? rawTransaction : undefined,
|
|
1201
|
+
};
|
|
1202
|
+
input.requestNext();
|
|
1203
|
+
continue;
|
|
1204
|
+
}
|
|
1205
|
+
throw this._unexpectedResponseError("watch_table");
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
finally {
|
|
1209
|
+
input.close();
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1133
1212
|
async count({ table, text, vector, where, namespace, branch, version }) {
|
|
1134
1213
|
const response = await this.invoke("count", {
|
|
1135
1214
|
table,
|
package/dist/browser/protocol.js
CHANGED
|
@@ -158,7 +158,9 @@ class WebSocketProtocolChannel {
|
|
|
158
158
|
this._onDataReceived = onDataReceived;
|
|
159
159
|
this._doneHandler = onDone;
|
|
160
160
|
this._errorHandler = onError;
|
|
161
|
-
const socket =
|
|
161
|
+
const socket = isNodeRuntime()
|
|
162
|
+
? new isomorphic_ws_1.default(url.toString(), [], { perMessageDeflate: true })
|
|
163
|
+
: new isomorphic_ws_1.default(url.toString());
|
|
162
164
|
this.webSocket = socket;
|
|
163
165
|
if (isNodeRuntime()) {
|
|
164
166
|
socket.on("unexpected-response", this._onUnexpectedResponse);
|
|
@@ -62,7 +62,14 @@ export interface RoomContainer {
|
|
|
62
62
|
private: boolean;
|
|
63
63
|
serviceId?: string;
|
|
64
64
|
}
|
|
65
|
+
export interface LogProgress {
|
|
66
|
+
layer?: string | null;
|
|
67
|
+
message: string;
|
|
68
|
+
current?: number | null;
|
|
69
|
+
total?: number | null;
|
|
70
|
+
}
|
|
65
71
|
export interface ContainerLogsSession {
|
|
72
|
+
progress: AsyncIterable<LogProgress>;
|
|
66
73
|
stream: AsyncIterable<string>;
|
|
67
74
|
result: Promise<void>;
|
|
68
75
|
cancel(): Promise<void>;
|
|
@@ -167,7 +174,8 @@ export declare class ContainersClient {
|
|
|
167
174
|
private?: boolean;
|
|
168
175
|
}): Promise<string>;
|
|
169
176
|
build(params: {
|
|
170
|
-
|
|
177
|
+
tags?: string[];
|
|
178
|
+
tag?: string;
|
|
171
179
|
mountPath: string;
|
|
172
180
|
contextPath: string;
|
|
173
181
|
chunks: AsyncIterable<Uint8Array>;
|
|
@@ -251,11 +251,15 @@ function parseBuildJob(data, operation) {
|
|
|
251
251
|
};
|
|
252
252
|
}
|
|
253
253
|
async function* buildInputStream(params) {
|
|
254
|
+
const tags = params.tags ?? (params.tag === undefined ? [] : [params.tag]);
|
|
255
|
+
if (tags.length === 0) {
|
|
256
|
+
throw new room_server_client_1.RoomServerException("containers.build requires at least one tag");
|
|
257
|
+
}
|
|
254
258
|
yield new response_1.BinaryContent({
|
|
255
259
|
data: new Uint8Array(0),
|
|
256
260
|
headers: {
|
|
257
261
|
kind: "start",
|
|
258
|
-
|
|
262
|
+
tags,
|
|
259
263
|
mount_path: params.mountPath,
|
|
260
264
|
context_path: params.contextPath,
|
|
261
265
|
dockerfile_path: params.dockerfilePath ?? null,
|
|
@@ -630,6 +634,7 @@ class ContainersClient {
|
|
|
630
634
|
logs(params) {
|
|
631
635
|
const requestId = (0, uuid_1.v4)();
|
|
632
636
|
const closeInput = new completer_1.Completer();
|
|
637
|
+
const progressController = new stream_controller_1.StreamController();
|
|
633
638
|
const streamController = new stream_controller_1.StreamController();
|
|
634
639
|
const result = new completer_1.Completer();
|
|
635
640
|
let inputClosed = false;
|
|
@@ -668,6 +673,7 @@ class ContainersClient {
|
|
|
668
673
|
if (chunk instanceof response_1.ControlContent) {
|
|
669
674
|
if (chunk.method === "close") {
|
|
670
675
|
closeInputStream();
|
|
676
|
+
progressController.close();
|
|
671
677
|
streamController.close();
|
|
672
678
|
if (!result.completed) {
|
|
673
679
|
result.complete();
|
|
@@ -689,6 +695,7 @@ class ContainersClient {
|
|
|
689
695
|
streamController.add(decodeUtf8(chunk.data, "logs"));
|
|
690
696
|
}
|
|
691
697
|
closeInputStream();
|
|
698
|
+
progressController.close();
|
|
692
699
|
streamController.close();
|
|
693
700
|
if (!result.completed) {
|
|
694
701
|
result.complete();
|
|
@@ -696,6 +703,7 @@ class ContainersClient {
|
|
|
696
703
|
})
|
|
697
704
|
.catch((error) => {
|
|
698
705
|
closeInputStream();
|
|
706
|
+
progressController.close();
|
|
699
707
|
streamController.close();
|
|
700
708
|
if (!result.completed) {
|
|
701
709
|
result.completeError(error);
|
|
@@ -723,6 +731,7 @@ class ContainersClient {
|
|
|
723
731
|
},
|
|
724
732
|
};
|
|
725
733
|
return {
|
|
734
|
+
progress: progressController.stream,
|
|
726
735
|
stream: outputStream,
|
|
727
736
|
result: result.fut,
|
|
728
737
|
cancel: async () => {
|
|
@@ -123,6 +123,19 @@ export type DatasetSqlCancelStatus = "cancelled" | "cancelling" | "not_cancellab
|
|
|
123
123
|
export interface DatasetSqlCancelResult {
|
|
124
124
|
status: DatasetSqlCancelStatus;
|
|
125
125
|
}
|
|
126
|
+
export interface DatasetWatchEvent {
|
|
127
|
+
kind: string;
|
|
128
|
+
phase?: string;
|
|
129
|
+
table?: Table;
|
|
130
|
+
version?: number;
|
|
131
|
+
changeType?: string;
|
|
132
|
+
beginVersion?: number;
|
|
133
|
+
endVersion?: number;
|
|
134
|
+
watchEvent?: string;
|
|
135
|
+
transactions?: Record<string, unknown>[];
|
|
136
|
+
deletePredicate?: string;
|
|
137
|
+
transaction?: Record<string, unknown>;
|
|
138
|
+
}
|
|
126
139
|
export declare abstract class DatasetValueEncoder {
|
|
127
140
|
abstract encodeDatasetValue(): unknown;
|
|
128
141
|
}
|
|
@@ -368,6 +381,12 @@ export declare class DatasetsClient {
|
|
|
368
381
|
branch?: string;
|
|
369
382
|
version?: number;
|
|
370
383
|
}): AsyncIterable<Table>;
|
|
384
|
+
watchTable({ table, namespace, branch, pollIntervalSeconds }: {
|
|
385
|
+
table: string;
|
|
386
|
+
namespace?: string[];
|
|
387
|
+
branch?: string;
|
|
388
|
+
pollIntervalSeconds?: number;
|
|
389
|
+
}): AsyncIterable<DatasetWatchEvent>;
|
|
371
390
|
count({ table, text, vector, where, namespace, branch, version }: {
|
|
372
391
|
table: string;
|
|
373
392
|
text?: string;
|
|
@@ -444,6 +444,18 @@ function tableBranchFromJson(value) {
|
|
|
444
444
|
manifestSize: value.manifest_size ?? null,
|
|
445
445
|
};
|
|
446
446
|
}
|
|
447
|
+
function optionalDatasetInt(value) {
|
|
448
|
+
if (typeof value === "number" && Number.isInteger(value)) {
|
|
449
|
+
return value;
|
|
450
|
+
}
|
|
451
|
+
if (typeof value === "string" && /^-?\d+$/.test(value)) {
|
|
452
|
+
return Number.parseInt(value, 10);
|
|
453
|
+
}
|
|
454
|
+
return undefined;
|
|
455
|
+
}
|
|
456
|
+
function optionalDatasetString(value) {
|
|
457
|
+
return typeof value === "string" ? value : undefined;
|
|
458
|
+
}
|
|
447
459
|
class DatasetWriteInputStream {
|
|
448
460
|
constructor(start, chunks) {
|
|
449
461
|
this.start = start;
|
|
@@ -1130,6 +1142,73 @@ class DatasetsClient {
|
|
|
1130
1142
|
version: version ?? null,
|
|
1131
1143
|
});
|
|
1132
1144
|
}
|
|
1145
|
+
async *watchTable({ table, namespace, branch, pollIntervalSeconds = 0.5 }) {
|
|
1146
|
+
const input = new DatasetArrowReadInputStream({
|
|
1147
|
+
kind: "start",
|
|
1148
|
+
table,
|
|
1149
|
+
namespace: namespace ?? null,
|
|
1150
|
+
branch: branch ?? null,
|
|
1151
|
+
poll_interval_seconds: pollIntervalSeconds,
|
|
1152
|
+
});
|
|
1153
|
+
const response = await this.invokeStream("watch_table", input.stream());
|
|
1154
|
+
input.requestNext();
|
|
1155
|
+
try {
|
|
1156
|
+
for await (const chunk of response) {
|
|
1157
|
+
if (chunk instanceof response_1.ErrorContent) {
|
|
1158
|
+
throw new room_server_client_1.RoomServerException(chunk.text, chunk.code);
|
|
1159
|
+
}
|
|
1160
|
+
if (chunk instanceof response_1.ControlContent) {
|
|
1161
|
+
if (chunk.method === "close") {
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
throw this._unexpectedResponseError("watch_table");
|
|
1165
|
+
}
|
|
1166
|
+
if (chunk instanceof response_1.BinaryContent) {
|
|
1167
|
+
if (chunk.headers.kind !== "data") {
|
|
1168
|
+
throw this._unexpectedResponseError("watch_table");
|
|
1169
|
+
}
|
|
1170
|
+
const watchEvent = optionalDatasetString(chunk.headers.watch_event);
|
|
1171
|
+
yield {
|
|
1172
|
+
kind: watchEvent ?? "data",
|
|
1173
|
+
phase: optionalDatasetString(chunk.headers.phase),
|
|
1174
|
+
table: tableFromIPCBytes(chunk.data),
|
|
1175
|
+
version: optionalDatasetInt(chunk.headers.version),
|
|
1176
|
+
changeType: optionalDatasetString(chunk.headers.change_type),
|
|
1177
|
+
beginVersion: optionalDatasetInt(chunk.headers.begin_version),
|
|
1178
|
+
endVersion: optionalDatasetInt(chunk.headers.end_version),
|
|
1179
|
+
watchEvent,
|
|
1180
|
+
};
|
|
1181
|
+
input.requestNext();
|
|
1182
|
+
continue;
|
|
1183
|
+
}
|
|
1184
|
+
if (chunk instanceof response_1.JsonContent) {
|
|
1185
|
+
if (!isRecord(chunk.json)) {
|
|
1186
|
+
throw this._unexpectedResponseError("watch_table");
|
|
1187
|
+
}
|
|
1188
|
+
const rawTransactions = chunk.json.transactions;
|
|
1189
|
+
const rawTransaction = chunk.json.transaction;
|
|
1190
|
+
yield {
|
|
1191
|
+
kind: typeof chunk.json.kind === "string" ? chunk.json.kind : "event",
|
|
1192
|
+
phase: optionalDatasetString(chunk.json.phase),
|
|
1193
|
+
version: optionalDatasetInt(chunk.json.version),
|
|
1194
|
+
beginVersion: optionalDatasetInt(chunk.json.begin_version),
|
|
1195
|
+
endVersion: optionalDatasetInt(chunk.json.end_version),
|
|
1196
|
+
transactions: Array.isArray(rawTransactions)
|
|
1197
|
+
? rawTransactions.filter(isRecord)
|
|
1198
|
+
: undefined,
|
|
1199
|
+
deletePredicate: optionalDatasetString(chunk.json.predicate),
|
|
1200
|
+
transaction: isRecord(rawTransaction) ? rawTransaction : undefined,
|
|
1201
|
+
};
|
|
1202
|
+
input.requestNext();
|
|
1203
|
+
continue;
|
|
1204
|
+
}
|
|
1205
|
+
throw this._unexpectedResponseError("watch_table");
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
finally {
|
|
1209
|
+
input.close();
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1133
1212
|
async count({ table, text, vector, where, namespace, branch, version }) {
|
|
1134
1213
|
const response = await this.invoke("count", {
|
|
1135
1214
|
table,
|
package/dist/esm/protocol.js
CHANGED
|
@@ -158,7 +158,9 @@ class WebSocketProtocolChannel {
|
|
|
158
158
|
this._onDataReceived = onDataReceived;
|
|
159
159
|
this._doneHandler = onDone;
|
|
160
160
|
this._errorHandler = onError;
|
|
161
|
-
const socket =
|
|
161
|
+
const socket = isNodeRuntime()
|
|
162
|
+
? new isomorphic_ws_1.default(url.toString(), [], { perMessageDeflate: true })
|
|
163
|
+
: new isomorphic_ws_1.default(url.toString());
|
|
162
164
|
this.webSocket = socket;
|
|
163
165
|
if (isNodeRuntime()) {
|
|
164
166
|
socket.on("unexpected-response", this._onUnexpectedResponse);
|
|
@@ -62,7 +62,14 @@ export interface RoomContainer {
|
|
|
62
62
|
private: boolean;
|
|
63
63
|
serviceId?: string;
|
|
64
64
|
}
|
|
65
|
+
export interface LogProgress {
|
|
66
|
+
layer?: string | null;
|
|
67
|
+
message: string;
|
|
68
|
+
current?: number | null;
|
|
69
|
+
total?: number | null;
|
|
70
|
+
}
|
|
65
71
|
export interface ContainerLogsSession {
|
|
72
|
+
progress: AsyncIterable<LogProgress>;
|
|
66
73
|
stream: AsyncIterable<string>;
|
|
67
74
|
result: Promise<void>;
|
|
68
75
|
cancel(): Promise<void>;
|
|
@@ -167,7 +174,8 @@ export declare class ContainersClient {
|
|
|
167
174
|
private?: boolean;
|
|
168
175
|
}): Promise<string>;
|
|
169
176
|
build(params: {
|
|
170
|
-
|
|
177
|
+
tags?: string[];
|
|
178
|
+
tag?: string;
|
|
171
179
|
mountPath: string;
|
|
172
180
|
contextPath: string;
|
|
173
181
|
chunks: AsyncIterable<Uint8Array>;
|
|
@@ -251,11 +251,15 @@ function parseBuildJob(data, operation) {
|
|
|
251
251
|
};
|
|
252
252
|
}
|
|
253
253
|
async function* buildInputStream(params) {
|
|
254
|
+
const tags = params.tags ?? (params.tag === undefined ? [] : [params.tag]);
|
|
255
|
+
if (tags.length === 0) {
|
|
256
|
+
throw new room_server_client_1.RoomServerException("containers.build requires at least one tag");
|
|
257
|
+
}
|
|
254
258
|
yield new response_1.BinaryContent({
|
|
255
259
|
data: new Uint8Array(0),
|
|
256
260
|
headers: {
|
|
257
261
|
kind: "start",
|
|
258
|
-
|
|
262
|
+
tags,
|
|
259
263
|
mount_path: params.mountPath,
|
|
260
264
|
context_path: params.contextPath,
|
|
261
265
|
dockerfile_path: params.dockerfilePath ?? null,
|
|
@@ -630,6 +634,7 @@ class ContainersClient {
|
|
|
630
634
|
logs(params) {
|
|
631
635
|
const requestId = (0, uuid_1.v4)();
|
|
632
636
|
const closeInput = new completer_1.Completer();
|
|
637
|
+
const progressController = new stream_controller_1.StreamController();
|
|
633
638
|
const streamController = new stream_controller_1.StreamController();
|
|
634
639
|
const result = new completer_1.Completer();
|
|
635
640
|
let inputClosed = false;
|
|
@@ -668,6 +673,7 @@ class ContainersClient {
|
|
|
668
673
|
if (chunk instanceof response_1.ControlContent) {
|
|
669
674
|
if (chunk.method === "close") {
|
|
670
675
|
closeInputStream();
|
|
676
|
+
progressController.close();
|
|
671
677
|
streamController.close();
|
|
672
678
|
if (!result.completed) {
|
|
673
679
|
result.complete();
|
|
@@ -689,6 +695,7 @@ class ContainersClient {
|
|
|
689
695
|
streamController.add(decodeUtf8(chunk.data, "logs"));
|
|
690
696
|
}
|
|
691
697
|
closeInputStream();
|
|
698
|
+
progressController.close();
|
|
692
699
|
streamController.close();
|
|
693
700
|
if (!result.completed) {
|
|
694
701
|
result.complete();
|
|
@@ -696,6 +703,7 @@ class ContainersClient {
|
|
|
696
703
|
})
|
|
697
704
|
.catch((error) => {
|
|
698
705
|
closeInputStream();
|
|
706
|
+
progressController.close();
|
|
699
707
|
streamController.close();
|
|
700
708
|
if (!result.completed) {
|
|
701
709
|
result.completeError(error);
|
|
@@ -723,6 +731,7 @@ class ContainersClient {
|
|
|
723
731
|
},
|
|
724
732
|
};
|
|
725
733
|
return {
|
|
734
|
+
progress: progressController.stream,
|
|
726
735
|
stream: outputStream,
|
|
727
736
|
result: result.fut,
|
|
728
737
|
cancel: async () => {
|
|
@@ -123,6 +123,19 @@ export type DatasetSqlCancelStatus = "cancelled" | "cancelling" | "not_cancellab
|
|
|
123
123
|
export interface DatasetSqlCancelResult {
|
|
124
124
|
status: DatasetSqlCancelStatus;
|
|
125
125
|
}
|
|
126
|
+
export interface DatasetWatchEvent {
|
|
127
|
+
kind: string;
|
|
128
|
+
phase?: string;
|
|
129
|
+
table?: Table;
|
|
130
|
+
version?: number;
|
|
131
|
+
changeType?: string;
|
|
132
|
+
beginVersion?: number;
|
|
133
|
+
endVersion?: number;
|
|
134
|
+
watchEvent?: string;
|
|
135
|
+
transactions?: Record<string, unknown>[];
|
|
136
|
+
deletePredicate?: string;
|
|
137
|
+
transaction?: Record<string, unknown>;
|
|
138
|
+
}
|
|
126
139
|
export declare abstract class DatasetValueEncoder {
|
|
127
140
|
abstract encodeDatasetValue(): unknown;
|
|
128
141
|
}
|
|
@@ -368,6 +381,12 @@ export declare class DatasetsClient {
|
|
|
368
381
|
branch?: string;
|
|
369
382
|
version?: number;
|
|
370
383
|
}): AsyncIterable<Table>;
|
|
384
|
+
watchTable({ table, namespace, branch, pollIntervalSeconds }: {
|
|
385
|
+
table: string;
|
|
386
|
+
namespace?: string[];
|
|
387
|
+
branch?: string;
|
|
388
|
+
pollIntervalSeconds?: number;
|
|
389
|
+
}): AsyncIterable<DatasetWatchEvent>;
|
|
371
390
|
count({ table, text, vector, where, namespace, branch, version }: {
|
|
372
391
|
table: string;
|
|
373
392
|
text?: string;
|
|
@@ -444,6 +444,18 @@ function tableBranchFromJson(value) {
|
|
|
444
444
|
manifestSize: value.manifest_size ?? null,
|
|
445
445
|
};
|
|
446
446
|
}
|
|
447
|
+
function optionalDatasetInt(value) {
|
|
448
|
+
if (typeof value === "number" && Number.isInteger(value)) {
|
|
449
|
+
return value;
|
|
450
|
+
}
|
|
451
|
+
if (typeof value === "string" && /^-?\d+$/.test(value)) {
|
|
452
|
+
return Number.parseInt(value, 10);
|
|
453
|
+
}
|
|
454
|
+
return undefined;
|
|
455
|
+
}
|
|
456
|
+
function optionalDatasetString(value) {
|
|
457
|
+
return typeof value === "string" ? value : undefined;
|
|
458
|
+
}
|
|
447
459
|
class DatasetWriteInputStream {
|
|
448
460
|
constructor(start, chunks) {
|
|
449
461
|
this.start = start;
|
|
@@ -1130,6 +1142,73 @@ class DatasetsClient {
|
|
|
1130
1142
|
version: version ?? null,
|
|
1131
1143
|
});
|
|
1132
1144
|
}
|
|
1145
|
+
async *watchTable({ table, namespace, branch, pollIntervalSeconds = 0.5 }) {
|
|
1146
|
+
const input = new DatasetArrowReadInputStream({
|
|
1147
|
+
kind: "start",
|
|
1148
|
+
table,
|
|
1149
|
+
namespace: namespace ?? null,
|
|
1150
|
+
branch: branch ?? null,
|
|
1151
|
+
poll_interval_seconds: pollIntervalSeconds,
|
|
1152
|
+
});
|
|
1153
|
+
const response = await this.invokeStream("watch_table", input.stream());
|
|
1154
|
+
input.requestNext();
|
|
1155
|
+
try {
|
|
1156
|
+
for await (const chunk of response) {
|
|
1157
|
+
if (chunk instanceof response_1.ErrorContent) {
|
|
1158
|
+
throw new room_server_client_1.RoomServerException(chunk.text, chunk.code);
|
|
1159
|
+
}
|
|
1160
|
+
if (chunk instanceof response_1.ControlContent) {
|
|
1161
|
+
if (chunk.method === "close") {
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
throw this._unexpectedResponseError("watch_table");
|
|
1165
|
+
}
|
|
1166
|
+
if (chunk instanceof response_1.BinaryContent) {
|
|
1167
|
+
if (chunk.headers.kind !== "data") {
|
|
1168
|
+
throw this._unexpectedResponseError("watch_table");
|
|
1169
|
+
}
|
|
1170
|
+
const watchEvent = optionalDatasetString(chunk.headers.watch_event);
|
|
1171
|
+
yield {
|
|
1172
|
+
kind: watchEvent ?? "data",
|
|
1173
|
+
phase: optionalDatasetString(chunk.headers.phase),
|
|
1174
|
+
table: tableFromIPCBytes(chunk.data),
|
|
1175
|
+
version: optionalDatasetInt(chunk.headers.version),
|
|
1176
|
+
changeType: optionalDatasetString(chunk.headers.change_type),
|
|
1177
|
+
beginVersion: optionalDatasetInt(chunk.headers.begin_version),
|
|
1178
|
+
endVersion: optionalDatasetInt(chunk.headers.end_version),
|
|
1179
|
+
watchEvent,
|
|
1180
|
+
};
|
|
1181
|
+
input.requestNext();
|
|
1182
|
+
continue;
|
|
1183
|
+
}
|
|
1184
|
+
if (chunk instanceof response_1.JsonContent) {
|
|
1185
|
+
if (!isRecord(chunk.json)) {
|
|
1186
|
+
throw this._unexpectedResponseError("watch_table");
|
|
1187
|
+
}
|
|
1188
|
+
const rawTransactions = chunk.json.transactions;
|
|
1189
|
+
const rawTransaction = chunk.json.transaction;
|
|
1190
|
+
yield {
|
|
1191
|
+
kind: typeof chunk.json.kind === "string" ? chunk.json.kind : "event",
|
|
1192
|
+
phase: optionalDatasetString(chunk.json.phase),
|
|
1193
|
+
version: optionalDatasetInt(chunk.json.version),
|
|
1194
|
+
beginVersion: optionalDatasetInt(chunk.json.begin_version),
|
|
1195
|
+
endVersion: optionalDatasetInt(chunk.json.end_version),
|
|
1196
|
+
transactions: Array.isArray(rawTransactions)
|
|
1197
|
+
? rawTransactions.filter(isRecord)
|
|
1198
|
+
: undefined,
|
|
1199
|
+
deletePredicate: optionalDatasetString(chunk.json.predicate),
|
|
1200
|
+
transaction: isRecord(rawTransaction) ? rawTransaction : undefined,
|
|
1201
|
+
};
|
|
1202
|
+
input.requestNext();
|
|
1203
|
+
continue;
|
|
1204
|
+
}
|
|
1205
|
+
throw this._unexpectedResponseError("watch_table");
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
finally {
|
|
1209
|
+
input.close();
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1133
1212
|
async count({ table, text, vector, where, namespace, branch, version }) {
|
|
1134
1213
|
const response = await this.invoke("count", {
|
|
1135
1214
|
table,
|
package/dist/node/protocol.js
CHANGED
|
@@ -158,7 +158,9 @@ class WebSocketProtocolChannel {
|
|
|
158
158
|
this._onDataReceived = onDataReceived;
|
|
159
159
|
this._doneHandler = onDone;
|
|
160
160
|
this._errorHandler = onError;
|
|
161
|
-
const socket =
|
|
161
|
+
const socket = isNodeRuntime()
|
|
162
|
+
? new isomorphic_ws_1.default(url.toString(), [], { perMessageDeflate: true })
|
|
163
|
+
: new isomorphic_ws_1.default(url.toString());
|
|
162
164
|
this.webSocket = socket;
|
|
163
165
|
if (isNodeRuntime()) {
|
|
164
166
|
socket.on("unexpected-response", this._onUnexpectedResponse);
|