import { createHighlighterCore, type HighlighterCore } from "@shikijs/core";import { createJavaScriptRegexEngine } from "@shikijs/engine-javascript";import bashLanguage from "@shikijs/langs/bash";import diffLanguage from "@shikijs/langs/diff";import javascriptLanguage from "@shikijs/langs/javascript";import jsonLanguage from "@shikijs/langs/json";import jsxLanguage from "@shikijs/langs/jsx";import tsxLanguage from "@shikijs/langs/tsx";import typescriptLanguage from "@shikijs/langs/typescript";import yamlLanguage from "@shikijs/langs/yaml";import * as Schema from "effect/Schema"; import type { NativeReviewDiffFile, NativeReviewDiffLanguage } from "./nativeReviewDiffTypes";import type { NativeReviewDiffRow, NativeReviewDiffToken } from "./nativeReviewDiffSurface"; export type NativeReviewDiffHighlightScheme = "light" | "dark";export type NativeReviewDiffHighlightEngine = "native" | "javascript"; export class NativeReviewDiffHighlighterUnavailableError extends Schema.TaggedErrorClass<NativeReviewDiffHighlighterUnavailableError>()( "NativeReviewDiffHighlighterUnavailableError", {},) { override get message(): string { return "The native review diff highlighter is unavailable in this build."; }} export const isNativeReviewDiffHighlighterUnavailableError = Schema.is( NativeReviewDiffHighlighterUnavailableError,); export class NativeReviewDiffHighlighterInitializationError extends Schema.TaggedErrorClass<NativeReviewDiffHighlighterInitializationError>()( "NativeReviewDiffHighlighterInitializationError", { requestedEngine: Schema.Literals(["native", "javascript"]), attemptedEngine: Schema.Literals(["native", "javascript"]), cause: Schema.Defect(), },) { override get message(): string { return `Failed to initialize the ${this.attemptedEngine} review diff highlighter requested as ${this.requestedEngine}.`; }} export interface NativeReviewDiffHighlighterHandle { readonly engine: NativeReviewDiffHighlightEngine; readonly tokenize: ( code: string, options: { readonly lang: NativeReviewDiffLanguage; readonly theme: string }, ) => ReadonlyArray<ReadonlyArray<NativeReviewDiffToken>>;} interface NativeReviewDiffLineRow extends NativeReviewDiffRow { readonly kind: "line"; readonly fileId: string; readonly content: string;} interface IndexedNativeReviewDiffLineRow { readonly row: NativeReviewDiffLineRow; readonly rowIndex: number;} export interface NativeReviewDiffTokenChunk { readonly chunkIndex: number; readonly fileId: string; readonly filePath: string; readonly language: NativeReviewDiffLanguage; readonly lineCount: number; readonly durationMs: number; readonly tokensByRowId: Record<string, ReadonlyArray<NativeReviewDiffToken>>;} export interface StreamNativeReviewDiffTokenInput { readonly rows: ReadonlyArray<NativeReviewDiffRow>; readonly files: ReadonlyArray<NativeReviewDiffFile>; readonly scheme: NativeReviewDiffHighlightScheme; readonly engine?: NativeReviewDiffHighlightEngine; readonly chunkSize?: number; readonly signal?: AbortSignal; readonly onChunk: (chunk: NativeReviewDiffTokenChunk) => void;} export interface HighlightNativeReviewDiffVisibleRowsInput { readonly rows: ReadonlyArray<NativeReviewDiffRow>; readonly files: ReadonlyArray<NativeReviewDiffFile>; readonly scheme: NativeReviewDiffHighlightScheme; readonly engine?: NativeReviewDiffHighlightEngine; readonly firstRowIndex: number; readonly lastRowIndex: number; readonly overscanRows?: number; readonly maxRows?: number; readonly alreadyHighlightedRowIds?: ReadonlySet<string>; readonly signal?: AbortSignal;} const NATIVE_REVIEW_DIFF_HIGHLIGHT_CHUNK_SIZE = 500;const NATIVE_REVIEW_DIFF_VISIBLE_OVERSCAN_ROWS = 160;const NATIVE_REVIEW_DIFF_VISIBLE_MAX_ROWS = 360; const NATIVE_REVIEW_DIFF_THEME_NAME_BY_SCHEME = { dark: "t3-pierre-dark", light: "t3-pierre-light",} as const; const PIERRE_LIGHT_SHIKI_THEME = { name: NATIVE_REVIEW_DIFF_THEME_NAME_BY_SCHEME.light, type: "light" as const, fg: "#070707", bg: "#ffffff", settings: [ { settings: { foreground: "#070707", background: "#ffffff" } }, { scope: "comment, punctuation.definition.comment", settings: { foreground: "#84848A" } }, { scope: "keyword, storage, storage.type, keyword.operator.expression", settings: { foreground: "#FC2B73" }, }, { scope: "entity.name.function, support.function, meta.function-call", settings: { foreground: "#7B43F8" }, }, { scope: "entity.name.type, support.type, support.class", settings: { foreground: "#C635E4" }, }, { scope: "string, constant.character, punctuation.definition.string", settings: { foreground: "#199F43" }, }, { scope: "constant.numeric, constant.language, constant.other", settings: { foreground: "#1CA1C7" }, }, { scope: "variable.parameter, variable.other.readwrite, meta.object-literal.key", settings: { foreground: "#D47628" }, }, { scope: "entity.name.tag, support.class.component", settings: { foreground: "#199F43" }, }, { scope: "punctuation, meta.brace, meta.delimiter", settings: { foreground: "#79797F" }, }, { scope: "invalid", settings: { foreground: "#D52C36" } }, ],}; const PIERRE_DARK_SHIKI_THEME = { name: NATIVE_REVIEW_DIFF_THEME_NAME_BY_SCHEME.dark, type: "dark" as const, fg: "#adadb1", bg: "#0a0a0a", settings: [ { settings: { foreground: "#adadb1", background: "#0a0a0a" } }, { scope: "comment, punctuation.definition.comment", settings: { foreground: "#84848A" } }, { scope: "keyword, storage, storage.type, keyword.operator.expression", settings: { foreground: "#FF678D" }, }, { scope: "entity.name.function, support.function, meta.function-call", settings: { foreground: "#9D6AFB" }, }, { scope: "entity.name.type, support.type, support.class", settings: { foreground: "#D568EA" }, }, { scope: "string, constant.character, punctuation.definition.string", settings: { foreground: "#5ECC71" }, }, { scope: "constant.numeric, constant.language, constant.other", settings: { foreground: "#68CDF2" }, }, { scope: "variable.parameter, variable.other.readwrite, meta.object-literal.key", settings: { foreground: "#FFA359" }, }, { scope: "entity.name.tag, support.class.component", settings: { foreground: "#5ECC71" }, }, { scope: "punctuation, meta.brace, meta.delimiter", settings: { foreground: "#79797F" }, }, { scope: "invalid", settings: { foreground: "#FF6762" } }, ],}; const NATIVE_REVIEW_DIFF_SHIKI_THEMES = [ PIERRE_LIGHT_SHIKI_THEME, PIERRE_DARK_SHIKI_THEME,] satisfies Parameters<typeof createHighlighterCore>[0]["themes"]; const NATIVE_REVIEW_DIFF_LANGUAGES = [ bashLanguage, diffLanguage, javascriptLanguage, jsonLanguage, jsxLanguage, tsxLanguage, typescriptLanguage, yamlLanguage,] satisfies Parameters<typeof createHighlighterCore>[0]["langs"]; let nativeHighlighterPromise: Promise<NativeReviewDiffHighlighterHandle> | null = null;let javascriptHighlighterPromise: Promise<NativeReviewDiffHighlighterHandle> | null = null; function waitForNextFrame(): Promise<void> { return new Promise((resolve) => setTimeout(resolve, 0));} function normalizeTokens( tokenLines: ReadonlyArray<ReadonlyArray<{ content: string; color?: string; fontStyle?: number }>>,): ReadonlyArray<ReadonlyArray<NativeReviewDiffToken>> { return tokenLines.map((line) => line.map((token) => ({ content: token.content, color: token.color ?? null, fontStyle: token.fontStyle ?? null, })), );} async function createNativeReviewDiffHighlighter(): Promise<NativeReviewDiffHighlighterHandle> { const nativeEngineModule = await import("react-native-shiki-engine"); if (!nativeEngineModule.isNativeEngineAvailable()) { throw new NativeReviewDiffHighlighterUnavailableError(); } const highlighter = await createHighlighterCore({ langs: NATIVE_REVIEW_DIFF_LANGUAGES, themes: NATIVE_REVIEW_DIFF_SHIKI_THEMES, engine: nativeEngineModule.createNativeEngine(), }); return { engine: "native", tokenize: (code, options) => normalizeTokens(highlighter.codeToTokensBase(code, options)), };} async function createJavascriptReviewDiffHighlighter(): Promise<NativeReviewDiffHighlighterHandle> { const highlighter: HighlighterCore = await createHighlighterCore({ langs: NATIVE_REVIEW_DIFF_LANGUAGES, themes: NATIVE_REVIEW_DIFF_SHIKI_THEMES, engine: createJavaScriptRegexEngine(), }); return { engine: "javascript", tokenize: (code, options) => normalizeTokens(highlighter.codeToTokensBase(code, options)), };} export async function getNativeReviewDiffHighlighter( engine: NativeReviewDiffHighlightEngine = "native",): Promise<NativeReviewDiffHighlighterHandle> { if (engine === "javascript") { try { javascriptHighlighterPromise ??= createJavascriptReviewDiffHighlighter(); return await javascriptHighlighterPromise; } catch (cause) { javascriptHighlighterPromise = null; throw new NativeReviewDiffHighlighterInitializationError({ requestedEngine: engine, attemptedEngine: "javascript", cause, }); } } nativeHighlighterPromise ??= createNativeReviewDiffHighlighter() .catch(async (cause: unknown) => { const nativeError = isNativeReviewDiffHighlighterUnavailableError(cause) ? cause : new NativeReviewDiffHighlighterInitializationError({ requestedEngine: engine, attemptedEngine: "native", cause, }); console.warn("[debug-native-diff] native highlighter unavailable", { error: nativeError, }); try { javascriptHighlighterPromise ??= createJavascriptReviewDiffHighlighter(); return await javascriptHighlighterPromise; } catch (fallbackCause) { javascriptHighlighterPromise = null; throw new NativeReviewDiffHighlighterInitializationError({ requestedEngine: engine, attemptedEngine: "javascript", cause: new AggregateError( [nativeError, fallbackCause], "Native and JavaScript review diff highlighter initialization failed.", { cause: nativeError }, ), }); } }) .catch((error) => { nativeHighlighterPromise = null; throw error; }); return await nativeHighlighterPromise;} function isHighlightableLineRow(row: NativeReviewDiffRow): row is NativeReviewDiffLineRow { return row.kind === "line" && typeof row.fileId === "string" && typeof row.content === "string";} function hasConsecutiveLineNumbers( previous: number | null | undefined, next: number | null | undefined,): boolean { return typeof previous === "number" && typeof next === "number" && next === previous + 1;} function hasOnlyCommentRowsBetween( rows: ReadonlyArray<NativeReviewDiffRow>, previousRowIndex: number, nextRowIndex: number,): boolean { for (let rowIndex = previousRowIndex + 1; rowIndex < nextRowIndex; rowIndex += 1) { if (rows[rowIndex]?.kind !== "comment") { return false; } } return true;} function canShareGrammarContext( previous: IndexedNativeReviewDiffLineRow, next: IndexedNativeReviewDiffLineRow, rows: ReadonlyArray<NativeReviewDiffRow>,): boolean { if ( next.row.fileId !== previous.row.fileId || !hasOnlyCommentRowsBetween(rows, previous.rowIndex, next.rowIndex) ) { return false; } if (previous.row.change === "delete" || next.row.change === "delete") { return ( previous.row.change !== "add" && next.row.change !== "add" && hasConsecutiveLineNumbers(previous.row.oldLineNumber, next.row.oldLineNumber) ); } if (previous.row.change === "add" || next.row.change === "add") { return hasConsecutiveLineNumbers(previous.row.newLineNumber, next.row.newLineNumber); } return ( previous.row.change === "context" && next.row.change === "context" && hasConsecutiveLineNumbers(previous.row.oldLineNumber, next.row.oldLineNumber) && hasConsecutiveLineNumbers(previous.row.newLineNumber, next.row.newLineNumber) );} function groupLineRowsByFileId(rows: ReadonlyArray<NativeReviewDiffRow>) { const rowsByFileId = new Map<string, NativeReviewDiffLineRow[]>(); for (const row of rows) { if (!isHighlightableLineRow(row)) { continue; } const fileRows = rowsByFileId.get(row.fileId) ?? []; fileRows.push(row); rowsByFileId.set(row.fileId, fileRows); } return rowsByFileId;} function createFileMap(files: ReadonlyArray<NativeReviewDiffFile>) { return new Map(files.map((file) => [file.id, file]));} function clampRowIndex(index: number, rows: ReadonlyArray<NativeReviewDiffRow>) { if (rows.length === 0) { return 0; } return Math.min(rows.length - 1, Math.max(0, Math.floor(index)));} function makePlainTokenFallback( row: NativeReviewDiffLineRow,): ReadonlyArray<NativeReviewDiffToken> { return [{ content: row.content || " ", color: null, fontStyle: null }];} export async function highlightNativeReviewDiffVisibleRows( input: HighlightNativeReviewDiffVisibleRowsInput,): Promise<{ readonly engine: NativeReviewDiffHighlightEngine; readonly tokensByRowId: Record<string, ReadonlyArray<NativeReviewDiffToken>>; readonly rowCount: number; readonly durationMs: number;}> { const highlighter = await getNativeReviewDiffHighlighter(input.engine ?? "native"); if (input.signal?.aborted) { return { engine: highlighter.engine, tokensByRowId: {}, rowCount: 0, durationMs: 0 }; } const startedAt = performance.now(); const theme = NATIVE_REVIEW_DIFF_THEME_NAME_BY_SCHEME[input.scheme]; const fileMap = createFileMap(input.files); const overscanRows = input.overscanRows ?? NATIVE_REVIEW_DIFF_VISIBLE_OVERSCAN_ROWS; const maxRows = input.maxRows ?? NATIVE_REVIEW_DIFF_VISIBLE_MAX_ROWS; const startIndex = clampRowIndex(input.firstRowIndex - overscanRows, input.rows); const endIndex = clampRowIndex(input.lastRowIndex + overscanRows, input.rows); const selectedRows: IndexedNativeReviewDiffLineRow[] = []; for ( let rowIndex = startIndex; rowIndex <= endIndex && selectedRows.length < maxRows; rowIndex += 1 ) { const row = input.rows[rowIndex]; if ( row && isHighlightableLineRow(row) && !input.alreadyHighlightedRowIds?.has(row.id) && fileMap.has(row.fileId) ) { selectedRows.push({ row, rowIndex }); } } const tokensByRowId: Record<string, ReadonlyArray<NativeReviewDiffToken>> = {}; let segmentRows: IndexedNativeReviewDiffLineRow[] = []; let segmentFile: NativeReviewDiffFile | undefined; const flushSegment = () => { if (!segmentFile || segmentRows.length === 0 || input.signal?.aborted) { segmentRows = []; segmentFile = undefined; return; } const code = segmentRows.map(({ row }) => row.content).join("\n"); const tokenLines = highlighter.tokenize(code, { lang: segmentFile.language, theme }); segmentRows.forEach(({ row }, rowIndex) => { tokensByRowId[row.id] = tokenLines[rowIndex] ?? makePlainTokenFallback(row); }); segmentRows = []; segmentFile = undefined; }; for (const selectedRow of selectedRows) { const { row } = selectedRow; const file = fileMap.get(row.fileId); if (!file) { continue; } const previousRow = segmentRows.at(-1); if ( segmentFile && (segmentFile.id !== file.id || (previousRow !== undefined && !canShareGrammarContext(previousRow, selectedRow, input.rows))) ) { flushSegment(); } segmentFile = file; segmentRows.push(selectedRow); } flushSegment(); return { engine: highlighter.engine, tokensByRowId, rowCount: selectedRows.length, durationMs: Math.round(performance.now() - startedAt), };} export async function streamNativeReviewDiffTokens( input: StreamNativeReviewDiffTokenInput,): Promise<NativeReviewDiffHighlightEngine> { const highlighter = await getNativeReviewDiffHighlighter(input.engine ?? "native"); const rowsByFileId = groupLineRowsByFileId(input.rows); const theme = NATIVE_REVIEW_DIFF_THEME_NAME_BY_SCHEME[input.scheme]; const chunkSize = input.chunkSize ?? NATIVE_REVIEW_DIFF_HIGHLIGHT_CHUNK_SIZE; let chunkIndex = 0; for (const file of input.files) { const fileRows = rowsByFileId.get(file.id) ?? []; for (let startIndex = 0; startIndex < fileRows.length; startIndex += chunkSize) { if (input.signal?.aborted) {Lines 1–500 of 530. Load more
import { createHighlighterCore, type HighlighterCore } from "@shikijs/core"; import { createJavaScriptRegexEngine } from "@shikijs/engine-javascript"; import bashLanguage from "@shikijs/langs/bash"; import diffLanguage from "@shikijs/langs/diff"; import javascriptLanguage from "@shikijs/langs/javascript"; import jsonLanguage from "@shikijs/langs/json"; import jsxLanguage from "@shikijs/langs/jsx"; import tsxLanguage from "@shikijs/langs/tsx"; import typescriptLanguage from "@shikijs/langs/typescript"; import yamlLanguage from "@shikijs/langs/yaml"; import * as Schema from "effect/Schema"; import type { NativeReviewDiffFile, NativeReviewDiffLanguage } from "./nativeReviewDiffTypes"; import type { NativeReviewDiffRow, NativeReviewDiffToken } from "./nativeReviewDiffSurface"; export type NativeReviewDiffHighlightScheme = "light" | "dark"; export type NativeReviewDiffHighlightEngine = "native" | "javascript"; export class NativeReviewDiffHighlighterUnavailableError extends Schema.TaggedErrorClass<NativeReviewDiffHighlighterUnavailableError>()( "NativeReviewDiffHighlighterUnavailableError", {}, ) { override get message(): string { return "The native review diff highlighter is unavailable in this build."; } } export const isNativeReviewDiffHighlighterUnavailableError = Schema.is( NativeReviewDiffHighlighterUnavailableError, ); export class NativeReviewDiffHighlighterInitializationError extends Schema.TaggedErrorClass<NativeReviewDiffHighlighterInitializationError>()( "NativeReviewDiffHighlighterInitializationError", { requestedEngine: Schema.Literals(["native", "javascript"]), attemptedEngine: Schema.Literals(["native", "javascript"]), cause: Schema.Defect(), }, ) { override get message(): string { return `Failed to initialize the ${this.attemptedEngine} review diff highlighter requested as ${this.requestedEngine}.`; } } export interface NativeReviewDiffHighlighterHandle { readonly engine: NativeReviewDiffHighlightEngine; readonly tokenize: ( code: string, options: { readonly lang: NativeReviewDiffLanguage; readonly theme: string }, ) => ReadonlyArray<ReadonlyArray<NativeReviewDiffToken>>; } interface NativeReviewDiffLineRow extends NativeReviewDiffRow { readonly kind: "line"; readonly fileId: string; readonly content: string; } interface IndexedNativeReviewDiffLineRow { readonly row: NativeReviewDiffLineRow; readonly rowIndex: number; } export interface NativeReviewDiffTokenChunk { readonly chunkIndex: number; readonly fileId: string; readonly filePath: string; readonly language: NativeReviewDiffLanguage; readonly lineCount: number; readonly durationMs: number; readonly tokensByRowId: Record<string, ReadonlyArray<NativeReviewDiffToken>>; } export interface StreamNativeReviewDiffTokenInput { readonly rows: ReadonlyArray<NativeReviewDiffRow>; readonly files: ReadonlyArray<NativeReviewDiffFile>; readonly scheme: NativeReviewDiffHighlightScheme; readonly engine?: NativeReviewDiffHighlightEngine; readonly chunkSize?: number; readonly signal?: AbortSignal; readonly onChunk: (chunk: NativeReviewDiffTokenChunk) => void; } export interface HighlightNativeReviewDiffVisibleRowsInput { readonly rows: ReadonlyArray<NativeReviewDiffRow>; readonly files: ReadonlyArray<NativeReviewDiffFile>; readonly scheme: NativeReviewDiffHighlightScheme; readonly engine?: NativeReviewDiffHighlightEngine; readonly firstRowIndex: number; readonly lastRowIndex: number; readonly overscanRows?: number; readonly maxRows?: number; readonly alreadyHighlightedRowIds?: ReadonlySet<string>; readonly signal?: AbortSignal; } const NATIVE_REVIEW_DIFF_HIGHLIGHT_CHUNK_SIZE = 500; const NATIVE_REVIEW_DIFF_VISIBLE_OVERSCAN_ROWS = 160; const NATIVE_REVIEW_DIFF_VISIBLE_MAX_ROWS = 360; const NATIVE_REVIEW_DIFF_THEME_NAME_BY_SCHEME = { dark: "t3-pierre-dark", light: "t3-pierre-light", } as const; const PIERRE_LIGHT_SHIKI_THEME = { name: NATIVE_REVIEW_DIFF_THEME_NAME_BY_SCHEME.light, type: "light" as const, fg: "#070707", bg: "#ffffff", settings: [ { settings: { foreground: "#070707", background: "#ffffff" } }, { scope: "comment, punctuation.definition.comment", settings: { foreground: "#84848A" } }, { scope: "keyword, storage, storage.type, keyword.operator.expression", settings: { foreground: "#FC2B73" }, }, { scope: "entity.name.function, support.function, meta.function-call", settings: { foreground: "#7B43F8" }, }, { scope: "entity.name.type, support.type, support.class", settings: { foreground: "#C635E4" }, }, { scope: "string, constant.character, punctuation.definition.string", settings: { foreground: "#199F43" }, }, { scope: "constant.numeric, constant.language, constant.other", settings: { foreground: "#1CA1C7" }, }, { scope: "variable.parameter, variable.other.readwrite, meta.object-literal.key", settings: { foreground: "#D47628" }, }, { scope: "entity.name.tag, support.class.component", settings: { foreground: "#199F43" }, }, { scope: "punctuation, meta.brace, meta.delimiter", settings: { foreground: "#79797F" }, }, { scope: "invalid", settings: { foreground: "#D52C36" } }, ], }; const PIERRE_DARK_SHIKI_THEME = { name: NATIVE_REVIEW_DIFF_THEME_NAME_BY_SCHEME.dark, type: "dark" as const, fg: "#adadb1", bg: "#0a0a0a", settings: [ { settings: { foreground: "#adadb1", background: "#0a0a0a" } }, { scope: "comment, punctuation.definition.comment", settings: { foreground: "#84848A" } }, { scope: "keyword, storage, storage.type, keyword.operator.expression", settings: { foreground: "#FF678D" }, }, { scope: "entity.name.function, support.function, meta.function-call", settings: { foreground: "#9D6AFB" }, }, { scope: "entity.name.type, support.type, support.class", settings: { foreground: "#D568EA" }, }, { scope: "string, constant.character, punctuation.definition.string", settings: { foreground: "#5ECC71" }, }, { scope: "constant.numeric, constant.language, constant.other", settings: { foreground: "#68CDF2" }, }, { scope: "variable.parameter, variable.other.readwrite, meta.object-literal.key", settings: { foreground: "#FFA359" }, }, { scope: "entity.name.tag, support.class.component", settings: { foreground: "#5ECC71" }, }, { scope: "punctuation, meta.brace, meta.delimiter", settings: { foreground: "#79797F" }, }, { scope: "invalid", settings: { foreground: "#FF6762" } }, ], }; const NATIVE_REVIEW_DIFF_SHIKI_THEMES = [ PIERRE_LIGHT_SHIKI_THEME, PIERRE_DARK_SHIKI_THEME, ] satisfies Parameters<typeof createHighlighterCore>[0]["themes"]; const NATIVE_REVIEW_DIFF_LANGUAGES = [ bashLanguage, diffLanguage, javascriptLanguage, jsonLanguage, jsxLanguage, tsxLanguage, typescriptLanguage, yamlLanguage, ] satisfies Parameters<typeof createHighlighterCore>[0]["langs"]; let nativeHighlighterPromise: Promise<NativeReviewDiffHighlighterHandle> | null = null; let javascriptHighlighterPromise: Promise<NativeReviewDiffHighlighterHandle> | null = null; function waitForNextFrame(): Promise<void> { return new Promise((resolve) => setTimeout(resolve, 0)); } function normalizeTokens( tokenLines: ReadonlyArray<ReadonlyArray<{ content: string; color?: string; fontStyle?: number }>>, ): ReadonlyArray<ReadonlyArray<NativeReviewDiffToken>> { return tokenLines.map((line) => line.map((token) => ({ content: token.content, color: token.color ?? null, fontStyle: token.fontStyle ?? null, })), ); } async function createNativeReviewDiffHighlighter(): Promise<NativeReviewDiffHighlighterHandle> { const nativeEngineModule = await import("react-native-shiki-engine"); if (!nativeEngineModule.isNativeEngineAvailable()) { throw new NativeReviewDiffHighlighterUnavailableError(); } const highlighter = await createHighlighterCore({ langs: NATIVE_REVIEW_DIFF_LANGUAGES, themes: NATIVE_REVIEW_DIFF_SHIKI_THEMES, engine: nativeEngineModule.createNativeEngine(), }); return { engine: "native", tokenize: (code, options) => normalizeTokens(highlighter.codeToTokensBase(code, options)), }; } async function createJavascriptReviewDiffHighlighter(): Promise<NativeReviewDiffHighlighterHandle> { const highlighter: HighlighterCore = await createHighlighterCore({ langs: NATIVE_REVIEW_DIFF_LANGUAGES, themes: NATIVE_REVIEW_DIFF_SHIKI_THEMES, engine: createJavaScriptRegexEngine(), }); return { engine: "javascript", tokenize: (code, options) => normalizeTokens(highlighter.codeToTokensBase(code, options)), }; } export async function getNativeReviewDiffHighlighter( engine: NativeReviewDiffHighlightEngine = "native", ): Promise<NativeReviewDiffHighlighterHandle> { if (engine === "javascript") { try { javascriptHighlighterPromise ??= createJavascriptReviewDiffHighlighter(); return await javascriptHighlighterPromise; } catch (cause) { javascriptHighlighterPromise = null; throw new NativeReviewDiffHighlighterInitializationError({ requestedEngine: engine, attemptedEngine: "javascript", cause, }); } } nativeHighlighterPromise ??= createNativeReviewDiffHighlighter() .catch(async (cause: unknown) => { const nativeError = isNativeReviewDiffHighlighterUnavailableError(cause) ? cause : new NativeReviewDiffHighlighterInitializationError({ requestedEngine: engine, attemptedEngine: "native", cause, }); console.warn("[debug-native-diff] native highlighter unavailable", { error: nativeError, }); try { javascriptHighlighterPromise ??= createJavascriptReviewDiffHighlighter(); return await javascriptHighlighterPromise; } catch (fallbackCause) { javascriptHighlighterPromise = null; throw new NativeReviewDiffHighlighterInitializationError({ requestedEngine: engine, attemptedEngine: "javascript", cause: new AggregateError( [nativeError, fallbackCause], "Native and JavaScript review diff highlighter initialization failed.", { cause: nativeError }, ), }); } }) .catch((error) => { nativeHighlighterPromise = null; throw error; }); return await nativeHighlighterPromise; } function isHighlightableLineRow(row: NativeReviewDiffRow): row is NativeReviewDiffLineRow { return row.kind === "line" && typeof row.fileId === "string" && typeof row.content === "string"; } function hasConsecutiveLineNumbers( previous: number | null | undefined, next: number | null | undefined, ): boolean { return typeof previous === "number" && typeof next === "number" && next === previous + 1; } function hasOnlyCommentRowsBetween( rows: ReadonlyArray<NativeReviewDiffRow>, previousRowIndex: number, nextRowIndex: number, ): boolean { for (let rowIndex = previousRowIndex + 1; rowIndex < nextRowIndex; rowIndex += 1) { if (rows[rowIndex]?.kind !== "comment") { return false; } } return true; } function canShareGrammarContext( previous: IndexedNativeReviewDiffLineRow, next: IndexedNativeReviewDiffLineRow, rows: ReadonlyArray<NativeReviewDiffRow>, ): boolean { if ( next.row.fileId !== previous.row.fileId || !hasOnlyCommentRowsBetween(rows, previous.rowIndex, next.rowIndex) ) { return false; } if (previous.row.change === "delete" || next.row.change === "delete") { return ( previous.row.change !== "add" && next.row.change !== "add" && hasConsecutiveLineNumbers(previous.row.oldLineNumber, next.row.oldLineNumber) ); } if (previous.row.change === "add" || next.row.change === "add") { return hasConsecutiveLineNumbers(previous.row.newLineNumber, next.row.newLineNumber); } return ( previous.row.change === "context" && next.row.change === "context" && hasConsecutiveLineNumbers(previous.row.oldLineNumber, next.row.oldLineNumber) && hasConsecutiveLineNumbers(previous.row.newLineNumber, next.row.newLineNumber) ); } function groupLineRowsByFileId(rows: ReadonlyArray<NativeReviewDiffRow>) { const rowsByFileId = new Map<string, NativeReviewDiffLineRow[]>(); for (const row of rows) { if (!isHighlightableLineRow(row)) { continue; } const fileRows = rowsByFileId.get(row.fileId) ?? []; fileRows.push(row); rowsByFileId.set(row.fileId, fileRows); } return rowsByFileId; } function createFileMap(files: ReadonlyArray<NativeReviewDiffFile>) { return new Map(files.map((file) => [file.id, file])); } function clampRowIndex(index: number, rows: ReadonlyArray<NativeReviewDiffRow>) { if (rows.length === 0) { return 0; } return Math.min(rows.length - 1, Math.max(0, Math.floor(index))); } function makePlainTokenFallback( row: NativeReviewDiffLineRow, ): ReadonlyArray<NativeReviewDiffToken> { return [{ content: row.content || " ", color: null, fontStyle: null }]; } export async function highlightNativeReviewDiffVisibleRows( input: HighlightNativeReviewDiffVisibleRowsInput, ): Promise<{ readonly engine: NativeReviewDiffHighlightEngine; readonly tokensByRowId: Record<string, ReadonlyArray<NativeReviewDiffToken>>; readonly rowCount: number; readonly durationMs: number; }> { const highlighter = await getNativeReviewDiffHighlighter(input.engine ?? "native"); if (input.signal?.aborted) { return { engine: highlighter.engine, tokensByRowId: {}, rowCount: 0, durationMs: 0 }; } const startedAt = performance.now(); const theme = NATIVE_REVIEW_DIFF_THEME_NAME_BY_SCHEME[input.scheme]; const fileMap = createFileMap(input.files); const overscanRows = input.overscanRows ?? NATIVE_REVIEW_DIFF_VISIBLE_OVERSCAN_ROWS; const maxRows = input.maxRows ?? NATIVE_REVIEW_DIFF_VISIBLE_MAX_ROWS; const startIndex = clampRowIndex(input.firstRowIndex - overscanRows, input.rows); const endIndex = clampRowIndex(input.lastRowIndex + overscanRows, input.rows); const selectedRows: IndexedNativeReviewDiffLineRow[] = []; for ( let rowIndex = startIndex; rowIndex <= endIndex && selectedRows.length < maxRows; rowIndex += 1 ) { const row = input.rows[rowIndex]; if ( row && isHighlightableLineRow(row) && !input.alreadyHighlightedRowIds?.has(row.id) && fileMap.has(row.fileId) ) { selectedRows.push({ row, rowIndex }); } } const tokensByRowId: Record<string, ReadonlyArray<NativeReviewDiffToken>> = {}; let segmentRows: IndexedNativeReviewDiffLineRow[] = []; let segmentFile: NativeReviewDiffFile | undefined; const flushSegment = () => { if (!segmentFile || segmentRows.length === 0 || input.signal?.aborted) { segmentRows = []; segmentFile = undefined; return; } const code = segmentRows.map(({ row }) => row.content).join("\n"); const tokenLines = highlighter.tokenize(code, { lang: segmentFile.language, theme }); segmentRows.forEach(({ row }, rowIndex) => { tokensByRowId[row.id] = tokenLines[rowIndex] ?? makePlainTokenFallback(row); }); segmentRows = []; segmentFile = undefined; }; for (const selectedRow of selectedRows) { const { row } = selectedRow; const file = fileMap.get(row.fileId); if (!file) { continue; } const previousRow = segmentRows.at(-1); if ( segmentFile && (segmentFile.id !== file.id || (previousRow !== undefined && !canShareGrammarContext(previousRow, selectedRow, input.rows))) ) { flushSegment(); } segmentFile = file; segmentRows.push(selectedRow); } flushSegment(); return { engine: highlighter.engine, tokensByRowId, rowCount: selectedRows.length, durationMs: Math.round(performance.now() - startedAt), }; } export async function streamNativeReviewDiffTokens( input: StreamNativeReviewDiffTokenInput, ): Promise<NativeReviewDiffHighlightEngine> { const highlighter = await getNativeReviewDiffHighlighter(input.engine ?? "native"); const rowsByFileId = groupLineRowsByFileId(input.rows); const theme = NATIVE_REVIEW_DIFF_THEME_NAME_BY_SCHEME[input.scheme]; const chunkSize = input.chunkSize ?? NATIVE_REVIEW_DIFF_HIGHLIGHT_CHUNK_SIZE; let chunkIndex = 0; for (const file of input.files) { const fileRows = rowsByFileId.get(file.id) ?? []; for (let startIndex = 0; startIndex < fileRows.length; startIndex += chunkSize) { if (input.signal?.aborted) {