lit-shell.js 0.1.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/dist/client/browser-bundle.js +240 -4
- package/dist/client/browser-bundle.js.map +2 -2
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/terminal-client.d.ts +78 -3
- package/dist/client/terminal-client.d.ts.map +1 -1
- package/dist/client/terminal-client.js +237 -4
- package/dist/client/terminal-client.js.map +1 -1
- package/dist/server/circular-buffer.d.ts +55 -0
- package/dist/server/circular-buffer.d.ts.map +1 -0
- package/dist/server/circular-buffer.js +91 -0
- package/dist/server/circular-buffer.js.map +1 -0
- package/dist/server/index.d.ts +4 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/session-manager.d.ts +195 -0
- package/dist/server/session-manager.d.ts.map +1 -0
- package/dist/server/session-manager.js +448 -0
- package/dist/server/session-manager.js.map +1 -0
- package/dist/server/terminal-server.d.ts +75 -5
- package/dist/server/terminal-server.d.ts.map +1 -1
- package/dist/server/terminal-server.js +496 -79
- package/dist/server/terminal-server.js.map +1 -1
- package/dist/shared/types.d.ts +179 -2
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/ui/browser-bundle.js +240 -4
- package/dist/ui/browser-bundle.js.map +3 -3
- package/package.json +9 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.1.0] - 2025-01-09
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Tabbed Terminals**: New `show-tabs` attribute enables multiple terminal tabs in a single component
|
|
13
|
+
- Each tab has independent WebSocket connection and terminal session
|
|
14
|
+
- Tab bar with status indicators and add/close buttons
|
|
15
|
+
- Dynamic labels showing shell or container name
|
|
16
|
+
- `createTab()`, `switchTab()`, `closeTab()` methods
|
|
17
|
+
- **Join Existing Session**: Connection panel now shows "Join Existing Session" mode when sessions are available
|
|
18
|
+
- **Prompt Refresh on Join**: Joining a session now triggers a fresh prompt display
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Fixed duplicate output when multiple tabs join the same session
|
|
23
|
+
- Fixed session list not updating after spawning a session
|
|
24
|
+
- Each client's data handler now correctly writes to its own tab's terminal
|
|
25
|
+
|
|
26
|
+
## [1.0.0] - 2025-01-08
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- Initial release
|
|
31
|
+
- WebSocket-based terminal server with node-pty
|
|
32
|
+
- Lightweight client library with auto-reconnection
|
|
33
|
+
- `<lit-shell-terminal>` Lit web component with xterm.js
|
|
34
|
+
- Docker exec support for connecting to containers
|
|
35
|
+
- Docker attach mode for connecting to container's main process (PID 1)
|
|
36
|
+
- Session multiplexing - multiple clients sharing the same terminal
|
|
37
|
+
- Session persistence with configurable orphan timeout
|
|
38
|
+
- History replay for clients joining existing sessions
|
|
39
|
+
- Built-in connection panel with container/shell selector
|
|
40
|
+
- Settings dropdown (theme, font size)
|
|
41
|
+
- Status bar with connection info
|
|
42
|
+
- Dark/light/auto theme support
|
|
43
|
+
- Security features: shell, path, and container allowlists
|
|
44
|
+
- Python client bindings (`bindings/python/`)
|
|
45
|
+
- Example projects for Docker containers and multiplexing
|
|
@@ -5,6 +5,7 @@ var TerminalClient = class {
|
|
|
5
5
|
this.state = "disconnected";
|
|
6
6
|
this.sessionId = null;
|
|
7
7
|
this.sessionInfo = null;
|
|
8
|
+
this.serverInfo = null;
|
|
8
9
|
this.reconnectAttempts = 0;
|
|
9
10
|
this.reconnectTimeout = null;
|
|
10
11
|
// Event handlers
|
|
@@ -14,9 +15,21 @@ var TerminalClient = class {
|
|
|
14
15
|
this.exitHandlers = [];
|
|
15
16
|
this.errorHandlers = [];
|
|
16
17
|
this.spawnedHandlers = [];
|
|
17
|
-
|
|
18
|
+
this.serverInfoHandlers = [];
|
|
19
|
+
this.containerListHandlers = [];
|
|
20
|
+
// Session multiplexing handlers
|
|
21
|
+
this.sessionListHandlers = [];
|
|
22
|
+
this.joinedHandlers = [];
|
|
23
|
+
this.leftHandlers = [];
|
|
24
|
+
this.clientJoinedHandlers = [];
|
|
25
|
+
this.clientLeftHandlers = [];
|
|
26
|
+
this.sessionClosedHandlers = [];
|
|
27
|
+
// Promise resolvers for spawn/join
|
|
18
28
|
this.spawnResolve = null;
|
|
19
29
|
this.spawnReject = null;
|
|
30
|
+
this.joinResolve = null;
|
|
31
|
+
this.joinReject = null;
|
|
32
|
+
this.listSessionsResolve = null;
|
|
20
33
|
this.config = {
|
|
21
34
|
url: config.url,
|
|
22
35
|
reconnect: config.reconnect ?? true,
|
|
@@ -123,7 +136,8 @@ var TerminalClient = class {
|
|
|
123
136
|
cwd: message.cwd,
|
|
124
137
|
cols: message.cols,
|
|
125
138
|
rows: message.rows,
|
|
126
|
-
createdAt: /* @__PURE__ */ new Date()
|
|
139
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
140
|
+
container: message.container
|
|
127
141
|
};
|
|
128
142
|
this.spawnedHandlers.forEach((handler) => handler(this.sessionInfo));
|
|
129
143
|
if (this.spawnResolve) {
|
|
@@ -149,6 +163,76 @@ var TerminalClient = class {
|
|
|
149
163
|
this.spawnResolve = null;
|
|
150
164
|
this.spawnReject = null;
|
|
151
165
|
}
|
|
166
|
+
if (this.joinReject) {
|
|
167
|
+
this.joinReject(error);
|
|
168
|
+
this.joinResolve = null;
|
|
169
|
+
this.joinReject = null;
|
|
170
|
+
}
|
|
171
|
+
break;
|
|
172
|
+
case "serverInfo":
|
|
173
|
+
this.serverInfo = message.info;
|
|
174
|
+
this.serverInfoHandlers.forEach((handler) => handler(message.info));
|
|
175
|
+
break;
|
|
176
|
+
case "containerList":
|
|
177
|
+
this.containerListHandlers.forEach((handler) => handler(message.containers));
|
|
178
|
+
break;
|
|
179
|
+
case "sessionList":
|
|
180
|
+
this.sessionListHandlers.forEach(
|
|
181
|
+
(handler) => handler(message.sessions)
|
|
182
|
+
);
|
|
183
|
+
if (this.listSessionsResolve) {
|
|
184
|
+
this.listSessionsResolve(message.sessions);
|
|
185
|
+
this.listSessionsResolve = null;
|
|
186
|
+
}
|
|
187
|
+
break;
|
|
188
|
+
case "joined":
|
|
189
|
+
const joinedSession = message.session;
|
|
190
|
+
const history = message.history;
|
|
191
|
+
this.sessionId = message.sessionId;
|
|
192
|
+
this.sessionInfo = {
|
|
193
|
+
sessionId: joinedSession.sessionId,
|
|
194
|
+
shell: joinedSession.shell,
|
|
195
|
+
cwd: joinedSession.cwd,
|
|
196
|
+
cols: joinedSession.cols,
|
|
197
|
+
rows: joinedSession.rows,
|
|
198
|
+
createdAt: joinedSession.createdAt,
|
|
199
|
+
container: joinedSession.container
|
|
200
|
+
};
|
|
201
|
+
this.joinedHandlers.forEach((handler) => handler(joinedSession, history));
|
|
202
|
+
if (this.joinResolve) {
|
|
203
|
+
this.joinResolve(joinedSession);
|
|
204
|
+
this.joinResolve = null;
|
|
205
|
+
this.joinReject = null;
|
|
206
|
+
}
|
|
207
|
+
break;
|
|
208
|
+
case "left":
|
|
209
|
+
const leftSessionId = message.sessionId;
|
|
210
|
+
if (this.sessionId === leftSessionId) {
|
|
211
|
+
this.sessionId = null;
|
|
212
|
+
this.sessionInfo = null;
|
|
213
|
+
}
|
|
214
|
+
this.leftHandlers.forEach((handler) => handler(leftSessionId));
|
|
215
|
+
break;
|
|
216
|
+
case "clientJoined":
|
|
217
|
+
this.clientJoinedHandlers.forEach(
|
|
218
|
+
(handler) => handler(message.sessionId, message.clientCount)
|
|
219
|
+
);
|
|
220
|
+
break;
|
|
221
|
+
case "clientLeft":
|
|
222
|
+
this.clientLeftHandlers.forEach(
|
|
223
|
+
(handler) => handler(message.sessionId, message.clientCount)
|
|
224
|
+
);
|
|
225
|
+
break;
|
|
226
|
+
case "sessionClosed":
|
|
227
|
+
const closedSessionId = message.sessionId;
|
|
228
|
+
const reason = message.reason;
|
|
229
|
+
if (this.sessionId === closedSessionId) {
|
|
230
|
+
this.sessionId = null;
|
|
231
|
+
this.sessionInfo = null;
|
|
232
|
+
}
|
|
233
|
+
this.sessionClosedHandlers.forEach(
|
|
234
|
+
(handler) => handler(closedSessionId, reason)
|
|
235
|
+
);
|
|
152
236
|
break;
|
|
153
237
|
}
|
|
154
238
|
}
|
|
@@ -162,7 +246,7 @@ var TerminalClient = class {
|
|
|
162
246
|
return;
|
|
163
247
|
}
|
|
164
248
|
if (this.sessionId) {
|
|
165
|
-
reject(new Error("Session already
|
|
249
|
+
reject(new Error("Session already active. Call kill() or leave() first."));
|
|
166
250
|
return;
|
|
167
251
|
}
|
|
168
252
|
this.spawnResolve = resolve;
|
|
@@ -217,7 +301,7 @@ var TerminalClient = class {
|
|
|
217
301
|
);
|
|
218
302
|
}
|
|
219
303
|
/**
|
|
220
|
-
* Kill the terminal session
|
|
304
|
+
* Kill the terminal session (close and terminate)
|
|
221
305
|
*/
|
|
222
306
|
kill() {
|
|
223
307
|
if (!this.ws || this.state !== "connected") {
|
|
@@ -236,6 +320,91 @@ var TerminalClient = class {
|
|
|
236
320
|
this.sessionInfo = null;
|
|
237
321
|
}
|
|
238
322
|
// ==========================================
|
|
323
|
+
// Session Multiplexing Methods
|
|
324
|
+
// ==========================================
|
|
325
|
+
/**
|
|
326
|
+
* List available sessions
|
|
327
|
+
*/
|
|
328
|
+
listSessions(filter) {
|
|
329
|
+
return new Promise((resolve, reject) => {
|
|
330
|
+
if (this.state !== "connected" || !this.ws) {
|
|
331
|
+
reject(new Error("Not connected to server"));
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
this.listSessionsResolve = resolve;
|
|
335
|
+
this.ws.send(
|
|
336
|
+
JSON.stringify({
|
|
337
|
+
type: "listSessions",
|
|
338
|
+
filter
|
|
339
|
+
})
|
|
340
|
+
);
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Join an existing session
|
|
345
|
+
*/
|
|
346
|
+
join(options) {
|
|
347
|
+
return new Promise((resolve, reject) => {
|
|
348
|
+
if (this.state !== "connected" || !this.ws) {
|
|
349
|
+
reject(new Error("Not connected to server"));
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
if (this.sessionId) {
|
|
353
|
+
reject(new Error("Already in a session. Call leave() first."));
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
this.joinResolve = resolve;
|
|
357
|
+
this.joinReject = reject;
|
|
358
|
+
this.ws.send(
|
|
359
|
+
JSON.stringify({
|
|
360
|
+
type: "join",
|
|
361
|
+
options
|
|
362
|
+
})
|
|
363
|
+
);
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Leave the current session without killing it
|
|
368
|
+
*/
|
|
369
|
+
leave(sessionId) {
|
|
370
|
+
if (!this.ws || this.state !== "connected") {
|
|
371
|
+
console.error("[lit-shell] Cannot leave: not connected");
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
const targetSession = sessionId || this.sessionId;
|
|
375
|
+
if (!targetSession) {
|
|
376
|
+
console.error("[lit-shell] Cannot leave: no active session");
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
this.ws.send(
|
|
380
|
+
JSON.stringify({
|
|
381
|
+
type: "leave",
|
|
382
|
+
sessionId: targetSession
|
|
383
|
+
})
|
|
384
|
+
);
|
|
385
|
+
if (targetSession === this.sessionId) {
|
|
386
|
+
this.sessionId = null;
|
|
387
|
+
this.sessionInfo = null;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Request session list and trigger onSessionList handlers
|
|
392
|
+
* (Fire-and-forget version of listSessions)
|
|
393
|
+
*/
|
|
394
|
+
requestSessionList(filter) {
|
|
395
|
+
this.listSessions(filter).then((sessions) => {
|
|
396
|
+
this.sessionListHandlers.forEach((handler) => {
|
|
397
|
+
try {
|
|
398
|
+
handler(sessions);
|
|
399
|
+
} catch (e) {
|
|
400
|
+
console.error("[lit-shell] Error in sessionList handler:", e);
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
}).catch((err) => {
|
|
404
|
+
console.error("[lit-shell] Failed to list sessions:", err);
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
// ==========================================
|
|
239
408
|
// Event handlers
|
|
240
409
|
// ==========================================
|
|
241
410
|
/**
|
|
@@ -274,6 +443,67 @@ var TerminalClient = class {
|
|
|
274
443
|
onSpawned(handler) {
|
|
275
444
|
this.spawnedHandlers.push(handler);
|
|
276
445
|
}
|
|
446
|
+
/**
|
|
447
|
+
* Called when server info is received
|
|
448
|
+
*/
|
|
449
|
+
onServerInfo(handler) {
|
|
450
|
+
this.serverInfoHandlers.push(handler);
|
|
451
|
+
if (this.serverInfo) {
|
|
452
|
+
handler(this.serverInfo);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Called when container list is received
|
|
457
|
+
*/
|
|
458
|
+
onContainerList(handler) {
|
|
459
|
+
this.containerListHandlers.push(handler);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Called when session list is received
|
|
463
|
+
*/
|
|
464
|
+
onSessionList(handler) {
|
|
465
|
+
this.sessionListHandlers.push(handler);
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Called when successfully joined a session
|
|
469
|
+
*/
|
|
470
|
+
onJoined(handler) {
|
|
471
|
+
this.joinedHandlers.push(handler);
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Called when left a session
|
|
475
|
+
*/
|
|
476
|
+
onLeft(handler) {
|
|
477
|
+
this.leftHandlers.push(handler);
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Called when another client joins the current session
|
|
481
|
+
*/
|
|
482
|
+
onClientJoined(handler) {
|
|
483
|
+
this.clientJoinedHandlers.push(handler);
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Called when another client leaves the current session
|
|
487
|
+
*/
|
|
488
|
+
onClientLeft(handler) {
|
|
489
|
+
this.clientLeftHandlers.push(handler);
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Called when the session is closed by owner or orphan timeout
|
|
493
|
+
*/
|
|
494
|
+
onSessionClosed(handler) {
|
|
495
|
+
this.sessionClosedHandlers.push(handler);
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Request list of available containers
|
|
499
|
+
*/
|
|
500
|
+
requestContainerList() {
|
|
501
|
+
if (!this.ws || this.state !== "connected") {
|
|
502
|
+
console.error("[lit-shell] Cannot request containers: not connected");
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
this.ws.send(JSON.stringify({ type: "listContainers" }));
|
|
506
|
+
}
|
|
277
507
|
// ==========================================
|
|
278
508
|
// Getters
|
|
279
509
|
// ==========================================
|
|
@@ -307,6 +537,12 @@ var TerminalClient = class {
|
|
|
307
537
|
hasActiveSession() {
|
|
308
538
|
return this.sessionId !== null;
|
|
309
539
|
}
|
|
540
|
+
/**
|
|
541
|
+
* Get server info
|
|
542
|
+
*/
|
|
543
|
+
getServerInfo() {
|
|
544
|
+
return this.serverInfo;
|
|
545
|
+
}
|
|
310
546
|
};
|
|
311
547
|
export {
|
|
312
548
|
TerminalClient
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/client/terminal-client.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Terminal client for connecting to lit-shell server\n *\n * Example usage:\n * ```typescript\n * import { TerminalClient } from 'lit-shell.js/client';\n *\n * const client = new TerminalClient({ url: 'ws://localhost:3000/terminal' });\n * await client.connect();\n *\n * client.onData((data) => console.log(data));\n * client.onExit((code) => console.log('Exited with code:', code));\n *\n * await client.spawn({ shell: '/bin/bash', cwd: '/home/user' });\n * client.write('ls -la\\n');\n * client.resize(120, 40);\n * client.kill();\n * ```\n */\n\nimport type {\n ClientConfig,\n TerminalOptions,\n TerminalMessage,\n SessionInfo,\n} from '../shared/types.js';\n\n/**\n * Connection state\n */\nexport type ConnectionState = 'disconnected' | 'connecting' | 'connected';\n\n/**\n * Terminal client class\n */\nexport class TerminalClient {\n private config: Required<ClientConfig>;\n private ws: WebSocket | null = null;\n private state: ConnectionState = 'disconnected';\n private sessionId: string | null = null;\n private sessionInfo: SessionInfo | null = null;\n private reconnectAttempts = 0;\n private reconnectTimeout: ReturnType<typeof setTimeout> | null = null;\n\n // Event handlers\n private connectHandlers: (() => void)[] = [];\n private disconnectHandlers: (() => void)[] = [];\n private dataHandlers: ((data: string) => void)[] = [];\n private exitHandlers: ((code: number) => void)[] = [];\n private errorHandlers: ((error: Error) => void)[] = [];\n private spawnedHandlers: ((info: SessionInfo) => void)[] = [];\n\n // Promise resolvers for spawn\n private spawnResolve: ((info: SessionInfo) => void) | null = null;\n private spawnReject: ((error: Error) => void) | null = null;\n\n constructor(config: ClientConfig) {\n this.config = {\n url: config.url,\n reconnect: config.reconnect ?? true,\n maxReconnectAttempts: config.maxReconnectAttempts ?? 10,\n reconnectDelay: config.reconnectDelay ?? 1000,\n };\n }\n\n /**\n * Connect to the terminal server\n */\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.state === 'connected') {\n resolve();\n return;\n }\n\n this.state = 'connecting';\n\n try {\n this.ws = new WebSocket(this.config.url);\n } catch (error) {\n this.state = 'disconnected';\n reject(error);\n return;\n }\n\n this.ws.onopen = () => {\n this.state = 'connected';\n this.reconnectAttempts = 0;\n this.connectHandlers.forEach((handler) => handler());\n resolve();\n };\n\n this.ws.onclose = () => {\n const wasConnected = this.state === 'connected';\n this.state = 'disconnected';\n this.sessionId = null;\n this.sessionInfo = null;\n\n if (wasConnected) {\n this.disconnectHandlers.forEach((handler) => handler());\n }\n\n // Attempt reconnection\n if (this.config.reconnect && this.reconnectAttempts < this.config.maxReconnectAttempts) {\n this.scheduleReconnect();\n }\n };\n\n this.ws.onerror = (event) => {\n const error = new Error('WebSocket error');\n this.errorHandlers.forEach((handler) => handler(error));\n\n if (this.state === 'connecting') {\n reject(error);\n }\n };\n\n this.ws.onmessage = (event) => {\n this.handleMessage(event.data);\n };\n });\n }\n\n /**\n * Disconnect from the terminal server\n */\n disconnect(): void {\n this.config.reconnect = false; // Prevent auto-reconnect\n\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n\n this.state = 'disconnected';\n this.sessionId = null;\n this.sessionInfo = null;\n }\n\n /**\n * Schedule a reconnection attempt\n */\n private scheduleReconnect(): void {\n if (this.reconnectTimeout) return;\n\n const delay = this.config.reconnectDelay * Math.pow(2, this.reconnectAttempts);\n const maxDelay = 30000; // 30 seconds max\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = null;\n this.reconnectAttempts++;\n this.connect().catch(() => {\n // Error handled by onclose\n });\n }, Math.min(delay, maxDelay));\n }\n\n /**\n * Handle incoming message\n */\n private handleMessage(data: string): void {\n let message: TerminalMessage;\n\n try {\n message = JSON.parse(data);\n } catch {\n console.error('[lit-shell] Invalid message:', data);\n return;\n }\n\n switch (message.type) {\n case 'spawned':\n this.sessionId = message.sessionId;\n this.sessionInfo = {\n sessionId: message.sessionId,\n shell: message.shell,\n cwd: message.cwd,\n cols: message.cols,\n rows: message.rows,\n createdAt: new Date(),\n };\n this.spawnedHandlers.forEach((handler) => handler(this.sessionInfo!));\n if (this.spawnResolve) {\n this.spawnResolve(this.sessionInfo);\n this.spawnResolve = null;\n this.spawnReject = null;\n }\n break;\n\n case 'data':\n this.dataHandlers.forEach((handler) => handler(message.data));\n break;\n\n case 'exit':\n const exitCode = message.exitCode;\n this.exitHandlers.forEach((handler) => handler(exitCode));\n this.sessionId = null;\n this.sessionInfo = null;\n break;\n\n case 'error':\n const error = new Error(message.error);\n this.errorHandlers.forEach((handler) => handler(error));\n if (this.spawnReject) {\n this.spawnReject(error);\n this.spawnResolve = null;\n this.spawnReject = null;\n }\n break;\n }\n }\n\n /**\n * Spawn a terminal session\n */\n spawn(options: TerminalOptions = {}): Promise<SessionInfo> {\n return new Promise((resolve, reject) => {\n if (this.state !== 'connected' || !this.ws) {\n reject(new Error('Not connected to server'));\n return;\n }\n\n if (this.sessionId) {\n reject(new Error('Session already spawned. Call kill() first.'));\n return;\n }\n\n this.spawnResolve = resolve;\n this.spawnReject = reject;\n\n this.ws.send(\n JSON.stringify({\n type: 'spawn',\n options,\n })\n );\n });\n }\n\n /**\n * Write data to the terminal\n */\n write(data: string): void {\n if (!this.ws || this.state !== 'connected') {\n console.error('[lit-shell] Cannot write: not connected');\n return;\n }\n\n if (!this.sessionId) {\n console.error('[lit-shell] Cannot write: no active session');\n return;\n }\n\n this.ws.send(\n JSON.stringify({\n type: 'data',\n sessionId: this.sessionId,\n data,\n })\n );\n }\n\n /**\n * Resize the terminal\n */\n resize(cols: number, rows: number): void {\n if (!this.ws || this.state !== 'connected') {\n console.error('[lit-shell] Cannot resize: not connected');\n return;\n }\n\n if (!this.sessionId) {\n console.error('[lit-shell] Cannot resize: no active session');\n return;\n }\n\n this.ws.send(\n JSON.stringify({\n type: 'resize',\n sessionId: this.sessionId,\n cols,\n rows,\n })\n );\n }\n\n /**\n * Kill the terminal session\n */\n kill(): void {\n if (!this.ws || this.state !== 'connected') {\n return;\n }\n\n if (!this.sessionId) {\n return;\n }\n\n this.ws.send(\n JSON.stringify({\n type: 'close',\n sessionId: this.sessionId,\n })\n );\n\n this.sessionId = null;\n this.sessionInfo = null;\n }\n\n // ==========================================\n // Event handlers\n // ==========================================\n\n /**\n * Called when connected to server\n */\n onConnect(handler: () => void): void {\n this.connectHandlers.push(handler);\n }\n\n /**\n * Called when disconnected from server\n */\n onDisconnect(handler: () => void): void {\n this.disconnectHandlers.push(handler);\n }\n\n /**\n * Called when data is received from the terminal\n */\n onData(handler: (data: string) => void): void {\n this.dataHandlers.push(handler);\n }\n\n /**\n * Called when the terminal session exits\n */\n onExit(handler: (code: number) => void): void {\n this.exitHandlers.push(handler);\n }\n\n /**\n * Called when an error occurs\n */\n onError(handler: (error: Error) => void): void {\n this.errorHandlers.push(handler);\n }\n\n /**\n * Called when a session is spawned\n */\n onSpawned(handler: (info: SessionInfo) => void): void {\n this.spawnedHandlers.push(handler);\n }\n\n // ==========================================\n // Getters\n // ==========================================\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.state === 'connected';\n }\n\n /**\n * Get current session ID\n */\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n /**\n * Get current session info\n */\n getSessionInfo(): SessionInfo | null {\n return this.sessionInfo;\n }\n\n /**\n * Check if a session is active\n */\n hasActiveSession(): boolean {\n return this.sessionId !== null;\n }\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["/**\n * Terminal client for connecting to lit-shell server\n *\n * Example usage:\n * ```typescript\n * import { TerminalClient } from 'lit-shell.js/client';\n *\n * const client = new TerminalClient({ url: 'ws://localhost:3000/terminal' });\n * await client.connect();\n *\n * client.onData((data) => console.log(data));\n * client.onExit((code) => console.log('Exited with code:', code));\n *\n * await client.spawn({ shell: '/bin/bash', cwd: '/home/user' });\n * client.write('ls -la\\n');\n * client.resize(120, 40);\n * client.kill();\n *\n * // Session multiplexing example\n * const sessions = await client.listSessions();\n * if (sessions.length > 0) {\n * await client.join({ sessionId: sessions[0].sessionId, requestHistory: true });\n * }\n * ```\n */\n\nimport type {\n ClientConfig,\n TerminalOptions,\n TerminalMessage,\n SessionInfo,\n ContainerInfo,\n ServerInfo,\n SharedSessionInfo,\n SessionListFilter,\n JoinSessionOptions,\n} from '../shared/types.js';\n\n/**\n * Connection state\n */\nexport type ConnectionState = 'disconnected' | 'connecting' | 'connected';\n\n/**\n * Terminal client class with session multiplexing support\n */\nexport class TerminalClient {\n private config: Required<ClientConfig>;\n private ws: WebSocket | null = null;\n private state: ConnectionState = 'disconnected';\n private sessionId: string | null = null;\n private sessionInfo: SessionInfo | null = null;\n private serverInfo: ServerInfo | null = null;\n private reconnectAttempts = 0;\n private reconnectTimeout: ReturnType<typeof setTimeout> | null = null;\n\n // Event handlers\n private connectHandlers: (() => void)[] = [];\n private disconnectHandlers: (() => void)[] = [];\n private dataHandlers: ((data: string) => void)[] = [];\n private exitHandlers: ((code: number) => void)[] = [];\n private errorHandlers: ((error: Error) => void)[] = [];\n private spawnedHandlers: ((info: SessionInfo) => void)[] = [];\n private serverInfoHandlers: ((info: ServerInfo) => void)[] = [];\n private containerListHandlers: ((containers: ContainerInfo[]) => void)[] = [];\n // Session multiplexing handlers\n private sessionListHandlers: ((sessions: SharedSessionInfo[]) => void)[] = [];\n private joinedHandlers: ((session: SharedSessionInfo, history?: string) => void)[] = [];\n private leftHandlers: ((sessionId: string) => void)[] = [];\n private clientJoinedHandlers: ((sessionId: string, clientCount: number) => void)[] = [];\n private clientLeftHandlers: ((sessionId: string, clientCount: number) => void)[] = [];\n private sessionClosedHandlers: ((sessionId: string, reason: string) => void)[] = [];\n\n // Promise resolvers for spawn/join\n private spawnResolve: ((info: SessionInfo) => void) | null = null;\n private spawnReject: ((error: Error) => void) | null = null;\n private joinResolve: ((info: SharedSessionInfo) => void) | null = null;\n private joinReject: ((error: Error) => void) | null = null;\n private listSessionsResolve: ((sessions: SharedSessionInfo[]) => void) | null = null;\n\n constructor(config: ClientConfig) {\n this.config = {\n url: config.url,\n reconnect: config.reconnect ?? true,\n maxReconnectAttempts: config.maxReconnectAttempts ?? 10,\n reconnectDelay: config.reconnectDelay ?? 1000,\n };\n }\n\n /**\n * Connect to the terminal server\n */\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.state === 'connected') {\n resolve();\n return;\n }\n\n this.state = 'connecting';\n\n try {\n this.ws = new WebSocket(this.config.url);\n } catch (error) {\n this.state = 'disconnected';\n reject(error);\n return;\n }\n\n this.ws.onopen = () => {\n this.state = 'connected';\n this.reconnectAttempts = 0;\n this.connectHandlers.forEach((handler) => handler());\n resolve();\n };\n\n this.ws.onclose = () => {\n const wasConnected = this.state === 'connected';\n this.state = 'disconnected';\n this.sessionId = null;\n this.sessionInfo = null;\n\n if (wasConnected) {\n this.disconnectHandlers.forEach((handler) => handler());\n }\n\n // Attempt reconnection\n if (this.config.reconnect && this.reconnectAttempts < this.config.maxReconnectAttempts) {\n this.scheduleReconnect();\n }\n };\n\n this.ws.onerror = (event) => {\n const error = new Error('WebSocket error');\n this.errorHandlers.forEach((handler) => handler(error));\n\n if (this.state === 'connecting') {\n reject(error);\n }\n };\n\n this.ws.onmessage = (event) => {\n this.handleMessage(event.data);\n };\n });\n }\n\n /**\n * Disconnect from the terminal server\n */\n disconnect(): void {\n this.config.reconnect = false; // Prevent auto-reconnect\n\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n\n this.state = 'disconnected';\n this.sessionId = null;\n this.sessionInfo = null;\n }\n\n /**\n * Schedule a reconnection attempt\n */\n private scheduleReconnect(): void {\n if (this.reconnectTimeout) return;\n\n const delay = this.config.reconnectDelay * Math.pow(2, this.reconnectAttempts);\n const maxDelay = 30000; // 30 seconds max\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = null;\n this.reconnectAttempts++;\n this.connect().catch(() => {\n // Error handled by onclose\n });\n }, Math.min(delay, maxDelay));\n }\n\n /**\n * Handle incoming message\n */\n private handleMessage(data: string): void {\n let message: TerminalMessage;\n\n try {\n message = JSON.parse(data);\n } catch {\n console.error('[lit-shell] Invalid message:', data);\n return;\n }\n\n switch (message.type) {\n case 'spawned':\n this.sessionId = message.sessionId;\n this.sessionInfo = {\n sessionId: message.sessionId,\n shell: message.shell,\n cwd: message.cwd,\n cols: message.cols,\n rows: message.rows,\n createdAt: new Date(),\n container: message.container,\n };\n this.spawnedHandlers.forEach((handler) => handler(this.sessionInfo!));\n if (this.spawnResolve) {\n this.spawnResolve(this.sessionInfo);\n this.spawnResolve = null;\n this.spawnReject = null;\n }\n break;\n\n case 'data':\n this.dataHandlers.forEach((handler) => handler(message.data));\n break;\n\n case 'exit':\n const exitCode = message.exitCode;\n this.exitHandlers.forEach((handler) => handler(exitCode));\n this.sessionId = null;\n this.sessionInfo = null;\n break;\n\n case 'error':\n const error = new Error(message.error);\n this.errorHandlers.forEach((handler) => handler(error));\n if (this.spawnReject) {\n this.spawnReject(error);\n this.spawnResolve = null;\n this.spawnReject = null;\n }\n if (this.joinReject) {\n this.joinReject(error);\n this.joinResolve = null;\n this.joinReject = null;\n }\n break;\n\n case 'serverInfo':\n this.serverInfo = message.info;\n this.serverInfoHandlers.forEach((handler) => handler(message.info));\n break;\n\n case 'containerList':\n this.containerListHandlers.forEach((handler) => handler(message.containers));\n break;\n\n // Session multiplexing messages\n case 'sessionList':\n this.sessionListHandlers.forEach((handler) =>\n handler((message as any).sessions)\n );\n if (this.listSessionsResolve) {\n this.listSessionsResolve((message as any).sessions);\n this.listSessionsResolve = null;\n }\n break;\n\n case 'joined':\n const joinedSession = (message as any).session as SharedSessionInfo;\n const history = (message as any).history as string | undefined;\n this.sessionId = message.sessionId!;\n this.sessionInfo = {\n sessionId: joinedSession.sessionId,\n shell: joinedSession.shell,\n cwd: joinedSession.cwd,\n cols: joinedSession.cols,\n rows: joinedSession.rows,\n createdAt: joinedSession.createdAt,\n container: joinedSession.container,\n };\n this.joinedHandlers.forEach((handler) => handler(joinedSession, history));\n if (this.joinResolve) {\n this.joinResolve(joinedSession);\n this.joinResolve = null;\n this.joinReject = null;\n }\n break;\n\n case 'left':\n const leftSessionId = message.sessionId!;\n if (this.sessionId === leftSessionId) {\n this.sessionId = null;\n this.sessionInfo = null;\n }\n this.leftHandlers.forEach((handler) => handler(leftSessionId));\n break;\n\n case 'clientJoined':\n this.clientJoinedHandlers.forEach((handler) =>\n handler(message.sessionId!, (message as any).clientCount)\n );\n break;\n\n case 'clientLeft':\n this.clientLeftHandlers.forEach((handler) =>\n handler(message.sessionId!, (message as any).clientCount)\n );\n break;\n\n case 'sessionClosed':\n const closedSessionId = message.sessionId!;\n const reason = (message as any).reason as string;\n if (this.sessionId === closedSessionId) {\n this.sessionId = null;\n this.sessionInfo = null;\n }\n this.sessionClosedHandlers.forEach((handler) =>\n handler(closedSessionId, reason)\n );\n break;\n }\n }\n\n /**\n * Spawn a terminal session\n */\n spawn(options: TerminalOptions = {}): Promise<SessionInfo> {\n return new Promise((resolve, reject) => {\n if (this.state !== 'connected' || !this.ws) {\n reject(new Error('Not connected to server'));\n return;\n }\n\n if (this.sessionId) {\n reject(new Error('Session already active. Call kill() or leave() first.'));\n return;\n }\n\n this.spawnResolve = resolve;\n this.spawnReject = reject;\n\n this.ws.send(\n JSON.stringify({\n type: 'spawn',\n options,\n })\n );\n });\n }\n\n /**\n * Write data to the terminal\n */\n write(data: string): void {\n if (!this.ws || this.state !== 'connected') {\n console.error('[lit-shell] Cannot write: not connected');\n return;\n }\n\n if (!this.sessionId) {\n console.error('[lit-shell] Cannot write: no active session');\n return;\n }\n\n this.ws.send(\n JSON.stringify({\n type: 'data',\n sessionId: this.sessionId,\n data,\n })\n );\n }\n\n /**\n * Resize the terminal\n */\n resize(cols: number, rows: number): void {\n if (!this.ws || this.state !== 'connected') {\n console.error('[lit-shell] Cannot resize: not connected');\n return;\n }\n\n if (!this.sessionId) {\n console.error('[lit-shell] Cannot resize: no active session');\n return;\n }\n\n this.ws.send(\n JSON.stringify({\n type: 'resize',\n sessionId: this.sessionId,\n cols,\n rows,\n })\n );\n }\n\n /**\n * Kill the terminal session (close and terminate)\n */\n kill(): void {\n if (!this.ws || this.state !== 'connected') {\n return;\n }\n\n if (!this.sessionId) {\n return;\n }\n\n this.ws.send(\n JSON.stringify({\n type: 'close',\n sessionId: this.sessionId,\n })\n );\n\n this.sessionId = null;\n this.sessionInfo = null;\n }\n\n // ==========================================\n // Session Multiplexing Methods\n // ==========================================\n\n /**\n * List available sessions\n */\n listSessions(filter?: SessionListFilter): Promise<SharedSessionInfo[]> {\n return new Promise((resolve, reject) => {\n if (this.state !== 'connected' || !this.ws) {\n reject(new Error('Not connected to server'));\n return;\n }\n\n this.listSessionsResolve = resolve;\n\n this.ws.send(\n JSON.stringify({\n type: 'listSessions',\n filter,\n })\n );\n });\n }\n\n /**\n * Join an existing session\n */\n join(options: JoinSessionOptions): Promise<SharedSessionInfo> {\n return new Promise((resolve, reject) => {\n if (this.state !== 'connected' || !this.ws) {\n reject(new Error('Not connected to server'));\n return;\n }\n\n if (this.sessionId) {\n reject(new Error('Already in a session. Call leave() first.'));\n return;\n }\n\n this.joinResolve = resolve;\n this.joinReject = reject;\n\n this.ws.send(\n JSON.stringify({\n type: 'join',\n options,\n })\n );\n });\n }\n\n /**\n * Leave the current session without killing it\n */\n leave(sessionId?: string): void {\n if (!this.ws || this.state !== 'connected') {\n console.error('[lit-shell] Cannot leave: not connected');\n return;\n }\n\n const targetSession = sessionId || this.sessionId;\n if (!targetSession) {\n console.error('[lit-shell] Cannot leave: no active session');\n return;\n }\n\n this.ws.send(\n JSON.stringify({\n type: 'leave',\n sessionId: targetSession,\n })\n );\n\n if (targetSession === this.sessionId) {\n this.sessionId = null;\n this.sessionInfo = null;\n }\n }\n\n /**\n * Request session list and trigger onSessionList handlers\n * (Fire-and-forget version of listSessions)\n */\n requestSessionList(filter?: SessionListFilter): void {\n this.listSessions(filter)\n .then((sessions) => {\n this.sessionListHandlers.forEach((handler) => {\n try {\n handler(sessions);\n } catch (e) {\n console.error('[lit-shell] Error in sessionList handler:', e);\n }\n });\n })\n .catch((err) => {\n console.error('[lit-shell] Failed to list sessions:', err);\n });\n }\n\n // ==========================================\n // Event handlers\n // ==========================================\n\n /**\n * Called when connected to server\n */\n onConnect(handler: () => void): void {\n this.connectHandlers.push(handler);\n }\n\n /**\n * Called when disconnected from server\n */\n onDisconnect(handler: () => void): void {\n this.disconnectHandlers.push(handler);\n }\n\n /**\n * Called when data is received from the terminal\n */\n onData(handler: (data: string) => void): void {\n this.dataHandlers.push(handler);\n }\n\n /**\n * Called when the terminal session exits\n */\n onExit(handler: (code: number) => void): void {\n this.exitHandlers.push(handler);\n }\n\n /**\n * Called when an error occurs\n */\n onError(handler: (error: Error) => void): void {\n this.errorHandlers.push(handler);\n }\n\n /**\n * Called when a session is spawned\n */\n onSpawned(handler: (info: SessionInfo) => void): void {\n this.spawnedHandlers.push(handler);\n }\n\n /**\n * Called when server info is received\n */\n onServerInfo(handler: (info: ServerInfo) => void): void {\n this.serverInfoHandlers.push(handler);\n // If we already have server info, call immediately\n if (this.serverInfo) {\n handler(this.serverInfo);\n }\n }\n\n /**\n * Called when container list is received\n */\n onContainerList(handler: (containers: ContainerInfo[]) => void): void {\n this.containerListHandlers.push(handler);\n }\n\n /**\n * Called when session list is received\n */\n onSessionList(handler: (sessions: SharedSessionInfo[]) => void): void {\n this.sessionListHandlers.push(handler);\n }\n\n /**\n * Called when successfully joined a session\n */\n onJoined(handler: (session: SharedSessionInfo, history?: string) => void): void {\n this.joinedHandlers.push(handler);\n }\n\n /**\n * Called when left a session\n */\n onLeft(handler: (sessionId: string) => void): void {\n this.leftHandlers.push(handler);\n }\n\n /**\n * Called when another client joins the current session\n */\n onClientJoined(handler: (sessionId: string, clientCount: number) => void): void {\n this.clientJoinedHandlers.push(handler);\n }\n\n /**\n * Called when another client leaves the current session\n */\n onClientLeft(handler: (sessionId: string, clientCount: number) => void): void {\n this.clientLeftHandlers.push(handler);\n }\n\n /**\n * Called when the session is closed by owner or orphan timeout\n */\n onSessionClosed(handler: (sessionId: string, reason: string) => void): void {\n this.sessionClosedHandlers.push(handler);\n }\n\n /**\n * Request list of available containers\n */\n requestContainerList(): void {\n if (!this.ws || this.state !== 'connected') {\n console.error('[lit-shell] Cannot request containers: not connected');\n return;\n }\n\n this.ws.send(JSON.stringify({ type: 'listContainers' }));\n }\n\n // ==========================================\n // Getters\n // ==========================================\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.state === 'connected';\n }\n\n /**\n * Get current session ID\n */\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n /**\n * Get current session info\n */\n getSessionInfo(): SessionInfo | null {\n return this.sessionInfo;\n }\n\n /**\n * Check if a session is active\n */\n hasActiveSession(): boolean {\n return this.sessionId !== null;\n }\n\n /**\n * Get server info\n */\n getServerInfo(): ServerInfo | null {\n return this.serverInfo;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export { TerminalClient } from './terminal-client.js';
|
|
5
5
|
export type { ConnectionState } from './terminal-client.js';
|
|
6
|
-
export type { ClientConfig, TerminalOptions, SessionInfo, } from '../shared/types.js';
|
|
6
|
+
export type { ClientConfig, TerminalOptions, SessionInfo, SharedSessionInfo, SessionType, SessionListFilter, JoinSessionOptions, } from '../shared/types.js';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EACV,YAAY,EACZ,eAAe,EACf,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EACV,YAAY,EACZ,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC"}
|
|
@@ -15,15 +15,21 @@
|
|
|
15
15
|
* client.write('ls -la\n');
|
|
16
16
|
* client.resize(120, 40);
|
|
17
17
|
* client.kill();
|
|
18
|
+
*
|
|
19
|
+
* // Session multiplexing example
|
|
20
|
+
* const sessions = await client.listSessions();
|
|
21
|
+
* if (sessions.length > 0) {
|
|
22
|
+
* await client.join({ sessionId: sessions[0].sessionId, requestHistory: true });
|
|
23
|
+
* }
|
|
18
24
|
* ```
|
|
19
25
|
*/
|
|
20
|
-
import type { ClientConfig, TerminalOptions, SessionInfo } from '../shared/types.js';
|
|
26
|
+
import type { ClientConfig, TerminalOptions, SessionInfo, ContainerInfo, ServerInfo, SharedSessionInfo, SessionListFilter, JoinSessionOptions } from '../shared/types.js';
|
|
21
27
|
/**
|
|
22
28
|
* Connection state
|
|
23
29
|
*/
|
|
24
30
|
export type ConnectionState = 'disconnected' | 'connecting' | 'connected';
|
|
25
31
|
/**
|
|
26
|
-
* Terminal client class
|
|
32
|
+
* Terminal client class with session multiplexing support
|
|
27
33
|
*/
|
|
28
34
|
export declare class TerminalClient {
|
|
29
35
|
private config;
|
|
@@ -31,6 +37,7 @@ export declare class TerminalClient {
|
|
|
31
37
|
private state;
|
|
32
38
|
private sessionId;
|
|
33
39
|
private sessionInfo;
|
|
40
|
+
private serverInfo;
|
|
34
41
|
private reconnectAttempts;
|
|
35
42
|
private reconnectTimeout;
|
|
36
43
|
private connectHandlers;
|
|
@@ -39,8 +46,19 @@ export declare class TerminalClient {
|
|
|
39
46
|
private exitHandlers;
|
|
40
47
|
private errorHandlers;
|
|
41
48
|
private spawnedHandlers;
|
|
49
|
+
private serverInfoHandlers;
|
|
50
|
+
private containerListHandlers;
|
|
51
|
+
private sessionListHandlers;
|
|
52
|
+
private joinedHandlers;
|
|
53
|
+
private leftHandlers;
|
|
54
|
+
private clientJoinedHandlers;
|
|
55
|
+
private clientLeftHandlers;
|
|
56
|
+
private sessionClosedHandlers;
|
|
42
57
|
private spawnResolve;
|
|
43
58
|
private spawnReject;
|
|
59
|
+
private joinResolve;
|
|
60
|
+
private joinReject;
|
|
61
|
+
private listSessionsResolve;
|
|
44
62
|
constructor(config: ClientConfig);
|
|
45
63
|
/**
|
|
46
64
|
* Connect to the terminal server
|
|
@@ -71,9 +89,26 @@ export declare class TerminalClient {
|
|
|
71
89
|
*/
|
|
72
90
|
resize(cols: number, rows: number): void;
|
|
73
91
|
/**
|
|
74
|
-
* Kill the terminal session
|
|
92
|
+
* Kill the terminal session (close and terminate)
|
|
75
93
|
*/
|
|
76
94
|
kill(): void;
|
|
95
|
+
/**
|
|
96
|
+
* List available sessions
|
|
97
|
+
*/
|
|
98
|
+
listSessions(filter?: SessionListFilter): Promise<SharedSessionInfo[]>;
|
|
99
|
+
/**
|
|
100
|
+
* Join an existing session
|
|
101
|
+
*/
|
|
102
|
+
join(options: JoinSessionOptions): Promise<SharedSessionInfo>;
|
|
103
|
+
/**
|
|
104
|
+
* Leave the current session without killing it
|
|
105
|
+
*/
|
|
106
|
+
leave(sessionId?: string): void;
|
|
107
|
+
/**
|
|
108
|
+
* Request session list and trigger onSessionList handlers
|
|
109
|
+
* (Fire-and-forget version of listSessions)
|
|
110
|
+
*/
|
|
111
|
+
requestSessionList(filter?: SessionListFilter): void;
|
|
77
112
|
/**
|
|
78
113
|
* Called when connected to server
|
|
79
114
|
*/
|
|
@@ -98,6 +133,42 @@ export declare class TerminalClient {
|
|
|
98
133
|
* Called when a session is spawned
|
|
99
134
|
*/
|
|
100
135
|
onSpawned(handler: (info: SessionInfo) => void): void;
|
|
136
|
+
/**
|
|
137
|
+
* Called when server info is received
|
|
138
|
+
*/
|
|
139
|
+
onServerInfo(handler: (info: ServerInfo) => void): void;
|
|
140
|
+
/**
|
|
141
|
+
* Called when container list is received
|
|
142
|
+
*/
|
|
143
|
+
onContainerList(handler: (containers: ContainerInfo[]) => void): void;
|
|
144
|
+
/**
|
|
145
|
+
* Called when session list is received
|
|
146
|
+
*/
|
|
147
|
+
onSessionList(handler: (sessions: SharedSessionInfo[]) => void): void;
|
|
148
|
+
/**
|
|
149
|
+
* Called when successfully joined a session
|
|
150
|
+
*/
|
|
151
|
+
onJoined(handler: (session: SharedSessionInfo, history?: string) => void): void;
|
|
152
|
+
/**
|
|
153
|
+
* Called when left a session
|
|
154
|
+
*/
|
|
155
|
+
onLeft(handler: (sessionId: string) => void): void;
|
|
156
|
+
/**
|
|
157
|
+
* Called when another client joins the current session
|
|
158
|
+
*/
|
|
159
|
+
onClientJoined(handler: (sessionId: string, clientCount: number) => void): void;
|
|
160
|
+
/**
|
|
161
|
+
* Called when another client leaves the current session
|
|
162
|
+
*/
|
|
163
|
+
onClientLeft(handler: (sessionId: string, clientCount: number) => void): void;
|
|
164
|
+
/**
|
|
165
|
+
* Called when the session is closed by owner or orphan timeout
|
|
166
|
+
*/
|
|
167
|
+
onSessionClosed(handler: (sessionId: string, reason: string) => void): void;
|
|
168
|
+
/**
|
|
169
|
+
* Request list of available containers
|
|
170
|
+
*/
|
|
171
|
+
requestContainerList(): void;
|
|
101
172
|
/**
|
|
102
173
|
* Get current connection state
|
|
103
174
|
*/
|
|
@@ -118,5 +189,9 @@ export declare class TerminalClient {
|
|
|
118
189
|
* Check if a session is active
|
|
119
190
|
*/
|
|
120
191
|
hasActiveSession(): boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Get server info
|
|
194
|
+
*/
|
|
195
|
+
getServerInfo(): ServerInfo | null;
|
|
121
196
|
}
|
|
122
197
|
//# sourceMappingURL=terminal-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-client.d.ts","sourceRoot":"","sources":["../../src/client/terminal-client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"terminal-client.d.ts","sourceRoot":"","sources":["../../src/client/terminal-client.ts"],"names":[],"mappings":"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"}
|