@linxin666/dsh-ssh 0.1.14 → 0.1.15
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/lib/client.js +26 -4
- package/lib/client.js.map +1 -1
- package/lib/index.js +660 -598
- package/lib/types/client/panel/TunnelsTab.d.ts +10 -0
- package/lib/types/engine/cluster.d.ts +17 -0
- package/lib/types/engine/connection-pool.d.ts +81 -0
- package/lib/types/engine/pty.d.ts +32 -0
- package/lib/types/engine/sftp.d.ts +20 -0
- package/lib/types/engine/tunnel.d.ts +32 -0
- package/lib/types/engine.d.ts +18 -79
- package/package.json +1 -1
- package/src/client/panel/TerminalTab.tsx +10 -3
- package/src/client/panel/TunnelsTab.tsx +31 -4
- package/src/engine/cluster.ts +51 -0
- package/src/engine/connection-pool.ts +307 -0
- package/src/engine/pty.ts +74 -0
- package/src/engine/sftp.ts +235 -0
- package/src/engine/tunnel.ts +125 -0
- package/src/engine.ts +45 -687
package/lib/client.js
CHANGED
|
@@ -14554,6 +14554,7 @@ window.__ModuleLoader__.load({
|
|
|
14554
14554
|
const termRef = (0, react.useRef)(null);
|
|
14555
14555
|
const fitRef = (0, react.useRef)(null);
|
|
14556
14556
|
const connRef = (0, react.useRef)(null);
|
|
14557
|
+
const dataSubRef = (0, react.useRef)(null);
|
|
14557
14558
|
(0, react.useEffect)(() => {
|
|
14558
14559
|
ensureXtermCss();
|
|
14559
14560
|
}, []);
|
|
@@ -14586,6 +14587,8 @@ window.__ModuleLoader__.load({
|
|
|
14586
14587
|
connection.onExit = void 0;
|
|
14587
14588
|
connection.close();
|
|
14588
14589
|
}
|
|
14590
|
+
dataSubRef.current?.dispose();
|
|
14591
|
+
dataSubRef.current = null;
|
|
14589
14592
|
termRef.current?.dispose();
|
|
14590
14593
|
termRef.current = null;
|
|
14591
14594
|
fitRef.current = null;
|
|
@@ -14633,7 +14636,7 @@ window.__ModuleLoader__.load({
|
|
|
14633
14636
|
fitRef.current = fit;
|
|
14634
14637
|
connRef.current = connection;
|
|
14635
14638
|
let settled = false;
|
|
14636
|
-
|
|
14639
|
+
dataSubRef.current = term.onData((data) => {
|
|
14637
14640
|
connection.send(data);
|
|
14638
14641
|
});
|
|
14639
14642
|
connection.onReady = () => {
|
|
@@ -14648,7 +14651,8 @@ window.__ModuleLoader__.load({
|
|
|
14648
14651
|
connection.onExit = (code, error) => {
|
|
14649
14652
|
if (settled) return;
|
|
14650
14653
|
settled = true;
|
|
14651
|
-
|
|
14654
|
+
dataSubRef.current?.dispose();
|
|
14655
|
+
dataSubRef.current = null;
|
|
14652
14656
|
term.options.disableStdin = true;
|
|
14653
14657
|
connRef.current = null;
|
|
14654
14658
|
setStatus({
|
|
@@ -15059,6 +15063,24 @@ window.__ModuleLoader__.load({
|
|
|
15059
15063
|
* mounted) with per-row stop, a stop-all action scoped to the selected alias,
|
|
15060
15064
|
* and a new-tunnel form.
|
|
15061
15065
|
*/
|
|
15066
|
+
/** Live-tunnel polling interval while the tab is mounted (ms). */
|
|
15067
|
+
const TUNNEL_POLL_MS = 5e3;
|
|
15068
|
+
/**
|
|
15069
|
+
* Return `next` only when the tunnel list changed in a user-visible way
|
|
15070
|
+
* (identity, ordering or any renderable field), else `null` so a poll tick
|
|
15071
|
+
* with no real change keeps the previous reference and React skips the
|
|
15072
|
+
* re-render. `prev === null` (first load) always accepts the list.
|
|
15073
|
+
*/
|
|
15074
|
+
function diffTunnels(prev, next) {
|
|
15075
|
+
if (prev === null) return next;
|
|
15076
|
+
if (prev.length !== next.length) return next;
|
|
15077
|
+
for (let index = 0; index < prev.length; index += 1) {
|
|
15078
|
+
const a = prev[index];
|
|
15079
|
+
const b = next[index];
|
|
15080
|
+
if (a.id !== b.id || a.alias !== b.alias || a.state !== b.state || a.localPort !== b.localPort || a.remoteHost !== b.remoteHost || a.remotePort !== b.remotePort || a.startedAt !== b.startedAt || a.error !== b.error) return next;
|
|
15081
|
+
}
|
|
15082
|
+
return null;
|
|
15083
|
+
}
|
|
15062
15084
|
/** The tunnels tab. */
|
|
15063
15085
|
function TunnelsTab({ api }) {
|
|
15064
15086
|
const [hosts, setHosts] = (0, react.useState)([]);
|
|
@@ -15089,7 +15111,7 @@ window.__ModuleLoader__.load({
|
|
|
15089
15111
|
try {
|
|
15090
15112
|
const list = await api.listTunnels();
|
|
15091
15113
|
if (seq !== seqRef.current) return;
|
|
15092
|
-
setTunnels(list);
|
|
15114
|
+
setTunnels((prev) => diffTunnels(prev, list) ?? prev);
|
|
15093
15115
|
setError(null);
|
|
15094
15116
|
} catch (cause) {
|
|
15095
15117
|
if (seq !== seqRef.current) return;
|
|
@@ -15099,7 +15121,7 @@ window.__ModuleLoader__.load({
|
|
|
15099
15121
|
load();
|
|
15100
15122
|
const timer = setInterval(() => {
|
|
15101
15123
|
load();
|
|
15102
|
-
},
|
|
15124
|
+
}, TUNNEL_POLL_MS);
|
|
15103
15125
|
return () => {
|
|
15104
15126
|
clearInterval(timer);
|
|
15105
15127
|
};
|