@daytonaio/sdk 0.175.1-alpha.1 → 0.178.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 (91) hide show
  1. package/cjs/CodeInterpreter.d.ts +3 -2
  2. package/cjs/CodeInterpreter.js.map +1 -1
  3. package/cjs/ComputerUse.d.ts +104 -2
  4. package/cjs/ComputerUse.js +851 -763
  5. package/cjs/ComputerUse.js.map +1 -1
  6. package/cjs/Daytona.d.ts +4 -3
  7. package/cjs/Daytona.js +429 -443
  8. package/cjs/Daytona.js.map +1 -1
  9. package/cjs/FileSystem.d.ts +2 -2
  10. package/cjs/FileSystem.js +491 -521
  11. package/cjs/FileSystem.js.map +1 -1
  12. package/cjs/Git.d.ts +2 -1
  13. package/cjs/Git.js +287 -310
  14. package/cjs/Git.js.map +1 -1
  15. package/cjs/LspServer.d.ts +2 -1
  16. package/cjs/LspServer.js +209 -226
  17. package/cjs/LspServer.js.map +1 -1
  18. package/cjs/ObjectStorage.js +170 -166
  19. package/cjs/ObjectStorage.js.map +1 -1
  20. package/cjs/Process.d.ts +4 -3
  21. package/cjs/Process.js +562 -600
  22. package/cjs/Process.js.map +1 -1
  23. package/cjs/PtyHandle.d.ts +2 -2
  24. package/cjs/PtyHandle.js +327 -338
  25. package/cjs/PtyHandle.js.map +1 -1
  26. package/cjs/Sandbox.d.ts +4 -3
  27. package/cjs/Sandbox.js +756 -821
  28. package/cjs/Sandbox.js.map +1 -1
  29. package/cjs/Snapshot.d.ts +3 -2
  30. package/cjs/Snapshot.js +203 -213
  31. package/cjs/Snapshot.js.map +1 -1
  32. package/cjs/Volume.d.ts +2 -1
  33. package/cjs/Volume.js +90 -92
  34. package/cjs/Volume.js.map +1 -1
  35. package/cjs/errors/DaytonaError.d.ts +2 -1
  36. package/cjs/errors/DaytonaError.js.map +1 -1
  37. package/cjs/index.d.ts +2 -2
  38. package/cjs/index.js +2 -1
  39. package/cjs/index.js.map +1 -1
  40. package/cjs/types/CodeInterpreter.d.ts +1 -1
  41. package/cjs/utils/Binary.js +14 -2
  42. package/cjs/utils/Binary.js.map +1 -1
  43. package/cjs/utils/otel.decorator.d.ts +7 -8
  44. package/cjs/utils/otel.decorator.js +24 -30
  45. package/cjs/utils/otel.decorator.js.map +1 -1
  46. package/esm/CodeInterpreter.d.ts +3 -2
  47. package/esm/CodeInterpreter.js.map +1 -1
  48. package/esm/ComputerUse.d.ts +104 -2
  49. package/esm/ComputerUse.js +857 -763
  50. package/esm/ComputerUse.js.map +1 -1
  51. package/esm/Daytona.d.ts +4 -3
  52. package/esm/Daytona.js +431 -444
  53. package/esm/Daytona.js.map +1 -1
  54. package/esm/FileSystem.d.ts +2 -2
  55. package/esm/FileSystem.js +493 -522
  56. package/esm/FileSystem.js.map +1 -1
  57. package/esm/Git.d.ts +2 -1
  58. package/esm/Git.js +289 -311
  59. package/esm/Git.js.map +1 -1
  60. package/esm/LspServer.d.ts +2 -1
  61. package/esm/LspServer.js +211 -227
  62. package/esm/LspServer.js.map +1 -1
  63. package/esm/ObjectStorage.js +172 -167
  64. package/esm/ObjectStorage.js.map +1 -1
  65. package/esm/Process.d.ts +4 -3
  66. package/esm/Process.js +564 -601
  67. package/esm/Process.js.map +1 -1
  68. package/esm/PtyHandle.d.ts +2 -2
  69. package/esm/PtyHandle.js +329 -339
  70. package/esm/PtyHandle.js.map +1 -1
  71. package/esm/Sandbox.d.ts +4 -3
  72. package/esm/Sandbox.js +759 -823
  73. package/esm/Sandbox.js.map +1 -1
  74. package/esm/Snapshot.d.ts +3 -2
  75. package/esm/Snapshot.js +206 -215
  76. package/esm/Snapshot.js.map +1 -1
  77. package/esm/Volume.d.ts +2 -1
  78. package/esm/Volume.js +92 -93
  79. package/esm/Volume.js.map +1 -1
  80. package/esm/errors/DaytonaError.d.ts +2 -1
  81. package/esm/errors/DaytonaError.js.map +1 -1
  82. package/esm/index.d.ts +2 -2
  83. package/esm/index.js +1 -1
  84. package/esm/index.js.map +1 -1
  85. package/esm/types/CodeInterpreter.d.ts +1 -1
  86. package/esm/utils/Binary.js +14 -2
  87. package/esm/utils/Binary.js.map +1 -1
  88. package/esm/utils/otel.decorator.d.ts +7 -8
  89. package/esm/utils/otel.decorator.js +26 -32
  90. package/esm/utils/otel.decorator.js.map +1 -1
  91. package/package.json +3 -3
