chore: cleanup

This commit is contained in:
adamelmore
2026-01-24 06:57:13 -06:00
committed by Adam
parent 962ab3bc8c
commit 09f45320b7
4 changed files with 90 additions and 82 deletions

View File

@@ -24,6 +24,7 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
type Queued = { directory: string; payload: Event } type Queued = { directory: string; payload: Event }
let queue: Array<Queued | undefined> = [] let queue: Array<Queued | undefined> = []
let buffer: Array<Queued | undefined> = []
const coalesced = new Map<string, number>() const coalesced = new Map<string, number>()
let timer: ReturnType<typeof setTimeout> | undefined let timer: ReturnType<typeof setTimeout> | undefined
let last = 0 let last = 0
@@ -41,10 +42,13 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
if (timer) clearTimeout(timer) if (timer) clearTimeout(timer)
timer = undefined timer = undefined
if (queue.length === 0) return
const events = queue const events = queue
queue = [] queue = buffer
buffer = events
queue.length = 0
coalesced.clear() coalesced.clear()
if (events.length === 0) return
last = Date.now() last = Date.now()
batch(() => { batch(() => {
@@ -53,6 +57,8 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
emitter.emit(event.directory, event.payload) emitter.emit(event.directory, event.payload)
} }
}) })
buffer.length = 0
} }
const schedule = () => { const schedule = () => {
@@ -61,10 +67,6 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
timer = setTimeout(flush, Math.max(0, 16 - elapsed)) timer = setTimeout(flush, Math.max(0, 16 - elapsed))
} }
const stop = () => {
flush()
}
void (async () => { void (async () => {
const events = await eventSdk.global.event() const events = await eventSdk.global.event()
let yielded = Date.now() let yielded = Date.now()
@@ -87,12 +89,12 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
await new Promise<void>((resolve) => setTimeout(resolve, 0)) await new Promise<void>((resolve) => setTimeout(resolve, 0))
} }
})() })()
.finally(stop) .finally(flush)
.catch(() => undefined) .catch(() => undefined)
onCleanup(() => { onCleanup(() => {
abort.abort() abort.abort()
stop() flush()
}) })
const sdk = createOpencodeClient({ const sdk = createOpencodeClient({

View File

@@ -119,6 +119,16 @@ type ChildOptions = {
bootstrap?: boolean bootstrap?: boolean
} }
function normalizeProviderList(input: ProviderListResponse): ProviderListResponse {
return {
...input,
all: input.all.map((provider) => ({
...provider,
models: Object.fromEntries(Object.entries(provider.models).filter(([, info]) => info.status !== "deprecated")),
})),
}
}
function createGlobalSync() { function createGlobalSync() {
const globalSDK = useGlobalSDK() const globalSDK = useGlobalSDK()
const platform = usePlatform() const platform = usePlatform()
@@ -129,6 +139,21 @@ function createGlobalSync() {
const metaCache = new Map<string, MetaCache>() const metaCache = new Map<string, MetaCache>()
const iconCache = new Map<string, IconCache>() const iconCache = new Map<string, IconCache>()
const sdkCache = new Map<string, ReturnType<typeof createOpencodeClient>>()
const sdkFor = (directory: string) => {
const cached = sdkCache.get(directory)
if (cached) return cached
const sdk = createOpencodeClient({
baseUrl: globalSDK.url,
fetch: platform.fetch,
directory,
throwOnError: true,
})
sdkCache.set(directory, sdk)
return sdk
}
const [projectCache, setProjectCache, , projectCacheReady] = persisted( const [projectCache, setProjectCache, , projectCacheReady] = persisted(
Persist.global("globalSync.project", ["globalSync.project.v1"]), Persist.global("globalSync.project", ["globalSync.project.v1"]),
createStore({ value: [] as Project[] }), createStore({ value: [] as Project[] }),
@@ -183,7 +208,7 @@ function createGlobalSync() {
setProjectCache("value", projects.map(sanitizeProject)) setProjectCache("value", projects.map(sanitizeProject))
}) })
createEffect(async () => { createEffect(() => {
if (globalStore.reload !== "complete") return if (globalStore.reload !== "complete") return
if (bootstrapQueue.length) { if (bootstrapQueue.length) {
for (const directory of bootstrapQueue) { for (const directory of bootstrapQueue) {
@@ -203,14 +228,16 @@ function createGlobalSync() {
function ensureChild(directory: string) { function ensureChild(directory: string) {
if (!directory) console.error("No directory provided") if (!directory) console.error("No directory provided")
if (!children[directory]) { if (!children[directory]) {
const cache = runWithOwner(owner, () => const vcs = runWithOwner(owner, () =>
persisted( persisted(
Persist.workspace(directory, "vcs", ["vcs.v1"]), Persist.workspace(directory, "vcs", ["vcs.v1"]),
createStore({ value: undefined as VcsInfo | undefined }), createStore({ value: undefined as VcsInfo | undefined }),
), ),
) )
if (!cache) throw new Error("Failed to create persisted cache") if (!vcs) throw new Error("Failed to create persisted cache")
vcsCache.set(directory, { store: cache[0], setStore: cache[1], ready: cache[3] }) const vcsStore = vcs[0]
const vcsReady = vcs[3]
vcsCache.set(directory, { store: vcsStore, setStore: vcs[1], ready: vcsReady })
const meta = runWithOwner(owner, () => const meta = runWithOwner(owner, () =>
persisted( persisted(
@@ -250,7 +277,7 @@ function createGlobalSync() {
question: {}, question: {},
mcp: {}, mcp: {},
lsp: [], lsp: [],
vcs: cache[0].value, vcs: vcsStore.value,
limit: 5, limit: 5,
message: {}, message: {},
part: {}, part: {},
@@ -258,6 +285,13 @@ function createGlobalSync() {
children[directory] = child children[directory] = child
createEffect(() => {
if (!vcsReady()) return
const cached = vcsStore.value
if (!cached?.branch) return
child[1]("vcs", (value) => value ?? cached)
})
createEffect(() => { createEffect(() => {
child[1]("projectMeta", meta[0].value) child[1]("projectMeta", meta[0].value)
}) })
@@ -297,7 +331,6 @@ function createGlobalSync() {
const nonArchived = (x.data ?? []) const nonArchived = (x.data ?? [])
.filter((s) => !!s?.id) .filter((s) => !!s?.id)
.filter((s) => !s.time?.archived) .filter((s) => !s.time?.archived)
.slice()
.sort((a, b) => a.id.localeCompare(b.id)) .sort((a, b) => a.id.localeCompare(b.id))
// Read the current limit at resolve-time so callers that bump the limit while // Read the current limit at resolve-time so callers that bump the limit while
@@ -348,38 +381,18 @@ function createGlobalSync() {
if (!cache) return if (!cache) return
const meta = metaCache.get(directory) const meta = metaCache.get(directory)
if (!meta) return if (!meta) return
const sdk = createOpencodeClient({ const sdk = sdkFor(directory)
baseUrl: globalSDK.url,
fetch: platform.fetch,
directory,
throwOnError: true,
})
setStore("status", "loading") setStore("status", "loading")
createEffect(() => {
if (!cache.ready()) return
const cached = cache.store.value
if (!cached?.branch) return
setStore("vcs", (value) => value ?? cached)
})
// projectMeta is synced from persisted storage in ensureChild. // projectMeta is synced from persisted storage in ensureChild.
// vcs is seeded from persisted storage in ensureChild.
const blockingRequests = { const blockingRequests = {
project: () => sdk.project.current().then((x) => setStore("project", x.data!.id)), project: () => sdk.project.current().then((x) => setStore("project", x.data!.id)),
provider: () => provider: () =>
sdk.provider.list().then((x) => { sdk.provider.list().then((x) => {
const data = x.data! setStore("provider", normalizeProviderList(x.data!))
setStore("provider", {
...data,
all: data.all.map((provider) => ({
...provider,
models: Object.fromEntries(
Object.entries(provider.models).filter(([, info]) => info.status !== "deprecated"),
),
})),
})
}), }),
agent: () => sdk.app.agents().then((x) => setStore("agent", x.data ?? [])), agent: () => sdk.app.agents().then((x) => setStore("agent", x.data ?? [])),
config: () => sdk.config.get().then((x) => setStore("config", x.data!)), config: () => sdk.config.get().then((x) => setStore("config", x.data!)),
@@ -432,10 +445,7 @@ function createGlobalSync() {
"permission", "permission",
sessionID, sessionID,
reconcile( reconcile(
permissions permissions.filter((p) => !!p?.id).sort((a, b) => a.id.localeCompare(b.id)),
.filter((p) => !!p?.id)
.slice()
.sort((a, b) => a.id.localeCompare(b.id)),
{ key: "id" }, { key: "id" },
), ),
) )
@@ -464,10 +474,7 @@ function createGlobalSync() {
"question", "question",
sessionID, sessionID,
reconcile( reconcile(
questions questions.filter((q) => !!q?.id).sort((a, b) => a.id.localeCompare(b.id)),
.filter((q) => !!q?.id)
.slice()
.sort((a, b) => a.id.localeCompare(b.id)),
{ key: "id" }, { key: "id" },
), ),
) )
@@ -750,13 +757,9 @@ function createGlobalSync() {
break break
} }
case "lsp.updated": { case "lsp.updated": {
const sdk = createOpencodeClient({ sdkFor(directory)
baseUrl: globalSDK.url, .lsp.status()
fetch: platform.fetch, .then((x) => setStore("lsp", x.data ?? []))
directory,
throwOnError: true,
})
sdk.lsp.status().then((x) => setStore("lsp", x.data ?? []))
break break
} }
} }
@@ -796,16 +799,7 @@ function createGlobalSync() {
), ),
retry(() => retry(() =>
globalSDK.client.provider.list().then((x) => { globalSDK.client.provider.list().then((x) => {
const data = x.data! setGlobalStore("provider", normalizeProviderList(x.data!))
setGlobalStore("provider", {
...data,
all: data.all.map((provider) => ({
...provider,
models: Object.fromEntries(
Object.entries(provider.models).filter(([, info]) => info.status !== "deprecated"),
),
})),
})
}), }),
), ),
retry(() => retry(() =>

View File

@@ -209,6 +209,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
}) })
const [colors, setColors] = createStore<Record<string, AvatarColorKey>>({}) const [colors, setColors] = createStore<Record<string, AvatarColorKey>>({})
const colorRequested = new Map<string, AvatarColorKey>()
function pickAvailableColor(used: Set<string>): AvatarColorKey { function pickAvailableColor(used: Set<string>): AvatarColorKey {
const available = AVATAR_COLOR_KEYS.filter((c) => !used.has(c)) const available = AVATAR_COLOR_KEYS.filter((c) => !used.has(c))
@@ -324,13 +325,21 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
createEffect(() => { createEffect(() => {
const projects = enriched() const projects = enriched()
if (projects.length === 0) return if (projects.length === 0) return
if (!globalSync.ready) return
if (globalSync.ready) { for (const project of projects) {
for (const project of projects) { if (!project.id) continue
if (!project.id) continue if (project.id === "global") continue
if (project.id === "global") continue globalSync.project.icon(project.worktree, project.icon?.override)
globalSync.project.icon(project.worktree, project.icon?.override) }
} })
createEffect(() => {
const projects = enriched()
if (projects.length === 0) return
for (const project of projects) {
if (project.icon?.color) colorRequested.delete(project.worktree)
} }
const used = new Set<string>() const used = new Set<string>()
@@ -341,18 +350,29 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
for (const project of projects) { for (const project of projects) {
if (project.icon?.color) continue if (project.icon?.color) continue
const existing = colors[project.worktree] const worktree = project.worktree
const existing = colors[worktree]
const color = existing ?? pickAvailableColor(used) const color = existing ?? pickAvailableColor(used)
if (!existing) { if (!existing) {
used.add(color) used.add(color)
setColors(project.worktree, color) setColors(worktree, color)
} }
if (!project.id) continue if (!project.id) continue
const requested = colorRequested.get(worktree)
if (requested === color) continue
colorRequested.set(worktree, color)
if (project.id === "global") { if (project.id === "global") {
globalSync.project.meta(project.worktree, { icon: { color } }) globalSync.project.meta(worktree, { icon: { color } })
continue continue
} }
void globalSdk.client.project.update({ projectID: project.id, directory: project.worktree, icon: { color } })
void globalSdk.client.project
.update({ projectID: project.id, directory: worktree, icon: { color } })
.catch(() => {
if (colorRequested.get(worktree) === color) colorRequested.delete(worktree)
})
} }
}) })

View File

@@ -72,7 +72,6 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
const next = items const next = items
.map((x) => x.info) .map((x) => x.info)
.filter((m) => !!m?.id) .filter((m) => !!m?.id)
.slice()
.sort((a, b) => a.id.localeCompare(b.id)) .sort((a, b) => a.id.localeCompare(b.id))
batch(() => { batch(() => {
@@ -83,10 +82,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
"part", "part",
message.info.id, message.info.id,
reconcile( reconcile(
message.parts message.parts.filter((p) => !!p?.id).sort((a, b) => a.id.localeCompare(b.id)),
.filter((p) => !!p?.id)
.slice()
.sort((a, b) => a.id.localeCompare(b.id)),
{ key: "id" }, { key: "id" },
), ),
) )
@@ -146,10 +142,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
const result = Binary.search(messages, input.messageID, (m) => m.id) const result = Binary.search(messages, input.messageID, (m) => m.id)
messages.splice(result.index, 0, message) messages.splice(result.index, 0, message)
} }
draft.part[input.messageID] = input.parts draft.part[input.messageID] = input.parts.filter((p) => !!p?.id).sort((a, b) => a.id.localeCompare(b.id))
.filter((p) => !!p?.id)
.slice()
.sort((a, b) => a.id.localeCompare(b.id))
}), }),
) )
}, },
@@ -291,7 +284,6 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
await client.session.list().then((x) => { await client.session.list().then((x) => {
const sessions = (x.data ?? []) const sessions = (x.data ?? [])
.filter((s) => !!s?.id) .filter((s) => !!s?.id)
.slice()
.sort((a, b) => a.id.localeCompare(b.id)) .sort((a, b) => a.id.localeCompare(b.id))
.slice(0, store.limit) .slice(0, store.limit)
setStore("session", reconcile(sessions, { key: "id" })) setStore("session", reconcile(sessions, { key: "id" }))