Simplify message cache pruning and diff/markdown initialization
This commit is contained in:
@@ -55,94 +55,45 @@ export function ToolCallDiffViewer(props: ToolCallDiffViewerProps) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
let diffContainerRef: HTMLDivElement | undefined
|
let diffContainerRef: HTMLDivElement | undefined
|
||||||
let pendingCapture: number | undefined
|
let lastCapturedKey: string | undefined
|
||||||
let pendingContext: CaptureContext | undefined
|
|
||||||
let lastRenderedMarkup: string | undefined
|
|
||||||
let lastCachedHtml: string | undefined
|
|
||||||
|
|
||||||
const clearPendingCapture = () => {
|
const contextKey = createMemo(() => {
|
||||||
if (pendingCapture !== undefined) {
|
const data = diffData()
|
||||||
cancelAnimationFrame(pendingCapture)
|
if (!data) return ""
|
||||||
pendingCapture = undefined
|
return `${props.theme}|${props.mode}|${props.diffText}`
|
||||||
}
|
})
|
||||||
pendingContext = undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
const runCapture = (context: CaptureContext) => {
|
|
||||||
if (!diffContainerRef) {
|
|
||||||
props.onRendered?.()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const markup = diffContainerRef.innerHTML
|
|
||||||
if (!markup) {
|
|
||||||
props.onRendered?.()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const hasChanged = markup !== lastRenderedMarkup
|
|
||||||
if (hasChanged) {
|
|
||||||
lastRenderedMarkup = markup
|
|
||||||
if (context.cacheEntryParams) {
|
|
||||||
setCacheEntry(context.cacheEntryParams, {
|
|
||||||
text: context.diffText,
|
|
||||||
html: markup,
|
|
||||||
theme: context.theme,
|
|
||||||
mode: context.mode,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
props.onRendered?.()
|
|
||||||
}
|
|
||||||
|
|
||||||
const scheduleCapture = (context: CaptureContext) => {
|
|
||||||
clearPendingCapture()
|
|
||||||
pendingContext = context
|
|
||||||
pendingCapture = requestAnimationFrame(() => {
|
|
||||||
const activeContext = pendingContext
|
|
||||||
pendingContext = undefined
|
|
||||||
pendingCapture = undefined
|
|
||||||
if (activeContext) {
|
|
||||||
runCapture(activeContext)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
const cachedHtml = props.cachedHtml
|
const cachedHtml = props.cachedHtml
|
||||||
if (cachedHtml) {
|
if (cachedHtml) {
|
||||||
clearPendingCapture()
|
// When we are given cached HTML, we rely on the caller's cache
|
||||||
if (cachedHtml !== lastCachedHtml) {
|
// and simply notify once rendered.
|
||||||
lastCachedHtml = cachedHtml
|
props.onRendered?.()
|
||||||
lastRenderedMarkup = cachedHtml
|
return
|
||||||
props.onRendered?.()
|
}
|
||||||
|
|
||||||
|
const key = contextKey()
|
||||||
|
if (!key) return
|
||||||
|
if (!diffContainerRef) return
|
||||||
|
if (lastCapturedKey === key) return
|
||||||
|
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
if (!diffContainerRef) return
|
||||||
|
const markup = diffContainerRef.innerHTML
|
||||||
|
if (!markup) return
|
||||||
|
lastCapturedKey = key
|
||||||
|
if (props.cacheEntryParams) {
|
||||||
|
setCacheEntry(props.cacheEntryParams, {
|
||||||
|
text: props.diffText,
|
||||||
|
html: markup,
|
||||||
|
theme: props.theme,
|
||||||
|
mode: props.mode,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return
|
props.onRendered?.()
|
||||||
}
|
|
||||||
|
|
||||||
lastCachedHtml = undefined
|
|
||||||
|
|
||||||
const data = diffData()
|
|
||||||
const theme = props.theme
|
|
||||||
const mode = props.mode
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
clearPendingCapture()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduleCapture({
|
|
||||||
theme,
|
|
||||||
mode,
|
|
||||||
diffText: props.diffText,
|
|
||||||
cacheEntryParams: props.cacheEntryParams,
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
onCleanup(() => {
|
|
||||||
clearPendingCapture()
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="tool-call-diff-viewer">
|
<div class="tool-call-diff-viewer">
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ export function Markdown(props: MarkdownProps) {
|
|||||||
|
|
||||||
latestRequestedText = text
|
latestRequestedText = text
|
||||||
|
|
||||||
await initMarkdown(dark)
|
// Markdown initialization is now handled globally in App.
|
||||||
|
// initMarkdown is idempotent but we avoid per-part calls here.
|
||||||
|
|
||||||
if (!highlightEnabled) {
|
if (!highlightEnabled) {
|
||||||
part.renderCache = undefined
|
part.renderCache = undefined
|
||||||
|
|||||||
@@ -295,28 +295,6 @@ export default function MessageStreamV2(props: MessageStreamV2Props) {
|
|||||||
return `${revisionValue}:${tailSignature}`
|
return `${revisionValue}:${tailSignature}`
|
||||||
})
|
})
|
||||||
|
|
||||||
createEffect(() => {
|
|
||||||
const ids = new Set(messageIds())
|
|
||||||
const cache = getSessionRenderCache(props.instanceId, props.sessionId)
|
|
||||||
for (const [key] of cache.messageBlocks) {
|
|
||||||
if (!ids.has(key)) {
|
|
||||||
cache.messageBlocks.delete(key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const [key] of cache.messageItems) {
|
|
||||||
const messageId = key.split(":", 1)[0]
|
|
||||||
if (!ids.has(messageId)) {
|
|
||||||
cache.messageItems.delete(key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const [key] of cache.toolItems) {
|
|
||||||
const messageId = key.split(":", 1)[0]
|
|
||||||
if (!ids.has(messageId)) {
|
|
||||||
cache.toolItems.delete(key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const scrollCache = useScrollCache({
|
const scrollCache = useScrollCache({
|
||||||
instanceId: () => props.instanceId,
|
instanceId: () => props.instanceId,
|
||||||
sessionId: () => props.sessionId,
|
sessionId: () => props.sessionId,
|
||||||
|
|||||||
Reference in New Issue
Block a user