@pierre/diffs 1.1.0-beta.7 → 1.1.0-beta.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.
Files changed (288) hide show
  1. package/dist/components/AdvancedVirtualizedFileDiff.d.ts +40 -0
  2. package/dist/components/AdvancedVirtualizedFileDiff.d.ts.map +1 -0
  3. package/dist/components/AdvancedVirtualizedFileDiff.js +145 -0
  4. package/dist/components/AdvancedVirtualizedFileDiff.js.map +1 -0
  5. package/dist/components/AdvancedVirtualizer.d.ts +38 -0
  6. package/dist/components/AdvancedVirtualizer.d.ts.map +1 -0
  7. package/dist/components/AdvancedVirtualizer.js +201 -0
  8. package/dist/components/AdvancedVirtualizer.js.map +1 -0
  9. package/dist/components/File.d.ts +58 -33
  10. package/dist/components/File.d.ts.map +1 -1
  11. package/dist/components/File.js +223 -22
  12. package/dist/components/File.js.map +1 -1
  13. package/dist/components/FileDiff.d.ts +42 -16
  14. package/dist/components/FileDiff.d.ts.map +1 -1
  15. package/dist/components/FileDiff.js +505 -65
  16. package/dist/components/FileDiff.js.map +1 -1
  17. package/dist/components/FileStream.d.ts +5 -0
  18. package/dist/components/FileStream.d.ts.map +1 -1
  19. package/dist/components/FileStream.js +66 -8
  20. package/dist/components/FileStream.js.map +1 -1
  21. package/dist/components/VirtualizedFile.d.ts +33 -0
  22. package/dist/components/VirtualizedFile.d.ts.map +1 -0
  23. package/dist/components/VirtualizedFile.js +227 -0
  24. package/dist/components/VirtualizedFile.js.map +1 -0
  25. package/dist/components/VirtualizedFileDiff.d.ts +39 -0
  26. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -0
  27. package/dist/components/VirtualizedFileDiff.js +316 -0
  28. package/dist/components/VirtualizedFileDiff.js.map +1 -0
  29. package/dist/components/Virtualizer.d.ts +63 -0
  30. package/dist/components/Virtualizer.d.ts.map +1 -0
  31. package/dist/components/Virtualizer.js +369 -0
  32. package/dist/components/Virtualizer.js.map +1 -0
  33. package/dist/components/VirtulizerDevelopment.d.ts +14 -0
  34. package/dist/components/VirtulizerDevelopment.d.ts.map +1 -0
  35. package/dist/components/web-components.d.ts +1 -1
  36. package/dist/components/web-components.d.ts.map +1 -1
  37. package/dist/constants.d.ts +4 -7
  38. package/dist/constants.d.ts.map +1 -1
  39. package/dist/constants.js +14 -6
  40. package/dist/constants.js.map +1 -1
  41. package/dist/highlighter/languages/areLanguagesAttached.d.ts.map +1 -1
  42. package/dist/highlighter/languages/attachResolvedLanguages.d.ts.map +1 -1
  43. package/dist/highlighter/languages/cleanUpResolvedLanguages.d.ts.map +1 -1
  44. package/dist/highlighter/languages/constants.d.ts.map +1 -1
  45. package/dist/highlighter/languages/getResolvedLanguages.d.ts.map +1 -1
  46. package/dist/highlighter/languages/getResolvedOrResolveLanguage.d.ts +1 -1
  47. package/dist/highlighter/languages/getResolvedOrResolveLanguage.d.ts.map +1 -1
  48. package/dist/highlighter/languages/hasResolvedLanguages.d.ts.map +1 -1
  49. package/dist/highlighter/languages/registerCustomLanguage.d.ts +11 -4
  50. package/dist/highlighter/languages/registerCustomLanguage.d.ts.map +1 -1
  51. package/dist/highlighter/languages/resolveLanguage.d.ts +1 -1
  52. package/dist/highlighter/languages/resolveLanguage.d.ts.map +1 -1
  53. package/dist/highlighter/languages/resolveLanguages.d.ts.map +1 -1
  54. package/dist/highlighter/shared_highlighter.d.ts.map +1 -1
  55. package/dist/highlighter/shared_highlighter.js.map +1 -1
  56. package/dist/highlighter/themes/areThemesAttached.d.ts.map +1 -1
  57. package/dist/highlighter/themes/attachResolvedThemes.d.ts.map +1 -1
  58. package/dist/highlighter/themes/cleanUpResolvedThemes.d.ts.map +1 -1
  59. package/dist/highlighter/themes/constants.d.ts.map +1 -1
  60. package/dist/highlighter/themes/getResolvedOrResolveTheme.d.ts.map +1 -1
  61. package/dist/highlighter/themes/getResolvedThemes.d.ts.map +1 -1
  62. package/dist/highlighter/themes/hasResolvedThemes.d.ts.map +1 -1
  63. package/dist/highlighter/themes/registerCustomCSSVariableTheme.d.ts.map +1 -1
  64. package/dist/highlighter/themes/registerCustomTheme.d.ts.map +1 -1
  65. package/dist/highlighter/themes/resolveTheme.d.ts.map +1 -1
  66. package/dist/highlighter/themes/resolveThemes.d.ts.map +1 -1
  67. package/dist/index.d.ts +13 -10
  68. package/dist/index.js +10 -7
  69. package/dist/managers/LineSelectionManager.d.ts +14 -15
  70. package/dist/managers/LineSelectionManager.d.ts.map +1 -1
  71. package/dist/managers/LineSelectionManager.js +60 -71
  72. package/dist/managers/LineSelectionManager.js.map +1 -1
  73. package/dist/managers/MouseEventManager.d.ts +13 -6
  74. package/dist/managers/MouseEventManager.d.ts.map +1 -1
  75. package/dist/managers/MouseEventManager.js +161 -47
  76. package/dist/managers/MouseEventManager.js.map +1 -1
  77. package/dist/managers/ResizeManager.d.ts +6 -1
  78. package/dist/managers/ResizeManager.d.ts.map +1 -1
  79. package/dist/managers/ResizeManager.js +114 -64
  80. package/dist/managers/ResizeManager.js.map +1 -1
  81. package/dist/managers/ScrollSyncManager.d.ts.map +1 -1
  82. package/dist/managers/UniversalRenderingManager.d.ts.map +1 -1
  83. package/dist/react/File.d.ts +1 -0
  84. package/dist/react/File.d.ts.map +1 -1
  85. package/dist/react/File.js +2 -1
  86. package/dist/react/File.js.map +1 -1
  87. package/dist/react/FileDiff.d.ts +1 -0
  88. package/dist/react/FileDiff.d.ts.map +1 -1
  89. package/dist/react/FileDiff.js +2 -1
  90. package/dist/react/FileDiff.js.map +1 -1
  91. package/dist/react/MultiFileDiff.d.ts +1 -0
  92. package/dist/react/MultiFileDiff.d.ts.map +1 -1
  93. package/dist/react/MultiFileDiff.js +2 -1
  94. package/dist/react/MultiFileDiff.js.map +1 -1
  95. package/dist/react/PatchDiff.d.ts +1 -0
  96. package/dist/react/PatchDiff.d.ts.map +1 -1
  97. package/dist/react/PatchDiff.js +3 -2
  98. package/dist/react/PatchDiff.js.map +1 -1
  99. package/dist/react/Virtualizer.d.ts +25 -0
  100. package/dist/react/Virtualizer.d.ts.map +1 -0
  101. package/dist/react/Virtualizer.js +38 -0
  102. package/dist/react/Virtualizer.js.map +1 -0
  103. package/dist/react/WorkerPoolContext.d.ts.map +1 -1
  104. package/dist/react/WorkerPoolContext.js +1 -1
  105. package/dist/react/WorkerPoolContext.js.map +1 -1
  106. package/dist/react/constants.d.ts.map +1 -1
  107. package/dist/react/index.d.ts +3 -2
  108. package/dist/react/index.js +2 -1
  109. package/dist/react/jsx.d.ts.map +1 -1
  110. package/dist/react/types.d.ts +5 -3
  111. package/dist/react/types.d.ts.map +1 -1
  112. package/dist/react/utils/renderDiffChildren.d.ts +5 -5
  113. package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
  114. package/dist/react/utils/renderFileChildren.d.ts +5 -5
  115. package/dist/react/utils/renderFileChildren.d.ts.map +1 -1
  116. package/dist/react/utils/templateRender.d.ts.map +1 -1
  117. package/dist/react/utils/useFileDiffInstance.d.ts +5 -3
  118. package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
  119. package/dist/react/utils/useFileDiffInstance.js +6 -2
  120. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  121. package/dist/react/utils/useFileInstance.d.ts +5 -3
  122. package/dist/react/utils/useFileInstance.d.ts.map +1 -1
  123. package/dist/react/utils/useFileInstance.js +6 -2
  124. package/dist/react/utils/useFileInstance.js.map +1 -1
  125. package/dist/react/utils/useStableCallback.d.ts.map +1 -1
  126. package/dist/react/utils/useStableCallback.js.map +1 -1
  127. package/dist/renderers/DiffHunksRenderer.d.ts +15 -10
  128. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  129. package/dist/renderers/DiffHunksRenderer.js +240 -136
  130. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  131. package/dist/renderers/FileRenderer.d.ts +12 -5
  132. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  133. package/dist/renderers/FileRenderer.js +90 -31
  134. package/dist/renderers/FileRenderer.js.map +1 -1
  135. package/dist/shiki-stream/stream.d.ts +2 -2
  136. package/dist/shiki-stream/stream.d.ts.map +1 -1
  137. package/dist/shiki-stream/stream.js.map +1 -1
  138. package/dist/shiki-stream/tokenizer.d.ts +2 -2
  139. package/dist/shiki-stream/tokenizer.d.ts.map +1 -1
  140. package/dist/shiki-stream/tokenizer.js.map +1 -1
  141. package/dist/shiki-stream/types.d.ts +18 -18
  142. package/dist/shiki-stream/types.d.ts.map +1 -1
  143. package/dist/sprite.d.ts +1 -1
  144. package/dist/sprite.d.ts.map +1 -1
  145. package/dist/ssr/FileDiffReact.d.ts.map +1 -1
  146. package/dist/ssr/FileDiffReact.js +1 -1
  147. package/dist/ssr/index.d.ts +2 -2
  148. package/dist/ssr/preloadDiffs.d.ts.map +1 -1
  149. package/dist/ssr/preloadFile.d.ts.map +1 -1
  150. package/dist/ssr/preloadPatchFile.d.ts.map +1 -1
  151. package/dist/ssr/preloadPatchFile.js.map +1 -1
  152. package/dist/ssr/renderHTML.d.ts.map +1 -1
  153. package/dist/style.js +1 -1
  154. package/dist/style.js.map +1 -1
  155. package/dist/types.d.ts +191 -172
  156. package/dist/types.d.ts.map +1 -1
  157. package/dist/utils/areDiffLineAnnotationsEqual.d.ts.map +1 -1
  158. package/dist/utils/areDiffLineAnnotationsEqual.js.map +1 -1
  159. package/dist/utils/areFilesEqual.d.ts.map +1 -1
  160. package/dist/utils/areHunkDataEqual.d.ts.map +1 -1
  161. package/dist/utils/areLineAnnotationsEqual.d.ts.map +1 -1
  162. package/dist/utils/areObjectsEqual.d.ts.map +1 -1
  163. package/dist/utils/areOptionsEqual.d.ts +1 -1
  164. package/dist/utils/areOptionsEqual.d.ts.map +1 -1
  165. package/dist/utils/arePrePropertiesEqual.d.ts.map +1 -1
  166. package/dist/utils/arePrePropertiesEqual.js +1 -1
  167. package/dist/utils/arePrePropertiesEqual.js.map +1 -1
  168. package/dist/utils/areRenderRangesEqual.d.ts.map +1 -1
  169. package/dist/utils/areSelectionsEqual.d.ts.map +1 -1
  170. package/dist/utils/areThemesEqual.d.ts.map +1 -1
  171. package/dist/utils/areVirtualWindowSpecsEqual.d.ts.map +1 -1
  172. package/dist/utils/areWorkerStatsEqual.d.ts.map +1 -1
  173. package/dist/utils/cleanLastNewline.d.ts.map +1 -1
  174. package/dist/utils/createAnnotationElement.d.ts.map +1 -1
  175. package/dist/utils/createAnnotationWrapperNode.d.ts.map +1 -1
  176. package/dist/utils/createContentColumn.d.ts +7 -0
  177. package/dist/utils/createContentColumn.d.ts.map +1 -0
  178. package/dist/utils/createContentColumn.js +17 -0
  179. package/dist/utils/createContentColumn.js.map +1 -0
  180. package/dist/utils/createEmptyRowBuffer.d.ts.map +1 -1
  181. package/dist/utils/createEmptyRowBuffer.js +2 -1
  182. package/dist/utils/createEmptyRowBuffer.js.map +1 -1
  183. package/dist/utils/createFileHeaderElement.d.ts.map +1 -1
  184. package/dist/utils/createHoverContentNode.d.ts.map +1 -1
  185. package/dist/utils/createNoNewlineElement.d.ts +2 -1
  186. package/dist/utils/createNoNewlineElement.d.ts.map +1 -1
  187. package/dist/utils/createNoNewlineElement.js +3 -6
  188. package/dist/utils/createNoNewlineElement.js.map +1 -1
  189. package/dist/utils/createPreElement.d.ts +2 -1
  190. package/dist/utils/createPreElement.d.ts.map +1 -1
  191. package/dist/utils/createPreElement.js +4 -3
  192. package/dist/utils/createPreElement.js.map +1 -1
  193. package/dist/utils/createRowNodes.d.ts.map +1 -1
  194. package/dist/utils/createSeparator.d.ts.map +1 -1
  195. package/dist/utils/createSeparator.js +1 -1
  196. package/dist/utils/createSeparator.js.map +1 -1
  197. package/dist/utils/createSpanNodeFromToken.d.ts.map +1 -1
  198. package/dist/utils/createSpanNodeFromToken.js.map +1 -1
  199. package/dist/utils/createStyleElement.d.ts.map +1 -1
  200. package/dist/utils/createTransformerWithState.d.ts.map +1 -1
  201. package/dist/utils/createUnsafeCSSStyleNode.d.ts.map +1 -1
  202. package/dist/utils/createWindowFromScrollPosition.d.ts.map +1 -1
  203. package/dist/utils/cssWrappers.d.ts.map +1 -1
  204. package/dist/utils/diffAcceptRejectHunk.d.ts +1 -1
  205. package/dist/utils/diffAcceptRejectHunk.d.ts.map +1 -1
  206. package/dist/utils/formatCSSVariablePrefix.d.ts +1 -1
  207. package/dist/utils/formatCSSVariablePrefix.d.ts.map +1 -1
  208. package/dist/utils/getFiletypeFromFileName.d.ts.map +1 -1
  209. package/dist/utils/getHighlighterOptions.d.ts.map +1 -1
  210. package/dist/utils/getHighlighterThemeStyles.d.ts.map +1 -1
  211. package/dist/utils/getHunkSeparatorSlotName.d.ts +3 -1
  212. package/dist/utils/getHunkSeparatorSlotName.d.ts.map +1 -1
  213. package/dist/utils/getHunkSeparatorSlotName.js.map +1 -1
  214. package/dist/utils/getIconForType.d.ts +1 -1
  215. package/dist/utils/getIconForType.d.ts.map +1 -1
  216. package/dist/utils/getLineAnnotationName.d.ts.map +1 -1
  217. package/dist/utils/getLineEndingType.d.ts +1 -1
  218. package/dist/utils/getLineEndingType.d.ts.map +1 -1
  219. package/dist/utils/getLineNodes.d.ts.map +1 -1
  220. package/dist/utils/getOrCreateCodeNode.d.ts +4 -2
  221. package/dist/utils/getOrCreateCodeNode.d.ts.map +1 -1
  222. package/dist/utils/getOrCreateCodeNode.js +9 -6
  223. package/dist/utils/getOrCreateCodeNode.js.map +1 -1
  224. package/dist/utils/getSingularPatch.d.ts.map +1 -1
  225. package/dist/utils/getThemes.d.ts.map +1 -1
  226. package/dist/utils/getTotalLineCountFromHunks.d.ts.map +1 -1
  227. package/dist/utils/hast_utils.d.ts +6 -3
  228. package/dist/utils/hast_utils.d.ts.map +1 -1
  229. package/dist/utils/hast_utils.js +28 -4
  230. package/dist/utils/hast_utils.js.map +1 -1
  231. package/dist/utils/isDefaultRenderRange.d.ts.map +1 -1
  232. package/dist/utils/isWorkerContext.d.ts.map +1 -1
  233. package/dist/utils/iterateOverDiff.d.ts +26 -13
  234. package/dist/utils/iterateOverDiff.d.ts.map +1 -1
  235. package/dist/utils/iterateOverDiff.js +94 -55
  236. package/dist/utils/iterateOverDiff.js.map +1 -1
  237. package/dist/utils/iterateOverFile.d.ts +50 -0
  238. package/dist/utils/iterateOverFile.d.ts.map +1 -0
  239. package/dist/utils/iterateOverFile.js +49 -0
  240. package/dist/utils/iterateOverFile.js.map +1 -0
  241. package/dist/utils/parseDiffDecorations.d.ts.map +1 -1
  242. package/dist/utils/parseDiffFromFile.d.ts +5 -5
  243. package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  244. package/dist/utils/parseLineType.d.ts +1 -1
  245. package/dist/utils/parseLineType.d.ts.map +1 -1
  246. package/dist/utils/parsePatchFiles.d.ts +7 -7
  247. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  248. package/dist/utils/parsePatchFiles.js.map +1 -1
  249. package/dist/utils/prerenderHTMLIfNecessary.d.ts.map +1 -1
  250. package/dist/utils/processLine.d.ts.map +1 -1
  251. package/dist/utils/processLine.js +7 -24
  252. package/dist/utils/processLine.js.map +1 -1
  253. package/dist/utils/renderDiffWithHighlighter.d.ts +2 -2
  254. package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
  255. package/dist/utils/renderDiffWithHighlighter.js +15 -14
  256. package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
  257. package/dist/utils/renderFileWithHighlighter.d.ts +7 -2
  258. package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
  259. package/dist/utils/renderFileWithHighlighter.js +30 -4
  260. package/dist/utils/renderFileWithHighlighter.js.map +1 -1
  261. package/dist/utils/resolveVirtualFileMetrics.d.ts +7 -0
  262. package/dist/utils/resolveVirtualFileMetrics.d.ts.map +1 -0
  263. package/dist/utils/resolveVirtualFileMetrics.js +24 -0
  264. package/dist/utils/resolveVirtualFileMetrics.js.map +1 -0
  265. package/dist/utils/setLanguageOverride.d.ts.map +1 -1
  266. package/dist/utils/setWrapperNodeProps.d.ts +1 -0
  267. package/dist/utils/setWrapperNodeProps.d.ts.map +1 -1
  268. package/dist/utils/setWrapperNodeProps.js +19 -12
  269. package/dist/utils/setWrapperNodeProps.js.map +1 -1
  270. package/dist/utils/splitFileContents.d.ts +12 -0
  271. package/dist/utils/splitFileContents.d.ts.map +1 -0
  272. package/dist/utils/splitFileContents.js +17 -0
  273. package/dist/utils/splitFileContents.js.map +1 -0
  274. package/dist/utils/trimPatchContext.d.ts +5 -5
  275. package/dist/utils/trimPatchContext.d.ts.map +1 -1
  276. package/dist/worker/WorkerPoolManager.d.ts +1 -2
  277. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  278. package/dist/worker/WorkerPoolManager.js +7 -2
  279. package/dist/worker/WorkerPoolManager.js.map +1 -1
  280. package/dist/worker/getOrCreateWorkerPoolSingleton.d.ts.map +1 -1
  281. package/dist/worker/getOrCreateWorkerPoolSingleton.js.map +1 -1
  282. package/dist/worker/types.d.ts +26 -26
  283. package/dist/worker/types.d.ts.map +1 -1
  284. package/dist/worker/worker-portable.js +254 -107
  285. package/dist/worker/worker-portable.js.map +1 -1
  286. package/dist/worker/worker.js +206 -106
  287. package/dist/worker/worker.js.map +1 -1
  288. package/package.json +52 -53
