@meshagent/meshagent 0.29.2 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/browser/agent-client.js +3 -28
  3. package/dist/browser/agent.js +6 -6
  4. package/dist/browser/containers-client.d.ts +125 -0
  5. package/dist/browser/containers-client.js +458 -0
  6. package/dist/browser/database-client.d.ts +42 -6
  7. package/dist/browser/database-client.js +610 -77
  8. package/dist/browser/developer-client.d.ts +2 -2
  9. package/dist/browser/developer-client.js +60 -15
  10. package/dist/browser/helpers.js +4 -3
  11. package/dist/browser/index.d.ts +1 -0
  12. package/dist/browser/index.js +1 -0
  13. package/dist/browser/lk-client.js +12 -3
  14. package/dist/browser/meshagent-client.d.ts +5 -0
  15. package/dist/browser/messaging-client.d.ts +1 -0
  16. package/dist/browser/messaging-client.js +52 -8
  17. package/dist/browser/queues-client.d.ts +2 -0
  18. package/dist/browser/queues-client.js +34 -7
  19. package/dist/browser/response.d.ts +28 -0
  20. package/dist/browser/response.js +76 -1
  21. package/dist/browser/room-client.d.ts +43 -1
  22. package/dist/browser/room-client.js +204 -0
  23. package/dist/browser/secrets-client.d.ts +1 -0
  24. package/dist/browser/secrets-client.js +32 -27
  25. package/dist/browser/storage-client.d.ts +22 -7
  26. package/dist/browser/storage-client.js +353 -15
  27. package/dist/browser/sync-client.d.ts +12 -13
  28. package/dist/browser/sync-client.js +263 -65
  29. package/dist/esm/agent-client.js +3 -28
  30. package/dist/esm/agent.js +6 -6
  31. package/dist/esm/containers-client.d.ts +125 -0
  32. package/dist/esm/containers-client.js +453 -0
  33. package/dist/esm/database-client.d.ts +42 -6
  34. package/dist/esm/database-client.js +611 -78
  35. package/dist/esm/developer-client.d.ts +2 -2
  36. package/dist/esm/developer-client.js +61 -16
  37. package/dist/esm/helpers.js +4 -3
  38. package/dist/esm/index.d.ts +1 -0
  39. package/dist/esm/index.js +1 -0
  40. package/dist/esm/lk-client.js +12 -3
  41. package/dist/esm/meshagent-client.d.ts +5 -0
  42. package/dist/esm/messaging-client.d.ts +1 -0
  43. package/dist/esm/messaging-client.js +52 -8
  44. package/dist/esm/queues-client.d.ts +2 -0
  45. package/dist/esm/queues-client.js +35 -8
  46. package/dist/esm/response.d.ts +28 -0
  47. package/dist/esm/response.js +73 -0
  48. package/dist/esm/room-client.d.ts +43 -1
  49. package/dist/esm/room-client.js +207 -3
  50. package/dist/esm/secrets-client.d.ts +1 -0
  51. package/dist/esm/secrets-client.js +33 -28
  52. package/dist/esm/storage-client.d.ts +22 -7
  53. package/dist/esm/storage-client.js +353 -15
  54. package/dist/esm/sync-client.d.ts +12 -13
  55. package/dist/esm/sync-client.js +263 -64
  56. package/dist/node/agent-client.js +3 -28
  57. package/dist/node/agent.js +6 -6
  58. package/dist/node/containers-client.d.ts +125 -0
  59. package/dist/node/containers-client.js +458 -0
  60. package/dist/node/database-client.d.ts +42 -6
  61. package/dist/node/database-client.js +610 -77
  62. package/dist/node/developer-client.d.ts +2 -2
  63. package/dist/node/developer-client.js +60 -15
  64. package/dist/node/helpers.js +4 -3
  65. package/dist/node/index.d.ts +1 -0
  66. package/dist/node/index.js +1 -0
  67. package/dist/node/lk-client.js +12 -3
  68. package/dist/node/meshagent-client.d.ts +5 -0
  69. package/dist/node/messaging-client.d.ts +1 -0
  70. package/dist/node/messaging-client.js +52 -8
  71. package/dist/node/queues-client.d.ts +2 -0
  72. package/dist/node/queues-client.js +34 -7
  73. package/dist/node/response.d.ts +28 -0
  74. package/dist/node/response.js +76 -1
  75. package/dist/node/room-client.d.ts +43 -1
  76. package/dist/node/room-client.js +204 -0
  77. package/dist/node/secrets-client.d.ts +1 -0
  78. package/dist/node/secrets-client.js +32 -27
  79. package/dist/node/storage-client.d.ts +22 -7
  80. package/dist/node/storage-client.js +353 -15
  81. package/dist/node/sync-client.d.ts +12 -13
  82. package/dist/node/sync-client.js +263 -65
  83. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
