|
|
@@ -10,9 +10,8 @@ import type {
|
|
|
import { showToast } from "@opencode-ai/ui/toast"
|
|
|
import { getFilename } from "@opencode-ai/shared/util/path"
|
|
|
import { batch, createContext, getOwner, onCleanup, onMount, type ParentProps, untrack, useContext } from "solid-js"
|
|
|
-import { createStore, produce, reconcile, unwrap } from "solid-js/store"
|
|
|
+import { createStore, produce, reconcile } from "solid-js/store"
|
|
|
import { useLanguage } from "@/context/language"
|
|
|
-import { Persist, persisted } from "@/utils/persist"
|
|
|
import type { InitError } from "../pages/error"
|
|
|
import { useGlobalSDK } from "./global-sdk"
|
|
|
import {
|
|
|
@@ -31,9 +30,9 @@ import { estimateRootSessionTotal, loadRootSessionsWithFallback } from "./global
|
|
|
import { trimSessions } from "./global-sync/session-trim"
|
|
|
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, useMutation, useQueries, useQuery, useQueryClient } from "@tanstack/solid-query"
|
|
|
+import { createRefreshQueue } from "./global-sync/queue"
|
|
|
|
|
|
type GlobalStore = {
|
|
|
ready: boolean
|
|
|
@@ -61,7 +60,7 @@ export const loadMcpQuery = (directory: string, sdk?: OpencodeClient) =>
|
|
|
export const loadLspQuery = (directory: string, sdk?: OpencodeClient) =>
|
|
|
queryOptions({
|
|
|
queryKey: [directory, "lsp"],
|
|
|
- queryFn: sdk ? () => sdk.lsp.status().then((r) => r.data ?? {}) : skipToken,
|
|
|
+ queryFn: sdk ? () => sdk.lsp.status().then((r) => r.data ?? []) : skipToken,
|
|
|
})
|
|
|
|
|
|
function createGlobalSync() {
|
|
|
@@ -75,11 +74,6 @@ function createGlobalSync() {
|
|
|
const sessionLoads = new Map<string, Promise<void>>()
|
|
|
const sessionMeta = new Map<string, { limit: number }>()
|
|
|
|
|
|
- const [projectCache, setProjectCache, projectInit] = persisted(
|
|
|
- Persist.global("globalSync.project", ["globalSync.project.v1"]),
|
|
|
- createStore({ value: [] as Project[] }),
|
|
|
- )
|
|
|
-
|
|
|
const [configQuery, providerQuery, pathQuery] = useQueries(() => ({
|
|
|
queries: [loadGlobalConfigQuery(), loadProvidersQuery(null), loadPathQuery(null), loadProjectsQuery()],
|
|
|
}))
|
|
|
@@ -88,7 +82,7 @@ function createGlobalSync() {
|
|
|
get ready() {
|
|
|
return bootstrap.isPending
|
|
|
},
|
|
|
- project: projectCache.value,
|
|
|
+ project: [],
|
|
|
session_todo: {},
|
|
|
provider_auth: {},
|
|
|
get path() {
|
|
|
@@ -111,32 +105,18 @@ function createGlobalSync() {
|
|
|
})
|
|
|
const queryClient = useQueryClient()
|
|
|
|
|
|
- let active = true
|
|
|
- let projectWritten = false
|
|
|
let bootedAt = 0
|
|
|
let bootingRoot = false
|
|
|
let eventFrame: number | undefined
|
|
|
let eventTimer: ReturnType<typeof setTimeout> | undefined
|
|
|
|
|
|
- onCleanup(() => {
|
|
|
- active = false
|
|
|
- })
|
|
|
onCleanup(() => {
|
|
|
if (eventFrame !== undefined) cancelAnimationFrame(eventFrame)
|
|
|
if (eventTimer !== undefined) clearTimeout(eventTimer)
|
|
|
})
|
|
|
|
|
|
- const cacheProjects = () => {
|
|
|
- setProjectCache(
|
|
|
- "value",
|
|
|
- untrack(() => globalStore.project.map(sanitizeProject)),
|
|
|
- )
|
|
|
- }
|
|
|
-
|
|
|
const setProjects = (next: Project[] | ((draft: Project[]) => Project[])) => {
|
|
|
- projectWritten = true
|
|
|
setGlobalStore("project", next)
|
|
|
- cacheProjects()
|
|
|
}
|
|
|
|
|
|
const setBootStore = ((...input: unknown[]) => {
|
|
|
@@ -171,16 +151,6 @@ function createGlobalSync() {
|
|
|
return (setGlobalStore as (...args: unknown[]) => unknown)(...input)
|
|
|
}) as typeof setGlobalStore
|
|
|
|
|
|
- if (projectInit instanceof Promise) {
|
|
|
- void projectInit.then(() => {
|
|
|
- if (!active) return
|
|
|
- if (projectWritten) return
|
|
|
- const cached = projectCache.value
|
|
|
- if (cached.length === 0) return
|
|
|
- setGlobalStore("project", cached)
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
const setSessionTodo = (sessionID: string, todos: Todo[] | undefined) => {
|
|
|
if (!sessionID) return
|
|
|
if (!todos) {
|
|
|
@@ -197,11 +167,22 @@ function createGlobalSync() {
|
|
|
|
|
|
const paused = () => untrack(() => globalStore.reload) !== undefined
|
|
|
|
|
|
- // const queue = createRefreshQueue({
|
|
|
- // paused,
|
|
|
- // bootstrap: () => queryClient.fetchQuery({ queryKey: ["bootstrap"] }),
|
|
|
- // bootstrapInstance,
|
|
|
- // })
|
|
|
+ const queue = createRefreshQueue({
|
|
|
+ paused,
|
|
|
+ bootstrap: () => queryClient.fetchQuery({ queryKey: ["bootstrap"] }),
|
|
|
+ bootstrapInstance,
|
|
|
+ })
|
|
|
+
|
|
|
+ const sdkFor = (directory: string) => {
|
|
|
+ const cached = sdkCache.get(directory)
|
|
|
+ if (cached) return cached
|
|
|
+ const sdk = globalSDK.createClient({
|
|
|
+ directory,
|
|
|
+ throwOnError: true,
|
|
|
+ })
|
|
|
+ sdkCache.set(directory, sdk)
|
|
|
+ return sdk
|
|
|
+ }
|
|
|
|
|
|
const children = createChildStoreManager({
|
|
|
owner,
|
|
|
@@ -211,26 +192,16 @@ function createGlobalSync() {
|
|
|
void bootstrapInstance(directory)
|
|
|
},
|
|
|
onDispose: (directory) => {
|
|
|
- // queue.clear(directory)
|
|
|
+ queue.clear(directory)
|
|
|
sessionMeta.delete(directory)
|
|
|
sdkCache.delete(directory)
|
|
|
clearProviderRev(directory)
|
|
|
clearSessionPrefetchDirectory(directory)
|
|
|
},
|
|
|
translate: language.t,
|
|
|
+ getSdk: sdkFor,
|
|
|
})
|
|
|
|
|
|
- const sdkFor = (directory: string) => {
|
|
|
- const cached = sdkCache.get(directory)
|
|
|
- if (cached) return cached
|
|
|
- const sdk = globalSDK.createClient({
|
|
|
- directory,
|
|
|
- throwOnError: true,
|
|
|
- })
|
|
|
- sdkCache.set(directory, sdk)
|
|
|
- return sdk
|
|
|
- }
|
|
|
-
|
|
|
async function loadSessions(directory: string) {
|
|
|
const pending = sessionLoads.get(directory)
|
|
|
if (pending) return pending
|
|
|
@@ -362,7 +333,7 @@ function createGlobalSync() {
|
|
|
if (event.type === "server.connected" || event.type === "global.disposed") {
|
|
|
if (recent) return
|
|
|
for (const directory of Object.keys(children.children)) {
|
|
|
- // queue.push(directory)
|
|
|
+ queue.push(directory)
|
|
|
}
|
|
|
}
|
|
|
return
|
|
|
@@ -377,21 +348,19 @@ function createGlobalSync() {
|
|
|
directory,
|
|
|
store,
|
|
|
setStore,
|
|
|
- push: () => {}, // queue.push,
|
|
|
+ push: queue.push,
|
|
|
setSessionTodo,
|
|
|
vcsCache: children.vcsCache.get(directory),
|
|
|
loadLsp: () => {
|
|
|
- void queryClient.fetchQuery(loadLspQuery(directory, sdkFor(directory))).then((data) => {
|
|
|
- setStore("lsp", data ?? [])
|
|
|
- })
|
|
|
+ void queryClient.fetchQuery(loadLspQuery(directory, sdkFor(directory)))
|
|
|
},
|
|
|
})
|
|
|
})
|
|
|
|
|
|
onCleanup(unsub)
|
|
|
- // onCleanup(() => {
|
|
|
- // queue.dispose()
|
|
|
- // })
|
|
|
+ onCleanup(() => {
|
|
|
+ queue.dispose()
|
|
|
+ })
|
|
|
onCleanup(() => {
|
|
|
for (const directory of Object.keys(children.children)) {
|
|
|
children.disposeDirectory(directory)
|
|
|
@@ -427,7 +396,7 @@ function createGlobalSync() {
|
|
|
|
|
|
const updateConfigMutation = useMutation(() => ({
|
|
|
mutationFn: (config: Config) => globalSDK.client.global.config.update({ config }),
|
|
|
- // onSuccess: () => bootstrap.refetch(),
|
|
|
+ onSuccess: () => bootstrap.refetch(),
|
|
|
}))
|
|
|
|
|
|
return {
|