summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/context/global-sync.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/app/src/context/global-sync.tsx')
-rw-r--r--packages/app/src/context/global-sync.tsx103
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()