From d0ce3c7ec3e79fb39f968727d1ffa7822ab04ade Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Wed, 29 Jul 2026 16:04:03 -0700 Subject: [PATCH] perf(terminal): serialize checkpoints with one payload walk Co-authored-by: Orca --- .../terminal-checkpoint-serializer.test.ts | 60 +++++++++++++++++++ .../daemon/terminal-checkpoint-serializer.ts | 9 +-- 2 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 src/main/daemon/terminal-checkpoint-serializer.test.ts diff --git a/src/main/daemon/terminal-checkpoint-serializer.test.ts b/src/main/daemon/terminal-checkpoint-serializer.test.ts new file mode 100644 index 00000000000..a628066d50c --- /dev/null +++ b/src/main/daemon/terminal-checkpoint-serializer.test.ts @@ -0,0 +1,60 @@ +import { describe, expect, it } from 'vitest' +import type { TerminalSnapshot } from './types' +import { serializeTerminalCheckpointWithinLimit } from './terminal-checkpoint-serializer' + +function snapshotWithCountedLinks( + linkCount: number, + uri: string +): { + snapshot: TerminalSnapshot + uriReads: () => number +} { + let reads = 0 + const oscLinks = Array.from({ length: linkCount }, (_, row) => ({ + row, + startCol: 0, + endCol: 1, + get uri(): string { + reads += 1 + return uri + } + })) + return { + snapshot: { + snapshotAnsi: 'visible', + scrollbackAnsi: '', + oscLinks, + rehydrateSequences: '', + cwd: '/workspace', + modes: { + bracketedPaste: false, + mouseTracking: false, + applicationCursor: false, + alternateScreen: false + }, + cols: 80, + rows: 24, + scrollbackLines: 0 + }, + uriReads: () => reads + } +} + +describe('terminal checkpoint serializer', () => { + it('traverses a large checkpoint payload once', async () => { + const linkCount = 4_096 + const { snapshot, uriReads } = snapshotWithCountedLinks( + linkCount, + `https://example.com/${'x'.repeat(4_096)}` + ) + + const json = await serializeTerminalCheckpointWithinLimit( + snapshot, + { cwd: snapshot.cwd, generation: 1, checkpointedAt: '2026-07-29T00:00:00.000Z' }, + 20 * 1024 * 1024 + ) + + expect(Buffer.byteLength(json, 'utf8')).toBeLessThanOrEqual(20 * 1024 * 1024) + expect(uriReads()).toBe(linkCount) + }) +}) diff --git a/src/main/daemon/terminal-checkpoint-serializer.ts b/src/main/daemon/terminal-checkpoint-serializer.ts index 595d42fd6a2..62adf35349a 100644 --- a/src/main/daemon/terminal-checkpoint-serializer.ts +++ b/src/main/daemon/terminal-checkpoint-serializer.ts @@ -1,7 +1,6 @@ import type { TerminalCheckpointFile, TerminalSnapshot } from './types' import { ColdRestoreReplayWriter } from './cold-restore-replay-writer' import { HeadlessEmulator } from './headless-emulator' -import { jsonUtf8ByteLength } from './json-utf8-byte-length' type CheckpointMetadata = { cwd: string | null @@ -33,14 +32,8 @@ function checkpointFile( } function stringifyWithinLimit(checkpoint: TerminalCheckpointFile, maxBytes: number): string | null { - if (jsonUtf8ByteLength(checkpoint) > maxBytes) { - return null - } const json = JSON.stringify(checkpoint) - if (Buffer.byteLength(json, 'utf8') > maxBytes) { - throw new Error('Terminal checkpoint size estimator mismatch') - } - return json + return Buffer.byteLength(json, 'utf8') <= maxBytes ? json : null } async function replaySnapshot(snapshot: TerminalSnapshot): Promise {