@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 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
- tag: string;
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
- tag: params.tag,
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,
@@ -158,7 +158,9 @@ class WebSocketProtocolChannel {
158
158
  this._onDataReceived = onDataReceived;
159
159
  this._doneHandler = onDone;
160
160
  this._errorHandler = onError;
161
- const socket = new isomorphic_ws_1.default(url.toString());
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
- tag: string;
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
- tag: params.tag,
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,
@@ -158,7 +158,9 @@ class WebSocketProtocolChannel {
158
158
  this._onDataReceived = onDataReceived;
159
159
  this._doneHandler = onDone;
160
160
  this._errorHandler = onError;
161
- const socket = new isomorphic_ws_1.default(url.toString());
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
- tag: string;
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
- tag: params.tag,
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,
@@ -158,7 +158,9 @@ class WebSocketProtocolChannel {
158
158
  this._onDataReceived = onDataReceived;
159
159
  this._doneHandler = onDone;
160
160
  this._errorHandler = onError;
161
- const socket = new isomorphic_ws_1.default(url.toString());
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshagent/meshagent",
3
- "version": "0.39.8",
3
+ "version": "0.40.0",
4
4
  "description": "Meshagent Client",
5
5
  "homepage": "https://github.com/meshagent/meshagent-ts",
6
6
  "scripts": {