refactor(tui): simplify MCP catalog refresh
This commit is contained in:
parent
cc3ddb5bb0
commit
4d3ff36869
2 changed files with 10 additions and 56 deletions
|
|
@ -115,8 +115,6 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
|
||||||
let connectionGeneration = 0
|
let connectionGeneration = 0
|
||||||
let statusChanges: Set<string> | undefined
|
let statusChanges: Set<string> | undefined
|
||||||
let bootstrapping: Promise<void> | undefined
|
let bootstrapping: Promise<void> | undefined
|
||||||
const pendingMcpResourceRefresh = new Map<string, LocationRef>()
|
|
||||||
const mcpResourceRefreshes = new Map<string, Promise<void>>()
|
|
||||||
|
|
||||||
function setSessionStatus(sessionID: string, status: DataSessionStatus) {
|
function setSessionStatus(sessionID: string, status: DataSessionStatus) {
|
||||||
statusChanges?.add(sessionID)
|
statusChanges?.add(sessionID)
|
||||||
|
|
@ -767,15 +765,10 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
|
||||||
if (bootstrapping) break
|
if (bootstrapping) break
|
||||||
void result.location.mcp.refresh(event.location)
|
void result.location.mcp.refresh(event.location)
|
||||||
break
|
break
|
||||||
case "mcp.resources.changed": {
|
case "mcp.resources.changed":
|
||||||
const location = event.location ?? defaultLocation()
|
if (bootstrapping) break
|
||||||
if (bootstrapping || mcpResourceRefreshes.has(locationKey(location))) {
|
void result.location.mcp.resource.refresh(event.location)
|
||||||
pendingMcpResourceRefresh.set(locationKey(location), location)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
void result.location.mcp.resource.refresh(location)
|
|
||||||
break
|
break
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -965,26 +958,12 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
|
||||||
catalog(location?: LocationRef) {
|
catalog(location?: LocationRef) {
|
||||||
return store.location[locationKey(location ?? defaultLocation())]?.mcpResource
|
return store.location[locationKey(location ?? defaultLocation())]?.mcpResource
|
||||||
},
|
},
|
||||||
refresh(ref?: LocationRef) {
|
async refresh(ref?: LocationRef) {
|
||||||
const location = ref ?? defaultLocation()
|
const result = await sdk.api["server.mcp"].catalog({
|
||||||
const key = locationKey(location)
|
location: locationQuery(ref ?? defaultLocation()),
|
||||||
const active = mcpResourceRefreshes.get(key)
|
})
|
||||||
if (active) return active
|
const key = locationKey(result.location)
|
||||||
const refresh = sdk.api["server.mcp"]
|
setStore("location", key, { ...store.location[key], mcpResource: mutable(result.data) })
|
||||||
.catalog({ location: locationQuery(location) })
|
|
||||||
.then((result) => {
|
|
||||||
const key = locationKey(result.location)
|
|
||||||
setStore("location", key, { ...store.location[key], mcpResource: mutable(result.data) })
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
mcpResourceRefreshes.delete(key)
|
|
||||||
const pending = pendingMcpResourceRefresh.get(key)
|
|
||||||
if (!pending || bootstrapping) return
|
|
||||||
pendingMcpResourceRefresh.delete(key)
|
|
||||||
void result.location.mcp.resource.refresh(pending)
|
|
||||||
})
|
|
||||||
mcpResourceRefreshes.set(key, refresh)
|
|
||||||
return refresh
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -1069,11 +1048,6 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
bootstrapping = undefined
|
bootstrapping = undefined
|
||||||
for (const [key, location] of pendingMcpResourceRefresh) {
|
|
||||||
if (mcpResourceRefreshes.has(key)) continue
|
|
||||||
pendingMcpResourceRefresh.delete(key)
|
|
||||||
void result.location.mcp.resource.refresh(location)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
return bootstrapping
|
return bootstrapping
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,19 +112,12 @@ test("refreshes MCP resource catalogs after change events", async () => {
|
||||||
const events = createEventStream()
|
const events = createEventStream()
|
||||||
let resources = [{ server: "docs", name: "Readme", uri: "docs://readme" }]
|
let resources = [{ server: "docs", name: "Readme", uri: "docs://readme" }]
|
||||||
let requests = 0
|
let requests = 0
|
||||||
let release: (() => void) | undefined
|
|
||||||
const calls = createFetch((url) => {
|
const calls = createFetch((url) => {
|
||||||
if (url.pathname !== "/api/mcp/resource") return
|
if (url.pathname !== "/api/mcp/resource") return
|
||||||
requests++
|
requests++
|
||||||
const data = { resources, templates: [] }
|
|
||||||
if (requests === 3)
|
|
||||||
return new Promise<Response>((resolve) => {
|
|
||||||
release = () =>
|
|
||||||
resolve(json({ location: { directory, project: { id: "proj_test", directory } }, data }))
|
|
||||||
})
|
|
||||||
return json({
|
return json({
|
||||||
location: { directory, project: { id: "proj_test", directory } },
|
location: { directory, project: { id: "proj_test", directory } },
|
||||||
data,
|
data: { resources, templates: [] },
|
||||||
})
|
})
|
||||||
}, events)
|
}, events)
|
||||||
let data!: ReturnType<typeof useData>
|
let data!: ReturnType<typeof useData>
|
||||||
|
|
@ -158,19 +151,6 @@ test("refreshes MCP resource catalogs after change events", async () => {
|
||||||
data: { server: "docs" },
|
data: { server: "docs" },
|
||||||
})
|
})
|
||||||
await wait(() => requests === 2 && data.location.mcp.resource.catalog()?.resources[0]?.name === "Guide")
|
await wait(() => requests === 2 && data.location.mcp.resource.catalog()?.resources[0]?.name === "Guide")
|
||||||
|
|
||||||
const refresh = data.location.mcp.resource.refresh()
|
|
||||||
await wait(() => requests === 3)
|
|
||||||
resources = [{ server: "docs", name: "Reference", uri: "docs://reference" }]
|
|
||||||
emitEvent(events, {
|
|
||||||
id: "evt_mcp_resources_during_refresh",
|
|
||||||
created: 2,
|
|
||||||
type: "mcp.resources.changed",
|
|
||||||
data: { server: "docs" },
|
|
||||||
})
|
|
||||||
release?.()
|
|
||||||
await refresh
|
|
||||||
await wait(() => requests === 4 && data.location.mcp.resource.catalog()?.resources[0]?.name === "Reference")
|
|
||||||
} finally {
|
} finally {
|
||||||
app.renderer.destroy()
|
app.renderer.destroy()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue