summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/utils
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-03-24 09:10:24 -0500
committerGitHub <[email protected]>2026-03-24 09:10:24 -0500
commit546748a461539ca63e188ee07ab2b143c5ac2c83 (patch)
tree1eb96ef20f37aaa533efe0f467d7c15628524dd7 /packages/app/src/utils
parentc9c93eac00bda356f4cf2b03e011d0b19e535952 (diff)
downloadopencode-546748a461539ca63e188ee07ab2b143c5ac2c83.tar.gz
opencode-546748a461539ca63e188ee07ab2b143c5ac2c83.zip
fix(app): startup efficiency (#18854)
Diffstat (limited to 'packages/app/src/utils')
-rw-r--r--packages/app/src/utils/server-health.ts24
-rw-r--r--packages/app/src/utils/sound.ts177
2 files changed, 104 insertions, 97 deletions
diff --git a/packages/app/src/utils/server-health.ts b/packages/app/src/utils/server-health.ts
index 45a323c7b..a13fd34ef 100644
--- a/packages/app/src/utils/server-health.ts
+++ b/packages/app/src/utils/server-health.ts
@@ -14,6 +14,15 @@ interface CheckServerHealthOptions {
const defaultTimeoutMs = 3000
const defaultRetryCount = 2
const defaultRetryDelayMs = 100
+const cacheMs = 750
+const healthCache = new Map<
+ string,
+ { at: number; done: boolean; fetch: typeof globalThis.fetch; promise: Promise<ServerHealth> }
+>()
+
+function cacheKey(server: ServerConnection.HttpBase) {
+ return `${server.url}\n${server.username ?? ""}\n${server.password ?? ""}`
+}
function timeoutSignal(timeoutMs: number) {
const timeout = (AbortSignal as unknown as { timeout?: (ms: number) => AbortSignal }).timeout
@@ -87,5 +96,18 @@ export function useCheckServerHealth() {
const platform = usePlatform()
const fetcher = platform.fetch ?? globalThis.fetch
- return (http: ServerConnection.HttpBase) => checkServerHealth(http, fetcher)
+ return (http: ServerConnection.HttpBase) => {
+ const key = cacheKey(http)
+ const hit = healthCache.get(key)
+ const now = Date.now()
+ if (hit && hit.fetch === fetcher && (!hit.done || now - hit.at < cacheMs)) return hit.promise
+ const promise = checkServerHealth(http, fetcher).finally(() => {
+ const next = healthCache.get(key)
+ if (!next || next.promise !== promise) return
+ next.done = true
+ next.at = Date.now()
+ })
+ healthCache.set(key, { at: now, done: false, fetch: fetcher, promise })
+ return promise
+ }
}
diff --git a/packages/app/src/utils/sound.ts b/packages/app/src/utils/sound.ts
index 6dea812ec..78e5a0c56 100644
--- a/packages/app/src/utils/sound.ts
+++ b/packages/app/src/utils/sound.ts
@@ -1,106 +1,89 @@
-import alert01 from "@opencode-ai/ui/audio/alert-01.aac"
-import alert02 from "@opencode-ai/ui/audio/alert-02.aac"
-import alert03 from "@opencode-ai/ui/audio/alert-03.aac"
-import alert04 from "@opencode-ai/ui/audio/alert-04.aac"
-import alert05 from "@opencode-ai/ui/audio/alert-05.aac"
-import alert06 from "@opencode-ai/ui/audio/alert-06.aac"
-import alert07 from "@opencode-ai/ui/audio/alert-07.aac"
-import alert08 from "@opencode-ai/ui/audio/alert-08.aac"
-import alert09 from "@opencode-ai/ui/audio/alert-09.aac"
-import alert10 from "@opencode-ai/ui/audio/alert-10.aac"
-import bipbop01 from "@opencode-ai/ui/audio/bip-bop-01.aac"
-import bipbop02 from "@opencode-ai/ui/audio/bip-bop-02.aac"
-import bipbop03 from "@opencode-ai/ui/audio/bip-bop-03.aac"
-import bipbop04 from "@opencode-ai/ui/audio/bip-bop-04.aac"
-import bipbop05 from "@opencode-ai/ui/audio/bip-bop-05.aac"
-import bipbop06 from "@opencode-ai/ui/audio/bip-bop-06.aac"
-import bipbop07 from "@opencode-ai/ui/audio/bip-bop-07.aac"
-import bipbop08 from "@opencode-ai/ui/audio/bip-bop-08.aac"
-import bipbop09 from "@opencode-ai/ui/audio/bip-bop-09.aac"
-import bipbop10 from "@opencode-ai/ui/audio/bip-bop-10.aac"
-import nope01 from "@opencode-ai/ui/audio/nope-01.aac"
-import nope02 from "@opencode-ai/ui/audio/nope-02.aac"
-import nope03 from "@opencode-ai/ui/audio/nope-03.aac"
-import nope04 from "@opencode-ai/ui/audio/nope-04.aac"
-import nope05 from "@opencode-ai/ui/audio/nope-05.aac"
-import nope06 from "@opencode-ai/ui/audio/nope-06.aac"
-import nope07 from "@opencode-ai/ui/audio/nope-07.aac"
-import nope08 from "@opencode-ai/ui/audio/nope-08.aac"
-import nope09 from "@opencode-ai/ui/audio/nope-09.aac"
-import nope10 from "@opencode-ai/ui/audio/nope-10.aac"
-import nope11 from "@opencode-ai/ui/audio/nope-11.aac"
-import nope12 from "@opencode-ai/ui/audio/nope-12.aac"
-import staplebops01 from "@opencode-ai/ui/audio/staplebops-01.aac"
-import staplebops02 from "@opencode-ai/ui/audio/staplebops-02.aac"
-import staplebops03 from "@opencode-ai/ui/audio/staplebops-03.aac"
-import staplebops04 from "@opencode-ai/ui/audio/staplebops-04.aac"
-import staplebops05 from "@opencode-ai/ui/audio/staplebops-05.aac"
-import staplebops06 from "@opencode-ai/ui/audio/staplebops-06.aac"
-import staplebops07 from "@opencode-ai/ui/audio/staplebops-07.aac"
-import yup01 from "@opencode-ai/ui/audio/yup-01.aac"
-import yup02 from "@opencode-ai/ui/audio/yup-02.aac"
-import yup03 from "@opencode-ai/ui/audio/yup-03.aac"
-import yup04 from "@opencode-ai/ui/audio/yup-04.aac"
-import yup05 from "@opencode-ai/ui/audio/yup-05.aac"
-import yup06 from "@opencode-ai/ui/audio/yup-06.aac"
+let files: Record<string, () => Promise<string>> | undefined
+let loads: Record<SoundID, () => Promise<string>> | undefined
+
+function getFiles() {
+ if (files) return files
+ files = import.meta.glob("../../../ui/src/assets/audio/*.aac", { import: "default" }) as Record<
+ string,
+ () => Promise<string>
+ >
+ return files
+}
export const SOUND_OPTIONS = [
- { id: "alert-01", label: "sound.option.alert01", src: alert01 },
- { id: "alert-02", label: "sound.option.alert02", src: alert02 },
- { id: "alert-03", label: "sound.option.alert03", src: alert03 },
- { id: "alert-04", label: "sound.option.alert04", src: alert04 },
- { id: "alert-05", label: "sound.option.alert05", src: alert05 },
- { id: "alert-06", label: "sound.option.alert06", src: alert06 },
- { id: "alert-07", label: "sound.option.alert07", src: alert07 },
- { id: "alert-08", label: "sound.option.alert08", src: alert08 },
- { id: "alert-09", label: "sound.option.alert09", src: alert09 },
- { id: "alert-10", label: "sound.option.alert10", src: alert10 },
- { id: "bip-bop-01", label: "sound.option.bipbop01", src: bipbop01 },
- { id: "bip-bop-02", label: "sound.option.bipbop02", src: bipbop02 },
- { id: "bip-bop-03", label: "sound.option.bipbop03", src: bipbop03 },
- { id: "bip-bop-04", label: "sound.option.bipbop04", src: bipbop04 },
- { id: "bip-bop-05", label: "sound.option.bipbop05", src: bipbop05 },
- { id: "bip-bop-06", label: "sound.option.bipbop06", src: bipbop06 },
- { id: "bip-bop-07", label: "sound.option.bipbop07", src: bipbop07 },
- { id: "bip-bop-08", label: "sound.option.bipbop08", src: bipbop08 },
- { id: "bip-bop-09", label: "sound.option.bipbop09", src: bipbop09 },
- { id: "bip-bop-10", label: "sound.option.bipbop10", src: bipbop10 },
- { id: "staplebops-01", label: "sound.option.staplebops01", src: staplebops01 },
- { id: "staplebops-02", label: "sound.option.staplebops02", src: staplebops02 },
- { id: "staplebops-03", label: "sound.option.staplebops03", src: staplebops03 },
- { id: "staplebops-04", label: "sound.option.staplebops04", src: staplebops04 },
- { id: "staplebops-05", label: "sound.option.staplebops05", src: staplebops05 },
- { id: "staplebops-06", label: "sound.option.staplebops06", src: staplebops06 },
- { id: "staplebops-07", label: "sound.option.staplebops07", src: staplebops07 },
- { id: "nope-01", label: "sound.option.nope01", src: nope01 },
- { id: "nope-02", label: "sound.option.nope02", src: nope02 },
- { id: "nope-03", label: "sound.option.nope03", src: nope03 },
- { id: "nope-04", label: "sound.option.nope04", src: nope04 },
- { id: "nope-05", label: "sound.option.nope05", src: nope05 },
- { id: "nope-06", label: "sound.option.nope06", src: nope06 },
- { id: "nope-07", label: "sound.option.nope07", src: nope07 },
- { id: "nope-08", label: "sound.option.nope08", src: nope08 },
- { id: "nope-09", label: "sound.option.nope09", src: nope09 },
- { id: "nope-10", label: "sound.option.nope10", src: nope10 },
- { id: "nope-11", label: "sound.option.nope11", src: nope11 },
- { id: "nope-12", label: "sound.option.nope12", src: nope12 },
- { id: "yup-01", label: "sound.option.yup01", src: yup01 },
- { id: "yup-02", label: "sound.option.yup02", src: yup02 },
- { id: "yup-03", label: "sound.option.yup03", src: yup03 },
- { id: "yup-04", label: "sound.option.yup04", src: yup04 },
- { id: "yup-05", label: "sound.option.yup05", src: yup05 },
- { id: "yup-06", label: "sound.option.yup06", src: yup06 },
+ { id: "alert-01", label: "sound.option.alert01" },
+ { id: "alert-02", label: "sound.option.alert02" },
+ { id: "alert-03", label: "sound.option.alert03" },
+ { id: "alert-04", label: "sound.option.alert04" },
+ { id: "alert-05", label: "sound.option.alert05" },
+ { id: "alert-06", label: "sound.option.alert06" },
+ { id: "alert-07", label: "sound.option.alert07" },
+ { id: "alert-08", label: "sound.option.alert08" },
+ { id: "alert-09", label: "sound.option.alert09" },
+ { id: "alert-10", label: "sound.option.alert10" },
+ { id: "bip-bop-01", label: "sound.option.bipbop01" },
+ { id: "bip-bop-02", label: "sound.option.bipbop02" },
+ { id: "bip-bop-03", label: "sound.option.bipbop03" },
+ { id: "bip-bop-04", label: "sound.option.bipbop04" },
+ { id: "bip-bop-05", label: "sound.option.bipbop05" },
+ { id: "bip-bop-06", label: "sound.option.bipbop06" },
+ { id: "bip-bop-07", label: "sound.option.bipbop07" },
+ { id: "bip-bop-08", label: "sound.option.bipbop08" },
+ { id: "bip-bop-09", label: "sound.option.bipbop09" },
+ { id: "bip-bop-10", label: "sound.option.bipbop10" },
+ { id: "staplebops-01", label: "sound.option.staplebops01" },
+ { id: "staplebops-02", label: "sound.option.staplebops02" },
+ { id: "staplebops-03", label: "sound.option.staplebops03" },
+ { id: "staplebops-04", label: "sound.option.staplebops04" },
+ { id: "staplebops-05", label: "sound.option.staplebops05" },
+ { id: "staplebops-06", label: "sound.option.staplebops06" },
+ { id: "staplebops-07", label: "sound.option.staplebops07" },
+ { id: "nope-01", label: "sound.option.nope01" },
+ { id: "nope-02", label: "sound.option.nope02" },
+ { id: "nope-03", label: "sound.option.nope03" },
+ { id: "nope-04", label: "sound.option.nope04" },
+ { id: "nope-05", label: "sound.option.nope05" },
+ { id: "nope-06", label: "sound.option.nope06" },
+ { id: "nope-07", label: "sound.option.nope07" },
+ { id: "nope-08", label: "sound.option.nope08" },
+ { id: "nope-09", label: "sound.option.nope09" },
+ { id: "nope-10", label: "sound.option.nope10" },
+ { id: "nope-11", label: "sound.option.nope11" },
+ { id: "nope-12", label: "sound.option.nope12" },
+ { id: "yup-01", label: "sound.option.yup01" },
+ { id: "yup-02", label: "sound.option.yup02" },
+ { id: "yup-03", label: "sound.option.yup03" },
+ { id: "yup-04", label: "sound.option.yup04" },
+ { id: "yup-05", label: "sound.option.yup05" },
+ { id: "yup-06", label: "sound.option.yup06" },
] as const
export type SoundOption = (typeof SOUND_OPTIONS)[number]
export type SoundID = SoundOption["id"]
-const soundById = Object.fromEntries(SOUND_OPTIONS.map((s) => [s.id, s.src])) as Record<SoundID, string>
+function getLoads() {
+ if (loads) return loads
+ loads = Object.fromEntries(
+ Object.entries(getFiles()).flatMap(([path, load]) => {
+ const file = path.split("/").at(-1)
+ if (!file) return []
+ return [[file.replace(/\.aac$/, ""), load] as const]
+ }),
+ ) as Record<SoundID, () => Promise<string>>
+ return loads
+}
+
+const cache = new Map<SoundID, Promise<string | undefined>>()
export function soundSrc(id: string | undefined) {
- if (!id) return
- if (!(id in soundById)) return
- return soundById[id as SoundID]
+ const loads = getLoads()
+ if (!id || !(id in loads)) return Promise.resolve(undefined)
+ const key = id as SoundID
+ const hit = cache.get(key)
+ if (hit) return hit
+ const next = loads[key]().catch(() => undefined)
+ cache.set(key, next)
+ return next
}
export function playSound(src: string | undefined) {
@@ -108,10 +91,12 @@ export function playSound(src: string | undefined) {
if (!src) return
const audio = new Audio(src)
audio.play().catch(() => undefined)
-
- // Return a cleanup function to pause the sound.
return () => {
audio.pause()
audio.currentTime = 0
}
}
+
+export function playSoundById(id: string | undefined) {
+ return soundSrc(id).then((src) => playSound(src))
+}