package/esm/PtyHandle.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Copyright 2025 Daytona Platforms Inc.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { __decorate, __metadata } from "tslib";
5
+ import { __esDecorate, __runInitializers } from "tslib";
6
6
  import WebSocket from 'isomorphic-ws';
7
7
  import { DaytonaConnectionError, DaytonaError, DaytonaTimeoutError } from './errors/DaytonaError.js';
8
8
  import { WithInstrumentation } from './utils/otel.decorator.js';
@@ -38,375 +38,365 @@ import { WithInstrumentation } from './utils/otel.decorator.js';
38
38
  * await ptyHandle.disconnect();
39
39
  * ```
40
40
  */
41
- export class PtyHandle {
42
- ws;
43
- handleResize;
44
- handleKill;
45
- onPty;
46
- sessionId;
47
- _exitCode;
48
- _error;
49
- connected = false;
50
- connectionEstablished = false; // Track control message received
51
- constructor(ws, handleResize, handleKill, onPty, sessionId) {
52
- this.ws = ws;
53
- this.handleResize = handleResize;
54
- this.handleKill = handleKill;
55
- this.onPty = onPty;
56
- this.sessionId = sessionId;
57
- this.setupWebSocketHandlers();
58
- }
59
- /**
60
- * Exit code of the PTY process (if terminated)
61
- */
62
- get exitCode() {
63
- return this._exitCode;
64
- }
65
- /**
66
- * Error message if the PTY failed
67
- */
68
- get error() {
69
- return this._error;
70
- }
71
- /**
72
- * Check if connected to the PTY session
73
- */
74
- isConnected() {
75
- return this.connected && this.ws.readyState === WebSocket.OPEN;
76
- }
77
- /**
78
- * Wait for the WebSocket connection to be established.
79
- *
80
- * This method ensures the PTY session is ready to receive input and send output.
81
- * It waits for the server to confirm the connection is established.
82
- *
83
- * @throws {Error} If connection times out (10 seconds) or connection fails
84
- */
85
- async waitForConnection() {
86
- if (this.connectionEstablished) {
87
- return;
41
+ let PtyHandle = (() => {
42
+ let _instanceExtraInitializers = [];
43
+ let _waitForConnection_decorators;
44
+ let _sendInput_decorators;
45
+ let _resize_decorators;
46
+ let _disconnect_decorators;
47
+ let _wait_decorators;
48
+ let _kill_decorators;
49
+ return class PtyHandle {
50
+ static {
51
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
52
+ _waitForConnection_decorators = [WithInstrumentation()];
53
+ _sendInput_decorators = [WithInstrumentation()];
54
+ _resize_decorators = [WithInstrumentation()];
55
+ _disconnect_decorators = [WithInstrumentation()];
56
+ _wait_decorators = [WithInstrumentation()];
57
+ _kill_decorators = [WithInstrumentation()];
58
+ __esDecorate(this, null, _waitForConnection_decorators, { kind: "method", name: "waitForConnection", static: false, private: false, access: { has: obj => "waitForConnection" in obj, get: obj => obj.waitForConnection }, metadata: _metadata }, null, _instanceExtraInitializers);
59
+ __esDecorate(this, null, _sendInput_decorators, { kind: "method", name: "sendInput", static: false, private: false, access: { has: obj => "sendInput" in obj, get: obj => obj.sendInput }, metadata: _metadata }, null, _instanceExtraInitializers);
60
+ __esDecorate(this, null, _resize_decorators, { kind: "method", name: "resize", static: false, private: false, access: { has: obj => "resize" in obj, get: obj => obj.resize }, metadata: _metadata }, null, _instanceExtraInitializers);
61
+ __esDecorate(this, null, _disconnect_decorators, { kind: "method", name: "disconnect", static: false, private: false, access: { has: obj => "disconnect" in obj, get: obj => obj.disconnect }, metadata: _metadata }, null, _instanceExtraInitializers);
62
+ __esDecorate(this, null, _wait_decorators, { kind: "method", name: "wait", static: false, private: false, access: { has: obj => "wait" in obj, get: obj => obj.wait }, metadata: _metadata }, null, _instanceExtraInitializers);
63
+ __esDecorate(this, null, _kill_decorators, { kind: "method", name: "kill", static: false, private: false, access: { has: obj => "kill" in obj, get: obj => obj.kill }, metadata: _metadata }, null, _instanceExtraInitializers);
64
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
88
65
  }
89
- return new Promise((resolve, reject) => {
90
- const timeout = setTimeout(() => {
91
- reject(new DaytonaTimeoutError('PTY connection timeout'));
92
- }, 10000); // 10 second timeout
93
- const checkConnection = () => {
94
- if (this.connectionEstablished) {
95
- clearTimeout(timeout);
96
- resolve();
97
- }
98
- else if (this.ws.readyState === WebSocket.CLOSED || this._error) {
99
- clearTimeout(timeout);
100
- reject(new DaytonaConnectionError(this._error || 'Connection failed'));
66
+ ws = __runInitializers(this, _instanceExtraInitializers);
67
+ handleResize;
68
+ handleKill;
69
+ onPty;
70
+ sessionId;
71
+ _exitCode;
72
+ _error;
73
+ connected = false;
74
+ connectionEstablished = false; // Track control message received
75
+ constructor(ws, handleResize, handleKill, onPty, sessionId) {
76
+ this.ws = ws;
77
+ this.handleResize = handleResize;
78
+ this.handleKill = handleKill;
79
+ this.onPty = onPty;
80
+ this.sessionId = sessionId;
81
+ this.setupWebSocketHandlers();
82
+ }
83
+ /**
84
+ * Exit code of the PTY process (if terminated)
85
+ */
86
+ get exitCode() {
87
+ return this._exitCode;
88
+ }
89
+ /**
90
+ * Error message if the PTY failed
91
+ */
92
+ get error() {
93
+ return this._error;
94
+ }
95
+ /**
96
+ * Check if connected to the PTY session
97
+ */
98
+ isConnected() {
99
+ return this.connected && this.ws.readyState === WebSocket.OPEN;
100
+ }
101
+ /**
102
+ * Wait for the WebSocket connection to be established.
103
+ *
104
+ * This method ensures the PTY session is ready to receive input and send output.
105
+ * It waits for the server to confirm the connection is established.
106
+ *
107
+ * @throws {Error} If connection times out (10 seconds) or connection fails
108
+ */
109
+ async waitForConnection() {
110
+ if (this.connectionEstablished) {
111
+ return;
112
+ }
113
+ return new Promise((resolve, reject) => {
114
+ const timeout = setTimeout(() => {
115
+ reject(new DaytonaTimeoutError('PTY connection timeout'));
116
+ }, 10000); // 10 second timeout
117
+ const checkConnection = () => {
118
+ if (this.connectionEstablished) {
119
+ clearTimeout(timeout);
120
+ resolve();
121
+ }
122
+ else if (this.ws.readyState === WebSocket.CLOSED || this._error) {
123
+ clearTimeout(timeout);
124
+ reject(new DaytonaConnectionError(this._error || 'Connection failed'));
125
+ }
126
+ else {
127
+ setTimeout(checkConnection, 100);
128
+ }
129
+ };
130
+ checkConnection();
131
+ });
132
+ }
133
+ /**
134
+ * Send input data to the PTY session.
135
+ *
136
+ * Sends keyboard input or commands to the terminal session. The data will be
137
+ * processed as if it was typed in the terminal.
138
+ *
139
+ * @param {string | Uint8Array} data - Input data to send (commands, keystrokes, etc.)
140
+ * @throws {Error} If PTY is not connected or sending fails
141
+ *
142
+ * @example
143
+ * // Send a command
144
+ * await ptyHandle.sendInput('ls -la\n');
145
+ *
146
+ * // Send raw bytes
147
+ * await ptyHandle.sendInput(new Uint8Array([3])); // Ctrl+C
148
+ */
149
+ async sendInput(data) {
150
+ if (!this.isConnected()) {
151
+ throw new DaytonaConnectionError('PTY is not connected');
152
+ }
153
+ try {
154
+ if (typeof data === 'string') {
155
+ this.ws.send(new TextEncoder().encode(data));
101
156
  }
102
157
  else {
103
- setTimeout(checkConnection, 100);
158
+ this.ws.send(data);
104
159
  }
105
- };
106
- checkConnection();
107
- });
108
- }
109
- /**
110
- * Send input data to the PTY session.
111
- *
112
- * Sends keyboard input or commands to the terminal session. The data will be
113
- * processed as if it was typed in the terminal.
114
- *
115
- * @param {string | Uint8Array} data - Input data to send (commands, keystrokes, etc.)
116
- * @throws {Error} If PTY is not connected or sending fails
117
- *
118
- * @example
119
- * // Send a command
120
- * await ptyHandle.sendInput('ls -la\n');
121
- *
122
- * // Send raw bytes
123
- * await ptyHandle.sendInput(new Uint8Array([3])); // Ctrl+C
124
- */
125
- async sendInput(data) {
126
- if (!this.isConnected()) {
127
- throw new DaytonaConnectionError('PTY is not connected');
128
- }
129
- try {
130
- if (typeof data === 'string') {
131
- this.ws.send(new TextEncoder().encode(data));
132
160
  }
133
- else {
134
- this.ws.send(data);
161
+ catch (error) {
162
+ const errorMessage = error instanceof Error ? error.message : String(error);
163
+ throw new DaytonaConnectionError(`Failed to send input to PTY: ${errorMessage}`);
135
164
  }
136
165
  }
137
- catch (error) {
138
- const errorMessage = error instanceof Error ? error.message : String(error);
139
- throw new DaytonaConnectionError(`Failed to send input to PTY: ${errorMessage}`);
166
+ /**
167
+ * Resize the PTY terminal dimensions.
168
+ *
169
+ * Changes the terminal size which will notify terminal applications
170
+ * about the new dimensions via SIGWINCH signal.
171
+ *
172
+ * @param {number} cols - New number of terminal columns
173
+ * @param {number} rows - New number of terminal rows
174
+ *
175
+ * @example
176
+ * // Resize to 120x30
177
+ * await ptyHandle.resize(120, 30);
178
+ */
179
+ async resize(cols, rows) {
180
+ return await this.handleResize(cols, rows);
140
181
  }
141
- }
142
- /**
143
- * Resize the PTY terminal dimensions.
144
- *
145
- * Changes the terminal size which will notify terminal applications
146
- * about the new dimensions via SIGWINCH signal.
147
- *
148
- * @param {number} cols - New number of terminal columns
149
- * @param {number} rows - New number of terminal rows
150
- *
151
- * @example
152
- * // Resize to 120x30
153
- * await ptyHandle.resize(120, 30);
154
- */
155
- async resize(cols, rows) {
156
- return await this.handleResize(cols, rows);
157
- }
158
- /**
159
- * Disconnect from the PTY session and clean up resources.
160
- *
161
- * Closes the WebSocket connection and releases any associated resources.
162
- * Should be called when done with the PTY session.
163
- *
164
- * @example
165
- * // Always clean up when done
166
- * try {
167
- * // ... use PTY session
168
- * } finally {
169
- * await ptyHandle.disconnect();
170
- * }
171
- */
172
- async disconnect() {
173
- if (this.ws) {
174
- try {
175
- this.ws.close();
176
- }
177
- catch {
178
- // Ignore close errors
182
+ /**
183
+ * Disconnect from the PTY session and clean up resources.
184
+ *
185
+ * Closes the WebSocket connection and releases any associated resources.
186
+ * Should be called when done with the PTY session.
187
+ *
188
+ * @example
189
+ * // Always clean up when done
190
+ * try {
191
+ * // ... use PTY session
192
+ * } finally {
193
+ * await ptyHandle.disconnect();
194
+ * }
195
+ */
196
+ async disconnect() {
197
+ if (this.ws) {
198
+ try {
199
+ this.ws.close();
200
+ }
201
+ catch {
202
+ // Ignore close errors
203
+ }
179
204
  }
180
205
  }
181
- }
182
- /**
183
- * Wait for the PTY process to exit and return the result.
184
- *
185
- * This method blocks until the PTY process terminates and returns
186
- * information about how it exited.
187
- *
188
- * @returns {Promise<PtyResult>} Result containing exit code and error information
189
- *
190
- * @example
191
- * // Wait for process to complete
192
- * const result = await ptyHandle.wait();
193
- *
194
- * if (result.exitCode === 0) {
195
- * console.log('Process completed successfully');
196
- * } else {
197
- * console.log(`Process failed with code: ${result.exitCode}`);
198
- * if (result.error) {
199
- * console.log(`Error: ${result.error}`);
200
- * }
201
- * }
202
- */
203
- async wait() {
204
- return new Promise((resolve, reject) => {
205
- if (this._exitCode !== undefined) {
206
- resolve({
207
- exitCode: this._exitCode,
208
- error: this._error,
209
- });
210
- return;
211
- }
212
- const checkExit = () => {
206
+ /**
207
+ * Wait for the PTY process to exit and return the result.
208
+ *
209
+ * This method blocks until the PTY process terminates and returns
210
+ * information about how it exited.
211
+ *
212
+ * @returns {Promise<PtyResult>} Result containing exit code and error information
213
+ *
214
+ * @example
215
+ * // Wait for process to complete
216
+ * const result = await ptyHandle.wait();
217
+ *
218
+ * if (result.exitCode === 0) {
219
+ * console.log('Process completed successfully');
220
+ * } else {
221
+ * console.log(`Process failed with code: ${result.exitCode}`);
222
+ * if (result.error) {
223
+ * console.log(`Error: ${result.error}`);
224
+ * }
225
+ * }
226
+ */
227
+ async wait() {
228
+ return new Promise((resolve, reject) => {
213
229
  if (this._exitCode !== undefined) {
214
230
  resolve({
215
231
  exitCode: this._exitCode,
216
232
  error: this._error,
217
233
  });
234
+ return;
235
+ }
236
+ const checkExit = () => {
237
+ if (this._exitCode !== undefined) {
238
+ resolve({
239
+ exitCode: this._exitCode,
240
+ error: this._error,
241
+ });
242
+ }
243
+ else if (this._error) {
244
+ reject(new DaytonaError(this._error));
245
+ }
246
+ else {
247
+ setTimeout(checkExit, 100);
248
+ }
249
+ };
250
+ checkExit();
251
+ });
252
+ }
253
+ /**
254
+ * Kill the PTY process and terminate the session.
255
+ *
256
+ * Forcefully terminates the PTY session and its associated process.
257
+ * This operation is irreversible and will cause the PTY to exit immediately.
258
+ *
259
+ * @throws {Error} If the kill operation fails
260
+ *
261
+ * @example
262
+ * // Kill a long-running process
263
+ * await ptyHandle.kill();
264
+ *
265
+ * // Wait to confirm termination
266
+ * const result = await ptyHandle.wait();
267
+ * console.log(`Process terminated with exit code: ${result.exitCode}`);
268
+ */
269
+ async kill() {
270
+ return await this.handleKill();
271
+ }
272
+ setupWebSocketHandlers() {
273
+ // Set binary type for binary data handling
274
+ if ('binaryType' in this.ws) {
275
+ this.ws.binaryType = 'arraybuffer';
276
+ }
277
+ // Handle WebSocket open
278
+ const handleOpen = async () => {
279
+ this.connected = true;
280
+ };
281
+ // Handle WebSocket messages - control messages and PTY data
282
+ const handleMessage = async (event) => {
283
+ try {
284
+ const data = event && typeof event === 'object' && 'data' in event ? event.data : event;
285
+ if (typeof data === 'string') {
286
+ // Try to parse as control message first
287
+ try {
288
+ const controlMsg = JSON.parse(data);
289
+ if (controlMsg.type === 'control') {
290
+ if (controlMsg.status === 'connected') {
291
+ this.connectionEstablished = true;
292
+ return;
293
+ }
294
+ else if (controlMsg.status === 'error') {
295
+ this._error = controlMsg.error || 'Unknown connection error';
296
+ this.connected = false;
297
+ return;
298
+ }
299
+ }
300
+ }
301
+ catch {
302
+ // Not a control message, treat as PTY output
303
+ }
304
+ // Regular PTY text output
305
+ if (this.onPty) {
306
+ await this.onPty(new TextEncoder().encode(data));
307
+ }
308
+ }
309
+ else {
310
+ // Handle binary data (terminal output)
311
+ let bytes;
312
+ if (data instanceof ArrayBuffer) {
313
+ bytes = new Uint8Array(data);
314
+ }
315
+ else if (ArrayBuffer.isView(data)) {
316
+ bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
317
+ }
318
+ else if (data instanceof Blob) {
319
+ const buffer = await data.arrayBuffer();
320
+ bytes = new Uint8Array(buffer);
321
+ }
322
+ else {
323
+ throw new DaytonaError(`Unsupported message data type: ${Object.prototype.toString.call(data)}`);
324
+ }
325
+ if (this.onPty) {
326
+ await this.onPty(bytes);
327
+ }
328
+ }
329
+ }
330
+ catch (error) {
331
+ const errorMessage = error instanceof Error ? error.message : String(error);
332
+ throw new DaytonaError(`Error handling PTY message: ${errorMessage}`);
333
+ }
334
+ };
335
+ // Handle WebSocket errors
336
+ const handleError = async (error) => {
337
+ let errorMessage;
338
+ if (error instanceof Error) {
339
+ errorMessage = error.message;
218
340
  }
219
- else if (this._error) {
220
- reject(new DaytonaError(this._error));
341
+ else if (error && error instanceof Event) {
342
+ errorMessage = 'WebSocket connection error';
221
343
  }
222
344
  else {
223
- setTimeout(checkExit, 100);
345
+ errorMessage = String(error);
224
346
  }
347
+ this._error = errorMessage;
348
+ this.connected = false;
225
349
  };
226
- checkExit();
227
- });
228
- }
229
- /**
230
- * Kill the PTY process and terminate the session.
231
- *
232
- * Forcefully terminates the PTY session and its associated process.
233
- * This operation is irreversible and will cause the PTY to exit immediately.
234
- *
235
- * @throws {Error} If the kill operation fails
236
- *
237
- * @example
238
- * // Kill a long-running process
239
- * await ptyHandle.kill();
240
- *
241
- * // Wait to confirm termination
242
- * const result = await ptyHandle.wait();
243
- * console.log(`Process terminated with exit code: ${result.exitCode}`);
244
- */
245
- async kill() {
246
- return await this.handleKill();
247
- }
248
- setupWebSocketHandlers() {
249
- // Set binary type for binary data handling
250
- if ('binaryType' in this.ws) {
251
- this.ws.binaryType = 'arraybuffer';
252
- }
253
- // Handle WebSocket open
254
- const handleOpen = async () => {
255
- this.connected = true;
256
- };
257
- // Handle WebSocket messages - control messages and PTY data
258
- const handleMessage = async (event) => {
259
- try {
260
- const data = event && typeof event === 'object' && 'data' in event ? event.data : event;
261
- if (typeof data === 'string') {
262
- // Try to parse as control message first
350
+ // Handle WebSocket close - parse structured exit data
351
+ const handleClose = async (event) => {
352
+ this.connected = false;
353
+ // Parse structured exit data from close reason
354
+ if (event && event.reason) {
263
355
  try {
264
- const controlMsg = JSON.parse(data);
265
- if (controlMsg.type === 'control') {
266
- if (controlMsg.status === 'connected') {
267
- this.connectionEstablished = true;
268
- return;
269
- }
270
- else if (controlMsg.status === 'error') {
271
- this._error = controlMsg.error || 'Unknown connection error';
272
- this.connected = false;
273
- return;
356
+ const exitData = JSON.parse(event.reason);
357
+ if (typeof exitData.exitCode === 'number') {
358
+ this._exitCode = exitData.exitCode;
359
+ // Store exit reason if provided (undefined for exitCode 0)
360
+ if (exitData.exitReason) {
361
+ this._error = exitData.exitReason;
274
362
  }
275
363
  }
364
+ // Handle error messages from server (e.g., "PTY session not found")
365
+ if (exitData.error) {
366
+ this._error = exitData.error;
367
+ }
276
368
  }
277
369
  catch {
278
- // Not a control message, treat as PTY output
279
- }
280
- // Regular PTY text output
281
- if (this.onPty) {
282
- await this.onPty(new TextEncoder().encode(data));
370
+ if (event.code === 1000) {
371
+ this._exitCode = 0;
372
+ }
283
373
  }
284
374
  }
285
- else {
286
- // Handle binary data (terminal output)
287
- let bytes;
288
- if (data instanceof ArrayBuffer) {
289
- bytes = new Uint8Array(data);
290
- }
291
- else if (ArrayBuffer.isView(data)) {
292
- bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
293
- }
294
- else if (data instanceof Blob) {
295
- const buffer = await data.arrayBuffer();
296
- bytes = new Uint8Array(buffer);
297
- }
298
- else {
299
- throw new DaytonaError(`Unsupported message data type: ${Object.prototype.toString.call(data)}`);
300
- }
301
- if (this.onPty) {
302
- await this.onPty(bytes);
303
- }
375
+ // Default to exit code 0 if we can't parse it and it was a normal close
376
+ if (this._exitCode === undefined && event && event.code === 1000) {
377
+ this._exitCode = 0;
304
378
  }
379
+ };
380
+ // Attach event listeners based on WebSocket implementation
381
+ if (this.ws.addEventListener) {
382
+ // Browser WebSocket
383
+ this.ws.addEventListener('open', handleOpen);
384
+ this.ws.addEventListener('message', handleMessage);
385
+ this.ws.addEventListener('error', handleError);
386
+ this.ws.addEventListener('close', handleClose);
305
387
  }
306
- catch (error) {
307
- const errorMessage = error instanceof Error ? error.message : String(error);
308
- throw new DaytonaError(`Error handling PTY message: ${errorMessage}`);
309
- }
310
- };
311
- // Handle WebSocket errors
312
- const handleError = async (error) => {
313
- let errorMessage;
314
- if (error instanceof Error) {
315
- errorMessage = error.message;
316
- }
317
- else if (error && error instanceof Event) {
318
- errorMessage = 'WebSocket connection error';
388
+ else if ('on' in this.ws && typeof this.ws.on === 'function') {
389
+ // Node.js WebSocket
390
+ this.ws.on('open', handleOpen);
391
+ this.ws.on('message', handleMessage);
392
+ this.ws.on('error', handleError);
393
+ this.ws.on('close', handleClose);
319
394
  }
320
395
  else {
321
- errorMessage = String(error);
396
+ throw new DaytonaError('Unsupported WebSocket implementation');
322
397
  }
323
- this._error = errorMessage;
324
- this.connected = false;
325
- };
326
- // Handle WebSocket close - parse structured exit data
327
- const handleClose = async (event) => {
328
- this.connected = false;
329
- // Parse structured exit data from close reason
330
- if (event && event.reason) {
331
- try {
332
- const exitData = JSON.parse(event.reason);
333
- if (typeof exitData.exitCode === 'number') {
334
- this._exitCode = exitData.exitCode;
335
- // Store exit reason if provided (undefined for exitCode 0)
336
- if (exitData.exitReason) {
337
- this._error = exitData.exitReason;
338
- }
339
- }
340
- // Handle error messages from server (e.g., "PTY session not found")
341
- if (exitData.error) {
342
- this._error = exitData.error;
343
- }
344
- }
345
- catch {
346
- if (event.code === 1000) {
347
- this._exitCode = 0;
348
- }
349
- }
350
- }
351
- // Default to exit code 0 if we can't parse it and it was a normal close
352
- if (this._exitCode === undefined && event && event.code === 1000) {
353
- this._exitCode = 0;
354
- }
355
- };
356
- // Attach event listeners based on WebSocket implementation
357
- if (this.ws.addEventListener) {
358
- // Browser WebSocket
359
- this.ws.addEventListener('open', handleOpen);
360
- this.ws.addEventListener('message', handleMessage);
361
- this.ws.addEventListener('error', handleError);
362
- this.ws.addEventListener('close', handleClose);
363
- }
364
- else if ('on' in this.ws && typeof this.ws.on === 'function') {
365
- // Node.js WebSocket
366
- this.ws.on('open', handleOpen);
367
- this.ws.on('message', handleMessage);
368
- this.ws.on('error', handleError);
369
- this.ws.on('close', handleClose);
370
- }
371
- else {
372
- throw new DaytonaError('Unsupported WebSocket implementation');
373
398
  }
374
- }
375
- }
376
- __decorate([
377
- WithInstrumentation(),
378
- __metadata("design:type", Function),
379
- __metadata("design:paramtypes", []),
380
- __metadata("design:returntype", Promise)
381
- ], PtyHandle.prototype, "waitForConnection", null);
382
- __decorate([
383
- WithInstrumentation(),
384
- __metadata("design:type", Function),
385
- __metadata("design:paramtypes", [Object]),
386
- __metadata("design:returntype", Promise)
387
- ], PtyHandle.prototype, "sendInput", null);
388
- __decorate([
389
- WithInstrumentation(),
390
- __metadata("design:type", Function),
391
- __metadata("design:paramtypes", [Number, Number]),
392
- __metadata("design:returntype", Promise)
393
- ], PtyHandle.prototype, "resize", null);
394
- __decorate([
395
- WithInstrumentation(),
396
- __metadata("design:type", Function),
397
- __metadata("design:paramtypes", []),
398
- __metadata("design:returntype", Promise)
399
- ], PtyHandle.prototype, "disconnect", null);
400
- __decorate([
401
- WithInstrumentation(),
402
- __metadata("design:type", Function),
403
- __metadata("design:paramtypes", []),
404
- __metadata("design:returntype", Promise)
405
- ], PtyHandle.prototype, "wait", null);
406
- __decorate([
407
- WithInstrumentation(),
408
- __metadata("design:type", Function),
409
- __metadata("design:paramtypes", []),
410
- __metadata("design:returntype", Promise)
411
- ], PtyHandle.prototype, "kill", null);
399
+ };
400
+ })();
401
+ export { PtyHandle };
412
402
  //# sourceMappingURL=PtyHandle.js.map