2022-08-25 16:17:50 -07:00
|
|
|
import { Terminal } from "xterm"
|
|
|
|
import { FitAddon } from "xterm-addon-fit"
|
|
|
|
|
|
|
|
export type SSHSessionDef = {
|
|
|
|
username: string
|
|
|
|
hostname: string
|
|
|
|
}
|
|
|
|
|
|
|
|
export function runSSHSession(
|
|
|
|
termContainerNode: HTMLDivElement,
|
|
|
|
def: SSHSessionDef,
|
|
|
|
ipn: IPN,
|
|
|
|
onDone: () => void
|
|
|
|
) {
|
|
|
|
const term = new Terminal({
|
|
|
|
cursorBlink: true,
|
|
|
|
})
|
|
|
|
const fitAddon = new FitAddon()
|
|
|
|
term.loadAddon(fitAddon)
|
|
|
|
term.open(termContainerNode)
|
|
|
|
fitAddon.fit()
|
|
|
|
|
|
|
|
let onDataHook: ((data: string) => void) | undefined
|
|
|
|
term.onData((e) => {
|
|
|
|
onDataHook?.(e)
|
|
|
|
})
|
|
|
|
|
|
|
|
term.focus()
|
|
|
|
|
2022-08-29 18:12:52 -07:00
|
|
|
let resizeObserver: ResizeObserver | undefined
|
|
|
|
let handleBeforeUnload: ((e: BeforeUnloadEvent) => void) | undefined
|
|
|
|
|
2022-08-30 10:57:23 -07:00
|
|
|
const sshSession = ipn.ssh(def.hostname, def.username, {
|
2022-08-29 18:12:52 -07:00
|
|
|
writeFn(input) {
|
|
|
|
term.write(input)
|
|
|
|
},
|
|
|
|
writeErrorFn(err) {
|
|
|
|
console.error(err)
|
|
|
|
term.write(err)
|
|
|
|
},
|
|
|
|
setReadFn(hook) {
|
|
|
|
onDataHook = hook
|
|
|
|
},
|
2022-08-25 16:17:50 -07:00
|
|
|
rows: term.rows,
|
|
|
|
cols: term.cols,
|
2022-08-29 18:12:52 -07:00
|
|
|
onDone() {
|
|
|
|
resizeObserver?.disconnect()
|
2022-08-25 16:17:50 -07:00
|
|
|
term.dispose()
|
2022-08-29 18:12:52 -07:00
|
|
|
if (handleBeforeUnload) {
|
|
|
|
window.removeEventListener("beforeunload", handleBeforeUnload)
|
|
|
|
}
|
2022-08-25 16:17:50 -07:00
|
|
|
onDone()
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
// Make terminal and SSH session track the size of the containing DOM node.
|
2022-09-07 18:23:37 -07:00
|
|
|
resizeObserver =
|
|
|
|
new termContainerNode.ownerDocument.defaultView!.ResizeObserver(() =>
|
|
|
|
fitAddon.fit()
|
|
|
|
)
|
2022-08-25 16:17:50 -07:00
|
|
|
resizeObserver.observe(termContainerNode)
|
|
|
|
term.onResize(({ rows, cols }) => sshSession.resize(rows, cols))
|
|
|
|
|
|
|
|
// Close the session if the user closes the window without an explicit
|
|
|
|
// exit.
|
2022-08-29 18:12:52 -07:00
|
|
|
handleBeforeUnload = () => sshSession.close()
|
2022-08-25 16:17:50 -07:00
|
|
|
window.addEventListener("beforeunload", handleBeforeUnload)
|
|
|
|
}
|