Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152// the css side of pierre theming lives in src/pierre.css
import type { FileDiffOptions, FileOptions, VirtualFileMetrics } from "@pierre/diffs";import { browser } from "$app/env";import diffShadowCSS from "#lib/components/repo/pierreDiff.css?raw";import { getSharedHighlighter, SYNTAX_HIGHLIGHTER, SYNTAX_THEME_NAME } from "#lib/syntax.ts";import type { WorkerPoolManager } from "@pierre/diffs/worker";
// pierre's two diff layouts, threaded from the ?diff= url param down to the// FileDiff instancesexport type DiffStyle = NonNullable<FileDiffOptions<undefined, undefined>["diffStyle"]>;
// pierre stops highlighting after 1000 characters, lockfiles often run longerconst PIERRE_TOKENIZE_MAX_LINE_LENGTH = 5000;
const PIERRE_BASE_OPTIONS = { theme: SYNTAX_THEME_NAME, themeType: "system", preferredHighlighter: SYNTAX_HIGHLIGHTER, tokenizeMaxLineLength: PIERRE_TOKENIZE_MAX_LINE_LENGTH} as const;
// pierre's core stylesheet reaches a container two ways: the `diffs-container`// custom element adopts it in its constructor, but bails when the element already// has a shadow root — which an ssr'd `<template shadowrootmode>` gives it — and the// ssr preloads embed it as a `<style data-core-css>` child instead. so clearing// every child of an ssr'd shadow root leaves each later client render unstyled:// pierre rebuilds the <pre> but never re-emits core css for a managed container.// one sheet covers unified, split and wrap, so the ssr'd one stays correct.export const clearPierreRender = (host: HTMLElement): void => { for (const node of [...(host.shadowRoot?.children ?? [])]) if (node instanceof HTMLPreElement) node.remove();};
// Pierre's CodeView accepts only a strict subset of Diff options.export const pierreCodeViewOptions = (style: DiffStyle, wrap: boolean = false) => ({ ...PIERRE_BASE_OPTIONS, diffStyle: style, diffIndicators: "bars" as const, lineDiffType: "word-alt" as const, hunkSeparators: "line-info" as const, overflow: wrap ? ("wrap" as const) : ("scroll" as const), unsafeCSS: diffShadowCSS});
export const pierreFileOptions = (wrap: boolean): FileOptions<undefined, undefined> => ({ ...PIERRE_BASE_OPTIONS, disableFileHeader: true, overflow: wrap ? "wrap" : "scroll"});
export const prerenderFile = async ( name: string, contents: string | null): Promise<string | undefined> => { if (browser || contents === null) return undefined; const { preloadFile } = await import("@pierre/diffs/ssr"); const { prerenderedHTML } = await preloadFile({ file: { name, contents }, options: pierreFileOptions(false) }); return prerenderedHTML;};
// lazy dynamic imports: pierre's worker bundle trips vite's dev dependency optimizerlet workerPoolPromise: Promise<WorkerPoolManager | undefined> | undefined;let terminateWorkerPool: (() => void) | undefined;let consumers = 0;let idleTimer: ReturnType<typeof setTimeout> | undefined;
const POOL_IDLE_MS = 1000;
const poolSize = (): number => matchMedia("(pointer: coarse)").matches ? 1 : Math.max(2, Math.min(4, (navigator.hardwareConcurrency ?? 4) - 1));
const createWorkerPool = async (): Promise<WorkerPoolManager | undefined> => { try { const [ { getOrCreateWorkerPoolSingleton, terminateWorkerPoolSingleton }, { default: PierreWorker } ] = await Promise.all([ import("@pierre/diffs/worker"), import("@pierre/diffs/worker/worker.js?worker") ]); const pool = getOrCreateWorkerPoolSingleton({ poolOptions: { workerFactory: () => new PierreWorker(), poolSize: poolSize(), totalASTLRUCacheSize: 24 }, highlighterOptions: { theme: SYNTAX_THEME_NAME, useTokenTransformer: false, lineDiffType: "word-alt", maxLineDiffLength: 1000, tokenizeMaxLineLength: PIERRE_TOKENIZE_MAX_LINE_LENGTH, preferredHighlighter: SYNTAX_HIGHLIGHTER, langs: [] } }); terminateWorkerPool = terminateWorkerPoolSingleton; return pool; } catch { workerPoolPromise = undefined; return undefined; }};
const shutDownWorkerPool = () => { terminateWorkerPool?.(); terminateWorkerPool = undefined; workerPoolPromise = undefined;};
export const retainPierreWorkerPool = (): { pool: Promise<WorkerPoolManager | undefined>; release: () => void;} => { if (!browser) return { pool: Promise.resolve(undefined), release: () => {} };
consumers++; clearTimeout(idleTimer); let released = false; return { pool: (workerPoolPromise ??= createWorkerPool()), release: () => { if (released) return; released = true; if (--consumers > 0) return; idleTimer = setTimeout(shutDownWorkerPool, POOL_IDLE_MS); } };};
// without this warmup pierre's first render of a missing language is blankif (browser) void getSharedHighlighter({ themes: [SYNTAX_THEME_NAME], langs: [] });
export const PIERRE_VALIDATE_ITEM_HEIGHTS = import.meta.env.DEV && browser && new URLSearchParams(location.search).has("diffmetrics");
export const PIERRE_LINE_HEIGHT = 20;export const PIERRE_HUNK_LINE_COUNT = 50;
export const PIERRE_ITEM_METRICS: Partial<VirtualFileMetrics> = { lineHeight: PIERRE_LINE_HEIGHT, hunkLineCount: PIERRE_HUNK_LINE_COUNT, hunkSeparatorHeight: PIERRE_LINE_HEIGHT, spacing: 0};