Skip to content

Commit 6324d1c

Browse files
committed
fix(app): more terminal replay issues
1 parent 95ad675 commit 6324d1c

1 file changed

Lines changed: 30 additions & 15 deletions

File tree

packages/app/src/components/terminal.tsx

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,27 @@ export const Terminal = (props: TerminalProps) => {
287287
handleResize = () => fit.fit()
288288
window.addEventListener("resize", handleResize)
289289
cleanups.push(() => window.removeEventListener("resize", handleResize))
290+
const limit = 16_384
291+
const min = 32
292+
const windowMs = 750
293+
const seed = tail.length > limit ? tail.slice(-limit) : tail
294+
let sync = seed.length >= min
295+
let syncUntil = 0
296+
const stopSync = () => {
297+
sync = false
298+
syncUntil = 0
299+
}
300+
301+
const overlap = (data: string) => {
302+
if (!seed) return 0
303+
const max = Math.min(seed.length, data.length)
304+
if (max < min) return 0
305+
for (let i = max; i >= min; i--) {
306+
if (seed.slice(-i) === data.slice(0, i)) return i
307+
}
308+
return 0
309+
}
310+
290311
const onResize = t.onResize(async (size) => {
291312
if (socket.readyState === WebSocket.OPEN) {
292313
await sdk.client.pty
@@ -302,6 +323,7 @@ export const Terminal = (props: TerminalProps) => {
302323
})
303324
cleanups.push(() => disposeIfDisposable(onResize))
304325
const onData = t.onData((data) => {
326+
if (data) stopSync()
305327
if (socket.readyState === WebSocket.OPEN) {
306328
socket.send(data)
307329
}
@@ -317,21 +339,9 @@ export const Terminal = (props: TerminalProps) => {
317339
// console.log("Scroll position:", ydisp)
318340
// })
319341

320-
const limit = 16_384
321-
const seed = tail
322-
let sync = !!seed
323-
324-
const overlap = (data: string) => {
325-
if (!seed) return 0
326-
const max = Math.min(seed.length, data.length)
327-
for (let i = max; i > 0; i--) {
328-
if (seed.slice(-i) === data.slice(0, i)) return i
329-
}
330-
return 0
331-
}
332-
333342
const handleOpen = () => {
334343
local.onConnect?.()
344+
if (sync) syncUntil = Date.now() + windowMs
335345
sdk.client.pty
336346
.update({
337347
ptyID: local.pty.id,
@@ -346,18 +356,23 @@ export const Terminal = (props: TerminalProps) => {
346356
cleanups.push(() => socket.removeEventListener("open", handleOpen))
347357

348358
const handleMessage = (event: MessageEvent) => {
359+
if (disposed) return
349360
const data = typeof event.data === "string" ? event.data : ""
350361
if (!data) return
351362

352363
const next = (() => {
353364
if (!sync) return data
365+
if (syncUntil && Date.now() > syncUntil) {
366+
stopSync()
367+
return data
368+
}
354369
const n = overlap(data)
355370
if (!n) {
356-
sync = false
371+
stopSync()
357372
return data
358373
}
359374
const trimmed = data.slice(n)
360-
if (trimmed) sync = false
375+
if (trimmed) stopSync()
361376
return trimmed
362377
})()
363378

0 commit comments

Comments
 (0)