Merge pull request 'perf(apps): launch never waits on the credentials RPC — 1.2s budget + memo' (#119) from fix/apps-launch-latency into main
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m52s

This commit is contained in:
lfg2025 2026-07-24 08:14:47 +00:00
commit 0fa2a866f5

View File

@ -646,37 +646,51 @@ function launchAppNow(id: string) {
useAppLauncherStore().openSession(id) useAppLauncherStore().openSession(id)
} }
async function maybeShowCredentialsBeforeLaunch(id: string): Promise<boolean> { // Per-app credentials memo: the pre-launch RPC could hold an Apps-tab launch
try { // hostage for its full 5s timeout over the mesh (home-card launches skip this
const result = await rpcClient.call<AppCredentialsResponse>({ // gate entirely, which is why they always felt instant). First launch waits at
// most LAUNCH_CRED_BUDGET_MS; the RPC keeps running in the background and its
// answer is memoized, so every later launch of that app resolves instantly.
const LAUNCH_CRED_BUDGET_MS = 1200
const credentialsCache = new Map<string, AppCredentialsResponse | null>()
function fetchCredentials(id: string): Promise<AppCredentialsResponse | null> {
return rpcClient
.call<AppCredentialsResponse>({
method: 'package.credentials', method: 'package.credentials',
params: { app_id: id }, params: { app_id: id },
timeout: 5000, timeout: 5000,
}) })
const credentials = resolveAppCredentials(id, result) .then((r) => {
if (!credentials) return false credentialsCache.set(id, r)
credentialModal.value = { return r
show: true, })
appId: id, .catch(() => {
title: credentials.title || `${packages.value[id]?.manifest.title || id} credentials`, credentialsCache.set(id, null)
description: credentials.description || 'Use these credentials when the app asks you to sign in.', return null
credentials: credentials.credentials, })
copied: '', }
}
return true async function maybeShowCredentialsBeforeLaunch(id: string): Promise<boolean> {
} catch { const result = credentialsCache.has(id)
const credentials = resolveAppCredentials(id, null) ? credentialsCache.get(id) ?? null
if (!credentials) return false : await Promise.race([
credentialModal.value = { fetchCredentials(id),
show: true, // Budget exceeded launch with the static fallback config; the
appId: id, // in-flight RPC still lands in the cache for next time.
title: credentials.title || `${packages.value[id]?.manifest.title || id} credentials`, new Promise<null>((resolve) => setTimeout(() => resolve(null), LAUNCH_CRED_BUDGET_MS)),
description: credentials.description || 'Use these credentials when the app asks you to sign in.', ])
credentials: credentials.credentials, const credentials = resolveAppCredentials(id, result)
copied: '', if (!credentials) return false
} credentialModal.value = {
return true show: true,
appId: id,
title: credentials.title || `${packages.value[id]?.manifest.title || id} credentials`,
description: credentials.description || 'Use these credentials when the app asks you to sign in.',
credentials: credentials.credentials,
copied: '',
} }
return true
} }
function closeCredentialModal() { function closeCredentialModal() {