@pierre/diffs 1.1.7 → 1.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/components/AdvancedVirtualizedFileDiff.d.ts.map +1 -1
  2. package/dist/components/File.d.ts.map +1 -1
  3. package/dist/components/FileDiff.js +2 -2
  4. package/dist/components/FileDiff.js.map +1 -1
  5. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  6. package/dist/components/VirtualizedFileDiff.js +1 -1
  7. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  8. package/dist/index.d.ts +4 -3
  9. package/dist/index.js +2 -1
  10. package/dist/managers/InteractionManager.d.ts +15 -2
  11. package/dist/managers/InteractionManager.d.ts.map +1 -1
  12. package/dist/managers/InteractionManager.js +143 -40
  13. package/dist/managers/InteractionManager.js.map +1 -1
  14. package/dist/react/index.d.ts +2 -2
  15. package/dist/renderers/DiffHunksRenderer.js +11 -10
  16. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  17. package/dist/renderers/FileRenderer.js +3 -1
  18. package/dist/renderers/FileRenderer.js.map +1 -1
  19. package/dist/ssr/FileDiffReact.js +1 -1
  20. package/dist/ssr/index.d.ts +2 -2
  21. package/dist/ssr/preloadDiffs.js +1 -1
  22. package/dist/ssr/preloadDiffs.js.map +1 -1
  23. package/dist/style.js +1 -1
  24. package/dist/style.js.map +1 -1
  25. package/dist/types.d.ts +23 -2
  26. package/dist/types.d.ts.map +1 -1
  27. package/dist/utils/areDiffRenderOptionsEqual.d.ts +7 -0
  28. package/dist/utils/areDiffRenderOptionsEqual.d.ts.map +1 -0
  29. package/dist/utils/areDiffRenderOptionsEqual.js +10 -0
  30. package/dist/utils/areDiffRenderOptionsEqual.js.map +1 -0
  31. package/dist/utils/areOptionsEqual.d.ts +2 -1
  32. package/dist/utils/areOptionsEqual.d.ts.map +1 -1
  33. package/dist/utils/areOptionsEqual.js +8 -1
  34. package/dist/utils/areOptionsEqual.js.map +1 -1
  35. package/dist/utils/createTransformerWithState.d.ts +1 -1
  36. package/dist/utils/createTransformerWithState.d.ts.map +1 -1
  37. package/dist/utils/createTransformerWithState.js +27 -2
  38. package/dist/utils/createTransformerWithState.js.map +1 -1
  39. package/dist/utils/parseDiffFromFile.js +1 -0
  40. package/dist/utils/parseDiffFromFile.js.map +1 -1
  41. package/dist/utils/renderDiffWithHighlighter.js +6 -3
  42. package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
  43. package/dist/utils/renderFileWithHighlighter.d.ts +2 -1
  44. package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
  45. package/dist/utils/renderFileWithHighlighter.js +2 -2
  46. package/dist/utils/renderFileWithHighlighter.js.map +1 -1
  47. package/dist/utils/shouldUseTokenTransformer.d.ts +9 -0
  48. package/dist/utils/shouldUseTokenTransformer.d.ts.map +1 -0
  49. package/dist/utils/shouldUseTokenTransformer.js +8 -0
  50. package/dist/utils/shouldUseTokenTransformer.js.map +1 -0
  51. package/dist/utils/wrapTokenFragments.d.ts +10 -0
  52. package/dist/utils/wrapTokenFragments.d.ts.map +1 -0
  53. package/dist/utils/wrapTokenFragments.js +82 -0
  54. package/dist/utils/wrapTokenFragments.js.map +1 -0
  55. package/dist/worker/WorkerPoolManager.d.ts +4 -0
  56. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  57. package/dist/worker/WorkerPoolManager.js +11 -6
  58. package/dist/worker/WorkerPoolManager.js.map +1 -1
  59. package/dist/worker/types.d.ts +2 -0
  60. package/dist/worker/types.d.ts.map +1 -1
  61. package/dist/worker/worker-portable.js +142 -8
  62. package/dist/worker/worker-portable.js.map +1 -1
  63. package/dist/worker/worker.js +124 -8
  64. package/dist/worker/worker.js.map +1 -1
  65. package/package.json +1 -1
