diff options
| author | Adam <[email protected]> | 2025-12-02 06:50:16 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2025-12-02 06:50:21 -0600 |
| commit | c0a35141e6b70eed1a9ba576fe43b7f7d690b968 (patch) | |
| tree | 50d3f50af029076faa3f5d4a5d9a9acb752e6b6e /packages/ui/src/components/diff.tsx | |
| parent | 221bb64aebda8263ea2ce48c1a1dc1f36ac83857 (diff) | |
| download | opencode-c0a35141e6b70eed1a9ba576fe43b7f7d690b968.tar.gz opencode-c0a35141e6b70eed1a9ba576fe43b7f7d690b968.zip | |
feat: better code and diff rendering performance
Diffstat (limited to 'packages/ui/src/components/diff.tsx')
| -rw-r--r-- | packages/ui/src/components/diff.tsx | 98 |
1 files changed, 27 insertions, 71 deletions
diff --git a/packages/ui/src/components/diff.tsx b/packages/ui/src/components/diff.tsx index bd2134515..8e19c3172 100644 --- a/packages/ui/src/components/diff.tsx +++ b/packages/ui/src/components/diff.tsx @@ -1,17 +1,22 @@ -import { type FileContents, FileDiff, type DiffLineAnnotation, FileDiffOptions } from "@pierre/precision-diffs" -import { PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr" -import { ComponentProps, createEffect, onCleanup, onMount, Show, splitProps } from "solid-js" -import { isServer } from "solid-js/web" -import { createDefaultOptions, styleVariables } from "./pierre" - -export type DiffProps<T = {}> = FileDiffOptions<T> & { - preloadedDiff?: PreloadMultiFileDiffResult<T> - before: FileContents - after: FileContents - annotations?: DiffLineAnnotation<T>[] - class?: string - classList?: ComponentProps<"div">["classList"] -} +import { FileDiff } from "@pierre/precision-diffs" +import { getOrCreateWorkerPoolSingleton } from "@pierre/precision-diffs/worker" +import { createEffect, onCleanup, splitProps } from "solid-js" +import { createDefaultOptions, type DiffProps, styleVariables } from "../pierre" +import { workerFactory } from "../pierre/worker" + +const workerPool = getOrCreateWorkerPoolSingleton({ + poolOptions: { + workerFactory, + // poolSize defaults to 8. More workers = more parallelism but + // also more memory. Too many can actually slow things down. + // poolSize: 8, + }, + highlighterOptions: { + theme: "OpenCode", + // Optionally preload languages to avoid lazy-loading delays + // langs: ["typescript", "javascript", "css", "html"], + }, +}) // interface ThreadMetadata { // threadId: string @@ -21,21 +26,21 @@ export type DiffProps<T = {}> = FileDiffOptions<T> & { export function Diff<T>(props: DiffProps<T>) { let container!: HTMLDivElement - let fileDiffRef!: HTMLElement const [local, others] = splitProps(props, ["before", "after", "class", "classList", "annotations"]) let fileDiffInstance: FileDiff<T> | undefined const cleanupFunctions: Array<() => void> = [] createEffect(() => { - if (props.preloadedDiff) return container.innerHTML = "" if (!fileDiffInstance) { - fileDiffInstance = new FileDiff<T>({ - ...createDefaultOptions(props.diffStyle), - ...others, - ...(props.preloadedDiff ?? {}), - }) + fileDiffInstance = new FileDiff<T>( + { + ...createDefaultOptions(props.diffStyle), + ...others, + }, + workerPool, + ) } fileDiffInstance.render({ oldFile: local.before, @@ -45,60 +50,11 @@ export function Diff<T>(props: DiffProps<T>) { }) }) - onMount(() => { - if (isServer || !props.preloadedDiff) return - fileDiffInstance = new FileDiff<T>({ - ...createDefaultOptions(props.diffStyle), - ...others, - ...(props.preloadedDiff ?? {}), - }) - // @ts-expect-error - fileContainer is private but needed for SSR hydration - fileDiffInstance.fileContainer = fileDiffRef - fileDiffInstance.hydrate({ - oldFile: local.before, - newFile: local.after, - lineAnnotations: local.annotations, - fileContainer: fileDiffRef, - containerWrapper: container, - }) - - // Hydrate annotation slots with interactive SolidJS components - // if (props.annotations.length > 0 && props.renderAnnotation != null) { - // for (const annotation of props.annotations) { - // const slotName = `annotation-${annotation.side}-${annotation.lineNumber}`; - // const slotElement = fileDiffRef.querySelector( - // `[slot="${slotName}"]` - // ) as HTMLElement; - // - // if (slotElement != null) { - // // Clear the static server-rendered content from the slot - // slotElement.innerHTML = ''; - // - // // Mount a fresh SolidJS component into this slot using render(). - // // This enables full SolidJS reactivity (signals, effects, etc.) - // const dispose = render( - // () => props.renderAnnotation!(annotation), - // slotElement - // ); - // cleanupFunctions.push(dispose); - // } - // } - // } - }) - onCleanup(() => { // Clean up FileDiff event handlers and dispose SolidJS components fileDiffInstance?.cleanUp() cleanupFunctions.forEach((dispose) => dispose()) }) - return ( - <div data-component="diff" style={styleVariables} ref={container}> - <file-diff ref={fileDiffRef} id="ssr-diff"> - <Show when={isServer && props.preloadedDiff}> - {(preloadedDiff) => <template shadowrootmode="open" innerHTML={preloadedDiff().prerenderedHTML} />} - </Show> - </file-diff> - </div> - ) + return <div data-component="diff" style={styleVariables} ref={container} /> } |
