fix(app): more terminal replay issues

This commit is contained in:
Adam
2026-02-06 09:54:38 -06:00
parent 95ad6758af
commit 6324d1c351

View File

@@ -287,6 +287,27 @@ export const Terminal = (props: TerminalProps) => {
handleResize = () => fit.fit()
window.addEventListener("resize", handleResize)
cleanups.push(() => window.removeEventListener("resize", handleResize))
const limit = 16_384
const min = 32
const windowMs = 750
const seed = tail.length > limit ? tail.slice(-limit) : tail
let sync = seed.length >= min
let syncUntil = 0
const stopSync = () => {
sync = false
syncUntil = 0
}
const overlap = (data: string) => {
if (!seed) return 0
const max = Math.min(seed.length, data.length)
if (max < min) return 0
for (let i = max; i >= min; i--) {
if (seed.slice(-i) === data.slice(0, i)) return i
}
return 0
}
const onResize = t.onResize(async (size) => {
if (socket.readyState === WebSocket.OPEN) {
await sdk.client.pty
@@ -302,6 +323,7 @@ export const Terminal = (props: TerminalProps) => {
})
cleanups.push(() => disposeIfDisposable(onResize))
const onData = t.onData((data) => {
if (data) stopSync()
if (socket.readyState === WebSocket.OPEN) {
socket.send(data)
}
@@ -317,21 +339,9 @@ export const Terminal = (props: TerminalProps) => {
// console.log("Scroll position:", ydisp)
// })
const limit = 16_384
const seed = tail
let sync = !!seed
const overlap = (data: string) => {
if (!seed) return 0
const max = Math.min(seed.length, data.length)
for (let i = max; i > 0; i--) {
if (seed.slice(-i) === data.slice(0, i)) return i
}
return 0
}
const handleOpen = () => {
local.onConnect?.()
if (sync) syncUntil = Date.now() + windowMs
sdk.client.pty
.update({
ptyID: local.pty.id,
@@ -346,18 +356,23 @@ export const Terminal = (props: TerminalProps) => {
cleanups.push(() => socket.removeEventListener("open", handleOpen))
const handleMessage = (event: MessageEvent) => {
if (disposed) return
const data = typeof event.data === "string" ? event.data : ""
if (!data) return
const next = (() => {
if (!sync) return data
if (syncUntil && Date.now() > syncUntil) {
stopSync()
return data
}
const n = overlap(data)
if (!n) {
sync = false
stopSync()
return data
}
const trimmed = data.slice(n)
if (trimmed) sync = false
if (trimmed) stopSync()
return trimmed
})()