# @pierre/diffs — Precision Diff Engine

> The core of diffs.com: a Shiki-backed diff renderer with lazy language/theme resolution, UniversalRenderingManager + InteractionManager + ScrollSyncManager + ResizeManager, DiffHunksRenderer and FileRenderer, full virtualization (VirtualizedFileDiff), both React and web-component entry points, and extensive unit tests that assert exact DOM and scroll behavior without broad snapshots.

- Repository: pierrecomputer/pierre
- GitHub: https://github.com/pierrecomputer/pierre
- Human wiki: https://grok-wiki.com/public/wiki/pierrecomputer-pierre-fac2c554b845
- Complete Markdown: https://grok-wiki.com/public/wiki/pierrecomputer-pierre-fac2c554b845/llms-full.txt

## Source Files

- `packages/diffs/package.json`
- `packages/diffs/src/index.ts`
- `packages/diffs/src/managers/UniversalRenderingManager.ts`
- `packages/diffs/src/renderers/DiffHunksRenderer.ts`
- `packages/diffs/src/highlighter/shared_highlighter.ts`
- `packages/diffs/src/react/CodeView.tsx`
- `packages/diffs/test/CodeView.diffIndicators.test.ts`
- `packages/diffs/test/FileRenderer.test.ts`

---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [packages/diffs/package.json](packages/diffs/package.json)
- [packages/diffs/README.md](packages/diffs/README.md)
- [packages/diffs/src/index.ts](packages/diffs/src/index.ts)
- [packages/diffs/src/managers/UniversalRenderingManager.ts](packages/diffs/src/managers/UniversalRenderingManager.ts)
- [packages/diffs/src/managers/InteractionManager.ts](packages/diffs/src/managers/InteractionManager.ts)
- [packages/diffs/src/managers/ScrollSyncManager.ts](packages/diffs/src/managers/ScrollSyncManager.ts)
- [packages/diffs/src/managers/ResizeManager.ts](packages/diffs/src/managers/ResizeManager.ts)
- [packages/diffs/src/renderers/DiffHunksRenderer.ts](packages/diffs/src/renderers/DiffHunksRenderer.ts)
- [packages/diffs/src/renderers/FileRenderer.ts](packages/diffs/src/renderers/FileRenderer.ts)
- [packages/diffs/src/highlighter/shared_highlighter.ts](packages/diffs/src/highlighter/shared_highlighter.ts)
- [packages/diffs/src/components/CodeView.ts](packages/diffs/src/components/CodeView.ts)
- [packages/diffs/src/components/VirtualizedFileDiff.ts](packages/diffs/src/components/VirtualizedFileDiff.ts)
- [packages/diffs/src/components/web-components.ts](packages/diffs/src/components/web-components.ts)
- [packages/diffs/src/react/CodeView.tsx](packages/diffs/src/react/CodeView.tsx)
- [packages/diffs/src/react/index.ts](packages/diffs/src/react/index.ts)
- [packages/diffs/test/CodeView.diffIndicators.test.ts](packages/diffs/test/CodeView.diffIndicators.test.ts)
- [packages/diffs/test/FileRenderer.test.ts](packages/diffs/test/FileRenderer.test.ts)

</details>

# @pierre/diffs — Precision Diff Engine

`@pierre/diffs` is the core rendering engine behind diffs.com. It is a Shiki-backed library that produces exact, syntax-highlighted diff and file views with split/unified layouts, hunk expansion, line annotations, selection, smooth scrolling, and full virtualization. The package exports both React components and an imperative DOM API, plus SSR helpers and an optional Web Worker path for large inputs. Every major behavior—scroll anchoring, indicator toggles, column measurements—is covered by narrow, assertion-heavy tests that avoid broad snapshots.

The design keeps renderers pure (they emit HAST only) while four focused managers own DOM events, measurements, and cross-view coordination. Lazy language/theme resolution and a render queue keep first-paint fast and bundle size small.

## Package Shape and Entry Points

```json
// packages/diffs/package.json:1-55
{
  "name": "@pierre/diffs",
  "exports": {
    ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" },
    "./react": "...",
    "./ssr": "...",
    "./worker": "..."
  },
  "sideEffects": ["dist/components/web-components.js"]
}
```

