Skip to content

Commit c147443

Browse files
committed
feat(browser): execute client page commands locally
1 parent ac4461f commit c147443

11 files changed

Lines changed: 1390 additions & 61 deletions

config/reliability-gates.jsonc

Lines changed: 28 additions & 11 deletions
Large diffs are not rendered by default.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import type { BrowserRouteGuestLifecycleClaim } from './browser-route-page-authority'
2+
import type { BrowserRouteSessionHandle } from './browser-route-session-state'
3+
import type { BrowserRouteProxyEndpoint } from './browser-route-session-policy'
4+
import type { BrowserRouteWebContentsRegistry } from './browser-route-webcontents-registry'
5+
6+
export type BrowserClientPageNetworkRoute = {
7+
key: string
8+
executionHostIdentity: string
9+
proxyEndpoint: BrowserRouteProxyEndpoint
10+
release(): void | Promise<void>
11+
}
12+
13+
export type BrowserClientPageRendererIdentity = Readonly<{
14+
partition: string
15+
browserPageId: string
16+
pageHostGeneration: number
17+
}>
18+
19+
export type BrowserClientPageRenderer = {
20+
rendererWebContentsId: number
21+
isCurrent(): boolean
22+
mountPage(
23+
page: BrowserClientPageRendererIdentity,
24+
signal: AbortSignal
25+
): Promise<{ webContentsId: number }>
26+
retirePage(page: BrowserClientPageRendererIdentity): void | Promise<void>
27+
}
28+
29+
export async function cleanupBrowserClientPage(
30+
routeWebContents: Pick<BrowserRouteWebContentsRegistry, 'beginGuestRetirement'>,
31+
target: {
32+
guestMayExist: boolean
33+
lifecycleClaim: BrowserRouteGuestLifecycleClaim | null
34+
renderer: BrowserClientPageRenderer | null
35+
rendererPage: BrowserClientPageRendererIdentity | null
36+
routeSession: BrowserRouteSessionHandle | null
37+
route: BrowserClientPageNetworkRoute | null
38+
}
39+
): Promise<void> {
40+
const failures: unknown[] = []
41+
const guestDestruction = target.lifecycleClaim?.whenDestroyed ?? null
42+
let guestDestroyed = !target.guestMayExist
43+
if (target.guestMayExist && !target.lifecycleClaim) {
44+
failures.push(new Error('Browser client page guest destruction was not observable'))
45+
}
46+
if (target.lifecycleClaim) {
47+
try {
48+
if (!routeWebContents.beginGuestRetirement(target.lifecycleClaim)) {
49+
failures.push(new Error('Browser client page guest retirement was not admitted'))
50+
}
51+
} catch (error) {
52+
failures.push(error)
53+
}
54+
}
55+
const renderer = target.renderer
56+
const rendererPage = target.rendererPage
57+
if (renderer && rendererPage) {
58+
await collectCleanupFailure(() => renderer.retirePage(rendererPage), failures)
59+
}
60+
if (guestDestruction) {
61+
guestDestroyed = await collectCleanupFailure(() => guestDestruction, failures)
62+
}
63+
const routeSession = target.routeSession
64+
if (routeSession && guestDestroyed) {
65+
await collectCleanupFailure(() => routeSession.release(), failures)
66+
}
67+
const route = target.route
68+
if (route && guestDestroyed) {
69+
await collectCleanupFailure(() => route.release(), failures)
70+
}
71+
if (failures.length > 0) {
72+
throw new AggregateError(failures, 'Browser client page cleanup failed')
73+
}
74+
}
75+
76+
async function collectCleanupFailure(
77+
cleanup: () => void | Promise<void>,
78+
failures: unknown[]
79+
): Promise<boolean> {
80+
try {
81+
await cleanup()
82+
return true
83+
} catch (error) {
84+
failures.push(error)
85+
return false
86+
}
87+
}

0 commit comments

Comments
 (0)