kumo-cli 1.3.9 → 1.3.10
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.
|
@@ -20,6 +20,10 @@ function logFrame(direction, msg, size) {
|
|
|
20
20
|
}
|
|
21
21
|
// the server pings every 30s; missing two and a half of them means the link is dead
|
|
22
22
|
const SERVER_PING_TIMEOUT_MS = 75_000;
|
|
23
|
+
// the cli pings too: a check that finds nothing read since the last one drops the link, so a dead
|
|
24
|
+
// one is left within two checks, before the server gives up on it and tells the app the computer
|
|
25
|
+
// went offline
|
|
26
|
+
const HEARTBEAT_MS = 10_000;
|
|
23
27
|
// the largest frame the app sends: a file write, prompt images or a 10 MB tunnel body as base64
|
|
24
28
|
const MAX_PAYLOAD_BYTES = 64 * 1024 * 1024;
|
|
25
29
|
// reconnect waits double from 3s up to 30s, plus some jitter so many clis do not return at once
|
|
@@ -33,16 +37,19 @@ export class WsClient {
|
|
|
33
37
|
onOpen;
|
|
34
38
|
onMessage;
|
|
35
39
|
onClose;
|
|
40
|
+
heartbeatMs;
|
|
36
41
|
ws = null;
|
|
37
42
|
reconnectTimer = null;
|
|
38
43
|
pingWatchdog = null;
|
|
44
|
+
heartbeat = null;
|
|
39
45
|
attempts = 0;
|
|
40
46
|
// close() was called: the socket stays down
|
|
41
47
|
closed = false;
|
|
42
|
-
constructor(onOpen, onMessage, onClose) {
|
|
48
|
+
constructor(onOpen, onMessage, onClose, heartbeatMs = HEARTBEAT_MS) {
|
|
43
49
|
this.onOpen = onOpen;
|
|
44
50
|
this.onMessage = onMessage;
|
|
45
51
|
this.onClose = onClose;
|
|
52
|
+
this.heartbeatMs = heartbeatMs;
|
|
46
53
|
}
|
|
47
54
|
send(data) {
|
|
48
55
|
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
@@ -63,10 +70,29 @@ export class WsClient {
|
|
|
63
70
|
this.clearWatchdog();
|
|
64
71
|
this.pingWatchdog = setTimeout(() => ws.terminate(), SERVER_PING_TIMEOUT_MS);
|
|
65
72
|
};
|
|
73
|
+
// any byte from the server shows the link is up: a pong, or a large frame still arriving
|
|
74
|
+
let socket;
|
|
75
|
+
let lastRead = -1;
|
|
76
|
+
ws.on('upgrade', (res) => { socket = res.socket; });
|
|
77
|
+
const check = () => {
|
|
78
|
+
// a frame still going out holds the pong back; the watchdog covers a link that dies meanwhile
|
|
79
|
+
if (ws.bufferedAmount === 0) {
|
|
80
|
+
const read = socket?.bytesRead ?? 0;
|
|
81
|
+
if (read === lastRead) {
|
|
82
|
+
log('[ws] no answer from the server');
|
|
83
|
+
ws.terminate();
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
lastRead = read;
|
|
87
|
+
ws.ping();
|
|
88
|
+
}
|
|
89
|
+
this.heartbeat = setTimeout(check, this.heartbeatMs);
|
|
90
|
+
};
|
|
66
91
|
ws.on('open', () => {
|
|
67
92
|
this.attempts = 0;
|
|
68
93
|
log(`[ws] connected to ${SERVER_WS()}`);
|
|
69
94
|
armWatchdog();
|
|
95
|
+
check();
|
|
70
96
|
Promise.resolve(this.onOpen()).catch((e) => log(`[onOpen] error: ${e}`));
|
|
71
97
|
});
|
|
72
98
|
ws.on('ping', armWatchdog);
|
|
@@ -82,7 +108,7 @@ export class WsClient {
|
|
|
82
108
|
}
|
|
83
109
|
});
|
|
84
110
|
ws.on('close', () => {
|
|
85
|
-
this.
|
|
111
|
+
this.clearTimers();
|
|
86
112
|
// closed on purpose, or replaced by a newer socket: no reconnect from here
|
|
87
113
|
if (this.closed || this.ws !== ws)
|
|
88
114
|
return;
|
|
@@ -101,7 +127,7 @@ export class WsClient {
|
|
|
101
127
|
clearTimeout(this.reconnectTimer);
|
|
102
128
|
this.reconnectTimer = null;
|
|
103
129
|
}
|
|
104
|
-
this.
|
|
130
|
+
this.clearTimers();
|
|
105
131
|
try {
|
|
106
132
|
this.ws?.close();
|
|
107
133
|
}
|
|
@@ -114,5 +140,12 @@ export class WsClient {
|
|
|
114
140
|
this.pingWatchdog = null;
|
|
115
141
|
}
|
|
116
142
|
}
|
|
143
|
+
clearTimers() {
|
|
144
|
+
this.clearWatchdog();
|
|
145
|
+
if (this.heartbeat) {
|
|
146
|
+
clearTimeout(this.heartbeat);
|
|
147
|
+
this.heartbeat = null;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
117
150
|
}
|
|
118
151
|
//# sourceMappingURL=wsClient.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wsClient.js","sourceRoot":"","sources":["../../src/transport/wsClient.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wsClient.js","sourceRoot":"","sources":["../../src/transport/wsClient.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kumo-cli",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.10",
|
|
4
4
|
"description": "Kumo CLI — where your code drifts between devices, softly. A pairing-based companion for the Kumo app that bridges your terminal sessions to remote devices.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|