From c4930eb6b219a2011cddc70a9b76f41809418114 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Mon, 29 Dec 2025 08:47:27 -0600 Subject: fix(desktop): more fine-grained state updates for permissions --- packages/app/src/context/global-sync.tsx | 65 +++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 21 deletions(-) (limited to 'packages/app/src') diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx index 0296dfad3..e1dcf15fc 100644 --- a/packages/app/src/context/global-sync.tsx +++ b/packages/app/src/context/global-sync.tsx @@ -23,7 +23,7 @@ import { Binary } from "@opencode-ai/util/binary" import { retry } from "@opencode-ai/util/retry" import { useGlobalSDK } from "./global-sdk" import { ErrorPage, type InitError } from "../pages/error" -import { createContext, useContext, onMount, type ParentProps, Switch, Match } from "solid-js" +import { batch, createContext, useContext, onMount, type ParentProps, Switch, Match } from "solid-js" import { showToast } from "@opencode-ai/ui/toast" import { getFilename } from "@opencode-ai/util/path" @@ -135,7 +135,7 @@ function createGlobalSync() { async function bootstrapInstance(directory: string) { if (!directory) return - const [, setStore] = child(directory) + const [store, setStore] = child(directory) const sdk = createOpencodeClient({ baseUrl: globalSDK.url, directory, @@ -167,12 +167,32 @@ function createGlobalSync() { vcs: () => sdk.vcs.get().then((x) => setStore("vcs", x.data)), permission: () => sdk.permission.list().then((x) => { - const grouped: Record = {} + const grouped: Record = {} for (const perm of x.data ?? []) { - grouped[perm.sessionID] = grouped[perm.sessionID] ?? [] - grouped[perm.sessionID]!.push(perm) + const existing = grouped[perm.sessionID] + if (existing) { + existing.push(perm) + continue + } + grouped[perm.sessionID] = [perm] } - setStore("permission", grouped) + + batch(() => { + for (const sessionID of Object.keys(store.permission)) { + if (grouped[sessionID]) continue + setStore("permission", sessionID, []) + } + for (const [sessionID, permissions] of Object.entries(grouped)) { + setStore( + "permission", + sessionID, + reconcile( + permissions.slice().sort((a, b) => a.id.localeCompare(b.id)), + { key: "id" }, + ), + ) + } + }) }), } await Promise.all(Object.values(load).map((p) => retry(p).catch((e) => setGlobalStore("error", e)))) @@ -325,23 +345,26 @@ function createGlobalSync() { break } case "permission.updated": { - const permissions = store.permission[event.properties.sessionID] + const sessionID = event.properties.sessionID + const permissions = store.permission[sessionID] if (!permissions) { - setStore("permission", event.properties.sessionID, [event.properties]) - } else { - const result = Binary.search(permissions, event.properties.id, (p) => p.id) - setStore( - "permission", - event.properties.sessionID, - produce((draft) => { - if (result.found) { - draft[result.index] = event.properties - return - } - draft.push(event.properties) - }), - ) + setStore("permission", sessionID, [event.properties]) + break } + + const result = Binary.search(permissions, event.properties.id, (p) => p.id) + if (result.found) { + setStore("permission", sessionID, result.index, reconcile(event.properties)) + break + } + + setStore( + "permission", + sessionID, + produce((draft) => { + draft.splice(result.index, 0, event.properties) + }), + ) break } case "permission.replied": { -- cgit v1.2.3