refactor(mobile-web): put the transport connection state on the wire

The shell collapsed six transport states into four, and every page route
expanded them back. Both mappings are gone; the page reads the state the
transport reported.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
This commit is contained in:
Jinwoo-H
2026-09-07 15:08:45 -04:00
parent effd8ec5de
commit f09f618f3b
15 changed files with 26 additions and 81 deletions
+2 -1
View File
@@ -15,6 +15,7 @@ import {
parseMobileWebBridgeInitialMessage,
parseMobileWebBridgeShellMessage,
type MobileWebBridgeMessageContext,
type MobileWebConnectionState,
type MobileWebNavigationRoute,
type MobileWebResumeRoute
} from '../../shared/mobile-web/bridge-contract'
@@ -29,7 +30,7 @@ import { subscribeToMobileWebShellMessages } from './native-shell-message-inbox'
export type MobileWebNativeShellState = {
client: MobileWebBridgeClient | null
context: MobileWebBridgeMessageContext | null
connection: 'connecting' | 'connected' | 'offline' | 'recovering'
connection: MobileWebConnectionState
hostDisplayName: string | null
reconnectAttempts: number
lastConnectedAt: number | null
@@ -516,7 +516,7 @@ describe('mobile web bridge shell contract', () => {
type: 'connection',
shellSessionId: SHELL_SESSION_ID,
buildId: BUILD_ID,
state: 'recovering'
state: 'reconnecting'
}
expect(
+10 -1
View File
@@ -165,7 +165,16 @@ const ShellEnvelopeSchema = z.object({
buildId: BuildIdSchema
})
const ConnectionStateSchema = z.enum(['connecting', 'connected', 'offline', 'recovering'])
// The shell publishes the transport's own state; the page decides what to show for each.
const ConnectionStateSchema = z.enum([
'connecting',
'handshaking',
'connected',
'disconnected',
'reconnecting',
'auth-failed'
])
export type MobileWebConnectionState = z.infer<typeof ConnectionStateSchema>
const ConnectionMetricsShape = {
reconnectAttempts: z.number().int().nonnegative().max(1_000_000).optional(),
lastConnectedAt: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).nullable().optional()