@pierre/diffs 1.1.7 → 1.1.8
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.
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/FileDiff.js +2 -2
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +1 -1
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/components/VirtulizerDevelopment.d.ts.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/types.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +7 -9
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/ssr/index.d.ts +2 -2
- package/dist/ssr/preloadDiffs.js +1 -1
- package/dist/ssr/preloadDiffs.js.map +1 -1
- package/dist/types.d.ts +9 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/areDiffRenderOptionsEqual.d.ts +7 -0
- package/dist/utils/areDiffRenderOptionsEqual.d.ts.map +1 -0
- package/dist/utils/areDiffRenderOptionsEqual.js +10 -0
- package/dist/utils/areDiffRenderOptionsEqual.js.map +1 -0
- package/dist/utils/areOptionsEqual.d.ts +2 -1
- package/dist/utils/areOptionsEqual.d.ts.map +1 -1
- package/dist/utils/areOptionsEqual.js +8 -1
- package/dist/utils/areOptionsEqual.js.map +1 -1
- package/dist/utils/parseDiffFromFile.js +1 -0
- package/dist/utils/parseDiffFromFile.js.map +1 -1
- package/dist/utils/renderDiffWithHighlighter.js +5 -2
- package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
- package/dist/worker/WorkerPoolManager.d.ts +2 -0
- package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
- package/dist/worker/WorkerPoolManager.js +7 -5
- package/dist/worker/WorkerPoolManager.js.map +1 -1
- package/dist/worker/types.d.ts +1 -0
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/worker-portable.js +9 -3
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +7 -3
- package/dist/worker/worker.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"areDiffRenderOptionsEqual.d.ts","names":["RenderDiffOptions","areDiffRenderOptionsEqual"],"sources":["../../src/utils/areDiffRenderOptionsEqual.d.ts"],"sourcesContent":["import type { RenderDiffOptions } from '../types';\nexport declare function areDiffRenderOptionsEqual(optionsA: RenderDiffOptions, optionsB: RenderDiffOptions): boolean;\n//# sourceMappingURL=areDiffRenderOptionsEqual.d.ts.map"],"mappings":";;;iBACwBC,yBAAAA,WAAoCD,6BAA6BA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { areThemesEqual } from "./areThemesEqual.js";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/areDiffRenderOptionsEqual.ts
|
|
4
|
+
function areDiffRenderOptionsEqual(optionsA, optionsB) {
|
|
5
|
+
return areThemesEqual(optionsA.theme, optionsB.theme) && optionsA.tokenizeMaxLineLength === optionsB.tokenizeMaxLineLength && optionsA.lineDiffType === optionsB.lineDiffType && optionsA.maxLineDiffLength === optionsB.maxLineDiffLength;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//#endregion
|
|
9
|
+
export { areDiffRenderOptionsEqual };
|
|
10
|
+
//# sourceMappingURL=areDiffRenderOptionsEqual.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"areDiffRenderOptionsEqual.js","names":[],"sources":["../../src/utils/areDiffRenderOptionsEqual.ts"],"sourcesContent":["import type { RenderDiffOptions } from '../types';\nimport { areThemesEqual } from './areThemesEqual';\n\nexport function areDiffRenderOptionsEqual(\n optionsA: RenderDiffOptions,\n optionsB: RenderDiffOptions\n): boolean {\n return (\n areThemesEqual(optionsA.theme, optionsB.theme) &&\n optionsA.tokenizeMaxLineLength === optionsB.tokenizeMaxLineLength &&\n optionsA.lineDiffType === optionsB.lineDiffType &&\n optionsA.maxLineDiffLength === optionsB.maxLineDiffLength\n );\n}\n"],"mappings":";;;AAGA,SAAgB,0BACd,UACA,UACS;AACT,QACE,eAAe,SAAS,OAAO,SAAS,MAAM,IAC9C,SAAS,0BAA0B,SAAS,yBAC5C,SAAS,iBAAiB,SAAS,gBACnC,SAAS,sBAAsB,SAAS"}
|
|
@@ -3,7 +3,8 @@ import "../react/index.js";
|
|
|
3
3
|
import { FileDiffOptions } from "../components/FileDiff.js";
|
|
4
4
|
|
|
5
5
|
//#region src/utils/areOptionsEqual.d.ts
|
|
6
|
-
|
|
6
|
+
type AnyOptions<L> = FileOptions<L> | FileDiffOptions<L> | undefined;
|
|
7
|
+
declare function areOptionsEqual<LAnnotation>(optionsA: AnyOptions<LAnnotation>, optionsB: AnyOptions<LAnnotation>): boolean;
|
|
7
8
|
//#endregion
|
|
8
9
|
export { areOptionsEqual };
|
|
9
10
|
//# sourceMappingURL=areOptionsEqual.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"areOptionsEqual.d.ts","names":["FileDiffOptions","FileOptions","areOptionsEqual","LAnnotation"],"sources":["../../src/utils/areOptionsEqual.d.ts"],"sourcesContent":["import type { FileDiffOptions } from '../components/FileDiff';\nimport type { FileOptions } from '../react';\
|
|
1
|
+
{"version":3,"file":"areOptionsEqual.d.ts","names":["FileDiffOptions","FileOptions","AnyOptions","L","areOptionsEqual","LAnnotation"],"sources":["../../src/utils/areOptionsEqual.d.ts"],"sourcesContent":["import type { FileDiffOptions } from '../components/FileDiff';\nimport type { FileOptions } from '../react';\ntype AnyOptions<L> = FileOptions<L> | FileDiffOptions<L> | undefined;\nexport declare function areOptionsEqual<LAnnotation>(optionsA: AnyOptions<LAnnotation>, optionsB: AnyOptions<LAnnotation>): boolean;\nexport {};\n//# sourceMappingURL=areOptionsEqual.d.ts.map"],"mappings":";;;;;KAEKE,gBAAgBD,YAAYE,KAAKH,gBAAgBG;iBAC9BC,uCAAuCF,WAAWG,wBAAwBH,WAAWG"}
|
|
@@ -4,7 +4,14 @@ import { areObjectsEqual } from "./areObjectsEqual.js";
|
|
|
4
4
|
|
|
5
5
|
//#region src/utils/areOptionsEqual.ts
|
|
6
6
|
function areOptionsEqual(optionsA, optionsB) {
|
|
7
|
-
|
|
7
|
+
const themeA = optionsA?.theme ?? DEFAULT_THEMES;
|
|
8
|
+
const themeB = optionsB?.theme ?? DEFAULT_THEMES;
|
|
9
|
+
const diffOptsA = getParseDiffOptions(optionsA);
|
|
10
|
+
const diffOptsB = getParseDiffOptions(optionsB);
|
|
11
|
+
return areThemesEqual(themeA, themeB) && areObjectsEqual(optionsA, optionsB, ["theme", "parseDiffOptions"]) && areObjectsEqual(diffOptsA, diffOptsB);
|
|
12
|
+
}
|
|
13
|
+
function getParseDiffOptions(options) {
|
|
14
|
+
if (options != null && "parseDiffOptions" in options) return options.parseDiffOptions;
|
|
8
15
|
}
|
|
9
16
|
|
|
10
17
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"areOptionsEqual.js","names":[],"sources":["../../src/utils/areOptionsEqual.ts"],"sourcesContent":["import type { FileDiffOptions } from '../components/FileDiff';\nimport { DEFAULT_THEMES } from '../constants';\nimport type { FileOptions } from '../react';\nimport { areObjectsEqual } from './areObjectsEqual';\nimport { areThemesEqual } from './areThemesEqual';\n\
|
|
1
|
+
{"version":3,"file":"areOptionsEqual.js","names":[],"sources":["../../src/utils/areOptionsEqual.ts"],"sourcesContent":["import type { CreatePatchOptionsNonabortable } from 'diff';\n\nimport type { FileDiffOptions } from '../components/FileDiff';\nimport { DEFAULT_THEMES } from '../constants';\nimport type { FileOptions } from '../react';\nimport { areObjectsEqual } from './areObjectsEqual';\nimport { areThemesEqual } from './areThemesEqual';\n\ntype AnyOptions<L> = FileOptions<L> | FileDiffOptions<L> | undefined;\n\nexport function areOptionsEqual<LAnnotation>(\n optionsA: AnyOptions<LAnnotation>,\n optionsB: AnyOptions<LAnnotation>\n): boolean {\n const themeA = optionsA?.theme ?? DEFAULT_THEMES;\n const themeB = optionsB?.theme ?? DEFAULT_THEMES;\n const diffOptsA = getParseDiffOptions(optionsA);\n const diffOptsB = getParseDiffOptions(optionsB);\n return (\n areThemesEqual(themeA, themeB) &&\n areObjectsEqual(optionsA, optionsB, [\n 'theme',\n 'parseDiffOptions' as keyof typeof optionsA,\n ]) &&\n areObjectsEqual(diffOptsA, diffOptsB)\n );\n}\n\nfunction getParseDiffOptions<L>(\n options: AnyOptions<L>\n): CreatePatchOptionsNonabortable | undefined {\n if (options != null && 'parseDiffOptions' in options) {\n return options.parseDiffOptions;\n }\n return undefined;\n}\n"],"mappings":";;;;;AAUA,SAAgB,gBACd,UACA,UACS;CACT,MAAM,SAAS,UAAU,SAAS;CAClC,MAAM,SAAS,UAAU,SAAS;CAClC,MAAM,YAAY,oBAAoB,SAAS;CAC/C,MAAM,YAAY,oBAAoB,SAAS;AAC/C,QACE,eAAe,QAAQ,OAAO,IAC9B,gBAAgB,UAAU,UAAU,CAClC,SACA,mBACD,CAAC,IACF,gBAAgB,WAAW,UAAU;;AAIzC,SAAS,oBACP,SAC4C;AAC5C,KAAI,WAAW,QAAQ,sBAAsB,QAC3C,QAAO,QAAQ"}
|
|
@@ -18,6 +18,7 @@ function parseDiffFromFile(oldFile, newFile, options, throwOnError = false) {
|
|
|
18
18
|
throwOnError
|
|
19
19
|
});
|
|
20
20
|
if (fileData == null) throw new Error("parseDiffFrom: FileInvalid diff -- probably need to fix something -- if the files are the same maybe?");
|
|
21
|
+
if (newFile.lang != null) fileData.lang = newFile.lang;
|
|
21
22
|
return fileData;
|
|
22
23
|
}
|
|
23
24
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseDiffFromFile.js","names":[],"sources":["../../src/utils/parseDiffFromFile.ts"],"sourcesContent":["import { type CreatePatchOptionsNonabortable, createTwoFilesPatch } from 'diff';\n\nimport type { FileContents, FileDiffMetadata } from '../types';\nimport { processFile } from './parsePatchFiles';\n\n/**\n * Parses a diff from two file contents objects.\n *\n * If both `oldFile` and `newFile` have a `cacheKey`, the resulting diff will\n * automatically get a combined cache key in the format `oldKey:newKey`.\n */\nexport function parseDiffFromFile(\n // FIXME(amadeus): oldFile/newFile should be optional to simulate new/deleted\n // files\n oldFile: FileContents,\n newFile: FileContents,\n options?: CreatePatchOptionsNonabortable,\n throwOnError = false\n): FileDiffMetadata {\n const patch = createTwoFilesPatch(\n oldFile.name,\n newFile.name,\n oldFile.contents,\n newFile.contents,\n oldFile.header,\n newFile.header,\n options\n );\n\n const fileData = processFile(patch, {\n cacheKey: (() => {\n if (oldFile.cacheKey != null && newFile.cacheKey != null) {\n return `${oldFile.cacheKey}:${newFile.cacheKey}`;\n }\n return undefined;\n })(),\n oldFile,\n newFile,\n throwOnError,\n });\n if (fileData == null) {\n throw new Error(\n 'parseDiffFrom: FileInvalid diff -- probably need to fix something -- if the files are the same maybe?'\n );\n }\n return fileData;\n}\n"],"mappings":";;;;;;;;;;AAWA,SAAgB,kBAGd,SACA,SACA,SACA,eAAe,OACG;CAWlB,MAAM,WAAW,YAVH,oBACZ,QAAQ,MACR,QAAQ,MACR,QAAQ,UACR,QAAQ,UACR,QAAQ,QACR,QAAQ,QACR,QACD,EAEmC;EAClC,iBAAiB;AACf,OAAI,QAAQ,YAAY,QAAQ,QAAQ,YAAY,KAClD,QAAO,GAAG,QAAQ,SAAS,GAAG,QAAQ;MAGtC;EACJ;EACA;EACA;EACD,CAAC;AACF,KAAI,YAAY,KACd,OAAM,IAAI,MACR,wGACD;
|
|
1
|
+
{"version":3,"file":"parseDiffFromFile.js","names":[],"sources":["../../src/utils/parseDiffFromFile.ts"],"sourcesContent":["import { type CreatePatchOptionsNonabortable, createTwoFilesPatch } from 'diff';\n\nimport type { FileContents, FileDiffMetadata } from '../types';\nimport { processFile } from './parsePatchFiles';\n\n/**\n * Parses a diff from two file contents objects.\n *\n * If both `oldFile` and `newFile` have a `cacheKey`, the resulting diff will\n * automatically get a combined cache key in the format `oldKey:newKey`.\n */\nexport function parseDiffFromFile(\n // FIXME(amadeus): oldFile/newFile should be optional to simulate new/deleted\n // files\n oldFile: FileContents,\n newFile: FileContents,\n options?: CreatePatchOptionsNonabortable,\n throwOnError = false\n): FileDiffMetadata {\n const patch = createTwoFilesPatch(\n oldFile.name,\n newFile.name,\n oldFile.contents,\n newFile.contents,\n oldFile.header,\n newFile.header,\n options\n );\n\n const fileData = processFile(patch, {\n cacheKey: (() => {\n if (oldFile.cacheKey != null && newFile.cacheKey != null) {\n return `${oldFile.cacheKey}:${newFile.cacheKey}`;\n }\n return undefined;\n })(),\n oldFile,\n newFile,\n throwOnError,\n });\n if (fileData == null) {\n throw new Error(\n 'parseDiffFrom: FileInvalid diff -- probably need to fix something -- if the files are the same maybe?'\n );\n }\n // If we've been provided an override for language in the newFile, let’s pass\n // it through to FileDiffMetadata.\n if (newFile.lang != null) {\n fileData.lang = newFile.lang;\n }\n return fileData;\n}\n"],"mappings":";;;;;;;;;;AAWA,SAAgB,kBAGd,SACA,SACA,SACA,eAAe,OACG;CAWlB,MAAM,WAAW,YAVH,oBACZ,QAAQ,MACR,QAAQ,MACR,QAAQ,UACR,QAAQ,UACR,QAAQ,QACR,QAAQ,QACR,QACD,EAEmC;EAClC,iBAAiB;AACf,OAAI,QAAQ,YAAY,QAAQ,QAAQ,YAAY,KAClD,QAAO,GAAG,QAAQ,SAAS,GAAG,QAAQ;MAGtC;EACJ;EACA;EACA;EACD,CAAC;AACF,KAAI,YAAY,KACd,OAAM,IAAI,MACR,wGACD;AAIH,KAAI,QAAQ,QAAQ,KAClB,UAAS,OAAO,QAAQ;AAE1B,QAAO"}
|
|
@@ -30,6 +30,7 @@ function renderDiffWithHighlighter(diff, highlighter, options, { forcePlainText,
|
|
|
30
30
|
deletionLines: [],
|
|
31
31
|
additionLines: []
|
|
32
32
|
};
|
|
33
|
+
const { maxLineDiffLength } = options;
|
|
33
34
|
const shouldGroupAll = !forcePlainText && !diff.isPartial;
|
|
34
35
|
const expandedHunksForIteration = forcePlainText ? expandedHunks : void 0;
|
|
35
36
|
const buckets = /* @__PURE__ */ new Map();
|
|
@@ -71,7 +72,8 @@ function renderDiffWithHighlighter(diff, highlighter, options, { forcePlainText,
|
|
|
71
72
|
additionLineIndex: bucket.additionContent.length,
|
|
72
73
|
deletionDecorations: bucket.deletionDecorations,
|
|
73
74
|
additionDecorations: bucket.additionDecorations,
|
|
74
|
-
lineDiffType
|
|
75
|
+
lineDiffType,
|
|
76
|
+
maxLineDiffLength
|
|
75
77
|
});
|
|
76
78
|
if (deletionLine != null) {
|
|
77
79
|
appendContent(diff.deletionLines[deletionLine.lineIndex], deletionLine.lineIndex, bucket.deletionSegments, bucket.deletionContent);
|
|
@@ -130,10 +132,11 @@ function renderDiffWithHighlighter(diff, highlighter, options, { forcePlainText,
|
|
|
130
132
|
baseThemeType
|
|
131
133
|
};
|
|
132
134
|
}
|
|
133
|
-
function computeLineDiffDecorations({ deletionLine, additionLine, deletionLineIndex, additionLineIndex, deletionDecorations, additionDecorations, lineDiffType }) {
|
|
135
|
+
function computeLineDiffDecorations({ deletionLine, additionLine, deletionLineIndex, additionLineIndex, deletionDecorations, additionDecorations, lineDiffType, maxLineDiffLength }) {
|
|
134
136
|
if (deletionLine == null || additionLine == null || lineDiffType === "none") return;
|
|
135
137
|
deletionLine = cleanLastNewline(deletionLine);
|
|
136
138
|
additionLine = cleanLastNewline(additionLine);
|
|
139
|
+
if (deletionLine.length > maxLineDiffLength || additionLine.length > maxLineDiffLength) return;
|
|
137
140
|
const lineDiff = lineDiffType === "char" ? diffChars(deletionLine, additionLine) : diffWordsWithSpace(deletionLine, additionLine);
|
|
138
141
|
const deletionSpans = [];
|
|
139
142
|
const additionSpans = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderDiffWithHighlighter.js","names":["DEFAULT_PLAIN_TEXT_OPTIONS: ForceDiffPlainTextOptions","code: RenderDiffFilesResult","deletionSpans: [0 | 1, string][]","additionSpans: [0 | 1, string][]","hastConfig: CodeToHastOptions<DiffsThemeNames>"],"sources":["../../src/utils/renderDiffWithHighlighter.ts"],"sourcesContent":["import { diffChars, diffWordsWithSpace } from 'diff';\n\nimport {\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n DEFAULT_THEMES,\n} from '../constants';\nimport type {\n CodeToHastOptions,\n DecorationItem,\n DiffsHighlighter,\n DiffsThemeNames,\n FileContents,\n FileDiffMetadata,\n ForceDiffPlainTextOptions,\n LineDiffTypes,\n LineInfo,\n RenderDiffFilesResult,\n RenderDiffOptions,\n SupportedLanguages,\n ThemedDiffResult,\n} from '../types';\nimport { cleanLastNewline } from './cleanLastNewline';\nimport { createTransformerWithState } from './createTransformerWithState';\nimport { formatCSSVariablePrefix } from './formatCSSVariablePrefix';\nimport { getFiletypeFromFileName } from './getFiletypeFromFileName';\nimport { getHighlighterThemeStyles } from './getHighlighterThemeStyles';\nimport { getLineNodes } from './getLineNodes';\nimport { iterateOverDiff } from './iterateOverDiff';\nimport {\n createDiffSpanDecoration,\n pushOrJoinSpan,\n} from './parseDiffDecorations';\n\nconst DEFAULT_PLAIN_TEXT_OPTIONS: ForceDiffPlainTextOptions = {\n forcePlainText: false,\n};\n\nexport function renderDiffWithHighlighter(\n diff: FileDiffMetadata,\n highlighter: DiffsHighlighter,\n options: RenderDiffOptions,\n {\n forcePlainText,\n startingLine,\n totalLines,\n expandedHunks,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n }: ForceDiffPlainTextOptions = DEFAULT_PLAIN_TEXT_OPTIONS\n): ThemedDiffResult {\n if (forcePlainText) {\n startingLine ??= 0;\n totalLines ??= Infinity;\n } else {\n // If we aren't forcing plain text, then we intentionally do not support\n // ranges for highlighting as that could break the syntax highlighting, we\n // we override any values that may have been passed in. Maybe one day we\n // warn about this?\n startingLine = 0;\n totalLines = Infinity;\n }\n const isWindowedHighlight = startingLine > 0 || totalLines < Infinity;\n const baseThemeType =\n typeof options.theme === 'string'\n ? highlighter.getTheme(options.theme).type\n : undefined;\n const themeStyles = getHighlighterThemeStyles({\n theme: options.theme,\n highlighter,\n });\n\n // If we have a large file and we are rendering the WHOLE plain diff ast,\n // then we should remove the lineDiffType to make sure things render quickly.\n // For highlighted ASTs or windowed highlights, we should just inherit the\n // setting\n const lineDiffType =\n forcePlainText &&\n !isWindowedHighlight &&\n (diff.unifiedLineCount > 1000 || diff.splitLineCount > 1000)\n ? 'none'\n : options.lineDiffType;\n\n const code: RenderDiffFilesResult = {\n deletionLines: [],\n additionLines: [],\n };\n\n const shouldGroupAll = !forcePlainText && !diff.isPartial;\n const expandedHunksForIteration = forcePlainText ? expandedHunks : undefined;\n const buckets = new Map<number, RenderBucket>();\n function getBucketForHunk(hunkIndex: number) {\n const index = shouldGroupAll ? 0 : hunkIndex;\n const bucket = buckets.get(index) ?? createBucket();\n buckets.set(index, bucket);\n return bucket;\n }\n\n function appendContent(\n lineContent: string,\n lineIndex: number,\n segments: HighlightSegment[],\n contentWrapper: FakeArrayType\n ) {\n if (isWindowedHighlight) {\n let segment = segments.at(-1);\n if (\n segment == null ||\n segment.targetIndex + segment.count !== lineIndex\n ) {\n segment = {\n targetIndex: lineIndex,\n originalOffset: contentWrapper.length,\n count: 0,\n };\n segments.push(segment);\n }\n segment.count++;\n }\n contentWrapper.push(lineContent);\n }\n\n iterateOverDiff({\n diff,\n diffStyle: 'both',\n startingLine,\n totalLines,\n expandedHunks: isWindowedHighlight ? expandedHunksForIteration : true,\n collapsedContextThreshold,\n callback: ({ hunkIndex, additionLine, deletionLine, type }) => {\n const bucket = getBucketForHunk(hunkIndex);\n const splitLineIndex =\n additionLine != null\n ? additionLine.splitLineIndex\n : deletionLine.splitLineIndex;\n\n if (type === 'change' && additionLine != null && deletionLine != null) {\n computeLineDiffDecorations({\n additionLine: diff.additionLines[additionLine.lineIndex],\n deletionLine: diff.deletionLines[deletionLine.lineIndex],\n deletionLineIndex: bucket.deletionContent.length,\n additionLineIndex: bucket.additionContent.length,\n deletionDecorations: bucket.deletionDecorations,\n additionDecorations: bucket.additionDecorations,\n lineDiffType,\n });\n }\n\n if (deletionLine != null) {\n appendContent(\n diff.deletionLines[deletionLine.lineIndex],\n deletionLine.lineIndex,\n bucket.deletionSegments,\n bucket.deletionContent\n );\n bucket.deletionInfo.push({\n type: type === 'change' ? 'change-deletion' : type,\n lineNumber: deletionLine.lineNumber,\n altLineNumber:\n type === 'change'\n ? undefined\n : (additionLine.lineNumber ?? undefined),\n lineIndex: `${deletionLine.unifiedLineIndex},${splitLineIndex}`,\n });\n }\n\n if (additionLine != null) {\n appendContent(\n diff.additionLines[additionLine.lineIndex],\n additionLine.lineIndex,\n bucket.additionSegments,\n bucket.additionContent\n );\n bucket.additionInfo.push({\n type: type === 'change' ? 'change-addition' : type,\n lineNumber: additionLine.lineNumber,\n altLineNumber:\n type === 'change'\n ? undefined\n : (deletionLine.lineNumber ?? undefined),\n lineIndex: `${additionLine.unifiedLineIndex},${splitLineIndex}`,\n });\n }\n },\n });\n\n for (const bucket of buckets.values()) {\n if (\n bucket.deletionContent.length === 0 &&\n bucket.additionContent.length === 0\n ) {\n continue;\n }\n\n const deletionFile = {\n name: diff.prevName ?? diff.name,\n contents: bucket.deletionContent.value,\n };\n const additionFile = {\n name: diff.name,\n contents: bucket.additionContent.value,\n };\n const { deletionLines, additionLines } = renderTwoFiles({\n deletionFile,\n deletionInfo: bucket.deletionInfo,\n deletionDecorations: bucket.deletionDecorations,\n\n additionFile,\n additionInfo: bucket.additionInfo,\n additionDecorations: bucket.additionDecorations,\n\n highlighter,\n options,\n languageOverride: forcePlainText ? 'text' : diff.lang,\n });\n\n if (shouldGroupAll) {\n code.deletionLines = deletionLines;\n code.additionLines = additionLines;\n continue;\n }\n\n if (bucket.deletionSegments.length > 0) {\n for (const seg of bucket.deletionSegments) {\n for (let i = 0; i < seg.count; i++) {\n code.deletionLines[seg.targetIndex + i] =\n deletionLines[seg.originalOffset + i];\n }\n }\n } else {\n code.deletionLines.push(...deletionLines);\n }\n if (bucket.additionSegments.length > 0) {\n for (const seg of bucket.additionSegments) {\n for (let i = 0; i < seg.count; i++) {\n code.additionLines[seg.targetIndex + i] =\n additionLines[seg.originalOffset + i];\n }\n }\n } else {\n code.additionLines.push(...additionLines);\n }\n }\n\n return { code, themeStyles, baseThemeType };\n}\n\ninterface ProcessLineDiffProps {\n deletionLine: string | undefined;\n additionLine: string | undefined;\n deletionLineIndex: number;\n additionLineIndex: number;\n deletionDecorations: DecorationItem[];\n additionDecorations: DecorationItem[];\n lineDiffType: LineDiffTypes;\n}\n\nfunction computeLineDiffDecorations({\n deletionLine,\n additionLine,\n deletionLineIndex,\n additionLineIndex,\n deletionDecorations,\n additionDecorations,\n lineDiffType,\n}: ProcessLineDiffProps) {\n if (deletionLine == null || additionLine == null || lineDiffType === 'none') {\n return;\n }\n deletionLine = cleanLastNewline(deletionLine);\n additionLine = cleanLastNewline(additionLine);\n // NOTE(amadeus): Because we visually trim trailing newlines when rendering,\n // we also gotta make sure the diff parsing doesn't include the newline\n // character that could be there...\n const lineDiff =\n lineDiffType === 'char'\n ? diffChars(deletionLine, additionLine)\n : diffWordsWithSpace(deletionLine, additionLine);\n const deletionSpans: [0 | 1, string][] = [];\n const additionSpans: [0 | 1, string][] = [];\n const enableJoin = lineDiffType === 'word-alt';\n const lastItem = lineDiff.at(-1);\n for (const item of lineDiff) {\n const isLastItem = item === lastItem;\n if (!item.added && !item.removed) {\n pushOrJoinSpan({\n item,\n arr: deletionSpans,\n enableJoin,\n isNeutral: true,\n isLastItem,\n });\n pushOrJoinSpan({\n item,\n arr: additionSpans,\n enableJoin,\n isNeutral: true,\n isLastItem,\n });\n } else if (item.removed) {\n pushOrJoinSpan({ item, arr: deletionSpans, enableJoin, isLastItem });\n } else {\n pushOrJoinSpan({ item, arr: additionSpans, enableJoin, isLastItem });\n }\n }\n let spanIndex = 0;\n for (const span of deletionSpans) {\n if (span[0] === 1) {\n deletionDecorations.push(\n createDiffSpanDecoration({\n line: deletionLineIndex,\n spanStart: spanIndex,\n spanLength: span[1].length,\n })\n );\n }\n spanIndex += span[1].length;\n }\n spanIndex = 0;\n for (const span of additionSpans) {\n if (span[0] === 1) {\n additionDecorations.push(\n createDiffSpanDecoration({\n line: additionLineIndex,\n spanStart: spanIndex,\n spanLength: span[1].length,\n })\n );\n }\n spanIndex += span[1].length;\n }\n}\n\ninterface HighlightSegment {\n // The where the highlighted region starts\n originalOffset: number;\n // Where to place the highlighted line in RenderDiffFilesResult\n targetIndex: number;\n // Number of highlighted lines\n count: number;\n}\n\ninterface FakeArrayType {\n push(value: string): void;\n value: string;\n length: number;\n}\n\ninterface RenderBucket {\n deletionContent: FakeArrayType;\n additionContent: FakeArrayType;\n deletionInfo: (LineInfo | undefined)[];\n additionInfo: (LineInfo | undefined)[];\n deletionDecorations: DecorationItem[];\n additionDecorations: DecorationItem[];\n deletionSegments: HighlightSegment[];\n additionSegments: HighlightSegment[];\n}\n\nfunction createBucket(): RenderBucket {\n return {\n deletionContent: {\n push(value: string) {\n this.value += value;\n this.length++;\n },\n value: '',\n length: 0,\n },\n additionContent: {\n push(value: string) {\n this.value += value;\n this.length++;\n },\n value: '',\n length: 0,\n },\n deletionInfo: [],\n additionInfo: [],\n deletionDecorations: [],\n additionDecorations: [],\n deletionSegments: [],\n additionSegments: [],\n };\n}\n\ninterface RenderTwoFilesProps {\n deletionFile: FileContents;\n additionFile: FileContents;\n deletionInfo: (LineInfo | undefined)[];\n additionInfo: (LineInfo | undefined)[];\n deletionDecorations: DecorationItem[];\n additionDecorations: DecorationItem[];\n options: RenderDiffOptions;\n highlighter: DiffsHighlighter;\n languageOverride: SupportedLanguages | undefined;\n}\n\nfunction renderTwoFiles({\n deletionFile,\n additionFile,\n deletionInfo,\n additionInfo,\n highlighter,\n deletionDecorations,\n additionDecorations,\n languageOverride,\n options: { theme: themeOrThemes = DEFAULT_THEMES, ...options },\n}: RenderTwoFilesProps): RenderDiffFilesResult {\n const deletionLang =\n languageOverride ?? getFiletypeFromFileName(deletionFile.name);\n const additionLang =\n languageOverride ?? getFiletypeFromFileName(additionFile.name);\n const { state, transformers } = createTransformerWithState();\n const hastConfig: CodeToHastOptions<DiffsThemeNames> = (() => {\n return typeof themeOrThemes === 'string'\n ? {\n ...options,\n // language will be overwritten for each highlight\n lang: 'text',\n theme: themeOrThemes,\n transformers,\n decorations: undefined,\n defaultColor: false,\n cssVariablePrefix: formatCSSVariablePrefix('token'),\n }\n : {\n ...options,\n // language will be overwritten for each highlight\n lang: 'text',\n themes: themeOrThemes,\n transformers,\n decorations: undefined,\n defaultColor: false,\n cssVariablePrefix: formatCSSVariablePrefix('token'),\n };\n })();\n\n const deletionLines = (() => {\n if (deletionFile.contents === '') {\n return [];\n }\n hastConfig.lang = deletionLang;\n state.lineInfo = deletionInfo;\n hastConfig.decorations = deletionDecorations;\n return getLineNodes(\n highlighter.codeToHast(\n cleanLastNewline(deletionFile.contents),\n hastConfig\n )\n );\n })();\n const additionLines = (() => {\n if (additionFile.contents === '') {\n return [];\n }\n hastConfig.lang = additionLang;\n hastConfig.decorations = additionDecorations;\n state.lineInfo = additionInfo;\n return getLineNodes(\n highlighter.codeToHast(\n cleanLastNewline(additionFile.contents),\n hastConfig\n )\n );\n })();\n\n return { deletionLines, additionLines };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"renderDiffWithHighlighter.js","names":["DEFAULT_PLAIN_TEXT_OPTIONS: ForceDiffPlainTextOptions","code: RenderDiffFilesResult","deletionSpans: [0 | 1, string][]","additionSpans: [0 | 1, string][]","hastConfig: CodeToHastOptions<DiffsThemeNames>"],"sources":["../../src/utils/renderDiffWithHighlighter.ts"],"sourcesContent":["import { diffChars, diffWordsWithSpace } from 'diff';\n\nimport {\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n DEFAULT_THEMES,\n} from '../constants';\nimport type {\n CodeToHastOptions,\n DecorationItem,\n DiffsHighlighter,\n DiffsThemeNames,\n FileContents,\n FileDiffMetadata,\n ForceDiffPlainTextOptions,\n LineDiffTypes,\n LineInfo,\n RenderDiffFilesResult,\n RenderDiffOptions,\n SupportedLanguages,\n ThemedDiffResult,\n} from '../types';\nimport { cleanLastNewline } from './cleanLastNewline';\nimport { createTransformerWithState } from './createTransformerWithState';\nimport { formatCSSVariablePrefix } from './formatCSSVariablePrefix';\nimport { getFiletypeFromFileName } from './getFiletypeFromFileName';\nimport { getHighlighterThemeStyles } from './getHighlighterThemeStyles';\nimport { getLineNodes } from './getLineNodes';\nimport { iterateOverDiff } from './iterateOverDiff';\nimport {\n createDiffSpanDecoration,\n pushOrJoinSpan,\n} from './parseDiffDecorations';\n\nconst DEFAULT_PLAIN_TEXT_OPTIONS: ForceDiffPlainTextOptions = {\n forcePlainText: false,\n};\n\nexport function renderDiffWithHighlighter(\n diff: FileDiffMetadata,\n highlighter: DiffsHighlighter,\n options: RenderDiffOptions,\n {\n forcePlainText,\n startingLine,\n totalLines,\n expandedHunks,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n }: ForceDiffPlainTextOptions = DEFAULT_PLAIN_TEXT_OPTIONS\n): ThemedDiffResult {\n if (forcePlainText) {\n startingLine ??= 0;\n totalLines ??= Infinity;\n } else {\n // If we aren't forcing plain text, then we intentionally do not support\n // ranges for highlighting as that could break the syntax highlighting, we\n // we override any values that may have been passed in. Maybe one day we\n // warn about this?\n startingLine = 0;\n totalLines = Infinity;\n }\n const isWindowedHighlight = startingLine > 0 || totalLines < Infinity;\n const baseThemeType =\n typeof options.theme === 'string'\n ? highlighter.getTheme(options.theme).type\n : undefined;\n const themeStyles = getHighlighterThemeStyles({\n theme: options.theme,\n highlighter,\n });\n\n // If we have a large file and we are rendering the WHOLE plain diff ast,\n // then we should remove the lineDiffType to make sure things render quickly.\n // For highlighted ASTs or windowed highlights, we should just inherit the\n // setting\n const lineDiffType =\n forcePlainText &&\n !isWindowedHighlight &&\n (diff.unifiedLineCount > 1000 || diff.splitLineCount > 1000)\n ? 'none'\n : options.lineDiffType;\n\n const code: RenderDiffFilesResult = {\n deletionLines: [],\n additionLines: [],\n };\n\n const { maxLineDiffLength } = options;\n const shouldGroupAll = !forcePlainText && !diff.isPartial;\n const expandedHunksForIteration = forcePlainText ? expandedHunks : undefined;\n const buckets = new Map<number, RenderBucket>();\n function getBucketForHunk(hunkIndex: number) {\n const index = shouldGroupAll ? 0 : hunkIndex;\n const bucket = buckets.get(index) ?? createBucket();\n buckets.set(index, bucket);\n return bucket;\n }\n\n function appendContent(\n lineContent: string,\n lineIndex: number,\n segments: HighlightSegment[],\n contentWrapper: FakeArrayType\n ) {\n if (isWindowedHighlight) {\n let segment = segments.at(-1);\n if (\n segment == null ||\n segment.targetIndex + segment.count !== lineIndex\n ) {\n segment = {\n targetIndex: lineIndex,\n originalOffset: contentWrapper.length,\n count: 0,\n };\n segments.push(segment);\n }\n segment.count++;\n }\n contentWrapper.push(lineContent);\n }\n\n iterateOverDiff({\n diff,\n diffStyle: 'both',\n startingLine,\n totalLines,\n expandedHunks: isWindowedHighlight ? expandedHunksForIteration : true,\n collapsedContextThreshold,\n callback: ({ hunkIndex, additionLine, deletionLine, type }) => {\n const bucket = getBucketForHunk(hunkIndex);\n const splitLineIndex =\n additionLine != null\n ? additionLine.splitLineIndex\n : deletionLine.splitLineIndex;\n\n if (type === 'change' && additionLine != null && deletionLine != null) {\n computeLineDiffDecorations({\n additionLine: diff.additionLines[additionLine.lineIndex],\n deletionLine: diff.deletionLines[deletionLine.lineIndex],\n deletionLineIndex: bucket.deletionContent.length,\n additionLineIndex: bucket.additionContent.length,\n deletionDecorations: bucket.deletionDecorations,\n additionDecorations: bucket.additionDecorations,\n lineDiffType,\n maxLineDiffLength,\n });\n }\n\n if (deletionLine != null) {\n appendContent(\n diff.deletionLines[deletionLine.lineIndex],\n deletionLine.lineIndex,\n bucket.deletionSegments,\n bucket.deletionContent\n );\n bucket.deletionInfo.push({\n type: type === 'change' ? 'change-deletion' : type,\n lineNumber: deletionLine.lineNumber,\n altLineNumber:\n type === 'change'\n ? undefined\n : (additionLine.lineNumber ?? undefined),\n lineIndex: `${deletionLine.unifiedLineIndex},${splitLineIndex}`,\n });\n }\n\n if (additionLine != null) {\n appendContent(\n diff.additionLines[additionLine.lineIndex],\n additionLine.lineIndex,\n bucket.additionSegments,\n bucket.additionContent\n );\n bucket.additionInfo.push({\n type: type === 'change' ? 'change-addition' : type,\n lineNumber: additionLine.lineNumber,\n altLineNumber:\n type === 'change'\n ? undefined\n : (deletionLine.lineNumber ?? undefined),\n lineIndex: `${additionLine.unifiedLineIndex},${splitLineIndex}`,\n });\n }\n },\n });\n\n for (const bucket of buckets.values()) {\n if (\n bucket.deletionContent.length === 0 &&\n bucket.additionContent.length === 0\n ) {\n continue;\n }\n\n const deletionFile = {\n name: diff.prevName ?? diff.name,\n contents: bucket.deletionContent.value,\n };\n const additionFile = {\n name: diff.name,\n contents: bucket.additionContent.value,\n };\n const { deletionLines, additionLines } = renderTwoFiles({\n deletionFile,\n deletionInfo: bucket.deletionInfo,\n deletionDecorations: bucket.deletionDecorations,\n\n additionFile,\n additionInfo: bucket.additionInfo,\n additionDecorations: bucket.additionDecorations,\n\n highlighter,\n options,\n languageOverride: forcePlainText ? 'text' : diff.lang,\n });\n\n if (shouldGroupAll) {\n code.deletionLines = deletionLines;\n code.additionLines = additionLines;\n continue;\n }\n\n if (bucket.deletionSegments.length > 0) {\n for (const seg of bucket.deletionSegments) {\n for (let i = 0; i < seg.count; i++) {\n code.deletionLines[seg.targetIndex + i] =\n deletionLines[seg.originalOffset + i];\n }\n }\n } else {\n code.deletionLines.push(...deletionLines);\n }\n if (bucket.additionSegments.length > 0) {\n for (const seg of bucket.additionSegments) {\n for (let i = 0; i < seg.count; i++) {\n code.additionLines[seg.targetIndex + i] =\n additionLines[seg.originalOffset + i];\n }\n }\n } else {\n code.additionLines.push(...additionLines);\n }\n }\n\n return { code, themeStyles, baseThemeType };\n}\n\ninterface ProcessLineDiffProps {\n deletionLine: string | undefined;\n additionLine: string | undefined;\n deletionLineIndex: number;\n additionLineIndex: number;\n deletionDecorations: DecorationItem[];\n additionDecorations: DecorationItem[];\n lineDiffType: LineDiffTypes;\n maxLineDiffLength: number;\n}\n\nfunction computeLineDiffDecorations({\n deletionLine,\n additionLine,\n deletionLineIndex,\n additionLineIndex,\n deletionDecorations,\n additionDecorations,\n lineDiffType,\n maxLineDiffLength,\n}: ProcessLineDiffProps) {\n if (deletionLine == null || additionLine == null || lineDiffType === 'none') {\n return;\n }\n deletionLine = cleanLastNewline(deletionLine);\n additionLine = cleanLastNewline(additionLine);\n // If we have really long lines, we probably shouldn't compute diffs on them.\n if (\n deletionLine.length > maxLineDiffLength ||\n additionLine.length > maxLineDiffLength\n ) {\n return;\n }\n // NOTE(amadeus): Because we visually trim trailing newlines when rendering,\n // we also gotta make sure the diff parsing doesn't include the newline\n // character that could be there...\n const lineDiff =\n lineDiffType === 'char'\n ? diffChars(deletionLine, additionLine)\n : diffWordsWithSpace(deletionLine, additionLine);\n const deletionSpans: [0 | 1, string][] = [];\n const additionSpans: [0 | 1, string][] = [];\n const enableJoin = lineDiffType === 'word-alt';\n const lastItem = lineDiff.at(-1);\n for (const item of lineDiff) {\n const isLastItem = item === lastItem;\n if (!item.added && !item.removed) {\n pushOrJoinSpan({\n item,\n arr: deletionSpans,\n enableJoin,\n isNeutral: true,\n isLastItem,\n });\n pushOrJoinSpan({\n item,\n arr: additionSpans,\n enableJoin,\n isNeutral: true,\n isLastItem,\n });\n } else if (item.removed) {\n pushOrJoinSpan({ item, arr: deletionSpans, enableJoin, isLastItem });\n } else {\n pushOrJoinSpan({ item, arr: additionSpans, enableJoin, isLastItem });\n }\n }\n let spanIndex = 0;\n for (const span of deletionSpans) {\n if (span[0] === 1) {\n deletionDecorations.push(\n createDiffSpanDecoration({\n line: deletionLineIndex,\n spanStart: spanIndex,\n spanLength: span[1].length,\n })\n );\n }\n spanIndex += span[1].length;\n }\n spanIndex = 0;\n for (const span of additionSpans) {\n if (span[0] === 1) {\n additionDecorations.push(\n createDiffSpanDecoration({\n line: additionLineIndex,\n spanStart: spanIndex,\n spanLength: span[1].length,\n })\n );\n }\n spanIndex += span[1].length;\n }\n}\n\ninterface HighlightSegment {\n // The where the highlighted region starts\n originalOffset: number;\n // Where to place the highlighted line in RenderDiffFilesResult\n targetIndex: number;\n // Number of highlighted lines\n count: number;\n}\n\ninterface FakeArrayType {\n push(value: string): void;\n value: string;\n length: number;\n}\n\ninterface RenderBucket {\n deletionContent: FakeArrayType;\n additionContent: FakeArrayType;\n deletionInfo: (LineInfo | undefined)[];\n additionInfo: (LineInfo | undefined)[];\n deletionDecorations: DecorationItem[];\n additionDecorations: DecorationItem[];\n deletionSegments: HighlightSegment[];\n additionSegments: HighlightSegment[];\n}\n\nfunction createBucket(): RenderBucket {\n return {\n deletionContent: {\n push(value: string) {\n this.value += value;\n this.length++;\n },\n value: '',\n length: 0,\n },\n additionContent: {\n push(value: string) {\n this.value += value;\n this.length++;\n },\n value: '',\n length: 0,\n },\n deletionInfo: [],\n additionInfo: [],\n deletionDecorations: [],\n additionDecorations: [],\n deletionSegments: [],\n additionSegments: [],\n };\n}\n\ninterface RenderTwoFilesProps {\n deletionFile: FileContents;\n additionFile: FileContents;\n deletionInfo: (LineInfo | undefined)[];\n additionInfo: (LineInfo | undefined)[];\n deletionDecorations: DecorationItem[];\n additionDecorations: DecorationItem[];\n options: RenderDiffOptions;\n highlighter: DiffsHighlighter;\n languageOverride: SupportedLanguages | undefined;\n}\n\nfunction renderTwoFiles({\n deletionFile,\n additionFile,\n deletionInfo,\n additionInfo,\n highlighter,\n deletionDecorations,\n additionDecorations,\n languageOverride,\n options: { theme: themeOrThemes = DEFAULT_THEMES, ...options },\n}: RenderTwoFilesProps): RenderDiffFilesResult {\n const deletionLang =\n languageOverride ?? getFiletypeFromFileName(deletionFile.name);\n const additionLang =\n languageOverride ?? getFiletypeFromFileName(additionFile.name);\n const { state, transformers } = createTransformerWithState();\n const hastConfig: CodeToHastOptions<DiffsThemeNames> = (() => {\n return typeof themeOrThemes === 'string'\n ? {\n ...options,\n // language will be overwritten for each highlight\n lang: 'text',\n theme: themeOrThemes,\n transformers,\n decorations: undefined,\n defaultColor: false,\n cssVariablePrefix: formatCSSVariablePrefix('token'),\n }\n : {\n ...options,\n // language will be overwritten for each highlight\n lang: 'text',\n themes: themeOrThemes,\n transformers,\n decorations: undefined,\n defaultColor: false,\n cssVariablePrefix: formatCSSVariablePrefix('token'),\n };\n })();\n\n const deletionLines = (() => {\n if (deletionFile.contents === '') {\n return [];\n }\n hastConfig.lang = deletionLang;\n state.lineInfo = deletionInfo;\n hastConfig.decorations = deletionDecorations;\n return getLineNodes(\n highlighter.codeToHast(\n cleanLastNewline(deletionFile.contents),\n hastConfig\n )\n );\n })();\n const additionLines = (() => {\n if (additionFile.contents === '') {\n return [];\n }\n hastConfig.lang = additionLang;\n hastConfig.decorations = additionDecorations;\n state.lineInfo = additionInfo;\n return getLineNodes(\n highlighter.codeToHast(\n cleanLastNewline(additionFile.contents),\n hastConfig\n )\n );\n })();\n\n return { deletionLines, additionLines };\n}\n"],"mappings":"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"}
|
|
@@ -31,6 +31,7 @@ declare class WorkerPoolManager {
|
|
|
31
31
|
langs,
|
|
32
32
|
theme,
|
|
33
33
|
lineDiffType,
|
|
34
|
+
maxLineDiffLength,
|
|
34
35
|
tokenizeMaxLineLength,
|
|
35
36
|
preferredHighlighter
|
|
36
37
|
}: WorkerInitializationRenderOptions);
|
|
@@ -43,6 +44,7 @@ declare class WorkerPoolManager {
|
|
|
43
44
|
setRenderOptions({
|
|
44
45
|
theme,
|
|
45
46
|
lineDiffType,
|
|
47
|
+
maxLineDiffLength,
|
|
46
48
|
tokenizeMaxLineLength
|
|
47
49
|
}: Partial<WorkerRenderingOptions>): Promise<void>;
|
|
48
50
|
getFileRenderOptions(): RenderFileOptions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkerPoolManager.d.ts","names":["LRUMapPkg","FileContents","FileDiffMetadata","HunkExpansionRegion","RenderDiffOptions","RenderDiffResult","RenderFileOptions","RenderFileResult","SupportedLanguages","ThemedDiffResult","ThemedFileResult","DiffRendererInstance","FileRendererInstance","WorkerInitializationRenderOptions","WorkerPoolOptions","WorkerRenderingOptions","WorkerStats","GetCachesResult","LRUMap","ThemeSubscriber","WorkerPoolManager","langs","theme","lineDiffType","tokenizeMaxLineLength","preferredHighlighter","Partial","Promise","Map"],"sources":["../../src/worker/WorkerPoolManager.d.ts"],"sourcesContent":["import LRUMapPkg from 'lru_map';\nimport type { FileContents, FileDiffMetadata, HunkExpansionRegion, RenderDiffOptions, RenderDiffResult, RenderFileOptions, RenderFileResult, SupportedLanguages, ThemedDiffResult, ThemedFileResult } from '../types';\nimport type { DiffRendererInstance, FileRendererInstance, WorkerInitializationRenderOptions, WorkerPoolOptions, WorkerRenderingOptions, WorkerStats } from './types';\ninterface GetCachesResult {\n fileCache: LRUMapPkg.LRUMap<string, RenderFileResult>;\n diffCache: LRUMapPkg.LRUMap<string, RenderDiffResult>;\n}\ninterface ThemeSubscriber {\n rerender(): void;\n}\nexport declare class WorkerPoolManager {\n private options;\n private highlighter;\n private readonly preferredHighlighter;\n private renderOptions;\n private initialized;\n private workers;\n private taskQueue;\n private pendingTasks;\n private nextRequestId;\n private themeSubscribers;\n private workersFailed;\n private instanceRequestMap;\n private statSubscribers;\n private fileCache;\n private diffCache;\n private _queuedBroadcast;\n constructor(options: WorkerPoolOptions, { langs, theme, lineDiffType, tokenizeMaxLineLength, preferredHighlighter }: WorkerInitializationRenderOptions);\n isWorkingPool(): boolean;\n getFileResultCache(file: FileContents): RenderFileResult | undefined;\n getDiffResultCache(diff: FileDiffMetadata): RenderDiffResult | undefined;\n inspectCaches(): GetCachesResult;\n evictFileFromCache(cacheKey: string): boolean;\n evictDiffFromCache(cacheKey: string): boolean;\n setRenderOptions({ theme, lineDiffType, tokenizeMaxLineLength }: Partial<WorkerRenderingOptions>): Promise<void>;\n getFileRenderOptions(): RenderFileOptions;\n getDiffRenderOptions(): RenderDiffOptions;\n private setRenderOptionsOnWorkers;\n subscribeToThemeChanges(instance: ThemeSubscriber): () => void;\n unsubscribeToThemeChanges(instance: ThemeSubscriber): void;\n subscribeToStatChanges(callback: (stats: WorkerStats) => unknown): () => void;\n private queueBroadcastStateChanges;\n private _broadcastStateChanges;\n cleanUpPendingTasks(instance: FileRendererInstance | DiffRendererInstance): void;\n isInitialized(): boolean;\n initialize(languages?: SupportedLanguages[]): Promise<void>;\n private initializeWorkers;\n private drainQueue;\n highlightFileAST(instance: FileRendererInstance, file: FileContents): void;\n getPlainFileAST(file: FileContents, startingLine: number, totalLines: number, lines?: string[]): ThemedFileResult | undefined;\n highlightDiffAST(instance: DiffRendererInstance, diff: FileDiffMetadata): void;\n getPlainDiffAST(diff: FileDiffMetadata, startingLine: number, totalLines: number, expandedHunks?: Map<number, HunkExpansionRegion> | true, collapsedContextThreshold?: number): ThemedDiffResult | undefined;\n terminate(): void;\n private terminateWorkers;\n getStats(): WorkerStats;\n private submitTask;\n private resolveLanguagesAndExecuteTask;\n private handleWorkerMessage;\n private _queuedDrain;\n private queueDrain;\n private assignWorkerToTask;\n private cleanWorkerAndTask;\n private executeTask;\n private getAvailableWorker;\n private generateRequestId;\n}\nexport {};\n//# sourceMappingURL=WorkerPoolManager.d.ts.map"],"mappings":";;;;;UAGUiB,eAAAA;aACKjB,SAAAA,CAAUkB,eAAeX;EAD9BU,SAAAA,EAEKjB,SAAAA,CAAUkB,MAFA,CAAA,MAAA,EAEeb,gBAFf,CAAA;;UAIfc,eAAAA,CAHeD;EACeb,QAAAA,EAAAA,EAAAA,IAAAA;;AAAT,cAKVe,iBAAAA,CALU;EAErBD,QAAAA,OAAAA;EAGWC,QAAAA,WAAAA;EAiBIN,iBAAAA,oBAAAA;EAAqBO,QAAAA,aAAAA;EAAOC,QAAAA,WAAAA;EAAOC,QAAAA,OAAAA;EAAcC,QAAAA,SAAAA;
|
|
1
|
+
{"version":3,"file":"WorkerPoolManager.d.ts","names":["LRUMapPkg","FileContents","FileDiffMetadata","HunkExpansionRegion","RenderDiffOptions","RenderDiffResult","RenderFileOptions","RenderFileResult","SupportedLanguages","ThemedDiffResult","ThemedFileResult","DiffRendererInstance","FileRendererInstance","WorkerInitializationRenderOptions","WorkerPoolOptions","WorkerRenderingOptions","WorkerStats","GetCachesResult","LRUMap","ThemeSubscriber","WorkerPoolManager","langs","theme","lineDiffType","maxLineDiffLength","tokenizeMaxLineLength","preferredHighlighter","Partial","Promise","Map"],"sources":["../../src/worker/WorkerPoolManager.d.ts"],"sourcesContent":["import LRUMapPkg from 'lru_map';\nimport type { FileContents, FileDiffMetadata, HunkExpansionRegion, RenderDiffOptions, RenderDiffResult, RenderFileOptions, RenderFileResult, SupportedLanguages, ThemedDiffResult, ThemedFileResult } from '../types';\nimport type { DiffRendererInstance, FileRendererInstance, WorkerInitializationRenderOptions, WorkerPoolOptions, WorkerRenderingOptions, WorkerStats } from './types';\ninterface GetCachesResult {\n fileCache: LRUMapPkg.LRUMap<string, RenderFileResult>;\n diffCache: LRUMapPkg.LRUMap<string, RenderDiffResult>;\n}\ninterface ThemeSubscriber {\n rerender(): void;\n}\nexport declare class WorkerPoolManager {\n private options;\n private highlighter;\n private readonly preferredHighlighter;\n private renderOptions;\n private initialized;\n private workers;\n private taskQueue;\n private pendingTasks;\n private nextRequestId;\n private themeSubscribers;\n private workersFailed;\n private instanceRequestMap;\n private statSubscribers;\n private fileCache;\n private diffCache;\n private _queuedBroadcast;\n constructor(options: WorkerPoolOptions, { langs, theme, lineDiffType, maxLineDiffLength, tokenizeMaxLineLength, preferredHighlighter }: WorkerInitializationRenderOptions);\n isWorkingPool(): boolean;\n getFileResultCache(file: FileContents): RenderFileResult | undefined;\n getDiffResultCache(diff: FileDiffMetadata): RenderDiffResult | undefined;\n inspectCaches(): GetCachesResult;\n evictFileFromCache(cacheKey: string): boolean;\n evictDiffFromCache(cacheKey: string): boolean;\n setRenderOptions({ theme, lineDiffType, maxLineDiffLength, tokenizeMaxLineLength }: Partial<WorkerRenderingOptions>): Promise<void>;\n getFileRenderOptions(): RenderFileOptions;\n getDiffRenderOptions(): RenderDiffOptions;\n private setRenderOptionsOnWorkers;\n subscribeToThemeChanges(instance: ThemeSubscriber): () => void;\n unsubscribeToThemeChanges(instance: ThemeSubscriber): void;\n subscribeToStatChanges(callback: (stats: WorkerStats) => unknown): () => void;\n private queueBroadcastStateChanges;\n private _broadcastStateChanges;\n cleanUpPendingTasks(instance: FileRendererInstance | DiffRendererInstance): void;\n isInitialized(): boolean;\n initialize(languages?: SupportedLanguages[]): Promise<void>;\n private initializeWorkers;\n private drainQueue;\n highlightFileAST(instance: FileRendererInstance, file: FileContents): void;\n getPlainFileAST(file: FileContents, startingLine: number, totalLines: number, lines?: string[]): ThemedFileResult | undefined;\n highlightDiffAST(instance: DiffRendererInstance, diff: FileDiffMetadata): void;\n getPlainDiffAST(diff: FileDiffMetadata, startingLine: number, totalLines: number, expandedHunks?: Map<number, HunkExpansionRegion> | true, collapsedContextThreshold?: number): ThemedDiffResult | undefined;\n terminate(): void;\n private terminateWorkers;\n getStats(): WorkerStats;\n private submitTask;\n private resolveLanguagesAndExecuteTask;\n private handleWorkerMessage;\n private _queuedDrain;\n private queueDrain;\n private assignWorkerToTask;\n private cleanWorkerAndTask;\n private executeTask;\n private getAvailableWorker;\n private generateRequestId;\n}\nexport {};\n//# sourceMappingURL=WorkerPoolManager.d.ts.map"],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ import { getFiletypeFromFileName } from "../utils/getFiletypeFromFileName.js";
|
|
|
8
8
|
import { isFilePlainText } from "../utils/isFilePlainText.js";
|
|
9
9
|
import { renderFileWithHighlighter } from "../utils/renderFileWithHighlighter.js";
|
|
10
10
|
import { areFilesEqual } from "../utils/areFilesEqual.js";
|
|
11
|
+
import { areDiffRenderOptionsEqual } from "../utils/areDiffRenderOptionsEqual.js";
|
|
11
12
|
import { isDiffPlainText } from "../utils/isDiffPlainText.js";
|
|
12
13
|
import { renderDiffWithHighlighter } from "../utils/renderDiffWithHighlighter.js";
|
|
13
14
|
import { getResolvedLanguages } from "../highlighter/languages/getResolvedLanguages.js";
|
|
@@ -35,12 +36,13 @@ var WorkerPoolManager = class {
|
|
|
35
36
|
fileCache;
|
|
36
37
|
diffCache;
|
|
37
38
|
_queuedBroadcast;
|
|
38
|
-
constructor(options, { langs, theme = DEFAULT_THEMES, lineDiffType = "word-alt", tokenizeMaxLineLength = 1e3, preferredHighlighter = "shiki-js" }) {
|
|
39
|
+
constructor(options, { langs, theme = DEFAULT_THEMES, lineDiffType = "word-alt", maxLineDiffLength = 1e3, tokenizeMaxLineLength = 1e3, preferredHighlighter = "shiki-js" }) {
|
|
39
40
|
this.options = options;
|
|
40
41
|
this.preferredHighlighter = preferredHighlighter;
|
|
41
42
|
this.renderOptions = {
|
|
42
43
|
theme,
|
|
43
44
|
lineDiffType,
|
|
45
|
+
maxLineDiffLength,
|
|
44
46
|
tokenizeMaxLineLength
|
|
45
47
|
};
|
|
46
48
|
this.fileCache = new LRUMapPkg.LRUMap(options.totalASTLRUCacheSize ?? 100);
|
|
@@ -77,18 +79,18 @@ var WorkerPoolManager = class {
|
|
|
77
79
|
this.queueBroadcastStateChanges();
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
|
-
async setRenderOptions({ theme = DEFAULT_THEMES, lineDiffType = "word-alt", tokenizeMaxLineLength = 1e3 }) {
|
|
82
|
+
async setRenderOptions({ theme = DEFAULT_THEMES, lineDiffType = "word-alt", maxLineDiffLength = 1e3, tokenizeMaxLineLength = 1e3 }) {
|
|
81
83
|
const newRenderOptions = {
|
|
82
84
|
theme,
|
|
83
85
|
lineDiffType,
|
|
86
|
+
maxLineDiffLength,
|
|
84
87
|
tokenizeMaxLineLength
|
|
85
88
|
};
|
|
86
89
|
if (!this.isInitialized()) await this.initialize();
|
|
87
|
-
|
|
88
|
-
if (themesEqual && newRenderOptions.lineDiffType === this.renderOptions.lineDiffType && newRenderOptions.tokenizeMaxLineLength === this.renderOptions.tokenizeMaxLineLength) return;
|
|
90
|
+
if (areDiffRenderOptionsEqual(newRenderOptions, this.renderOptions)) return;
|
|
89
91
|
const themeNames = getThemes(theme);
|
|
90
92
|
let resolvedThemes = [];
|
|
91
|
-
if (!
|
|
93
|
+
if (!areThemesEqual(newRenderOptions.theme, this.renderOptions.theme)) if (hasResolvedThemes(themeNames)) resolvedThemes = getResolvedThemes(themeNames);
|
|
92
94
|
else resolvedThemes = await resolveThemes(themeNames);
|
|
93
95
|
if (this.highlighter != null) {
|
|
94
96
|
attachResolvedThemes(resolvedThemes, this.highlighter);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkerPoolManager.js","names":["options: WorkerPoolOptions","newRenderOptions: WorkerRenderingOptions","resolvedThemes: ThemeRegistrationResolved[]","taskPromises: Promise<void>[]","task: SetRenderOptionsWorkerTask","resolvedLanguages: ResolvedLanguage[]","initPromises: Promise<unknown>[]","managedWorker: ManagedWorker","task: InitializeWorkerTask","task: RenderFileTask | RenderDiffTask","worker: ManagedWorker | undefined"],"sources":["../../src/worker/WorkerPoolManager.ts"],"sourcesContent":["import LRUMapPkg from 'lru_map';\n\nimport { DEFAULT_THEMES } from '../constants';\nimport { getResolvedLanguages } from '../highlighter/languages/getResolvedLanguages';\nimport { hasResolvedLanguages } from '../highlighter/languages/hasResolvedLanguages';\nimport { resolveLanguages } from '../highlighter/languages/resolveLanguages';\nimport { getSharedHighlighter } from '../highlighter/shared_highlighter';\nimport { attachResolvedThemes } from '../highlighter/themes/attachResolvedThemes';\nimport { getResolvedThemes } from '../highlighter/themes/getResolvedThemes';\nimport { hasResolvedThemes } from '../highlighter/themes/hasResolvedThemes';\nimport { resolveThemes } from '../highlighter/themes/resolveThemes';\nimport type {\n DiffsHighlighter,\n FileContents,\n FileDiffMetadata,\n HighlighterTypes,\n HunkExpansionRegion,\n RenderDiffOptions,\n RenderDiffResult,\n RenderFileOptions,\n RenderFileResult,\n SupportedLanguages,\n ThemedDiffResult,\n ThemedFileResult,\n ThemeRegistrationResolved,\n} from '../types';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areThemesEqual } from '../utils/areThemesEqual';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { getThemes } from '../utils/getThemes';\nimport { isDiffPlainText } from '../utils/isDiffPlainText';\nimport { isFilePlainText } from '../utils/isFilePlainText';\nimport { renderDiffWithHighlighter } from '../utils/renderDiffWithHighlighter';\nimport { renderFileWithHighlighter } from '../utils/renderFileWithHighlighter';\nimport type {\n AllWorkerTasks,\n DiffRendererInstance,\n FileRendererInstance,\n InitializeWorkerTask,\n RenderDiffRequest,\n RenderDiffTask,\n RenderFileRequest,\n RenderFileTask,\n ResolvedLanguage,\n SetRenderOptionsWorkerTask,\n SubmitRequest,\n WorkerInitializationRenderOptions,\n WorkerPoolOptions,\n WorkerRenderingOptions,\n WorkerRequestId,\n WorkerResponse,\n WorkerStats,\n} from './types';\n\nconst IGNORE_RESPONSE = Symbol('IGNORE_RESPONSE');\n\ninterface GetCachesResult {\n fileCache: LRUMapPkg.LRUMap<string, RenderFileResult>;\n diffCache: LRUMapPkg.LRUMap<string, RenderDiffResult>;\n}\n\ninterface ManagedWorker {\n worker: Worker;\n request_id: string | undefined;\n initialized: boolean;\n langs: Set<SupportedLanguages>;\n}\n\ninterface ThemeSubscriber {\n rerender(): void;\n}\n\nexport class WorkerPoolManager {\n private highlighter: DiffsHighlighter | undefined;\n private readonly preferredHighlighter: HighlighterTypes;\n private renderOptions: WorkerRenderingOptions;\n private initialized: Promise<void> | boolean = false;\n private workers: ManagedWorker[] = [];\n private taskQueue = new Map<\n FileRendererInstance | DiffRendererInstance,\n RenderDiffTask | RenderFileTask\n >();\n private pendingTasks = new Map<WorkerRequestId, AllWorkerTasks>();\n private nextRequestId = 0;\n private themeSubscribers = new Set<ThemeSubscriber>();\n private workersFailed = false;\n private instanceRequestMap = new Map<\n FileRendererInstance | DiffRendererInstance,\n string\n >();\n private statSubscribers = new Set<(stats: WorkerStats) => unknown>();\n private fileCache: LRUMapPkg.LRUMap<string, RenderFileResult>;\n private diffCache: LRUMapPkg.LRUMap<string, RenderDiffResult>;\n private _queuedBroadcast: number | undefined;\n\n constructor(\n private options: WorkerPoolOptions,\n {\n langs,\n theme = DEFAULT_THEMES,\n lineDiffType = 'word-alt',\n tokenizeMaxLineLength = 1000,\n preferredHighlighter = 'shiki-js',\n }: WorkerInitializationRenderOptions\n ) {\n this.preferredHighlighter = preferredHighlighter;\n this.renderOptions = { theme, lineDiffType, tokenizeMaxLineLength };\n this.fileCache = new LRUMapPkg.LRUMap(options.totalASTLRUCacheSize ?? 100);\n this.diffCache = new LRUMapPkg.LRUMap(options.totalASTLRUCacheSize ?? 100);\n void this.initialize(langs);\n }\n\n isWorkingPool(): boolean {\n return !this.workersFailed;\n }\n\n getFileResultCache(file: FileContents): RenderFileResult | undefined {\n return file.cacheKey != null\n ? this.fileCache.get(file.cacheKey)\n : undefined;\n }\n\n getDiffResultCache(diff: FileDiffMetadata): RenderDiffResult | undefined {\n return diff.cacheKey != null\n ? this.diffCache.get(diff.cacheKey)\n : undefined;\n }\n\n inspectCaches(): GetCachesResult {\n const { fileCache, diffCache } = this;\n return { fileCache, diffCache };\n }\n\n evictFileFromCache(cacheKey: string): boolean {\n try {\n return this.fileCache.delete(cacheKey) !== undefined;\n } finally {\n this.queueBroadcastStateChanges();\n }\n }\n\n evictDiffFromCache(cacheKey: string): boolean {\n try {\n return this.diffCache.delete(cacheKey) !== undefined;\n } finally {\n this.queueBroadcastStateChanges();\n }\n }\n\n async setRenderOptions({\n theme = DEFAULT_THEMES,\n lineDiffType = 'word-alt',\n tokenizeMaxLineLength = 1000,\n }: Partial<WorkerRenderingOptions>): Promise<void> {\n const newRenderOptions: WorkerRenderingOptions = {\n theme,\n lineDiffType,\n tokenizeMaxLineLength,\n };\n if (!this.isInitialized()) {\n await this.initialize();\n }\n const themesEqual = areThemesEqual(\n newRenderOptions.theme,\n this.renderOptions.theme\n );\n if (\n themesEqual &&\n newRenderOptions.lineDiffType === this.renderOptions.lineDiffType &&\n newRenderOptions.tokenizeMaxLineLength ===\n this.renderOptions.tokenizeMaxLineLength\n ) {\n return;\n }\n\n const themeNames = getThemes(theme);\n let resolvedThemes: ThemeRegistrationResolved[] = [];\n if (!themesEqual) {\n if (hasResolvedThemes(themeNames)) {\n resolvedThemes = getResolvedThemes(themeNames);\n } else {\n resolvedThemes = await resolveThemes(themeNames);\n }\n }\n\n if (this.highlighter != null) {\n attachResolvedThemes(resolvedThemes, this.highlighter);\n await this.setRenderOptionsOnWorkers(newRenderOptions, resolvedThemes);\n } else {\n const [highlighter] = await Promise.all([\n getSharedHighlighter({\n themes: themeNames,\n langs: ['text'],\n preferredHighlighter: this.preferredHighlighter,\n }),\n this.setRenderOptionsOnWorkers(newRenderOptions, resolvedThemes),\n ]);\n this.highlighter = highlighter;\n }\n\n this.renderOptions = newRenderOptions;\n this.diffCache.clear();\n this.fileCache.clear();\n\n for (const instance of this.themeSubscribers) {\n instance.rerender();\n }\n }\n\n getFileRenderOptions(): RenderFileOptions {\n const { tokenizeMaxLineLength, theme } = this.renderOptions;\n return { theme, tokenizeMaxLineLength };\n }\n\n getDiffRenderOptions(): RenderDiffOptions {\n return { ...this.renderOptions };\n }\n\n private async setRenderOptionsOnWorkers(\n renderOptions: WorkerRenderingOptions,\n resolvedThemes: ThemeRegistrationResolved[]\n ): Promise<void> {\n if (this.workersFailed) {\n return;\n }\n if (!this.isInitialized()) {\n await this.initialize();\n }\n const taskPromises: Promise<void>[] = [];\n for (const managedWorker of this.workers) {\n if (!managedWorker.initialized) {\n console.log({ managedWorker });\n throw new Error(\n 'setRenderOptionsOnWorkers: Somehow we have an uninitialized worker'\n );\n }\n taskPromises.push(\n new Promise<void>((resolve, reject) => {\n const id = this.generateRequestId();\n const task: SetRenderOptionsWorkerTask = {\n type: 'set-render-options',\n id,\n request: {\n type: 'set-render-options',\n id,\n renderOptions,\n resolvedThemes,\n },\n resolve,\n reject,\n requestStart: Date.now(),\n };\n // NOTE(amadeus): We intentionally ignore the normal pending requests\n // infra because these tasks should technically interrupt the normal\n // flow and should be processed by the worker when ready immediately\n this.pendingTasks.set(id, task);\n managedWorker.worker.postMessage(task.request);\n })\n );\n }\n await Promise.all(taskPromises);\n }\n\n subscribeToThemeChanges(instance: ThemeSubscriber): () => void {\n this.themeSubscribers.add(instance);\n this.queueBroadcastStateChanges();\n return () => {\n this.unsubscribeToThemeChanges(instance);\n this.queueBroadcastStateChanges();\n };\n }\n\n unsubscribeToThemeChanges(instance: ThemeSubscriber): void {\n this.themeSubscribers.delete(instance);\n this.queueBroadcastStateChanges();\n }\n\n subscribeToStatChanges(\n callback: (stats: WorkerStats) => unknown\n ): () => void {\n this.statSubscribers.add(callback);\n callback(this.getStats());\n return () => {\n this.statSubscribers.delete(callback);\n };\n }\n\n private queueBroadcastStateChanges() {\n if (this._queuedBroadcast != null) return;\n this._queuedBroadcast = requestAnimationFrame(this._broadcastStateChanges);\n }\n\n private _broadcastStateChanges = () => {\n if (this._queuedBroadcast != null) {\n cancelAnimationFrame(this._queuedBroadcast);\n this._queuedBroadcast = undefined;\n }\n const stats = this.getStats();\n for (const callback of this.statSubscribers) {\n callback(stats);\n }\n };\n\n cleanUpPendingTasks(\n instance: FileRendererInstance | DiffRendererInstance\n ): void {\n this.taskQueue.delete(instance);\n const requestId = this.instanceRequestMap.get(instance);\n if (requestId != null) {\n this.pendingTasks.delete(requestId);\n this.instanceRequestMap.delete(instance);\n }\n this.queueBroadcastStateChanges();\n }\n\n isInitialized(): boolean {\n return this.initialized === true;\n }\n\n async initialize(languages: SupportedLanguages[] = []): Promise<void> {\n if (this.initialized === true) {\n return;\n } else if (this.initialized === false) {\n this.initialized = new Promise((resolve, reject) => {\n void (async () => {\n try {\n const themes = getThemes(this.renderOptions.theme);\n let resolvedThemes: ThemeRegistrationResolved[] = [];\n if (hasResolvedThemes(themes)) {\n resolvedThemes = getResolvedThemes(themes);\n } else {\n resolvedThemes = await resolveThemes(themes);\n }\n\n let resolvedLanguages: ResolvedLanguage[] = [];\n if (hasResolvedLanguages(languages)) {\n resolvedLanguages = getResolvedLanguages(languages);\n } else {\n resolvedLanguages = await resolveLanguages(languages);\n }\n\n const [highlighter] = await Promise.all([\n getSharedHighlighter({\n themes,\n langs: ['text', ...languages],\n preferredHighlighter: this.preferredHighlighter,\n }),\n this.initializeWorkers(resolvedThemes, resolvedLanguages),\n ]);\n\n // If we were terminated while initializing, we should probably kill\n // any workers that may have been created\n if (this.initialized === false) {\n this.terminateWorkers();\n throw new Error(\n 'WorkerPoolManager: workers failed to initialize'\n );\n }\n this.highlighter = highlighter;\n this.initialized = true;\n this.diffCache.clear();\n this.fileCache.clear();\n this.drainQueue();\n this.queueBroadcastStateChanges();\n resolve();\n } catch (e) {\n this.initialized = false;\n this.workersFailed = true;\n this.queueBroadcastStateChanges();\n reject(e);\n }\n })();\n });\n this.queueBroadcastStateChanges();\n } else {\n return this.initialized;\n }\n }\n\n private async initializeWorkers(\n resolvedThemes: ThemeRegistrationResolved[],\n resolvedLanguages: ResolvedLanguage[]\n ): Promise<void> {\n this.workersFailed = false;\n const initPromises: Promise<unknown>[] = [];\n if (this.workers.length > 0) {\n this.terminateWorkers();\n }\n for (let i = 0; i < (this.options.poolSize ?? 8); i++) {\n const worker = this.options.workerFactory();\n const managedWorker: ManagedWorker = {\n worker,\n request_id: undefined,\n initialized: false,\n langs: new Set(['text', ...resolvedLanguages.map(({ name }) => name)]),\n };\n worker.addEventListener(\n 'message',\n (event: MessageEvent<WorkerResponse>) => {\n this.handleWorkerMessage(managedWorker, event.data);\n }\n );\n worker.addEventListener('error', (error) =>\n console.error('Worker error:', error, managedWorker)\n );\n this.workers.push(managedWorker);\n initPromises.push(\n new Promise<void>((resolve, reject) => {\n const id = this.generateRequestId();\n const task: InitializeWorkerTask = {\n type: 'initialize',\n id,\n request: {\n type: 'initialize',\n id,\n renderOptions: this.renderOptions,\n preferredHighlighter: this.preferredHighlighter,\n resolvedThemes,\n resolvedLanguages,\n },\n resolve() {\n managedWorker.initialized = true;\n resolve();\n },\n reject,\n requestStart: Date.now(),\n };\n this.pendingTasks.set(id, task);\n this.executeTask(managedWorker, task);\n })\n );\n }\n await Promise.all(initPromises);\n }\n\n private drainQueue = () => {\n this._queuedDrain = undefined;\n // If we are initializing or things got cancelled while initializing, we\n // should not attempt to drain the queue\n if (this.initialized !== true || this.taskQueue.size === 0) {\n return;\n }\n for (const [instance, task] of this.taskQueue) {\n // If we have a request in progress for the same instance, we should wait\n // for it to finish\n if (this.instanceRequestMap.has(instance)) {\n continue;\n }\n const langs = getLangsFromTask(task);\n const availableWorker = this.getAvailableWorker(langs);\n if (availableWorker == null) {\n break;\n }\n this.assignWorkerToTask(task, availableWorker);\n void this.resolveLanguagesAndExecuteTask(availableWorker, task, langs);\n }\n this.queueBroadcastStateChanges();\n };\n\n highlightFileAST(instance: FileRendererInstance, file: FileContents): void {\n if (isFilePlainText(file)) {\n return;\n }\n // If we already have a task in progress for this same file content, we\n // should drop it\n for (const tasks of [this.taskQueue, this.pendingTasks.values()]) {\n for (const task of tasks) {\n if (\n 'instance' in task &&\n task.instance === instance &&\n task.request.type === 'file' &&\n areFilesEqual(file, task.request.file)\n ) {\n return;\n }\n }\n }\n this.submitTask(instance, { type: 'file', file });\n }\n\n getPlainFileAST(\n file: FileContents,\n startingLine: number,\n totalLines: number,\n lines?: string[]\n ): ThemedFileResult | undefined {\n if (this.highlighter == null) {\n void this.initialize();\n return undefined;\n }\n return renderFileWithHighlighter(\n file,\n this.highlighter,\n this.renderOptions,\n { forcePlainText: true, startingLine, totalLines, lines }\n );\n }\n\n highlightDiffAST(\n instance: DiffRendererInstance,\n diff: FileDiffMetadata\n ): void {\n if (isDiffPlainText(diff)) {\n return;\n }\n // If we already have a task in progress for this same diff content, we\n // should ignore executing it again\n for (const tasks of [this.taskQueue, this.pendingTasks.values()]) {\n for (const task of tasks) {\n if (\n 'instance' in task &&\n task.instance === instance &&\n task.request.type === 'diff' &&\n task.request.diff === diff\n ) {\n return;\n }\n }\n }\n this.submitTask(instance, { type: 'diff', diff });\n }\n\n getPlainDiffAST(\n diff: FileDiffMetadata,\n startingLine: number,\n totalLines: number,\n expandedHunks?: Map<number, HunkExpansionRegion> | true,\n collapsedContextThreshold?: number\n ): ThemedDiffResult | undefined {\n return this.highlighter != null\n ? renderDiffWithHighlighter(diff, this.highlighter, this.renderOptions, {\n forcePlainText: true,\n startingLine,\n totalLines,\n expandedHunks,\n collapsedContextThreshold,\n })\n : undefined;\n }\n\n terminate(): void {\n this.terminateWorkers();\n this.fileCache.clear();\n this.diffCache.clear();\n this.instanceRequestMap.clear();\n this.taskQueue.clear();\n this.pendingTasks.clear();\n this.highlighter = undefined;\n this.initialized = false;\n this.workersFailed = false;\n this.queueBroadcastStateChanges();\n }\n\n private terminateWorkers() {\n for (const managedWorker of this.workers) {\n managedWorker.worker.terminate();\n }\n this.workers.length = 0;\n }\n\n getStats(): WorkerStats {\n return {\n managerState: (() => {\n if (this.initialized === false) {\n return 'waiting';\n }\n if (this.initialized !== true) {\n return 'initializing';\n }\n return 'initialized';\n })(),\n totalWorkers: this.workers.length,\n workersFailed: this.workersFailed,\n busyWorkers: this.workers.filter((w) => w.request_id != null).length,\n queuedTasks: this.taskQueue.size,\n pendingTasks: this.pendingTasks.size,\n themeSubscribers: this.themeSubscribers.size,\n fileCacheSize: this.fileCache.size,\n diffCacheSize: this.diffCache.size,\n };\n }\n\n private submitTask(\n instance: FileRendererInstance,\n request: Omit<RenderFileRequest, 'id'>\n ): void;\n private submitTask(\n instance: DiffRendererInstance,\n request: Omit<RenderDiffRequest, 'id'>\n ): void;\n private submitTask(\n instance: FileRendererInstance | DiffRendererInstance,\n request: SubmitRequest\n ): void {\n if (this.initialized === false) {\n void this.initialize();\n }\n\n const id = this.generateRequestId();\n const requestStart = Date.now();\n const task: RenderFileTask | RenderDiffTask = (() => {\n switch (request.type) {\n case 'file':\n return {\n type: 'file',\n id,\n request: { ...request, id },\n instance: instance as FileRendererInstance,\n requestStart,\n };\n case 'diff':\n return {\n type: 'diff',\n id,\n request: { ...request, id },\n instance: instance as DiffRendererInstance,\n requestStart,\n };\n }\n })();\n\n this.taskQueue.set(instance, task);\n this.queueDrain();\n }\n\n private async resolveLanguagesAndExecuteTask(\n availableWorker: ManagedWorker,\n task: RenderFileTask | RenderDiffTask,\n langs: SupportedLanguages[]\n ): Promise<void> {\n try {\n // Add resolved languages if required\n const workerMissingLangs = langs.filter(\n (lang) => !availableWorker.langs.has(lang)\n );\n\n if (workerMissingLangs.length > 0) {\n if (hasResolvedLanguages(workerMissingLangs)) {\n task.request.resolvedLanguages =\n getResolvedLanguages(workerMissingLangs);\n } else {\n task.request.resolvedLanguages =\n await resolveLanguages(workerMissingLangs);\n }\n }\n this.executeTask(availableWorker, task);\n } catch {\n this.cleanWorkerAndTask(availableWorker, task);\n }\n }\n\n private handleWorkerMessage(\n managedWorker: ManagedWorker,\n response: WorkerResponse\n ): void {\n const task = this.pendingTasks.get(response.id);\n try {\n if (task == null) {\n // If we can't find a task for this response, it probably means the\n // component has been unmounted, so we should silently ignore it\n throw IGNORE_RESPONSE;\n } else if (response.type === 'error') {\n const error = new Error(response.error);\n if (response.stack) {\n error.stack = response.stack;\n }\n if ('reject' in task) {\n task.reject(error);\n } else {\n task.instance.onHighlightError(error);\n }\n throw error;\n } else {\n // If we've gotten a newer request from the same instance, we should\n // ignore this response either because it's out of order or because we\n // have a newer more important request\n if (\n 'instance' in task &&\n this.instanceRequestMap.get(task.instance) !== response.id\n ) {\n throw IGNORE_RESPONSE;\n }\n switch (response.requestType) {\n case 'initialize':\n if (task.type !== 'initialize') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n task.resolve();\n break;\n case 'set-render-options':\n if (task.type !== 'set-render-options') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n task.resolve();\n break;\n case 'file': {\n if (task.type !== 'file') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n const { result, options } = response;\n const { instance, request } = task;\n if (request.file.cacheKey != null) {\n this.fileCache.set(request.file.cacheKey, { result, options });\n }\n instance.onHighlightSuccess(request.file, result, options);\n break;\n }\n case 'diff': {\n if (task.type !== 'diff') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n const { result, options } = response;\n const { instance, request } = task;\n if (request.diff.cacheKey != null) {\n this.diffCache.set(request.diff.cacheKey, { result, options });\n }\n instance.onHighlightSuccess(request.diff, result, options);\n break;\n }\n }\n }\n } catch (error) {\n if (error !== IGNORE_RESPONSE) {\n console.error(error, task, response);\n }\n }\n\n this.cleanWorkerAndTask(managedWorker, task);\n this.queueBroadcastStateChanges();\n if (this.taskQueue.size > 0) {\n // We queue drain so that potentially multiple workers can free up\n // allowing for better language matches if possible\n this.queueDrain();\n }\n }\n\n private _queuedDrain: Promise<void> | undefined;\n private queueDrain() {\n if (this._queuedDrain != null) return;\n this._queuedDrain = Promise.resolve().then(this.drainQueue);\n this.queueBroadcastStateChanges();\n }\n\n private assignWorkerToTask(\n task: AllWorkerTasks,\n managedWorker: ManagedWorker\n ) {\n managedWorker.request_id = task.id;\n if ('instance' in task) {\n this.taskQueue.delete(task.instance);\n this.instanceRequestMap.set(task.instance, task.id);\n }\n this.pendingTasks.set(task.id, task);\n }\n\n private cleanWorkerAndTask(\n managedWorker: ManagedWorker,\n task?: AllWorkerTasks\n ) {\n managedWorker.request_id = undefined;\n if (task != null) {\n if ('instance' in task) {\n this.instanceRequestMap.delete(task.instance);\n }\n this.pendingTasks.delete(task.id);\n }\n }\n\n private executeTask(\n managedWorker: ManagedWorker,\n task: AllWorkerTasks\n ): void {\n this.assignWorkerToTask(task, managedWorker);\n for (const lang of getLangsFromTask(task)) {\n managedWorker.langs.add(lang);\n }\n try {\n managedWorker.worker.postMessage(task.request);\n } catch (error) {\n this.cleanWorkerAndTask(managedWorker, task);\n console.error('Failed to post message to worker:', error);\n if ('instance' in task) {\n task.instance.onHighlightError(error);\n } else if ('reject' in task) {\n task.reject(error as Error);\n }\n }\n this.queueBroadcastStateChanges();\n }\n\n private getAvailableWorker(\n langs: SupportedLanguages[]\n ): ManagedWorker | undefined {\n let worker: ManagedWorker | undefined;\n for (const managedWorker of this.workers) {\n if (managedWorker.request_id != null || !managedWorker.initialized) {\n continue;\n }\n worker = managedWorker;\n if (langs.length === 0) {\n break;\n }\n let hasEveryLang = true;\n for (const lang of langs) {\n if (!managedWorker.langs.has(lang)) {\n hasEveryLang = false;\n break;\n }\n }\n if (hasEveryLang) {\n break;\n }\n }\n return worker;\n }\n\n private generateRequestId(): WorkerRequestId {\n return `req_${++this.nextRequestId}`;\n }\n}\n\nfunction getLangsFromTask(task: AllWorkerTasks): SupportedLanguages[] {\n const langs = new Set<SupportedLanguages>();\n if (task.type === 'initialize' || task.type === 'set-render-options') {\n return [];\n }\n switch (task.type) {\n case 'file': {\n langs.add(\n task.request.file.lang ??\n getFiletypeFromFileName(task.request.file.name)\n );\n break;\n }\n case 'diff': {\n langs.add(\n task.request.diff.lang ??\n getFiletypeFromFileName(task.request.diff.name)\n );\n langs.add(\n task.request.diff.lang ??\n getFiletypeFromFileName(task.request.diff.prevName ?? '-')\n );\n break;\n }\n }\n langs.delete('text');\n return Array.from(langs);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WorkerPoolManager.js","names":["options: WorkerPoolOptions","newRenderOptions: WorkerRenderingOptions","resolvedThemes: ThemeRegistrationResolved[]","taskPromises: Promise<void>[]","task: SetRenderOptionsWorkerTask","resolvedLanguages: ResolvedLanguage[]","initPromises: Promise<unknown>[]","managedWorker: ManagedWorker","task: InitializeWorkerTask","task: RenderFileTask | RenderDiffTask","worker: ManagedWorker | undefined"],"sources":["../../src/worker/WorkerPoolManager.ts"],"sourcesContent":["import LRUMapPkg from 'lru_map';\n\nimport { DEFAULT_THEMES } from '../constants';\nimport { getResolvedLanguages } from '../highlighter/languages/getResolvedLanguages';\nimport { hasResolvedLanguages } from '../highlighter/languages/hasResolvedLanguages';\nimport { resolveLanguages } from '../highlighter/languages/resolveLanguages';\nimport { getSharedHighlighter } from '../highlighter/shared_highlighter';\nimport { attachResolvedThemes } from '../highlighter/themes/attachResolvedThemes';\nimport { getResolvedThemes } from '../highlighter/themes/getResolvedThemes';\nimport { hasResolvedThemes } from '../highlighter/themes/hasResolvedThemes';\nimport { resolveThemes } from '../highlighter/themes/resolveThemes';\nimport type {\n DiffsHighlighter,\n FileContents,\n FileDiffMetadata,\n HighlighterTypes,\n HunkExpansionRegion,\n RenderDiffOptions,\n RenderDiffResult,\n RenderFileOptions,\n RenderFileResult,\n SupportedLanguages,\n ThemedDiffResult,\n ThemedFileResult,\n ThemeRegistrationResolved,\n} from '../types';\nimport { areDiffRenderOptionsEqual } from '../utils/areDiffRenderOptionsEqual';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areThemesEqual } from '../utils/areThemesEqual';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { getThemes } from '../utils/getThemes';\nimport { isDiffPlainText } from '../utils/isDiffPlainText';\nimport { isFilePlainText } from '../utils/isFilePlainText';\nimport { renderDiffWithHighlighter } from '../utils/renderDiffWithHighlighter';\nimport { renderFileWithHighlighter } from '../utils/renderFileWithHighlighter';\nimport type {\n AllWorkerTasks,\n DiffRendererInstance,\n FileRendererInstance,\n InitializeWorkerTask,\n RenderDiffRequest,\n RenderDiffTask,\n RenderFileRequest,\n RenderFileTask,\n ResolvedLanguage,\n SetRenderOptionsWorkerTask,\n SubmitRequest,\n WorkerInitializationRenderOptions,\n WorkerPoolOptions,\n WorkerRenderingOptions,\n WorkerRequestId,\n WorkerResponse,\n WorkerStats,\n} from './types';\n\nconst IGNORE_RESPONSE = Symbol('IGNORE_RESPONSE');\n\ninterface GetCachesResult {\n fileCache: LRUMapPkg.LRUMap<string, RenderFileResult>;\n diffCache: LRUMapPkg.LRUMap<string, RenderDiffResult>;\n}\n\ninterface ManagedWorker {\n worker: Worker;\n request_id: string | undefined;\n initialized: boolean;\n langs: Set<SupportedLanguages>;\n}\n\ninterface ThemeSubscriber {\n rerender(): void;\n}\n\nexport class WorkerPoolManager {\n private highlighter: DiffsHighlighter | undefined;\n private readonly preferredHighlighter: HighlighterTypes;\n private renderOptions: WorkerRenderingOptions;\n private initialized: Promise<void> | boolean = false;\n private workers: ManagedWorker[] = [];\n private taskQueue = new Map<\n FileRendererInstance | DiffRendererInstance,\n RenderDiffTask | RenderFileTask\n >();\n private pendingTasks = new Map<WorkerRequestId, AllWorkerTasks>();\n private nextRequestId = 0;\n private themeSubscribers = new Set<ThemeSubscriber>();\n private workersFailed = false;\n private instanceRequestMap = new Map<\n FileRendererInstance | DiffRendererInstance,\n string\n >();\n private statSubscribers = new Set<(stats: WorkerStats) => unknown>();\n private fileCache: LRUMapPkg.LRUMap<string, RenderFileResult>;\n private diffCache: LRUMapPkg.LRUMap<string, RenderDiffResult>;\n private _queuedBroadcast: number | undefined;\n\n constructor(\n private options: WorkerPoolOptions,\n {\n langs,\n theme = DEFAULT_THEMES,\n lineDiffType = 'word-alt',\n maxLineDiffLength = 1000,\n tokenizeMaxLineLength = 1000,\n preferredHighlighter = 'shiki-js',\n }: WorkerInitializationRenderOptions\n ) {\n this.preferredHighlighter = preferredHighlighter;\n this.renderOptions = {\n theme,\n lineDiffType,\n maxLineDiffLength,\n tokenizeMaxLineLength,\n };\n this.fileCache = new LRUMapPkg.LRUMap(options.totalASTLRUCacheSize ?? 100);\n this.diffCache = new LRUMapPkg.LRUMap(options.totalASTLRUCacheSize ?? 100);\n void this.initialize(langs);\n }\n\n isWorkingPool(): boolean {\n return !this.workersFailed;\n }\n\n getFileResultCache(file: FileContents): RenderFileResult | undefined {\n return file.cacheKey != null\n ? this.fileCache.get(file.cacheKey)\n : undefined;\n }\n\n getDiffResultCache(diff: FileDiffMetadata): RenderDiffResult | undefined {\n return diff.cacheKey != null\n ? this.diffCache.get(diff.cacheKey)\n : undefined;\n }\n\n inspectCaches(): GetCachesResult {\n const { fileCache, diffCache } = this;\n return { fileCache, diffCache };\n }\n\n evictFileFromCache(cacheKey: string): boolean {\n try {\n return this.fileCache.delete(cacheKey) !== undefined;\n } finally {\n this.queueBroadcastStateChanges();\n }\n }\n\n evictDiffFromCache(cacheKey: string): boolean {\n try {\n return this.diffCache.delete(cacheKey) !== undefined;\n } finally {\n this.queueBroadcastStateChanges();\n }\n }\n\n async setRenderOptions({\n theme = DEFAULT_THEMES,\n lineDiffType = 'word-alt',\n maxLineDiffLength = 1000,\n tokenizeMaxLineLength = 1000,\n }: Partial<WorkerRenderingOptions>): Promise<void> {\n const newRenderOptions: WorkerRenderingOptions = {\n theme,\n lineDiffType,\n maxLineDiffLength,\n tokenizeMaxLineLength,\n };\n if (!this.isInitialized()) {\n await this.initialize();\n }\n if (areDiffRenderOptionsEqual(newRenderOptions, this.renderOptions)) {\n return;\n }\n\n const themeNames = getThemes(theme);\n let resolvedThemes: ThemeRegistrationResolved[] = [];\n if (!areThemesEqual(newRenderOptions.theme, this.renderOptions.theme)) {\n if (hasResolvedThemes(themeNames)) {\n resolvedThemes = getResolvedThemes(themeNames);\n } else {\n resolvedThemes = await resolveThemes(themeNames);\n }\n }\n\n if (this.highlighter != null) {\n attachResolvedThemes(resolvedThemes, this.highlighter);\n await this.setRenderOptionsOnWorkers(newRenderOptions, resolvedThemes);\n } else {\n const [highlighter] = await Promise.all([\n getSharedHighlighter({\n themes: themeNames,\n langs: ['text'],\n preferredHighlighter: this.preferredHighlighter,\n }),\n this.setRenderOptionsOnWorkers(newRenderOptions, resolvedThemes),\n ]);\n this.highlighter = highlighter;\n }\n\n this.renderOptions = newRenderOptions;\n this.diffCache.clear();\n this.fileCache.clear();\n\n for (const instance of this.themeSubscribers) {\n instance.rerender();\n }\n }\n\n getFileRenderOptions(): RenderFileOptions {\n const { tokenizeMaxLineLength, theme } = this.renderOptions;\n return { theme, tokenizeMaxLineLength };\n }\n\n getDiffRenderOptions(): RenderDiffOptions {\n return { ...this.renderOptions };\n }\n\n private async setRenderOptionsOnWorkers(\n renderOptions: WorkerRenderingOptions,\n resolvedThemes: ThemeRegistrationResolved[]\n ): Promise<void> {\n if (this.workersFailed) {\n return;\n }\n if (!this.isInitialized()) {\n await this.initialize();\n }\n const taskPromises: Promise<void>[] = [];\n for (const managedWorker of this.workers) {\n if (!managedWorker.initialized) {\n console.log({ managedWorker });\n throw new Error(\n 'setRenderOptionsOnWorkers: Somehow we have an uninitialized worker'\n );\n }\n taskPromises.push(\n new Promise<void>((resolve, reject) => {\n const id = this.generateRequestId();\n const task: SetRenderOptionsWorkerTask = {\n type: 'set-render-options',\n id,\n request: {\n type: 'set-render-options',\n id,\n renderOptions,\n resolvedThemes,\n },\n resolve,\n reject,\n requestStart: Date.now(),\n };\n // NOTE(amadeus): We intentionally ignore the normal pending requests\n // infra because these tasks should technically interrupt the normal\n // flow and should be processed by the worker when ready immediately\n this.pendingTasks.set(id, task);\n managedWorker.worker.postMessage(task.request);\n })\n );\n }\n await Promise.all(taskPromises);\n }\n\n subscribeToThemeChanges(instance: ThemeSubscriber): () => void {\n this.themeSubscribers.add(instance);\n this.queueBroadcastStateChanges();\n return () => {\n this.unsubscribeToThemeChanges(instance);\n this.queueBroadcastStateChanges();\n };\n }\n\n unsubscribeToThemeChanges(instance: ThemeSubscriber): void {\n this.themeSubscribers.delete(instance);\n this.queueBroadcastStateChanges();\n }\n\n subscribeToStatChanges(\n callback: (stats: WorkerStats) => unknown\n ): () => void {\n this.statSubscribers.add(callback);\n callback(this.getStats());\n return () => {\n this.statSubscribers.delete(callback);\n };\n }\n\n private queueBroadcastStateChanges() {\n if (this._queuedBroadcast != null) return;\n this._queuedBroadcast = requestAnimationFrame(this._broadcastStateChanges);\n }\n\n private _broadcastStateChanges = () => {\n if (this._queuedBroadcast != null) {\n cancelAnimationFrame(this._queuedBroadcast);\n this._queuedBroadcast = undefined;\n }\n const stats = this.getStats();\n for (const callback of this.statSubscribers) {\n callback(stats);\n }\n };\n\n cleanUpPendingTasks(\n instance: FileRendererInstance | DiffRendererInstance\n ): void {\n this.taskQueue.delete(instance);\n const requestId = this.instanceRequestMap.get(instance);\n if (requestId != null) {\n this.pendingTasks.delete(requestId);\n this.instanceRequestMap.delete(instance);\n }\n this.queueBroadcastStateChanges();\n }\n\n isInitialized(): boolean {\n return this.initialized === true;\n }\n\n async initialize(languages: SupportedLanguages[] = []): Promise<void> {\n if (this.initialized === true) {\n return;\n } else if (this.initialized === false) {\n this.initialized = new Promise((resolve, reject) => {\n void (async () => {\n try {\n const themes = getThemes(this.renderOptions.theme);\n let resolvedThemes: ThemeRegistrationResolved[] = [];\n if (hasResolvedThemes(themes)) {\n resolvedThemes = getResolvedThemes(themes);\n } else {\n resolvedThemes = await resolveThemes(themes);\n }\n\n let resolvedLanguages: ResolvedLanguage[] = [];\n if (hasResolvedLanguages(languages)) {\n resolvedLanguages = getResolvedLanguages(languages);\n } else {\n resolvedLanguages = await resolveLanguages(languages);\n }\n\n const [highlighter] = await Promise.all([\n getSharedHighlighter({\n themes,\n langs: ['text', ...languages],\n preferredHighlighter: this.preferredHighlighter,\n }),\n this.initializeWorkers(resolvedThemes, resolvedLanguages),\n ]);\n\n // If we were terminated while initializing, we should probably kill\n // any workers that may have been created\n if (this.initialized === false) {\n this.terminateWorkers();\n throw new Error(\n 'WorkerPoolManager: workers failed to initialize'\n );\n }\n this.highlighter = highlighter;\n this.initialized = true;\n this.diffCache.clear();\n this.fileCache.clear();\n this.drainQueue();\n this.queueBroadcastStateChanges();\n resolve();\n } catch (e) {\n this.initialized = false;\n this.workersFailed = true;\n this.queueBroadcastStateChanges();\n reject(e);\n }\n })();\n });\n this.queueBroadcastStateChanges();\n } else {\n return this.initialized;\n }\n }\n\n private async initializeWorkers(\n resolvedThemes: ThemeRegistrationResolved[],\n resolvedLanguages: ResolvedLanguage[]\n ): Promise<void> {\n this.workersFailed = false;\n const initPromises: Promise<unknown>[] = [];\n if (this.workers.length > 0) {\n this.terminateWorkers();\n }\n for (let i = 0; i < (this.options.poolSize ?? 8); i++) {\n const worker = this.options.workerFactory();\n const managedWorker: ManagedWorker = {\n worker,\n request_id: undefined,\n initialized: false,\n langs: new Set(['text', ...resolvedLanguages.map(({ name }) => name)]),\n };\n worker.addEventListener(\n 'message',\n (event: MessageEvent<WorkerResponse>) => {\n this.handleWorkerMessage(managedWorker, event.data);\n }\n );\n worker.addEventListener('error', (error) =>\n console.error('Worker error:', error, managedWorker)\n );\n this.workers.push(managedWorker);\n initPromises.push(\n new Promise<void>((resolve, reject) => {\n const id = this.generateRequestId();\n const task: InitializeWorkerTask = {\n type: 'initialize',\n id,\n request: {\n type: 'initialize',\n id,\n renderOptions: this.renderOptions,\n preferredHighlighter: this.preferredHighlighter,\n resolvedThemes,\n resolvedLanguages,\n },\n resolve() {\n managedWorker.initialized = true;\n resolve();\n },\n reject,\n requestStart: Date.now(),\n };\n this.pendingTasks.set(id, task);\n this.executeTask(managedWorker, task);\n })\n );\n }\n await Promise.all(initPromises);\n }\n\n private drainQueue = () => {\n this._queuedDrain = undefined;\n // If we are initializing or things got cancelled while initializing, we\n // should not attempt to drain the queue\n if (this.initialized !== true || this.taskQueue.size === 0) {\n return;\n }\n for (const [instance, task] of this.taskQueue) {\n // If we have a request in progress for the same instance, we should wait\n // for it to finish\n if (this.instanceRequestMap.has(instance)) {\n continue;\n }\n const langs = getLangsFromTask(task);\n const availableWorker = this.getAvailableWorker(langs);\n if (availableWorker == null) {\n break;\n }\n this.assignWorkerToTask(task, availableWorker);\n void this.resolveLanguagesAndExecuteTask(availableWorker, task, langs);\n }\n this.queueBroadcastStateChanges();\n };\n\n highlightFileAST(instance: FileRendererInstance, file: FileContents): void {\n if (isFilePlainText(file)) {\n return;\n }\n // If we already have a task in progress for this same file content, we\n // should drop it\n for (const tasks of [this.taskQueue, this.pendingTasks.values()]) {\n for (const task of tasks) {\n if (\n 'instance' in task &&\n task.instance === instance &&\n task.request.type === 'file' &&\n areFilesEqual(file, task.request.file)\n ) {\n return;\n }\n }\n }\n this.submitTask(instance, { type: 'file', file });\n }\n\n getPlainFileAST(\n file: FileContents,\n startingLine: number,\n totalLines: number,\n lines?: string[]\n ): ThemedFileResult | undefined {\n if (this.highlighter == null) {\n void this.initialize();\n return undefined;\n }\n return renderFileWithHighlighter(\n file,\n this.highlighter,\n this.renderOptions,\n { forcePlainText: true, startingLine, totalLines, lines }\n );\n }\n\n highlightDiffAST(\n instance: DiffRendererInstance,\n diff: FileDiffMetadata\n ): void {\n if (isDiffPlainText(diff)) {\n return;\n }\n // If we already have a task in progress for this same diff content, we\n // should ignore executing it again\n for (const tasks of [this.taskQueue, this.pendingTasks.values()]) {\n for (const task of tasks) {\n if (\n 'instance' in task &&\n task.instance === instance &&\n task.request.type === 'diff' &&\n task.request.diff === diff\n ) {\n return;\n }\n }\n }\n this.submitTask(instance, { type: 'diff', diff });\n }\n\n getPlainDiffAST(\n diff: FileDiffMetadata,\n startingLine: number,\n totalLines: number,\n expandedHunks?: Map<number, HunkExpansionRegion> | true,\n collapsedContextThreshold?: number\n ): ThemedDiffResult | undefined {\n return this.highlighter != null\n ? renderDiffWithHighlighter(diff, this.highlighter, this.renderOptions, {\n forcePlainText: true,\n startingLine,\n totalLines,\n expandedHunks,\n collapsedContextThreshold,\n })\n : undefined;\n }\n\n terminate(): void {\n this.terminateWorkers();\n this.fileCache.clear();\n this.diffCache.clear();\n this.instanceRequestMap.clear();\n this.taskQueue.clear();\n this.pendingTasks.clear();\n this.highlighter = undefined;\n this.initialized = false;\n this.workersFailed = false;\n this.queueBroadcastStateChanges();\n }\n\n private terminateWorkers() {\n for (const managedWorker of this.workers) {\n managedWorker.worker.terminate();\n }\n this.workers.length = 0;\n }\n\n getStats(): WorkerStats {\n return {\n managerState: (() => {\n if (this.initialized === false) {\n return 'waiting';\n }\n if (this.initialized !== true) {\n return 'initializing';\n }\n return 'initialized';\n })(),\n totalWorkers: this.workers.length,\n workersFailed: this.workersFailed,\n busyWorkers: this.workers.filter((w) => w.request_id != null).length,\n queuedTasks: this.taskQueue.size,\n pendingTasks: this.pendingTasks.size,\n themeSubscribers: this.themeSubscribers.size,\n fileCacheSize: this.fileCache.size,\n diffCacheSize: this.diffCache.size,\n };\n }\n\n private submitTask(\n instance: FileRendererInstance,\n request: Omit<RenderFileRequest, 'id'>\n ): void;\n private submitTask(\n instance: DiffRendererInstance,\n request: Omit<RenderDiffRequest, 'id'>\n ): void;\n private submitTask(\n instance: FileRendererInstance | DiffRendererInstance,\n request: SubmitRequest\n ): void {\n if (this.initialized === false) {\n void this.initialize();\n }\n\n const id = this.generateRequestId();\n const requestStart = Date.now();\n const task: RenderFileTask | RenderDiffTask = (() => {\n switch (request.type) {\n case 'file':\n return {\n type: 'file',\n id,\n request: { ...request, id },\n instance: instance as FileRendererInstance,\n requestStart,\n };\n case 'diff':\n return {\n type: 'diff',\n id,\n request: { ...request, id },\n instance: instance as DiffRendererInstance,\n requestStart,\n };\n }\n })();\n\n this.taskQueue.set(instance, task);\n this.queueDrain();\n }\n\n private async resolveLanguagesAndExecuteTask(\n availableWorker: ManagedWorker,\n task: RenderFileTask | RenderDiffTask,\n langs: SupportedLanguages[]\n ): Promise<void> {\n try {\n // Add resolved languages if required\n const workerMissingLangs = langs.filter(\n (lang) => !availableWorker.langs.has(lang)\n );\n\n if (workerMissingLangs.length > 0) {\n if (hasResolvedLanguages(workerMissingLangs)) {\n task.request.resolvedLanguages =\n getResolvedLanguages(workerMissingLangs);\n } else {\n task.request.resolvedLanguages =\n await resolveLanguages(workerMissingLangs);\n }\n }\n this.executeTask(availableWorker, task);\n } catch {\n this.cleanWorkerAndTask(availableWorker, task);\n }\n }\n\n private handleWorkerMessage(\n managedWorker: ManagedWorker,\n response: WorkerResponse\n ): void {\n const task = this.pendingTasks.get(response.id);\n try {\n if (task == null) {\n // If we can't find a task for this response, it probably means the\n // component has been unmounted, so we should silently ignore it\n throw IGNORE_RESPONSE;\n } else if (response.type === 'error') {\n const error = new Error(response.error);\n if (response.stack) {\n error.stack = response.stack;\n }\n if ('reject' in task) {\n task.reject(error);\n } else {\n task.instance.onHighlightError(error);\n }\n throw error;\n } else {\n // If we've gotten a newer request from the same instance, we should\n // ignore this response either because it's out of order or because we\n // have a newer more important request\n if (\n 'instance' in task &&\n this.instanceRequestMap.get(task.instance) !== response.id\n ) {\n throw IGNORE_RESPONSE;\n }\n switch (response.requestType) {\n case 'initialize':\n if (task.type !== 'initialize') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n task.resolve();\n break;\n case 'set-render-options':\n if (task.type !== 'set-render-options') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n task.resolve();\n break;\n case 'file': {\n if (task.type !== 'file') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n const { result, options } = response;\n const { instance, request } = task;\n if (request.file.cacheKey != null) {\n this.fileCache.set(request.file.cacheKey, { result, options });\n }\n instance.onHighlightSuccess(request.file, result, options);\n break;\n }\n case 'diff': {\n if (task.type !== 'diff') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n const { result, options } = response;\n const { instance, request } = task;\n if (request.diff.cacheKey != null) {\n this.diffCache.set(request.diff.cacheKey, { result, options });\n }\n instance.onHighlightSuccess(request.diff, result, options);\n break;\n }\n }\n }\n } catch (error) {\n if (error !== IGNORE_RESPONSE) {\n console.error(error, task, response);\n }\n }\n\n this.cleanWorkerAndTask(managedWorker, task);\n this.queueBroadcastStateChanges();\n if (this.taskQueue.size > 0) {\n // We queue drain so that potentially multiple workers can free up\n // allowing for better language matches if possible\n this.queueDrain();\n }\n }\n\n private _queuedDrain: Promise<void> | undefined;\n private queueDrain() {\n if (this._queuedDrain != null) return;\n this._queuedDrain = Promise.resolve().then(this.drainQueue);\n this.queueBroadcastStateChanges();\n }\n\n private assignWorkerToTask(\n task: AllWorkerTasks,\n managedWorker: ManagedWorker\n ) {\n managedWorker.request_id = task.id;\n if ('instance' in task) {\n this.taskQueue.delete(task.instance);\n this.instanceRequestMap.set(task.instance, task.id);\n }\n this.pendingTasks.set(task.id, task);\n }\n\n private cleanWorkerAndTask(\n managedWorker: ManagedWorker,\n task?: AllWorkerTasks\n ) {\n managedWorker.request_id = undefined;\n if (task != null) {\n if ('instance' in task) {\n this.instanceRequestMap.delete(task.instance);\n }\n this.pendingTasks.delete(task.id);\n }\n }\n\n private executeTask(\n managedWorker: ManagedWorker,\n task: AllWorkerTasks\n ): void {\n this.assignWorkerToTask(task, managedWorker);\n for (const lang of getLangsFromTask(task)) {\n managedWorker.langs.add(lang);\n }\n try {\n managedWorker.worker.postMessage(task.request);\n } catch (error) {\n this.cleanWorkerAndTask(managedWorker, task);\n console.error('Failed to post message to worker:', error);\n if ('instance' in task) {\n task.instance.onHighlightError(error);\n } else if ('reject' in task) {\n task.reject(error as Error);\n }\n }\n this.queueBroadcastStateChanges();\n }\n\n private getAvailableWorker(\n langs: SupportedLanguages[]\n ): ManagedWorker | undefined {\n let worker: ManagedWorker | undefined;\n for (const managedWorker of this.workers) {\n if (managedWorker.request_id != null || !managedWorker.initialized) {\n continue;\n }\n worker = managedWorker;\n if (langs.length === 0) {\n break;\n }\n let hasEveryLang = true;\n for (const lang of langs) {\n if (!managedWorker.langs.has(lang)) {\n hasEveryLang = false;\n break;\n }\n }\n if (hasEveryLang) {\n break;\n }\n }\n return worker;\n }\n\n private generateRequestId(): WorkerRequestId {\n return `req_${++this.nextRequestId}`;\n }\n}\n\nfunction getLangsFromTask(task: AllWorkerTasks): SupportedLanguages[] {\n const langs = new Set<SupportedLanguages>();\n if (task.type === 'initialize' || task.type === 'set-render-options') {\n return [];\n }\n switch (task.type) {\n case 'file': {\n langs.add(\n task.request.file.lang ??\n getFiletypeFromFileName(task.request.file.name)\n );\n break;\n }\n case 'diff': {\n langs.add(\n task.request.diff.lang ??\n getFiletypeFromFileName(task.request.diff.name)\n );\n langs.add(\n task.request.diff.lang ??\n getFiletypeFromFileName(task.request.diff.prevName ?? '-')\n );\n break;\n }\n }\n langs.delete('text');\n return Array.from(langs);\n}\n"],"mappings":"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"}
|
package/dist/worker/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":["DiffsThemeNames","FileContents","FileDiffMetadata","HighlighterTypes","LanguageRegistration","LineDiffTypes","RenderDiffOptions","RenderFileOptions","SupportedLanguages","ThemedDiffResult","ThemedFileResult","ThemeRegistrationResolved","ThemesType","WorkerRequestId","WorkerRenderingOptions","FileRendererInstance","DiffRendererInstance","RenderFileRequest","ResolvedLanguage","RenderDiffRequest","InitializeWorkerRequest","Exclude","SetRenderOptionsWorkerRequest","SubmitRequest","Omit","WorkerRequest","RenderFileSuccessResponse","RenderDiffSuccessResponse","InitializeSuccessResponse","RegisterThemeSuccessResponse","RenderErrorResponse","RenderSuccessResponse","WorkerResponse","WorkerPoolOptions","Worker","WorkerInitializationRenderOptions","Partial","InitializeWorkerTask","Error","SetRenderOptionsWorkerTask","RenderFileTask","RenderDiffTask","AllWorkerTasks","WorkerStats"],"sources":["../../src/worker/types.d.ts"],"sourcesContent":["import type { DiffsThemeNames, FileContents, FileDiffMetadata, HighlighterTypes, LanguageRegistration, LineDiffTypes, RenderDiffOptions, RenderFileOptions, SupportedLanguages, ThemedDiffResult, ThemedFileResult, ThemeRegistrationResolved, ThemesType } from '../types';\nexport type WorkerRequestId = string;\nexport interface WorkerRenderingOptions {\n theme: DiffsThemeNames | ThemesType;\n tokenizeMaxLineLength: number;\n lineDiffType: LineDiffTypes;\n}\nexport interface FileRendererInstance {\n readonly __id: string;\n onHighlightSuccess(file: FileContents, result: ThemedFileResult, options: RenderFileOptions): unknown;\n onHighlightError(error: unknown): unknown;\n}\nexport interface DiffRendererInstance {\n readonly __id: string;\n onHighlightSuccess(diff: FileDiffMetadata, result: ThemedDiffResult, options: RenderDiffOptions): unknown;\n onHighlightError(error: unknown): unknown;\n}\nexport interface RenderFileRequest {\n type: 'file';\n id: WorkerRequestId;\n file: FileContents;\n resolvedLanguages?: ResolvedLanguage[];\n}\nexport interface RenderDiffRequest {\n type: 'diff';\n id: WorkerRequestId;\n diff: FileDiffMetadata;\n resolvedLanguages?: ResolvedLanguage[];\n}\nexport interface InitializeWorkerRequest {\n type: 'initialize';\n id: WorkerRequestId;\n renderOptions: WorkerRenderingOptions;\n preferredHighlighter: HighlighterTypes;\n resolvedThemes: ThemeRegistrationResolved[];\n resolvedLanguages?: ResolvedLanguage[];\n}\nexport interface ResolvedLanguage {\n name: Exclude<SupportedLanguages, 'text'>;\n data: LanguageRegistration[];\n}\nexport interface SetRenderOptionsWorkerRequest {\n type: 'set-render-options';\n id: WorkerRequestId;\n renderOptions: WorkerRenderingOptions;\n resolvedThemes: ThemeRegistrationResolved[];\n}\nexport type SubmitRequest = Omit<RenderFileRequest, 'id'> | Omit<RenderDiffRequest, 'id'>;\nexport type WorkerRequest = RenderFileRequest | RenderDiffRequest | InitializeWorkerRequest | SetRenderOptionsWorkerRequest;\nexport interface RenderFileSuccessResponse {\n type: 'success';\n requestType: 'file';\n id: WorkerRequestId;\n result: ThemedFileResult;\n options: RenderFileOptions;\n sentAt: number;\n}\nexport interface RenderDiffSuccessResponse {\n type: 'success';\n requestType: 'diff';\n id: WorkerRequestId;\n result: ThemedDiffResult;\n options: RenderDiffOptions;\n sentAt: number;\n}\nexport interface InitializeSuccessResponse {\n type: 'success';\n requestType: 'initialize';\n id: WorkerRequestId;\n sentAt: number;\n}\nexport interface RegisterThemeSuccessResponse {\n type: 'success';\n requestType: 'set-render-options';\n id: WorkerRequestId;\n sentAt: number;\n}\nexport interface RenderErrorResponse {\n type: 'error';\n id: WorkerRequestId;\n error: string;\n stack?: string;\n}\nexport type RenderSuccessResponse = RenderFileSuccessResponse | RenderDiffSuccessResponse;\nexport type WorkerResponse = RenderSuccessResponse | RenderErrorResponse | InitializeSuccessResponse | RegisterThemeSuccessResponse;\nexport interface WorkerPoolOptions {\n /**\n * Factory function that creates a new Web Worker instance for the pool.\n * This is called once per worker in the pool during initialization.\n */\n workerFactory: () => Worker;\n /**\n * Number of workers to create in the pool.\n * @default 8\n */\n poolSize?: number;\n totalASTLRUCacheSize?: number;\n}\nexport interface WorkerInitializationRenderOptions extends Partial<WorkerRenderingOptions> {\n langs?: SupportedLanguages[];\n preferredHighlighter?: HighlighterTypes;\n}\nexport interface InitializeWorkerTask {\n type: 'initialize';\n id: WorkerRequestId;\n request: InitializeWorkerRequest;\n resolve(value?: undefined): void;\n reject(error: Error): void;\n requestStart: number;\n}\nexport interface SetRenderOptionsWorkerTask {\n type: 'set-render-options';\n id: WorkerRequestId;\n request: SetRenderOptionsWorkerRequest;\n resolve(value?: undefined): void;\n reject(error: Error): void;\n requestStart: number;\n}\nexport interface RenderFileTask {\n type: 'file';\n id: WorkerRequestId;\n request: RenderFileRequest;\n instance: FileRendererInstance;\n requestStart: number;\n}\nexport interface RenderDiffTask {\n type: 'diff';\n id: WorkerRequestId;\n request: RenderDiffRequest;\n instance: DiffRendererInstance;\n requestStart: number;\n}\nexport type AllWorkerTasks = InitializeWorkerTask | SetRenderOptionsWorkerTask | RenderFileTask | RenderDiffTask;\nexport interface WorkerStats {\n managerState: 'waiting' | 'initializing' | 'initialized';\n workersFailed: boolean;\n totalWorkers: number;\n busyWorkers: number;\n queuedTasks: number;\n pendingTasks: number;\n themeSubscribers: number;\n fileCacheSize: number;\n diffCacheSize: number;\n}\n//# sourceMappingURL=types.d.ts.map"],"mappings":";;;KACYa,eAAAA;UACKC,sBAAAA;EADLD,KAAAA,EAEDb,eAFgB,GAEEY,UAFF;EACVE,qBAAAA,EAAAA,MAAsB;EAC5Bd,YAAAA,EAEOK,aAFPL;;
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":["DiffsThemeNames","FileContents","FileDiffMetadata","HighlighterTypes","LanguageRegistration","LineDiffTypes","RenderDiffOptions","RenderFileOptions","SupportedLanguages","ThemedDiffResult","ThemedFileResult","ThemeRegistrationResolved","ThemesType","WorkerRequestId","WorkerRenderingOptions","FileRendererInstance","DiffRendererInstance","RenderFileRequest","ResolvedLanguage","RenderDiffRequest","InitializeWorkerRequest","Exclude","SetRenderOptionsWorkerRequest","SubmitRequest","Omit","WorkerRequest","RenderFileSuccessResponse","RenderDiffSuccessResponse","InitializeSuccessResponse","RegisterThemeSuccessResponse","RenderErrorResponse","RenderSuccessResponse","WorkerResponse","WorkerPoolOptions","Worker","WorkerInitializationRenderOptions","Partial","InitializeWorkerTask","Error","SetRenderOptionsWorkerTask","RenderFileTask","RenderDiffTask","AllWorkerTasks","WorkerStats"],"sources":["../../src/worker/types.d.ts"],"sourcesContent":["import type { DiffsThemeNames, FileContents, FileDiffMetadata, HighlighterTypes, LanguageRegistration, LineDiffTypes, RenderDiffOptions, RenderFileOptions, SupportedLanguages, ThemedDiffResult, ThemedFileResult, ThemeRegistrationResolved, ThemesType } from '../types';\nexport type WorkerRequestId = string;\nexport interface WorkerRenderingOptions {\n theme: DiffsThemeNames | ThemesType;\n tokenizeMaxLineLength: number;\n lineDiffType: LineDiffTypes;\n maxLineDiffLength: number;\n}\nexport interface FileRendererInstance {\n readonly __id: string;\n onHighlightSuccess(file: FileContents, result: ThemedFileResult, options: RenderFileOptions): unknown;\n onHighlightError(error: unknown): unknown;\n}\nexport interface DiffRendererInstance {\n readonly __id: string;\n onHighlightSuccess(diff: FileDiffMetadata, result: ThemedDiffResult, options: RenderDiffOptions): unknown;\n onHighlightError(error: unknown): unknown;\n}\nexport interface RenderFileRequest {\n type: 'file';\n id: WorkerRequestId;\n file: FileContents;\n resolvedLanguages?: ResolvedLanguage[];\n}\nexport interface RenderDiffRequest {\n type: 'diff';\n id: WorkerRequestId;\n diff: FileDiffMetadata;\n resolvedLanguages?: ResolvedLanguage[];\n}\nexport interface InitializeWorkerRequest {\n type: 'initialize';\n id: WorkerRequestId;\n renderOptions: WorkerRenderingOptions;\n preferredHighlighter: HighlighterTypes;\n resolvedThemes: ThemeRegistrationResolved[];\n resolvedLanguages?: ResolvedLanguage[];\n}\nexport interface ResolvedLanguage {\n name: Exclude<SupportedLanguages, 'text'>;\n data: LanguageRegistration[];\n}\nexport interface SetRenderOptionsWorkerRequest {\n type: 'set-render-options';\n id: WorkerRequestId;\n renderOptions: WorkerRenderingOptions;\n resolvedThemes: ThemeRegistrationResolved[];\n}\nexport type SubmitRequest = Omit<RenderFileRequest, 'id'> | Omit<RenderDiffRequest, 'id'>;\nexport type WorkerRequest = RenderFileRequest | RenderDiffRequest | InitializeWorkerRequest | SetRenderOptionsWorkerRequest;\nexport interface RenderFileSuccessResponse {\n type: 'success';\n requestType: 'file';\n id: WorkerRequestId;\n result: ThemedFileResult;\n options: RenderFileOptions;\n sentAt: number;\n}\nexport interface RenderDiffSuccessResponse {\n type: 'success';\n requestType: 'diff';\n id: WorkerRequestId;\n result: ThemedDiffResult;\n options: RenderDiffOptions;\n sentAt: number;\n}\nexport interface InitializeSuccessResponse {\n type: 'success';\n requestType: 'initialize';\n id: WorkerRequestId;\n sentAt: number;\n}\nexport interface RegisterThemeSuccessResponse {\n type: 'success';\n requestType: 'set-render-options';\n id: WorkerRequestId;\n sentAt: number;\n}\nexport interface RenderErrorResponse {\n type: 'error';\n id: WorkerRequestId;\n error: string;\n stack?: string;\n}\nexport type RenderSuccessResponse = RenderFileSuccessResponse | RenderDiffSuccessResponse;\nexport type WorkerResponse = RenderSuccessResponse | RenderErrorResponse | InitializeSuccessResponse | RegisterThemeSuccessResponse;\nexport interface WorkerPoolOptions {\n /**\n * Factory function that creates a new Web Worker instance for the pool.\n * This is called once per worker in the pool during initialization.\n */\n workerFactory: () => Worker;\n /**\n * Number of workers to create in the pool.\n * @default 8\n */\n poolSize?: number;\n totalASTLRUCacheSize?: number;\n}\nexport interface WorkerInitializationRenderOptions extends Partial<WorkerRenderingOptions> {\n langs?: SupportedLanguages[];\n preferredHighlighter?: HighlighterTypes;\n}\nexport interface InitializeWorkerTask {\n type: 'initialize';\n id: WorkerRequestId;\n request: InitializeWorkerRequest;\n resolve(value?: undefined): void;\n reject(error: Error): void;\n requestStart: number;\n}\nexport interface SetRenderOptionsWorkerTask {\n type: 'set-render-options';\n id: WorkerRequestId;\n request: SetRenderOptionsWorkerRequest;\n resolve(value?: undefined): void;\n reject(error: Error): void;\n requestStart: number;\n}\nexport interface RenderFileTask {\n type: 'file';\n id: WorkerRequestId;\n request: RenderFileRequest;\n instance: FileRendererInstance;\n requestStart: number;\n}\nexport interface RenderDiffTask {\n type: 'diff';\n id: WorkerRequestId;\n request: RenderDiffRequest;\n instance: DiffRendererInstance;\n requestStart: number;\n}\nexport type AllWorkerTasks = InitializeWorkerTask | SetRenderOptionsWorkerTask | RenderFileTask | RenderDiffTask;\nexport interface WorkerStats {\n managerState: 'waiting' | 'initializing' | 'initialized';\n workersFailed: boolean;\n totalWorkers: number;\n busyWorkers: number;\n queuedTasks: number;\n pendingTasks: number;\n themeSubscribers: number;\n fileCacheSize: number;\n diffCacheSize: number;\n}\n//# sourceMappingURL=types.d.ts.map"],"mappings":"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"}
|