`src/index.ts` re-exports the imperative core (`CodeView`, `VirtualizedFileDiff`, `DiffHunksRenderer`, managers, highlighter utilities) plus the Shiki `codeToHtml` and `createCSSVariablesTheme` helpers. The React surface lives under `./react`; SSR and worker entry points are separate to keep the main bundle lean.

Sources: [packages/diffs/package.json:30-55](), [packages/diffs/src/index.ts:6-112]()

## Rendering Pipeline

User items (a diff or a file) flow through this sequence:

1. `CodeView` (or `Virtualizer`) owns the scroll viewport and a list of `VirtualizedFileDiff` / `VirtualizedFile` instances.
2. Each virtualized item extends `FileDiff` / `File` and owns a `DiffHunksRenderer` or `FileRenderer`.
3. `hydrate()` seeds a render cache and may start a worker task or async highlighter load.
4. `renderDiff(range)` or `renderCodeAST(range)` returns a `HunksRenderResult` / `FileRenderResult` containing HAST arrays, pre node, theme CSS, row counts, and buffer sizes.
5. The virtualizer materializes only the visible window plus overscroll into pooled DOM elements.
6. The four managers attach listeners, measure columns/annotations, and keep split panes in sync.

When the highlighter or language is not yet ready, the renderer emits plain-text HAST first and schedules a follow-up highlight pass that later updates the cache and triggers a targeted re-render via the `onRenderUpdate` callback.

Sources: [packages/diffs/src/components/CodeView.ts:445-524](), [packages/diffs/src/components/VirtualizedFileDiff.ts:61-100](), [packages/diffs/src/renderers/DiffHunksRenderer.ts:395-573]()

## The Four Managers

| Manager                    | Responsibility                                                                 | Key Mechanism                          |
|----------------------------|--------------------------------------------------------------------------------|----------------------------------------|
| UniversalRenderingManager  | Global RAF batching queue for all view updates                                 | `queueRender` / `dequeueRender` set    |
| InteractionManager         | Pointer handling, hover, line/token selection, gutter utilities                | Per-<pre> listeners + slot elements    |
| ScrollSyncManager          | Keep deletions and additions columns in sync in split view                     | Passive scroll listeners + timeout guard |
| ResizeManager              | Measure line-number gutters, content columns, annotation heights               | Shared ResizeObserver, batched per-view updates |

`UniversalRenderingManager` is deliberately tiny (one rAF drain loop) so that many independent virtualized items do not each schedule their own frames.

```ts
// packages/diffs/src/managers/UniversalRenderingManager.ts:7-9
export function queueRender(callback: Callback): void {
  callbacks.add(callback);
  frameId ??= requestAnimationFrame(render);
}
```

Sources: [packages/diffs/src/managers/UniversalRenderingManager.ts:1-37](), [packages/diffs/src/managers/InteractionManager.ts:227-276](), [packages/diffs/src/managers/ScrollSyncManager.ts:27-85](), [packages/diffs/src/managers/ResizeManager.ts:18-60]()

## DiffHunksRenderer and FileRenderer

Both renderer classes follow an identical lifecycle:

- Constructor accepts options, an optional `onRenderUpdate` hook, and an optional `WorkerPoolManager`.
- `setLineAnnotations`, `expandHunk`, `setOptions` mutate internal state and invalidate caches only when necessary.
- `renderDiff` / `renderCodeAST` consult the cache, the worker result, or the current highlighter and return a complete render result (HAST + metrics + CSS).
- Protected hooks (`getUnifiedInjectedRowsForLine`, `getSplitInjectedRowsForLine`) let subclasses inject extra rows (annotations, accept/reject controls) without subclassing the entire AST builder.
- `cleanUp` / `recycle` release worker tasks and cached highlighter references.

The renderers never touch real DOM; they only produce HAST via `renderDiffWithHighlighter` / `renderFileWithHighlighter` and the small set of `create*Element` utilities.

