diff options
Diffstat (limited to 'packages/app/src/context/global-sync.tsx')
| -rw-r--r-- | packages/app/src/context/global-sync.tsx | 103 |
1 files changed, 59 insertions, 44 deletions
diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx index 0cf3570a8..6ff60f161 100644 --- a/packages/app/src/context/global-sync.tsx +++ b/packages/app/src/context/global-sync.tsx @@ -8,7 +8,7 @@ import type { Todo, } from "@opencode-ai/sdk/v2/client" import { showToast } from "@opencode-ai/ui/toast" -import { getFilename } from "@opencode-ai/util/path" +import { getFilename } from "@opencode-ai/shared/util/path" import { createContext, getOwner, onCleanup, onMount, type ParentProps, untrack, useContext } from "solid-js" import { createStore, produce, reconcile } from "solid-js/store" import { useLanguage } from "@/context/language" @@ -26,6 +26,7 @@ import type { ProjectMeta } from "./global-sync/types" import { SESSION_RECENT_LIMIT } from "./global-sync/types" import { sanitizeProject } from "./global-sync/utils" import { formatServerError } from "@/utils/server-errors" +import { queryOptions, skipToken, useQueryClient } from "@tanstack/solid-query" type GlobalStore = { ready: boolean @@ -41,6 +42,9 @@ type GlobalStore = { reload: undefined | "pending" | "complete" } +export const loadSessionsQuery = (directory: string) => + queryOptions<null>({ queryKey: [directory, "loadSessions"], queryFn: skipToken }) + function createGlobalSync() { const globalSDK = useGlobalSDK() const language = useLanguage() @@ -67,6 +71,7 @@ function createGlobalSync() { config: {}, reload: undefined, }) + const queryClient = useQueryClient() let active = true let projectWritten = false @@ -198,46 +203,53 @@ function createGlobalSync() { } const limit = Math.max(store.limit + SESSION_RECENT_LIMIT, SESSION_RECENT_LIMIT) - const promise = loadRootSessionsWithFallback({ - directory, - limit, - list: (query) => globalSDK.client.session.list(query), - }) - .then((x) => { - const nonArchived = (x.data ?? []) - .filter((s) => !!s?.id) - .filter((s) => !s.time?.archived) - .sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)) - const limit = store.limit - const childSessions = store.session.filter((s) => !!s.parentID) - const sessions = trimSessions([...nonArchived, ...childSessions], { - limit, - permission: store.permission, - }) - setStore( - "sessionTotal", - estimateRootSessionTotal({ - count: nonArchived.length, - limit: x.limit, - limited: x.limited, - }), - ) - setStore("session", reconcile(sessions, { key: "id" })) - cleanupDroppedSessionCaches(store, setStore, sessions, setSessionTodo) - sessionMeta.set(directory, { limit }) - }) - .catch((err) => { - console.error("Failed to load sessions", err) - const project = getFilename(directory) - showToast({ - variant: "error", - title: language.t("toast.session.listFailed.title", { project }), - description: formatServerError(err, language.t), - }) + const promise = queryClient + .ensureQueryData({ + ...loadSessionsQuery(directory), + queryFn: () => + loadRootSessionsWithFallback({ + directory, + limit, + list: (query) => globalSDK.client.session.list(query), + }) + .then((x) => { + const nonArchived = (x.data ?? []) + .filter((s) => !!s?.id) + .filter((s) => !s.time?.archived) + .sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)) + const limit = store.limit + const childSessions = store.session.filter((s) => !!s.parentID) + const sessions = trimSessions([...nonArchived, ...childSessions], { + limit, + permission: store.permission, + }) + setStore( + "sessionTotal", + estimateRootSessionTotal({ + count: nonArchived.length, + limit: x.limit, + limited: x.limited, + }), + ) + setStore("session", reconcile(sessions, { key: "id" })) + cleanupDroppedSessionCaches(store, setStore, sessions, setSessionTodo) + sessionMeta.set(directory, { limit }) + }) + .catch((err) => { + console.error("Failed to load sessions", err) + const project = getFilename(directory) + showToast({ + variant: "error", + title: language.t("toast.session.listFailed.title", { project }), + description: formatServerError(err, language.t), + }) + }) + .then(() => null), }) + .then(() => {}) sessionLoads.set(directory, promise) - promise.finally(() => { + void promise.finally(() => { sessionLoads.delete(directory) children.unpin(directory) }) @@ -250,8 +262,9 @@ function createGlobalSync() { if (pending) return pending children.pin(directory) - const promise = (async () => { + const promise = Promise.resolve().then(async () => { const child = children.ensureChild(directory) + child[1]("bootstrapPromise", promise!) const cache = children.vcsCache.get(directory) if (!cache) return const sdk = sdkFor(directory) @@ -269,11 +282,12 @@ function createGlobalSync() { vcsCache: cache, loadSessions, translate: language.t, + queryClient, }) - })() + }) booting.set(directory, promise) - promise.finally(() => { + void promise.finally(() => { booting.delete(directory) children.unpin(directory) }) @@ -317,7 +331,7 @@ function createGlobalSync() { setSessionTodo, vcsCache: children.vcsCache.get(directory), loadLsp: () => { - sdkFor(directory) + void sdkFor(directory) .lsp.status() .then((x) => { setStore("lsp", x.data ?? []) @@ -346,6 +360,7 @@ function createGlobalSync() { translate: language.t, formatMoreCount: (count) => language.t("common.moreCountSuffix", { count }), setGlobalStore: setBootStore, + queryClient, }) bootedAt = Date.now() } finally { @@ -359,13 +374,13 @@ function createGlobalSync() { eventFrame = undefined eventTimer = setTimeout(() => { eventTimer = undefined - globalSDK.event.start() + void globalSDK.event.start() }, 0) }) } else { eventTimer = setTimeout(() => { eventTimer = undefined - globalSDK.event.start() + void globalSDK.event.start() }, 0) } void bootstrap() |
