diff options
Diffstat (limited to 'packages/ui/src')
| -rw-r--r-- | packages/ui/src/components/code.tsx | 4 | ||||
| -rw-r--r-- | packages/ui/src/components/diff-ssr.tsx | 2 | ||||
| -rw-r--r-- | packages/ui/src/components/diff.tsx | 17 | ||||
| -rw-r--r-- | packages/ui/src/components/session-review.tsx | 18 | ||||
| -rw-r--r-- | packages/ui/src/context/worker-pool.tsx | 16 | ||||
| -rw-r--r-- | packages/ui/src/pierre/worker.ts | 47 |
6 files changed, 75 insertions, 29 deletions
diff --git a/packages/ui/src/components/code.tsx b/packages/ui/src/components/code.tsx index 77696faed..fda08260f 100644 --- a/packages/ui/src/components/code.tsx +++ b/packages/ui/src/components/code.tsx @@ -1,7 +1,7 @@ import { type FileContents, File, FileOptions, LineAnnotation } from "@pierre/diffs" import { ComponentProps, createEffect, createMemo, splitProps } from "solid-js" import { createDefaultOptions, styleVariables } from "../pierre" -import { workerPool } from "../pierre/worker" +import { getWorkerPool } from "../pierre/worker" export type CodeProps<T = {}> = FileOptions<T> & { file: FileContents @@ -21,7 +21,7 @@ export function Code<T>(props: CodeProps<T>) { ...createDefaultOptions<T>("unified"), ...others, }, - workerPool, + getWorkerPool("unified"), ), ) diff --git a/packages/ui/src/components/diff-ssr.tsx b/packages/ui/src/components/diff-ssr.tsx index e367a4fbe..56a12c100 100644 --- a/packages/ui/src/components/diff-ssr.tsx +++ b/packages/ui/src/components/diff-ssr.tsx @@ -13,7 +13,7 @@ export function Diff<T>(props: SSRDiffProps<T>) { let container!: HTMLDivElement let fileDiffRef!: HTMLElement const [local, others] = splitProps(props, ["before", "after", "class", "classList", "annotations"]) - const workerPool = useWorkerPool() + const workerPool = useWorkerPool(props.diffStyle) let fileDiffInstance: FileDiff<T> | undefined const cleanupFunctions: Array<() => void> = [] diff --git a/packages/ui/src/components/diff.tsx b/packages/ui/src/components/diff.tsx index 75dde0440..ff70cece9 100644 --- a/packages/ui/src/components/diff.tsx +++ b/packages/ui/src/components/diff.tsx @@ -1,7 +1,7 @@ import { FileDiff } from "@pierre/diffs" import { createEffect, createMemo, onCleanup, splitProps } from "solid-js" import { createDefaultOptions, type DiffProps, styleVariables } from "../pierre" -import { workerPool } from "../pierre/worker" +import { getWorkerPool } from "../pierre/worker" // interface ThreadMetadata { // threadId: string @@ -20,26 +20,23 @@ export function Diff<T>(props: DiffProps<T>) { ...createDefaultOptions(props.diffStyle), ...others, }, - workerPool, + getWorkerPool(props.diffStyle), ), ) - const cleanupFunctions: Array<() => void> = [] - createEffect(() => { + const diff = fileDiff() container.innerHTML = "" - fileDiff().render({ + diff.render({ oldFile: local.before, newFile: local.after, lineAnnotations: local.annotations, containerWrapper: container, }) - }) - onCleanup(() => { - // Clean up FileDiff event handlers and dispose SolidJS components - fileDiff()?.cleanUp() - cleanupFunctions.forEach((dispose) => dispose()) + onCleanup(() => { + diff.cleanUp() + }) }) return <div data-component="diff" style={styleVariables} ref={container} /> diff --git a/packages/ui/src/components/session-review.tsx b/packages/ui/src/components/session-review.tsx index 9162b5216..9e6c633f4 100644 --- a/packages/ui/src/components/session-review.tsx +++ b/packages/ui/src/components/session-review.tsx @@ -1,5 +1,6 @@ import { Accordion } from "./accordion" import { Button } from "./button" +import { RadioGroup } from "./radio-group" import { DiffChanges } from "./diff-changes" import { FileIcon } from "./file-icon" import { Icon } from "./icon" @@ -13,8 +14,12 @@ import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" import { Dynamic } from "solid-js/web" import { checksum } from "@opencode-ai/util/encode" +export type SessionReviewDiffStyle = "unified" | "split" + export interface SessionReviewProps { split?: boolean + diffStyle?: SessionReviewDiffStyle + onDiffStyleChange?: (diffStyle: SessionReviewDiffStyle) => void class?: string classList?: Record<string, boolean | undefined> classes?: { root?: string; header?: string; container?: string } @@ -28,6 +33,8 @@ export const SessionReview = (props: SessionReviewProps) => { open: props.diffs.length > 10 ? [] : props.diffs.map((d) => d.file), }) + const diffStyle = () => props.diffStyle ?? (props.split ? "split" : "unified") + const handleChange = (open: string[]) => { setStore("open", open) } @@ -60,6 +67,15 @@ export const SessionReview = (props: SessionReviewProps) => { > <div data-slot="session-review-title">Session changes</div> <div data-slot="session-review-actions"> + <Show when={props.onDiffStyleChange}> + <RadioGroup + options={["unified", "split"] as const} + current={diffStyle()} + value={(style) => style} + label={(style) => (style === "unified" ? "Unified" : "Split")} + onSelect={(style) => style && props.onDiffStyleChange?.(style)} + /> + </Show> <Button size="normal" icon="chevron-grabber-vertical" onClick={handleExpandOrCollapseAll}> <Switch> <Match when={store.open.length > 0}>Collapse all</Match> @@ -102,7 +118,7 @@ export const SessionReview = (props: SessionReviewProps) => { <Dynamic component={diffComponent} preloadedDiff={diff.preloaded} - diffStyle={props.split ? "split" : "unified"} + diffStyle={diffStyle()} before={{ name: diff.file!, contents: diff.before!, diff --git a/packages/ui/src/context/worker-pool.tsx b/packages/ui/src/context/worker-pool.tsx index fc2eecc03..5f788f786 100644 --- a/packages/ui/src/context/worker-pool.tsx +++ b/packages/ui/src/context/worker-pool.tsx @@ -1,10 +1,20 @@ import type { WorkerPoolManager } from "@pierre/diffs/worker" import { createSimpleContext } from "./helper" -const ctx = createSimpleContext<WorkerPoolManager | undefined, { pool: WorkerPoolManager | undefined }>({ +export type WorkerPools = { + unified: WorkerPoolManager | undefined + split: WorkerPoolManager | undefined +} + +const ctx = createSimpleContext<WorkerPools, { pools: WorkerPools }>({ name: "WorkerPool", - init: (props) => props.pool, + init: (props) => props.pools, }) export const WorkerPoolProvider = ctx.provider -export const useWorkerPool = ctx.use + +export function useWorkerPool(diffStyle: "unified" | "split" | undefined) { + const pools = ctx.use() + if (diffStyle === "split") return pools.split + return pools.unified +} diff --git a/packages/ui/src/pierre/worker.ts b/packages/ui/src/pierre/worker.ts index 2d2640674..0d117c368 100644 --- a/packages/ui/src/pierre/worker.ts +++ b/packages/ui/src/pierre/worker.ts @@ -1,16 +1,15 @@ -import { getOrCreateWorkerPoolSingleton, WorkerPoolManager } from "@pierre/diffs/worker" +import { WorkerPoolManager } from "@pierre/diffs/worker" import ShikiWorkerUrl from "@pierre/diffs/worker/worker.js?worker&url" +export type WorkerPoolStyle = "unified" | "split" + export function workerFactory(): Worker { return new Worker(ShikiWorkerUrl, { type: "module" }) } -export const workerPool: WorkerPoolManager | undefined = (() => { - if (typeof window === "undefined") { - return undefined - } - return getOrCreateWorkerPoolSingleton({ - poolOptions: { +function createPool(lineDiffType: "none" | "word-alt") { + const pool = new WorkerPoolManager( + { workerFactory, // poolSize defaults to 8. More workers = more parallelism but // also more memory. Too many can actually slow things down. @@ -19,10 +18,34 @@ export const workerPool: WorkerPoolManager | undefined = (() => { // boot up time for workers poolSize: 2, }, - highlighterOptions: { + { theme: "OpenCode", - // Optionally preload languages to avoid lazy-loading delays - // langs: ["typescript", "javascript", "css", "html"], + lineDiffType, }, - }) -})() + ) + + pool.initialize() + return pool +} + +let unified: WorkerPoolManager | undefined +let split: WorkerPoolManager | undefined + +export function getWorkerPool(style: WorkerPoolStyle | undefined): WorkerPoolManager | undefined { + if (typeof window === "undefined") return + + if (style === "split") { + if (!split) split = createPool("word-alt") + return split + } + + if (!unified) unified = createPool("none") + return unified +} + +export function getWorkerPools() { + return { + unified: getWorkerPool("unified"), + split: getWorkerPool("split"), + } +} |
