Skip to content

Commit cbe1337

Browse files
committed
Revert "fix(app): more startup efficiency (anomalyco#18985)"
This reverts commit 98b3340.
1 parent 50f6aa3 commit cbe1337

8 files changed

Lines changed: 129 additions & 241 deletions

File tree

packages/app/src/components/prompt-input.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,6 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
572572
const open = recent()
573573
const seen = new Set(open)
574574
const pinned: AtOption[] = open.map((path) => ({ type: "file", path, display: path, recent: true }))
575-
if (!query.trim()) return [...agents, ...pinned]
576575
const paths = await files.searchFilesAndDirectories(query)
577576
const fileOptions: AtOption[] = paths
578577
.filter((path) => !seen.has(path))

packages/app/src/context/global-sync/bootstrap.ts

Lines changed: 121 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -31,102 +31,52 @@ type GlobalStore = {
3131
reload: undefined | "pending" | "complete"
3232
}
3333

34-
function waitForPaint() {
35-
return new Promise<void>((resolve) => {
36-
let done = false
37-
const finish = () => {
38-
if (done) return
39-
done = true
40-
resolve()
41-
}
42-
const timer = setTimeout(finish, 50)
43-
if (typeof requestAnimationFrame !== "function") return
44-
requestAnimationFrame(() => {
45-
clearTimeout(timer)
46-
finish()
47-
})
48-
})
49-
}
50-
51-
function errors(list: PromiseSettledResult<unknown>[]) {
52-
return list.filter((item): item is PromiseRejectedResult => item.status === "rejected").map((item) => item.reason)
53-
}
54-
55-
function runAll(list: Array<() => Promise<unknown>>) {
56-
return Promise.allSettled(list.map((item) => item()))
57-
}
58-
59-
function showErrors(input: {
60-
errors: unknown[]
61-
title: string
62-
translate: (key: string, vars?: Record<string, string | number>) => string
63-
formatMoreCount: (count: number) => string
64-
}) {
65-
if (input.errors.length === 0) return
66-
const message = formatServerError(input.errors[0], input.translate)
67-
const more = input.errors.length > 1 ? input.formatMoreCount(input.errors.length - 1) : ""
68-
showToast({
69-
variant: "error",
70-
title: input.title,
71-
description: message + more,
72-
})
73-
}
74-
7534
export async function bootstrapGlobal(input: {
7635
globalSDK: OpencodeClient
7736
requestFailedTitle: string
7837
translate: (key: string, vars?: Record<string, string | number>) => string
7938
formatMoreCount: (count: number) => string
8039
setGlobalStore: SetStoreFunction<GlobalStore>
8140
}) {
82-
const fast = [
83-
() =>
84-
retry(() =>
85-
input.globalSDK.path.get().then((x) => {
86-
input.setGlobalStore("path", x.data!)
87-
}),
88-
),
89-
() =>
90-
retry(() =>
91-
input.globalSDK.global.config.get().then((x) => {
92-
input.setGlobalStore("config", x.data!)
93-
}),
94-
),
95-
() =>
96-
retry(() =>
97-
input.globalSDK.provider.list().then((x) => {
98-
input.setGlobalStore("provider", normalizeProviderList(x.data!))
99-
}),
100-
),
41+
const tasks = [
42+
retry(() =>
43+
input.globalSDK.path.get().then((x) => {
44+
input.setGlobalStore("path", x.data!)
45+
}),
46+
),
47+
retry(() =>
48+
input.globalSDK.global.config.get().then((x) => {
49+
input.setGlobalStore("config", x.data!)
50+
}),
51+
),
52+
retry(() =>
53+
input.globalSDK.project.list().then((x) => {
54+
const projects = (x.data ?? [])
55+
.filter((p) => !!p?.id)
56+
.filter((p) => !!p.worktree && !p.worktree.includes("opencode-test"))
57+
.slice()
58+
.sort((a, b) => cmp(a.id, b.id))
59+
input.setGlobalStore("project", projects)
60+
}),
61+
),
62+
retry(() =>
63+
input.globalSDK.provider.list().then((x) => {
64+
input.setGlobalStore("provider", normalizeProviderList(x.data!))
65+
}),
66+
),
10167
]
10268

103-
const slow = [
104-
() =>
105-
retry(() =>
106-
input.globalSDK.project.list().then((x) => {
107-
const projects = (x.data ?? [])
108-
.filter((p) => !!p?.id)
109-
.filter((p) => !!p.worktree && !p.worktree.includes("opencode-test"))
110-
.slice()
111-
.sort((a, b) => cmp(a.id, b.id))
112-
input.setGlobalStore("project", projects)
113-
}),
114-
),
115-
]
116-
117-
showErrors({
118-
errors: errors(await runAll(fast)),
119-
title: input.requestFailedTitle,
120-
translate: input.translate,
121-
formatMoreCount: input.formatMoreCount,
122-
})
123-
await waitForPaint()
124-
showErrors({
125-
errors: errors(await runAll(slow)),
126-
title: input.requestFailedTitle,
127-
translate: input.translate,
128-
formatMoreCount: input.formatMoreCount,
129-
})
69+
const results = await Promise.allSettled(tasks)
70+
const errors = results.filter((r): r is PromiseRejectedResult => r.status === "rejected").map((r) => r.reason)
71+
if (errors.length) {
72+
const message = formatServerError(errors[0], input.translate)
73+
const more = errors.length > 1 ? input.formatMoreCount(errors.length - 1) : ""
74+
showToast({
75+
variant: "error",
76+
title: input.requestFailedTitle,
77+
description: message + more,
78+
})
79+
}
13080
input.setGlobalStore("ready", true)
13181
}
13282

@@ -169,113 +119,95 @@ export async function bootstrapDirectory(input: {
169119
}
170120
if (loading) input.setStore("status", "partial")
171121

172-
const fast = [
173-
() =>
174-
seededProject
175-
? Promise.resolve()
176-
: retry(() => input.sdk.project.current()).then((x) => input.setStore("project", x.data!.id)),
177-
() => retry(() => input.sdk.app.agents().then((x) => input.setStore("agent", x.data ?? []))),
178-
() => retry(() => input.sdk.config.get().then((x) => input.setStore("config", x.data!))),
179-
() =>
180-
retry(() =>
181-
input.sdk.path.get().then((x) => {
182-
input.setStore("path", x.data!)
183-
const next = projectID(x.data?.directory ?? input.directory, input.global.project)
184-
if (next) input.setStore("project", next)
185-
}),
186-
),
187-
() => retry(() => input.sdk.session.status().then((x) => input.setStore("session_status", x.data!))),
188-
() =>
189-
retry(() =>
190-
input.sdk.vcs.get().then((x) => {
191-
const next = x.data ?? input.store.vcs
192-
input.setStore("vcs", next)
193-
if (next?.branch) input.vcsCache.setStore("value", next)
194-
}),
195-
),
196-
() => retry(() => input.sdk.command.list().then((x) => input.setStore("command", x.data ?? []))),
197-
() =>
198-
retry(() =>
199-
input.sdk.permission.list().then((x) => {
200-
const grouped = groupBySession(
201-
(x.data ?? []).filter((perm): perm is PermissionRequest => !!perm?.id && !!perm.sessionID),
202-
)
203-
batch(() => {
204-
for (const sessionID of Object.keys(input.store.permission)) {
205-
if (grouped[sessionID]) continue
206-
input.setStore("permission", sessionID, [])
207-
}
208-
for (const [sessionID, permissions] of Object.entries(grouped)) {
209-
input.setStore(
210-
"permission",
211-
sessionID,
212-
reconcile(
213-
permissions.filter((p) => !!p?.id).sort((a, b) => cmp(a.id, b.id)),
214-
{ key: "id" },
215-
),
216-
)
217-
}
218-
})
219-
}),
220-
),
221-
() =>
222-
retry(() =>
223-
input.sdk.question.list().then((x) => {
224-
const grouped = groupBySession((x.data ?? []).filter((q): q is QuestionRequest => !!q?.id && !!q.sessionID))
225-
batch(() => {
226-
for (const sessionID of Object.keys(input.store.question)) {
227-
if (grouped[sessionID]) continue
228-
input.setStore("question", sessionID, [])
229-
}
230-
for (const [sessionID, questions] of Object.entries(grouped)) {
231-
input.setStore(
232-
"question",
233-
sessionID,
234-
reconcile(
235-
questions.filter((q) => !!q?.id).sort((a, b) => cmp(a.id, b.id)),
236-
{ key: "id" },
237-
),
238-
)
239-
}
240-
})
241-
}),
242-
),
243-
]
244-
245-
const slow = [
246-
() =>
247-
retry(() =>
248-
input.sdk.provider.list().then((x) => {
249-
input.setStore("provider", normalizeProviderList(x.data!))
250-
}),
251-
),
252-
() => Promise.resolve(input.loadSessions(input.directory)),
253-
() => retry(() => input.sdk.mcp.status().then((x) => input.setStore("mcp", x.data!))),
254-
() => retry(() => input.sdk.lsp.status().then((x) => input.setStore("lsp", x.data!))),
255-
]
256-
257-
const errs = errors(await runAll(fast))
258-
if (errs.length > 0) {
259-
console.error("Failed to bootstrap instance", errs[0])
260-
const project = getFilename(input.directory)
261-
showToast({
262-
variant: "error",
263-
title: input.translate("toast.project.reloadFailed.title", { project }),
264-
description: formatServerError(errs[0], input.translate),
265-
})
266-
}
267-
268-
await waitForPaint()
269-
const slowErrs = errors(await runAll(slow))
270-
if (slowErrs.length > 0) {
271-
console.error("Failed to finish bootstrap instance", slowErrs[0])
122+
const results = await Promise.allSettled([
123+
seededProject
124+
? Promise.resolve()
125+
: retry(() => input.sdk.project.current()).then((x) => input.setStore("project", x.data!.id)),
126+
retry(() =>
127+
input.sdk.provider.list().then((x) => {
128+
input.setStore("provider", normalizeProviderList(x.data!))
129+
}),
130+
),
131+
retry(() => input.sdk.app.agents().then((x) => input.setStore("agent", x.data ?? []))),
132+
retry(() => input.sdk.config.get().then((x) => input.setStore("config", x.data!))),
133+
retry(() =>
134+
input.sdk.path.get().then((x) => {
135+
input.setStore("path", x.data!)
136+
const next = projectID(x.data?.directory ?? input.directory, input.global.project)
137+
if (next) input.setStore("project", next)
138+
}),
139+
),
140+
retry(() => input.sdk.command.list().then((x) => input.setStore("command", x.data ?? []))),
141+
retry(() => input.sdk.session.status().then((x) => input.setStore("session_status", x.data!))),
142+
input.loadSessions(input.directory),
143+
retry(() => input.sdk.mcp.status().then((x) => input.setStore("mcp", x.data!))),
144+
retry(() => input.sdk.lsp.status().then((x) => input.setStore("lsp", x.data!))),
145+
retry(() =>
146+
input.sdk.vcs.get().then((x) => {
147+
const next = x.data ?? input.store.vcs
148+
input.setStore("vcs", next)
149+
if (next?.branch) input.vcsCache.setStore("value", next)
150+
}),
151+
),
152+
retry(() =>
153+
input.sdk.permission.list().then((x) => {
154+
const grouped = groupBySession(
155+
(x.data ?? []).filter((perm): perm is PermissionRequest => !!perm?.id && !!perm.sessionID),
156+
)
157+
batch(() => {
158+
for (const sessionID of Object.keys(input.store.permission)) {
159+
if (grouped[sessionID]) continue
160+
input.setStore("permission", sessionID, [])
161+
}
162+
for (const [sessionID, permissions] of Object.entries(grouped)) {
163+
input.setStore(
164+
"permission",
165+
sessionID,
166+
reconcile(
167+
permissions.filter((p) => !!p?.id).sort((a, b) => cmp(a.id, b.id)),
168+
{ key: "id" },
169+
),
170+
)
171+
}
172+
})
173+
}),
174+
),
175+
retry(() =>
176+
input.sdk.question.list().then((x) => {
177+
const grouped = groupBySession((x.data ?? []).filter((q): q is QuestionRequest => !!q?.id && !!q.sessionID))
178+
batch(() => {
179+
for (const sessionID of Object.keys(input.store.question)) {
180+
if (grouped[sessionID]) continue
181+
input.setStore("question", sessionID, [])
182+
}
183+
for (const [sessionID, questions] of Object.entries(grouped)) {
184+
input.setStore(
185+
"question",
186+
sessionID,
187+
reconcile(
188+
questions.filter((q) => !!q?.id).sort((a, b) => cmp(a.id, b.id)),
189+
{ key: "id" },
190+
),
191+
)
192+
}
193+
})
194+
}),
195+
),
196+
])
197+
198+
const errors = results
199+
.filter((item): item is PromiseRejectedResult => item.status === "rejected")
200+
.map((item) => item.reason)
201+
if (errors.length > 0) {
202+
console.error("Failed to bootstrap instance", errors[0])
272203
const project = getFilename(input.directory)
273204
showToast({
274205
variant: "error",
275206
title: input.translate("toast.project.reloadFailed.title", { project }),
276-
description: formatServerError(slowErrs[0], input.translate),
207+
description: formatServerError(errors[0], input.translate),
277208
})
209+
return
278210
}
279211

280-
if (loading && errs.length === 0 && slowErrs.length === 0) input.setStore("status", "complete")
212+
if (loading) input.setStore("status", "complete")
281213
}

packages/app/src/context/settings.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,8 @@ export const { use: useSettings, provider: SettingsProvider } = createSimpleCont
118118

119119
createEffect(() => {
120120
if (typeof document === "undefined") return
121-
const id = store.appearance?.font ?? defaultSettings.appearance.font
122-
if (id !== defaultSettings.appearance.font) {
123-
void loadFont().then((x) => x.ensureMonoFont(id))
124-
}
125-
document.documentElement.style.setProperty("--font-family-mono", monoFontFamily(id))
121+
void loadFont().then((x) => x.ensureMonoFont(store.appearance?.font))
122+
document.documentElement.style.setProperty("--font-family-mono", monoFontFamily(store.appearance?.font))
126123
})
127124

128125
return {

packages/app/src/context/sync.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
180180
return globalSync.child(directory)
181181
}
182182
const absolute = (path: string) => (current()[0].path.directory + "/" + path).replace("//", "/")
183-
const initialMessagePageSize = 80
184-
const historyMessagePageSize = 200
183+
const messagePageSize = 200
185184
const inflight = new Map<string, Promise<void>>()
186185
const inflightDiff = new Map<string, Promise<void>>()
187186
const inflightTodo = new Map<string, Promise<void>>()
@@ -464,7 +463,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
464463
const cached = store.message[sessionID] !== undefined && meta.limit[key] !== undefined
465464
if (cached && hasSession && !opts?.force) return
466465

467-
const limit = meta.limit[key] ?? initialMessagePageSize
466+
const limit = meta.limit[key] ?? messagePageSize
468467
const sessionReq =
469468
hasSession && !opts?.force
470469
? Promise.resolve()
@@ -561,7 +560,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
561560
const [, setStore] = globalSync.child(directory)
562561
touch(directory, setStore, sessionID)
563562
const key = keyFor(directory, sessionID)
564-
const step = count ?? historyMessagePageSize
563+
const step = count ?? messagePageSize
565564
if (meta.loading[key]) return
566565
if (meta.complete[key]) return
567566
const before = meta.cursor[key]

0 commit comments

Comments
 (0)