@pierre/diffs 1.1.8 → 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 (52) hide show
  1. package/dist/components/AdvancedVirtualizedFileDiff.d.ts.map +1 -1
  2. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  3. package/dist/components/VirtulizerDevelopment.d.ts.map +1 -1
  4. package/dist/constants.d.ts.map +1 -1
  5. package/dist/index.d.ts +3 -3
  6. package/dist/managers/InteractionManager.d.ts +15 -2
  7. package/dist/managers/InteractionManager.d.ts.map +1 -1
  8. package/dist/managers/InteractionManager.js +143 -40
  9. package/dist/managers/InteractionManager.js.map +1 -1
  10. package/dist/react/index.d.ts +2 -2
  11. package/dist/react/types.d.ts.map +1 -1
  12. package/dist/renderers/DiffHunksRenderer.js +4 -1
  13. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  14. package/dist/renderers/FileRenderer.js +3 -1
  15. package/dist/renderers/FileRenderer.js.map +1 -1
  16. package/dist/ssr/FileDiffReact.js +1 -1
  17. package/dist/ssr/index.d.ts +2 -2
  18. package/dist/style.js +1 -1
  19. package/dist/style.js.map +1 -1
  20. package/dist/types.d.ts +15 -1
  21. package/dist/types.d.ts.map +1 -1
  22. package/dist/utils/areDiffRenderOptionsEqual.js +1 -1
  23. package/dist/utils/areDiffRenderOptionsEqual.js.map +1 -1
  24. package/dist/utils/createTransformerWithState.d.ts +1 -1
  25. package/dist/utils/createTransformerWithState.d.ts.map +1 -1
  26. package/dist/utils/createTransformerWithState.js +27 -2
  27. package/dist/utils/createTransformerWithState.js.map +1 -1
  28. package/dist/utils/renderDiffWithHighlighter.js +1 -1
  29. package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
  30. package/dist/utils/renderFileWithHighlighter.d.ts +2 -1
  31. package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
  32. package/dist/utils/renderFileWithHighlighter.js +2 -2
  33. package/dist/utils/renderFileWithHighlighter.js.map +1 -1
  34. package/dist/utils/shouldUseTokenTransformer.d.ts +9 -0
  35. package/dist/utils/shouldUseTokenTransformer.d.ts.map +1 -0
  36. package/dist/utils/shouldUseTokenTransformer.js +8 -0
  37. package/dist/utils/shouldUseTokenTransformer.js.map +1 -0
  38. package/dist/utils/wrapTokenFragments.d.ts +10 -0
  39. package/dist/utils/wrapTokenFragments.d.ts.map +1 -0
  40. package/dist/utils/wrapTokenFragments.js +82 -0
  41. package/dist/utils/wrapTokenFragments.js.map +1 -0
  42. package/dist/worker/WorkerPoolManager.d.ts +2 -0
  43. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  44. package/dist/worker/WorkerPoolManager.js +6 -3
  45. package/dist/worker/WorkerPoolManager.js.map +1 -1
  46. package/dist/worker/types.d.ts +1 -0
  47. package/dist/worker/types.d.ts.map +1 -1
  48. package/dist/worker/worker-portable.js +133 -5
  49. package/dist/worker/worker-portable.js.map +1 -1
  50. package/dist/worker/worker.js +117 -5
  51. package/dist/worker/worker.js.map +1 -1
  52. 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 {
@@ -1191,7 +1301,7 @@ function createBucket() {
1191
1301
  function renderTwoFiles({ deletionFile, additionFile, deletionInfo, additionInfo, highlighter: highlighter$1, deletionDecorations, additionDecorations, languageOverride, options: { theme: themeOrThemes = DEFAULT_THEMES,...options } }) {
1192
1302
  const deletionLang = languageOverride ?? getFiletypeFromFileName(deletionFile.name);
1193
1303
  const additionLang = languageOverride ?? getFiletypeFromFileName(additionFile.name);
1194
- const { state, transformers } = createTransformerWithState();
1304
+ const { state, transformers } = createTransformerWithState(options.useTokenTransformer);
1195
1305
  const hastConfig = (() => {
1196
1306
  return typeof themeOrThemes === "string" ? {
1197
1307
  ...options,
@@ -1292,7 +1402,7 @@ function splitFileContents(contents) {
1292
1402
  //#endregion
1293
1403
  //#region src/utils/renderFileWithHighlighter.ts
1294
1404
  const DEFAULT_PLAIN_TEXT_OPTIONS = { forcePlainText: false };
1295
- 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) {
1296
1406
  if (forcePlainText) {
1297
1407
  startingLine ??= 0;
1298
1408
  totalLines ??= Infinity;
@@ -1301,7 +1411,7 @@ function renderFileWithHighlighter(file, highlighter$1, { theme = DEFAULT_THEMES
1301
1411
  totalLines = Infinity;
1302
1412
  }
1303
1413
  const isWindowedHighlight = startingLine > 0 || totalLines < Infinity;
1304
- const { state, transformers } = createTransformerWithState();
1414
+ const { state, transformers } = createTransformerWithState(useTokenTransformer);
1305
1415
  const lang = forcePlainText ? "text" : file.lang ?? getFiletypeFromFileName(file.name);
1306
1416
  const baseThemeType = typeof theme === "string" ? highlighter$1.getTheme(theme).type : void 0;
1307
1417
  const themeStyles = getHighlighterThemeStyles({
@@ -1358,6 +1468,7 @@ function extractWindowedFileContent(lines, startingLine, totalLines) {
1358
1468
  let highlighter;
1359
1469
  let renderOptions = {
1360
1470
  theme: DEFAULT_THEMES,
1471
+ useTokenTransformer: false,
1361
1472
  tokenizeMaxLineLength: 1e3,
1362
1473
  lineDiffType: "word-alt",
1363
1474
  maxLineDiffLength: 1e3
@@ -1421,6 +1532,7 @@ async function handleRenderFile({ id, file, resolvedLanguages }) {
1421
1532
  if (resolvedLanguages != null) attachResolvedLanguages(resolvedLanguages, highlighter$1);
1422
1533
  const fileOptions = {
1423
1534
  theme: renderOptions.theme,
1535
+ useTokenTransformer: renderOptions.useTokenTransformer,
1424
1536
  tokenizeMaxLineLength: renderOptions.tokenizeMaxLineLength
1425
1537
  };
1426
1538
  sendFileSuccess(id, renderFileWithHighlighter(file, highlighter$1, fileOptions), fileOptions);