@@ -1 +1 @@
1
- {"version":3,"file":"iterateOverDiff.js","names":["state: IterationState","unifiedLineIndex","splitLineIndex","deletionLineIndex","additionLineIndex","deletionLineNumber","additionLineNumber","iterationRanges: [number, number][]","merged: [number, number][]"],"sources":["../../src/utils/iterateOverDiff.ts"],"sourcesContent":["import { DEFAULT_COLLAPSED_CONTEXT_THRESHOLD } from '../constants';\nimport type {\n ChangeContent,\n FileDiffMetadata,\n Hunk,\n HunkExpansionRegion,\n} from '../types';\n\nexport interface DiffLineCallbackProps {\n hunkIndex: number;\n hunk: Hunk | undefined; // undefined for trailing expansion region\n collapsedBefore: number; // > 0 means separator before this line, value = hidden lines\n collapsedAfter: number; // > 0 only on final line if trailing collapsed content\n unifiedDeletionLineIndex: number | undefined;\n unifiedAdditionLineIndex: number | undefined;\n splitLineIndex: number;\n additionLineIndex: number | undefined;\n deletionLineIndex: number | undefined;\n additionLineNumber: number | undefined; // 1-based file line number\n deletionLineNumber: number | undefined;\n type: 'context' | 'context-expanded' | 'change';\n // noEOFCR metadata - true if this is the last line and has no trailing newline\n noEOFCRAddition: boolean;\n noEOFCRDeletion: boolean;\n}\n\ninterface IterationState {\n finalHunk: Hunk | undefined;\n isWindowedHighlight: boolean;\n viewportStart: number;\n viewportEnd: number;\n splitCount: number;\n unifiedCount: number;\n shouldBreak(): boolean;\n shouldSkip(unifiedHeight: number, splitHeight: number): boolean;\n incrementCounts(unifiedValue: number, splitValue: number): void;\n isInWindow(unifiedHeight: number, splitHeight: number): boolean;\n isInUnifiedWindow(height: number): boolean;\n isInSplitWindow(height: number): boolean;\n emit(props: DiffLineCallbackProps, silent?: boolean): boolean;\n}\n\nexport type DiffLineCallback = (props: DiffLineCallbackProps) => boolean | void;\n\nexport interface IterateOverDiffProps {\n diff: FileDiffMetadata;\n diffStyle: 'unified' | 'split' | 'both';\n startingLine?: number;\n totalLines?: number;\n expandedHunks?: Map<number, HunkExpansionRegion> | true;\n collapsedContextThreshold?: number;\n callback: DiffLineCallback;\n}\n\nexport function iterateOverDiff({\n diff,\n diffStyle,\n startingLine = 0,\n totalLines = Infinity,\n expandedHunks,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n callback,\n}: IterateOverDiffProps): void {\n const state: IterationState = {\n finalHunk: diff.hunks.at(-1),\n viewportStart: startingLine,\n viewportEnd: startingLine + totalLines,\n isWindowedHighlight: startingLine > 0 || totalLines < Infinity,\n splitCount: 0,\n unifiedCount: 0,\n shouldBreak() {\n if (!state.isWindowedHighlight) {\n return false;\n }\n\n const breakUnified = state.unifiedCount >= startingLine + totalLines;\n const breakSplit = state.splitCount >= startingLine + totalLines;\n\n if (diffStyle === 'unified') {\n return breakUnified;\n } else if (diffStyle === 'split') {\n return breakSplit;\n } else {\n return breakUnified && breakSplit;\n }\n },\n shouldSkip(unifiedHeight: number, splitHeight: number) {\n if (!state.isWindowedHighlight) {\n return false;\n }\n\n const skipUnified = state.unifiedCount + unifiedHeight < startingLine;\n const skipSplit = state.splitCount + splitHeight < startingLine;\n\n if (diffStyle === 'unified') {\n return skipUnified;\n } else if (diffStyle === 'split') {\n return skipSplit;\n } else {\n return skipUnified && skipSplit;\n }\n },\n incrementCounts(unifiedValue: number, splitValue: number) {\n if (diffStyle === 'unified' || diffStyle === 'both') {\n state.unifiedCount += unifiedValue;\n }\n if (diffStyle === 'split' || diffStyle === 'both') {\n state.splitCount += splitValue;\n }\n },\n isInWindow(unifiedHeight: number, splitHeight: number) {\n if (!state.isWindowedHighlight) {\n return true;\n }\n\n const unifiedInWindow = state.isInUnifiedWindow(unifiedHeight);\n const splitInWindow = state.isInSplitWindow(splitHeight);\n\n if (diffStyle === 'unified') {\n return unifiedInWindow;\n } else if (diffStyle === 'split') {\n return splitInWindow;\n } else {\n return unifiedInWindow || splitInWindow;\n }\n },\n isInUnifiedWindow(unifiedHeight: number) {\n return (\n !state.isWindowedHighlight ||\n (state.unifiedCount >= startingLine - unifiedHeight &&\n state.unifiedCount < startingLine + totalLines)\n );\n },\n isInSplitWindow(splitHeight: number) {\n return (\n !state.isWindowedHighlight ||\n (state.splitCount >= startingLine - splitHeight &&\n state.splitCount < startingLine + totalLines)\n );\n },\n emit(props: DiffLineCallbackProps, silent = false): boolean {\n if (!silent) {\n if (diffStyle === 'unified') {\n state.incrementCounts(1, 0);\n } else if (diffStyle === 'split') {\n state.incrementCounts(0, 1);\n } else {\n state.incrementCounts(1, 1);\n // FIXME MAYBE\n // state.incrementCounts(\n // state.isInUnifiedWindow(0) ? 1 : 0,\n // state.isInSplitWindow(0) ? 1 : 0\n // );\n }\n }\n return callback(props) ?? false;\n },\n };\n\n hunkIterator: for (const [hunkIndex, hunk] of diff.hunks.entries()) {\n if (state.shouldBreak()) {\n break;\n }\n\n const leadingRegion = getExpandedRegion(\n diff.isPartial,\n hunk.collapsedBefore,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold\n );\n // We only create a trailing region if it's the last hunk\n const trailingRegion = (() => {\n if (hunk !== state.finalHunk || !hasFinalCollapsedHunk(diff)) {\n return undefined;\n }\n const additionRemaining =\n diff.additionLines.length -\n (hunk.additionLineIndex + hunk.additionCount);\n const deletionRemaining =\n diff.deletionLines.length -\n (hunk.deletionLineIndex + hunk.deletionCount);\n\n if (additionRemaining !== deletionRemaining) {\n throw new Error(\n `iterateOverDiff: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${diff.name}`\n );\n }\n const trailingRangeSize = Math.min(additionRemaining, deletionRemaining);\n return getExpandedRegion(\n diff.isPartial,\n trailingRangeSize,\n expandedHunks,\n // hunkIndex for trailing region\n diff.hunks.length,\n collapsedContextThreshold\n );\n })();\n const expandedLineCount = leadingRegion.fromStart + leadingRegion.fromEnd;\n\n function getTrailingCollapsedAfter(\n unifiedLineIndex: number,\n splitLineIndex: number\n ) {\n if (\n trailingRegion == null ||\n trailingRegion.collapsedLines <= 0 ||\n trailingRegion.fromStart + trailingRegion.fromEnd > 0\n ) {\n return 0;\n }\n if (diffStyle === 'unified') {\n return unifiedLineIndex ===\n hunk.unifiedLineStart + hunk.unifiedLineCount - 1\n ? trailingRegion.collapsedLines\n : 0;\n }\n return splitLineIndex === hunk.splitLineStart + hunk.splitLineCount - 1\n ? trailingRegion.collapsedLines\n : 0;\n }\n function getPendingCollapsed() {\n if (leadingRegion.collapsedLines === 0) {\n return 0;\n }\n const value = leadingRegion.collapsedLines;\n leadingRegion.collapsedLines = 0;\n return value;\n }\n\n // Emit for expanded lines\n if (!state.shouldSkip(expandedLineCount, expandedLineCount)) {\n let unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.rangeSize;\n let splitLineIndex = hunk.splitLineStart - leadingRegion.rangeSize;\n\n let deletionLineIndex = hunk.deletionLineIndex - leadingRegion.rangeSize;\n let additionLineIndex = hunk.additionLineIndex - leadingRegion.rangeSize;\n let deletionLineNumber = hunk.deletionStart - leadingRegion.rangeSize;\n let additionLineNumber = hunk.additionStart - leadingRegion.rangeSize;\n\n let index = 0;\n // FIXME: add skip\n while (index < leadingRegion.fromStart) {\n if (state.isInWindow(0, 0)) {\n if (\n state.emit({\n hunkIndex,\n hunk: hunk,\n collapsedBefore: 0,\n collapsedAfter: 0,\n // NOTE(amadeus): Pretty sure this is would never return a value,\n // so lets not call it, but if i notice a bug, i may need to\n // bring this back.\n // collapsedAfter: getTrailingCollapsedAfter(\n // unifiedRowIndex,\n // splitRowIndex\n // ),\n unifiedDeletionLineIndex: unifiedLineIndex + index,\n unifiedAdditionLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n deletionLineIndex: deletionLineIndex + index,\n additionLineIndex: additionLineIndex + index,\n deletionLineNumber: deletionLineNumber + index,\n additionLineNumber: additionLineNumber + index,\n type: 'context-expanded',\n noEOFCRAddition: false,\n noEOFCRDeletion: false,\n })\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(1, 1);\n }\n index++;\n }\n\n unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.fromEnd;\n splitLineIndex = hunk.splitLineStart - leadingRegion.fromEnd;\n\n deletionLineIndex = hunk.deletionLineIndex - leadingRegion.fromEnd;\n additionLineIndex = hunk.additionLineIndex - leadingRegion.fromEnd;\n deletionLineNumber = hunk.deletionStart - leadingRegion.fromEnd;\n additionLineNumber = hunk.additionStart - leadingRegion.fromEnd;\n index = 0;\n\n // FIXME(amadeus): Implement a skip if needed\n while (index < leadingRegion.fromEnd) {\n if (state.isInWindow(0, 0)) {\n if (\n state.emit({\n hunkIndex,\n hunk,\n collapsedBefore: getPendingCollapsed(),\n collapsedAfter: 0,\n // NOTE(amadeus): Pretty sure this is would never return a value,\n // so lets not call it, but if i notice a bug, i may need to\n // bring this back.\n // collapsedAfter: getTrailingCollapsedAfter(\n // unifiedRowIndex,\n // splitRowIndex\n // ),\n unifiedDeletionLineIndex: unifiedLineIndex + index,\n unifiedAdditionLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n deletionLineIndex: deletionLineIndex + index,\n additionLineIndex: additionLineIndex + index,\n deletionLineNumber: deletionLineNumber + index,\n additionLineNumber: additionLineNumber + index,\n type: 'context-expanded',\n noEOFCRAddition: false,\n noEOFCRDeletion: false,\n })\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(1, 1);\n }\n index++;\n }\n } else {\n state.incrementCounts(expandedLineCount, expandedLineCount);\n getPendingCollapsed();\n }\n\n let unifiedLineIndex = hunk.unifiedLineStart;\n let splitLineIndex = hunk.splitLineStart;\n\n let deletionLineIndex = hunk.deletionLineIndex;\n let additionLineIndex = hunk.additionLineIndex;\n let deletionLineNumber = hunk.deletionStart;\n let additionLineNumber = hunk.additionStart;\n const lastContent = hunk.hunkContent.at(-1);\n\n for (const content of hunk.hunkContent) {\n if (state.shouldBreak()) {\n break hunkIterator;\n }\n\n const isLastContent = content === lastContent;\n\n // Hunk Context Content\n if (content.type === 'context') {\n if (!state.shouldSkip(content.lines, content.lines)) {\n let index = 0;\n // FIXME: add a skip if we aren't rendering all the lines\n while (index < content.lines) {\n if (state.isInWindow(0, 0)) {\n const isLastLine = isLastContent && index === content.lines - 1;\n const unifiedRowIndex = unifiedLineIndex + index;\n const splitRowIndex = splitLineIndex + index;\n if (\n state.emit({\n hunkIndex,\n hunk,\n collapsedBefore: getPendingCollapsed(),\n collapsedAfter: getTrailingCollapsedAfter(\n unifiedRowIndex,\n splitRowIndex\n ),\n unifiedDeletionLineIndex: unifiedRowIndex,\n unifiedAdditionLineIndex: unifiedRowIndex,\n splitLineIndex: splitRowIndex,\n deletionLineIndex: deletionLineIndex + index,\n additionLineIndex: additionLineIndex + index,\n deletionLineNumber: deletionLineNumber + index,\n additionLineNumber: additionLineNumber + index,\n type: 'context',\n noEOFCRAddition: isLastLine && hunk.noEOFCRAdditions,\n noEOFCRDeletion: isLastLine && hunk.noEOFCRDeletions,\n })\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(1, 1);\n }\n index++;\n }\n } else {\n state.incrementCounts(content.lines, content.lines);\n getPendingCollapsed();\n }\n unifiedLineIndex += content.lines;\n splitLineIndex += content.lines;\n\n deletionLineIndex += content.lines;\n additionLineIndex += content.lines;\n deletionLineNumber += content.lines;\n additionLineNumber += content.lines;\n }\n // Hunk Change Content\n else {\n const splitCount = Math.max(content.deletions, content.additions);\n const unifiedCount = content.deletions + content.additions;\n const shouldSkipChange = state.shouldSkip(unifiedCount, splitCount);\n if (!shouldSkipChange) {\n const iterationRanges = getChangeIterationRanges(\n state,\n content,\n diffStyle\n );\n\n // No need for any skipping because the render ranges skip for us\n for (const [rangeStart, rangeEnd] of iterationRanges) {\n for (let index = rangeStart; index < rangeEnd; index++) {\n const unifiedRowIndex = unifiedLineIndex + index;\n const splitRowIndex =\n diffStyle === 'unified'\n ? splitLineIndex +\n (index < content.deletions\n ? index\n : index - content.deletions)\n : splitLineIndex + index;\n const collapsedAfter = getTrailingCollapsedAfter(\n unifiedRowIndex,\n splitRowIndex\n );\n if (\n state.emit(\n getChangeLineData({\n hunkIndex,\n hunk,\n collapsedBefore: getPendingCollapsed(),\n collapsedAfter,\n diffStyle,\n index,\n unifiedLineIndex,\n splitLineIndex,\n additionLineIndex,\n deletionLineIndex,\n additionLineNumber,\n deletionLineNumber,\n content,\n isLastContent,\n unifiedCount,\n splitCount,\n }),\n true\n )\n ) {\n break hunkIterator;\n }\n }\n }\n }\n\n getPendingCollapsed();\n state.incrementCounts(unifiedCount, splitCount);\n unifiedLineIndex += unifiedCount;\n splitLineIndex += splitCount;\n deletionLineIndex += content.deletions;\n additionLineIndex += content.additions;\n deletionLineNumber += content.deletions;\n additionLineNumber += content.additions;\n }\n }\n\n if (trailingRegion != null) {\n const { collapsedLines, fromStart, fromEnd } = trailingRegion;\n const len = fromStart + fromEnd;\n let index = 0;\n // FIXME: add a skip\n while (index < len) {\n if (state.shouldBreak()) {\n break hunkIterator;\n }\n if (state.isInWindow(0, 0)) {\n const isLastLine = index === len - 1;\n if (\n state.emit({\n hunkIndex: diff.hunks.length,\n hunk: undefined,\n collapsedBefore: 0,\n collapsedAfter: isLastLine ? collapsedLines : 0,\n unifiedDeletionLineIndex: unifiedLineIndex + index,\n unifiedAdditionLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n additionLineIndex: additionLineIndex + index,\n deletionLineIndex: deletionLineIndex + index,\n additionLineNumber: additionLineNumber + index,\n deletionLineNumber: deletionLineNumber + index,\n type: 'context-expanded',\n noEOFCRAddition: false,\n noEOFCRDeletion: false,\n })\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(1, 1);\n }\n index++;\n }\n }\n }\n}\n\ninterface ExpandedRegionResult {\n fromStart: number;\n fromEnd: number;\n rangeSize: number;\n collapsedLines: number;\n}\n\nfunction getExpandedRegion(\n isPartial: boolean,\n rangeSize: number,\n expandedHunks: Map<number, HunkExpansionRegion> | true | undefined,\n hunkIndex: number,\n collapsedContextThreshold: number\n): ExpandedRegionResult {\n rangeSize = Math.max(rangeSize, 0);\n if (rangeSize === 0 || isPartial) {\n return {\n fromStart: 0,\n fromEnd: 0,\n rangeSize,\n collapsedLines: Math.max(rangeSize, 0),\n };\n }\n if (expandedHunks === true || rangeSize <= collapsedContextThreshold) {\n return {\n fromStart: rangeSize,\n fromEnd: 0,\n rangeSize,\n collapsedLines: 0,\n };\n }\n const region = expandedHunks?.get(hunkIndex);\n const fromStart = Math.min(Math.max(region?.fromStart ?? 0, 0), rangeSize);\n const fromEnd = Math.min(Math.max(region?.fromEnd ?? 0, 0), rangeSize);\n const expandedCount = fromStart + fromEnd;\n const renderAll = expandedCount >= rangeSize;\n return {\n fromStart: renderAll ? rangeSize : fromStart,\n fromEnd: renderAll ? 0 : fromEnd,\n rangeSize,\n collapsedLines: Math.max(rangeSize - expandedCount, 0),\n };\n}\n\nfunction hasFinalCollapsedHunk(diff: FileDiffMetadata): boolean {\n const lastHunk = diff.hunks.at(-1);\n if (\n lastHunk == null ||\n diff.isPartial ||\n diff.additionLines.length === 0 ||\n diff.deletionLines.length === 0\n ) {\n return false;\n }\n return (\n lastHunk.additionLineIndex + lastHunk.additionCount <\n diff.additionLines.length ||\n lastHunk.deletionLineIndex + lastHunk.deletionCount <\n diff.deletionLines.length\n );\n}\n\n// The intention of this function is to grab the appropriate windowed ranges of\n// the change content. If diffStyle is both, we will iterate AS split, however\n// we will encompass all needed lines to allow us to render split or unified\nfunction getChangeIterationRanges(\n state: IterationState,\n content: ChangeContent,\n diffStyle: 'split' | 'unified' | 'both'\n): [number, number][] {\n // If not a window highlight, then we should just render the entire range\n if (!state.isWindowedHighlight) {\n return [\n [\n 0,\n diffStyle === 'unified'\n ? content.deletions + content.additions\n : Math.max(content.deletions, content.additions),\n ],\n ];\n }\n const useUnified = diffStyle !== 'split';\n const useSplit = diffStyle !== 'unified';\n const iterationSpace = diffStyle === 'unified' ? 'unified' : 'split';\n const iterationRanges: [number, number][] = [];\n function getVisibleRange(\n start: number,\n count: number\n ): [number, number] | undefined {\n const end = start + count;\n if (end <= state.viewportStart || start >= state.viewportEnd) {\n return undefined;\n }\n const visibleStart = Math.max(0, state.viewportStart - start);\n const visibleEnd = Math.min(count, state.viewportEnd - start);\n return visibleEnd > visibleStart ? [visibleStart, visibleEnd] : undefined;\n }\n function mapRangeToIteration(\n range: [number, number],\n kind: 'deletions' | 'additions'\n ): [number, number] {\n if (iterationSpace === 'split') {\n // For split iteration, additions/deletions are already in split row space.\n return range;\n }\n return kind === 'additions'\n ? [range[0] + content.deletions, range[1] + content.deletions]\n : range;\n }\n function pushRange(\n range: [number, number] | undefined,\n kind: 'deletions' | 'additions'\n ) {\n if (range == null) {\n return;\n }\n const [start, end] = mapRangeToIteration(range, kind);\n if (end > start) {\n iterationRanges.push([start, end]);\n }\n }\n\n if (useUnified) {\n pushRange(\n getVisibleRange(state.unifiedCount, content.deletions),\n 'deletions'\n );\n pushRange(\n getVisibleRange(\n state.unifiedCount + content.deletions,\n content.additions\n ),\n 'additions'\n );\n }\n\n if (useSplit) {\n pushRange(\n getVisibleRange(state.splitCount, content.deletions),\n 'deletions'\n );\n pushRange(\n getVisibleRange(state.splitCount, content.additions),\n 'additions'\n );\n }\n\n if (iterationRanges.length === 0) {\n return iterationRanges;\n }\n\n iterationRanges.sort((a, b) => a[0] - b[0]);\n const merged: [number, number][] = [iterationRanges[0]];\n for (const [start, end] of iterationRanges.slice(1)) {\n const last = merged[merged.length - 1];\n if (start <= last[1]) {\n last[1] = Math.max(last[1], end);\n } else {\n merged.push([start, end]);\n }\n }\n\n return merged;\n}\n\ninterface GetChangeLineDataProps {\n hunkIndex: number;\n hunk: Hunk;\n collapsedBefore: number;\n collapsedAfter: number;\n diffStyle: 'split' | 'unified' | 'both';\n index: number;\n unifiedLineIndex: number;\n splitLineIndex: number;\n additionLineIndex: number;\n additionLineNumber: number;\n deletionLineNumber: number;\n deletionLineIndex: number;\n content: ChangeContent;\n isLastContent: boolean;\n unifiedCount: number;\n splitCount: number;\n}\n\n// NOTE(amadeus): It's quite tedious to grab the appropriate line info and\n// related props for change content regions, so I made it a specialized\n// function to help make the main hunkIterator easy to reason about\nfunction getChangeLineData({\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n diffStyle,\n index,\n unifiedLineIndex,\n splitLineIndex,\n additionLineIndex,\n deletionLineIndex,\n additionLineNumber,\n deletionLineNumber,\n content,\n isLastContent,\n unifiedCount,\n splitCount,\n}: GetChangeLineDataProps): DiffLineCallbackProps {\n if (diffStyle === 'unified') {\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n unifiedDeletionLineIndex:\n index < content.deletions ? unifiedLineIndex + index : undefined,\n unifiedAdditionLineIndex:\n index >= content.deletions ? unifiedLineIndex + index : undefined,\n splitLineIndex:\n splitLineIndex +\n (index < content.deletions ? index : index - content.deletions),\n additionLineIndex:\n index >= content.deletions\n ? additionLineIndex + (index - content.deletions)\n : undefined,\n additionLineNumber:\n index >= content.deletions\n ? additionLineNumber + (index - content.deletions)\n : undefined,\n deletionLineIndex:\n index < content.deletions ? deletionLineIndex + index : undefined,\n deletionLineNumber:\n index < content.deletions ? deletionLineNumber + index : undefined,\n noEOFCRDeletion:\n isLastContent &&\n index === content.deletions - 1 &&\n hunk.noEOFCRDeletions,\n noEOFCRAddition:\n isLastContent && index === unifiedCount - 1 && hunk.noEOFCRAdditions,\n };\n }\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n unifiedDeletionLineIndex:\n index < content.deletions ? unifiedLineIndex + index : undefined,\n unifiedAdditionLineIndex:\n index < content.additions\n ? unifiedLineIndex + content.deletions + index\n : undefined,\n splitLineIndex: splitLineIndex + index,\n additionLineIndex:\n index < content.additions ? additionLineIndex + index : undefined,\n additionLineNumber:\n index < content.additions ? additionLineNumber + index : undefined,\n deletionLineIndex:\n index < content.deletions ? deletionLineIndex + index : undefined,\n deletionLineNumber:\n index < content.deletions ? deletionLineNumber + index : undefined,\n noEOFCRDeletion:\n isLastContent && index === splitCount - 1 && hunk.noEOFCRDeletions,\n noEOFCRAddition:\n isLastContent && index === splitCount - 1 && hunk.noEOFCRAdditions,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"iterateOverDiff.js","names":["state: IterationState","unifiedLineIndex","splitLineIndex","deletionLineIndex","additionLineIndex","deletionLineNumber","additionLineNumber","iterationRanges: [number, number][]","merged: [number, number][]","deletionLine: DiffLineMetadata | undefined","additionLine: DiffLineMetadata | undefined"],"sources":["../../src/utils/iterateOverDiff.ts"],"sourcesContent":["import { DEFAULT_COLLAPSED_CONTEXT_THRESHOLD } from '../constants';\nimport type {\n ChangeContent,\n FileDiffMetadata,\n Hunk,\n HunkExpansionRegion,\n} from '../types';\n\nexport interface DiffLineMetadata {\n unifiedLineIndex: number;\n splitLineIndex: number;\n lineIndex: number;\n lineNumber: number;\n noEOFCR: boolean;\n}\n\nexport interface DiffLineCallbackBase {\n hunkIndex: number;\n hunk: Hunk | undefined; // undefined for trailing expansion region\n collapsedBefore: number; // > 0 means separator before this line, value = hidden lines\n collapsedAfter: number; // > 0 only on final line if trailing collapsed content\n}\n\ninterface DiffLineCallbackContextChange extends DiffLineCallbackBase {\n type: 'change' | 'context' | 'context-expanded';\n deletionLine: DiffLineMetadata;\n additionLine: DiffLineMetadata;\n}\n\ninterface DiffLineCallbackChangeDeletion extends DiffLineCallbackBase {\n type: 'change';\n deletionLine: DiffLineMetadata;\n additionLine?: undefined;\n}\n\ninterface DiffLineCallbackChangeAddition extends DiffLineCallbackBase {\n type: 'change';\n deletionLine?: undefined;\n additionLine: DiffLineMetadata;\n}\n\nexport type DiffLineCallbackProps =\n | DiffLineCallbackContextChange\n | DiffLineCallbackChangeDeletion\n | DiffLineCallbackChangeAddition;\n\ninterface IterationState {\n finalHunk: Hunk | undefined;\n isWindowedHighlight: boolean;\n viewportStart: number;\n viewportEnd: number;\n splitCount: number;\n unifiedCount: number;\n shouldBreak(): boolean;\n shouldSkip(unifiedHeight: number, splitHeight: number): boolean;\n incrementCounts(unifiedValue: number, splitValue: number): void;\n isInWindow(unifiedHeight: number, splitHeight: number): boolean;\n isInUnifiedWindow(height: number): boolean;\n isInSplitWindow(height: number): boolean;\n emit(props: DiffLineCallbackProps, silent?: boolean): boolean;\n}\n\nexport type DiffLineCallback = (props: DiffLineCallbackProps) => boolean | void;\n\nexport interface IterateOverDiffProps {\n diff: FileDiffMetadata;\n diffStyle: 'unified' | 'split' | 'both';\n startingLine?: number;\n totalLines?: number;\n expandedHunks?: Map<number, HunkExpansionRegion> | true;\n collapsedContextThreshold?: number;\n callback: DiffLineCallback;\n}\n\nexport function iterateOverDiff({\n diff,\n diffStyle,\n startingLine = 0,\n totalLines = Infinity,\n expandedHunks,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n callback,\n}: IterateOverDiffProps): void {\n const state: IterationState = {\n finalHunk: diff.hunks.at(-1),\n viewportStart: startingLine,\n viewportEnd: startingLine + totalLines,\n isWindowedHighlight: startingLine > 0 || totalLines < Infinity,\n splitCount: 0,\n unifiedCount: 0,\n shouldBreak() {\n if (!state.isWindowedHighlight) {\n return false;\n }\n\n const breakUnified = state.unifiedCount >= startingLine + totalLines;\n const breakSplit = state.splitCount >= startingLine + totalLines;\n\n if (diffStyle === 'unified') {\n return breakUnified;\n } else if (diffStyle === 'split') {\n return breakSplit;\n } else {\n return breakUnified && breakSplit;\n }\n },\n shouldSkip(unifiedHeight: number, splitHeight: number) {\n if (!state.isWindowedHighlight) {\n return false;\n }\n\n const skipUnified = state.unifiedCount + unifiedHeight < startingLine;\n const skipSplit = state.splitCount + splitHeight < startingLine;\n\n if (diffStyle === 'unified') {\n return skipUnified;\n } else if (diffStyle === 'split') {\n return skipSplit;\n } else {\n return skipUnified && skipSplit;\n }\n },\n incrementCounts(unifiedValue: number, splitValue: number) {\n if (diffStyle === 'unified' || diffStyle === 'both') {\n state.unifiedCount += unifiedValue;\n }\n if (diffStyle === 'split' || diffStyle === 'both') {\n state.splitCount += splitValue;\n }\n },\n isInWindow(unifiedHeight: number, splitHeight: number) {\n if (!state.isWindowedHighlight) {\n return true;\n }\n\n const unifiedInWindow = state.isInUnifiedWindow(unifiedHeight);\n const splitInWindow = state.isInSplitWindow(splitHeight);\n\n if (diffStyle === 'unified') {\n return unifiedInWindow;\n } else if (diffStyle === 'split') {\n return splitInWindow;\n } else {\n return unifiedInWindow || splitInWindow;\n }\n },\n isInUnifiedWindow(unifiedHeight: number) {\n return (\n !state.isWindowedHighlight ||\n (state.unifiedCount >= startingLine - unifiedHeight &&\n state.unifiedCount < startingLine + totalLines)\n );\n },\n isInSplitWindow(splitHeight: number) {\n return (\n !state.isWindowedHighlight ||\n (state.splitCount >= startingLine - splitHeight &&\n state.splitCount < startingLine + totalLines)\n );\n },\n emit(props: DiffLineCallbackProps, silent = false): boolean {\n if (!silent) {\n if (diffStyle === 'unified') {\n state.incrementCounts(1, 0);\n } else if (diffStyle === 'split') {\n state.incrementCounts(0, 1);\n } else {\n state.incrementCounts(1, 1);\n // FIXME MAYBE\n // state.incrementCounts(\n // state.isInUnifiedWindow(0) ? 1 : 0,\n // state.isInSplitWindow(0) ? 1 : 0\n // );\n }\n }\n return callback(props) ?? false;\n },\n };\n\n hunkIterator: for (const [hunkIndex, hunk] of diff.hunks.entries()) {\n if (state.shouldBreak()) {\n break;\n }\n\n const leadingRegion = getExpandedRegion(\n diff.isPartial,\n hunk.collapsedBefore,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold\n );\n // We only create a trailing region if it's the last hunk\n const trailingRegion = (() => {\n if (hunk !== state.finalHunk || !hasFinalCollapsedHunk(diff)) {\n return undefined;\n }\n const additionRemaining =\n diff.additionLines.length -\n (hunk.additionLineIndex + hunk.additionCount);\n const deletionRemaining =\n diff.deletionLines.length -\n (hunk.deletionLineIndex + hunk.deletionCount);\n\n if (additionRemaining !== deletionRemaining) {\n throw new Error(\n `iterateOverDiff: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${diff.name}`\n );\n }\n const trailingRangeSize = Math.min(additionRemaining, deletionRemaining);\n return getExpandedRegion(\n diff.isPartial,\n trailingRangeSize,\n expandedHunks,\n // hunkIndex for trailing region\n diff.hunks.length,\n collapsedContextThreshold\n );\n })();\n const expandedLineCount = leadingRegion.fromStart + leadingRegion.fromEnd;\n\n function getTrailingCollapsedAfter(\n unifiedLineIndex: number,\n splitLineIndex: number\n ) {\n if (\n trailingRegion == null ||\n trailingRegion.collapsedLines <= 0 ||\n trailingRegion.fromStart + trailingRegion.fromEnd > 0\n ) {\n return 0;\n }\n if (diffStyle === 'unified') {\n return unifiedLineIndex ===\n hunk.unifiedLineStart + hunk.unifiedLineCount - 1\n ? trailingRegion.collapsedLines\n : 0;\n }\n return splitLineIndex === hunk.splitLineStart + hunk.splitLineCount - 1\n ? trailingRegion.collapsedLines\n : 0;\n }\n function getPendingCollapsed() {\n if (leadingRegion.collapsedLines === 0) {\n return 0;\n }\n const value = leadingRegion.collapsedLines;\n leadingRegion.collapsedLines = 0;\n return value;\n }\n\n // Emit for expanded lines\n if (!state.shouldSkip(expandedLineCount, expandedLineCount)) {\n let unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.rangeSize;\n let splitLineIndex = hunk.splitLineStart - leadingRegion.rangeSize;\n\n let deletionLineIndex = hunk.deletionLineIndex - leadingRegion.rangeSize;\n let additionLineIndex = hunk.additionLineIndex - leadingRegion.rangeSize;\n let deletionLineNumber = hunk.deletionStart - leadingRegion.rangeSize;\n let additionLineNumber = hunk.additionStart - leadingRegion.rangeSize;\n\n let index = 0;\n // FIXME: add skip\n while (index < leadingRegion.fromStart) {\n if (state.isInWindow(0, 0)) {\n if (\n state.emit({\n hunkIndex,\n hunk: hunk,\n collapsedBefore: 0,\n collapsedAfter: 0,\n // NOTE(amadeus): Pretty sure this is would never return a value,\n // so lets not call it, but if i notice a bug, i may need to\n // bring this back.\n // collapsedAfter: getTrailingCollapsedAfter(\n // unifiedRowIndex,\n // splitRowIndex\n // ),\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n })\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(1, 1);\n }\n index++;\n }\n\n unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.fromEnd;\n splitLineIndex = hunk.splitLineStart - leadingRegion.fromEnd;\n\n deletionLineIndex = hunk.deletionLineIndex - leadingRegion.fromEnd;\n additionLineIndex = hunk.additionLineIndex - leadingRegion.fromEnd;\n deletionLineNumber = hunk.deletionStart - leadingRegion.fromEnd;\n additionLineNumber = hunk.additionStart - leadingRegion.fromEnd;\n index = 0;\n\n // FIXME(amadeus): Implement a skip if needed\n while (index < leadingRegion.fromEnd) {\n if (state.isInWindow(0, 0)) {\n if (\n state.emit({\n hunkIndex,\n hunk,\n collapsedBefore: getPendingCollapsed(),\n collapsedAfter: 0,\n // NOTE(amadeus): Pretty sure this is would never return a value,\n // so lets not call it, but if i notice a bug, i may need to\n // bring this back.\n // collapsedAfter: getTrailingCollapsedAfter(\n // unifiedRowIndex,\n // splitRowIndex\n // ),\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n })\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(1, 1);\n }\n index++;\n }\n } else {\n state.incrementCounts(expandedLineCount, expandedLineCount);\n getPendingCollapsed();\n }\n\n let unifiedLineIndex = hunk.unifiedLineStart;\n let splitLineIndex = hunk.splitLineStart;\n\n let deletionLineIndex = hunk.deletionLineIndex;\n let additionLineIndex = hunk.additionLineIndex;\n let deletionLineNumber = hunk.deletionStart;\n let additionLineNumber = hunk.additionStart;\n const lastContent = hunk.hunkContent.at(-1);\n\n for (const content of hunk.hunkContent) {\n if (state.shouldBreak()) {\n break hunkIterator;\n }\n\n const isLastContent = content === lastContent;\n\n // Hunk Context Content\n if (content.type === 'context') {\n if (!state.shouldSkip(content.lines, content.lines)) {\n let index = 0;\n // FIXME: add a skip if we aren't rendering all the lines\n while (index < content.lines) {\n if (state.isInWindow(0, 0)) {\n const isLastLine = isLastContent && index === content.lines - 1;\n const unifiedRowIndex = unifiedLineIndex + index;\n const splitRowIndex = splitLineIndex + index;\n if (\n state.emit({\n hunkIndex,\n hunk,\n collapsedBefore: getPendingCollapsed(),\n collapsedAfter: getTrailingCollapsedAfter(\n unifiedRowIndex,\n splitRowIndex\n ),\n type: 'context',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: isLastLine && hunk.noEOFCRDeletions,\n unifiedLineIndex: unifiedRowIndex,\n splitLineIndex: splitRowIndex,\n },\n additionLine: {\n unifiedLineIndex: unifiedRowIndex,\n splitLineIndex: splitRowIndex,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: isLastLine && hunk.noEOFCRAdditions,\n },\n })\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(1, 1);\n }\n index++;\n }\n } else {\n state.incrementCounts(content.lines, content.lines);\n getPendingCollapsed();\n }\n unifiedLineIndex += content.lines;\n splitLineIndex += content.lines;\n\n deletionLineIndex += content.lines;\n additionLineIndex += content.lines;\n deletionLineNumber += content.lines;\n additionLineNumber += content.lines;\n }\n // Hunk Change Content\n else {\n const splitCount = Math.max(content.deletions, content.additions);\n const unifiedCount = content.deletions + content.additions;\n const shouldSkipChange = state.shouldSkip(unifiedCount, splitCount);\n if (!shouldSkipChange) {\n const iterationRanges = getChangeIterationRanges(\n state,\n content,\n diffStyle\n );\n\n // No need for any skipping because the render ranges skip for us\n for (const [rangeStart, rangeEnd] of iterationRanges) {\n for (let index = rangeStart; index < rangeEnd; index++) {\n const unifiedRowIndex = unifiedLineIndex + index;\n const splitRowIndex =\n diffStyle === 'unified'\n ? splitLineIndex +\n (index < content.deletions\n ? index\n : index - content.deletions)\n : splitLineIndex + index;\n const collapsedAfter = getTrailingCollapsedAfter(\n unifiedRowIndex,\n splitRowIndex\n );\n if (\n state.emit(\n getChangeLineData({\n hunkIndex,\n hunk,\n collapsedBefore: getPendingCollapsed(),\n collapsedAfter,\n diffStyle,\n index,\n unifiedLineIndex,\n splitLineIndex,\n additionLineIndex,\n deletionLineIndex,\n additionLineNumber,\n deletionLineNumber,\n content,\n isLastContent,\n unifiedCount,\n splitCount,\n }),\n true\n )\n ) {\n break hunkIterator;\n }\n }\n }\n }\n\n getPendingCollapsed();\n state.incrementCounts(unifiedCount, splitCount);\n unifiedLineIndex += unifiedCount;\n splitLineIndex += splitCount;\n deletionLineIndex += content.deletions;\n additionLineIndex += content.additions;\n deletionLineNumber += content.deletions;\n additionLineNumber += content.additions;\n }\n }\n\n if (trailingRegion != null) {\n const { collapsedLines, fromStart, fromEnd } = trailingRegion;\n const len = fromStart + fromEnd;\n let index = 0;\n // FIXME: add a skip\n while (index < len) {\n if (state.shouldBreak()) {\n break hunkIterator;\n }\n if (state.isInWindow(0, 0)) {\n const isLastLine = index === len - 1;\n if (\n state.emit({\n hunkIndex: diff.hunks.length,\n hunk: undefined,\n collapsedBefore: 0,\n collapsedAfter: isLastLine ? collapsedLines : 0,\n type: 'context-expanded',\n // NOTE(amadeus): Maybe create an object cache for this to reduce\n // garbage collection?\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n })\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(1, 1);\n }\n index++;\n }\n }\n }\n}\n\ninterface ExpandedRegionResult {\n fromStart: number;\n fromEnd: number;\n rangeSize: number;\n collapsedLines: number;\n}\n\nfunction getExpandedRegion(\n isPartial: boolean,\n rangeSize: number,\n expandedHunks: Map<number, HunkExpansionRegion> | true | undefined,\n hunkIndex: number,\n collapsedContextThreshold: number\n): ExpandedRegionResult {\n rangeSize = Math.max(rangeSize, 0);\n if (rangeSize === 0 || isPartial) {\n return {\n fromStart: 0,\n fromEnd: 0,\n rangeSize,\n collapsedLines: Math.max(rangeSize, 0),\n };\n }\n if (expandedHunks === true || rangeSize <= collapsedContextThreshold) {\n return {\n fromStart: rangeSize,\n fromEnd: 0,\n rangeSize,\n collapsedLines: 0,\n };\n }\n const region = expandedHunks?.get(hunkIndex);\n const fromStart = Math.min(Math.max(region?.fromStart ?? 0, 0), rangeSize);\n const fromEnd = Math.min(Math.max(region?.fromEnd ?? 0, 0), rangeSize);\n const expandedCount = fromStart + fromEnd;\n const renderAll = expandedCount >= rangeSize;\n return {\n fromStart: renderAll ? rangeSize : fromStart,\n fromEnd: renderAll ? 0 : fromEnd,\n rangeSize,\n collapsedLines: Math.max(rangeSize - expandedCount, 0),\n };\n}\n\nfunction hasFinalCollapsedHunk(diff: FileDiffMetadata): boolean {\n const lastHunk = diff.hunks.at(-1);\n if (\n lastHunk == null ||\n diff.isPartial ||\n diff.additionLines.length === 0 ||\n diff.deletionLines.length === 0\n ) {\n return false;\n }\n return (\n lastHunk.additionLineIndex + lastHunk.additionCount <\n diff.additionLines.length ||\n lastHunk.deletionLineIndex + lastHunk.deletionCount <\n diff.deletionLines.length\n );\n}\n\n// The intention of this function is to grab the appropriate windowed ranges of\n// the change content. If diffStyle is both, we will iterate AS split, however\n// we will encompass all needed lines to allow us to render split or unified\nfunction getChangeIterationRanges(\n state: IterationState,\n content: ChangeContent,\n diffStyle: 'split' | 'unified' | 'both'\n): [number, number][] {\n // If not a window highlight, then we should just render the entire range\n if (!state.isWindowedHighlight) {\n return [\n [\n 0,\n diffStyle === 'unified'\n ? content.deletions + content.additions\n : Math.max(content.deletions, content.additions),\n ],\n ];\n }\n const useUnified = diffStyle !== 'split';\n const useSplit = diffStyle !== 'unified';\n const iterationSpace = diffStyle === 'unified' ? 'unified' : 'split';\n const iterationRanges: [number, number][] = [];\n function getVisibleRange(\n start: number,\n count: number\n ): [number, number] | undefined {\n const end = start + count;\n if (end <= state.viewportStart || start >= state.viewportEnd) {\n return undefined;\n }\n const visibleStart = Math.max(0, state.viewportStart - start);\n const visibleEnd = Math.min(count, state.viewportEnd - start);\n return visibleEnd > visibleStart ? [visibleStart, visibleEnd] : undefined;\n }\n function mapRangeToIteration(\n range: [number, number],\n kind: 'deletions' | 'additions'\n ): [number, number] {\n if (iterationSpace === 'split') {\n // For split iteration, additions/deletions are already in split row space.\n return range;\n }\n return kind === 'additions'\n ? [range[0] + content.deletions, range[1] + content.deletions]\n : range;\n }\n function pushRange(\n range: [number, number] | undefined,\n kind: 'deletions' | 'additions'\n ) {\n if (range == null) {\n return;\n }\n const [start, end] = mapRangeToIteration(range, kind);\n if (end > start) {\n iterationRanges.push([start, end]);\n }\n }\n\n if (useUnified) {\n pushRange(\n getVisibleRange(state.unifiedCount, content.deletions),\n 'deletions'\n );\n pushRange(\n getVisibleRange(\n state.unifiedCount + content.deletions,\n content.additions\n ),\n 'additions'\n );\n }\n\n if (useSplit) {\n pushRange(\n getVisibleRange(state.splitCount, content.deletions),\n 'deletions'\n );\n pushRange(\n getVisibleRange(state.splitCount, content.additions),\n 'additions'\n );\n }\n\n if (iterationRanges.length === 0) {\n return iterationRanges;\n }\n\n iterationRanges.sort((a, b) => a[0] - b[0]);\n const merged: [number, number][] = [iterationRanges[0]];\n for (const [start, end] of iterationRanges.slice(1)) {\n const last = merged[merged.length - 1];\n if (start <= last[1]) {\n last[1] = Math.max(last[1], end);\n } else {\n merged.push([start, end]);\n }\n }\n\n return merged;\n}\n\ninterface GetChangeLineDataProps {\n hunkIndex: number;\n hunk: Hunk;\n collapsedBefore: number;\n collapsedAfter: number;\n diffStyle: 'split' | 'unified' | 'both';\n index: number;\n unifiedLineIndex: number;\n splitLineIndex: number;\n additionLineIndex: number;\n additionLineNumber: number;\n deletionLineNumber: number;\n deletionLineIndex: number;\n content: ChangeContent;\n isLastContent: boolean;\n unifiedCount: number;\n splitCount: number;\n}\n\n// NOTE(amadeus): It's quite tedious to grab the appropriate line info and\n// related props for change content regions, so I made it a specialized\n// function to help make the main hunkIterator easy to reason about\nfunction getChangeLineData({\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n diffStyle,\n index,\n unifiedLineIndex,\n splitLineIndex,\n additionLineIndex,\n deletionLineIndex,\n additionLineNumber,\n deletionLineNumber,\n content,\n isLastContent,\n unifiedCount,\n splitCount,\n}: GetChangeLineDataProps): DiffLineCallbackProps {\n const unifiedDeletionLineIndex =\n index < content.deletions ? unifiedLineIndex + index : undefined;\n const unifiedAdditionLineIndex =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? unifiedLineIndex + index\n : undefined\n : index < content.additions\n ? unifiedLineIndex + content.deletions + index\n : undefined;\n\n const resolvedSplitLineIndex =\n diffStyle === 'unified'\n ? splitLineIndex +\n (index < content.deletions ? index : index - content.deletions)\n : splitLineIndex + index;\n\n const deletionLineIndexValue =\n index < content.deletions ? deletionLineIndex + index : undefined;\n const deletionLineNumberValue =\n index < content.deletions ? deletionLineNumber + index : undefined;\n const additionLineIndexValue =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? additionLineIndex + (index - content.deletions)\n : undefined\n : index < content.additions\n ? additionLineIndex + index\n : undefined;\n const additionLineNumberValue =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? additionLineNumber + (index - content.deletions)\n : undefined\n : index < content.additions\n ? additionLineNumber + index\n : undefined;\n\n const noEOFCRDeletion =\n diffStyle === 'unified'\n ? isLastContent &&\n index === content.deletions - 1 &&\n hunk.noEOFCRDeletions\n : isLastContent && index === splitCount - 1 && hunk.noEOFCRDeletions;\n const noEOFCRAddition =\n diffStyle === 'unified'\n ? isLastContent && index === unifiedCount - 1 && hunk.noEOFCRAdditions\n : isLastContent && index === splitCount - 1 && hunk.noEOFCRAdditions;\n\n const deletionLine: DiffLineMetadata | undefined =\n deletionLineIndexValue != null &&\n deletionLineNumberValue != null &&\n unifiedDeletionLineIndex != null\n ? // NOTE(amadeus): Maybe create an object cache for this to reduce\n // garbage collection?\n {\n lineNumber: deletionLineNumberValue,\n lineIndex: deletionLineIndexValue,\n noEOFCR: noEOFCRDeletion,\n unifiedLineIndex: unifiedDeletionLineIndex,\n splitLineIndex: resolvedSplitLineIndex,\n }\n : undefined;\n const additionLine: DiffLineMetadata | undefined =\n additionLineIndexValue != null &&\n additionLineNumberValue != null &&\n unifiedAdditionLineIndex != null\n ? // NOTE(amadeus): Maybe create an object cache for this to reduce\n // garbage collection?\n {\n unifiedLineIndex: unifiedAdditionLineIndex,\n splitLineIndex: resolvedSplitLineIndex,\n lineIndex: additionLineIndexValue,\n lineNumber: additionLineNumberValue,\n noEOFCR: noEOFCRAddition,\n }\n : undefined;\n\n if (deletionLine == null && additionLine != null) {\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine: undefined,\n additionLine,\n };\n } else if (deletionLine != null && additionLine == null) {\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine,\n additionLine: undefined,\n };\n }\n\n if (deletionLine == null || additionLine == null) {\n throw new Error('iterateOverDiff: missing change line data');\n }\n\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine,\n additionLine,\n };\n}\n"],"mappings":";;;AA0EA,SAAgB,gBAAgB,EAC9B,MACA,WACA,eAAe,GACf,aAAa,UACb,eACA,4BAA4B,qCAC5B,YAC6B;CAC7B,MAAMA,QAAwB;EAC5B,WAAW,KAAK,MAAM,GAAG,GAAG;EAC5B,eAAe;EACf,aAAa,eAAe;EAC5B,qBAAqB,eAAe,KAAK,aAAa;EACtD,YAAY;EACZ,cAAc;EACd,cAAc;AACZ,OAAI,CAAC,MAAM,oBACT,QAAO;GAGT,MAAM,eAAe,MAAM,gBAAgB,eAAe;GAC1D,MAAM,aAAa,MAAM,cAAc,eAAe;AAEtD,OAAI,cAAc,UAChB,QAAO;YACE,cAAc,QACvB,QAAO;OAEP,QAAO,gBAAgB;;EAG3B,WAAW,eAAuB,aAAqB;AACrD,OAAI,CAAC,MAAM,oBACT,QAAO;GAGT,MAAM,cAAc,MAAM,eAAe,gBAAgB;GACzD,MAAM,YAAY,MAAM,aAAa,cAAc;AAEnD,OAAI,cAAc,UAChB,QAAO;YACE,cAAc,QACvB,QAAO;OAEP,QAAO,eAAe;;EAG1B,gBAAgB,cAAsB,YAAoB;AACxD,OAAI,cAAc,aAAa,cAAc,OAC3C,OAAM,gBAAgB;AAExB,OAAI,cAAc,WAAW,cAAc,OACzC,OAAM,cAAc;;EAGxB,WAAW,eAAuB,aAAqB;AACrD,OAAI,CAAC,MAAM,oBACT,QAAO;GAGT,MAAM,kBAAkB,MAAM,kBAAkB,cAAc;GAC9D,MAAM,gBAAgB,MAAM,gBAAgB,YAAY;AAExD,OAAI,cAAc,UAChB,QAAO;YACE,cAAc,QACvB,QAAO;OAEP,QAAO,mBAAmB;;EAG9B,kBAAkB,eAAuB;AACvC,UACE,CAAC,MAAM,uBACN,MAAM,gBAAgB,eAAe,iBACpC,MAAM,eAAe,eAAe;;EAG1C,gBAAgB,aAAqB;AACnC,UACE,CAAC,MAAM,uBACN,MAAM,cAAc,eAAe,eAClC,MAAM,aAAa,eAAe;;EAGxC,KAAK,OAA8B,SAAS,OAAgB;AAC1D,OAAI,CAAC,OACH,KAAI,cAAc,UAChB,OAAM,gBAAgB,GAAG,EAAE;YAClB,cAAc,QACvB,OAAM,gBAAgB,GAAG,EAAE;OAE3B,OAAM,gBAAgB,GAAG,EAAE;AAQ/B,UAAO,SAAS,MAAM,IAAI;;EAE7B;AAED,cAAc,MAAK,MAAM,CAAC,WAAW,SAAS,KAAK,MAAM,SAAS,EAAE;AAClE,MAAI,MAAM,aAAa,CACrB;EAGF,MAAM,gBAAgB,kBACpB,KAAK,WACL,KAAK,iBACL,eACA,WACA,0BACD;EAED,MAAM,wBAAwB;AAC5B,OAAI,SAAS,MAAM,aAAa,CAAC,sBAAsB,KAAK,CAC1D;GAEF,MAAM,oBACJ,KAAK,cAAc,UAClB,KAAK,oBAAoB,KAAK;GACjC,MAAM,oBACJ,KAAK,cAAc,UAClB,KAAK,oBAAoB,KAAK;AAEjC,OAAI,sBAAsB,kBACxB,OAAM,IAAI,MACR,yDAAyD,kBAAkB,cAAc,kBAAkB,QAAQ,KAAK,OACzH;GAEH,MAAM,oBAAoB,KAAK,IAAI,mBAAmB,kBAAkB;AACxE,UAAO,kBACL,KAAK,WACL,mBACA,eAEA,KAAK,MAAM,QACX,0BACD;MACC;EACJ,MAAM,oBAAoB,cAAc,YAAY,cAAc;EAElE,SAAS,0BACP,oBACA,kBACA;AACA,OACE,kBAAkB,QAClB,eAAe,kBAAkB,KACjC,eAAe,YAAY,eAAe,UAAU,EAEpD,QAAO;AAET,OAAI,cAAc,UAChB,QAAOC,uBACL,KAAK,mBAAmB,KAAK,mBAAmB,IAC9C,eAAe,iBACf;AAEN,UAAOC,qBAAmB,KAAK,iBAAiB,KAAK,iBAAiB,IAClE,eAAe,iBACf;;EAEN,SAAS,sBAAsB;AAC7B,OAAI,cAAc,mBAAmB,EACnC,QAAO;GAET,MAAM,QAAQ,cAAc;AAC5B,iBAAc,iBAAiB;AAC/B,UAAO;;AAIT,MAAI,CAAC,MAAM,WAAW,mBAAmB,kBAAkB,EAAE;GAC3D,IAAID,qBAAmB,KAAK,mBAAmB,cAAc;GAC7D,IAAIC,mBAAiB,KAAK,iBAAiB,cAAc;GAEzD,IAAIC,sBAAoB,KAAK,oBAAoB,cAAc;GAC/D,IAAIC,sBAAoB,KAAK,oBAAoB,cAAc;GAC/D,IAAIC,uBAAqB,KAAK,gBAAgB,cAAc;GAC5D,IAAIC,uBAAqB,KAAK,gBAAgB,cAAc;GAE5D,IAAI,QAAQ;AAEZ,UAAO,QAAQ,cAAc,WAAW;AACtC,QAAI,MAAM,WAAW,GAAG,EAAE,EACxB;SACE,MAAM,KAAK;MACT;MACM;MACN,iBAAiB;MACjB,gBAAgB;MAQhB,MAAM;MACN,cAAc;OACZ,YAAYD,uBAAqB;OACjC,WAAWF,sBAAoB;OAC/B,SAAS;OACT,kBAAkBF,qBAAmB;OACrC,gBAAgBC,mBAAiB;OAClC;MACD,cAAc;OACZ,kBAAkBD,qBAAmB;OACrC,gBAAgBC,mBAAiB;OACjC,WAAWE,sBAAoB;OAC/B,YAAYE,uBAAqB;OACjC,SAAS;OACV;MACF,CAAC,CAEF,OAAM;UAGR,OAAM,gBAAgB,GAAG,EAAE;AAE7B;;AAGF,wBAAmB,KAAK,mBAAmB,cAAc;AACzD,sBAAiB,KAAK,iBAAiB,cAAc;AAErD,yBAAoB,KAAK,oBAAoB,cAAc;AAC3D,yBAAoB,KAAK,oBAAoB,cAAc;AAC3D,0BAAqB,KAAK,gBAAgB,cAAc;AACxD,0BAAqB,KAAK,gBAAgB,cAAc;AACxD,WAAQ;AAGR,UAAO,QAAQ,cAAc,SAAS;AACpC,QAAI,MAAM,WAAW,GAAG,EAAE,EACxB;SACE,MAAM,KAAK;MACT;MACA;MACA,iBAAiB,qBAAqB;MACtC,gBAAgB;MAQhB,MAAM;MACN,cAAc;OACZ,YAAYD,uBAAqB;OACjC,WAAWF,sBAAoB;OAC/B,SAAS;OACT,kBAAkBF,qBAAmB;OACrC,gBAAgBC,mBAAiB;OAClC;MACD,cAAc;OACZ,kBAAkBD,qBAAmB;OACrC,gBAAgBC,mBAAiB;OACjC,WAAWE,sBAAoB;OAC/B,YAAYE,uBAAqB;OACjC,SAAS;OACV;MACF,CAAC,CAEF,OAAM;UAGR,OAAM,gBAAgB,GAAG,EAAE;AAE7B;;SAEG;AACL,SAAM,gBAAgB,mBAAmB,kBAAkB;AAC3D,wBAAqB;;EAGvB,IAAI,mBAAmB,KAAK;EAC5B,IAAI,iBAAiB,KAAK;EAE1B,IAAI,oBAAoB,KAAK;EAC7B,IAAI,oBAAoB,KAAK;EAC7B,IAAI,qBAAqB,KAAK;EAC9B,IAAI,qBAAqB,KAAK;EAC9B,MAAM,cAAc,KAAK,YAAY,GAAG,GAAG;AAE3C,OAAK,MAAM,WAAW,KAAK,aAAa;AACtC,OAAI,MAAM,aAAa,CACrB,OAAM;GAGR,MAAM,gBAAgB,YAAY;AAGlC,OAAI,QAAQ,SAAS,WAAW;AAC9B,QAAI,CAAC,MAAM,WAAW,QAAQ,OAAO,QAAQ,MAAM,EAAE;KACnD,IAAI,QAAQ;AAEZ,YAAO,QAAQ,QAAQ,OAAO;AAC5B,UAAI,MAAM,WAAW,GAAG,EAAE,EAAE;OAC1B,MAAM,aAAa,iBAAiB,UAAU,QAAQ,QAAQ;OAC9D,MAAM,kBAAkB,mBAAmB;OAC3C,MAAM,gBAAgB,iBAAiB;AACvC,WACE,MAAM,KAAK;QACT;QACA;QACA,iBAAiB,qBAAqB;QACtC,gBAAgB,0BACd,iBACA,cACD;QACD,MAAM;QACN,cAAc;SACZ,YAAY,qBAAqB;SACjC,WAAW,oBAAoB;SAC/B,SAAS,cAAc,KAAK;SAC5B,kBAAkB;SAClB,gBAAgB;SACjB;QACD,cAAc;SACZ,kBAAkB;SAClB,gBAAgB;SAChB,WAAW,oBAAoB;SAC/B,YAAY,qBAAqB;SACjC,SAAS,cAAc,KAAK;SAC7B;QACF,CAAC,CAEF,OAAM;YAGR,OAAM,gBAAgB,GAAG,EAAE;AAE7B;;WAEG;AACL,WAAM,gBAAgB,QAAQ,OAAO,QAAQ,MAAM;AACnD,0BAAqB;;AAEvB,wBAAoB,QAAQ;AAC5B,sBAAkB,QAAQ;AAE1B,yBAAqB,QAAQ;AAC7B,yBAAqB,QAAQ;AAC7B,0BAAsB,QAAQ;AAC9B,0BAAsB,QAAQ;UAG3B;IACH,MAAM,aAAa,KAAK,IAAI,QAAQ,WAAW,QAAQ,UAAU;IACjE,MAAM,eAAe,QAAQ,YAAY,QAAQ;AAEjD,QAAI,CADqB,MAAM,WAAW,cAAc,WAAW,EAC5C;KACrB,MAAM,kBAAkB,yBACtB,OACA,SACA,UACD;AAGD,UAAK,MAAM,CAAC,YAAY,aAAa,gBACnC,MAAK,IAAI,QAAQ,YAAY,QAAQ,UAAU,SAAS;MAStD,MAAM,iBAAiB,0BARC,mBAAmB,OAEzC,cAAc,YACV,kBACC,QAAQ,QAAQ,YACb,QACA,QAAQ,QAAQ,aACpB,iBAAiB,MAItB;AACD,UACE,MAAM,KACJ,kBAAkB;OAChB;OACA;OACA,iBAAiB,qBAAqB;OACtC;OACA;OACA;OACA;OACA;OACA;OACA;OACA;OACA;OACA;OACA;OACA;OACA;OACD,CAAC,EACF,KACD,CAED,OAAM;;;AAMd,yBAAqB;AACrB,UAAM,gBAAgB,cAAc,WAAW;AAC/C,wBAAoB;AACpB,sBAAkB;AAClB,yBAAqB,QAAQ;AAC7B,yBAAqB,QAAQ;AAC7B,0BAAsB,QAAQ;AAC9B,0BAAsB,QAAQ;;;AAIlC,MAAI,kBAAkB,MAAM;GAC1B,MAAM,EAAE,gBAAgB,WAAW,YAAY;GAC/C,MAAM,MAAM,YAAY;GACxB,IAAI,QAAQ;AAEZ,UAAO,QAAQ,KAAK;AAClB,QAAI,MAAM,aAAa,CACrB,OAAM;AAER,QAAI,MAAM,WAAW,GAAG,EAAE,EAAE;KAC1B,MAAM,aAAa,UAAU,MAAM;AACnC,SACE,MAAM,KAAK;MACT,WAAW,KAAK,MAAM;MACtB,MAAM;MACN,iBAAiB;MACjB,gBAAgB,aAAa,iBAAiB;MAC9C,MAAM;MAGN,cAAc;OACZ,YAAY,qBAAqB;OACjC,WAAW,oBAAoB;OAC/B,SAAS;OACT,kBAAkB,mBAAmB;OACrC,gBAAgB,iBAAiB;OAClC;MACD,cAAc;OACZ,kBAAkB,mBAAmB;OACrC,gBAAgB,iBAAiB;OACjC,WAAW,oBAAoB;OAC/B,YAAY,qBAAqB;OACjC,SAAS;OACV;MACF,CAAC,CAEF,OAAM;UAGR,OAAM,gBAAgB,GAAG,EAAE;AAE7B;;;;;AAaR,SAAS,kBACP,WACA,WACA,eACA,WACA,2BACsB;AACtB,aAAY,KAAK,IAAI,WAAW,EAAE;AAClC,KAAI,cAAc,KAAK,UACrB,QAAO;EACL,WAAW;EACX,SAAS;EACT;EACA,gBAAgB,KAAK,IAAI,WAAW,EAAE;EACvC;AAEH,KAAI,kBAAkB,QAAQ,aAAa,0BACzC,QAAO;EACL,WAAW;EACX,SAAS;EACT;EACA,gBAAgB;EACjB;CAEH,MAAM,SAAS,eAAe,IAAI,UAAU;CAC5C,MAAM,YAAY,KAAK,IAAI,KAAK,IAAI,QAAQ,aAAa,GAAG,EAAE,EAAE,UAAU;CAC1E,MAAM,UAAU,KAAK,IAAI,KAAK,IAAI,QAAQ,WAAW,GAAG,EAAE,EAAE,UAAU;CACtE,MAAM,gBAAgB,YAAY;CAClC,MAAM,YAAY,iBAAiB;AACnC,QAAO;EACL,WAAW,YAAY,YAAY;EACnC,SAAS,YAAY,IAAI;EACzB;EACA,gBAAgB,KAAK,IAAI,YAAY,eAAe,EAAE;EACvD;;AAGH,SAAS,sBAAsB,MAAiC;CAC9D,MAAM,WAAW,KAAK,MAAM,GAAG,GAAG;AAClC,KACE,YAAY,QACZ,KAAK,aACL,KAAK,cAAc,WAAW,KAC9B,KAAK,cAAc,WAAW,EAE9B,QAAO;AAET,QACE,SAAS,oBAAoB,SAAS,gBACpC,KAAK,cAAc,UACrB,SAAS,oBAAoB,SAAS,gBACpC,KAAK,cAAc;;AAOzB,SAAS,yBACP,OACA,SACA,WACoB;AAEpB,KAAI,CAAC,MAAM,oBACT,QAAO,CACL,CACE,GACA,cAAc,YACV,QAAQ,YAAY,QAAQ,YAC5B,KAAK,IAAI,QAAQ,WAAW,QAAQ,UAAU,CACnD,CACF;CAEH,MAAM,aAAa,cAAc;CACjC,MAAM,WAAW,cAAc;CAC/B,MAAM,iBAAiB,cAAc,YAAY,YAAY;CAC7D,MAAMC,kBAAsC,EAAE;CAC9C,SAAS,gBACP,OACA,OAC8B;AAE9B,MADY,QAAQ,SACT,MAAM,iBAAiB,SAAS,MAAM,YAC/C;EAEF,MAAM,eAAe,KAAK,IAAI,GAAG,MAAM,gBAAgB,MAAM;EAC7D,MAAM,aAAa,KAAK,IAAI,OAAO,MAAM,cAAc,MAAM;AAC7D,SAAO,aAAa,eAAe,CAAC,cAAc,WAAW,GAAG;;CAElE,SAAS,oBACP,OACA,MACkB;AAClB,MAAI,mBAAmB,QAErB,QAAO;AAET,SAAO,SAAS,cACZ,CAAC,MAAM,KAAK,QAAQ,WAAW,MAAM,KAAK,QAAQ,UAAU,GAC5D;;CAEN,SAAS,UACP,OACA,MACA;AACA,MAAI,SAAS,KACX;EAEF,MAAM,CAAC,OAAO,OAAO,oBAAoB,OAAO,KAAK;AACrD,MAAI,MAAM,MACR,iBAAgB,KAAK,CAAC,OAAO,IAAI,CAAC;;AAItC,KAAI,YAAY;AACd,YACE,gBAAgB,MAAM,cAAc,QAAQ,UAAU,EACtD,YACD;AACD,YACE,gBACE,MAAM,eAAe,QAAQ,WAC7B,QAAQ,UACT,EACD,YACD;;AAGH,KAAI,UAAU;AACZ,YACE,gBAAgB,MAAM,YAAY,QAAQ,UAAU,EACpD,YACD;AACD,YACE,gBAAgB,MAAM,YAAY,QAAQ,UAAU,EACpD,YACD;;AAGH,KAAI,gBAAgB,WAAW,EAC7B,QAAO;AAGT,iBAAgB,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,GAAG;CAC3C,MAAMC,SAA6B,CAAC,gBAAgB,GAAG;AACvD,MAAK,MAAM,CAAC,OAAO,QAAQ,gBAAgB,MAAM,EAAE,EAAE;EACnD,MAAM,OAAO,OAAO,OAAO,SAAS;AACpC,MAAI,SAAS,KAAK,GAChB,MAAK,KAAK,KAAK,IAAI,KAAK,IAAI,IAAI;MAEhC,QAAO,KAAK,CAAC,OAAO,IAAI,CAAC;;AAI7B,QAAO;;AAyBT,SAAS,kBAAkB,EACzB,WACA,MACA,gBACA,iBACA,WACA,OACA,kBACA,gBACA,mBACA,mBACA,oBACA,oBACA,SACA,eACA,cACA,cACgD;CAChD,MAAM,2BACJ,QAAQ,QAAQ,YAAY,mBAAmB,QAAQ;CACzD,MAAM,2BACJ,cAAc,YACV,SAAS,QAAQ,YACf,mBAAmB,QACnB,SACF,QAAQ,QAAQ,YACd,mBAAmB,QAAQ,YAAY,QACvC;CAER,MAAM,yBACJ,cAAc,YACV,kBACC,QAAQ,QAAQ,YAAY,QAAQ,QAAQ,QAAQ,aACrD,iBAAiB;CAEvB,MAAM,yBACJ,QAAQ,QAAQ,YAAY,oBAAoB,QAAQ;CAC1D,MAAM,0BACJ,QAAQ,QAAQ,YAAY,qBAAqB,QAAQ;CAC3D,MAAM,yBACJ,cAAc,YACV,SAAS,QAAQ,YACf,qBAAqB,QAAQ,QAAQ,aACrC,SACF,QAAQ,QAAQ,YACd,oBAAoB,QACpB;CACR,MAAM,0BACJ,cAAc,YACV,SAAS,QAAQ,YACf,sBAAsB,QAAQ,QAAQ,aACtC,SACF,QAAQ,QAAQ,YACd,qBAAqB,QACrB;CAER,MAAM,kBACJ,cAAc,YACV,iBACA,UAAU,QAAQ,YAAY,KAC9B,KAAK,mBACL,iBAAiB,UAAU,aAAa,KAAK,KAAK;CACxD,MAAM,kBACJ,cAAc,YACV,iBAAiB,UAAU,eAAe,KAAK,KAAK,mBACpD,iBAAiB,UAAU,aAAa,KAAK,KAAK;CAExD,MAAMC,eACJ,0BAA0B,QAC1B,2BAA2B,QAC3B,4BAA4B,OAGxB;EACE,YAAY;EACZ,WAAW;EACX,SAAS;EACT,kBAAkB;EAClB,gBAAgB;EACjB,GACD;CACN,MAAMC,eACJ,0BAA0B,QAC1B,2BAA2B,QAC3B,4BAA4B,OAGxB;EACE,kBAAkB;EAClB,gBAAgB;EAChB,WAAW;EACX,YAAY;EACZ,SAAS;EACV,GACD;AAEN,KAAI,gBAAgB,QAAQ,gBAAgB,KAC1C,QAAO;EACL,MAAM;EACN;EACA;EACA;EACA;EACA,cAAc;EACd;EACD;UACQ,gBAAgB,QAAQ,gBAAgB,KACjD,QAAO;EACL,MAAM;EACN;EACA;EACA;EACA;EACA;EACA,cAAc;EACf;AAGH,KAAI,gBAAgB,QAAQ,gBAAgB,KAC1C,OAAM,IAAI,MAAM,4CAA4C;AAG9D,QAAO;EACL,MAAM;EACN;EACA;EACA;EACA;EACA;EACA;EACD"}
@@ -0,0 +1,50 @@
1
+ //#region src/utils/iterateOverFile.d.ts
2
+ interface IterateOverFileProps {
3
+ lines: string[];
4
+ startingLine?: number;
5
+ totalLines?: number;
6
+ callback: FileLineCallback;
7
+ }
8
+ interface FileLineCallbackProps {
9
+ lineIndex: number;
10
+ lineNumber: number;
11
+ content: string;
12
+ isLastLine: boolean;
13
+ }
14
+ type FileLineCallback = (props: FileLineCallbackProps) => boolean | void;
15
+ /**
16
+ * Iterates over lines in a file with optional windowing support.
17
+ *
18
+ * Similar to `iterateOverDiff` but simplified for linear file content.
19
+ * Supports viewport windowing for virtualization scenarios.
20
+ *
21
+ * @param props - Configuration for iteration
22
+ * @param props.lines - Pre-split array of lines (use splitFileContents() to create from string)
23
+ * @param props.startingLine - Optional starting line index (0-based, default: 0)
24
+ * @param props.totalLines - Optional max lines to iterate (default: Infinity)
25
+ * @param props.callback - Callback invoked for each line in the window.
26
+ * Return `true` to stop iteration early.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const lines = splitFileContents('line1\nline2\nline3');
31
+ * iterateOverFile({
32
+ * lines,
33
+ * startingLine: 0,
34
+ * totalLines: 10,
35
+ * callback: ({ lineIndex, lineNumber, content, isLastLine }) => {
36
+ * console.log(`Line ${lineNumber}: ${content}`);
37
+ * if (content.includes('stop')) return true; // Stop iteration
38
+ * }
39
+ * });
40
+ * ```
41
+ */
42
+ declare function iterateOverFile({
43
+ lines,
44
+ startingLine,
45
+ totalLines,
46
+ callback
47
+ }: IterateOverFileProps): void;
48
+ //#endregion
49
+ export { FileLineCallback, FileLineCallbackProps, IterateOverFileProps, iterateOverFile };
50
+ //# sourceMappingURL=iterateOverFile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iterateOverFile.d.ts","names":["IterateOverFileProps","FileLineCallback","FileLineCallbackProps","iterateOverFile","lines","startingLine","totalLines","callback"],"sources":["../../src/utils/iterateOverFile.d.ts"],"sourcesContent":["export interface IterateOverFileProps {\n lines: string[];\n startingLine?: number;\n totalLines?: number;\n callback: FileLineCallback;\n}\nexport interface FileLineCallbackProps {\n lineIndex: number;\n lineNumber: number;\n content: string;\n isLastLine: boolean;\n}\nexport type FileLineCallback = (props: FileLineCallbackProps) => boolean | void;\n/**\n * Iterates over lines in a file with optional windowing support.\n *\n * Similar to `iterateOverDiff` but simplified for linear file content.\n * Supports viewport windowing for virtualization scenarios.\n *\n * @param props - Configuration for iteration\n * @param props.lines - Pre-split array of lines (use splitFileContents() to create from string)\n * @param props.startingLine - Optional starting line index (0-based, default: 0)\n * @param props.totalLines - Optional max lines to iterate (default: Infinity)\n * @param props.callback - Callback invoked for each line in the window.\n * Return `true` to stop iteration early.\n *\n * @example\n * ```typescript\n * const lines = splitFileContents('line1\\nline2\\nline3');\n * iterateOverFile({\n * lines,\n * startingLine: 0,\n * totalLines: 10,\n * callback: ({ lineIndex, lineNumber, content, isLastLine }) => {\n * console.log(`Line ${lineNumber}: ${content}`);\n * if (content.includes('stop')) return true; // Stop iteration\n * }\n * });\n * ```\n */\nexport declare function iterateOverFile({ lines, startingLine, totalLines, callback }: IterateOverFileProps): void;\n//# sourceMappingURL=iterateOverFile.d.ts.map"],"mappings":";UAAiBA,oBAAAA;EAAAA,KAAAA,EAAAA,MAAAA,EAAAA;EAMAE,YAAAA,CAAAA,EAAAA,MAAAA;EAMLD,UAAAA,CAAAA,EAAAA,MAAgB;EA4BJE,QAAAA,EApCVF,gBAoCyB;;AAAUI,UAlChCH,qBAAAA,CAkCgCG;EAAcC,SAAAA,EAAAA,MAAAA;EAAYC,UAAAA,EAAAA,MAAAA;EAAYP,OAAAA,EAAAA,MAAAA;EAAoB,UAAA,EAAA,OAAA;;KA5B/FC,gBAAAA,WAA2BC;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4BfC,eAAAA;;;;;GAA+DH"}
@@ -0,0 +1,49 @@
1
+ //#region src/utils/iterateOverFile.ts
2
+ /**
3
+ * Iterates over lines in a file with optional windowing support.
4
+ *
5
+ * Similar to `iterateOverDiff` but simplified for linear file content.
6
+ * Supports viewport windowing for virtualization scenarios.
7
+ *
8
+ * @param props - Configuration for iteration
9
+ * @param props.lines - Pre-split array of lines (use splitFileContents() to create from string)
10
+ * @param props.startingLine - Optional starting line index (0-based, default: 0)
11
+ * @param props.totalLines - Optional max lines to iterate (default: Infinity)
12
+ * @param props.callback - Callback invoked for each line in the window.
13
+ * Return `true` to stop iteration early.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const lines = splitFileContents('line1\nline2\nline3');
18
+ * iterateOverFile({
19
+ * lines,
20
+ * startingLine: 0,
21
+ * totalLines: 10,
22
+ * callback: ({ lineIndex, lineNumber, content, isLastLine }) => {
23
+ * console.log(`Line ${lineNumber}: ${content}`);
24
+ * if (content.includes('stop')) return true; // Stop iteration
25
+ * }
26
+ * });
27
+ * ```
28
+ */
29
+ function iterateOverFile({ lines, startingLine = 0, totalLines = Infinity, callback }) {
30
+ const len = Math.min(startingLine + totalLines, lines.length);
31
+ const lastLineIndex = (() => {
32
+ const lastLine = lines.at(-1);
33
+ if (lastLine === "" || lastLine === "\n" || lastLine === "\r\n" || lastLine === "\r") return Math.max(0, lines.length - 2);
34
+ return lines.length - 1;
35
+ })();
36
+ for (let lineIndex = startingLine; lineIndex < len; lineIndex++) {
37
+ const isLastLine = lineIndex === lastLineIndex;
38
+ if (callback({
39
+ lineIndex,
40
+ lineNumber: lineIndex + 1,
41
+ content: lines[lineIndex],
42
+ isLastLine
43
+ }) === true || isLastLine) break;
44
+ }
45
+ }
46
+
47
+ //#endregion
48
+ export { iterateOverFile };
49
+ //# sourceMappingURL=iterateOverFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iterateOverFile.js","names":[],"sources":["../../src/utils/iterateOverFile.ts"],"sourcesContent":["export interface IterateOverFileProps {\n lines: string[];\n startingLine?: number;\n totalLines?: number;\n callback: FileLineCallback;\n}\n\nexport interface FileLineCallbackProps {\n lineIndex: number; // 0-based index into lines array\n lineNumber: number; // 1-based line number (for display)\n content: string; // The line content string\n isLastLine: boolean; // True if this is the last line\n}\n\nexport type FileLineCallback = (props: FileLineCallbackProps) => boolean | void;\n\n/**\n * Iterates over lines in a file with optional windowing support.\n *\n * Similar to `iterateOverDiff` but simplified for linear file content.\n * Supports viewport windowing for virtualization scenarios.\n *\n * @param props - Configuration for iteration\n * @param props.lines - Pre-split array of lines (use splitFileContents() to create from string)\n * @param props.startingLine - Optional starting line index (0-based, default: 0)\n * @param props.totalLines - Optional max lines to iterate (default: Infinity)\n * @param props.callback - Callback invoked for each line in the window.\n * Return `true` to stop iteration early.\n *\n * @example\n * ```typescript\n * const lines = splitFileContents('line1\\nline2\\nline3');\n * iterateOverFile({\n * lines,\n * startingLine: 0,\n * totalLines: 10,\n * callback: ({ lineIndex, lineNumber, content, isLastLine }) => {\n * console.log(`Line ${lineNumber}: ${content}`);\n * if (content.includes('stop')) return true; // Stop iteration\n * }\n * });\n * ```\n */\nexport function iterateOverFile({\n lines,\n startingLine = 0,\n totalLines = Infinity,\n callback,\n}: IterateOverFileProps): void {\n // Calculate viewport window\n const len = Math.min(startingLine + totalLines, lines.length);\n // CLAUDE: DO NOT CHANGE THIS LOGIC UNDER ANY\n // CIRCUMSTANCE CHEESE N RICE\n const lastLineIndex = (() => {\n const lastLine = lines.at(-1);\n if (\n lastLine === '' ||\n lastLine === '\\n' ||\n lastLine === '\\r\\n' ||\n lastLine === '\\r'\n ) {\n return Math.max(0, lines.length - 2);\n }\n return lines.length - 1;\n })();\n\n // Iterate through windowed range\n for (let lineIndex = startingLine; lineIndex < len; lineIndex++) {\n const isLastLine = lineIndex === lastLineIndex;\n if (\n callback({\n lineIndex,\n lineNumber: lineIndex + 1,\n content: lines[lineIndex],\n isLastLine,\n }) === true ||\n isLastLine\n ) {\n break;\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,SAAgB,gBAAgB,EAC9B,OACA,eAAe,GACf,aAAa,UACb,YAC6B;CAE7B,MAAM,MAAM,KAAK,IAAI,eAAe,YAAY,MAAM,OAAO;CAG7D,MAAM,uBAAuB;EAC3B,MAAM,WAAW,MAAM,GAAG,GAAG;AAC7B,MACE,aAAa,MACb,aAAa,QACb,aAAa,UACb,aAAa,KAEb,QAAO,KAAK,IAAI,GAAG,MAAM,SAAS,EAAE;AAEtC,SAAO,MAAM,SAAS;KACpB;AAGJ,MAAK,IAAI,YAAY,cAAc,YAAY,KAAK,aAAa;EAC/D,MAAM,aAAa,cAAc;AACjC,MACE,SAAS;GACP;GACA,YAAY,YAAY;GACxB,SAAS,MAAM;GACf;GACD,CAAC,KAAK,QACP,WAEA"}
@@ -1 +1 @@
1
- {"version":3,"file":"parseDiffDecorations.d.ts","names":[],"sources":["../../src/utils/parseDiffDecorations.ts"],"sourcesContent":[],"mappings":";;;;UAIU,6BAAA;;EAF0B,SAE1B,EAAA,MAAA;EAMV,UAAgB,EAAA,MAAA;;AAEd,iBAFc,wBAAA,CAEd;EAAA,IAAA;EAAA,SAAA;EAAA;AAAA,CAAA,EAEC,6BAFD,CAAA,EAEiC,cAFjC;UAWQ,mBAAA,CAVR;EACC,IAAA,EAUK,YAVL,CAAA,MAAA,CAAA;EAAgC,GAAA,EAAA,CAAA,CAAA,GAAA,CAAA,EAAA,MAAA,CAAA,EAAA;EAAA,UAAA,EAAA,OAAA;EAAA,SASzB,CAAA,EAAA,OAAA;EAaV,UAAgB,CAAA,EAAA,OAAA;;AAEd,iBAFc,cAAA,CAEd;EAAA,IAAA;EAAA,GAAA;EAAA,UAAA;EAAA,SAAA;EAAA;AAAA,CAAA,EAIC,mBAJD,CAAA,EAAA,IAAA"}
1
+ {"version":3,"file":"parseDiffDecorations.d.ts","names":["ChangeObject","DecorationItem","CreateDiffSpanDecorationProps","createDiffSpanDecoration","line","spanStart","spanLength","PushOrJoinSpanProps","pushOrJoinSpan","item","arr","enableJoin","isNeutral","isLastItem"],"sources":["../../src/utils/parseDiffDecorations.d.ts"],"sourcesContent":["import { type ChangeObject } from 'diff';\nimport type { DecorationItem } from '../types';\ninterface CreateDiffSpanDecorationProps {\n line: number;\n spanStart: number;\n spanLength: number;\n}\nexport declare function createDiffSpanDecoration({ line, spanStart, spanLength }: CreateDiffSpanDecorationProps): DecorationItem;\ninterface PushOrJoinSpanProps {\n item: ChangeObject<string>;\n arr: [0 | 1, string][];\n enableJoin: boolean;\n isNeutral?: boolean;\n isLastItem?: boolean;\n}\nexport declare function pushOrJoinSpan({ item, arr, enableJoin, isNeutral, isLastItem }: PushOrJoinSpanProps): void;\nexport {};\n//# sourceMappingURL=parseDiffDecorations.d.ts.map"],"mappings":";;;;UAEUE,6BAAAA;;EAAAA,SAAAA,EAAAA,MAAAA;EAKcC,UAAAA,EAAAA,MAAAA;;AAAiCE,iBAAjCF,wBAAAA,CAAiCE;EAAAA,IAAAA;EAAAA,SAAAA;EAAAA;AAAAA,CAAAA,EAAyBH,6BAAzBG,CAAAA,EAAyDJ,cAAzDI;UAC/CE,mBAAAA,CAD0DD;EAAcJ,IAAAA,EAExEF,YAFwEE,CAAAA,MAAAA,CAAAA;EAAgCD,GAAAA,EAAAA,CAAAA,CAAAA,GAAAA,CAAAA,EAAAA,MAAAA,CAAAA,EAAAA;EAAc,UAAA,EAAA,OAAA;EACtHM,SAAAA,CAAAA,EAAAA,OAAAA;EAOcC,UAAAA,CAAAA,EAAAA,OAAc;;AAASE,iBAAvBF,cAAAA,CAAuBE;EAAAA,IAAAA;EAAAA,GAAAA;EAAAA,UAAAA;EAAAA,SAAAA;EAAAA;AAAAA,CAAAA,EAA0CH,mBAA1CG,CAAAA,EAAAA,IAAAA"}
@@ -4,11 +4,11 @@ import { CreatePatchOptionsNonabortable } from "diff";
4
4
  //#region src/utils/parseDiffFromFile.d.ts
5
5
 
6
6
  /**
7
- * Parses a diff from two file contents objects.
8
- *
9
- * If both `oldFile` and `newFile` have a `cacheKey`, the resulting diff will
10
- * automatically get a combined cache key in the format `oldKey:newKey`.
11
- */
7
+ * Parses a diff from two file contents objects.
8
+ *
9
+ * If both `oldFile` and `newFile` have a `cacheKey`, the resulting diff will
10
+ * automatically get a combined cache key in the format `oldKey:newKey`.
11
+ */
12
12
  declare function parseDiffFromFile(oldFile: FileContents, newFile: FileContents, options?: CreatePatchOptionsNonabortable, throwOnError?: boolean): FileDiffMetadata;
13
13
  //#endregion
14
14
  export { parseDiffFromFile };
@@ -1 +1 @@
1
- {"version":3,"file":"parseDiffFromFile.d.ts","names":[],"sources":["../../src/utils/parseDiffFromFile.ts"],"sourcesContent":[],"mappings":";;;;;;;AAWA;;;;AAOG,iBAPa,iBAAA,CAOb,OAAA,EAJQ,YAIR,EAAA,OAAA,EAHQ,YAGR,EAAA,OAAA,CAAA,EAFS,8BAET,EAAA,YAAA,CAAA,EAAA,OAAA,CAAA,EAAA,gBAAA"}
1
+ {"version":3,"file":"parseDiffFromFile.d.ts","names":["CreatePatchOptionsNonabortable","FileContents","FileDiffMetadata","parseDiffFromFile"],"sources":["../../src/utils/parseDiffFromFile.d.ts"],"sourcesContent":["import { type CreatePatchOptionsNonabortable } from 'diff';\nimport type { FileContents, FileDiffMetadata } from '../types';\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 declare function parseDiffFromFile(oldFile: FileContents, newFile: FileContents, options?: CreatePatchOptionsNonabortable, throwOnError?: boolean): FileDiffMetadata;\n//# sourceMappingURL=parseDiffFromFile.d.ts.map"],"mappings":";;;;;;;AAQA;;;;AAA2JE,iBAAnIC,iBAAAA,CAAmID,OAAAA,EAAxGD,YAAwGC,EAAAA,OAAAA,EAAjFD,YAAiFC,EAAAA,OAAAA,CAAAA,EAAzDF,8BAAyDE,EAAAA,YAAAA,CAAAA,EAAAA,OAAAA,CAAAA,EAAAA,gBAAAA"}
@@ -3,7 +3,7 @@ import { HunkLineType } from "../types.js";
3
3
  //#region src/utils/parseLineType.d.ts
4
4
  interface ParsedLine {
5
5
  line: string;
6
- type: Exclude<HunkLineType, "expanded">;
6
+ type: Exclude<HunkLineType, 'expanded'>;
7
7
  }
8
8
  declare function parseLineType(line: string): ParsedLine | undefined;
9
9
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"parseLineType.d.ts","names":[],"sources":["../../src/utils/parseLineType.ts"],"sourcesContent":[],"mappings":";;;UAEiB,UAAA;;EAAjB,IAAiB,EAET,OAFS,CAED,YAFC,EAAA,UAED,CAAA;AAGhB;iBAAgB,aAAA,gBAA6B"}
1
+ {"version":3,"file":"parseLineType.d.ts","names":["HunkLineType","ParsedLine","Exclude","parseLineType"],"sources":["../../src/utils/parseLineType.d.ts"],"sourcesContent":["import type { HunkLineType } from '../types';\nexport interface ParsedLine {\n line: string;\n type: Exclude<HunkLineType, 'expanded'>;\n}\nexport declare function parseLineType(line: string): ParsedLine | undefined;\n//# sourceMappingURL=parseLineType.d.ts.map"],"mappings":";;;UACiBC,UAAAA;;EAAAA,IAAAA,EAEPC,OAFiB,CAETF,YAAAA,EAAAA,UAAAA,CAAAA;AAElB;iBAAwBG,aAAAA,gBAA6BF"}
@@ -17,13 +17,13 @@ declare function processFile(fileDiffString: string, {
17
17
  throwOnError
18
18
  }?: ProcessFileOptions): FileDiffMetadata | undefined;
19
19
  /**
20
- * Parses a patch file string into an array of parsed patches.
21
- *
22
- * @param data - The raw patch file content (supports multi-commit patches)
23
- * @param cacheKeyPrefix - Optional prefix for generating cache keys. When provided,
24
- * each file in the patch will get a cache key in the format `prefix-patchIndex-fileIndex`.
25
- * This enables caching of rendered diff results in the worker pool.
26
- */
20
+ * Parses a patch file string into an array of parsed patches.
21
+ *
22
+ * @param data - The raw patch file content (supports multi-commit patches)
23
+ * @param cacheKeyPrefix - Optional prefix for generating cache keys. When provided,
24
+ * each file in the patch will get a cache key in the format `prefix-patchIndex-fileIndex`.
25
+ * This enables caching of rendered diff results in the worker pool.
26
+ */
27
27
  declare function parsePatchFiles(data: string, cacheKeyPrefix?: string, throwOnError?: boolean): ParsedPatch[];
28
28
  //#endregion
29
29
  export { parsePatchFiles, processFile, processPatch };
@@ -1 +1 @@
1
- {"version":3,"file":"parsePatchFiles.d.ts","names":[],"sources":["../../src/utils/parsePatchFiles.ts"],"sourcesContent":[],"mappings":";;;iBAuBgB,YAAA,iEAIb;UAyDO,kBAAA;EA7DV,QAAgB,CAAA,EAAA,MAAA;EAIb,SAyDO,CAAA,EAAA,OAAA;EAQV,OAAgB,CAAA,EALJ,YAKI;EAGZ,OAAA,CAAA,EAPQ,YAOR;EACA,YAAA,CAAA,EAAA,OAAA;;AAEA,iBANY,WAAA,CAMZ,cAAA,EAAA,MAAA,EAAA;EAAA,QAAA;EAAA,SAAA;EAAA,OAAA;EAAA,OAAA;EAAA;AAAA,CAAA,CAAA,EAEC,kBAFD,CAAA,EAGD,gBAHC,GAAA,SAAA;;;;;AA+XJ;;;;iBAAgB,eAAA,iEAIb"}
1
+ {"version":3,"file":"parsePatchFiles.d.ts","names":["FileContents","FileDiffMetadata","ParsedPatch","processPatch","ProcessFileOptions","processFile","cacheKey","isGitDiff","oldFile","newFile","throwOnError","parsePatchFiles"],"sources":["../../src/utils/parsePatchFiles.d.ts"],"sourcesContent":["import type { FileContents, FileDiffMetadata, ParsedPatch } from '../types';\nexport declare function processPatch(data: string, cacheKeyPrefix?: string, throwOnError?: boolean): ParsedPatch;\ninterface ProcessFileOptions {\n cacheKey?: string;\n isGitDiff?: boolean;\n oldFile?: FileContents;\n newFile?: FileContents;\n throwOnError?: boolean;\n}\nexport declare function processFile(fileDiffString: string, { cacheKey, isGitDiff, oldFile, newFile, throwOnError }?: ProcessFileOptions): FileDiffMetadata | undefined;\n/**\n * Parses a patch file string into an array of parsed patches.\n *\n * @param data - The raw patch file content (supports multi-commit patches)\n * @param cacheKeyPrefix - Optional prefix for generating cache keys. When provided,\n * each file in the patch will get a cache key in the format `prefix-patchIndex-fileIndex`.\n * This enables caching of rendered diff results in the worker pool.\n */\nexport declare function parsePatchFiles(data: string, cacheKeyPrefix?: string, throwOnError?: boolean): ParsedPatch[];\nexport {};\n//# sourceMappingURL=parsePatchFiles.d.ts.map"],"mappings":";;;iBACwBG,YAAAA,iEAA6ED;UAC3FE,kBAAAA;EADcD,QAAAA,CAAAA,EAAAA,MAAY;EAC1BC,SAAAA,CAAAA,EAAAA,OAAAA;EAOcC,OAAAA,CAAAA,EAJVL,YAIqB;EAA2BM,OAAAA,CAAAA,EAHhDN,YAGgDM;EAAUC,YAAAA,CAAAA,EAAAA,OAAAA;;AAAoBE,iBAApEJ,WAAAA,CAAoEI,cAAAA,EAAAA,MAAAA,EAAAA;EAAAA,QAAAA;EAAAA,SAAAA;EAAAA,OAAAA;EAAAA,OAAAA;EAAAA;AAAAA,CAAAA,CAAAA,EAA0BL,kBAA1BK,CAAAA,EAA+CR,gBAA/CQ,GAAAA,SAAAA;;;;;AAS5F;;;;iBAAwBE,eAAAA,iEAAgFT"}
@@ -1 +1 @@
1
- {"version":3,"file":"parsePatchFiles.js","names":["patchMetadata: string | undefined","files: FileDiffMetadata[]","currentFile: FileDiffMetadata | undefined","currentContent: ContextContent | ChangeContent | undefined","lastLineType: 'context' | 'addition' | 'deletion' | undefined","hunkData: Hunk","lastHunkEnd","patches: ParsedPatch[]"],"sources":["../../src/utils/parsePatchFiles.ts"],"sourcesContent":["import {\n ALTERNATE_FILE_NAMES_GIT,\n COMMIT_METADATA_SPLIT,\n FILENAME_HEADER_REGEX,\n FILENAME_HEADER_REGEX_GIT,\n FILE_CONTEXT_BLOB,\n GIT_DIFF_FILE_BREAK_REGEX,\n HUNK_HEADER,\n INDEX_LINE_METADATA,\n SPLIT_WITH_NEWLINES,\n UNIFIED_DIFF_FILE_BREAK_REGEX,\n} from '../constants';\nimport type {\n ChangeContent,\n ContextContent,\n FileContents,\n FileDiffMetadata,\n Hunk,\n ParsedPatch,\n} from '../types';\nimport { cleanLastNewline } from './cleanLastNewline';\nimport { parseLineType } from './parseLineType';\n\nexport function processPatch(\n data: string,\n cacheKeyPrefix?: string,\n throwOnError = false\n): ParsedPatch {\n const isGitDiff = GIT_DIFF_FILE_BREAK_REGEX.test(data);\n const rawFiles = data.split(\n isGitDiff ? GIT_DIFF_FILE_BREAK_REGEX : UNIFIED_DIFF_FILE_BREAK_REGEX\n );\n let patchMetadata: string | undefined;\n const files: FileDiffMetadata[] = [];\n for (const fileOrPatchMetadata of rawFiles) {\n if (isGitDiff && !GIT_DIFF_FILE_BREAK_REGEX.test(fileOrPatchMetadata)) {\n if (patchMetadata == null) {\n patchMetadata = fileOrPatchMetadata;\n } else {\n if (throwOnError) {\n throw Error('parsePatchContent: unknown file blob');\n } else {\n console.error(\n 'parsePatchContent: unknown file blob:',\n fileOrPatchMetadata\n );\n }\n }\n // If we get in here, it's most likely the introductory metadata from the\n // patch, or something is fucked with the diff format\n continue;\n } else if (\n !isGitDiff &&\n !UNIFIED_DIFF_FILE_BREAK_REGEX.test(fileOrPatchMetadata)\n ) {\n if (patchMetadata == null) {\n patchMetadata = fileOrPatchMetadata;\n } else {\n if (throwOnError) {\n throw Error('parsePatchContent: unknown file blob');\n } else {\n console.error(\n 'parsePatchContent: unknown file blob:',\n fileOrPatchMetadata\n );\n }\n }\n continue;\n }\n const currentFile = processFile(fileOrPatchMetadata, {\n cacheKey:\n cacheKeyPrefix != null\n ? `${cacheKeyPrefix}-${files.length}`\n : undefined,\n isGitDiff,\n throwOnError,\n });\n if (currentFile != null) {\n files.push(currentFile);\n }\n }\n return { patchMetadata, files };\n}\n\ninterface ProcessFileOptions {\n cacheKey?: string;\n isGitDiff?: boolean;\n oldFile?: FileContents;\n newFile?: FileContents;\n throwOnError?: boolean;\n}\n\nexport function processFile(\n fileDiffString: string,\n {\n cacheKey,\n isGitDiff = GIT_DIFF_FILE_BREAK_REGEX.test(fileDiffString),\n oldFile,\n newFile,\n throwOnError = false,\n }: ProcessFileOptions = {}\n): FileDiffMetadata | undefined {\n let lastHunkEnd = 0;\n const hunks = fileDiffString.split(FILE_CONTEXT_BLOB);\n let currentFile: FileDiffMetadata | undefined;\n const isPartial = oldFile == null || newFile == null;\n let deletionLineIndex = 0;\n let additionLineIndex = 0;\n for (const hunk of hunks) {\n const lines = hunk.split(SPLIT_WITH_NEWLINES);\n const firstLine = lines.shift();\n if (firstLine == null) {\n if (throwOnError) {\n throw Error('parsePatchContent: invalid hunk');\n } else {\n console.error('parsePatchContent: invalid hunk', hunk);\n }\n continue;\n }\n const fileHeaderMatch = firstLine.match(HUNK_HEADER);\n let additionLines = 0;\n let deletionLines = 0;\n // Setup currentFile, this should be the first iteration of our hunks, and\n // technically not a hunk\n if (fileHeaderMatch == null || currentFile == null) {\n if (currentFile != null) {\n if (throwOnError) {\n throw Error('parsePatchContent: Invalid hunk');\n } else {\n console.error('parsePatchContent: Invalid hunk', hunk);\n }\n continue;\n }\n currentFile = {\n name: '',\n type: 'change',\n hunks: [],\n splitLineCount: 0,\n unifiedLineCount: 0,\n isPartial,\n additionLines:\n !isPartial && oldFile != null && newFile != null\n ? newFile.contents.split(SPLIT_WITH_NEWLINES)\n : [],\n deletionLines:\n !isPartial && oldFile != null && newFile != null\n ? oldFile.contents.split(SPLIT_WITH_NEWLINES)\n : [],\n cacheKey,\n };\n // If either file is technically empty, then we should empty the\n // arrays respectively\n if (currentFile.additionLines.length === 1 && newFile?.contents === '') {\n currentFile.additionLines.length = 0;\n }\n if (currentFile.deletionLines.length === 1 && oldFile?.contents === '') {\n currentFile.deletionLines.length = 0;\n }\n\n // Push that first line back into the group of lines so we can properly\n // parse it out\n lines.unshift(firstLine);\n for (const line of lines) {\n const filenameMatch = line.match(\n isGitDiff ? FILENAME_HEADER_REGEX_GIT : FILENAME_HEADER_REGEX\n );\n if (line.startsWith('diff --git')) {\n const [, , prevName, , name] =\n line.trim().match(ALTERNATE_FILE_NAMES_GIT) ?? [];\n currentFile.name = name.trim();\n if (prevName !== name) {\n currentFile.prevName = prevName.trim();\n }\n } else if (filenameMatch != null) {\n const [, type, fileName] = filenameMatch;\n if (type === '---' && fileName !== '/dev/null') {\n currentFile.prevName = fileName.trim();\n currentFile.name = fileName.trim();\n } else if (type === '+++' && fileName !== '/dev/null') {\n currentFile.name = fileName.trim();\n }\n }\n // Git diffs have a bunch of additional metadata we can pull from\n else if (isGitDiff) {\n if (line.startsWith('new mode ')) {\n currentFile.mode = line.replace('new mode', '').trim();\n }\n if (line.startsWith('old mode ')) {\n currentFile.prevMode = line.replace('old mode', '').trim();\n }\n if (line.startsWith('new file mode')) {\n currentFile.type = 'new';\n currentFile.mode = line.replace('new file mode', '').trim();\n }\n if (line.startsWith('deleted file mode')) {\n currentFile.type = 'deleted';\n currentFile.mode = line.replace('deleted file mode', '').trim();\n }\n if (line.startsWith('similarity index')) {\n if (line.startsWith('similarity index 100%')) {\n currentFile.type = 'rename-pure';\n } else {\n currentFile.type = 'rename-changed';\n }\n }\n if (line.startsWith('index ')) {\n const [, prevObjectId, newObjectId, mode] =\n line.trim().match(INDEX_LINE_METADATA) ?? [];\n if (prevObjectId != null) {\n currentFile.prevObjectId = prevObjectId;\n }\n if (newObjectId != null) {\n currentFile.newObjectId = newObjectId;\n }\n if (mode != null) {\n currentFile.mode = mode;\n }\n }\n // We have to handle these for pure renames because there won't be\n // --- and +++ lines\n if (line.startsWith('rename from ')) {\n currentFile.prevName = line.replace('rename from ', '');\n }\n if (line.startsWith('rename to ')) {\n currentFile.name = line.replace('rename to ', '').trim();\n }\n }\n }\n continue;\n }\n\n // Otherwise, time to start parsing out the hunk\n let currentContent: ContextContent | ChangeContent | undefined;\n let lastLineType: 'context' | 'addition' | 'deletion' | undefined;\n\n // Strip trailing bare newlines (format-patch separators between commits)\n // if needed\n while (\n lines.length > 0 &&\n (lines[lines.length - 1] === '\\n' ||\n lines[lines.length - 1] === '\\r' ||\n lines[lines.length - 1] === '\\r\\n' ||\n lines[lines.length - 1] === '')\n ) {\n lines.pop();\n }\n\n const additionStart = parseInt(fileHeaderMatch[3]);\n const deletionStart = parseInt(fileHeaderMatch[1]);\n deletionLineIndex = isPartial ? deletionLineIndex : deletionStart - 1;\n additionLineIndex = isPartial ? additionLineIndex : additionStart - 1;\n\n const hunkData: Hunk = {\n collapsedBefore: 0,\n\n splitLineCount: 0,\n splitLineStart: 0,\n\n unifiedLineCount: 0,\n unifiedLineStart: 0,\n\n additionCount: parseInt(fileHeaderMatch[4] ?? '1'),\n additionStart,\n additionLines,\n\n deletionCount: parseInt(fileHeaderMatch[2] ?? '1'),\n deletionStart,\n deletionLines,\n\n deletionLineIndex,\n additionLineIndex,\n\n hunkContent: [],\n hunkContext: fileHeaderMatch[5],\n hunkSpecs: firstLine,\n\n noEOFCRAdditions: false,\n noEOFCRDeletions: false,\n };\n\n // Lets validate out hunkData to ensure there's no broken data from the\n // regex\n if (\n isNaN(hunkData.additionCount) ||\n isNaN(hunkData.deletionCount) ||\n isNaN(hunkData.additionStart) ||\n isNaN(hunkData.deletionStart)\n ) {\n if (throwOnError) {\n throw Error('parsePatchContent: invalid hunk metadata');\n } else {\n console.error('parsePatchContent: invalid hunk metadata', hunkData);\n }\n continue;\n }\n\n // Now we process each line of the hunk\n for (const rawLine of lines) {\n const parsedLine = parseLineType(rawLine);\n // If we can't properly process the line, well, lets just try to salvage\n // things and continue... It's possible an AI generated diff might have\n // some stray blank lines or something in there\n if (parsedLine == null) {\n console.error('processFile: invalid rawLine:', rawLine);\n continue;\n }\n\n const { type, line } = parsedLine;\n if (type === 'addition') {\n if (currentContent == null || currentContent.type !== 'change') {\n currentContent = createContentGroup(\n 'change',\n deletionLineIndex,\n additionLineIndex\n );\n hunkData.hunkContent.push(currentContent);\n }\n additionLineIndex++;\n if (isPartial) {\n currentFile.additionLines.push(line);\n }\n currentContent.additions++;\n additionLines++;\n lastLineType = 'addition';\n } else if (type === 'deletion') {\n if (currentContent == null || currentContent.type !== 'change') {\n currentContent = createContentGroup(\n 'change',\n deletionLineIndex,\n additionLineIndex\n );\n hunkData.hunkContent.push(currentContent);\n }\n deletionLineIndex++;\n if (isPartial) {\n currentFile.deletionLines.push(line);\n }\n currentContent.deletions++;\n deletionLines++;\n lastLineType = 'deletion';\n } else if (type === 'context') {\n if (currentContent == null || currentContent.type !== 'context') {\n currentContent = createContentGroup(\n 'context',\n deletionLineIndex,\n additionLineIndex\n );\n hunkData.hunkContent.push(currentContent);\n }\n additionLineIndex++;\n deletionLineIndex++;\n if (isPartial) {\n currentFile.deletionLines.push(line);\n currentFile.additionLines.push(line);\n }\n currentContent.lines++;\n lastLineType = 'context';\n } else if (type === 'metadata' && currentContent != null) {\n if (currentContent.type === 'context') {\n hunkData.noEOFCRAdditions = true;\n hunkData.noEOFCRDeletions = true;\n } else if (lastLineType === 'deletion') {\n hunkData.noEOFCRDeletions = true;\n } else if (lastLineType === 'addition') {\n hunkData.noEOFCRAdditions = true;\n }\n // If we're dealing with partial content from a diff, we need to strip\n // newlines manually from the content\n if (\n isPartial &&\n (lastLineType === 'addition' || lastLineType === 'context')\n ) {\n const lastIndex = currentFile.additionLines.length - 1;\n if (lastIndex >= 0) {\n currentFile.additionLines[lastIndex] = cleanLastNewline(\n currentFile.additionLines[lastIndex]\n );\n }\n }\n if (\n isPartial &&\n (lastLineType === 'deletion' || lastLineType === 'context')\n ) {\n const lastIndex = currentFile.deletionLines.length - 1;\n if (lastIndex >= 0) {\n currentFile.deletionLines[lastIndex] = cleanLastNewline(\n currentFile.deletionLines[lastIndex]\n );\n }\n }\n }\n }\n\n hunkData.additionLines = additionLines;\n hunkData.deletionLines = deletionLines;\n\n hunkData.collapsedBefore = Math.max(\n hunkData.additionStart - 1 - lastHunkEnd,\n 0\n );\n currentFile.hunks.push(hunkData);\n lastHunkEnd = hunkData.additionStart + hunkData.additionCount - 1;\n for (const content of hunkData.hunkContent) {\n if (content.type === 'context') {\n hunkData.splitLineCount += content.lines;\n hunkData.unifiedLineCount += content.lines;\n } else {\n hunkData.splitLineCount += Math.max(\n content.additions,\n content.deletions\n );\n hunkData.unifiedLineCount += content.deletions + content.additions;\n }\n }\n hunkData.splitLineStart =\n currentFile.splitLineCount + hunkData.collapsedBefore;\n hunkData.unifiedLineStart =\n currentFile.unifiedLineCount + hunkData.collapsedBefore;\n\n currentFile.splitLineCount +=\n hunkData.collapsedBefore + hunkData.splitLineCount;\n currentFile.unifiedLineCount +=\n hunkData.collapsedBefore + hunkData.unifiedLineCount;\n }\n if (currentFile == null) {\n return undefined;\n }\n\n // Account for collapsed lines after the final hunk and increment the\n // split/unified counts properly\n if (\n currentFile.hunks.length > 0 &&\n !isPartial &&\n currentFile.additionLines.length > 0 &&\n currentFile.deletionLines.length > 0\n ) {\n const lastHunk = currentFile.hunks[currentFile.hunks.length - 1];\n const lastHunkEnd = lastHunk.additionStart + lastHunk.additionCount - 1;\n const totalFileLines = currentFile.additionLines.length;\n const collapsedAfter = Math.max(totalFileLines - lastHunkEnd, 0);\n currentFile.splitLineCount += collapsedAfter;\n currentFile.unifiedLineCount += collapsedAfter;\n }\n\n // If this isn't a git diff style patch, then we'll need to sus out some\n // additional metadata manually\n if (!isGitDiff) {\n if (\n currentFile.prevName != null &&\n currentFile.name !== currentFile.prevName\n ) {\n if (currentFile.hunks.length > 0) {\n currentFile.type = 'rename-changed';\n } else {\n currentFile.type = 'rename-pure';\n }\n }\n // Sort of a hack for detecting deleted/added files...\n else if (newFile != null && newFile.contents === '') {\n currentFile.type = 'deleted';\n } else if (oldFile != null && oldFile.contents === '') {\n currentFile.type = 'new';\n }\n }\n if (\n currentFile.type !== 'rename-pure' &&\n currentFile.type !== 'rename-changed'\n ) {\n currentFile.prevName = undefined;\n }\n return currentFile;\n}\n\n/**\n * Parses a patch file string into an array of parsed patches.\n *\n * @param data - The raw patch file content (supports multi-commit patches)\n * @param cacheKeyPrefix - Optional prefix for generating cache keys. When provided,\n * each file in the patch will get a cache key in the format `prefix-patchIndex-fileIndex`.\n * This enables caching of rendered diff results in the worker pool.\n */\nexport function parsePatchFiles(\n data: string,\n cacheKeyPrefix?: string,\n throwOnError = false\n): ParsedPatch[] {\n // NOTE(amadeus): This function is pretty forgiving in that it can accept a\n // patch file that includes commit metdata, multiple commits, or not\n const patches: ParsedPatch[] = [];\n for (const patch of data.split(COMMIT_METADATA_SPLIT)) {\n try {\n patches.push(\n processPatch(\n patch,\n cacheKeyPrefix != null\n ? `${cacheKeyPrefix}-${patches.length}`\n : undefined,\n throwOnError\n )\n );\n } catch (error) {\n if (throwOnError) {\n throw error;\n } else {\n console.error(error);\n }\n }\n }\n return patches;\n}\n\nfunction createContentGroup(\n type: 'change',\n deletionLineIndex: number,\n additionLineIndex: number\n): ChangeContent;\nfunction createContentGroup(\n type: 'context',\n deletionLineIndex: number,\n additionLineIndex: number\n): ContextContent;\nfunction createContentGroup(\n type: 'change' | 'context',\n deletionLineIndex: number,\n additionLineIndex: number\n): ChangeContent | ContextContent {\n if (type === 'change') {\n return {\n type: 'change',\n additions: 0,\n deletions: 0,\n additionLineIndex,\n deletionLineIndex,\n };\n }\n return {\n type: 'context',\n lines: 0,\n additionLineIndex,\n deletionLineIndex,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"parsePatchFiles.js","names":["patchMetadata: string | undefined","files: FileDiffMetadata[]","currentFile: FileDiffMetadata | undefined","currentContent: ContextContent | ChangeContent | undefined","lastLineType: 'context' | 'addition' | 'deletion' | undefined","hunkData: Hunk","lastHunkEnd","patches: ParsedPatch[]"],"sources":["../../src/utils/parsePatchFiles.ts"],"sourcesContent":["import {\n ALTERNATE_FILE_NAMES_GIT,\n COMMIT_METADATA_SPLIT,\n FILE_CONTEXT_BLOB,\n FILENAME_HEADER_REGEX,\n FILENAME_HEADER_REGEX_GIT,\n GIT_DIFF_FILE_BREAK_REGEX,\n HUNK_HEADER,\n INDEX_LINE_METADATA,\n SPLIT_WITH_NEWLINES,\n UNIFIED_DIFF_FILE_BREAK_REGEX,\n} from '../constants';\nimport type {\n ChangeContent,\n ContextContent,\n FileContents,\n FileDiffMetadata,\n Hunk,\n ParsedPatch,\n} from '../types';\nimport { cleanLastNewline } from './cleanLastNewline';\nimport { parseLineType } from './parseLineType';\n\nexport function processPatch(\n data: string,\n cacheKeyPrefix?: string,\n throwOnError = false\n): ParsedPatch {\n const isGitDiff = GIT_DIFF_FILE_BREAK_REGEX.test(data);\n const rawFiles = data.split(\n isGitDiff ? GIT_DIFF_FILE_BREAK_REGEX : UNIFIED_DIFF_FILE_BREAK_REGEX\n );\n let patchMetadata: string | undefined;\n const files: FileDiffMetadata[] = [];\n for (const fileOrPatchMetadata of rawFiles) {\n if (isGitDiff && !GIT_DIFF_FILE_BREAK_REGEX.test(fileOrPatchMetadata)) {\n if (patchMetadata == null) {\n patchMetadata = fileOrPatchMetadata;\n } else {\n if (throwOnError) {\n throw Error('parsePatchContent: unknown file blob');\n } else {\n console.error(\n 'parsePatchContent: unknown file blob:',\n fileOrPatchMetadata\n );\n }\n }\n // If we get in here, it's most likely the introductory metadata from the\n // patch, or something is fucked with the diff format\n continue;\n } else if (\n !isGitDiff &&\n !UNIFIED_DIFF_FILE_BREAK_REGEX.test(fileOrPatchMetadata)\n ) {\n if (patchMetadata == null) {\n patchMetadata = fileOrPatchMetadata;\n } else {\n if (throwOnError) {\n throw Error('parsePatchContent: unknown file blob');\n } else {\n console.error(\n 'parsePatchContent: unknown file blob:',\n fileOrPatchMetadata\n );\n }\n }\n continue;\n }\n const currentFile = processFile(fileOrPatchMetadata, {\n cacheKey:\n cacheKeyPrefix != null\n ? `${cacheKeyPrefix}-${files.length}`\n : undefined,\n isGitDiff,\n throwOnError,\n });\n if (currentFile != null) {\n files.push(currentFile);\n }\n }\n return { patchMetadata, files };\n}\n\ninterface ProcessFileOptions {\n cacheKey?: string;\n isGitDiff?: boolean;\n oldFile?: FileContents;\n newFile?: FileContents;\n throwOnError?: boolean;\n}\n\nexport function processFile(\n fileDiffString: string,\n {\n cacheKey,\n isGitDiff = GIT_DIFF_FILE_BREAK_REGEX.test(fileDiffString),\n oldFile,\n newFile,\n throwOnError = false,\n }: ProcessFileOptions = {}\n): FileDiffMetadata | undefined {\n let lastHunkEnd = 0;\n const hunks = fileDiffString.split(FILE_CONTEXT_BLOB);\n let currentFile: FileDiffMetadata | undefined;\n const isPartial = oldFile == null || newFile == null;\n let deletionLineIndex = 0;\n let additionLineIndex = 0;\n for (const hunk of hunks) {\n const lines = hunk.split(SPLIT_WITH_NEWLINES);\n const firstLine = lines.shift();\n if (firstLine == null) {\n if (throwOnError) {\n throw Error('parsePatchContent: invalid hunk');\n } else {\n console.error('parsePatchContent: invalid hunk', hunk);\n }\n continue;\n }\n const fileHeaderMatch = firstLine.match(HUNK_HEADER);\n let additionLines = 0;\n let deletionLines = 0;\n // Setup currentFile, this should be the first iteration of our hunks, and\n // technically not a hunk\n if (fileHeaderMatch == null || currentFile == null) {\n if (currentFile != null) {\n if (throwOnError) {\n throw Error('parsePatchContent: Invalid hunk');\n } else {\n console.error('parsePatchContent: Invalid hunk', hunk);\n }\n continue;\n }\n currentFile = {\n name: '',\n type: 'change',\n hunks: [],\n splitLineCount: 0,\n unifiedLineCount: 0,\n isPartial,\n additionLines:\n !isPartial && oldFile != null && newFile != null\n ? newFile.contents.split(SPLIT_WITH_NEWLINES)\n : [],\n deletionLines:\n !isPartial && oldFile != null && newFile != null\n ? oldFile.contents.split(SPLIT_WITH_NEWLINES)\n : [],\n cacheKey,\n };\n // If either file is technically empty, then we should empty the\n // arrays respectively\n if (currentFile.additionLines.length === 1 && newFile?.contents === '') {\n currentFile.additionLines.length = 0;\n }\n if (currentFile.deletionLines.length === 1 && oldFile?.contents === '') {\n currentFile.deletionLines.length = 0;\n }\n\n // Push that first line back into the group of lines so we can properly\n // parse it out\n lines.unshift(firstLine);\n for (const line of lines) {\n const filenameMatch = line.match(\n isGitDiff ? FILENAME_HEADER_REGEX_GIT : FILENAME_HEADER_REGEX\n );\n if (line.startsWith('diff --git')) {\n const [, , prevName, , name] =\n line.trim().match(ALTERNATE_FILE_NAMES_GIT) ?? [];\n currentFile.name = name.trim();\n if (prevName !== name) {\n currentFile.prevName = prevName.trim();\n }\n } else if (filenameMatch != null) {\n const [, type, fileName] = filenameMatch;\n if (type === '---' && fileName !== '/dev/null') {\n currentFile.prevName = fileName.trim();\n currentFile.name = fileName.trim();\n } else if (type === '+++' && fileName !== '/dev/null') {\n currentFile.name = fileName.trim();\n }\n }\n // Git diffs have a bunch of additional metadata we can pull from\n else if (isGitDiff) {\n if (line.startsWith('new mode ')) {\n currentFile.mode = line.replace('new mode', '').trim();\n }\n if (line.startsWith('old mode ')) {\n currentFile.prevMode = line.replace('old mode', '').trim();\n }\n if (line.startsWith('new file mode')) {\n currentFile.type = 'new';\n currentFile.mode = line.replace('new file mode', '').trim();\n }\n if (line.startsWith('deleted file mode')) {\n currentFile.type = 'deleted';\n currentFile.mode = line.replace('deleted file mode', '').trim();\n }\n if (line.startsWith('similarity index')) {\n if (line.startsWith('similarity index 100%')) {\n currentFile.type = 'rename-pure';\n } else {\n currentFile.type = 'rename-changed';\n }\n }\n if (line.startsWith('index ')) {\n const [, prevObjectId, newObjectId, mode] =\n line.trim().match(INDEX_LINE_METADATA) ?? [];\n if (prevObjectId != null) {\n currentFile.prevObjectId = prevObjectId;\n }\n if (newObjectId != null) {\n currentFile.newObjectId = newObjectId;\n }\n if (mode != null) {\n currentFile.mode = mode;\n }\n }\n // We have to handle these for pure renames because there won't be\n // --- and +++ lines\n if (line.startsWith('rename from ')) {\n currentFile.prevName = line.replace('rename from ', '');\n }\n if (line.startsWith('rename to ')) {\n currentFile.name = line.replace('rename to ', '').trim();\n }\n }\n }\n continue;\n }\n\n // Otherwise, time to start parsing out the hunk\n let currentContent: ContextContent | ChangeContent | undefined;\n let lastLineType: 'context' | 'addition' | 'deletion' | undefined;\n\n // Strip trailing bare newlines (format-patch separators between commits)\n // if needed\n while (\n lines.length > 0 &&\n (lines[lines.length - 1] === '\\n' ||\n lines[lines.length - 1] === '\\r' ||\n lines[lines.length - 1] === '\\r\\n' ||\n lines[lines.length - 1] === '')\n ) {\n lines.pop();\n }\n\n const additionStart = parseInt(fileHeaderMatch[3]);\n const deletionStart = parseInt(fileHeaderMatch[1]);\n deletionLineIndex = isPartial ? deletionLineIndex : deletionStart - 1;\n additionLineIndex = isPartial ? additionLineIndex : additionStart - 1;\n\n const hunkData: Hunk = {\n collapsedBefore: 0,\n\n splitLineCount: 0,\n splitLineStart: 0,\n\n unifiedLineCount: 0,\n unifiedLineStart: 0,\n\n additionCount: parseInt(fileHeaderMatch[4] ?? '1'),\n additionStart,\n additionLines,\n\n deletionCount: parseInt(fileHeaderMatch[2] ?? '1'),\n deletionStart,\n deletionLines,\n\n deletionLineIndex,\n additionLineIndex,\n\n hunkContent: [],\n hunkContext: fileHeaderMatch[5],\n hunkSpecs: firstLine,\n\n noEOFCRAdditions: false,\n noEOFCRDeletions: false,\n };\n\n // Lets validate out hunkData to ensure there's no broken data from the\n // regex\n if (\n isNaN(hunkData.additionCount) ||\n isNaN(hunkData.deletionCount) ||\n isNaN(hunkData.additionStart) ||\n isNaN(hunkData.deletionStart)\n ) {\n if (throwOnError) {\n throw Error('parsePatchContent: invalid hunk metadata');\n } else {\n console.error('parsePatchContent: invalid hunk metadata', hunkData);\n }\n continue;\n }\n\n // Now we process each line of the hunk\n for (const rawLine of lines) {\n const parsedLine = parseLineType(rawLine);\n // If we can't properly process the line, well, lets just try to salvage\n // things and continue... It's possible an AI generated diff might have\n // some stray blank lines or something in there\n if (parsedLine == null) {\n console.error('processFile: invalid rawLine:', rawLine);\n continue;\n }\n\n const { type, line } = parsedLine;\n if (type === 'addition') {\n if (currentContent == null || currentContent.type !== 'change') {\n currentContent = createContentGroup(\n 'change',\n deletionLineIndex,\n additionLineIndex\n );\n hunkData.hunkContent.push(currentContent);\n }\n additionLineIndex++;\n if (isPartial) {\n currentFile.additionLines.push(line);\n }\n currentContent.additions++;\n additionLines++;\n lastLineType = 'addition';\n } else if (type === 'deletion') {\n if (currentContent == null || currentContent.type !== 'change') {\n currentContent = createContentGroup(\n 'change',\n deletionLineIndex,\n additionLineIndex\n );\n hunkData.hunkContent.push(currentContent);\n }\n deletionLineIndex++;\n if (isPartial) {\n currentFile.deletionLines.push(line);\n }\n currentContent.deletions++;\n deletionLines++;\n lastLineType = 'deletion';\n } else if (type === 'context') {\n if (currentContent == null || currentContent.type !== 'context') {\n currentContent = createContentGroup(\n 'context',\n deletionLineIndex,\n additionLineIndex\n );\n hunkData.hunkContent.push(currentContent);\n }\n additionLineIndex++;\n deletionLineIndex++;\n if (isPartial) {\n currentFile.deletionLines.push(line);\n currentFile.additionLines.push(line);\n }\n currentContent.lines++;\n lastLineType = 'context';\n } else if (type === 'metadata' && currentContent != null) {\n if (currentContent.type === 'context') {\n hunkData.noEOFCRAdditions = true;\n hunkData.noEOFCRDeletions = true;\n } else if (lastLineType === 'deletion') {\n hunkData.noEOFCRDeletions = true;\n } else if (lastLineType === 'addition') {\n hunkData.noEOFCRAdditions = true;\n }\n // If we're dealing with partial content from a diff, we need to strip\n // newlines manually from the content\n if (\n isPartial &&\n (lastLineType === 'addition' || lastLineType === 'context')\n ) {\n const lastIndex = currentFile.additionLines.length - 1;\n if (lastIndex >= 0) {\n currentFile.additionLines[lastIndex] = cleanLastNewline(\n currentFile.additionLines[lastIndex]\n );\n }\n }\n if (\n isPartial &&\n (lastLineType === 'deletion' || lastLineType === 'context')\n ) {\n const lastIndex = currentFile.deletionLines.length - 1;\n if (lastIndex >= 0) {\n currentFile.deletionLines[lastIndex] = cleanLastNewline(\n currentFile.deletionLines[lastIndex]\n );\n }\n }\n }\n }\n\n hunkData.additionLines = additionLines;\n hunkData.deletionLines = deletionLines;\n\n hunkData.collapsedBefore = Math.max(\n hunkData.additionStart - 1 - lastHunkEnd,\n 0\n );\n currentFile.hunks.push(hunkData);\n lastHunkEnd = hunkData.additionStart + hunkData.additionCount - 1;\n for (const content of hunkData.hunkContent) {\n if (content.type === 'context') {\n hunkData.splitLineCount += content.lines;\n hunkData.unifiedLineCount += content.lines;\n } else {\n hunkData.splitLineCount += Math.max(\n content.additions,\n content.deletions\n );\n hunkData.unifiedLineCount += content.deletions + content.additions;\n }\n }\n hunkData.splitLineStart =\n currentFile.splitLineCount + hunkData.collapsedBefore;\n hunkData.unifiedLineStart =\n currentFile.unifiedLineCount + hunkData.collapsedBefore;\n\n currentFile.splitLineCount +=\n hunkData.collapsedBefore + hunkData.splitLineCount;\n currentFile.unifiedLineCount +=\n hunkData.collapsedBefore + hunkData.unifiedLineCount;\n }\n if (currentFile == null) {\n return undefined;\n }\n\n // Account for collapsed lines after the final hunk and increment the\n // split/unified counts properly\n if (\n currentFile.hunks.length > 0 &&\n !isPartial &&\n currentFile.additionLines.length > 0 &&\n currentFile.deletionLines.length > 0\n ) {\n const lastHunk = currentFile.hunks[currentFile.hunks.length - 1];\n const lastHunkEnd = lastHunk.additionStart + lastHunk.additionCount - 1;\n const totalFileLines = currentFile.additionLines.length;\n const collapsedAfter = Math.max(totalFileLines - lastHunkEnd, 0);\n currentFile.splitLineCount += collapsedAfter;\n currentFile.unifiedLineCount += collapsedAfter;\n }\n\n // If this isn't a git diff style patch, then we'll need to sus out some\n // additional metadata manually\n if (!isGitDiff) {\n if (\n currentFile.prevName != null &&\n currentFile.name !== currentFile.prevName\n ) {\n if (currentFile.hunks.length > 0) {\n currentFile.type = 'rename-changed';\n } else {\n currentFile.type = 'rename-pure';\n }\n }\n // Sort of a hack for detecting deleted/added files...\n else if (newFile != null && newFile.contents === '') {\n currentFile.type = 'deleted';\n } else if (oldFile != null && oldFile.contents === '') {\n currentFile.type = 'new';\n }\n }\n if (\n currentFile.type !== 'rename-pure' &&\n currentFile.type !== 'rename-changed'\n ) {\n currentFile.prevName = undefined;\n }\n return currentFile;\n}\n\n/**\n * Parses a patch file string into an array of parsed patches.\n *\n * @param data - The raw patch file content (supports multi-commit patches)\n * @param cacheKeyPrefix - Optional prefix for generating cache keys. When provided,\n * each file in the patch will get a cache key in the format `prefix-patchIndex-fileIndex`.\n * This enables caching of rendered diff results in the worker pool.\n */\nexport function parsePatchFiles(\n data: string,\n cacheKeyPrefix?: string,\n throwOnError = false\n): ParsedPatch[] {\n // NOTE(amadeus): This function is pretty forgiving in that it can accept a\n // patch file that includes commit metdata, multiple commits, or not\n const patches: ParsedPatch[] = [];\n for (const patch of data.split(COMMIT_METADATA_SPLIT)) {\n try {\n patches.push(\n processPatch(\n patch,\n cacheKeyPrefix != null\n ? `${cacheKeyPrefix}-${patches.length}`\n : undefined,\n throwOnError\n )\n );\n } catch (error) {\n if (throwOnError) {\n throw error;\n } else {\n console.error(error);\n }\n }\n }\n return patches;\n}\n\nfunction createContentGroup(\n type: 'change',\n deletionLineIndex: number,\n additionLineIndex: number\n): ChangeContent;\nfunction createContentGroup(\n type: 'context',\n deletionLineIndex: number,\n additionLineIndex: number\n): ContextContent;\nfunction createContentGroup(\n type: 'change' | 'context',\n deletionLineIndex: number,\n additionLineIndex: number\n): ChangeContent | ContextContent {\n if (type === 'change') {\n return {\n type: 'change',\n additions: 0,\n deletions: 0,\n additionLineIndex,\n deletionLineIndex,\n };\n }\n return {\n type: 'context',\n lines: 0,\n additionLineIndex,\n deletionLineIndex,\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"prerenderHTMLIfNecessary.d.ts","names":[],"sources":["../../src/utils/prerenderHTMLIfNecessary.ts"],"sourcesContent":[],"mappings":";iBAAgB,wBAAA,UACL"}
1
+ {"version":3,"file":"prerenderHTMLIfNecessary.d.ts","names":["prerenderHTMLIfNecessary","HTMLElement"],"sources":["../../src/utils/prerenderHTMLIfNecessary.d.ts"],"sourcesContent":["export declare function prerenderHTMLIfNecessary(element: HTMLElement, html: string | undefined): void;\n//# sourceMappingURL=prerenderHTMLIfNecessary.d.ts.map"],"mappings":";iBAAwBA,wBAAAA,UAAkCC"}
@@ -1 +1 @@
1
- {"version":3,"file":"processLine.d.ts","names":[],"sources":["../../src/utils/processLine.ts"],"sourcesContent":[],"mappings":";;;;iBAKgB,WAAA,OACR,8BAEC,oBACN"}
1
+ {"version":3,"file":"processLine.d.ts","names":["ElementContent","Element","HASTElement","SharedRenderState","processLine"],"sources":["../../src/utils/processLine.d.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement } from 'hast';\nimport type { SharedRenderState } from '../types';\nexport declare function processLine(node: HASTElement, line: number, state: SharedRenderState): ElementContent;\n//# sourceMappingURL=processLine.d.ts.map"],"mappings":";;;;iBAEwBI,WAAAA,OAAkBF,8BAAkCC,oBAAoBH"}
@@ -1,4 +1,4 @@
1
- import { createHastElement, createTextNodeElement } from "./hast_utils.js";
1
+ import { createTextNodeElement } from "./hast_utils.js";
2
2
 
3
3
  //#region src/utils/processLine.ts
4
4
  function processLine(node, line, state) {
@@ -12,30 +12,13 @@ function processLine(node, line, state) {
12
12
  });
13
13
  throw new Error(errorMessage);
14
14
  }
15
- node.tagName = "span";
16
- node.properties["data-column-content"] = "";
15
+ node.tagName = "div";
16
+ node.properties["data-line"] = lineInfo.lineNumber;
17
+ node.properties["data-alt-line"] = lineInfo.altLineNumber;
18
+ node.properties["data-line-type"] = lineInfo.type;
19
+ node.properties["data-line-index"] = lineInfo.lineIndex;
17
20
  if (node.children.length === 0) node.children.push(createTextNodeElement("\n"));
18
- return createHastElement({
19
- tagName: "div",
20
- children: [createHastElement({
21
- tagName: "span",
22
- children: [createHastElement({
23
- tagName: "span",
24
- children: [{
25
- type: "text",
26
- value: `${lineInfo.lineNumber}`
27
- }],
28
- properties: { "data-line-number-content": "" }
29
- })],
30
- properties: { "data-column-number": "" }
31
- }), node],
32
- properties: {
33
- "data-line": lineInfo.lineNumber,
34
- "data-alt-line": lineInfo.altLineNumber,
35
- "data-line-type": lineInfo.type,
36
- "data-line-index": lineInfo.lineIndex
37
- }
38
- });
21
+ return node;
39
22
  }
40
23
 
41
24
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"processLine.js","names":[],"sources":["../../src/utils/processLine.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement } from 'hast';\n\nimport type { SharedRenderState } from '../types';\nimport { createHastElement, createTextNodeElement } from './hast_utils';\n\nexport function processLine(\n node: HASTElement,\n line: number,\n state: SharedRenderState\n): ElementContent {\n const lineInfo =\n typeof state.lineInfo === 'function'\n ? state.lineInfo(line)\n : state.lineInfo[line - 1];\n if (lineInfo == null) {\n const errorMessage = `processLine: line ${line}, contains no state.lineInfo`;\n console.error(errorMessage, { node, line, state });\n throw new Error(errorMessage);\n }\n // We need to convert the current line to a div but keep all the decorations\n // that may be applied\n node.tagName = 'span';\n node.properties['data-column-content'] = '';\n\n // NOTE(amadeus): We need to push newline characters into empty rows or else\n // copy/pasta will have issues\n if (node.children.length === 0) {\n node.children.push(createTextNodeElement('\\n'));\n }\n const children = [\n createHastElement({\n tagName: 'span',\n children: [\n createHastElement({\n tagName: 'span',\n children: [{ type: 'text', value: `${lineInfo.lineNumber}` }],\n properties: { 'data-line-number-content': '' },\n }),\n ],\n properties: { 'data-column-number': '' },\n }),\n node,\n ];\n return createHastElement({\n tagName: 'div',\n children,\n properties: {\n 'data-line': lineInfo.lineNumber,\n 'data-alt-line': lineInfo.altLineNumber,\n 'data-line-type': lineInfo.type,\n 'data-line-index': lineInfo.lineIndex,\n },\n });\n}\n"],"mappings":";;;AAKA,SAAgB,YACd,MACA,MACA,OACgB;CAChB,MAAM,WACJ,OAAO,MAAM,aAAa,aACtB,MAAM,SAAS,KAAK,GACpB,MAAM,SAAS,OAAO;AAC5B,KAAI,YAAY,MAAM;EACpB,MAAM,eAAe,qBAAqB,KAAK;AAC/C,UAAQ,MAAM,cAAc;GAAE;GAAM;GAAM;GAAO,CAAC;AAClD,QAAM,IAAI,MAAM,aAAa;;AAI/B,MAAK,UAAU;AACf,MAAK,WAAW,yBAAyB;AAIzC,KAAI,KAAK,SAAS,WAAW,EAC3B,MAAK,SAAS,KAAK,sBAAsB,KAAK,CAAC;AAgBjD,QAAO,kBAAkB;EACvB,SAAS;EACT,UAhBe,CACf,kBAAkB;GAChB,SAAS;GACT,UAAU,CACR,kBAAkB;IAChB,SAAS;IACT,UAAU,CAAC;KAAE,MAAM;KAAQ,OAAO,GAAG,SAAS;KAAc,CAAC;IAC7D,YAAY,EAAE,4BAA4B,IAAI;IAC/C,CAAC,CACH;GACD,YAAY,EAAE,sBAAsB,IAAI;GACzC,CAAC,EACF,KACD;EAIC,YAAY;GACV,aAAa,SAAS;GACtB,iBAAiB,SAAS;GAC1B,kBAAkB,SAAS;GAC3B,mBAAmB,SAAS;GAC7B;EACF,CAAC"}
1
+ {"version":3,"file":"processLine.js","names":[],"sources":["../../src/utils/processLine.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement } from 'hast';\n\nimport type { SharedRenderState } from '../types';\nimport { createTextNodeElement } from './hast_utils';\n\nexport function processLine(\n node: HASTElement,\n line: number,\n state: SharedRenderState\n): ElementContent {\n const lineInfo =\n typeof state.lineInfo === 'function'\n ? state.lineInfo(line)\n : state.lineInfo[line - 1];\n if (lineInfo == null) {\n const errorMessage = `processLine: line ${line}, contains no state.lineInfo`;\n console.error(errorMessage, { node, line, state });\n throw new Error(errorMessage);\n }\n // We need to convert the current line to a div but keep all the decorations\n // that may be applied\n node.tagName = 'div';\n node.properties['data-line'] = lineInfo.lineNumber;\n node.properties['data-alt-line'] = lineInfo.altLineNumber;\n node.properties['data-line-type'] = lineInfo.type;\n node.properties['data-line-index'] = lineInfo.lineIndex;\n\n // NOTE(amadeus): We need to push newline characters into empty rows or else\n // copy/pasta will have issues\n if (node.children.length === 0) {\n node.children.push(createTextNodeElement('\\n'));\n }\n\n return node;\n}\n"],"mappings":";;;AAKA,SAAgB,YACd,MACA,MACA,OACgB;CAChB,MAAM,WACJ,OAAO,MAAM,aAAa,aACtB,MAAM,SAAS,KAAK,GACpB,MAAM,SAAS,OAAO;AAC5B,KAAI,YAAY,MAAM;EACpB,MAAM,eAAe,qBAAqB,KAAK;AAC/C,UAAQ,MAAM,cAAc;GAAE;GAAM;GAAM;GAAO,CAAC;AAClD,QAAM,IAAI,MAAM,aAAa;;AAI/B,MAAK,UAAU;AACf,MAAK,WAAW,eAAe,SAAS;AACxC,MAAK,WAAW,mBAAmB,SAAS;AAC5C,MAAK,WAAW,oBAAoB,SAAS;AAC7C,MAAK,WAAW,qBAAqB,SAAS;AAI9C,KAAI,KAAK,SAAS,WAAW,EAC3B,MAAK,SAAS,KAAK,sBAAsB,KAAK,CAAC;AAGjD,QAAO"}
@@ -1,4 +1,4 @@
1
- import { DiffsHighlighter, FileDiffMetadata, ForcePlainTextOptions, RenderDiffOptions, ThemedDiffResult } from "../types.js";
1
+ import { DiffsHighlighter, FileDiffMetadata, ForceDiffPlainTextOptions, RenderDiffOptions, ThemedDiffResult } from "../types.js";
2
2
 
3
3
  //#region src/utils/renderDiffWithHighlighter.d.ts
4
4
  declare function renderDiffWithHighlighter(diff: FileDiffMetadata, highlighter: DiffsHighlighter, options: RenderDiffOptions, {
@@ -7,7 +7,7 @@ declare function renderDiffWithHighlighter(diff: FileDiffMetadata, highlighter:
7
7
  totalLines,
8
8
  expandedHunks,
9
9
  collapsedContextThreshold
10
- }?: ForcePlainTextOptions): ThemedDiffResult;
10
+ }?: ForceDiffPlainTextOptions): ThemedDiffResult;
11
11
  //#endregion
12
12
  export { renderDiffWithHighlighter };
13
13
  //# sourceMappingURL=renderDiffWithHighlighter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderDiffWithHighlighter.d.ts","names":[],"sources":["../../src/utils/renderDiffWithHighlighter.ts"],"sourcesContent":[],"mappings":";;;iBAqCgB,yBAAA,OACR,+BACO,2BACJ;;;;;;IAON,wBACF"}
1
+ {"version":3,"file":"renderDiffWithHighlighter.d.ts","names":["DiffsHighlighter","FileDiffMetadata","ForceDiffPlainTextOptions","RenderDiffOptions","ThemedDiffResult","renderDiffWithHighlighter","forcePlainText","startingLine","totalLines","expandedHunks","collapsedContextThreshold"],"sources":["../../src/utils/renderDiffWithHighlighter.d.ts"],"sourcesContent":["import type { DiffsHighlighter, FileDiffMetadata, ForceDiffPlainTextOptions, RenderDiffOptions, ThemedDiffResult } from '../types';\nexport declare function renderDiffWithHighlighter(diff: FileDiffMetadata, highlighter: DiffsHighlighter, options: RenderDiffOptions, { forcePlainText, startingLine, totalLines, expandedHunks, collapsedContextThreshold }?: ForceDiffPlainTextOptions): ThemedDiffResult;\n//# sourceMappingURL=renderDiffWithHighlighter.d.ts.map"],"mappings":";;;iBACwBK,yBAAAA,OAAgCJ,+BAA+BD,2BAA2BG;;;;;;IAA4GD,4BAA4BE"}