| 1 | import type { HistoryWindowRequestView } from "./types"; |
| 2 | import type { Action, State } from "./useController"; |
| 3 | import { getTranscriptStore } from "./transcriptStore"; |
| 4 | import { hydrateIdentityCurrent } from "./sessionIdentity"; |
| 5 | |
| 6 | export type TurnNavigationTarget = { messageId: string; generation?: string; snapshotSequence?: number }; |
| 7 | export type TurnNavigationOutcome = "loaded" | "cancelled" | "stale" | "unavailable"; |
| 8 | export type NavigateToTurn = (target: TurnNavigationTarget, current: () => boolean) => Promise<TurnNavigationOutcome>; |
| 9 | |
| 10 | /** Shared state boundary for local and remote owners; the view never dispatches. */ |
| 11 | export async function navigateHistoryTurn(tabId: string, state: State, getState: () => State | undefined, |
| 12 | dispatch: (action: Action) => void, target: TurnNavigationTarget, current: () => boolean): Promise<TurnNavigationOutcome> { |
| 13 | const identity = state.meta; |
| 14 | const valid = () => current() && getState()?.sessionGen === state.sessionGen && hydrateIdentityCurrent(identity ?? {}, getState()?.meta); |
| 15 | const request: HistoryWindowRequestView = { ...target, anchor: "message", direction: "newer", limit: 32 }; |
| 16 | const result = await getTranscriptStore().prepareTargetWindow(tabId, state.meta?.sessionPath ?? "", request, valid); |
| 17 | if (!valid() || result.status === "cancelled") return "cancelled"; |
| 18 | if (result.status !== "loaded") return result.status; |
| 19 | if (!result.current()) return "cancelled"; |
| 20 | result.prepared.commit(); |
| 21 | const projection = result.prepared.projection; |
| 22 | dispatch({ type: "transcript_records", projection: { ...projection, removeIds: [] }, confirmedUsers: [] }); |
| 23 | return "loaded"; |
| 24 | } |
| 25 |