Skip to content

Commit f736116

Browse files
authored
fix(app): more startup efficiency (#19454)
1 parent 82fc493 commit f736116

19 files changed

+251
-205
lines changed

packages/app/e2e/settings/settings.spec.ts

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,15 @@ test("typing a code font with spaces persists and updates CSS variable", async (
159159
const dialog = await openSettings(page)
160160
const input = dialog.locator(settingsCodeFontSelector)
161161
await expect(input).toBeVisible()
162-
await expect(input).toHaveAttribute("placeholder", "IBM Plex Mono")
162+
await expect(input).toHaveAttribute("placeholder", "System Mono")
163163

164164
const initialFontFamily = await page.evaluate(() =>
165165
getComputedStyle(document.documentElement).getPropertyValue("--font-family-mono").trim(),
166166
)
167167
const initialUIFamily = await page.evaluate(() =>
168168
getComputedStyle(document.documentElement).getPropertyValue("--font-family-sans").trim(),
169169
)
170-
expect(initialFontFamily).toContain("IBM Plex Mono")
170+
expect(initialFontFamily).toContain("ui-monospace")
171171

172172
const next = "Test Mono"
173173

@@ -185,7 +185,7 @@ test("typing a code font with spaces persists and updates CSS variable", async (
185185
})
186186
.toMatchObject({
187187
appearance: {
188-
font: next,
188+
mono: next,
189189
},
190190
})
191191

@@ -206,15 +206,15 @@ test("typing a UI font with spaces persists and updates CSS variable", async ({
206206
const dialog = await openSettings(page)
207207
const input = dialog.locator(settingsUIFontSelector)
208208
await expect(input).toBeVisible()
209-
await expect(input).toHaveAttribute("placeholder", "Inter")
209+
await expect(input).toHaveAttribute("placeholder", "System Sans")
210210

211211
const initialFontFamily = await page.evaluate(() =>
212212
getComputedStyle(document.documentElement).getPropertyValue("--font-family-sans").trim(),
213213
)
214214
const initialCodeFamily = await page.evaluate(() =>
215215
getComputedStyle(document.documentElement).getPropertyValue("--font-family-mono").trim(),
216216
)
217-
expect(initialFontFamily).toContain("Inter")
217+
expect(initialFontFamily).toContain("ui-sans-serif")
218218

219219
const next = "Test Sans"
220220

@@ -232,7 +232,7 @@ test("typing a UI font with spaces persists and updates CSS variable", async ({
232232
})
233233
.toMatchObject({
234234
appearance: {
235-
uiFont: next,
235+
sans: next,
236236
},
237237
})
238238

@@ -267,14 +267,14 @@ test("clearing the code font field restores the default placeholder and stack",
267267
})
268268
.toMatchObject({
269269
appearance: {
270-
font: "Reset Mono",
270+
mono: "Reset Mono",
271271
},
272272
})
273273

274274
await input.clear()
275275
await input.press("Space")
276276
await expect(input).toHaveValue("")
277-
await expect(input).toHaveAttribute("placeholder", "IBM Plex Mono")
277+
await expect(input).toHaveAttribute("placeholder", "System Mono")
278278

279279
await expect
280280
.poll(async () => {
@@ -285,14 +285,14 @@ test("clearing the code font field restores the default placeholder and stack",
285285
})
286286
.toMatchObject({
287287
appearance: {
288-
font: "",
288+
mono: "",
289289
},
290290
})
291291

292292
const fontFamily = await page.evaluate(() =>
293293
getComputedStyle(document.documentElement).getPropertyValue("--font-family-mono").trim(),
294294
)
295-
expect(fontFamily).toContain("IBM Plex Mono")
295+
expect(fontFamily).toContain("ui-monospace")
296296
expect(fontFamily).not.toContain("Reset Mono")
297297
})
298298

@@ -316,14 +316,14 @@ test("clearing the UI font field restores the default placeholder and stack", as
316316
})
317317
.toMatchObject({
318318
appearance: {
319-
uiFont: "Reset Sans",
319+
sans: "Reset Sans",
320320
},
321321
})
322322

323323
await input.clear()
324324
await input.press("Space")
325325
await expect(input).toHaveValue("")
326-
await expect(input).toHaveAttribute("placeholder", "Inter")
326+
await expect(input).toHaveAttribute("placeholder", "System Sans")
327327

328328
await expect
329329
.poll(async () => {
@@ -334,14 +334,14 @@ test("clearing the UI font field restores the default placeholder and stack", as
334334
})
335335
.toMatchObject({
336336
appearance: {
337-
uiFont: "",
337+
sans: "",
338338
},
339339
})
340340

341341
const fontFamily = await page.evaluate(() =>
342342
getComputedStyle(document.documentElement).getPropertyValue("--font-family-sans").trim(),
343343
)
344-
expect(fontFamily).toContain("Inter")
344+
expect(fontFamily).toContain("ui-sans-serif")
345345
expect(fontFamily).not.toContain("Reset Sans")
346346
})
347347

@@ -373,8 +373,8 @@ test("color scheme, code font, and UI font rehydrate after reload", async ({ pag
373373
return raw ? JSON.parse(raw) : null
374374
}, settingsKey)
375375

376-
const mono = initialSettings?.appearance?.font === "Reload Mono" ? "Reload Mono 2" : "Reload Mono"
377-
const sans = initialSettings?.appearance?.uiFont === "Reload Sans" ? "Reload Sans 2" : "Reload Sans"
376+
const mono = initialSettings?.appearance?.mono === "Reload Mono" ? "Reload Mono 2" : "Reload Mono"
377+
const sans = initialSettings?.appearance?.sans === "Reload Sans" ? "Reload Sans 2" : "Reload Sans"
378378

379379
await code.click()
380380
await code.clear()
@@ -395,8 +395,8 @@ test("color scheme, code font, and UI font rehydrate after reload", async ({ pag
395395
})
396396
.toMatchObject({
397397
appearance: {
398-
font: mono,
399-
uiFont: sans,
398+
mono,
399+
sans,
400400
},
401401
})
402402

@@ -415,8 +415,8 @@ test("color scheme, code font, and UI font rehydrate after reload", async ({ pag
415415
expect(updatedMono).not.toBe(initialMono)
416416
expect(updatedSans).toContain(sans)
417417
expect(updatedSans).not.toBe(initialSans)
418-
expect(updatedSettings?.appearance?.font).toBe(mono)
419-
expect(updatedSettings?.appearance?.uiFont).toBe(sans)
418+
expect(updatedSettings?.appearance?.mono).toBe(mono)
419+
expect(updatedSettings?.appearance?.sans).toBe(sans)
420420

421421
await closeDialog(page, dialog)
422422
await page.reload()
@@ -432,8 +432,8 @@ test("color scheme, code font, and UI font rehydrate after reload", async ({ pag
432432
})
433433
.toMatchObject({
434434
appearance: {
435-
font: mono,
436-
uiFont: sans,
435+
mono,
436+
sans,
437437
},
438438
})
439439

@@ -468,8 +468,8 @@ test("color scheme, code font, and UI font rehydrate after reload", async ({ pag
468468
expect(rehydratedMono).not.toBe(initialMono)
469469
expect(rehydratedSans).toContain(sans)
470470
expect(rehydratedSans).not.toBe(initialSans)
471-
expect(rehydratedSettings?.appearance?.font).toBe(mono)
472-
expect(rehydratedSettings?.appearance?.uiFont).toBe(sans)
471+
expect(rehydratedSettings?.appearance?.mono).toBe(mono)
472+
expect(rehydratedSettings?.appearance?.sans).toBe(sans)
473473
})
474474

475475
test("toggling notification agent switch updates localStorage", async ({ page, gotoSession }) => {

packages/app/src/app.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,14 @@ import { ErrorPage } from "./pages/error"
4747
import { useCheckServerHealth } from "./utils/server-health"
4848

4949
const HomeRoute = lazy(() => import("@/pages/home"))
50-
const Session = lazy(() => import("@/pages/session"))
50+
const loadSession = () => import("@/pages/session")
51+
const Session = lazy(loadSession)
5152
const Loading = () => <div class="size-full" />
5253

54+
if (typeof location === "object" && /\/session(?:\/|$)/.test(location.pathname)) {
55+
void loadSession()
56+
}
57+
5358
const SessionRoute = () => (
5459
<SessionProviders>
5560
<Session />
@@ -278,7 +283,11 @@ export function AppInterface(props: {
278283
disableHealthCheck?: boolean
279284
}) {
280285
return (
281-
<ServerProvider defaultServer={props.defaultServer} servers={props.servers}>
286+
<ServerProvider
287+
defaultServer={props.defaultServer}
288+
disableHealthCheck={props.disableHealthCheck}
289+
servers={props.servers}
290+
>
282291
<ConnectionGate disableHealthCheck={props.disableHealthCheck}>
283292
<ServerKey>
284293
<GlobalSDKProvider>

packages/app/src/context/global-sdk.tsx

Lines changed: 82 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
105105
const aborted = (error: unknown) => abortError.safeParse(error).success
106106

107107
let attempt: AbortController | undefined
108+
let run: Promise<void> | undefined
109+
let started = false
108110
const HEARTBEAT_TIMEOUT_MS = 15_000
109111
let lastEventAt = Date.now()
110112
let heartbeat: ReturnType<typeof setTimeout> | undefined
@@ -121,78 +123,93 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
121123
heartbeat = undefined
122124
}
123125

124-
void (async () => {
125-
while (!abort.signal.aborted) {
126-
attempt = new AbortController()
127-
lastEventAt = Date.now()
128-
const onAbort = () => {
129-
attempt?.abort()
130-
}
131-
abort.signal.addEventListener("abort", onAbort)
132-
try {
133-
const events = await eventSdk.global.event({
134-
signal: attempt.signal,
135-
onSseError: (error) => {
136-
if (aborted(error)) return
137-
if (streamErrorLogged) return
126+
const start = () => {
127+
if (started) return run
128+
started = true
129+
run = (async () => {
130+
while (!abort.signal.aborted && started) {
131+
attempt = new AbortController()
132+
lastEventAt = Date.now()
133+
const onAbort = () => {
134+
attempt?.abort()
135+
}
136+
abort.signal.addEventListener("abort", onAbort)
137+
try {
138+
const events = await eventSdk.global.event({
139+
signal: attempt.signal,
140+
onSseError: (error) => {
141+
if (aborted(error)) return
142+
if (streamErrorLogged) return
143+
streamErrorLogged = true
144+
console.error("[global-sdk] event stream error", {
145+
url: currentServer.http.url,
146+
fetch: eventFetch ? "platform" : "webview",
147+
error,
148+
})
149+
},
150+
})
151+
let yielded = Date.now()
152+
resetHeartbeat()
153+
for await (const event of events.stream) {
154+
resetHeartbeat()
155+
streamErrorLogged = false
156+
const directory = event.directory ?? "global"
157+
const payload = event.payload
158+
const k = key(directory, payload)
159+
if (k) {
160+
const i = coalesced.get(k)
161+
if (i !== undefined) {
162+
queue[i] = { directory, payload }
163+
if (payload.type === "message.part.updated") {
164+
const part = payload.properties.part
165+
staleDeltas.add(deltaKey(directory, part.messageID, part.id))
166+
}
167+
continue
168+
}
169+
coalesced.set(k, queue.length)
170+
}
171+
queue.push({ directory, payload })
172+
schedule()
173+
174+
if (Date.now() - yielded < STREAM_YIELD_MS) continue
175+
yielded = Date.now()
176+
await wait(0)
177+
}
178+
} catch (error) {
179+
if (!aborted(error) && !streamErrorLogged) {
138180
streamErrorLogged = true
139-
console.error("[global-sdk] event stream error", {
181+
console.error("[global-sdk] event stream failed", {
140182
url: currentServer.http.url,
141183
fetch: eventFetch ? "platform" : "webview",
142184
error,
143185
})
144-
},
145-
})
146-
let yielded = Date.now()
147-
resetHeartbeat()
148-
for await (const event of events.stream) {
149-
resetHeartbeat()
150-
streamErrorLogged = false
151-
const directory = event.directory ?? "global"
152-
const payload = event.payload
153-
const k = key(directory, payload)
154-
if (k) {
155-
const i = coalesced.get(k)
156-
if (i !== undefined) {
157-
queue[i] = { directory, payload }
158-
if (payload.type === "message.part.updated") {
159-
const part = payload.properties.part
160-
staleDeltas.add(deltaKey(directory, part.messageID, part.id))
161-
}
162-
continue
163-
}
164-
coalesced.set(k, queue.length)
165186
}
166-
queue.push({ directory, payload })
167-
schedule()
168-
169-
if (Date.now() - yielded < STREAM_YIELD_MS) continue
170-
yielded = Date.now()
171-
await wait(0)
172-
}
173-
} catch (error) {
174-
if (!aborted(error) && !streamErrorLogged) {
175-
streamErrorLogged = true
176-
console.error("[global-sdk] event stream failed", {
177-
url: currentServer.http.url,
178-
fetch: eventFetch ? "platform" : "webview",
179-
error,
180-
})
187+
} finally {
188+
abort.signal.removeEventListener("abort", onAbort)
189+
attempt = undefined
190+
clearHeartbeat()
181191
}
182-
} finally {
183-
abort.signal.removeEventListener("abort", onAbort)
184-
attempt = undefined
185-
clearHeartbeat()
192+
193+
if (abort.signal.aborted || !started) return
194+
await wait(RECONNECT_DELAY_MS)
186195
}
196+
})().finally(() => {
197+
run = undefined
198+
flush()
199+
})
200+
return run
201+
}
187202

188-
if (abort.signal.aborted) return
189-
await wait(RECONNECT_DELAY_MS)
190-
}
191-
})().finally(flush)
203+
const stop = () => {
204+
started = false
205+
attempt?.abort()
206+
clearHeartbeat()
207+
}
192208

193209
const onVisibility = () => {
194210
if (typeof document === "undefined") return
195211
if (document.visibilityState !== "visible") return
212+
if (!started) return
196213
if (Date.now() - lastEventAt < HEARTBEAT_TIMEOUT_MS) return
197214
attempt?.abort()
198215
}
@@ -204,6 +221,7 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
204221
if (typeof document !== "undefined") {
205222
document.removeEventListener("visibilitychange", onVisibility)
206223
}
224+
stop()
207225
abort.abort()
208226
flush()
209227
})
@@ -217,7 +235,11 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
217235
return {
218236
url: currentServer.http.url,
219237
client: sdk,
220-
event: emitter,
238+
event: {
239+
on: emitter.on.bind(emitter),
240+
listen: emitter.listen.bind(emitter),
241+
start,
242+
},
221243
createClient(opts: Omit<Parameters<typeof createSdkForServer>[0], "server" | "fetch">) {
222244
const s = server.current
223245
if (!s) throw new Error(language.t("error.globalSDK.serverNotAvailable"))

0 commit comments

Comments
 (0)