@meshagent/meshagent 0.39.9 → 0.40.1

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.1]
2
+ - Stability
3
+
4
+ ## [0.40.0]
5
+ - Enabled websocket compression for Node protocol connections while preserving the browser path.
6
+ - Aligned the JS and TS protocol surface with realtime model selection and output-modality negotiation.
7
+ - Refreshed the generated Node entrypoint to match the updated realtime protocol flow.
8
+
1
9
  ## [0.39.9]
2
10
  - Added streaming `watchTable` support to the TypeScript DatasetsClient to receive dataset table change events with versioning metadata.
3
11
 
@@ -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 () => {
@@ -124,7 +124,7 @@ export interface DatasetSqlCancelResult {
124
124
  status: DatasetSqlCancelStatus;
125
125
  }
126
126
  export interface DatasetWatchEvent {
127
- kind: "data" | "ready";
127
+ kind: string;
128
128
  phase?: string;
129
129
  table?: Table;
130
130
  version?: number;
@@ -132,6 +132,9 @@ export interface DatasetWatchEvent {
132
132
  beginVersion?: number;
133
133
  endVersion?: number;
134
134
  watchEvent?: string;
135
+ transactions?: Record<string, unknown>[];
136
+ deletePredicate?: string;
137
+ transaction?: Record<string, unknown>;
135
138
  }
136
139
  export declare abstract class DatasetValueEncoder {
137
140
  abstract encodeDatasetValue(): unknown;
@@ -1167,27 +1167,37 @@ class DatasetsClient {
1167
1167
  if (chunk.headers.kind !== "data") {
1168
1168
  throw this._unexpectedResponseError("watch_table");
1169
1169
  }
1170
+ const watchEvent = optionalDatasetString(chunk.headers.watch_event);
1170
1171
  yield {
1171
- kind: "data",
1172
+ kind: watchEvent ?? "data",
1172
1173
  phase: optionalDatasetString(chunk.headers.phase),
1173
1174
  table: tableFromIPCBytes(chunk.data),
1174
1175
  version: optionalDatasetInt(chunk.headers.version),
1175
1176
  changeType: optionalDatasetString(chunk.headers.change_type),
1176
1177
  beginVersion: optionalDatasetInt(chunk.headers.begin_version),
1177
1178
  endVersion: optionalDatasetInt(chunk.headers.end_version),
1178
- watchEvent: optionalDatasetString(chunk.headers.watch_event),
1179
+ watchEvent,
1179
1180
  };
1180
1181
  input.requestNext();
1181
1182
  continue;
1182
1183
  }
1183
1184
  if (chunk instanceof response_1.JsonContent) {
1184
- if (chunk.json.kind !== "ready") {
1185
+ if (!isRecord(chunk.json)) {
1185
1186
  throw this._unexpectedResponseError("watch_table");
1186
1187
  }
1188
+ const rawTransactions = chunk.json.transactions;
1189
+ const rawTransaction = chunk.json.transaction;
1187
1190
  yield {
1188
- kind: "ready",
1191
+ kind: typeof chunk.json.kind === "string" ? chunk.json.kind : "event",
1189
1192
  phase: optionalDatasetString(chunk.json.phase),
1190
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,
1191
1201
  };
1192
1202
  input.requestNext();
1193
1203
  continue;
@@ -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 () => {
@@ -124,7 +124,7 @@ export interface DatasetSqlCancelResult {
124
124
  status: DatasetSqlCancelStatus;
125
125
  }
126
126
  export interface DatasetWatchEvent {
127
- kind: "data" | "ready";
127
+ kind: string;
128
128
  phase?: string;
129
129
  table?: Table;
130
130
  version?: number;
@@ -132,6 +132,9 @@ export interface DatasetWatchEvent {
132
132
  beginVersion?: number;
133
133
  endVersion?: number;
134
134
  watchEvent?: string;
135
+ transactions?: Record<string, unknown>[];
136
+ deletePredicate?: string;
137
+ transaction?: Record<string, unknown>;
135
138
  }
136
139
  export declare abstract class DatasetValueEncoder {
137
140
  abstract encodeDatasetValue(): unknown;
@@ -1167,27 +1167,37 @@ class DatasetsClient {
1167
1167
  if (chunk.headers.kind !== "data") {
1168
1168
  throw this._unexpectedResponseError("watch_table");
1169
1169
  }
1170
+ const watchEvent = optionalDatasetString(chunk.headers.watch_event);
1170
1171
  yield {
1171
- kind: "data",
1172
+ kind: watchEvent ?? "data",
1172
1173
  phase: optionalDatasetString(chunk.headers.phase),
1173
1174
  table: tableFromIPCBytes(chunk.data),
1174
1175
  version: optionalDatasetInt(chunk.headers.version),
1175
1176
  changeType: optionalDatasetString(chunk.headers.change_type),
1176
1177
  beginVersion: optionalDatasetInt(chunk.headers.begin_version),
1177
1178
  endVersion: optionalDatasetInt(chunk.headers.end_version),
1178
- watchEvent: optionalDatasetString(chunk.headers.watch_event),
1179
+ watchEvent,
1179
1180
  };
1180
1181
  input.requestNext();
1181
1182
  continue;
1182
1183
  }
1183
1184
  if (chunk instanceof response_1.JsonContent) {
1184
- if (chunk.json.kind !== "ready") {
1185
+ if (!isRecord(chunk.json)) {
1185
1186
  throw this._unexpectedResponseError("watch_table");
1186
1187
  }
1188
+ const rawTransactions = chunk.json.transactions;
1189
+ const rawTransaction = chunk.json.transaction;
1187
1190
  yield {
1188
- kind: "ready",
1191
+ kind: typeof chunk.json.kind === "string" ? chunk.json.kind : "event",
1189
1192
  phase: optionalDatasetString(chunk.json.phase),
1190
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,
1191
1201
  };
1192
1202
  input.requestNext();
1193
1203
  continue;
@@ -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 () => {
@@ -124,7 +124,7 @@ export interface DatasetSqlCancelResult {
124
124
  status: DatasetSqlCancelStatus;
125
125
  }
126
126
  export interface DatasetWatchEvent {
127
- kind: "data" | "ready";
127
+ kind: string;
128
128
  phase?: string;
129
129
  table?: Table;
130
130
  version?: number;
@@ -132,6 +132,9 @@ export interface DatasetWatchEvent {
132
132
  beginVersion?: number;
133
133
  endVersion?: number;
134
134
  watchEvent?: string;
135
+ transactions?: Record<string, unknown>[];
136
+ deletePredicate?: string;
137
+ transaction?: Record<string, unknown>;
135
138
  }
136
139
  export declare abstract class DatasetValueEncoder {
137
140
  abstract encodeDatasetValue(): unknown;
@@ -1167,27 +1167,37 @@ class DatasetsClient {
1167
1167
  if (chunk.headers.kind !== "data") {
1168
1168
  throw this._unexpectedResponseError("watch_table");
1169
1169
  }
1170
+ const watchEvent = optionalDatasetString(chunk.headers.watch_event);
1170
1171
  yield {
1171
- kind: "data",
1172
+ kind: watchEvent ?? "data",
1172
1173
  phase: optionalDatasetString(chunk.headers.phase),
1173
1174
  table: tableFromIPCBytes(chunk.data),
1174
1175
  version: optionalDatasetInt(chunk.headers.version),
1175
1176
  changeType: optionalDatasetString(chunk.headers.change_type),
1176
1177
  beginVersion: optionalDatasetInt(chunk.headers.begin_version),
1177
1178
  endVersion: optionalDatasetInt(chunk.headers.end_version),
1178
- watchEvent: optionalDatasetString(chunk.headers.watch_event),
1179
+ watchEvent,
1179
1180
  };
1180
1181
  input.requestNext();
1181
1182
  continue;
1182
1183
  }
1183
1184
  if (chunk instanceof response_1.JsonContent) {
1184
- if (chunk.json.kind !== "ready") {
1185
+ if (!isRecord(chunk.json)) {
1185
1186
  throw this._unexpectedResponseError("watch_table");
1186
1187
  }
1188
+ const rawTransactions = chunk.json.transactions;
1189
+ const rawTransaction = chunk.json.transaction;
1187
1190
  yield {
1188
- kind: "ready",
1191
+ kind: typeof chunk.json.kind === "string" ? chunk.json.kind : "event",
1189
1192
  phase: optionalDatasetString(chunk.json.phase),
1190
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,
1191
1201
  };
1192
1202
  input.requestNext();
1193
1203
  continue;
@@ -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.9",
3
+ "version": "0.40.1",
4
4
  "description": "Meshagent Client",
5
5
  "homepage": "https://github.com/meshagent/meshagent-ts",
6
6
  "scripts": {