mirror of
https://github.com/stablyai/orca.git
synced 2026-10-24 00:04:01 +00:00
fix(notifications): admit reconnect repair replay
This commit is contained in:
@@ -371,6 +371,48 @@ describe('paired session-tab notification receipt ordering', () => {
|
||||
}
|
||||
)
|
||||
|
||||
it('repairs an exact reconnect replay without dispatching it again', async () => {
|
||||
const hook = renderHook(() => useWebSessionTabsSync())
|
||||
await act(settle)
|
||||
const global = findSubscription('session.tabs.subscribeAll')
|
||||
await publish(global, { type: 'updated', ...snapshot(1, 'working', NOW) })
|
||||
await publish(global, { type: 'updated', ...snapshot(2, 'waiting', NOW + 1_000) })
|
||||
vi.advanceTimersByTime(1_500)
|
||||
notificationDispatch.mockClear()
|
||||
|
||||
useAppStore.setState({
|
||||
runtimeStatusByEnvironmentId: new Map([
|
||||
[ENVIRONMENT_ID, { status: null, connectionGeneration: 1 }]
|
||||
]) as AppState['runtimeStatusByEnvironmentId'],
|
||||
agentStatusByPaneKey: {}
|
||||
})
|
||||
mocks.runtimeSessionMirrorEnvironmentKey.mockReturnValue('')
|
||||
hook.rerender()
|
||||
await act(settle)
|
||||
|
||||
runtimeCall.mockResolvedValueOnce({
|
||||
id: 'same-version-list-all-replay',
|
||||
ok: true,
|
||||
result: { snapshots: [snapshot(2, 'waiting', NOW + 1_000)] },
|
||||
_meta: { runtimeId: RUNTIME_ID }
|
||||
})
|
||||
useAppStore.setState({
|
||||
runtimeStatusByEnvironmentId: new Map([
|
||||
[ENVIRONMENT_ID, { status: { runtimeId: RUNTIME_ID }, connectionGeneration: 2 }]
|
||||
]) as AppState['runtimeStatusByEnvironmentId']
|
||||
})
|
||||
mocks.runtimeSessionMirrorEnvironmentKey.mockReturnValue(RECONNECTED_MIRROR_KEY)
|
||||
hook.rerender()
|
||||
await act(settle)
|
||||
vi.advanceTimersByTime(1_500)
|
||||
|
||||
expect(useAppStore.getState().agentStatusByPaneKey[PANE_KEY]).toMatchObject({
|
||||
state: 'waiting'
|
||||
})
|
||||
expect(notificationDispatch).not.toHaveBeenCalled()
|
||||
hook.unmount()
|
||||
})
|
||||
|
||||
it('keeps newer inventory eligibility when older recovery finishes last', async () => {
|
||||
const hook = renderHook(() => useWebSessionTabsSync())
|
||||
await act(settle)
|
||||
|
||||
@@ -595,6 +595,12 @@ export function acceptReplayedWebSessionTabsSnapshot(
|
||||
}
|
||||
}
|
||||
|
||||
function acceptReplayedWebSessionTabsEnvironment(environmentId: string): void {
|
||||
for (const { worktree } of getTrackedWebSessionTabsWorktrees(environmentId)) {
|
||||
acceptReplayedWebSessionTabsSnapshot(environmentId, worktree)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A frame's fate, paired with whether that fate is host evidence for the
|
||||
* worktree — the mirror latch reads the pair, never a bare boolean.
|
||||
@@ -4401,6 +4407,7 @@ export function useWebSessionTabsSync(): void {
|
||||
if (currentOwnerRevisions.get(environmentId) !== previousRevision) {
|
||||
clearWebSessionTabsTrackingForEnvironment(environmentId)
|
||||
} else if (!mirroredEnvironmentOwnerRevisions.has(environmentId)) {
|
||||
acceptReplayedWebSessionTabsEnvironment(environmentId)
|
||||
mirroredEnvironmentOwnerRevisions.set(environmentId, previousRevision)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user