1
  import { EventEmitter } from "./event-emitter";
2
2
  import { MeshSchema } from "./schema";
3
- import { StreamController } from "./stream-controller";
4
3
  import { MeshDocument, RoomServerException } from "./room-server-client";
5
- import { splitMessageHeader, splitMessagePayload, decoder, encoder, RefCount } from "./utils";
4
+ import { BinaryContent, ControlContent, ErrorContent } from "./response";
5
+ import { decoder, encoder, RefCount, unpackMessage } from "./utils";
6
6
  import { unregisterDocument, applyBackendChanges } from "./runtime";
7
7
  import { Completer } from "./completer";
8
8
  function normalizeSyncPath(path) {
@@ -18,98 +18,251 @@ function normalizeSyncPath(path) {
18
18
  }
19
19
  return normalized;
20
20
  }
21
- ;
22
- export class QueuedSync {
23
- constructor({ path, base64 }) {
24
- this.path = path;
25
- this.base64 = base64;
21
+ function parseSyncOpenStateChunkHeaders(headers) {
22
+ if (headers["kind"] !== "state" ||
23
+ typeof headers["path"] !== "string" ||
24
+ typeof headers["schema"] !== "object" ||
25
+ headers["schema"] == null) {
26
+ throw new RoomServerException("unexpected return type from sync.open");
26
27
  }
28
+ return {
29
+ kind: "state",
30
+ path: headers["path"],
31
+ schema: headers["schema"],
32
+ };
27
33
  }
34
+ function parseSyncOpenOutputChunkHeaders(headers) {
35
+ const kind = headers["kind"];
36
+ if ((kind !== "state" && kind !== "sync") ||
37
+ typeof headers["path"] !== "string") {
38
+ throw new RoomServerException("unexpected return type from sync.open");
39
+ }
40
+ return {
41
+ kind,
42
+ path: headers["path"],
43
+ };
44
+ }
45
+ class SyncOpenStreamState {
46
+ constructor(params) {
47
+ this.params = params;
48
+ this._inputQueue = [];
49
+ this._inputWaiters = [];
50
+ this._inputClosed = false;
51
+ }
52
+ _enqueueChunk(chunk) {
53
+ const waiter = this._inputWaiters.shift();
54
+ if (waiter) {
55
+ waiter(chunk);
56
+ return;
57
+ }
58
+ this._inputQueue.push(chunk);
59
+ }
60
+ _nextChunk() {
61
+ const queued = this._inputQueue.shift();
62
+ if (queued !== undefined) {
63
+ return Promise.resolve(queued);
64
+ }
65
+ return new Promise((resolve) => {
66
+ this._inputWaiters.push(resolve);
67
+ });
68
+ }
69
+ async *inputStream() {
70
+ yield new BinaryContent({
71
+ data: new Uint8Array(),
72
+ headers: {
73
+ kind: "start",
74
+ path: this.params.path,
75
+ create: this.params.create,
76
+ vector: this.params.vector,
77
+ schema: this.params.schemaJson,
78
+ schema_path: this.params.schemaPath,
79
+ initial_json: this.params.initialJson,
80
+ },
81
+ });
82
+ while (true) {
83
+ const chunk = await this._nextChunk();
84
+ if (chunk === SyncOpenStreamState.INPUT_STREAM_CLOSE) {
85
+ return;
86
+ }
87
+ yield chunk;
88
+ }
89
+ }
90
+ attachTask(task) {
91
+ this._task = task
92
+ .catch((error) => {
93
+ this._error = error;
94
+ throw error;
95
+ })
96
+ .finally(() => {
97
+ this.closeInputStream();
98
+ });
99
+ void this._task.catch(() => undefined);
100
+ }
101
+ closeInputStream() {
102
+ if (this._inputClosed) {
103
+ return;
104
+ }
105
+ this._inputClosed = true;
106
+ this._enqueueChunk(SyncOpenStreamState.INPUT_STREAM_CLOSE);
107
+ }
108
+ queueSync(data) {
109
+ if (this._error instanceof Error) {
110
+ throw this._error;
111
+ }
112
+ if (this._error !== undefined) {
113
+ throw new RoomServerException(`sync stream failed: ${String(this._error)}`);
114
+ }
115
+ if (this._inputClosed) {
116
+ throw new RoomServerException("attempted to sync to a document that is not connected");
117
+ }
118
+ this._enqueueChunk(new BinaryContent({
119
+ data,
120
+ headers: { kind: "sync" },
121
+ }));
122
+ }
123
+ async wait() {
124
+ await this._task;
125
+ }
126
+ }
127
+ SyncOpenStreamState.INPUT_STREAM_CLOSE = Symbol("sync-open-input-close");
28
128
  export class SyncClient extends EventEmitter {
29
129
  constructor({ room }) {
30
130
  super();
31
131
  this._connectingDocuments = {};
32
- this._changesToSync = new StreamController();
33
132
  this._connectedDocuments = {};
133
+ this._documentStreams = {};
34
134
  this.client = room;
35
- this.client.protocol.addHandler("room.sync", this._handleSync.bind(this));
36
135
  this.client.protocol.addHandler("room.status", this._handleStatus.bind(this));
37
136
  }
137
+ _unexpectedResponseError(operation) {
138
+ return new RoomServerException(`unexpected return type from sync.${operation}`);
139
+ }
140
+ async _invoke(operation, input) {
141
+ return await this.client.invoke({
142
+ toolkit: "sync",
143
+ tool: operation,
144
+ input,
145
+ });
146
+ }
38
147
  start({ onDone, onError } = {}) {
39
148
  this.client.protocol.start({ onDone, onError });
40
- (async () => {
41
- for await (const message of this._changesToSync.stream) {
42
- await this.client.sendRequest("room.sync", { path: message.path }, encoder.encode(message.base64));
43
- }
44
- })();
45
149
  }
46
150
  dispose() {
47
151
  super.dispose();
48
- this._changesToSync.close();
49
- }
50
- async _handleSync(protocol, messageId, data, bytes) {
51
- const headerStr = splitMessageHeader(bytes || new Uint8Array());
52
- const payload = splitMessagePayload(bytes || new Uint8Array());
53
- const header = JSON.parse(headerStr);
54
- const path = normalizeSyncPath(header["path"]);
55
- const isConnecting = this._connectingDocuments[path];
56
- if (isConnecting) {
57
- await isConnecting;
58
- }
59
- if (this._connectedDocuments[path]) {
60
- const rc = this._connectedDocuments[path];
61
- const doc = rc.ref;
152
+ for (const streamState of Object.values(this._documentStreams)) {
153
+ streamState.closeInputStream();
154
+ }
155
+ this._documentStreams = {};
156
+ for (const rc of Object.values(this._connectedDocuments)) {
157
+ unregisterDocument(rc.ref.id);
158
+ }
159
+ this._connectedDocuments = {};
160
+ this._connectingDocuments = {};
161
+ }
162
+ _applySyncPayload(rc, payload) {
163
+ const doc = rc.ref;
164
+ if (payload.length > 0) {
62
165
  const base64 = decoder.decode(payload);
63
166
  applyBackendChanges(doc.id, base64);
64
- this.emit("synced", { type: "sync", doc });
65
- if (!doc.isSynchronized) {
66
- doc.setSynchronizedComplete();
67
- }
68
167
  }
69
- else {
70
- throw new RoomServerException(`received change for a document that is not connected: ${path}`);
168
+ this.emit("synced", { type: "sync", doc });
169
+ if (!doc.isSynchronized) {
170
+ doc.setSynchronizedComplete();
71
171
  }
72
172
  }
73
- async _handleStatus(protocol, messageId, data, bytes) {
74
- const headerStr = splitMessageHeader(bytes || new Uint8Array());
75
- const header = JSON.parse(headerStr);
76
- this.emit("status", header.status);
173
+ async _handleStatus(_protocol, _messageId, _type, bytes) {
174
+ if (!bytes) {
175
+ return;
176
+ }
177
+ const [header] = unpackMessage(bytes);
178
+ this.emit("status", { type: "status", status: header.status });
77
179
  }
78
180
  async create(path, json) {
79
- path = normalizeSyncPath(path);
80
- await this.client.sendRequest("room.create", { path, json });
181
+ const normalizedPath = normalizeSyncPath(path);
182
+ await this._invoke("create", {
183
+ path: normalizedPath,
184
+ json: json ?? null,
185
+ schema: null,
186
+ schema_path: null,
187
+ });
81
188
  }
82
- async open(path, { create = true } = {}) {
189
+ async open(path, { create = true, initialJson, schema, } = {}) {
83
190
  path = normalizeSyncPath(path);
84
191
  const pending = this._connectingDocuments[path];
85
192
  if (pending) {
86
193
  await pending;
87
194
  }
88
- if (this._connectedDocuments[path]) {
89
- const rc = this._connectedDocuments[path];
90
- rc.count++;
91
- return rc.ref;
195
+ const connected = this._connectedDocuments[path];
196
+ if (connected) {
197
+ connected.count++;
198
+ return connected.ref;
92
199
  }
93
- const c = new Completer();
94
- this._connectingDocuments[path] = c.fut;
200
+ const connecting = new Completer();
201
+ this._connectingDocuments[path] = connecting.fut;
202
+ let streamState;
203
+ let iterator;
95
204
  try {
96
- const result = (await this.client.sendRequest("room.connect", { path, create }));
97
- const schema = MeshSchema.fromJson(result.json["schema"]);
205
+ streamState = new SyncOpenStreamState({
206
+ path,
207
+ create,
208
+ vector: null,
209
+ schemaJson: schema == null ? null : schema.toJson(),
210
+ schemaPath: null,
211
+ initialJson: initialJson ?? null,
212
+ });
213
+ const responseStream = await this.client.invokeStream({
214
+ toolkit: "sync",
215
+ tool: "open",
216
+ input: streamState.inputStream(),
217
+ });
218
+ iterator = responseStream[Symbol.asyncIterator]();
219
+ const first = await iterator.next();
220
+ if (first.done || first.value === undefined) {
221
+ throw new RoomServerException("sync.open stream closed before the initial document state was returned");
222
+ }
223
+ const firstChunk = first.value;
224
+ if (firstChunk instanceof ErrorContent) {
225
+ throw new RoomServerException(firstChunk.text, firstChunk.code);
226
+ }
227
+ if (!(firstChunk instanceof BinaryContent)) {
228
+ throw this._unexpectedResponseError("open");
229
+ }
230
+ const stateHeaders = parseSyncOpenStateChunkHeaders(firstChunk.headers);
231
+ if (normalizeSyncPath(stateHeaders.path) !== path) {
232
+ throw new RoomServerException("sync.open stream returned a mismatched path");
233
+ }
98
234
  const doc = new MeshDocument({
99
- schema,
100
- sendChangesToBackend: (base64Str) => {
101
- this._changesToSync.add({ path, base64: base64Str });
235
+ schema: MeshSchema.fromJson(stateHeaders.schema),
236
+ sendChangesToBackend: (base64) => {
237
+ try {
238
+ streamState?.queueSync(encoder.encode(base64));
239
+ }
240
+ catch {
241
+ }
102
242
  },
103
243
  });
104
244
  const rc = new RefCount(doc);
105
245
  this._connectedDocuments[path] = rc;
246
+ this._documentStreams[path] = streamState;
247
+ this._applySyncPayload(rc, firstChunk.data);
248
+ streamState.attachTask(this._consumeOpenStream({
249
+ path,
250
+ rc,
251
+ iterator,
252
+ streamState,
253
+ }));
106
254
  this.emit("connected", { type: "connect", doc });
107
- c.complete();
255
+ connecting.complete(rc);
256
+ await doc.synchronized;
108
257
  return doc;
109
258
  }
110
- catch (err) {
111
- c.completeError(err);
112
- throw err;
259
+ catch (error) {
260
+ streamState?.closeInputStream();
261
+ if (iterator) {
262
+ await iterator.return?.();
263
+ }
264
+ connecting.completeError(error);
265
+ throw error;
113
266
  }
114
267
  finally {
115
268
  delete this._connectingDocuments[path];
@@ -117,11 +270,6 @@ export class SyncClient extends EventEmitter {
117
270
  }
118
271
  async close(path) {
119
272
  path = normalizeSyncPath(path);
120
- const pending = this._connectingDocuments[path];
121
- if (pending) {
122
- await pending;
123
- await new Promise(resolve => setTimeout(resolve, 50));
124
- }
125
273
  const rc = this._connectedDocuments[path];
126
274
  if (!rc) {
127
275
  throw new RoomServerException(`Not connected to ${path}`);
@@ -130,13 +278,64 @@ export class SyncClient extends EventEmitter {
130
278
  rc.count--;
131
279
  if (rc.count === 0) {
132
280
  delete this._connectedDocuments[path];
133
- await this.client.sendRequest("room.disconnect", { path });
134
- unregisterDocument(doc.id);
281
+ const streamState = this._documentStreams[path];
282
+ delete this._documentStreams[path];
283
+ if (streamState) {
284
+ streamState.closeInputStream();
285
+ try {
286
+ await streamState.wait();
287
+ }
288
+ finally {
289
+ unregisterDocument(doc.id);
290
+ }
291
+ }
292
+ else {
293
+ unregisterDocument(doc.id);
294
+ }
135
295
  }
136
296
  this.emit("closed", { type: "close", doc });
137
297
  }
138
298
  async sync(path, data) {
139
299
  path = normalizeSyncPath(path);
140
- await this.client.sendRequest("room.sync", { path }, data);
300
+ if (!this._connectedDocuments[path]) {
301
+ throw new RoomServerException("attempted to sync to a document that is not connected");
302
+ }
303
+ const streamState = this._documentStreams[path];
304
+ if (!streamState) {
305
+ throw new RoomServerException("attempted to sync to a document that is not connected");
306
+ }
307
+ streamState.queueSync(data);
308
+ }
309
+ async _consumeOpenStream(params) {
310
+ try {
311
+ while (true) {
312
+ const next = await params.iterator.next();
313
+ if (next.done || next.value === undefined) {
314
+ return;
315
+ }
316
+ const chunk = next.value;
317
+ if (chunk instanceof ErrorContent) {
318
+ throw new RoomServerException(chunk.text, chunk.code);
319
+ }
320
+ if (chunk instanceof ControlContent) {
321
+ if (chunk.method === "close") {
322
+ return;
323
+ }
324
+ throw this._unexpectedResponseError("open");
325
+ }
326
+ if (!(chunk instanceof BinaryContent)) {
327
+ throw this._unexpectedResponseError("open");
328
+ }
329
+ const headers = parseSyncOpenOutputChunkHeaders(chunk.headers);
330
+ if (normalizeSyncPath(headers.path) !== params.path) {
331
+ throw new RoomServerException("sync.open stream returned a mismatched path");
332
+ }
333
+ this._applySyncPayload(params.rc, chunk.data);
334
+ }
335
+ }
336
+ finally {
337
+ params.streamState.closeInputStream();
338
+ await params.iterator.return?.();
339
+ }
141
340
  }
142
341
  }
@@ -173,38 +173,13 @@ class AgentsClient {
173
173
  this.client = room;
174
174
  }
175
175
  async call(params) {
176
- await this.client.sendRequest("agent.call", params);
176
+ await this.client.call(params);
177
177
  }
178
178
  async listToolkits(params) {
179
- const request = {};
180
- if (params?.participantId != null) {
181
- request["participant_id"] = params.participantId;
182
- }
183
- if (params?.participantName != null) {
184
- request["participant_name"] = params.participantName;
185
- }
186
- if (params?.timeout !== undefined) {
187
- request["timeout"] = params.timeout;
188
- }
189
- const result = (await this.client.sendRequest("agent.list_toolkits", request));
190
- const tools = result.json["tools"];
191
- const toolkits = [];
192
- for (const name of Object.keys(tools)) {
193
- const data = tools[name];
194
- toolkits.push(ToolkitDescription.fromJson(data, { name }));
195
- }
196
- return toolkits;
179
+ return await this.client.listToolkits(params);
197
180
  }
198
181
  async invokeTool(params) {
199
- const request = {
200
- toolkit: params.toolkit,
201
- tool: params.tool,
202
- arguments: {
203
- type: "json",
204
- json: params.arguments,
205
- },
206
- };
207
- return await this.client.sendRequest("agent.invoke_tool", request);
182
+ return await this.client.invoke(params);
208
183
  }
209
184
  }
210
185
  exports.AgentsClient = AgentsClient;
@@ -93,15 +93,15 @@ class RemoteToolkit extends Toolkit {
93
93
  }
94
94
  async start({ public_: isPublic = false } = {}) {
95
95
  const handler = this._toolCall.bind(this);
96
- this.client.protocol.addHandler(`agent.tool_call.${this.name}`, handler);
96
+ this.client.protocol.addHandler(`room.tool_call.${this.name}`, handler);
97
97
  await this._register(isPublic);
98
98
  }
99
99
  async stop() {
100
100
  await this._unregister();
101
- this.client.protocol.removeHandler(`agent.tool_call.${this.name}`);
101
+ this.client.protocol.removeHandler(`room.tool_call.${this.name}`);
102
102
  }
103
103
  async _register(public_) {
104
- const response = await this.client.sendRequest("agent.register_toolkit", {
104
+ const response = await this.client.sendRequest("room.register_toolkit", {
105
105
  name: this.name,
106
106
  title: this.title,
107
107
  description: this.description,
@@ -114,7 +114,7 @@ class RemoteToolkit extends Toolkit {
114
114
  async _unregister() {
115
115
  if (!this._registrationId)
116
116
  return;
117
- await this.client.sendRequest("agent.unregister_toolkit", {
117
+ await this.client.sendRequest("room.unregister_toolkit", {
118
118
  id: this._registrationId,
119
119
  });
120
120
  }
@@ -144,11 +144,11 @@ class RemoteToolkit extends Toolkit {
144
144
  args = rawArguments ?? {};
145
145
  }
146
146
  const response = await this.execute(toolName, args);
147
- await this.client.protocol.send("agent.tool_call_response", response.pack(), messageId);
147
+ await this.client.protocol.send("room.tool_call_response", response.pack(), messageId);
148
148
  }
149
149
  catch (e) {
150
150
  const err = new response_1.ErrorContent({ text: String(e) });
151
- await this.client.protocol.send("agent.tool_call_response", err.pack(), messageId);
151
+ await this.client.protocol.send("room.tool_call_response", err.pack(), messageId);
152
152
  }
153
153
  }
154
154
  }
@@ -0,0 +1,125 @@
1
+ import { ContainerMountSpec } from "./meshagent-client";
2
+ import { Content } from "./response";
3
+ import { RoomClient } from "./room-client";
4
+ export interface DockerSecret {
5
+ username: string;
6
+ password: string;
7
+ registry: string;
8
+ email?: string;
9
+ }
10
+ export interface ContainerImage {
11
+ id: string;
12
+ tags: string[];
13
+ size?: number;
14
+ labels: Record<string, unknown>;
15
+ }
16
+ export interface ContainerParticipantInfo {
17
+ id: string;
18
+ name: string;
19
+ }
20
+ export interface RoomContainer {
21
+ id: string;
22
+ image: string;
23
+ name?: string;
24
+ startedBy: ContainerParticipantInfo;
25
+ state: string;
26
+ private: boolean;
27
+ serviceId?: string;
28
+ }
29
+ export interface ContainerLogsSession {
30
+ stream: AsyncIterable<string>;
31
+ result: Promise<void>;
32
+ cancel(): Promise<void>;
33
+ }
34
+ export declare class ExecSession {
35
+ readonly command: string;
36
+ readonly result: Promise<number>;
37
+ readonly previousOutput: Uint8Array[];
38
+ readonly output: AsyncIterable<Uint8Array>;
39
+ private readonly requestId;
40
+ private readonly containerId;
41
+ private readonly tty?;
42
+ private readonly resultCompleter;
43
+ private readonly outputController;
44
+ private readonly queuedInput;
45
+ private inputClosed;
46
+ private closed;
47
+ private inputWaiter;
48
+ private lastResizeWidth?;
49
+ private lastResizeHeight?;
50
+ constructor(params: {
51
+ requestId: string;
52
+ command: string;
53
+ containerId: string;
54
+ tty?: boolean;
55
+ });
56
+ inputStream(): AsyncIterable<Content>;
57
+ write(data: Uint8Array): Promise<void>;
58
+ resize(params: {
59
+ width: number;
60
+ height: number;
61
+ }): Promise<void>;
62
+ stop(): Promise<void>;
63
+ kill(): Promise<void>;
64
+ close(status: number): void;
65
+ closeError(error: unknown): void;
66
+ addOutput(data: Uint8Array): void;
67
+ get isClosed(): boolean;
68
+ private queueInput;
69
+ private closeInputStream;
70
+ }
71
+ export declare class ContainersClient {
72
+ private readonly room;
73
+ constructor({ room }: {
74
+ room: RoomClient;
75
+ });
76
+ private unexpectedResponseError;
77
+ private invoke;
78
+ listImages(): Promise<ContainerImage[]>;
79
+ pullImage(params: {
80
+ tag: string;
81
+ credentials?: DockerSecret[];
82
+ }): Promise<void>;
83
+ run(params: {
84
+ image: string;
85
+ command?: string;
86
+ workingDir?: string;
87
+ env?: Record<string, string>;
88
+ mountPath?: string;
89
+ mountSubpath?: string;
90
+ role?: string;
91
+ participantName?: string;
92
+ ports?: Record<number, number> | Record<string, number>;
93
+ credentials?: DockerSecret[];
94
+ name?: string;
95
+ mounts?: ContainerMountSpec;
96
+ writableRootFs?: boolean;
97
+ private?: boolean;
98
+ }): Promise<string>;
99
+ runService(params: {
100
+ serviceId: string;
101
+ env?: Record<string, string>;
102
+ }): Promise<string>;
103
+ exec(params: {
104
+ containerId: string;
105
+ command: string;
106
+ tty?: boolean;
107
+ }): ExecSession;
108
+ stop(params: {
109
+ containerId: string;
110
+ force?: boolean;
111
+ }): Promise<void>;
112
+ waitForExit(params: {
113
+ containerId: string;
114
+ }): Promise<number>;
115
+ deleteContainer(params: {
116
+ containerId: string;
117
+ }): Promise<void>;
118
+ logs(params: {
119
+ containerId: string;
120
+ follow?: boolean;
121
+ }): ContainerLogsSession;
122
+ list(params?: {
123
+ all?: boolean;
124
+ }): Promise<RoomContainer[]>;
125
+ }