feat(option-c-types): extend PortMessage with requestId + PONG

Pure type-extension step for the Option C architectural refactor of the
offscreen↔SW port lifecycle (.planning/debug/empty-archive-port-race.md).

PortMessage.requestId is optional so PING/PONG keep their no-payload
shape. REQUEST_BUFFER and BUFFER will populate it once the recorder
(offscreen) and getVideoBufferFromOffscreen (SW) are wired up in the
next commits. The narrowing remains structural — every consumer must
still validate `type` before accessing `requestId`.

PONG joins PING as a no-payload liveness signal. The SW echoes PONG on
PING, closing the health-probe loop the offscreen uses to detect a dead
port (replacing the 290 s pre-emptive setTimeout that was the proximate
cause of the H1 race window per the bisect).

No runtime change. 52 tests, 10 RED still RED (waiting for impl).
tsc --noEmit exit 0; type-safety grep clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-16 14:29:12 +02:00
parent 4306d59dfd
commit c6e8101860

View File

@@ -29,13 +29,30 @@ export interface Message<T = unknown> {
}
// Типы сообщений в long-lived port (offscreen ↔ SW; D-17 / Plan 04 / D-13)
//
// Option C (debug session empty-archive-port-race) extends the surface:
// - 'PONG' completes the health-probe loop: offscreen pings, SW echoes,
// offscreen tracks last-pong time. Replaces the 290 s pre-emptive
// `setTimeout` reconnect (whose race window weaponised the upstream
// silent-skip in createArchive — see the bisect notes in the debug
// session for full lineage).
// - REQUEST_BUFFER + BUFFER carry an architectural `requestId` so the
// SW can match a response to the in-flight request that issued it.
// This retires the silent-cross-talk failure mode where a stale
// BUFFER from a prior request would route into a newer Promise.
export type PortMessageType =
| 'PING'
| 'PONG'
| 'REQUEST_BUFFER'
| 'BUFFER';
export interface PortMessage {
type: PortMessageType;
// Per-request correlation id (Option C). The SW generates a uuid for
// each REQUEST_BUFFER call and only resolves on BUFFER responses that
// echo the same id. PING/PONG do not carry a requestId — they are
// pure liveness signals.
requestId?: string;
// Wire-format (D-12 base64 transfer + D-13 segment lifecycle):
// segments travel as TransferredVideoSegment[] because
// chrome.runtime.Port JSON-serializes payloads across extension