@pierre/diffs 1.3.0-beta.9 → 1.3.0-rc.2

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 (241) hide show
  1. package/README.md +9 -0
  2. package/dist/components/CodeView.d.ts +12 -13
  3. package/dist/components/CodeView.d.ts.map +1 -1
  4. package/dist/components/CodeView.js +50 -58
  5. package/dist/components/CodeView.js.map +1 -1
  6. package/dist/components/File.d.ts +10 -3
  7. package/dist/components/File.d.ts.map +1 -1
  8. package/dist/components/File.js +41 -10
  9. package/dist/components/File.js.map +1 -1
  10. package/dist/components/FileDiff.d.ts +37 -6
  11. package/dist/components/FileDiff.d.ts.map +1 -1
  12. package/dist/components/FileDiff.js +202 -19
  13. package/dist/components/FileDiff.js.map +1 -1
  14. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  15. package/dist/components/UnresolvedFile.js +7 -2
  16. package/dist/components/UnresolvedFile.js.map +1 -1
  17. package/dist/components/VirtualizedFile.d.ts +2 -1
  18. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  19. package/dist/components/VirtualizedFile.js +9 -5
  20. package/dist/components/VirtualizedFile.js.map +1 -1
  21. package/dist/components/VirtualizedFileDiff.d.ts +14 -0
  22. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  23. package/dist/components/VirtualizedFileDiff.js +61 -3
  24. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  25. package/dist/components/Virtualizer.d.ts +14 -2
  26. package/dist/components/Virtualizer.d.ts.map +1 -1
  27. package/dist/components/Virtualizer.js +27 -2
  28. package/dist/components/Virtualizer.js.map +1 -1
  29. package/dist/edit/index.d.ts +5 -0
  30. package/dist/edit/index.js +3 -0
  31. package/dist/editor/command.d.ts +1 -1
  32. package/dist/editor/command.d.ts.map +1 -1
  33. package/dist/editor/command.js +11 -0
  34. package/dist/editor/command.js.map +1 -1
  35. package/dist/editor/editStack.d.ts +6 -2
  36. package/dist/editor/editStack.d.ts.map +1 -1
  37. package/dist/editor/editStack.js +53 -12
  38. package/dist/editor/editStack.js.map +1 -1
  39. package/dist/editor/editor.d.ts +51 -23
  40. package/dist/editor/editor.d.ts.map +1 -1
  41. package/dist/editor/editor.js +977 -241
  42. package/dist/editor/editor.js.map +1 -1
  43. package/dist/editor/editor2.js +1 -1
  44. package/dist/editor/languages.d.ts +26 -0
  45. package/dist/editor/languages.d.ts.map +1 -0
  46. package/dist/editor/languages.js +363 -0
  47. package/dist/editor/languages.js.map +1 -0
  48. package/dist/editor/lineAnnotations.d.ts.map +1 -1
  49. package/dist/editor/lineAnnotations.js +25 -26
  50. package/dist/editor/lineAnnotations.js.map +1 -1
  51. package/dist/editor/marker.d.ts +5 -3
  52. package/dist/editor/marker.d.ts.map +1 -1
  53. package/dist/editor/marker.js +111 -91
  54. package/dist/editor/marker.js.map +1 -1
  55. package/dist/editor/matchBrackets.d.ts +3 -2
  56. package/dist/editor/matchBrackets.d.ts.map +1 -1
  57. package/dist/editor/matchBrackets.js +2 -10
  58. package/dist/editor/matchBrackets.js.map +1 -1
  59. package/dist/editor/pieceTable.d.ts +2 -1
  60. package/dist/editor/pieceTable.d.ts.map +1 -1
  61. package/dist/editor/pieceTable.js +103 -39
  62. package/dist/editor/pieceTable.js.map +1 -1
  63. package/dist/editor/platform.js +2 -0
  64. package/dist/editor/platform.js.map +1 -1
  65. package/dist/editor/popover.d.ts +25 -5
  66. package/dist/editor/popover.d.ts.map +1 -1
  67. package/dist/editor/popover.js +60 -14
  68. package/dist/editor/popover.js.map +1 -1
  69. package/dist/editor/searchPanel.d.ts.map +1 -1
  70. package/dist/editor/searchPanel.js +9 -2
  71. package/dist/editor/searchPanel.js.map +1 -1
  72. package/dist/editor/selection.d.ts +31 -11
  73. package/dist/editor/selection.d.ts.map +1 -1
  74. package/dist/editor/selection.js +198 -70
  75. package/dist/editor/selection.js.map +1 -1
  76. package/dist/editor/selectionAction.d.ts +4 -3
  77. package/dist/editor/selectionAction.d.ts.map +1 -1
  78. package/dist/editor/selectionAction.js +9 -5
  79. package/dist/editor/selectionAction.js.map +1 -1
  80. package/dist/editor/stateStorage.d.ts +15 -0
  81. package/dist/editor/stateStorage.d.ts.map +1 -0
  82. package/dist/editor/stateStorage.js +65 -0
  83. package/dist/editor/stateStorage.js.map +1 -0
  84. package/dist/editor/textDocument.d.ts +12 -77
  85. package/dist/editor/textDocument.d.ts.map +1 -1
  86. package/dist/editor/textDocument.js +76 -34
  87. package/dist/editor/textDocument.js.map +1 -1
  88. package/dist/editor/textMeasure.d.ts +7 -12
  89. package/dist/editor/textMeasure.d.ts.map +1 -1
  90. package/dist/editor/textMeasure.js +40 -32
  91. package/dist/editor/textMeasure.js.map +1 -1
  92. package/dist/editor/{tokenzier.d.ts → tokenizer.d.ts} +3 -3
  93. package/dist/editor/tokenizer.d.ts.map +1 -0
  94. package/dist/editor/{tokenzier.js → tokenizer.js} +170 -50
  95. package/dist/editor/tokenizer.js.map +1 -0
  96. package/dist/editor/utils.js +1 -1
  97. package/dist/editor/utils.js.map +1 -1
  98. package/dist/index.d.ts +4 -3
  99. package/dist/index.js +6 -5
  100. package/dist/managers/InteractionManager.d.ts +18 -7
  101. package/dist/managers/InteractionManager.d.ts.map +1 -1
  102. package/dist/managers/InteractionManager.js +154 -99
  103. package/dist/managers/InteractionManager.js.map +1 -1
  104. package/dist/managers/UniversalRenderingManager.d.ts.map +1 -1
  105. package/dist/managers/UniversalRenderingManager.js +1 -2
  106. package/dist/managers/UniversalRenderingManager.js.map +1 -1
  107. package/dist/react/CodeView.d.ts +13 -13
  108. package/dist/react/CodeView.d.ts.map +1 -1
  109. package/dist/react/CodeView.js +37 -28
  110. package/dist/react/CodeView.js.map +1 -1
  111. package/dist/react/EditContext.d.ts +20 -0
  112. package/dist/react/EditContext.d.ts.map +1 -0
  113. package/dist/react/EditContext.js +20 -0
  114. package/dist/react/EditContext.js.map +1 -0
  115. package/dist/react/File.d.ts +2 -1
  116. package/dist/react/File.d.ts.map +1 -1
  117. package/dist/react/File.js +3 -2
  118. package/dist/react/File.js.map +1 -1
  119. package/dist/react/FileDiff.d.ts +2 -2
  120. package/dist/react/FileDiff.d.ts.map +1 -1
  121. package/dist/react/FileDiff.js +3 -2
  122. package/dist/react/FileDiff.js.map +1 -1
  123. package/dist/react/MultiFileDiff.d.ts +2 -2
  124. package/dist/react/MultiFileDiff.d.ts.map +1 -1
  125. package/dist/react/MultiFileDiff.js +3 -2
  126. package/dist/react/MultiFileDiff.js.map +1 -1
  127. package/dist/react/PatchDiff.d.ts +2 -2
  128. package/dist/react/PatchDiff.d.ts.map +1 -1
  129. package/dist/react/PatchDiff.js +3 -2
  130. package/dist/react/PatchDiff.js.map +1 -1
  131. package/dist/react/UnresolvedFile.d.ts +1 -1
  132. package/dist/react/UnresolvedFile.js.map +1 -1
  133. package/dist/react/index.d.ts +4 -4
  134. package/dist/react/index.js +3 -3
  135. package/dist/react/types.d.ts +9 -1
  136. package/dist/react/types.d.ts.map +1 -1
  137. package/dist/react/utils/useFileDiffInstance.d.ts +5 -3
  138. package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
  139. package/dist/react/utils/useFileDiffInstance.js +24 -34
  140. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  141. package/dist/react/utils/useFileInstance.d.ts +5 -3
  142. package/dist/react/utils/useFileInstance.d.ts.map +1 -1
  143. package/dist/react/utils/useFileInstance.js +23 -33
  144. package/dist/react/utils/useFileInstance.js.map +1 -1
  145. package/dist/react/utils/useUnresolvedFileInstance.js +4 -4
  146. package/dist/react/utils/useUnresolvedFileInstance.js.map +1 -1
  147. package/dist/renderers/DiffHunksRenderer.d.ts +41 -1
  148. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  149. package/dist/renderers/DiffHunksRenderer.js +167 -29
  150. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  151. package/dist/renderers/FileRenderer.d.ts +20 -1
  152. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  153. package/dist/renderers/FileRenderer.js +119 -29
  154. package/dist/renderers/FileRenderer.js.map +1 -1
  155. package/dist/ssr/index.d.ts +2 -2
  156. package/dist/ssr/preloadDiffs.d.ts.map +1 -1
  157. package/dist/ssr/preloadDiffs.js +3 -1
  158. package/dist/ssr/preloadDiffs.js.map +1 -1
  159. package/dist/ssr/preloadFile.d.ts.map +1 -1
  160. package/dist/ssr/preloadFile.js +2 -0
  161. package/dist/ssr/preloadFile.js.map +1 -1
  162. package/dist/style.js +1 -1
  163. package/dist/types.d.ts +192 -42
  164. package/dist/types.d.ts.map +1 -1
  165. package/dist/utils/annotationHelpers.d.ts +20 -0
  166. package/dist/utils/annotationHelpers.d.ts.map +1 -0
  167. package/dist/utils/annotationHelpers.js +29 -0
  168. package/dist/utils/annotationHelpers.js.map +1 -0
  169. package/dist/utils/computeFileOffsets.d.ts.map +1 -1
  170. package/dist/utils/computeFileOffsets.js +34 -5
  171. package/dist/utils/computeFileOffsets.js.map +1 -1
  172. package/dist/utils/editSessionHunks.d.ts +66 -0
  173. package/dist/utils/editSessionHunks.d.ts.map +1 -0
  174. package/dist/utils/editSessionHunks.js +437 -0
  175. package/dist/utils/editSessionHunks.js.map +1 -0
  176. package/dist/utils/getDiffHunksRendererOptions.d.ts.map +1 -1
  177. package/dist/utils/getDiffHunksRendererOptions.js +2 -1
  178. package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
  179. package/dist/utils/getFileRendererOptions.d.ts.map +1 -1
  180. package/dist/utils/getFileRendererOptions.js +2 -1
  181. package/dist/utils/getFileRendererOptions.js.map +1 -1
  182. package/dist/utils/getHunkSideBoundaries.d.ts +7 -0
  183. package/dist/utils/getHunkSideBoundaries.d.ts.map +1 -0
  184. package/dist/utils/getHunkSideBoundaries.js +12 -0
  185. package/dist/utils/getHunkSideBoundaries.js.map +1 -0
  186. package/dist/utils/getTotalLineCountFromHunks.d.ts.map +1 -1
  187. package/dist/utils/getTotalLineCountFromHunks.js +2 -1
  188. package/dist/utils/getTotalLineCountFromHunks.js.map +1 -1
  189. package/dist/utils/hydratePartialDiff.d.ts.map +1 -1
  190. package/dist/utils/hydratePartialDiff.js +4 -3
  191. package/dist/utils/hydratePartialDiff.js.map +1 -1
  192. package/dist/utils/isGutterUtilityPath.d.ts +5 -0
  193. package/dist/utils/isGutterUtilityPath.d.ts.map +1 -0
  194. package/dist/utils/isGutterUtilityPath.js +12 -0
  195. package/dist/utils/isGutterUtilityPath.js.map +1 -0
  196. package/dist/utils/iterateOverDiff.d.ts.map +1 -1
  197. package/dist/utils/iterateOverDiff.js +17 -12
  198. package/dist/utils/iterateOverDiff.js.map +1 -1
  199. package/dist/utils/parseMergeConflictDiffFromFile.d.ts.map +1 -1
  200. package/dist/utils/parseMergeConflictDiffFromFile.js +9 -6
  201. package/dist/utils/parseMergeConflictDiffFromFile.js.map +1 -1
  202. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  203. package/dist/utils/parsePatchFiles.js +6 -3
  204. package/dist/utils/parsePatchFiles.js.map +1 -1
  205. package/dist/utils/realignChangeContent.d.ts +33 -0
  206. package/dist/utils/realignChangeContent.d.ts.map +1 -0
  207. package/dist/utils/realignChangeContent.js +148 -0
  208. package/dist/utils/realignChangeContent.js.map +1 -0
  209. package/dist/utils/renderDiffWithHighlighter.js +1 -1
  210. package/dist/utils/resolveRegion.d.ts.map +1 -1
  211. package/dist/utils/resolveRegion.js +18 -2
  212. package/dist/utils/resolveRegion.js.map +1 -1
  213. package/dist/utils/shouldUseTokenTransformer.d.ts +7 -3
  214. package/dist/utils/shouldUseTokenTransformer.d.ts.map +1 -1
  215. package/dist/utils/shouldUseTokenTransformer.js +1 -1
  216. package/dist/utils/shouldUseTokenTransformer.js.map +1 -1
  217. package/dist/utils/updateDiffHunks.d.ts +8 -2
  218. package/dist/utils/updateDiffHunks.d.ts.map +1 -1
  219. package/dist/utils/updateDiffHunks.js +9 -7
  220. package/dist/utils/updateDiffHunks.js.map +1 -1
  221. package/dist/utils/virtualDiffLayout.d.ts +42 -2
  222. package/dist/utils/virtualDiffLayout.d.ts.map +1 -1
  223. package/dist/utils/virtualDiffLayout.js +101 -7
  224. package/dist/utils/virtualDiffLayout.js.map +1 -1
  225. package/dist/worker/WorkerPoolManager.d.ts +2 -1
  226. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  227. package/dist/worker/WorkerPoolManager.js +3 -0
  228. package/dist/worker/WorkerPoolManager.js.map +1 -1
  229. package/dist/worker/worker-portable.js +60 -20
  230. package/dist/worker/worker-portable.js.map +1 -1
  231. package/dist/worker/worker.js +61 -19
  232. package/dist/worker/worker.js.map +1 -1
  233. package/package.json +10 -7
  234. package/dist/editor/index.d.ts +0 -3
  235. package/dist/editor/index.js +0 -3
  236. package/dist/editor/tokenzier.d.ts.map +0 -1
  237. package/dist/editor/tokenzier.js.map +0 -1
  238. package/dist/react/EditorContext.d.ts +0 -15
  239. package/dist/react/EditorContext.d.ts.map +0 -1
  240. package/dist/react/EditorContext.js +0 -23
  241. package/dist/react/EditorContext.js.map +0 -1
