| 1 | import type { TabMeta, WireEvent } from "./types"; |
| 2 | |
| 3 | type MockTurnIdentity = { turnId: string; runtimeEpoch: string }; |
| 4 | |
| 5 | export function withMockSessionIdentity(tab: TabMeta | undefined): TabMeta | undefined { |
| 6 | if (!tab) return undefined; |
| 7 | const sessionId = tab.session?.sessionId || tab.sessionId || tab.sessionPath || (tab.topicId ? `mock:${tab.topicId}` : ""); |
| 8 | if (!sessionId) return tab; |
| 9 | return { |
| 10 | ...tab, |
| 11 | sessionId, |
| 12 | session: tab.session ?? { hostId: "local", sessionId }, |
| 13 | sessionGeneration: tab.sessionGeneration ?? 1, |
| 14 | }; |
| 15 | } |
| 16 | |
| 17 | export function mockSessionMeta(tab: TabMeta | undefined) { |
| 18 | const identified = withMockSessionIdentity(tab); |
| 19 | return { |
| 20 | sessionPath: identified?.sessionPath, |
| 21 | sessionId: identified?.sessionId, |
| 22 | session: identified?.session, |
| 23 | sessionGeneration: identified?.sessionGeneration, |
| 24 | }; |
| 25 | } |
| 26 | |
| 27 | export function createBrowserMockInteractionIdentity(input: { |
| 28 | emit: (event: WireEvent) => void; |
| 29 | currentTabId: () => string | undefined; |
| 30 | setRunning: (tabId: string | undefined, running: boolean) => void; |
| 31 | }) { |
| 32 | let sequence = 0; |
| 33 | const turns = new Map<string, MockTurnIdentity>(); |
| 34 | const current = (): MockTurnIdentity | undefined => { |
| 35 | const tabId = input.currentTabId(); |
| 36 | return tabId ? turns.get(tabId) : undefined; |
| 37 | }; |
| 38 | return { |
| 39 | emitPrompt(event: WireEvent) { |
| 40 | input.emit({ ...current(), ...event }); |
| 41 | }, |
| 42 | turnStarted(submissionId?: string) { |
| 43 | const tabId = input.currentTabId(); |
| 44 | const identity = { turnId: `mock-turn-${++sequence}`, runtimeEpoch: `mock-runtime:${tabId ?? "active"}` }; |
| 45 | if (tabId) turns.set(tabId, identity); |
| 46 | input.setRunning(tabId, true); |
| 47 | input.emit({ kind: "turn_started", submissionId, ...identity }); |
| 48 | }, |
| 49 | turnDone(submissionId?: string) { |
| 50 | const tabId = input.currentTabId(); |
| 51 | const identity = current(); |
| 52 | input.setRunning(tabId, false); |
| 53 | input.emit({ kind: "turn_done", submissionId, ...identity }); |
| 54 | if (tabId) turns.delete(tabId); |
| 55 | }, |
| 56 | }; |
| 57 | } |
| 58 |