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