@orz/ui-code 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +216 -2
  3. package/dist/capped-code-block.d.ts +21 -0
  4. package/dist/capped-code-block.d.ts.map +1 -0
  5. package/dist/capped-code-block.js +41 -0
  6. package/dist/capped-code-block.js.map +1 -0
  7. package/dist/code-block.d.ts +147 -0
  8. package/dist/code-block.d.ts.map +1 -0
  9. package/dist/code-block.js +494 -0
  10. package/dist/code-block.js.map +1 -0
  11. package/dist/code-worker.d.ts +28 -0
  12. package/dist/code-worker.d.ts.map +1 -0
  13. package/dist/code-worker.js +29 -0
  14. package/dist/code-worker.js.map +1 -0
  15. package/dist/content.d.ts +12 -0
  16. package/dist/content.d.ts.map +1 -0
  17. package/dist/content.js +35 -0
  18. package/dist/content.js.map +1 -0
  19. package/dist/file-text.d.ts +16 -0
  20. package/dist/file-text.d.ts.map +1 -0
  21. package/dist/file-text.js +37 -0
  22. package/dist/file-text.js.map +1 -0
  23. package/dist/index.d.ts +6 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +6 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/patch-commit.d.ts +27 -0
  28. package/dist/patch-commit.d.ts.map +1 -0
  29. package/dist/patch-commit.js +109 -0
  30. package/dist/patch-commit.js.map +1 -0
  31. package/dist/patch-content.d.ts +13 -0
  32. package/dist/patch-content.d.ts.map +1 -0
  33. package/dist/patch-content.js +43 -0
  34. package/dist/patch-content.js.map +1 -0
  35. package/dist/patch-view.d.ts +49 -0
  36. package/dist/patch-view.d.ts.map +1 -0
  37. package/dist/patch-view.js +167 -0
  38. package/dist/patch-view.js.map +1 -0
  39. package/dist/word-diff.d.ts +82 -0
  40. package/dist/word-diff.d.ts.map +1 -0
  41. package/dist/word-diff.js +209 -0
  42. package/dist/word-diff.js.map +1 -0
  43. package/package.json +63 -3
  44. package/styles.css +34 -0