@@ -76,6 +76,14 @@ function createTextNodeElement(value) {
76
76
  value
77
77
  };
78
78
  }
79
+ function createHastElement({ tagName, children = [], properties = {} }) {
80
+ return {
81
+ type: "element",
82
+ tagName,
83
+ properties,
84
+ children
85
+ };
86
+ }
79
87
  function findCodeElement(nodes) {
80
88
  let firstChild = nodes.children[0];
81
89
  while (firstChild != null) {
@@ -107,9 +115,87 @@ function processLine(node, line, state) {
107
115
  return node;
108
116
  }
109
117
 
118
+ //#endregion
119
+ //#region src/utils/wrapTokenFragments.ts
120
+ const NO_TOKEN = Symbol("no-token");
121
+ const MULTIPLE_TOKENS = Symbol("multiple-tokens");
122
+ function wrapTokenFragments(container) {
123
+ const ownTokenChar = getTokenChar(container);
124
+ if (ownTokenChar != null) return ownTokenChar;
125
+ let containerTokenState = NO_TOKEN;
126
+ const wrappedChildren = [];
127
+ let currentTokenChildren = [];
128
+ let currentTokenChar;
129
+ const flushTokenChildren = () => {
130
+ if (currentTokenChildren.length === 0 || currentTokenChar == null) {
131
+ currentTokenChildren = [];
132
+ currentTokenChar = void 0;
133
+ return;
134
+ }
135
+ if (currentTokenChildren.length === 1) {
136
+ const child = currentTokenChildren[0];
137
+ if (child?.type === "element") {
138
+ setTokenChar(child, currentTokenChar);
139
+ for (const grandChild of child.children) stripTokenChar(grandChild);
140
+ } else stripTokenChar(child);
141
+ wrappedChildren.push(child);
142
+ currentTokenChildren = [];
143
+ currentTokenChar = void 0;
144
+ return;
145
+ }
146
+ for (const child of currentTokenChildren) stripTokenChar(child);
147
+ wrappedChildren.push(createHastElement({
148
+ tagName: "span",
149
+ properties: { "data-char": currentTokenChar },
150
+ children: currentTokenChildren
151
+ }));
152
+ currentTokenChildren = [];
153
+ currentTokenChar = void 0;
154
+ };
155
+ const mergeContainerTokenState = (childTokenState) => {
156
+ if (childTokenState === NO_TOKEN) return;
157
+ if (childTokenState === MULTIPLE_TOKENS) {
158
+ containerTokenState = MULTIPLE_TOKENS;
159
+ return;
160
+ }
161
+ if (containerTokenState === NO_TOKEN) {
162
+ containerTokenState = childTokenState;
163
+ return;
164
+ }
165
+ if (containerTokenState !== childTokenState) containerTokenState = MULTIPLE_TOKENS;
166
+ };
167
+ for (const child of container.children) {
168
+ const childTokenState = child.type === "element" ? wrapTokenFragments(child) : NO_TOKEN;
169
+ mergeContainerTokenState(childTokenState);
170
+ if (typeof childTokenState !== "number") {
171
+ flushTokenChildren();
172
+ wrappedChildren.push(child);
173
+ continue;
174
+ }
175
+ if (currentTokenChar != null && currentTokenChar !== childTokenState) flushTokenChildren();
176
+ currentTokenChar ??= childTokenState;
177
+ currentTokenChildren.push(child);
178
+ }
179
+ flushTokenChildren();
180
+ container.children = wrappedChildren;
181
+ return containerTokenState;
182
+ }
183
+ function getTokenChar(node) {
184
+ const value = node.properties["data-char"];
185
+ if (typeof value === "number") return value;
186
+ }
187
+ function stripTokenChar(node) {
188
+ if (node.type !== "element") return;
189
+ node.properties["data-char"] = void 0;
190
+ for (const child of node.children) stripTokenChar(child);
191
+ }
192
+ function setTokenChar(node, char) {
193
+ node.properties["data-char"] = char;
194
+ }
195
+
110
196
  //#endregion
111
197
  //#region src/utils/createTransformerWithState.ts
112
- function createTransformerWithState(useCSSClasses = false) {
198
+ function createTransformerWithState(useTokenTransformer = false, useCSSClasses = false) {
113
199
  const state = { lineInfo: [] };
114
200
  const transformers = [{
115
201
  line(node) {
@@ -123,13 +209,37 @@ function createTransformerWithState(useCSSClasses = false) {
123
209
  let index = 1;
124
210
  for (const node of code.children) {
125
211
  if (node.type !== "element") continue;
212
+ if (useTokenTransformer) wrapTokenFragments(node);
126
213
  children.push(processLine(node, index, state));
127
214
  index++;
128
215
  }
129
216
  code.children = children;
130
217
  }
131
218
  return pre;
132
- }
219
+ },
220
+ ...useTokenTransformer ? {
221
+ tokens(lines) {
222
+ for (const line of lines) {
223
+ let col = 0;
224
+ for (const token of line) {
225
+ const tokenWithOriginalRange = token;
226
+ tokenWithOriginalRange.__lineChar ??= col;
227
+ col += token.content.length;
228
+ }
229
+ }
230
+ },
231
+ preprocess(_code, options) {
232
+ options.mergeWhitespaces = "never";
233
+ },
234
+ span(hast, _line, _char, _lineElement, token) {
235
+ if (token?.offset != null && token.content != null) {
236
+ const tokenChar = token.__lineChar;
237
+ if (tokenChar != null) hast.properties["data-char"] = tokenChar;
238
+ return hast;
239
+ }
240
+ return hast;
241
+ }
242
+ } : null
133
243
  }];
134
244
  if (useCSSClasses) transformers.push(tokenStyleNormalizer, toClass);
135
245
  return {
@@ -1001,6 +1111,7 @@ function renderDiffWithHighlighter(diff, highlighter$1, options, { forcePlainTex
1001
1111
  deletionLines: [],
1002
1112
  additionLines: []
1003
1113
  };
1114
+ const { maxLineDiffLength } = options;
1004
1115
  const shouldGroupAll = !forcePlainText && !diff.isPartial;
1005
1116
  const expandedHunksForIteration = forcePlainText ? expandedHunks : void 0;
1006
1117
  const buckets = /* @__PURE__ */ new Map();
@@ -1042,7 +1153,8 @@ function renderDiffWithHighlighter(diff, highlighter$1, options, { forcePlainTex
1042
1153
  additionLineIndex: bucket.additionContent.length,
1043
1154
  deletionDecorations: bucket.deletionDecorations,
1044
1155
  additionDecorations: bucket.additionDecorations,
1045
- lineDiffType
1156
+ lineDiffType,
1157
+ maxLineDiffLength
1046
1158
  });
1047
1159
  if (deletionLine != null) {
1048
1160
  appendContent(diff.deletionLines[deletionLine.lineIndex], deletionLine.lineIndex, bucket.deletionSegments, bucket.deletionContent);
@@ -1101,10 +1213,11 @@ function renderDiffWithHighlighter(diff, highlighter$1, options, { forcePlainTex
1101
1213
  baseThemeType
1102
1214
  };
1103
1215
  }
1104
- function computeLineDiffDecorations({ deletionLine, additionLine, deletionLineIndex, additionLineIndex, deletionDecorations, additionDecorations, lineDiffType }) {
1216
+ function computeLineDiffDecorations({ deletionLine, additionLine, deletionLineIndex, additionLineIndex, deletionDecorations, additionDecorations, lineDiffType, maxLineDiffLength }) {
1105
1217
  if (deletionLine == null || additionLine == null || lineDiffType === "none") return;
1106
1218
  deletionLine = cleanLastNewline(deletionLine);
1107
1219
  additionLine = cleanLastNewline(additionLine);
1220
+ if (deletionLine.length > maxLineDiffLength || additionLine.length > maxLineDiffLength) return;
1108
1221
  const lineDiff = lineDiffType === "char" ? diffChars(deletionLine, additionLine) : diffWordsWithSpace(deletionLine, additionLine);
1109
1222
  const deletionSpans = [];
1110
1223
  const additionSpans = [];
@@ -1188,7 +1301,7 @@ function createBucket() {
1188
1301
  function renderTwoFiles({ deletionFile, additionFile, deletionInfo, additionInfo, highlighter: highlighter$1, deletionDecorations, additionDecorations, languageOverride, options: { theme: themeOrThemes = DEFAULT_THEMES,...options } }) {
1189
1302
  const deletionLang = languageOverride ?? getFiletypeFromFileName(deletionFile.name);
1190
1303
  const additionLang = languageOverride ?? getFiletypeFromFileName(additionFile.name);
1191
- const { state, transformers } = createTransformerWithState();
1304
+ const { state, transformers } = createTransformerWithState(options.useTokenTransformer);
1192
1305
  const hastConfig = (() => {
1193
1306
  return typeof themeOrThemes === "string" ? {
1194
1307
  ...options,
@@ -1289,7 +1402,7 @@ function splitFileContents(contents) {
1289
1402
  //#endregion
1290
1403
  //#region src/utils/renderFileWithHighlighter.ts
1291
1404
  const DEFAULT_PLAIN_TEXT_OPTIONS = { forcePlainText: false };
1292
- function renderFileWithHighlighter(file, highlighter$1, { theme = DEFAULT_THEMES, tokenizeMaxLineLength }, { forcePlainText, startingLine, totalLines, lines } = DEFAULT_PLAIN_TEXT_OPTIONS) {
1405
+ function renderFileWithHighlighter(file, highlighter$1, { theme = DEFAULT_THEMES, tokenizeMaxLineLength, useTokenTransformer }, { forcePlainText, startingLine, totalLines, lines } = DEFAULT_PLAIN_TEXT_OPTIONS) {
1293
1406
  if (forcePlainText) {
1294
1407
  startingLine ??= 0;
1295
1408
  totalLines ??= Infinity;
@@ -1298,7 +1411,7 @@ function renderFileWithHighlighter(file, highlighter$1, { theme = DEFAULT_THEMES
1298
1411
  totalLines = Infinity;
1299
1412
  }
1300
1413
  const isWindowedHighlight = startingLine > 0 || totalLines < Infinity;
1301
- const { state, transformers } = createTransformerWithState();
1414
+ const { state, transformers } = createTransformerWithState(useTokenTransformer);
1302
1415
  const lang = forcePlainText ? "text" : file.lang ?? getFiletypeFromFileName(file.name);
1303
1416
  const baseThemeType = typeof theme === "string" ? highlighter$1.getTheme(theme).type : void 0;
1304
1417
  const themeStyles = getHighlighterThemeStyles({
@@ -1355,8 +1468,10 @@ function extractWindowedFileContent(lines, startingLine, totalLines) {
1355
1468
  let highlighter;
1356
1469
  let renderOptions = {
1357
1470
  theme: DEFAULT_THEMES,
1471
+ useTokenTransformer: false,
1358
1472
  tokenizeMaxLineLength: 1e3,
1359
- lineDiffType: "word-alt"
1473
+ lineDiffType: "word-alt",
1474
+ maxLineDiffLength: 1e3
1360
1475
  };
1361
1476
  self.addEventListener("error", (event) => {
1362
1477
  console.error("[Shiki Worker] Unhandled error:", event.error);
@@ -1417,6 +1532,7 @@ async function handleRenderFile({ id, file, resolvedLanguages }) {
1417
1532
  if (resolvedLanguages != null) attachResolvedLanguages(resolvedLanguages, highlighter$1);
1418
1533
  const fileOptions = {
1419
1534
  theme: renderOptions.theme,
1535
+ useTokenTransformer: renderOptions.useTokenTransformer,
1420
1536
  tokenizeMaxLineLength: renderOptions.tokenizeMaxLineLength
1421
1537
  };
1422
1538
  sendFileSuccess(id, renderFileWithHighlighter(file, highlighter$1, fileOptions), fileOptions);