@@ -1,12 +1,12 @@
1
1
  import { areOptionsEqual } from "../../utils/areOptionsEqual.js";
2
2
  import { parseMergeConflictDiffFromFile } from "../../utils/parseMergeConflictDiffFromFile.js";
3
3
  import { UnresolvedFile } from "../../components/UnresolvedFile.js";
4
- import { noopRender } from "../constants.js";
5
4
  import { useStableCallback } from "./useStableCallback.js";
5
+ import { noopRender } from "../constants.js";
6
6
  import { WorkerPoolContext } from "../WorkerPoolContext.js";
7
7
  import { useCallback, useContext, useEffect, useLayoutEffect, useRef, useState } from "react";
8
8
  //#region src/react/utils/useUnresolvedFileInstance.ts
9
- const useIsometricEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
9
+ const useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
10
10
  function useUnresolvedFileInstance({ file, options, lineAnnotations, selectedLines, prerenderedHTML, hasConflictUtility, hasGutterRenderUtility, hasCustomHeader, disableWorkerPool }) {
11
11
  const [{ fileDiff, actions, markerRows }, setState] = useState(() => {
12
12
  const { fileDiff, actions, markerRows } = parseMergeConflictDiffFromFile(file, options?.maxContextLines);
@@ -55,7 +55,7 @@ function useUnresolvedFileInstance({ file, options, lineAnnotations, selectedLin
55
55
  instanceRef.current = null;
56
56
  }
57
57
  });
58
- useIsometricEffect(() => {
58
+ useIsomorphicLayoutEffect(() => {
59
59
  if (instanceRef.current == null) return;
60
60
  const instance = instanceRef.current;
61
61
  const newOptions = mergeUnresolvedOptions({
@@ -66,7 +66,7 @@ function useUnresolvedFileInstance({ file, options, lineAnnotations, selectedLin
66
66
  onMergeConflictAction,
67
67
  options
68
68
  });
69
- const forceRender = !areOptionsEqual(instance.options, newOptions);
69
+ const forceRender = newOptions !== void 0 && !areOptionsEqual(instance.options, newOptions);
70
70
  instance.setOptions(newOptions);
71
71
  instance.render({
72
72
  fileDiff,
@@ -1 +1 @@
1
- {"version":3,"file":"useUnresolvedFileInstance.js","names":["UnresolvedFileClass"],"sources":["../../../src/react/utils/useUnresolvedFileInstance.ts"],"sourcesContent":["import {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\n\nimport {\n UnresolvedFile,\n UnresolvedFile as UnresolvedFileClass,\n type UnresolvedFileOptions,\n} from '../../components/UnresolvedFile';\nimport type { GetHoveredLineResult } from '../../managers/InteractionManager';\nimport type {\n DiffLineAnnotation,\n FileContents,\n FileDiffMetadata,\n MergeConflictActionPayload,\n MergeConflictMarkerRow,\n SelectedLineRange,\n} from '../../types';\nimport { areOptionsEqual } from '../../utils/areOptionsEqual';\nimport {\n type MergeConflictDiffAction,\n parseMergeConflictDiffFromFile,\n} from '../../utils/parseMergeConflictDiffFromFile';\nimport { noopRender } from '../constants';\nimport type { UnresolvedFileReactOptions } from '../UnresolvedFile';\nimport { WorkerPoolContext } from '../WorkerPoolContext';\nimport { useStableCallback } from './useStableCallback';\n\nconst useIsometricEffect =\n typeof window === 'undefined' ? useEffect : useLayoutEffect;\n\ninterface UseUnresolvedFileInstanceProps<LAnnotation> {\n file: FileContents;\n options?: UnresolvedFileReactOptions<LAnnotation>;\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined;\n selectedLines: SelectedLineRange | null | undefined;\n prerenderedHTML: string | undefined;\n hasConflictUtility: boolean;\n hasGutterRenderUtility: boolean;\n hasCustomHeader: boolean;\n disableWorkerPool: boolean;\n}\n\ninterface UseUnresolvedFileInstanceReturn<LAnnotation> {\n fileDiff: FileDiffMetadata;\n actions: (MergeConflictDiffAction | undefined)[];\n markerRows: MergeConflictMarkerRow[];\n ref(node: HTMLElement | null): void;\n getHoveredLine(): GetHoveredLineResult<'diff'> | undefined;\n getInstance(): UnresolvedFile<LAnnotation> | undefined;\n}\n\nexport function useUnresolvedFileInstance<LAnnotation>({\n file,\n options,\n lineAnnotations,\n selectedLines,\n prerenderedHTML,\n hasConflictUtility,\n hasGutterRenderUtility,\n hasCustomHeader,\n disableWorkerPool,\n}: UseUnresolvedFileInstanceProps<LAnnotation>): UseUnresolvedFileInstanceReturn<LAnnotation> {\n const [{ fileDiff, actions, markerRows }, setState] = useState(() => {\n const { fileDiff, actions, markerRows } = parseMergeConflictDiffFromFile(\n file,\n options?.maxContextLines\n );\n return { fileDiff, actions, markerRows };\n });\n // UnresolvedFile is intentionally uncontrolled in React. Keep an internal\n // source-of-truth file so sequential conflict actions apply to the latest\n // resolved contents rather than the initial prop value.\n const onMergeConflictAction = useStableCallback(\n (\n payload: MergeConflictActionPayload,\n instance: UnresolvedFile<LAnnotation>\n ) => {\n setState((prevState) => {\n const { fileDiff, actions, markerRows } =\n instance.resolveConflict(\n payload.conflict.conflictIndex,\n payload.resolution,\n prevState.fileDiff\n ) ?? {};\n if (fileDiff == null || actions == null || markerRows == null) {\n return prevState;\n } else {\n return { fileDiff, actions, markerRows };\n }\n });\n }\n );\n const controlledSelection = selectedLines !== undefined;\n const poolManager = useContext(WorkerPoolContext);\n const instanceRef = useRef<UnresolvedFileClass<LAnnotation> | null>(null);\n const ref = useStableCallback((fileContainer: HTMLElement | null) => {\n if (fileContainer != null) {\n if (instanceRef.current != null) {\n throw new Error(\n 'useUnresolvedFileInstance: An instance should not already exist when a node is created'\n );\n }\n instanceRef.current = new UnresolvedFileClass(\n mergeUnresolvedOptions({\n controlledSelection,\n hasConflictUtility,\n hasCustomHeader,\n hasGutterRenderUtility,\n onMergeConflictAction,\n options,\n }),\n !disableWorkerPool ? poolManager : undefined,\n true\n );\n void instanceRef.current.hydrate({\n fileDiff,\n actions,\n markerRows,\n fileContainer,\n lineAnnotations,\n prerenderedHTML,\n });\n } else {\n if (instanceRef.current == null) {\n throw new Error(\n 'useUnresolvedFileInstance: A UnresolvedFile instance should exist when unmounting'\n );\n }\n instanceRef.current.cleanUp();\n instanceRef.current = null;\n }\n });\n\n useIsometricEffect(() => {\n if (instanceRef.current == null) return;\n const instance = instanceRef.current;\n const newOptions = mergeUnresolvedOptions({\n controlledSelection,\n hasConflictUtility,\n hasCustomHeader,\n hasGutterRenderUtility,\n onMergeConflictAction,\n options,\n });\n const forceRender = !areOptionsEqual(instance.options, newOptions);\n instance.setOptions(newOptions);\n void instance.render({\n fileDiff,\n actions,\n markerRows,\n lineAnnotations,\n forceRender,\n });\n if (selectedLines !== undefined) {\n instance.setSelectedLines(selectedLines);\n }\n });\n\n const getHoveredLine = useCallback(():\n | GetHoveredLineResult<'diff'>\n | undefined => {\n return instanceRef.current?.getHoveredLine();\n }, []);\n\n const getInstance = useCallback(() => {\n return instanceRef.current ?? undefined;\n }, []);\n\n return { ref, getHoveredLine, fileDiff, actions, markerRows, getInstance };\n}\n\ninterface MergeUnresolvedOptionsProps<LAnnotation> {\n options: UnresolvedFileReactOptions<LAnnotation> | undefined;\n controlledSelection: boolean;\n onMergeConflictAction: UnresolvedFileOptions<LAnnotation>['onMergeConflictAction'];\n hasConflictUtility: boolean;\n hasGutterRenderUtility: boolean;\n hasCustomHeader: boolean;\n}\n\nfunction mergeUnresolvedOptions<LAnnotation>({\n options,\n controlledSelection,\n onMergeConflictAction,\n hasConflictUtility,\n hasCustomHeader,\n hasGutterRenderUtility,\n}: MergeUnresolvedOptionsProps<LAnnotation>): UnresolvedFileOptions<LAnnotation> {\n return {\n ...options,\n controlledSelection,\n onMergeConflictAction,\n hunkSeparators:\n options?.hunkSeparators === 'custom'\n ? noopRender\n : options?.hunkSeparators,\n // Add a placeholder type for the custom render\n mergeConflictActionsType:\n hasConflictUtility || options?.mergeConflictActionsType === 'custom'\n ? noopRender\n : options?.mergeConflictActionsType,\n renderCustomHeader: hasCustomHeader ? noopRender : undefined,\n renderGutterUtility: hasGutterRenderUtility ? noopRender : undefined,\n };\n}\n"],"mappings":";;;;;;;;AAiCA,MAAM,qBACJ,OAAO,WAAW,cAAc,YAAY;AAuB9C,SAAgB,0BAAuC,EACrD,MACA,SACA,iBACA,eACA,iBACA,oBACA,wBACA,iBACA,qBAC4F;CAC5F,MAAM,CAAC,EAAE,UAAU,SAAS,cAAc,YAAY,eAAe;EACnE,MAAM,EAAE,UAAU,SAAS,eAAe,+BACxC,MACA,SAAS,eACX;EACA,OAAO;GAAE;GAAU;GAAS;EAAW;CACzC,CAAC;CAID,MAAM,wBAAwB,mBAE1B,SACA,aACG;EACH,UAAU,cAAc;GACtB,MAAM,EAAE,UAAU,SAAS,eACzB,SAAS,gBACP,QAAQ,SAAS,eACjB,QAAQ,YACR,UAAU,QACZ,KAAK,CAAC;GACR,IAAI,YAAY,QAAQ,WAAW,QAAQ,cAAc,MACvD,OAAO;QAEP,OAAO;IAAE;IAAU;IAAS;GAAW;EAE3C,CAAC;CACH,CACF;CACA,MAAM,sBAAsB,kBAAkB,KAAA;CAC9C,MAAM,cAAc,WAAW,iBAAiB;CAChD,MAAM,cAAc,OAAgD,IAAI;CACxE,MAAM,MAAM,mBAAmB,kBAAsC;EACnE,IAAI,iBAAiB,MAAM;GACzB,IAAI,YAAY,WAAW,MACzB,MAAM,IAAI,MACR,wFACF;GAEF,YAAY,UAAU,IAAIA,eACxB,uBAAuB;IACrB;IACA;IACA;IACA;IACA;IACA;GACF,CAAC,GACD,CAAC,oBAAoB,cAAc,KAAA,GACnC,IACF;GACA,YAAiB,QAAQ,QAAQ;IAC/B;IACA;IACA;IACA;IACA;IACA;GACF,CAAC;EACH,OAAO;GACL,IAAI,YAAY,WAAW,MACzB,MAAM,IAAI,MACR,mFACF;GAEF,YAAY,QAAQ,QAAQ;GAC5B,YAAY,UAAU;EACxB;CACF,CAAC;CAED,yBAAyB;EACvB,IAAI,YAAY,WAAW,MAAM;EACjC,MAAM,WAAW,YAAY;EAC7B,MAAM,aAAa,uBAAuB;GACxC;GACA;GACA;GACA;GACA;GACA;EACF,CAAC;EACD,MAAM,cAAc,CAAC,gBAAgB,SAAS,SAAS,UAAU;EACjE,SAAS,WAAW,UAAU;EAC9B,SAAc,OAAO;GACnB;GACA;GACA;GACA;GACA;EACF,CAAC;EACD,IAAI,kBAAkB,KAAA,GACpB,SAAS,iBAAiB,aAAa;CAE3C,CAAC;CAYD,OAAO;EAAE;EAAK,gBAVS,kBAEN;GACf,OAAO,YAAY,SAAS,eAAe;EAC7C,GAAG,CAAC,CAMuB;EAAG;EAAU;EAAS;EAAY,aAJzC,kBAAkB;GACpC,OAAO,YAAY,WAAW,KAAA;EAChC,GAAG,CAAC,CAEmE;CAAE;AAC3E;AAWA,SAAS,uBAAoC,EAC3C,SACA,qBACA,uBACA,oBACA,iBACA,0BAC+E;CAC/E,OAAO;EACL,GAAG;EACH;EACA;EACA,gBACE,SAAS,mBAAmB,WACxB,aACA,SAAS;EAEf,0BACE,sBAAsB,SAAS,6BAA6B,WACxD,aACA,SAAS;EACf,oBAAoB,kBAAkB,aAAa,KAAA;EACnD,qBAAqB,yBAAyB,aAAa,KAAA;CAC7D;AACF"}
1
+ {"version":3,"file":"useUnresolvedFileInstance.js","names":["UnresolvedFileClass"],"sources":["../../../src/react/utils/useUnresolvedFileInstance.ts"],"sourcesContent":["import {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\n\nimport {\n UnresolvedFile,\n UnresolvedFile as UnresolvedFileClass,\n type UnresolvedFileOptions,\n} from '../../components/UnresolvedFile';\nimport type { GetHoveredLineResult } from '../../managers/InteractionManager';\nimport type {\n DiffLineAnnotation,\n FileContents,\n FileDiffMetadata,\n MergeConflictActionPayload,\n MergeConflictMarkerRow,\n SelectedLineRange,\n} from '../../types';\nimport { areOptionsEqual } from '../../utils/areOptionsEqual';\nimport {\n type MergeConflictDiffAction,\n parseMergeConflictDiffFromFile,\n} from '../../utils/parseMergeConflictDiffFromFile';\nimport { noopRender } from '../constants';\nimport type { UnresolvedFileReactOptions } from '../UnresolvedFile';\nimport { WorkerPoolContext } from '../WorkerPoolContext';\nimport { useStableCallback } from './useStableCallback';\n\nconst useIsomorphicLayoutEffect =\n typeof window === 'undefined' ? useEffect : useLayoutEffect;\n\ninterface UseUnresolvedFileInstanceProps<LAnnotation> {\n file: FileContents;\n options?: UnresolvedFileReactOptions<LAnnotation>;\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined;\n selectedLines: SelectedLineRange | null | undefined;\n prerenderedHTML: string | undefined;\n hasConflictUtility: boolean;\n hasGutterRenderUtility: boolean;\n hasCustomHeader: boolean;\n disableWorkerPool: boolean;\n}\n\ninterface UseUnresolvedFileInstanceReturn<LAnnotation> {\n fileDiff: FileDiffMetadata;\n actions: (MergeConflictDiffAction | undefined)[];\n markerRows: MergeConflictMarkerRow[];\n ref(node: HTMLElement | null): void;\n getHoveredLine(): GetHoveredLineResult<'diff'> | undefined;\n getInstance(): UnresolvedFile<LAnnotation> | undefined;\n}\n\nexport function useUnresolvedFileInstance<LAnnotation>({\n file,\n options,\n lineAnnotations,\n selectedLines,\n prerenderedHTML,\n hasConflictUtility,\n hasGutterRenderUtility,\n hasCustomHeader,\n disableWorkerPool,\n}: UseUnresolvedFileInstanceProps<LAnnotation>): UseUnresolvedFileInstanceReturn<LAnnotation> {\n const [{ fileDiff, actions, markerRows }, setState] = useState(() => {\n const { fileDiff, actions, markerRows } = parseMergeConflictDiffFromFile(\n file,\n options?.maxContextLines\n );\n return { fileDiff, actions, markerRows };\n });\n // UnresolvedFile is intentionally uncontrolled in React. Keep an internal\n // source-of-truth file so sequential conflict actions apply to the latest\n // resolved contents rather than the initial prop value.\n const onMergeConflictAction = useStableCallback(\n (\n payload: MergeConflictActionPayload,\n instance: UnresolvedFile<LAnnotation>\n ) => {\n setState((prevState) => {\n const { fileDiff, actions, markerRows } =\n instance.resolveConflict(\n payload.conflict.conflictIndex,\n payload.resolution,\n prevState.fileDiff\n ) ?? {};\n if (fileDiff == null || actions == null || markerRows == null) {\n return prevState;\n } else {\n return { fileDiff, actions, markerRows };\n }\n });\n }\n );\n const controlledSelection = selectedLines !== undefined;\n const poolManager = useContext(WorkerPoolContext);\n const instanceRef = useRef<UnresolvedFileClass<LAnnotation> | null>(null);\n const ref = useStableCallback((fileContainer: HTMLElement | null) => {\n if (fileContainer != null) {\n if (instanceRef.current != null) {\n throw new Error(\n 'useUnresolvedFileInstance: An instance should not already exist when a node is created'\n );\n }\n instanceRef.current = new UnresolvedFileClass(\n mergeUnresolvedOptions({\n controlledSelection,\n hasConflictUtility,\n hasCustomHeader,\n hasGutterRenderUtility,\n onMergeConflictAction,\n options,\n }),\n !disableWorkerPool ? poolManager : undefined,\n true\n );\n void instanceRef.current.hydrate({\n fileDiff,\n actions,\n markerRows,\n fileContainer,\n lineAnnotations,\n prerenderedHTML,\n });\n } else {\n if (instanceRef.current == null) {\n throw new Error(\n 'useUnresolvedFileInstance: A UnresolvedFile instance should exist when unmounting'\n );\n }\n instanceRef.current.cleanUp();\n instanceRef.current = null;\n }\n });\n\n useIsomorphicLayoutEffect(() => {\n if (instanceRef.current == null) return;\n const instance = instanceRef.current;\n const newOptions = mergeUnresolvedOptions({\n controlledSelection,\n hasConflictUtility,\n hasCustomHeader,\n hasGutterRenderUtility,\n onMergeConflictAction,\n options,\n });\n // setOptions(undefined) is a no-op, so an undefined merge result never\n // requires a forced render — comparing it against the instance's\n // constructor-default options would force a full render on every commit.\n const forceRender =\n newOptions !== undefined &&\n !areOptionsEqual(instance.options, newOptions);\n instance.setOptions(newOptions);\n void instance.render({\n fileDiff,\n actions,\n markerRows,\n lineAnnotations,\n forceRender,\n });\n if (selectedLines !== undefined) {\n instance.setSelectedLines(selectedLines);\n }\n });\n\n const getHoveredLine = useCallback(():\n | GetHoveredLineResult<'diff'>\n | undefined => {\n return instanceRef.current?.getHoveredLine();\n }, []);\n\n const getInstance = useCallback(() => {\n return instanceRef.current ?? undefined;\n }, []);\n\n return { ref, getHoveredLine, fileDiff, actions, markerRows, getInstance };\n}\n\ninterface MergeUnresolvedOptionsProps<LAnnotation> {\n options: UnresolvedFileReactOptions<LAnnotation> | undefined;\n controlledSelection: boolean;\n onMergeConflictAction: UnresolvedFileOptions<LAnnotation>['onMergeConflictAction'];\n hasConflictUtility: boolean;\n hasGutterRenderUtility: boolean;\n hasCustomHeader: boolean;\n}\n\nfunction mergeUnresolvedOptions<LAnnotation>({\n options,\n controlledSelection,\n onMergeConflictAction,\n hasConflictUtility,\n hasCustomHeader,\n hasGutterRenderUtility,\n}: MergeUnresolvedOptionsProps<LAnnotation>): UnresolvedFileOptions<LAnnotation> {\n return {\n ...options,\n controlledSelection,\n onMergeConflictAction,\n hunkSeparators:\n options?.hunkSeparators === 'custom'\n ? noopRender\n : options?.hunkSeparators,\n // Add a placeholder type for the custom render\n mergeConflictActionsType:\n hasConflictUtility || options?.mergeConflictActionsType === 'custom'\n ? noopRender\n : options?.mergeConflictActionsType,\n renderCustomHeader: hasCustomHeader ? noopRender : undefined,\n renderGutterUtility: hasGutterRenderUtility ? noopRender : undefined,\n };\n}\n"],"mappings":";;;;;;;;AAiCA,MAAM,4BACJ,OAAO,WAAW,cAAc,YAAY;AAuB9C,SAAgB,0BAAuC,EACrD,MACA,SACA,iBACA,eACA,iBACA,oBACA,wBACA,iBACA,qBAC4F;CAC5F,MAAM,CAAC,EAAE,UAAU,SAAS,cAAc,YAAY,eAAe;EACnE,MAAM,EAAE,UAAU,SAAS,eAAe,+BACxC,MACA,SAAS,eACX;EACA,OAAO;GAAE;GAAU;GAAS;EAAW;CACzC,CAAC;CAID,MAAM,wBAAwB,mBAE1B,SACA,aACG;EACH,UAAU,cAAc;GACtB,MAAM,EAAE,UAAU,SAAS,eACzB,SAAS,gBACP,QAAQ,SAAS,eACjB,QAAQ,YACR,UAAU,QACZ,KAAK,CAAC;GACR,IAAI,YAAY,QAAQ,WAAW,QAAQ,cAAc,MACvD,OAAO;QAEP,OAAO;IAAE;IAAU;IAAS;GAAW;EAE3C,CAAC;CACH,CACF;CACA,MAAM,sBAAsB,kBAAkB,KAAA;CAC9C,MAAM,cAAc,WAAW,iBAAiB;CAChD,MAAM,cAAc,OAAgD,IAAI;CACxE,MAAM,MAAM,mBAAmB,kBAAsC;EACnE,IAAI,iBAAiB,MAAM;GACzB,IAAI,YAAY,WAAW,MACzB,MAAM,IAAI,MACR,wFACF;GAEF,YAAY,UAAU,IAAIA,eACxB,uBAAuB;IACrB;IACA;IACA;IACA;IACA;IACA;GACF,CAAC,GACD,CAAC,oBAAoB,cAAc,KAAA,GACnC,IACF;GACA,YAAiB,QAAQ,QAAQ;IAC/B;IACA;IACA;IACA;IACA;IACA;GACF,CAAC;EACH,OAAO;GACL,IAAI,YAAY,WAAW,MACzB,MAAM,IAAI,MACR,mFACF;GAEF,YAAY,QAAQ,QAAQ;GAC5B,YAAY,UAAU;EACxB;CACF,CAAC;CAED,gCAAgC;EAC9B,IAAI,YAAY,WAAW,MAAM;EACjC,MAAM,WAAW,YAAY;EAC7B,MAAM,aAAa,uBAAuB;GACxC;GACA;GACA;GACA;GACA;GACA;EACF,CAAC;EAID,MAAM,cACJ,eAAe,KAAA,KACf,CAAC,gBAAgB,SAAS,SAAS,UAAU;EAC/C,SAAS,WAAW,UAAU;EAC9B,SAAc,OAAO;GACnB;GACA;GACA;GACA;GACA;EACF,CAAC;EACD,IAAI,kBAAkB,KAAA,GACpB,SAAS,iBAAiB,aAAa;CAE3C,CAAC;CAYD,OAAO;EAAE;EAAK,gBAVS,kBAEN;GACf,OAAO,YAAY,SAAS,eAAe;EAC7C,GAAG,CAAC,CAMuB;EAAG;EAAU;EAAS;EAAY,aAJzC,kBAAkB;GACpC,OAAO,YAAY,WAAW,KAAA;EAChC,GAAG,CAAC,CAEmE;CAAE;AAC3E;AAWA,SAAS,uBAAoC,EAC3C,SACA,qBACA,uBACA,oBACA,iBACA,0BAC+E;CAC/E,OAAO;EACL,GAAG;EACH;EACA;EACA,gBACE,SAAS,mBAAmB,WACxB,aACA,SAAS;EAEf,0BACE,sBAAsB,SAAS,6BAA6B,WACxD,aACA,SAAS;EACf,oBAAoB,kBAAkB,aAAa,KAAA;EACnD,qBAAqB,yBAAyB,aAAa,KAAA;CAC7D;AACF"}
@@ -81,9 +81,36 @@ declare class DiffHunksRenderer<LAnnotation = undefined> {
81
81
  private additionAnnotations;
82
82
  private computedLang;
83
83
  private renderCache;
84
+ private editSessionActive;
84
85
  constructor(options?: DiffHunksRendererOptions, onRenderUpdate?: (() => unknown) | undefined, workerManager?: WorkerPoolManager | undefined);
85
86
  cleanUp(): void;
86
87
  recycle(): void;
88
+ /**
89
+ * Enter edit-session mode: hunk updates preserve the current region
90
+ * skeleton instead of recomputing hunks, and rendering happens locally
91
+ * with the token transformer forced on (worker-pool requests/results are
92
+ * suspended for this renderer). Called on every editor attach, including
93
+ * a re-attach after recycle.
94
+ */
95
+ beginEditSession(): void;
96
+ /** Leave edit-session mode. The exit recompute is the host's concern. */
97
+ endEditSession(): void;
98
+ /**
99
+ * Ensures that the DOM is compatible with editor render updates
100
+ */
101
+ editorRenderReady(): boolean;
102
+ /**
103
+ * Re-highlights the current diff in the background and swaps the fresh
104
+ * result in (with a re-render) once it completes. Needed after an edit
105
+ * session's exit recompute: session passes plain-fill shifted lines in the
106
+ * cached result, and the recompute mutates the diff in place (same object,
107
+ * same cacheKey), so identity/cacheKey checks would otherwise treat the
108
+ * stale highlight as current forever. The current result — content-correct,
109
+ * mostly highlighted — keeps rendering until the fresh one lands, so no
110
+ * interim paint drops highlighting.
111
+ */
112
+ refreshHighlightedResult(): Promise<void>;
113
+ private applyRefreshedResult;
87
114
  get diffCache(): FileDiffMetadata | undefined;
88
115
  clearRenderCache(): void;
89
116
  setOptions(options: DiffHunksRendererOptions): void;
@@ -91,9 +118,20 @@ declare class DiffHunksRenderer<LAnnotation = undefined> {
91
118
  expandHunk(index: number, direction: ExpansionDirections, expansionLineCount?: number): void;
92
119
  getExpandedHunk(hunkIndex: number): HunkExpansionRegion;
93
120
  getExpandedHunksMap(): Map<number, HunkExpansionRegion>;
121
+ /** Replace the whole expansion map (session-exit expansion remapping). */
122
+ setExpandedHunksMap(expandedHunks: Map<number, HunkExpansionRegion>): void;
94
123
  setLineAnnotations(lineAnnotations: DiffLineAnnotation<LAnnotation>[]): void;
95
- updateRenderCache(dirtyLines: Map<number, Array<HighlightedToken>>, themeType: 'dark' | 'light'): void;
124
+ /**
125
+ * Returns true when a session-mode pass changed the region skeleton itself
126
+ * (a gap edit synthesized or merged regions), which changes the rendered
127
+ * row set without a line-count change — the host must escalate to a full
128
+ * re-render instead of its cheap refresh path.
129
+ */
130
+ updateRenderCache(dirtyLines: Map<number, Array<HighlightedToken>>, themeType: 'dark' | 'light', lineCountChangeInFlight?: boolean): boolean;
131
+ private applyExpansionRemap;
96
132
  applyDocumentChange(textDocument: DiffsTextDocument): void;
133
+ private applySessionDocumentChange;
134
+ private markEditSessionPass;
97
135
  protected getUnifiedLineDecoration({
98
136
  lineType
99
137
  }: UnifiedLineDecorationProps): LineDecoration;
@@ -107,6 +145,7 @@ declare class DiffHunksRenderer<LAnnotation = undefined> {
107
145
  protected getOptionsWithDefaults(): DiffHunksRendererOptionsWithDefaults;
108
146
  initializeHighlighter(): Promise<DiffsHighlighter>;
109
147
  hydrate(diff: FileDiffMetadata | undefined): void;
148
+ private getLocalHighlightTheme;
110
149
  private getRenderOptions;
111
150
  renderDiff(diff?: FileDiffMetadata | undefined, renderRange?: RenderRange): HunksRenderResult | undefined;
112
151
  asyncRender(diff: FileDiffMetadata, renderRange?: RenderRange): Promise<HunksRenderResult>;
@@ -114,6 +153,7 @@ declare class DiffHunksRenderer<LAnnotation = undefined> {
114
153
  private asyncHighlight;
115
154
  private renderDiffWithHighlighter;
116
155
  onHighlightSuccess(diff: FileDiffMetadata, result: ThemedDiffResult, options: RenderDiffOptions, highlighted?: boolean): void;
156
+ private applyHighlightResult;
117
157
  private getMatchingWorkerResultCache;
118
158
  private hasHighlightedRenderCache;
119
159
  onHighlightError(error: unknown): void;
@@ -1 +1 @@
1
- {"version":3,"file":"DiffHunksRenderer.d.ts","names":[],"sources":["../../src/renderers/DiffHunksRenderer.ts"],"mappings":"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"}
1
+ {"version":3,"file":"DiffHunksRenderer.d.ts","names":[],"sources":["../../src/renderers/DiffHunksRenderer.ts"],"mappings":"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"}
@@ -1,4 +1,8 @@
1
1
  import { DEFAULT_EXPANDED_REGION, DEFAULT_RENDER_RANGE, DEFAULT_THEMES, DEFAULT_TOKENIZE_MAX_LENGTH } from "../constants.js";
2
+ import { cleanLastNewline } from "../utils/cleanLastNewline.js";
3
+ import { getTrailingContextRangeSize } from "../utils/virtualDiffLayout.js";
4
+ import { recomputeDiffHunksForEdit, recomputeEmptyDocumentDiff, recomputeTopAlignedAdditionDiff, shouldTopAlignAdditionRecompute, updateDiffHunks } from "../utils/updateDiffHunks.js";
5
+ import { applySessionChangedLines, rebuildSessionHunks, remapExpandedHunksForRegionChange } from "../utils/editSessionHunks.js";
2
6
  import { getFileAnnotations, shouldRenderFileAnnotations } from "../utils/includesFileAnnotations.js";
3
7
  import { createGutterGap, createGutterItem, createGutterWrapper, createHastElement } from "../utils/hast_utils.js";
4
8
  import { areLanguagesAttached } from "../highlighter/languages/areLanguagesAttached.js";
@@ -13,11 +17,8 @@ import { createPreElement } from "../utils/createPreElement.js";
13
17
  import { getFiletypeFromFileName } from "../utils/getFiletypeFromFileName.js";
14
18
  import { getHighlighterOptions } from "../utils/getHighlighterOptions.js";
15
19
  import { getLineAnnotationName } from "../utils/getLineAnnotationName.js";
16
- import { shouldUseTokenTransformer } from "../utils/shouldUseTokenTransformer.js";
17
20
  import { areDiffTargetsEqual } from "../utils/areDiffTargetsEqual.js";
18
- import { getTrailingContextRangeSize } from "../utils/virtualDiffLayout.js";
19
21
  import { iterateOverDiff } from "../utils/iterateOverDiff.js";
20
- import { cleanLastNewline } from "../utils/cleanLastNewline.js";
21
22
  import { areDiffRenderOptionsEqual } from "../utils/areDiffRenderOptionsEqual.js";
22
23
  import { createEmptyRowBuffer } from "../utils/createEmptyRowBuffer.js";
23
24
  import { createNoNewlineElement } from "../utils/createNoNewlineElement.js";
@@ -27,7 +28,6 @@ import { getTotalLineCountFromHunks } from "../utils/getTotalLineCountFromHunks.
27
28
  import { isDefaultRenderRange } from "../utils/isDefaultRenderRange.js";
28
29
  import { isDiffPlainText } from "../utils/isDiffPlainText.js";
29
30
  import { renderDiffWithHighlighter } from "../utils/renderDiffWithHighlighter.js";
30
- import { recomputeDiffHunksForEdit, recomputeEmptyDocumentDiff, updateDiffHunks } from "../utils/updateDiffHunks.js";
31
31
  import { toHtml } from "hast-util-to-html";
32
32
  //#region src/renderers/DiffHunksRenderer.ts
33
33
  let instanceId = -1;
@@ -43,6 +43,7 @@ var DiffHunksRenderer = class {
43
43
  additionAnnotations = {};
44
44
  computedLang = "text";
45
45
  renderCache;
46
+ editSessionActive = false;
46
47
  constructor(options = { theme: DEFAULT_THEMES }, onRenderUpdate, workerManager) {
47
48
  this.options = options;
48
49
  this.onRenderUpdate = onRenderUpdate;
@@ -62,6 +63,63 @@ var DiffHunksRenderer = class {
62
63
  this.additionAnnotations = {};
63
64
  this.deletionAnnotations = {};
64
65
  this.workerManager?.cleanUpTasks(this);
66
+ this.endEditSession();
67
+ }
68
+ /**
69
+ * Enter edit-session mode: hunk updates preserve the current region
70
+ * skeleton instead of recomputing hunks, and rendering happens locally
71
+ * with the token transformer forced on (worker-pool requests/results are
72
+ * suspended for this renderer). Called on every editor attach, including
73
+ * a re-attach after recycle.
74
+ */
75
+ beginEditSession() {
76
+ this.editSessionActive = true;
77
+ }
78
+ /** Leave edit-session mode. The exit recompute is the host's concern. */
79
+ endEditSession() {
80
+ this.editSessionActive = false;
81
+ }
82
+ /**
83
+ * Ensures that the DOM is compatible with editor render updates
84
+ */
85
+ editorRenderReady() {
86
+ return this.renderCache?.options.useTokenTransformer === true && this.renderCache.highlighted && this.renderCache.result != null;
87
+ }
88
+ /**
89
+ * Re-highlights the current diff in the background and swaps the fresh
90
+ * result in (with a re-render) once it completes. Needed after an edit
91
+ * session's exit recompute: session passes plain-fill shifted lines in the
92
+ * cached result, and the recompute mutates the diff in place (same object,
93
+ * same cacheKey), so identity/cacheKey checks would otherwise treat the
94
+ * stale highlight as current forever. The current result — content-correct,
95
+ * mostly highlighted — keeps rendering until the fresh one lands, so no
96
+ * interim paint drops highlighting.
97
+ */
98
+ refreshHighlightedResult() {
99
+ const { renderCache } = this;
100
+ if (renderCache == null || isDiffPlainText(renderCache.diff) || isDiffMassive(renderCache.diff, this.getTokenizeMaxLength())) return Promise.resolve();
101
+ const { diff } = renderCache;
102
+ const { workerManager } = this;
103
+ if (!this.editSessionActive && workerManager?.isWorkingPool() === true && diff.cacheKey != null) {
104
+ workerManager.evictDiffFromCache(diff.cacheKey);
105
+ return workerManager.primeDiffHighlightCache(diff).then(() => {
106
+ this.applyRefreshedResult(diff, workerManager.getDiffResultCache(diff));
107
+ }).catch((error) => this.onHighlightError(error));
108
+ }
109
+ return this.asyncHighlight(diff).then((fresh) => this.applyRefreshedResult(diff, fresh)).catch((error) => this.onHighlightError(error));
110
+ }
111
+ applyRefreshedResult(diff, fresh) {
112
+ if (fresh == null || this.renderCache == null || this.renderCache.diff !== diff || this.editSessionActive) return;
113
+ const { options } = this.getRenderOptions(diff);
114
+ if (!areDiffRenderOptionsEqual(options, fresh.options)) return;
115
+ this.renderCache = {
116
+ diff,
117
+ options: fresh.options,
118
+ highlighted: true,
119
+ result: fresh.result,
120
+ renderRange: void 0
121
+ };
122
+ this.onRenderUpdate?.();
65
123
  }
66
124
  get diffCache() {
67
125
  return this.renderCache?.diff ?? this.diff;
@@ -96,6 +154,10 @@ var DiffHunksRenderer = class {
96
154
  getExpandedHunksMap() {
97
155
  return this.expandedHunks;
98
156
  }
157
+ /** Replace the whole expansion map (session-exit expansion remapping). */
158
+ setExpandedHunksMap(expandedHunks) {
159
+ this.expandedHunks = expandedHunks;
160
+ }
99
161
  setLineAnnotations(lineAnnotations) {
100
162
  this.additionAnnotations = {};
101
163
  this.deletionAnnotations = {};
@@ -111,13 +173,20 @@ var DiffHunksRenderer = class {
111
173
  arr.push(annotation);
112
174
  }
113
175
  }
114
- updateRenderCache(dirtyLines, themeType) {
115
- if (this.renderCache == null) return;
176
+ /**
177
+ * Returns true when a session-mode pass changed the region skeleton itself
178
+ * (a gap edit synthesized or merged regions), which changes the rendered
179
+ * row set without a line-count change — the host must escalate to a full
180
+ * re-render instead of its cheap refresh path.
181
+ */
182
+ updateRenderCache(dirtyLines, themeType, lineCountChangeInFlight = false) {
183
+ if (this.renderCache == null) return false;
116
184
  const { result, diff } = this.renderCache;
117
- if (result == null) return;
185
+ if (result == null) return false;
118
186
  if (diff.isPartial) throw new Error("Could not update render cache for partial diff");
119
187
  const hastLines = result.code.additionLines;
120
188
  const changedAdditionLines = [];
189
+ const previousAdditionLines = /* @__PURE__ */ new Map();
121
190
  for (const [line, tokens] of dirtyLines) {
122
191
  const prevProps = hastLines[line]?.properties ?? {};
123
192
  const lineText = tokens.map((a) => a[2]).join("");
@@ -126,7 +195,10 @@ var DiffHunksRenderer = class {
126
195
  const prevText = cleanLastNewline(prevLine);
127
196
  if (canSyncDiffLine) {
128
197
  diff.additionLines[line] = applyLineTextWithNewline(prevLine, lineText);
129
- if (prevText !== lineText) changedAdditionLines.push(line);
198
+ if (prevText !== lineText) {
199
+ changedAdditionLines.push(line);
200
+ previousAdditionLines.set(line, prevLine);
201
+ }
130
202
  }
131
203
  hastLines[line] = {
132
204
  type: "element",
@@ -154,7 +226,7 @@ var DiffHunksRenderer = class {
154
226
  tagName: "span",
155
227
  properties: {
156
228
  "data-char": char,
157
- style: `--diffs-token-${themeType}:${fg};`
229
+ style: `color:${fg};`
158
230
  },
159
231
  children: [{
160
232
  type: "text",
@@ -164,26 +236,59 @@ var DiffHunksRenderer = class {
164
236
  })
165
237
  };
166
238
  }
167
- if (changedAdditionLines.length > 0) Object.assign(diff, updateDiffHunks(diff, changedAdditionLines, this.options.parseDiffOptions));
239
+ let regionsChanged = false;
240
+ if (changedAdditionLines.length > 0) if (this.editSessionActive && !diff.isPartial) {
241
+ if (!lineCountChangeInFlight) if (diff.additionLines.length <= 1 && diff.additionLines.join("") === "") {
242
+ Object.assign(diff, recomputeEmptyDocumentDiff(diff, this.options.parseDiffOptions));
243
+ this.markEditSessionPass(diff);
244
+ regionsChanged = true;
245
+ } else if (shouldTopAlignAdditionRecompute(diff, diff.additionLines)) {
246
+ Object.assign(diff, recomputeTopAlignedAdditionDiff(diff, diff.additionLines, this.options.parseDiffOptions));
247
+ this.markEditSessionPass(diff);
248
+ regionsChanged = true;
249
+ } else {
250
+ const change = applySessionChangedLines(diff, changedAdditionLines, this.options.parseDiffOptions, previousAdditionLines);
251
+ this.applyExpansionRemap(change);
252
+ regionsChanged = change != null;
253
+ }
254
+ } else Object.assign(diff, updateDiffHunks(diff, changedAdditionLines, this.options.parseDiffOptions));
168
255
  result.baseThemeType = themeType;
169
256
  this.renderCache.isDirty = true;
257
+ return regionsChanged;
258
+ }
259
+ applyExpansionRemap(change) {
260
+ if (change != null) this.expandedHunks = remapExpandedHunksForRegionChange(this.expandedHunks, change);
170
261
  }
171
262
  applyDocumentChange(textDocument) {
172
263
  if (this.renderCache == null) return;
173
264
  const { diff, result } = this.renderCache;
174
265
  if (result == null) return;
175
- diff.additionLines = getEditorDocumentLines(textDocument, diff.additionLines);
176
- const newLength = diff.additionLines.length;
177
- const additionHastLines = result.code.additionLines;
178
- const prevLen = additionHastLines.length;
179
- if (newLength < prevLen) additionHastLines.length = newLength;
180
- for (let i = prevLen; i < newLength; i++) additionHastLines[i] ??= createPlainAdditionLineElement(i, textDocument);
181
- if (!diff.isPartial) if (diff.additionLines.length <= 1 && diff.additionLines.join("") === "") {
266
+ if (diff.isPartial) throw new Error("Could not apply document change for partial diff");
267
+ const { additionLines: previousAdditionLines } = diff;
268
+ diff.additionLines = getEditorDocumentLines(textDocument, previousAdditionLines);
269
+ result.code.additionLines = realignAdditionHastLines(previousAdditionLines, diff.additionLines, result.code.additionLines, textDocument);
270
+ if (diff.additionLines.length <= 1 && diff.additionLines.join("") === "") {
182
271
  Object.assign(diff, recomputeEmptyDocumentDiff(diff, this.options.parseDiffOptions));
183
- additionHastLines[0] = createPlainAdditionLineElement(0, textDocument);
184
- } else Object.assign(diff, recomputeDiffHunksForEdit(diff, this.options.parseDiffOptions));
272
+ result.code.additionLines[0] = createPlainAdditionLineElement(0, textDocument);
273
+ this.markEditSessionPass(diff);
274
+ } else if (this.editSessionActive) this.applySessionDocumentChange(diff);
275
+ else Object.assign(diff, recomputeDiffHunksForEdit(diff, this.options.parseDiffOptions));
185
276
  this.renderCache.isDirty = true;
186
277
  }
278
+ applySessionDocumentChange(diff) {
279
+ const { parseDiffOptions } = this.options;
280
+ const rawLines = diff.additionLines;
281
+ if (shouldTopAlignAdditionRecompute(diff, rawLines)) {
282
+ Object.assign(diff, recomputeTopAlignedAdditionDiff(diff, rawLines, parseDiffOptions));
283
+ this.markEditSessionPass(diff);
284
+ return;
285
+ }
286
+ this.applyExpansionRemap(rebuildSessionHunks(diff, parseDiffOptions));
287
+ }
288
+ markEditSessionPass(diff) {
289
+ if (!this.editSessionActive) return;
290
+ diff.editSessionDirty = true;
291
+ }
187
292
  getUnifiedLineDecoration({ lineType }) {
188
293
  return {
189
294
  gutterLineType: lineType,
@@ -227,7 +332,10 @@ var DiffHunksRenderer = class {
227
332
  };
228
333
  }
229
334
  async initializeHighlighter() {
230
- this.highlighter = await getSharedHighlighter(getHighlighterOptions(this.computedLang, this.options));
335
+ this.highlighter = await getSharedHighlighter(getHighlighterOptions(this.computedLang, {
336
+ theme: this.getLocalHighlightTheme(),
337
+ preferredHighlighter: this.workerManager?.getPreferredHighlighter() ?? this.options.preferredHighlighter
338
+ }));
231
339
  return this.highlighter;
232
340
  }
233
341
  hydrate(diff) {
@@ -244,20 +352,30 @@ var DiffHunksRenderer = class {
244
352
  result: massiveDiff ? void 0 : cache?.result,
245
353
  renderRange: void 0
246
354
  };
247
- if (this.workerManager?.isWorkingPool() === true) {
355
+ if (!this.editSessionActive && this.workerManager?.isWorkingPool() === true) {
248
356
  if (this.renderCache.result == null && !massiveDiff) this.workerManager.highlightDiffAST(this, this.diff);
249
357
  } else if (this.highlighter == null) {
250
358
  this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);
251
359
  this.initializeHighlighter();
252
360
  }
253
361
  }
362
+ getLocalHighlightTheme() {
363
+ return this.workerManager?.getDiffRenderOptions().theme ?? this.options.theme ?? DEFAULT_THEMES;
364
+ }
254
365
  getRenderOptions(diff) {
255
366
  const options = (() => {
256
- if (this.workerManager?.isWorkingPool() === true) return this.workerManager.getDiffRenderOptions();
367
+ if (this.workerManager?.isWorkingPool() === true) {
368
+ const poolOptions = this.workerManager.getDiffRenderOptions();
369
+ if (this.editSessionActive && poolOptions.useTokenTransformer !== true) return {
370
+ ...poolOptions,
371
+ useTokenTransformer: true
372
+ };
373
+ return poolOptions;
374
+ }
257
375
  const { theme, tokenizeMaxLineLength, lineDiffType, maxLineDiffLength } = this.getOptionsWithDefaults();
258
376
  return {
259
377
  theme,
260
- useTokenTransformer: shouldUseTokenTransformer(this.options),
378
+ useTokenTransformer: this.editSessionActive || this.options.useTokenTransformer === true,
261
379
  tokenizeMaxLineLength,
262
380
  lineDiffType,
263
381
  maxLineDiffLength
@@ -303,8 +421,10 @@ var DiffHunksRenderer = class {
303
421
  const forcePlainText = !hasContent || isDiffPlainText(diff) || isDiffMassive(diff, this.getTokenizeMaxLength());
304
422
  const newContent = !areDiffTargetsEqual(diff, this.renderCache.diff);
305
423
  const newRenderRange = !areRenderRangesEqual(this.renderCache.renderRange, renderRange);
306
- if (this.workerManager?.isWorkingPool() === true) {
307
- if (forcePlainText || this.renderCache.result == null || !this.renderCache.highlighted && (newContent || newRenderRange)) {
424
+ if (!this.editSessionActive && this.workerManager?.isWorkingPool() === true) {
425
+ const highlightPending = this.renderCache.result == null && this.renderCache.highlighted && !forcePlainText && !newContent && isDefaultRenderRange(renderRange);
426
+ if (highlightPending) this.renderCache.highlightPending = true;
427
+ if (!highlightPending && (forcePlainText || this.renderCache.result == null || !this.renderCache.highlighted && (newContent || newRenderRange))) {
308
428
  this.renderCache.diff = diff;
309
429
  this.renderCache.options = options;
310
430
  this.renderCache.highlighted = false;
@@ -329,7 +449,7 @@ var DiffHunksRenderer = class {
329
449
  }
330
450
  if (!hasThemes || !forcePlainText && !hasLangs) this.asyncHighlight(diff).then(({ result, options }) => {
331
451
  if (this.renderCache != null) this.renderCache.highlighted = false;
332
- this.onHighlightSuccess(diff, result, options, !forcePlainText);
452
+ this.applyHighlightResult(diff, result, options, !forcePlainText);
333
453
  });
334
454
  }
335
455
  return this.renderCache.result != null ? this.processDiffResult(this.renderCache.diff, renderRange, this.renderCache.result) : void 0;
@@ -354,7 +474,7 @@ var DiffHunksRenderer = class {
354
474
  async asyncHighlight(diff) {
355
475
  const forcePlainText = isDiffMassive(diff, this.getTokenizeMaxLength());
356
476
  this.computedLang = forcePlainText ? "text" : diff.lang ?? getFiletypeFromFileName(diff.name);
357
- const hasThemes = this.highlighter != null && areThemesAttached(this.options.theme ?? DEFAULT_THEMES);
477
+ const hasThemes = this.highlighter != null && areThemesAttached(this.getLocalHighlightTheme());
358
478
  const hasLangs = forcePlainText || this.highlighter != null && areLanguagesAttached(this.computedLang);
359
479
  if (this.highlighter == null || !hasThemes || !hasLangs) this.highlighter = await this.initializeHighlighter();
360
480
  return this.renderDiffWithHighlighter(diff, this.highlighter, forcePlainText);
@@ -372,8 +492,12 @@ var DiffHunksRenderer = class {
372
492
  };
373
493
  }
374
494
  onHighlightSuccess(diff, result, options, highlighted = true) {
495
+ if (this.editSessionActive) return;
496
+ this.applyHighlightResult(diff, result, options, highlighted);
497
+ }
498
+ applyHighlightResult(diff, result, options, highlighted = true) {
375
499
  if (this.renderCache == null) return;
376
- const triggerRenderUpdate = !this.renderCache.highlighted || !areDiffRenderOptionsEqual(this.renderCache.options, options) || !areDiffTargetsEqual(this.renderCache.diff, diff);
500
+ const triggerRenderUpdate = this.renderCache.highlightPending === true || !this.renderCache.highlighted || !areDiffRenderOptionsEqual(this.renderCache.options, options) || !areDiffTargetsEqual(this.renderCache.diff, diff);
377
501
  this.renderCache = {
378
502
  diff,
379
503
  options,
@@ -384,6 +508,7 @@ var DiffHunksRenderer = class {
384
508
  if (triggerRenderUpdate) this.onRenderUpdate?.();
385
509
  }
386
510
  getMatchingWorkerResultCache(diff, options) {
511
+ if (this.editSessionActive) return;
387
512
  const cache = this.workerManager?.getDiffResultCache(diff);
388
513
  if (cache == null || !areDiffRenderOptionsEqual(options, cache.options)) return;
389
514
  return cache;
@@ -574,7 +699,7 @@ var DiffHunksRenderer = class {
574
699
  if (pendingSplitContext.side != null && pendingSplitContext.side !== missingSide) pendingSplitContext.flush();
575
700
  pendingSplitContext.side = missingSide;
576
701
  pendingSplitContext.increment();
577
- }
702
+ } else if (type === "change") pendingSplitContext.flush();
578
703
  const annotationSpans = this.getAnnotations("split", deletionLine?.lineNumber, additionLine?.lineNumber, hunkIndex, lineIndex);
579
704
  if (annotationSpans != null && pendingSplitContext.size > 0) pendingSplitContext.flush();
580
705
  if (deletionLine != null) {
@@ -972,6 +1097,19 @@ function withContentProperties(lineNode, contentProperties, extendProperties) {
972
1097
  }
973
1098
  };
974
1099
  }
1100
+ function realignAdditionHastLines(previousLines, nextLines, hastLines, textDocument) {
1101
+ const maxShared = Math.min(previousLines.length, nextLines.length);
1102
+ let prefix = 0;
1103
+ while (prefix < maxShared && previousLines[prefix] === nextLines[prefix]) prefix++;
1104
+ let suffix = 0;
1105
+ while (suffix < maxShared - prefix && previousLines[previousLines.length - 1 - suffix] === nextLines[nextLines.length - 1 - suffix]) suffix++;
1106
+ const realigned = new Array(nextLines.length);
1107
+ for (let index = 0; index < prefix; index++) realigned[index] = hastLines[index];
1108
+ for (let offset = 0; offset < suffix; offset++) realigned[nextLines.length - 1 - offset] = hastLines[previousLines.length - 1 - offset];
1109
+ for (let index = previousLines.length; index < nextLines.length; index++) realigned[index] ??= hastLines[index];
1110
+ for (let index = prefix; index < nextLines.length - suffix; index++) realigned[index] ??= createPlainAdditionLineElement(index, textDocument);
1111
+ return realigned;
1112
+ }
975
1113
  function createPlainAdditionLineElement(lineIndex, textDocument) {
976
1114
  return {
977
1115
  type: "element",