/** * The followed page: the one page runtime whose traffic the node side * accepts, and everything that follows from that choice. Implements the * {@link TimelineSink} the source feeds, decides when a `ready` is a * reconnect, a reload or another page taking over, clears and forgets on * those edges, replays recording state and the settings override to a runtime * that just booted, and keeps the recording flag the runtime sees in step * with the shared session state. * * Talks out only through {@link FollowedPageEffects} (what the panel and the * terminal hear about) and {@link FollowedPageRuntime} (what the page is * told), so the ordering rules can be tested by driving the sink directly, * with no devframe booted. The {@link RecordingSession} behind it holds the * buffers and answers the read-side queries. * * @see CONTEXT.md for the page vocabulary. */ import type { InspectorMessage } from '../../types/inspector.js'; import type { HmrIncompatibilityEvent } from '../../types/hmr-incompatibility.js'; import type { HmrPatchEvent } from '../../types/hmr-patch.js'; import type { SettingsOverride, TimelineEvent, TimelineLayer, TimelineLayersState } from '../../types/timeline.js'; import type { SessionSnapshot } from '../../types/snapshot.js'; import type { InspectorRequester } from './inspector-request.js'; import type { PageChangedEvent, RangeSummaryArgs, RangeSummaryResult, RecentEventsArgs, RecentEventsResult, UpdateSummaryArgs, UpdateSummaryResult } from './protocol.js'; import { type RecordingSession } from './session.js'; import type { TimelineSink, TimelineSource } from './source.js'; /** * Terminal echo for an HMR notice, for an audience that only sees dev-server * stdout. `code` names a diagnostic the host defines; the rest are its * parameters. */ export type HmrDiagnostic = { code: 'LIT_HMR_ACCESSOR'; tagName: string; } | { code: 'LIT_HMR_PATCH_FAILED'; tagName: string; detail: string; } | { code: 'LIT_HMR_ATTRS_CHANGED'; tagName: string; }; /** What the followed page reports outward. Every call is fire-and-forget. */ export interface FollowedPageEffects { /** Stamped events from the followed page, for the timeline stream. */ events(stamped: TimelineEvent[]): void; /** A custom layer the followed page announced. May repeat an id. */ layerAdded(layer: TimelineLayer): void; /** An inspector message from the followed page, after the caches took it. */ inspectorMessage(message: InspectorMessage): void; /** Another page, or a reload of the same tab, took over. */ pageChanged(change: PageChangedEvent): void; hmrPatched(event: HmrPatchEvent): void; hmrIncompatible(event: HmrIncompatibilityEvent): void; diagnose(diagnostic: HmrDiagnostic): void; /** The durable settings override, to replay to a runtime that booted. */ readOverride(): Promise; } /** What the followed page tells the page runtime. */ export type FollowedPageRuntime = Pick; export interface FollowedPageOptions { runtime: FollowedPageRuntime; effects: FollowedPageEffects; /** Agent queries waiting on the page; resolved before the caches update. */ requester: Pick; /** The shared session's layers, read whenever a runtime needs replaying. */ layers: () => TimelineLayersState; /** Boot from a recorded session. See {@link RecordingSession}. */ replay?: SessionSnapshot; /** Event id epoch; tests pin it. */ epoch?: string; /** Wall clock for {@link PageChangedEvent.at}; tests pin it. */ now?: () => number; } export interface FollowedPage extends Pick { /** Hand to {@link TimelineSource.attach}. */ readonly sink: TimelineSink; /** * The shared session's layers changed (an action, or a panel writing the * shared state directly). Pushes them to the runtime, and clears the buffer * when recording turns on. */ layersChanged(layers: TimelineLayersState): void; /** The `recent-events` query, stamped with whether recording is on. */ query(args: RecentEventsArgs): RecentEventsResult; /** The `update-summary` query, stamped with whether recording is on. */ summarize(args: UpdateSummaryArgs): UpdateSummaryResult; /** The `range-summary` query, stamped with whether recording is on. */ summarizeRange(args: RangeSummaryArgs): RangeSummaryResult; } export declare function createFollowedPage(options: FollowedPageOptions): FollowedPage; //# sourceMappingURL=followed-page.d.ts.map