mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-30 13:13:25 +00:00
fix(terminal): project replay metadata onto the wire contract
Keep worker revision and input-mode preamble internal while preserving the required retained-history metadata delivered to clients.
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
decodeTerminalStreamFrame,
|
||||
} from "@getpaseo/protocol/binary-frames/index";
|
||||
import {
|
||||
createTerminalRestoreDelivery,
|
||||
encodeTerminalRestoreFrame,
|
||||
resolveRestoreAfterOutputOverflow,
|
||||
resolveTerminalRestoreSnapshotOptions,
|
||||
@@ -53,3 +54,40 @@ describe("terminal restore policy", () => {
|
||||
expect(new TextDecoder().decode(frame?.payload ?? new Uint8Array())).toContain("restored");
|
||||
});
|
||||
});
|
||||
|
||||
test("projects chunked replay begin onto the declared wire metadata", () => {
|
||||
const frames: Uint8Array[] = [];
|
||||
const deliver = createTerminalRestoreDelivery({
|
||||
slot: 7,
|
||||
chunked: true,
|
||||
send: (frame) => {
|
||||
frames.push(frame);
|
||||
},
|
||||
});
|
||||
deliver({
|
||||
type: "begin",
|
||||
metadata: {
|
||||
rows: 30,
|
||||
cols: 120,
|
||||
retainedHistoryLines: 842,
|
||||
revision: 5123,
|
||||
replayPreamble: "\x1b[?2004h",
|
||||
},
|
||||
});
|
||||
const data = new TextEncoder().encode("\x1b[31m界 replay\x1b[0m");
|
||||
deliver({ type: "data", data });
|
||||
deliver({ type: "end" });
|
||||
const decoded = frames.map((frame) => decodeTerminalStreamFrame(frame)!);
|
||||
expect(decoded.map((frame) => ({ slot: frame.slot, opcode: frame.opcode }))).toEqual([
|
||||
{ slot: 7, opcode: TerminalStreamOpcode.ReplayBegin },
|
||||
{ slot: 7, opcode: TerminalStreamOpcode.ReplayData },
|
||||
{ slot: 7, opcode: TerminalStreamOpcode.ReplayEnd },
|
||||
]);
|
||||
expect(JSON.parse(new TextDecoder().decode(decoded[0]!.payload))).toEqual({
|
||||
rows: 30,
|
||||
cols: 120,
|
||||
retainedHistoryLines: 842,
|
||||
});
|
||||
expect(decoded[1]!.payload).toEqual(data);
|
||||
expect(decoded[2]!.payload.byteLength).toBe(0);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import type { z } from "zod";
|
||||
import type { SubscribeTerminalRequest } from "@getpaseo/protocol/messages";
|
||||
import {
|
||||
TerminalStreamOpcode,
|
||||
type TerminalReplayMetadataSchema,
|
||||
encodeTerminalStreamFrame,
|
||||
} from "@getpaseo/protocol/binary-frames/index";
|
||||
import type { TerminalReplaySink, TerminalReplayOptions } from "./terminal-replay.js";
|
||||
@@ -91,7 +93,14 @@ export function createTerminalRestoreDelivery(input: {
|
||||
end: TerminalStreamOpcode.ReplayEnd,
|
||||
};
|
||||
let payload: string | Uint8Array | undefined;
|
||||
if (event.type === "begin") payload = JSON.stringify(event.metadata);
|
||||
if (event.type === "begin") {
|
||||
const begin = {
|
||||
rows: event.metadata.rows,
|
||||
cols: event.metadata.cols,
|
||||
retainedHistoryLines: event.metadata.retainedHistoryLines,
|
||||
} satisfies z.infer<typeof TerminalReplayMetadataSchema>;
|
||||
payload = JSON.stringify(begin);
|
||||
}
|
||||
if (event.type === "data") payload = event.data;
|
||||
input.send(
|
||||
encodeTerminalStreamFrame({ slot: input.slot, opcode: opcodes[event.type], payload }),
|
||||
|
||||
Reference in New Issue
Block a user