fix: don't stream when the append IPC is unavailable
Codex re-review: if openRecordingStream exists but appendRecordingChunk does not (renderer/main version skew), the recorder would open the stream and switch to streaming mode, but every append silently no-ops and the save ends up empty. Require both IPC methods before streaming; otherwise fall back to in-memory buffering. Adds a regression test. Verified: tsc --noEmit clean; biome clean; vitest 183/183. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -205,6 +205,26 @@ describe("createRecorderHandle", () => {
|
|||||||
expect(blob.size).toBe(2);
|
expect(blob.size).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("buffers in memory when appendRecordingChunk is unavailable (version skew)", async () => {
|
||||||
|
const openRecordingStream = vi.fn(async () => ({ success: true }));
|
||||||
|
// appendRecordingChunk intentionally omitted to simulate renderer/main skew.
|
||||||
|
stubElectronAPI({ openRecordingStream });
|
||||||
|
|
||||||
|
const handle = createRecorderHandle({} as MediaStream, { mimeType: "video/webm" }, "rec.webm");
|
||||||
|
const fake = driver(handle);
|
||||||
|
|
||||||
|
fake.emit(new Blob(["a"]));
|
||||||
|
await tick();
|
||||||
|
fake.emit(new Blob(["b"]));
|
||||||
|
fake.stop();
|
||||||
|
|
||||||
|
const blob = await handle.recordedBlobPromise;
|
||||||
|
// Never even attempts to open the stream when it can't append to it.
|
||||||
|
expect(openRecordingStream).not.toHaveBeenCalled();
|
||||||
|
expect(handle.isStreaming()).toBe(false);
|
||||||
|
expect(blob.size).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
it("discard closes the disk stream for a streamed recording", async () => {
|
it("discard closes the disk stream for a streamed recording", async () => {
|
||||||
const closeRecordingStream = vi.fn(async () => ({ success: true }));
|
const closeRecordingStream = vi.fn(async () => ({ success: true }));
|
||||||
stubElectronAPI({
|
stubElectronAPI({
|
||||||
|
|||||||
@@ -76,8 +76,14 @@ export function createRecorderHandle(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Require BOTH stream IPC methods before attempting to stream. If only
|
||||||
|
// openRecordingStream exists (renderer/main version skew), streaming would
|
||||||
|
// open but every append would silently no-op, saving an empty file — so in
|
||||||
|
// that case fall through to in-memory buffering instead.
|
||||||
const openPromise: Promise<{ success: boolean; error?: string }> =
|
const openPromise: Promise<{ success: boolean; error?: string }> =
|
||||||
fileName && api?.openRecordingStream
|
fileName !== undefined &&
|
||||||
|
typeof api?.openRecordingStream === "function" &&
|
||||||
|
typeof api?.appendRecordingChunk === "function"
|
||||||
? api.openRecordingStream(fileName)
|
? api.openRecordingStream(fileName)
|
||||||
: Promise.resolve({ success: false });
|
: Promise.resolve({ success: false });
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user