@@ -0,0 +1,494 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useTheme } from "@orz/ui/theme";
3
+ import { Component, lazy, Suspense, useCallback, useEffect, useMemo, useRef, useState, } from "react";
4
+ import { useCodeWorkerFactory, } from "./code-worker.js";
5
+ // @pierre/diffs is the heaviest dependency in the web bundle (T-24). Every
6
+ // value import goes through lazy() here so the library lands in its own
7
+ // chunk, fetched the first time a code surface actually renders; the rest
8
+ // of the app must only use type imports.
9
+ const LazyCodeView = lazy(() => import("@pierre/diffs/react").then((m) => ({
10
+ default: m.CodeView,
11
+ })));
12
+ /**
13
+ * CodeView with its tokenizing moved into pierre's worker pool, started from
14
+ * the factory a `CodeWorkerProvider` lends. pierre tokenizes the whole file
15
+ * even when only a screenful of lines is drawn: 1 MiB of log held the tab for
16
+ * 9.3 s on the main thread, 0.2 s with the worker. The lines show as plain
17
+ * text at once, and their colours follow.
18
+ */
19
+ const LazyWorkerCodeView = lazy(() => import("@pierre/diffs/react").then((m) => {
20
+ const CodeView = m.CodeView;
21
+ // The pool keeps the theme it was created with and overrides each
22
+ // view's own; a theme switch while it lives has to reach it here.
23
+ function ThemeSync({ theme }) {
24
+ const pool = m.useWorkerPool();
25
+ useEffect(() => {
26
+ pool?.setRenderOptions({ theme }).catch(() => { });
27
+ }, [pool, theme]);
28
+ return null;
29
+ }
30
+ function WorkerCodeView({ workerFactory, ...props }) {
31
+ const theme = useSyntaxTheme();
32
+ const [poolOptions] = useState(() => ({
33
+ workerFactory,
34
+ // One file is open at a time; each worker loads its own highlighter.
35
+ poolSize: 2,
36
+ }));
37
+ const [highlighterOptions] = useState(() => ({
38
+ theme,
39
+ preferredHighlighter: PIERRE_HIGHLIGHTER,
40
+ }));
41
+ return (_jsxs(m.WorkerPoolContextProvider, { poolOptions: poolOptions, highlighterOptions: highlighterOptions, children: [_jsx(ThemeSync, { theme: theme }), _jsx(CodeView, { ...props })] }));
42
+ }
43
+ return { default: WorkerCodeView };
44
+ }));
45
+ export const LazyMultiFileDiff = lazy(() => import("@pierre/diffs/react").then((m) => ({
46
+ default: m.MultiFileDiff,
47
+ })));
48
+ /**
49
+ * A unified diff split into commits and their files, or null when the text is
50
+ * not one. Strict on purpose: pierre's lenient mode skips a hunk whose counts
51
+ * do not add up and carries on, so the reader would be shown a patch with a
52
+ * change silently missing. Text before the first file — a commit message — is
53
+ * no reason to refuse; a patch with no file in it is.
54
+ */
55
+ export async function parsePatch(text) {
56
+ const { parsePatchFiles } = await import("@pierre/diffs");
57
+ try {
58
+ const patches = parsePatchFiles(text, undefined, true);
59
+ return patches.some((patch) => patch.files.length > 0) ? patches : null;
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ }
65
+ export const PIERRE_THEME = {
66
+ dark: "pierre-dark",
67
+ light: "pierre-light",
68
+ };
69
+ /**
70
+ * "system" makes pierre inject no color-scheme pin of its own; the actual
71
+ * scheme is forced from the outer tree by the `diffs-container` rules in
72
+ * this package's styles.css, which follow the app theme (T-36). Options objects that
73
+ * captured this value at module scope stay correct for the same reason.
74
+ */
75
+ export const PIERRE_THEME_TYPE = "system";
76
+ // Keyed by the pair, so every surface on the page hands pierre the same
77
+ // object identity across renders (props-stability guidance below).
78
+ const SYNTAX_THEMES = new Map();
79
+ function syntaxOf(theme, scheme, variant) {
80
+ const palette = theme[scheme];
81
+ const variants = palette?.variants;
82
+ const picked = variant !== undefined && variants && Object.hasOwn(variants, variant)
83
+ ? variants[variant]
84
+ : undefined;
85
+ return picked?.syntax ?? palette?.syntax;
86
+ }
87
+ /**
88
+ * Syntax token colors for the active theme (T-144). Under "system" each slot
89
+ * takes its own palette's shiki theme, because the light/dark choice is then
90
+ * made by CSS light-dark() inside the shadow root rather than by a React
91
+ * render. A pinned mode or a one-palette theme fills both slots from the side
92
+ * on screen: the slot the browser will not paint is irrelevant. A palette
93
+ * with no shiki theme keeps that slot of pierre's own pair.
94
+ */
95
+ export function useSyntaxTheme() {
96
+ const { pref, theme, colorScheme } = useTheme();
97
+ const variant = pref.ui?.variant;
98
+ const both = pref.ui?.mode === "system" && theme.light && theme.dark;
99
+ const light = syntaxOf(theme, both ? "light" : colorScheme, variant) ??
100
+ PIERRE_THEME.light;
101
+ const dark = syntaxOf(theme, both ? "dark" : colorScheme, variant) ?? PIERRE_THEME.dark;
102
+ const key = `${light}\0${dark}`;
103
+ let cached = SYNTAX_THEMES.get(key);
104
+ if (cached === undefined) {
105
+ cached =
106
+ light === PIERRE_THEME.light && dark === PIERRE_THEME.dark
107
+ ? PIERRE_THEME
108
+ : { light, dark };
109
+ SYNTAX_THEMES.set(key, cached);
110
+ }
111
+ return cached;
112
+ }
113
+ /** The shape every code surface falls back to: the code, unhighlighted. */
114
+ export function PlainCodeFallback({ contents }) {
115
+ return (_jsx("pre", { className: "overflow-x-auto rounded-md bg-muted p-3 text-[0.85em] leading-[1.45]", children: _jsx("code", { children: contents }) }));
116
+ }
117
+ // Keyed by the div CodeView renders into, so the module-level onPostRender
118
+ // below can find which block a failed <diffs-container> belongs to. A WeakMap
119
+ // because the entry is only ever reachable through a live node.
120
+ const DEGRADE_HANDLERS = new WeakMap();
121
+ // Options are cached at module scope; readiness belongs to the mounted block,
122
+ // just like degradation, rather than to a closure in an options object.
123
+ const READY_HANDLERS = new WeakMap();
124
+ /**
125
+ * pierre's own posture on a highlighter failure is to paint the exception
126
+ * message and its JS stack into the shadow root and carry on, which puts a
127
+ * stack trace where the reader expects code (T-177). An ErrorBoundary cannot
128
+ * take that over: the failing render happens partly on an async path, where a
129
+ * rethrow would only become an unhandled rejection and leave the block blank.
130
+ * `emitPostRender` does run right after the error is painted, in the same
131
+ * task, so spotting the wrapper here swaps in plain text before the next
132
+ * paint — the stack never reaches the screen.
133
+ */
134
+ function handlePostRender(container) {
135
+ const shadow = container.shadowRoot;
136
+ if (shadow?.querySelector("[data-error-wrapper]") != null) {
137
+ for (let node = container; node; node = node.parentElement) {
138
+ const degrade = DEGRADE_HANDLERS.get(node);
139
+ if (degrade !== undefined) {
140
+ degrade();
141
+ return;
142
+ }
143
+ }
144
+ }
145
+ if (shadow?.querySelector("[data-line]") != null) {
146
+ for (let node = container; node; node = node.parentElement) {
147
+ const ready = READY_HANDLERS.get(node);
148
+ if (ready !== undefined) {
149
+ ready();
150
+ return;
151
+ }
152
+ }
153
+ }
154
+ }
155
+ /**
156
+ * pierre defaults to "shiki-js", which transpiles the TextMate grammars'
157
+ * Oniguruma patterns into native RegExp through oniguruma-to-es. That
158
+ * transpiler is a recursive-descent pass over patterns, and the TypeScript
159
+ * grammar's giant lookaheads overflow SpiderMonkey's much shallower stack:
160
+ * Firefox rendered `too much recursion` in place of every `ts` fence
161
+ * (T-177). The wasm build is real Oniguruma and never runs that pass.
162
+ *
163
+ * pierre's highlighter is a module singleton whose engine is fixed by
164
+ * whichever surface creates it first, so every options object in the app has
165
+ * to name the same one — snippets, files, and the revision diff alike.
166
+ */
167
+ export const PIERRE_HIGHLIGHTER = "shiki-wasm";
168
+ // Module-scope per the library's props-stability guidance — now one object
169
+ // per theme rather than one overall, so a surface only re-renders when the
170
+ // theme it is rendered under actually changes.
171
+ const SNIPPET_OPTIONS = new Map();
172
+ const FILE_OPTIONS = new Map();
173
+ const FENCE_DIFF_OPTIONS = new Map();
174
+ const PATCH_OPTIONS = new Map();
175
+ // The only file items in a patch view are commit messages, and a message's
176
+ // line numbers count nothing the reader can use. pierre's own
177
+ // disableLineNumbers would take them off the diffs as well.
178
+ const COMMIT_MESSAGE_CSS = `
179
+ [data-file] [data-gutter-buffer], [data-file] [data-column-number] {
180
+ min-width: 0; padding: 0; border-right: 0;
181
+ }
182
+ [data-file] [data-column-number]::before { min-width: 0; }
183
+ [data-file] [data-line-number-content] { display: none; }
184
+ [data-file] [data-line] { min-height: 1lh; }
185
+ `;
186
+ /** px; the header rows `PatchFiles` callers draw must be exactly this tall. */
187
+ export const PATCH_HEADER_HEIGHT = 36;
188
+ function patchOptions(theme) {
189
+ const cached = PATCH_OPTIONS.get(theme);
190
+ if (cached)
191
+ return cached;
192
+ // The fence diff's look, with a header row per item: a patch is a list of
193
+ // files, and the header is the only place each one is named.
194
+ const options = {
195
+ theme,
196
+ themeType: PIERRE_THEME_TYPE,
197
+ diffStyle: "unified",
198
+ overflow: "wrap",
199
+ preferredHighlighter: PIERRE_HIGHLIGHTER,
200
+ onPostRender: handlePostRender,
201
+ unsafeCSS: COMMIT_MESSAGE_CSS,
202
+ layout: { paddingTop: 0, paddingBottom: 0, gap: 8 },
203
+ itemMetrics: { diffHeaderHeight: PATCH_HEADER_HEIGHT },
204
+ };
205
+ PATCH_OPTIONS.set(theme, options);
206
+ return options;
207
+ }
208
+ function snippetOptions(theme) {
209
+ const cached = SNIPPET_OPTIONS.get(theme);
210
+ if (cached)
211
+ return cached;
212
+ const options = {
213
+ theme,
214
+ themeType: PIERRE_THEME_TYPE,
215
+ disableFileHeader: true,
216
+ disableLineNumbers: true,
217
+ overflow: "wrap",
218
+ preferredHighlighter: PIERRE_HIGHLIGHTER,
219
+ onPostRender: handlePostRender,
220
+ };
221
+ SNIPPET_OPTIONS.set(theme, options);
222
+ return options;
223
+ }
224
+ function fileOptions(theme) {
225
+ const cached = FILE_OPTIONS.get(theme);
226
+ if (cached)
227
+ return cached;
228
+ const options = {
229
+ theme,
230
+ themeType: PIERRE_THEME_TYPE,
231
+ disableFileHeader: true,
232
+ preferredHighlighter: PIERRE_HIGHLIGHTER,
233
+ onPostRender: handlePostRender,
234
+ };
235
+ FILE_OPTIONS.set(theme, options);
236
+ return options;
237
+ }
238
+ function fenceDiffOptions(theme) {
239
+ const cached = FENCE_DIFF_OPTIONS.get(theme);
240
+ if (cached)
241
+ return cached;
242
+ const options = {
243
+ theme,
244
+ themeType: PIERRE_THEME_TYPE,
245
+ disableFileHeader: true,
246
+ // Red above green, one column. pierre's default is `split`, which puts
247
+ // the two sides in separate columns instead of next to each other.
248
+ diffStyle: "unified",
249
+ overflow: "wrap",
250
+ preferredHighlighter: PIERRE_HIGHLIGHTER,
251
+ // Off — pierre's default — unchanged context collapses to "N unmodified
252
+ // lines" past a single line of it. That reads well in a whole file's
253
+ // diff and badly in a fence the reader opened the document to read: a
254
+ // 34-line block with one edited line came out as 10 rendered lines.
255
+ expandUnchanged: true,
256
+ onPostRender: handlePostRender,
257
+ };
258
+ FENCE_DIFF_OPTIONS.set(theme, options);
259
+ return options;
260
+ }
261
+ /**
262
+ * Catches what the shadow-DOM check cannot: a CodeView that throws during
263
+ * React's own render, and a pierre chunk that never arrives (offline). Both
264
+ * land on the same plain text rather than on React's error screen.
265
+ */
266
+ class CodeViewBoundary extends Component {
267
+ state = { failed: false };
268
+ static getDerivedStateFromError() {
269
+ return { failed: true };
270
+ }
271
+ componentDidCatch(error) {
272
+ console.warn("pierre CodeView failed; showing plain text", error);
273
+ }
274
+ render() {
275
+ if (this.state.failed) {
276
+ return _jsx(PlainCodeFallback, { contents: this.props.contents });
277
+ }
278
+ return this.props.children;
279
+ }
280
+ }
281
+ // Fence tags that are language names rather than the file extensions
282
+ // pierre's filename inference knows.
283
+ const FENCE_TAG_EXTENSION = {
284
+ python: "py",
285
+ rust: "rs",
286
+ typescript: "ts",
287
+ javascript: "js",
288
+ shell: "sh",
289
+ golang: "go",
290
+ ruby: "rb",
291
+ csharp: "cs",
292
+ kotlin: "kt",
293
+ haskell: "hs",
294
+ perl: "pl",
295
+ powershell: "ps1",
296
+ elixir: "ex",
297
+ erlang: "erl",
298
+ clojure: "clj",
299
+ ocaml: "ml",
300
+ plaintext: "txt",
301
+ text: "txt",
302
+ };
303
+ /**
304
+ * A synthetic filename whose extension carries the fence's language.
305
+ * Passing the tag as `lang` instead would reject on unknown languages;
306
+ * filename inference degrades to plain text.
307
+ */
308
+ export function fenceFilename(tag) {
309
+ if (!tag)
310
+ return "snippet.txt";
311
+ return `snippet.${FENCE_TAG_EXTENSION[tag.toLowerCase()] ?? tag}`;
312
+ }
313
+ /**
314
+ * Read-only code rendering through pierre CodeView: syntax highlighting
315
+ * from the filename, dark/light theme in step with the revision diffs.
316
+ * Until pierre renders its first line a plain `<pre>` shows the same text, so
317
+ * content stays readable through both chunk loading and highlighter startup.
318
+ *
319
+ * pierre's virtualization scaffold declares `contain: inline-size`, so this
320
+ * block contributes 0px to an ancestor's intrinsic width: in a content-sized
321
+ * column (horizontal flex item, table cell, `max-content`) the code wraps at
322
+ * the width of the prose beside it — 30 lines came out 5416px tall in a 109px
323
+ * column, and a fence with no prose left the column 0px wide (T-287). Any such
324
+ * column has to be made to fill its row.
325
+ */
326
+ export function CodeBlock({ filename, contents, lineNumbers = false, plain = false, offThread = false, className, }) {
327
+ const items = useMemo(() => [
328
+ {
329
+ id: filename,
330
+ type: "file",
331
+ file: plain
332
+ ? { name: filename, contents, lang: "text" }
333
+ : { name: filename, contents },
334
+ },
335
+ ], [filename, contents, plain]);
336
+ const syntaxTheme = useSyntaxTheme();
337
+ const options = useMemo(() => lineNumbers ? fileOptions(syntaxTheme) : snippetOptions(syntaxTheme), [lineNumbers, syntaxTheme]);
338
+ const workerFactory = useCodeWorkerFactory();
339
+ const [degraded, setDegraded] = useState(false);
340
+ const [ready, setReady] = useState(contents === "");
341
+ const filenameRef = useRef(filename);
342
+ filenameRef.current = filename;
343
+ const warned = useRef(false);
344
+ // CodeView keeps the containerRef it was handed at mount, so the registered
345
+ // handler reads the filename off a ref rather than closing over the prop.
346
+ const containerRef = useCallback((node) => {
347
+ // Unmount hands us null; the WeakMap entry dies with the node anyway.
348
+ if (node === null)
349
+ return;
350
+ DEGRADE_HANDLERS.set(node, () => {
351
+ if (!warned.current) {
352
+ warned.current = true;
353
+ console.warn(`syntax highlighting failed for ${filenameRef.current}; showing plain text`);
354
+ }
355
+ setDegraded(true);
356
+ });
357
+ READY_HANDLERS.set(node, () => setReady(true));
358
+ }, []);
359
+ // Highlighting fails per grammar rather than per input, so a block that has
360
+ // gone plain stays plain: re-arming it would only repeat the same failure.
361
+ if (degraded)
362
+ return _jsx(PlainCodeFallback, { contents: contents });
363
+ return (_jsxs(CodeViewBoundary, { contents: contents, children: [!ready && _jsx(PlainCodeFallback, { contents: contents }), _jsx("div", { style: ready ? undefined : { visibility: "hidden" }, children: _jsx(Suspense, { fallback: null, children: offThread && !plain && workerFactory !== null ? (_jsx(LazyWorkerCodeView, { items: items, options: options, className: className, containerRef: containerRef, workerFactory: workerFactory })) : (_jsx(LazyCodeView, { items: items, options: options, className: className, containerRef: containerRef })) }) })] }));
364
+ }
365
+ function FenceDiff({ filename, before, after, }) {
366
+ const syntaxTheme = useSyntaxTheme();
367
+ const options = useMemo(() => fenceDiffOptions(syntaxTheme), [syntaxTheme]);
368
+ // A fence body carries no trailing newline, and pierre answers a last line
369
+ // that takes part in a change by drawing "No newline at end of file" —
370
+ // true of the string it was handed, meaningless to a reader of the document.
371
+ const oldFile = useMemo(() => ({ name: filename, contents: `${before}\n` }), [filename, before]);
372
+ const newFile = useMemo(() => ({ name: filename, contents: `${after}\n` }), [filename, after]);
373
+ const [degraded, setDegraded] = useState(false);
374
+ const [ready, setReady] = useState(after === "");
375
+ const filenameRef = useRef(filename);
376
+ filenameRef.current = filename;
377
+ const warned = useRef(false);
378
+ // MultiFileDiff takes no containerRef, so the handler goes on a wrapper of
379
+ // our own; `handlePostRender` walks up from the failing container to find it.
380
+ const containerRef = useCallback((node) => {
381
+ if (node === null)
382
+ return;
383
+ DEGRADE_HANDLERS.set(node, () => {
384
+ if (!warned.current) {
385
+ warned.current = true;
386
+ console.warn(`syntax highlighting failed for ${filenameRef.current}; showing plain text`);
387
+ }
388
+ setDegraded(true);
389
+ });
390
+ READY_HANDLERS.set(node, () => setReady(true));
391
+ // A warm pierre cache can synchronously render and emitPostRender from
392
+ // the child's ref before this parent ref registers its handlers. Replay
393
+ // any state already present in the shadow root so that signal is not lost.
394
+ for (const container of node.querySelectorAll("diffs-container")) {
395
+ handlePostRender(container);
396
+ }
397
+ }, []);
398
+ if (degraded)
399
+ return _jsx(PlainCodeFallback, { contents: after });
400
+ return (_jsx("div", { ref: containerRef, children: _jsxs(CodeViewBoundary, { contents: after, children: [!ready && _jsx(PlainCodeFallback, { contents: after }), _jsx("div", { style: ready ? undefined : { visibility: "hidden" }, children: _jsx(Suspense, { fallback: null, children: _jsx(LazyMultiFileDiff, { oldFile: oldFile, newFile: newFile, options: options }) }) })] }) }));
401
+ }
402
+ /**
403
+ * One code block shown as the line-level diff between two versions of it:
404
+ * red for the lines the baseline had, green for the ones that replaced them
405
+ * (T-343).
406
+ *
407
+ * Nothing is injected into the code. pierre is handed both bodies as plain
408
+ * strings and does its own diffing, highlighting and theming, so T-31's
409
+ * constraint — a mark reaching inside a fence deletes the code it wraps — is
410
+ * never engaged.
411
+ */
412
+ export function CodeDiffBlock({ filename, before, after, }) {
413
+ // Identical sides produce zero hunks, and a hunkless diff with no file
414
+ // header renders nothing at all — the block would vanish from the page.
415
+ // Branching here rather than inside `FenceDiff` also keeps every hook in
416
+ // both shapes unconditional.
417
+ if (before === after) {
418
+ return _jsx(CodeBlock, { filename: filename, contents: after });
419
+ }
420
+ return _jsx(FenceDiff, { filename: filename, before: before, after: after });
421
+ }
422
+ /** The CodeView item id of a patch's `index`-th file, counted across commits. */
423
+ export function patchFileId(index) {
424
+ return `file-${index}`;
425
+ }
426
+ /** The CodeView item id of a commit's message, counted across the patch. */
427
+ export function patchCommitId(index) {
428
+ return `commit-${index}`;
429
+ }
430
+ /**
431
+ * A parsed patch in one virtualized CodeView: per commit, its message, then
432
+ * one diff per file.
433
+ *
434
+ * `className` must cap the height. CodeView virtualizes against its own box,
435
+ * so an uncapped one grows to the whole patch and lays every line out: a
436
+ * 1 MB, 116-file patch froze the tab for 15 s in one task that way, against
437
+ * under 0.3 s capped.
438
+ *
439
+ * A highlighter failure takes the whole patch back to its plain text rather
440
+ * than one file: the grammar that failed is likely shared by its neighbours.
441
+ */
442
+ export function PatchFiles({ patches, messages, text, className, viewRef, collapsedFiles, renderHeader, }) {
443
+ const syntaxTheme = useSyntaxTheme();
444
+ const options = useMemo(() => patchOptions(syntaxTheme), [syntaxTheme]);
445
+ const items = useMemo(() => {
446
+ let position = 0;
447
+ return patches.flatMap((patch, index) => {
448
+ const files = patch.files.map((fileDiff) => {
449
+ const collapsed = collapsedFiles?.has(position) ?? false;
450
+ return {
451
+ id: patchFileId(position++),
452
+ type: "diff",
453
+ fileDiff,
454
+ collapsed,
455
+ // CodeView only takes a changed item from a changed version.
456
+ version: collapsed ? 0 : 1,
457
+ };
458
+ });
459
+ const message = messages[index];
460
+ if (message == null)
461
+ return files;
462
+ return [
463
+ {
464
+ id: patchCommitId(index),
465
+ type: "file",
466
+ collapsed: message === "",
467
+ file: {
468
+ name: patchCommitId(index),
469
+ contents: message,
470
+ lang: "text",
471
+ },
472
+ },
473
+ ...files,
474
+ ];
475
+ });
476
+ }, [patches, messages, collapsedFiles]);
477
+ const [degraded, setDegraded] = useState(false);
478
+ const warned = useRef(false);
479
+ const containerRef = useCallback((node) => {
480
+ if (node === null)
481
+ return;
482
+ DEGRADE_HANDLERS.set(node, () => {
483
+ if (!warned.current) {
484
+ warned.current = true;
485
+ console.warn("syntax highlighting failed for a patch; showing plain text");
486
+ }
487
+ setDegraded(true);
488
+ });
489
+ }, []);
490
+ if (degraded)
491
+ return _jsx(PlainCodeFallback, { contents: text });
492
+ return (_jsx(CodeViewBoundary, { contents: text, children: _jsx(Suspense, { fallback: _jsx(PlainCodeFallback, { contents: text }), children: _jsx(LazyCodeView, { ref: viewRef, items: items, options: options, className: className, containerRef: containerRef, renderCustomHeader: renderHeader }) }) }));
493
+ }
494
+ //# sourceMappingURL=code-block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-block.js","sourceRoot":"","sources":["../src/code-block.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type ReactNode } from "react";
2
+ /** Starts one of pierre's highlighting workers: `@pierre/diffs/worker/worker.js`, bundled. */
3
+ export type CodeWorkerFactory = () => Worker;
4
+ /**
5
+ * Lends pierre's highlighting worker to the code views below it that tokenize off the main
6
+ * thread: `codeContent`'s files, in the viewer and in cards. pierre tokenizes a whole file even
7
+ * when it draws a screenful, so 1 MiB of log held the tab for 9.3 s on the main thread and 0.2 s
8
+ * with the worker; the lines show at once and their colours follow. Without a provider those
9
+ * views tokenize on the main thread.
10
+ *
11
+ * The worker script has to come from the app's bundler, which is why the package cannot start it
12
+ * itself. With Vite:
13
+ *
14
+ * ```ts
15
+ * import PierreWorker from "@pierre/diffs/worker/worker.js?worker";
16
+ * <CodeWorkerProvider workerFactory={() => new PierreWorker()}>
17
+ * ```
18
+ *
19
+ * The pool is a page-wide singleton, created from the first factory and terminated when the
20
+ * last view using it unmounts, so it only exists while such a view is on screen.
21
+ */
22
+ export declare function CodeWorkerProvider({ workerFactory, children, }: {
23
+ workerFactory: CodeWorkerFactory;
24
+ children?: ReactNode;
25
+ }): import("react").JSX.Element;
26
+ /** The nearest provider's factory, or null outside one. */
27
+ export declare function useCodeWorkerFactory(): CodeWorkerFactory | null;
28
+ //# sourceMappingURL=code-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-worker.d.ts","sourceRoot":"","sources":["../src/code-worker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAAc,MAAM,OAAO,CAAC;AAElE,8FAA8F;AAC9F,MAAM,MAAM,iBAAiB,GAAG,MAAM,MAAM,CAAC;AAI7C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,aAAa,EACb,QAAQ,GACT,EAAE;IACD,aAAa,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,+BAMA;AAED,2DAA2D;AAC3D,wBAAgB,oBAAoB,IAAI,iBAAiB,GAAG,IAAI,CAE/D"}
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from "react";
3
+ const CodeWorkerContext = createContext(null);
4
+ /**
5
+ * Lends pierre's highlighting worker to the code views below it that tokenize off the main
6
+ * thread: `codeContent`'s files, in the viewer and in cards. pierre tokenizes a whole file even
7
+ * when it draws a screenful, so 1 MiB of log held the tab for 9.3 s on the main thread and 0.2 s
8
+ * with the worker; the lines show at once and their colours follow. Without a provider those
9
+ * views tokenize on the main thread.
10
+ *
11
+ * The worker script has to come from the app's bundler, which is why the package cannot start it
12
+ * itself. With Vite:
13
+ *
14
+ * ```ts
15
+ * import PierreWorker from "@pierre/diffs/worker/worker.js?worker";
16
+ * <CodeWorkerProvider workerFactory={() => new PierreWorker()}>
17
+ * ```
18
+ *
19
+ * The pool is a page-wide singleton, created from the first factory and terminated when the
20
+ * last view using it unmounts, so it only exists while such a view is on screen.
21
+ */
22
+ export function CodeWorkerProvider({ workerFactory, children, }) {
23
+ return (_jsx(CodeWorkerContext.Provider, { value: workerFactory, children: children }));
24
+ }
25
+ /** The nearest provider's factory, or null outside one. */
26
+ export function useCodeWorkerFactory() {
27
+ return useContext(CodeWorkerContext);
28
+ }
29
+ //# sourceMappingURL=code-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-worker.js","sourceRoot":"","sources":["../src/code-worker.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAkB,UAAU,EAAE,MAAM,OAAO,CAAC;AAKlE,MAAM,iBAAiB,GAAG,aAAa,CAA2B,IAAI,CAAC,CAAC;AAExE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,aAAa,EACb,QAAQ,GAIT;IACC,OAAO,CACL,KAAC,iBAAiB,CAAC,QAAQ,IAAC,KAAK,EAAE,aAAa,YAC7C,QAAQ,GACkB,CAC9B,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,oBAAoB;IAClC,OAAO,UAAU,CAAC,iBAAiB,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type ContentRenderer } from "@orz/ui-content";
2
+ /**
3
+ * The registry entry for code: every inline source (a fenced block, whatever its language) and
4
+ * every text file, in either placement. It takes everything a narrower renderer would, so register
5
+ * it after them — markdown files, mermaid diagrams, patches.
6
+ *
7
+ * It highlights at most `TEXT_PREVIEW_MAX_BYTES`, and draws text found larger plain. A file
8
+ * declared over `TEXT_PREVIEW_HARD_MAX_BYTES` is not loaded. A file tokenizes in the worker a
9
+ * `CodeWorkerProvider` lends, inside a height cap.
10
+ */
11
+ export declare const codeContent: ContentRenderer;
12
+ //# sourceMappingURL=content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../src/content.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EAGrB,MAAM,iBAAiB,CAAC;AAyCzB;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,eAKzB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { isTextFile, } from "@orz/ui-content";
3
+ import { CappedCodeBlock } from "./capped-code-block.js";
4
+ import { fenceFilename } from "./code-block.js";
5
+ import { FileText } from "./file-text.js";
6
+ function accepts(source) {
7
+ return source.kind === "inline" || isTextFile(source);
8
+ }
9
+ function Code({ source, placement, className }) {
10
+ if (source.kind === "file") {
11
+ return (_jsx(FileText, { source: source, placement: placement, className: className, children: (text) => (_jsx(CappedCodeBlock, { filename: source.name, contents: text, lineNumbers: true, offThread: true,
12
+ // A document's file sits in a card that clips its body; the
13
+ // viewer's pane hands down the height it may fill.
14
+ capClassName: placement === "viewer"
15
+ ? "max-h-(--attachment-pane-height) overflow-auto"
16
+ : "max-h-80 overflow-hidden" })) }));
17
+ }
18
+ return (_jsx("div", { className: className, children: _jsx(CappedCodeBlock, { filename: fenceFilename(source.lang), contents: source.text }) }));
19
+ }
20
+ /**
21
+ * The registry entry for code: every inline source (a fenced block, whatever its language) and
22
+ * every text file, in either placement. It takes everything a narrower renderer would, so register
23
+ * it after them — markdown files, mermaid diagrams, patches.
24
+ *
25
+ * It highlights at most `TEXT_PREVIEW_MAX_BYTES`, and draws text found larger plain. A file
26
+ * declared over `TEXT_PREVIEW_HARD_MAX_BYTES` is not loaded. A file tokenizes in the worker a
27
+ * `CodeWorkerProvider` lends, inside a height cap.
28
+ */
29
+ export const codeContent = {
30
+ name: "code",
31
+ accepts,
32
+ display: "block",
33
+ Component: Code,
34
+ };
35
+ //# sourceMappingURL=content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../src/content.tsx"],"names":[],"mappings":";AAAA,OAAO,EAIL,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAkB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAiB,CAAC;AAE3C,SAAS,OAAO,CAAC,MAAqB;IACpC,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAgB;IAC1D,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,OAAO,CACL,KAAC,QAAQ,IAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,YACjE,CAAC,IAAI,EAAE,EAAE,CAAC,CACT,KAAC,eAAe,IACd,QAAQ,EAAE,MAAM,CAAC,IAAI,EACrB,QAAQ,EAAE,IAAI,EACd,WAAW,QACX,SAAS;gBACT,4DAA4D;gBAC5D,mDAAmD;gBACnD,YAAY,EACV,SAAS,KAAK,QAAQ;oBACpB,CAAC,CAAC,gDAAgD;oBAClD,CAAC,CAAC,0BAA0B,GAEhC,CACH,GACQ,CACZ,CAAC;IACJ,CAAC;IACD,OAAO,CACL,cAAK,SAAS,EAAE,SAAS,YACvB,KAAC,eAAe,IACd,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,EACpC,QAAQ,EAAE,MAAM,CAAC,IAAI,GACrB,GACE,CACP,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,WAAW,GAAoB;IAC1C,IAAI,EAAE,MAAM;IACZ,OAAO;IACP,OAAO,EAAE,OAAO;IAChB,SAAS,EAAE,IAAI;CAChB,CAAC"}