Sources: [packages/diffs/src/renderers/DiffHunksRenderer.ts:202-573](), [packages/diffs/src/renderers/FileRenderer.ts:88-100]()

## Lazy Language and Theme Resolution

`shared_highlighter.ts` owns a module-level singleton. `getSharedHighlighter({ themes, langs, preferredHighlighter })` creates the Shiki instance once (JS regex engine by default) and then:

- For every requested language/theme, either reuses an already-resolved registration or queues a dynamic import.
- Awaits the loaders, attaches the results, and returns the ready instance.
- Four Pierre themes are pre-registered via `registerCustomTheme`.

Renderers call `getHighlighterIfLoaded()` for the synchronous fast path and fall back to plain text + an async `initializeHighlighter()` call when needed. This keeps initial JS small and only pays for languages that are actually rendered.

Sources: [packages/diffs/src/highlighter/shared_highlighter.ts:36-89](), [packages/diffs/src/highlighter/shared_highlighter.ts:116-149]()

## Virtualization and Scroll

`VirtualizedFileDiff` (and its file counterpart) add:

- A sparse height map and checkpoint array so deep scrolls do not re-walk the entire diff from line 0.
- `renderRange` + `expandedHunks` control exactly which subset the renderer materializes.
- `top` / `height` + visibility flags let the `Virtualizer` (IntersectionObserver + scroll listener) decide which items receive real DOM nodes.
- Pending scroll targets remain active across layout shifts caused by annotations or line wrapping; the next rAF recomputes the exact destination.

`CodeView` owns the scroll container, element pool, sticky header logic, and the smooth-scroll animation state machine.

Sources: [packages/diffs/src/components/VirtualizedFileDiff.ts:69-100](), [packages/diffs/src/components/CodeView.ts:478-510]()

## React versus Imperative / Web Component Usage

- **React** (`./react`): `CodeView`, `FileDiff`, `MultiFileDiff`, `PatchDiff`, `Virtualizer`. They create the imperative instances internally, forward refs, and use portals for custom header/annotation content. `WorkerPoolContext` lets many views share one worker pool.
- **Imperative**: `new CodeView(options)`, `.setup(container)`, `.setItems(...)`, `.render(true)`, `.scrollTo(...)`. This is the surface used by the web-component SSR path and by any non-React host.
- **Web Components**: A side-effect module registers `<diffs-container>` (a shadow host that adopts the library stylesheet). SSR output places prerendered HTML inside a declarative shadow root under this tag; client hydration reuses the same DOM.

Sources: [packages/diffs/src/react/CodeView.tsx:138-232](), [packages/diffs/src/components/web-components.ts:7-38](), [packages/diffs/src/react/index.ts:4-20]()

## Testing Approach

Tests run in JSDOM with mocked `requestAnimationFrame`, `ResizeObserver`, and `IntersectionObserver`. They exercise the imperative API directly and make precise assertions on attributes (`data-indicators`), scroll positions, node counts, and selection state.

`CodeView.diffIndicators.test.ts` is representative: it sets `diffIndicators`, waits for the `<pre>` to appear, asserts the attribute, changes the option, re-renders, and asserts the new attribute value—without any structural snapshot.

Snapshot tests are intentionally narrow (AST shapes from `FileRenderer`, parser outputs) while behavioral tests (scroll anchoring, range scroll, element pooling, pointer events) stay assertion-based. This protects the invariants that annotation layers and review UIs depend on.

Sources: [packages/diffs/test/CodeView.diffIndicators.test.ts:174-225](), [packages/diffs/test/FileRenderer.test.ts:11-17]()

## Summary

`@pierre/diffs` achieves precise, scalable diff rendering by keeping a clean separation between pure HAST production (renderers + lazy Shiki) and DOM lifecycle (virtualizer + four managers). The checkpointed layout, render-range pruning, and RAF queue let the engine handle files that would defeat simpler “render everything” approaches while still exposing an imperative handle for exact scroll and selection control. The test suite’s focus on narrow, repeatable DOM and scroll assertions gives consumers confidence that the surface they build on will not shift under them.

Sources: [packages/diffs/src/renderers/DiffHunksRenderer.ts:455-573]()
