@pierre/diffs 1.3.0-beta.6 → 1.3.0-beta.7

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 (119) hide show
  1. package/dist/components/CodeView.d.ts +4 -1
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +45 -6
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts.map +1 -1
  6. package/dist/components/File.js +5 -2
  7. package/dist/components/File.js.map +1 -1
  8. package/dist/components/FileDiff.d.ts +36 -23
  9. package/dist/components/FileDiff.d.ts.map +1 -1
  10. package/dist/components/FileDiff.js +126 -58
  11. package/dist/components/FileDiff.js.map +1 -1
  12. package/dist/components/UnresolvedFile.d.ts +3 -2
  13. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  14. package/dist/components/UnresolvedFile.js +4 -2
  15. package/dist/components/UnresolvedFile.js.map +1 -1
  16. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  17. package/dist/components/VirtualizedFile.js +3 -7
  18. package/dist/components/VirtualizedFile.js.map +1 -1
  19. package/dist/components/VirtualizedFileDiff.d.ts +10 -4
  20. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  21. package/dist/components/VirtualizedFileDiff.js +178 -49
  22. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  23. package/dist/editor/editor.d.ts +2 -2
  24. package/dist/editor/editor.d.ts.map +1 -1
  25. package/dist/editor/editor.js +163 -106
  26. package/dist/editor/editor.js.map +1 -1
  27. package/dist/editor/editor2.js +1 -1
  28. package/dist/editor/selection.d.ts +1 -1
  29. package/dist/editor/selection.d.ts.map +1 -1
  30. package/dist/editor/selection.js +87 -37
  31. package/dist/editor/selection.js.map +1 -1
  32. package/dist/editor/textMeasure.d.ts.map +1 -1
  33. package/dist/editor/textMeasure.js +25 -7
  34. package/dist/editor/textMeasure.js.map +1 -1
  35. package/dist/editor/tokenzier.d.ts +2 -0
  36. package/dist/editor/tokenzier.d.ts.map +1 -1
  37. package/dist/editor/tokenzier.js +11 -3
  38. package/dist/editor/tokenzier.js.map +1 -1
  39. package/dist/editor/utils.d.ts +3 -1
  40. package/dist/editor/utils.d.ts.map +1 -1
  41. package/dist/editor/utils.js +14 -1
  42. package/dist/editor/utils.js.map +1 -1
  43. package/dist/index.d.ts +5 -3
  44. package/dist/index.js +3 -1
  45. package/dist/managers/InteractionManager.d.ts.map +1 -1
  46. package/dist/managers/InteractionManager.js +0 -1
  47. package/dist/managers/InteractionManager.js.map +1 -1
  48. package/dist/react/EditorContext.js.map +1 -1
  49. package/dist/react/MultiFileDiff.d.ts +3 -4
  50. package/dist/react/MultiFileDiff.d.ts.map +1 -1
  51. package/dist/react/MultiFileDiff.js.map +1 -1
  52. package/dist/react/index.d.ts +2 -2
  53. package/dist/react/utils/useFileDiffInstance.js +14 -15
  54. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  55. package/dist/renderers/DiffHunksRenderer.d.ts +2 -2
  56. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  57. package/dist/renderers/DiffHunksRenderer.js +29 -16
  58. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  59. package/dist/renderers/FileRenderer.js.map +1 -1
  60. package/dist/ssr/index.d.ts +2 -2
  61. package/dist/ssr/preloadDiffs.d.ts +11 -10
  62. package/dist/ssr/preloadDiffs.d.ts.map +1 -1
  63. package/dist/ssr/preloadDiffs.js +14 -6
  64. package/dist/ssr/preloadDiffs.js.map +1 -1
  65. package/dist/types.d.ts +59 -5
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/utils/areHunkDataEqual.js +1 -1
  68. package/dist/utils/areHunkDataEqual.js.map +1 -1
  69. package/dist/utils/awaitWithTimeout.d.ts +5 -0
  70. package/dist/utils/awaitWithTimeout.d.ts.map +1 -0
  71. package/dist/utils/awaitWithTimeout.js +15 -0
  72. package/dist/utils/awaitWithTimeout.js.map +1 -0
  73. package/dist/utils/cloneFileDiffMetadata.d.ts +7 -0
  74. package/dist/utils/cloneFileDiffMetadata.d.ts.map +1 -0
  75. package/dist/utils/cloneFileDiffMetadata.js +16 -0
  76. package/dist/utils/cloneFileDiffMetadata.js.map +1 -0
  77. package/dist/utils/computeEstimatedDiffHeights.d.ts +3 -1
  78. package/dist/utils/computeEstimatedDiffHeights.d.ts.map +1 -1
  79. package/dist/utils/computeEstimatedDiffHeights.js +8 -1
  80. package/dist/utils/computeEstimatedDiffHeights.js.map +1 -1
  81. package/dist/utils/createPreElement.js +0 -1
  82. package/dist/utils/createPreElement.js.map +1 -1
  83. package/dist/utils/getDiffFileInput.d.ts +14 -0
  84. package/dist/utils/getDiffFileInput.d.ts.map +1 -0
  85. package/dist/utils/getDiffFileInput.js +24 -0
  86. package/dist/utils/getDiffFileInput.js.map +1 -0
  87. package/dist/utils/getDiffHunksRendererOptions.js +1 -0
  88. package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
  89. package/dist/utils/getFiletypeFromFileName.d.ts.map +1 -1
  90. package/dist/utils/getFiletypeFromFileName.js +2 -0
  91. package/dist/utils/getFiletypeFromFileName.js.map +1 -1
  92. package/dist/utils/hydratePartialDiff.d.ts +10 -0
  93. package/dist/utils/hydratePartialDiff.d.ts.map +1 -0
  94. package/dist/utils/hydratePartialDiff.js +140 -0
  95. package/dist/utils/hydratePartialDiff.js.map +1 -0
  96. package/dist/utils/iterateOverDiff.js +3 -3
  97. package/dist/utils/iterateOverDiff.js.map +1 -1
  98. package/dist/utils/parseDiffFromFile.d.ts +1 -1
  99. package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  100. package/dist/utils/parseDiffFromFile.js +26 -5
  101. package/dist/utils/parseDiffFromFile.js.map +1 -1
  102. package/dist/utils/setWrapperNodeProps.js +0 -1
  103. package/dist/utils/setWrapperNodeProps.js.map +1 -1
  104. package/dist/utils/updateDiffHunks.d.ts +5 -1
  105. package/dist/utils/updateDiffHunks.d.ts.map +1 -1
  106. package/dist/utils/updateDiffHunks.js +26 -4
  107. package/dist/utils/updateDiffHunks.js.map +1 -1
  108. package/dist/worker/WorkerPoolManager.d.ts +7 -2
  109. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  110. package/dist/worker/WorkerPoolManager.js +78 -15
  111. package/dist/worker/WorkerPoolManager.js.map +1 -1
  112. package/dist/worker/index.d.ts +2 -2
  113. package/dist/worker/types.d.ts +7 -1
  114. package/dist/worker/types.d.ts.map +1 -1
  115. package/dist/worker/worker-portable.js +5 -3
  116. package/dist/worker/worker-portable.js.map +1 -1
  117. package/dist/worker/worker.js +5 -3
  118. package/dist/worker/worker.js.map +1 -1
  119. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"UnresolvedFile.d.ts","names":[],"sources":["../../src/components/UnresolvedFile.ts"],"mappings":";;;;;;;;KAoCY,0BAAA,iBACV,MAAA,EAAQ,uBAAA,EACR,QAAA,EAAU,cAAA,CAAe,WAAA,MACtB,WAAA,GAAc,gBAAA;AAAA,KAEP,8BAAA,qCAGR,0BAA0B,CAAC,WAAA;AAAA,UAEd,qBAAA,sBAA2C,IAAA,CAC1D,eAAA,CAAgB,WAAA;EAGhB,YAAA,EACE,IAAA,EAAM,WAAA,EACN,QAAA,EAAU,cAAA,CAAe,WAAA,GACzB,KAAA,EAAO,eAAA;EAET,wBAAA,GAA2B,8BAAA,CAA+B,WAAA;EAC1D,qBAAA,EACE,OAAA,EAAS,0BAAA,EACT,QAAA,EAAU,cAAA,CAAe,WAAA;EAE3B,sBAAA,EACE,IAAA,EAAM,YAAA,EACN,OAAA,EAAS,0BAAA;EAEX,eAAA;AAAA;AAAA,UAGe,yBAAA,sBAA+C,IAAA,CAC9D,mBAAA,CAAoB,WAAA;EAGpB,IAAA,GAAO,YAAA;EACP,OAAA,IAAW,uBAAA;EACX,UAAA,GAAa,sBAAA;AAAA;AAAA,UAGE,4BAAA,sBAAkD,IAAA,CACjE,yBAAA,CAA0B,WAAA;EAG1B,IAAA,GAAO,YAAA;EACP,aAAA,EAAe,WAAA;EACf,eAAA;AAAA;AAAA,UAQQ,qBAAA;EACR,IAAA,EAAM,YAAA;EACN,QAAA,EAAU,gBAAA;EACV,OAAA,GAAU,uBAAA;EACV,UAAA,EAAY,sBAAA;AAAA;AAAA,UASJ,qBAAA;EACR,IAAA,EAAM,YAAA;EACN,QAAA,EAAU,gBAAA;EACV,OAAA,GAAU,uBAAA;EACV,UAAA,EAAY,sBAAA;AAAA;AAAA,KAGT,uBAAA,GAA0B,qBAAqB;AAAA,cAIvC,cAAA,kCAEH,QAAA,CAAS,WAAA;EAgBC,OAAA,EAAS,qBAAA,CAAsB,WAAA;EAAA,SAf/B,IAAA;EAAA,SACA,IAAA;EAAA,UAER,aAAA,EAAe,uBAAA;EAAA,QAMjB,eAAA;EAAA,QACA,UAAA;EAAA,QACA,mBAAA;EAGR,WAAA,CACkB,OAAA,GAAS,qBAAA,CAAsB,WAAA,GAG/C,aAAA,GAAgB,iBAAA,cAChB,kBAAA;EAMO,UAAA,CACP,OAAA,EAAS,qBAAA,CAAsB,WAAA;EAAA,UAiCd,mBAAA,CACjB,OAAA,EAAS,qBAAA,CAAsB,WAAA,IAC9B,2BAAA,CAA4B,WAAA;EAAA,UASZ,uBAAA,CACjB,OAAA,EAAS,qBAAA,CAAsB,WAAA,IAC9B,kCAAA;EAAA,UAIgB,sBAAA,CACjB,GAAA,EAAK,cAAA,EACL,MAAA,EAAQ,iBAAA;EAOD,OAAA;EAAA,QAaD,gBAAA;EA6HC,OAAA,CAAQ,KAAA,EAAO,4BAAA,CAA6B,WAAA;EA8C5C,QAAA;EAOA,MAAA,CAAO,KAAA,GAAO,yBAAA,CAA0B,WAAA;EAmC1C,eAAA,CACL,aAAA,UACA,UAAA,EAAY,uBAAA,EACZ,QAAA,GAAU,gBAAA,eACT,qBAAA;EAAA,QA+BK,wBAAA;EAAA,QA+CA,2BAAA;EAAA,QAkBA,8BAAA;EAAA,QAwBA,8BAAA;EAAA,QA+DA,yBAAA;EAAA,QAyBA,6BAAA;AAAA;AAAA,iBAyNM,qCAAA,cACd,OAAA,GAAU,qBAAA,CAAsB,WAAA,GAChC,WAAA,GAAc,qBAAA,CAAsB,WAAA,IACnC,kCAAA"}
1
+ {"version":3,"file":"UnresolvedFile.d.ts","names":[],"sources":["../../src/components/UnresolvedFile.ts"],"mappings":";;;;;;;;KAoCY,0BAAA,iBACV,MAAA,EAAQ,uBAAA,EACR,QAAA,EAAU,cAAA,CAAe,WAAA,MACtB,WAAA,GAAc,gBAAA;AAAA,KAEP,8BAAA,qCAGR,0BAA0B,CAAC,WAAA;AAAA,UAEd,qBAAA,sBAA2C,IAAA,CAC1D,eAAA,CAAgB,WAAA;EAGhB,YAAA,EACE,IAAA,EAAM,WAAA,EACN,QAAA,EAAU,cAAA,CAAe,WAAA,GACzB,KAAA,EAAO,eAAA;EAET,wBAAA,GAA2B,8BAAA,CAA+B,WAAA;EAC1D,qBAAA,EACE,OAAA,EAAS,0BAAA,EACT,QAAA,EAAU,cAAA,CAAe,WAAA;EAE3B,sBAAA,EACE,IAAA,EAAM,YAAA,EACN,OAAA,EAAS,0BAAA;EAEX,eAAA;AAAA;AAAA,UAGe,yBAAA,sBAEP,uBAAA,CAAwB,WAAA;EAChC,IAAA,GAAO,YAAA;EACP,OAAA,IAAW,uBAAA;EACX,UAAA,GAAa,sBAAA;AAAA;AAAA,UAGE,4BAAA,sBAAkD,IAAA,CACjE,yBAAA,CAA0B,WAAA;EAG1B,IAAA,GAAO,YAAA;EACP,aAAA,EAAe,WAAA;EACf,eAAA;AAAA;AAAA,UAQQ,qBAAA;EACR,IAAA,EAAM,YAAA;EACN,QAAA,EAAU,gBAAA;EACV,OAAA,GAAU,uBAAA;EACV,UAAA,EAAY,sBAAA;AAAA;AAAA,UASJ,qBAAA;EACR,IAAA,EAAM,YAAA;EACN,QAAA,EAAU,gBAAA;EACV,OAAA,GAAU,uBAAA;EACV,UAAA,EAAY,sBAAA;AAAA;AAAA,KAGT,uBAAA,GAA0B,qBAAqB;AAAA,cAIvC,cAAA,kCAEH,QAAA,CAAS,WAAA;EAgBC,OAAA,EAAS,qBAAA,CAAsB,WAAA;EAAA,SAf/B,IAAA;EAAA,SACA,IAAA;EAAA,UAER,aAAA,EAAe,uBAAA;EAAA,QAMjB,eAAA;EAAA,QACA,UAAA;EAAA,QACA,mBAAA;EAGR,WAAA,CACkB,OAAA,GAAS,qBAAA,CAAsB,WAAA,GAG/C,aAAA,GAAgB,iBAAA,cAChB,kBAAA;EAMO,UAAA,CACP,OAAA,EAAS,qBAAA,CAAsB,WAAA;EAAA,UAyBd,sBAAA;EAAA,UAeA,mBAAA,CACjB,OAAA,EAAS,qBAAA,CAAsB,WAAA,IAC9B,2BAAA,CAA4B,WAAA;EAAA,UASZ,uBAAA,CACjB,OAAA,EAAS,qBAAA,CAAsB,WAAA,IAC9B,kCAAA;EAAA,UAIgB,sBAAA,CACjB,GAAA,EAAK,cAAA,EACL,MAAA,EAAQ,iBAAA;EAOD,OAAA;EAAA,QAaD,gBAAA;EA6HC,OAAA,CAAQ,KAAA,EAAO,4BAAA,CAA6B,WAAA;EA8C5C,QAAA;EAOA,MAAA,CAAO,KAAA,GAAO,yBAAA,CAA0B,WAAA;EAmC1C,eAAA,CACL,aAAA,UACA,UAAA,EAAY,uBAAA,EACZ,QAAA,GAAU,gBAAA,eACT,qBAAA;EAAA,QA+BK,wBAAA;EAAA,QA+CA,2BAAA;EAAA,QAkBA,8BAAA;EAAA,QAwBA,8BAAA;EAAA,QA+DA,yBAAA;EAAA,QAyBA,6BAAA;AAAA;AAAA,iBAyNM,qCAAA,cACd,OAAA,GAAU,qBAAA,CAAsB,WAAA,GAChC,WAAA,GAAc,qBAAA,CAAsB,WAAA,IACnC,kCAAA"}
@@ -34,8 +34,10 @@ var UnresolvedFile = class extends FileDiff {
34
34
  if (options.onMergeConflictAction != null && options.onMergeConflictResolve != null) throw new Error("UnresolvedFile: onMergeConflictAction and onMergeConflictResolve are mutually exclusive. Use only one callback.");
35
35
  this.options = options;
36
36
  this.hunksRenderer.setOptions(this.getHunksRendererOptions(options));
37
- const hunkSeparators = this.options.hunkSeparators ?? "line-info";
38
- this.interactionManager.setOptions(pluckInteractionOptions(this.options, typeof hunkSeparators === "function" || hunkSeparators === "line-info" || hunkSeparators === "line-info-basic" ? this.expandHunk : void 0, this.getLineIndex, this.handleMergeConflictActionClick));
37
+ this.syncInteractionOptions();
38
+ }
39
+ syncInteractionOptions() {
40
+ this.interactionManager.setOptions(pluckInteractionOptions(this.options, typeof this.options.hunkSeparators === "function" || (this.options.hunkSeparators ?? "line-info") === "line-info" || this.options.hunkSeparators === "line-info-basic" ? this.handleExpandHunk : void 0, this.getLineIndex, this.handleMergeConflictActionClick));
39
41
  }
40
42
  createHunksRenderer(options) {
41
43
  return new UnresolvedFileHunksRenderer(this.getHunksRendererOptions(options), this.handleHighlightRender, this.workerManager);
@@ -1 +1 @@
1
- {"version":3,"file":"UnresolvedFile.js","names":["resolveConflictDiff"],"sources":["../../src/components/UnresolvedFile.ts"],"sourcesContent":["import { DEFAULT_THEMES } from '../constants';\nimport type { MergeConflictActionTarget } from '../managers/InteractionManager';\nimport { pluckInteractionOptions } from '../managers/InteractionManager';\nimport type { HunksRenderResult } from '../renderers/DiffHunksRenderer';\nimport {\n UnresolvedFileHunksRenderer,\n type UnresolvedFileHunksRendererOptions,\n} from '../renderers/UnresolvedFileHunksRenderer';\nimport type {\n FileContents,\n FileDiffMetadata,\n MergeConflictActionPayload,\n MergeConflictMarkerRow,\n MergeConflictRegion,\n MergeConflictResolution,\n PostRenderPhase,\n} from '../types';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areMergeConflictActionsEqual } from '../utils/areMergeConflictActionsEqual';\nimport { createAnnotationWrapperNode } from '../utils/createAnnotationWrapperNode';\nimport { getMergeConflictActionSlotName } from '../utils/getMergeConflictActionSlotName';\nimport {\n buildMergeConflictMarkerRows,\n getMergeConflictActionAnchor,\n type MergeConflictDiffAction,\n parseMergeConflictDiffFromFile,\n} from '../utils/parseMergeConflictDiffFromFile';\nimport { resolveConflict as resolveConflictDiff } from '../utils/resolveConflict';\nimport { splitFileContents } from '../utils/splitFileContents';\nimport type { WorkerPoolManager } from '../worker';\nimport {\n FileDiff,\n type FileDiffOptions,\n type FileDiffRenderProps,\n} from './FileDiff';\n\nexport type RenderMergeConflictActions<LAnnotation> = (\n action: MergeConflictDiffAction,\n instance: UnresolvedFile<LAnnotation>\n) => HTMLElement | DocumentFragment | null | undefined;\n\nexport type MergeConflictActionsTypeOption<LAnnotation> =\n | 'none'\n | 'default'\n | RenderMergeConflictActions<LAnnotation>;\n\nexport interface UnresolvedFileOptions<LAnnotation> extends Omit<\n FileDiffOptions<LAnnotation>,\n 'diffStyle' | 'onPostRender'\n> {\n onPostRender?(\n node: HTMLElement,\n instance: UnresolvedFile<LAnnotation>,\n phase: PostRenderPhase\n ): unknown;\n mergeConflictActionsType?: MergeConflictActionsTypeOption<LAnnotation>;\n onMergeConflictAction?(\n payload: MergeConflictActionPayload,\n instance: UnresolvedFile<LAnnotation>\n ): void;\n onMergeConflictResolve?(\n file: FileContents,\n payload: MergeConflictActionPayload\n ): void;\n maxContextLines?: number;\n}\n\nexport interface UnresolvedFileRenderProps<LAnnotation> extends Omit<\n FileDiffRenderProps<LAnnotation>,\n 'oldFile' | 'newFile'\n> {\n file?: FileContents;\n actions?: (MergeConflictDiffAction | undefined)[];\n markerRows?: MergeConflictMarkerRow[];\n}\n\nexport interface UnresolvedFileHydrationProps<LAnnotation> extends Omit<\n UnresolvedFileRenderProps<LAnnotation>,\n 'file'\n> {\n file?: FileContents;\n fileContainer: HTMLElement;\n prerenderedHTML?: string;\n}\n\ninterface MergeConflictActionElementCache {\n element: HTMLElement;\n action: MergeConflictDiffAction;\n}\n\ninterface GetOrComputeDiffProps {\n file: FileContents | undefined;\n fileDiff: FileDiffMetadata | undefined;\n actions: (MergeConflictDiffAction | undefined)[] | undefined;\n markerRows: MergeConflictMarkerRow[] | undefined;\n}\n\ninterface GetOrComputeDiffResult {\n fileDiff: FileDiffMetadata;\n actions: (MergeConflictDiffAction | undefined)[];\n markerRows: MergeConflictMarkerRow[];\n}\n\ninterface ResolveConflictReturn {\n file: FileContents;\n fileDiff: FileDiffMetadata;\n actions: (MergeConflictDiffAction | undefined)[];\n markerRows: MergeConflictMarkerRow[];\n}\n\ntype UnresolvedFileDataCache = GetOrComputeDiffProps;\n\nlet instanceId = -1;\n\nexport class UnresolvedFile<\n LAnnotation = undefined,\n> extends FileDiff<LAnnotation> {\n override readonly __id: string = `unresolved-file:${++instanceId}`;\n override readonly type = 'unresolved-file';\n\n protected computedCache: UnresolvedFileDataCache = {\n file: undefined,\n fileDiff: undefined,\n actions: undefined,\n markerRows: undefined,\n };\n private conflictActions: (MergeConflictDiffAction | undefined)[] = [];\n private markerRows: MergeConflictMarkerRow[] = [];\n private conflictActionCache: Map<string, MergeConflictActionElementCache> =\n new Map();\n\n constructor(\n public override options: UnresolvedFileOptions<LAnnotation> = {\n theme: DEFAULT_THEMES,\n },\n workerManager?: WorkerPoolManager | undefined,\n isContainerManaged = false\n ) {\n super(undefined, workerManager, isContainerManaged);\n this.setOptions(options);\n }\n\n override setOptions(\n options: UnresolvedFileOptions<LAnnotation> | undefined\n ): void {\n if (options == null) {\n return;\n }\n\n if (\n options.onMergeConflictAction != null &&\n options.onMergeConflictResolve != null\n ) {\n throw new Error(\n 'UnresolvedFile: onMergeConflictAction and onMergeConflictResolve are mutually exclusive. Use only one callback.'\n );\n }\n\n this.options = options;\n this.hunksRenderer.setOptions(this.getHunksRendererOptions(options));\n\n const hunkSeparators = this.options.hunkSeparators ?? 'line-info';\n this.interactionManager.setOptions(\n pluckInteractionOptions(\n this.options,\n typeof hunkSeparators === 'function' ||\n hunkSeparators === 'line-info' ||\n hunkSeparators === 'line-info-basic'\n ? this.expandHunk\n : undefined,\n this.getLineIndex,\n this.handleMergeConflictActionClick\n )\n );\n }\n\n protected override createHunksRenderer(\n options: UnresolvedFileOptions<LAnnotation>\n ): UnresolvedFileHunksRenderer<LAnnotation> {\n const renderer = new UnresolvedFileHunksRenderer<LAnnotation>(\n this.getHunksRendererOptions(options),\n this.handleHighlightRender,\n this.workerManager\n );\n return renderer;\n }\n\n protected override getHunksRendererOptions(\n options: UnresolvedFileOptions<LAnnotation>\n ): UnresolvedFileHunksRendererOptions {\n return getUnresolvedDiffHunksRendererOptions(options, this.options);\n }\n\n protected override applyPreNodeAttributes(\n pre: HTMLPreElement,\n result: HunksRenderResult\n ): void {\n super.applyPreNodeAttributes(pre, result, {\n 'data-has-merge-conflict': '',\n });\n }\n\n override cleanUp(): void {\n this.emitPostRender(true);\n this.clearMergeConflictActionCache();\n this.computedCache = {\n file: undefined,\n fileDiff: undefined,\n actions: undefined,\n markerRows: undefined,\n };\n this.conflictActions = [];\n super.cleanUp();\n }\n\n private getOrComputeDiff({\n file,\n fileDiff,\n actions,\n markerRows,\n }: GetOrComputeDiffProps): GetOrComputeDiffResult | undefined {\n const { maxContextLines, onMergeConflictAction } = this.options;\n wrapper: {\n // We are dealing with a controlled component\n if (onMergeConflictAction != null) {\n const hasFileDiff = fileDiff != null;\n const hasActions = actions != null;\n const hasMarkerRows = markerRows != null;\n if (hasFileDiff !== hasActions || hasFileDiff !== hasMarkerRows) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: fileDiff, actions, and markerRows must be passed together'\n );\n }\n // If we were provided a new fileDiff/actions/markerRows, we are a FULLY\n // controlled component, which means we will not do any computation\n if (fileDiff != null && actions != null && markerRows != null) {\n this.computedCache = {\n file: file ?? this.computedCache.file,\n fileDiff,\n actions,\n markerRows,\n };\n break wrapper;\n }\n // If we were provided a new file, we should attempt to parse out a new\n // diff/actions if we haven't computed it before. Once we initialize from\n // a file, later updates must flow through fileDiff/actions instead of\n // reparsing from a new file input.\n else if (file != null || this.computedCache.file != null) {\n if (\n file != null &&\n this.computedCache.file != null &&\n !areFilesEqual(file, this.computedCache.file) &&\n this.computedCache.fileDiff != null &&\n this.computedCache.actions != null\n ) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: file can only be used to initialize unresolved state once. Pass fileDiff and actions for subsequent updates.'\n );\n }\n file ??= this.computedCache.file;\n if (file == null) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: file is null, should be impossible'\n );\n }\n if (\n !areFilesEqual(file, this.computedCache.file) ||\n this.computedCache.fileDiff == null ||\n this.computedCache.actions == null\n ) {\n const computed = parseMergeConflictDiffFromFile(\n file,\n maxContextLines\n );\n this.computedCache = {\n file,\n fileDiff: computed.fileDiff,\n actions: computed.actions,\n markerRows: computed.markerRows,\n };\n }\n fileDiff = this.computedCache.fileDiff;\n actions = this.computedCache.actions;\n markerRows = this.computedCache.markerRows;\n break wrapper;\n }\n // Otherwise we should fall through and try to use the cache if it exists\n else {\n fileDiff = this.computedCache.fileDiff;\n actions = this.computedCache.actions;\n markerRows = this.computedCache.markerRows;\n break wrapper;\n }\n }\n // If we are uncontrolled we only rely on the file and only use the first\n // version. After that, the cached diff/action pair is the source of\n // truth and we should not accept a new file input.\n else {\n if (fileDiff != null || actions != null || markerRows != null) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: fileDiff, actions, and markerRows are only usable in controlled mode, you must pass in `onMergeConflictAction`'\n );\n }\n if (\n file != null &&\n this.computedCache.file != null &&\n !areFilesEqual(file, this.computedCache.file)\n ) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: uncontrolled unresolved files parse the file only once. Later updates must come from the cached diff state.'\n );\n }\n this.computedCache.file ??= file;\n if (\n this.computedCache.fileDiff == null &&\n this.computedCache.file != null\n ) {\n const computed = parseMergeConflictDiffFromFile(\n this.computedCache.file,\n maxContextLines\n );\n this.computedCache.fileDiff = computed.fileDiff;\n this.computedCache.actions = computed.actions;\n this.computedCache.markerRows = computed.markerRows;\n }\n // Because we are uncontrolled, the source of truth is the\n // computedCache\n fileDiff = this.computedCache.fileDiff;\n actions = this.computedCache.actions;\n markerRows = this.computedCache.markerRows;\n break wrapper;\n }\n }\n if (fileDiff == null || actions == null || markerRows == null) {\n return undefined;\n }\n return { fileDiff, actions, markerRows };\n }\n\n override hydrate(props: UnresolvedFileHydrationProps<LAnnotation>): void {\n const {\n file,\n fileDiff,\n actions,\n markerRows,\n lineAnnotations,\n fileContainer,\n prerenderedHTML,\n preventEmit = false,\n } = props;\n const source = this.getOrComputeDiff({\n file,\n fileDiff,\n actions,\n markerRows,\n });\n if (source == null) {\n return;\n }\n this.hydrateElements(fileContainer, prerenderedHTML);\n this.setActiveMergeConflictState(source.actions, source.markerRows);\n // If necessary hydration elements don't exist, we should assume a full\n // render\n if (\n shouldRenderCode(this.pre, source.fileDiff, this.options.collapsed) ||\n shouldRenderHeader(\n this.headerElement,\n source.fileDiff,\n this.options.disableFileHeader\n )\n ) {\n this.render({ ...props, preventEmit: true });\n }\n // Otherwise orchestrate our setup\n else {\n this.hydrationSetup({ fileDiff: source.fileDiff, lineAnnotations });\n if (this.pre != null) {\n this.renderMergeConflictActionSlots();\n }\n }\n if (!preventEmit) {\n this.emitPostRender();\n }\n }\n\n override rerender(): void {\n if (!this.enabled || this.fileDiff == null) {\n return;\n }\n this.render({ forceRender: true, renderRange: this.renderRange });\n }\n\n override render(props: UnresolvedFileRenderProps<LAnnotation> = {}): boolean {\n const {\n file,\n fileDiff,\n actions,\n markerRows,\n lineAnnotations,\n preventEmit = false,\n ...rest\n } = props;\n const source = this.getOrComputeDiff({\n file,\n fileDiff,\n actions,\n markerRows,\n });\n if (source == null) {\n return false;\n }\n this.setActiveMergeConflictState(source.actions, source.markerRows);\n const didRender = super.render({\n ...rest,\n fileDiff: source.fileDiff,\n lineAnnotations,\n preventEmit: true,\n });\n if (didRender) {\n this.renderMergeConflictActionSlots();\n if (!preventEmit) {\n this.emitPostRender();\n }\n }\n return didRender;\n }\n\n public resolveConflict(\n conflictIndex: number,\n resolution: MergeConflictResolution,\n fileDiff: FileDiffMetadata | undefined = this.computedCache.fileDiff\n ): ResolveConflictReturn | undefined {\n const action = this.conflictActions[conflictIndex];\n if (fileDiff == null || action == null) {\n return undefined;\n }\n\n if (action.conflictIndex !== conflictIndex) {\n console.error({ conflictIndex, action });\n throw new Error(\n \"UnresolvedFile.resolveConflict: conflictIndex and conflictAction don't match\"\n );\n }\n\n const newFileDiff = resolveConflictDiff(fileDiff, action, resolution);\n const previousFile = this.computedCache.file;\n const { file, actions, markerRows } = rebuildFileAndActions({\n fileDiff: newFileDiff,\n previousActions: this.conflictActions,\n resolvedConflictIndex: conflictIndex,\n previousFile,\n resolution,\n });\n\n return {\n file,\n fileDiff: newFileDiff,\n actions,\n markerRows,\n };\n }\n\n private resolveConflictAndRender(\n conflictIndex: number,\n resolution: MergeConflictResolution\n ): void {\n const action = this.conflictActions[conflictIndex];\n if (action == null) {\n return;\n }\n if (action.conflictIndex !== conflictIndex) {\n console.error({ conflictIndex, action });\n throw new Error(\n \"UnresolvedFile.resolveConflictAndRender: conflictIndex and conflictAction don't match\"\n );\n }\n const payload: MergeConflictActionPayload = {\n resolution,\n conflict: action.conflict,\n };\n const { file, fileDiff, actions, markerRows } =\n this.resolveConflict(conflictIndex, resolution) ?? {};\n if (\n file == null ||\n fileDiff == null ||\n actions == null ||\n markerRows == null\n ) {\n return;\n }\n\n this.computedCache = { file, fileDiff, actions, markerRows };\n this.setActiveMergeConflictState(actions, markerRows);\n // NOTE(amadeus): This is a bit jank, but helps to ensure we don't see a\n // bunch of jittery re-renders as things resolve out. In a more perfect\n // world we would have a more elegant way to kick off a render to the\n // highlighter and then resolve actions in a cleaner way, but time is short\n // right now. Can't let perfect be the enemy of good\n if (this.workerManager != null) {\n // Because we are using a workerManager, if we fire off the renderDiff\n // call, it will eventually get back to us in a callback which will\n // trigger a re-render\n this.hunksRenderer.renderDiff(fileDiff);\n } else {\n this.render({ forceRender: true });\n }\n this.options.onMergeConflictResolve?.(file, payload);\n }\n\n private setActiveMergeConflictState(\n actions: (MergeConflictDiffAction | undefined)[] = this.conflictActions,\n markerRows: MergeConflictMarkerRow[] = this.markerRows\n ): void {\n this.conflictActions = actions;\n this.markerRows = markerRows;\n if (\n this.computedCache.fileDiff != null &&\n this.hunksRenderer instanceof UnresolvedFileHunksRenderer\n ) {\n this.hunksRenderer.setConflictState(\n this.options.mergeConflictActionsType === 'none' ? [] : actions,\n markerRows,\n this.computedCache.fileDiff\n );\n }\n }\n\n private handleMergeConflictActionClick = (\n target: MergeConflictActionTarget\n ): void => {\n const action = this.conflictActions[target.conflictIndex];\n if (action == null) {\n return;\n }\n if (action.conflictIndex !== target.conflictIndex) {\n console.error({ conflictIndex: target.conflictIndex, action });\n throw new Error(\n \"UnresolvedFile.handleMergeConflictActionClick: conflictIndex and conflictAction don't match\"\n );\n }\n const payload: MergeConflictActionPayload = {\n resolution: target.resolution,\n conflict: action.conflict,\n };\n if (this.options.onMergeConflictAction != null) {\n this.options.onMergeConflictAction(payload, this);\n return;\n }\n this.resolveConflictAndRender(target.conflictIndex, target.resolution);\n };\n\n private renderMergeConflictActionSlots(): void {\n const { fileDiff } = this.computedCache;\n if (\n this.isContainerManaged ||\n this.fileContainer == null ||\n typeof this.options.mergeConflictActionsType !== 'function' ||\n this.conflictActions.length === 0 ||\n fileDiff == null\n ) {\n this.clearMergeConflictActionCache();\n return;\n }\n const staleActions = new Map(this.conflictActionCache);\n for (\n let actionIndex = 0;\n actionIndex < this.conflictActions.length;\n actionIndex++\n ) {\n const action = this.conflictActions[actionIndex];\n if (action == null) {\n continue;\n }\n if (action.conflictIndex !== actionIndex) {\n console.error({ conflictIndex: actionIndex, action });\n throw new Error(\n \"UnresolvedFile.renderMergeConflictActionSlots: conflictIndex and conflictAction don't match\"\n );\n }\n const anchor = getMergeConflictActionAnchor(action, fileDiff);\n if (anchor == null) {\n continue;\n }\n const conflictIndex = action.conflictIndex;\n const slotName = getMergeConflictActionSlotName({\n hunkIndex: anchor.hunkIndex,\n lineIndex: anchor.lineIndex,\n conflictIndex,\n });\n const id = `${actionIndex}-${slotName}`;\n let cache = this.conflictActionCache.get(id);\n if (\n cache == null ||\n !areMergeConflictActionsEqual(cache.action, action)\n ) {\n cache?.element.remove();\n const rendered = this.renderMergeConflictAction(action);\n if (rendered == null) {\n continue;\n }\n const element = createAnnotationWrapperNode(slotName);\n element.appendChild(rendered);\n this.fileContainer.appendChild(element);\n cache = { element, action };\n this.conflictActionCache.set(id, cache);\n }\n staleActions.delete(id);\n }\n for (const [id, { element }] of staleActions.entries()) {\n this.conflictActionCache.delete(id);\n element.remove();\n }\n }\n\n private renderMergeConflictAction(\n action: MergeConflictDiffAction\n ): HTMLElement | undefined {\n if (typeof this.options.mergeConflictActionsType !== 'function') {\n return undefined;\n }\n const rendered = this.options.mergeConflictActionsType(action, this);\n if (rendered == null) {\n return undefined;\n }\n if (rendered instanceof HTMLElement) {\n return rendered;\n }\n if (\n typeof DocumentFragment !== 'undefined' &&\n rendered instanceof DocumentFragment\n ) {\n const wrapper = document.createElement('div');\n wrapper.style.display = 'contents';\n wrapper.appendChild(rendered);\n return wrapper;\n }\n return undefined;\n }\n\n private clearMergeConflictActionCache(): void {\n for (const { element } of this.conflictActionCache.values()) {\n element.remove();\n }\n this.conflictActionCache.clear();\n }\n}\n\ninterface RebuildFileAndActionsProps {\n fileDiff: FileDiffMetadata;\n previousActions: (MergeConflictDiffAction | undefined)[];\n resolvedConflictIndex: number;\n // FIXME: Probably should remove this...\n // additionOffset: number;\n // deletionOffset: number;\n previousFile: FileContents | undefined;\n resolution: MergeConflictResolution;\n}\n\n// Rebuild the emitted unresolved file contents and remaining action anchors in\n// one pass over the post-resolution diff state.\nfunction rebuildFileAndActions({\n fileDiff,\n previousActions,\n resolvedConflictIndex,\n previousFile,\n resolution,\n}: RebuildFileAndActionsProps): Pick<\n ResolveConflictReturn,\n 'file' | 'actions' | 'markerRows'\n> {\n const resolvedAction = previousActions[resolvedConflictIndex];\n if (resolvedAction == null) {\n throw new Error(\n 'rebuildFileAndActions: missing resolved action for unresolved file rebuild'\n );\n }\n\n const actions = updateConflictActionsAfterResolution(\n previousActions,\n resolvedConflictIndex,\n resolvedAction,\n resolution\n );\n const markerRows = buildMergeConflictMarkerRows(fileDiff, actions);\n\n const file = rebuildUnresolvedFile({\n fileDiff,\n resolvedAction,\n resolvedConflictIndex,\n previousFile,\n resolution,\n });\n\n return {\n file,\n actions,\n markerRows,\n };\n}\n\ninterface RebuildUnresolvedFileProps {\n fileDiff: FileDiffMetadata;\n resolvedAction: MergeConflictDiffAction;\n resolvedConflictIndex: number;\n previousFile: FileContents | undefined;\n resolution: MergeConflictResolution;\n}\n\n// Rebuild the unresolved file text from the previous unresolved source so we\n// preserve remaining marker blocks exactly while the diff state stays in-place.\nfunction rebuildUnresolvedFile({\n resolvedAction,\n resolvedConflictIndex,\n previousFile,\n fileDiff,\n resolution,\n}: RebuildUnresolvedFileProps): FileContents {\n const previousContents = previousFile?.contents ?? '';\n const lines = splitFileContents(previousContents);\n const { conflict } = resolvedAction;\n const replacementLines = getResolvedConflictReplacementLines(\n lines,\n conflict,\n resolution\n );\n const contents = [\n ...lines.slice(0, conflict.startLineIndex),\n ...replacementLines,\n ...lines.slice(conflict.endLineIndex + 1),\n ].join('');\n\n return {\n name: previousFile?.name ?? fileDiff.name,\n contents,\n cacheKey:\n previousFile?.cacheKey != null\n ? `${previousFile.cacheKey}:mc-${resolvedConflictIndex}-${resolution}`\n : undefined,\n };\n}\n\nfunction getResolvedConflictReplacementLines(\n lines: string[],\n conflict: MergeConflictDiffAction['conflict'],\n resolution: MergeConflictResolution\n): string[] {\n const currentLines = lines.slice(\n conflict.startLineIndex + 1,\n conflict.baseMarkerLineIndex ?? conflict.separatorLineIndex\n );\n const incomingLines = lines.slice(\n conflict.separatorLineIndex + 1,\n conflict.endLineIndex\n );\n\n if (resolution === 'current') {\n return currentLines;\n }\n if (resolution === 'incoming') {\n return incomingLines;\n }\n return [...currentLines, ...incomingLines];\n}\n\n// The diff resolver keeps hunk/content group indexes stable, so the only\n// follow-up update we need here is shifting unresolved source-region line\n// numbers for later conflicts in the rebuilt file text.\nfunction updateConflictActionsAfterResolution(\n previousActions: (MergeConflictDiffAction | undefined)[],\n resolvedConflictIndex: number,\n resolvedAction: MergeConflictDiffAction,\n resolution: MergeConflictResolution\n): (MergeConflictDiffAction | undefined)[] {\n const lineDelta = getResolvedConflictLineDelta(\n resolvedAction.conflict,\n resolution\n );\n\n return previousActions.map((action, index) => {\n if (index === resolvedConflictIndex) {\n return undefined;\n }\n if (action == null) {\n return undefined;\n }\n if (action.conflict.startLineIndex > resolvedAction.conflict.endLineIndex) {\n return {\n ...action,\n conflict: shiftMergeConflictRegion(action.conflict, lineDelta),\n };\n }\n return action;\n });\n}\n\nfunction getResolvedConflictLineDelta(\n conflict: MergeConflictRegion,\n resolution: MergeConflictResolution\n): number {\n const currentLineCount =\n (conflict.baseMarkerLineIndex ?? conflict.separatorLineIndex) -\n conflict.startLineIndex -\n 1;\n const incomingLineCount =\n conflict.endLineIndex - conflict.separatorLineIndex - 1;\n const replacementLineCount =\n resolution === 'current'\n ? currentLineCount\n : resolution === 'incoming'\n ? incomingLineCount\n : currentLineCount + incomingLineCount;\n const conflictLineCount = conflict.endLineIndex - conflict.startLineIndex + 1;\n return replacementLineCount - conflictLineCount;\n}\n\nfunction shiftMergeConflictRegion(\n conflict: MergeConflictRegion,\n lineDelta: number\n): MergeConflictRegion {\n return {\n ...conflict,\n startLineIndex: conflict.startLineIndex + lineDelta,\n startLineNumber: conflict.startLineNumber + lineDelta,\n separatorLineIndex: conflict.separatorLineIndex + lineDelta,\n separatorLineNumber: conflict.separatorLineNumber + lineDelta,\n endLineIndex: conflict.endLineIndex + lineDelta,\n endLineNumber: conflict.endLineNumber + lineDelta,\n baseMarkerLineIndex:\n conflict.baseMarkerLineIndex != null\n ? conflict.baseMarkerLineIndex + lineDelta\n : undefined,\n baseMarkerLineNumber:\n conflict.baseMarkerLineNumber != null\n ? conflict.baseMarkerLineNumber + lineDelta\n : undefined,\n };\n}\n\nfunction shouldRenderCode(\n pre: HTMLPreElement | undefined,\n fileDiff: FileDiffMetadata | undefined,\n collapsed = false\n): boolean {\n return !collapsed && pre == null && fileDiff != null;\n}\n\nfunction shouldRenderHeader(\n headerElement: HTMLElement | undefined,\n fileDiff: FileDiffMetadata | undefined,\n disableFileHeader = false\n): boolean {\n return headerElement == null && fileDiff != null && !disableFileHeader;\n}\n\n// NOTE(amadeus): Should probably pull this out into a util, and make variants\n// for all component types\nexport function getUnresolvedDiffHunksRendererOptions<LAnnotation>(\n options?: UnresolvedFileOptions<LAnnotation>,\n baseOptions?: UnresolvedFileOptions<LAnnotation>\n): UnresolvedFileHunksRendererOptions {\n return {\n ...baseOptions,\n ...options,\n hunkSeparators:\n typeof options?.hunkSeparators === 'function'\n ? 'custom'\n : options?.hunkSeparators,\n mergeConflictActionsType:\n typeof options?.mergeConflictActionsType === 'function'\n ? 'custom'\n : options?.mergeConflictActionsType,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"UnresolvedFile.js","names":["resolveConflictDiff"],"sources":["../../src/components/UnresolvedFile.ts"],"sourcesContent":["import { DEFAULT_THEMES } from '../constants';\nimport type { MergeConflictActionTarget } from '../managers/InteractionManager';\nimport { pluckInteractionOptions } from '../managers/InteractionManager';\nimport type { HunksRenderResult } from '../renderers/DiffHunksRenderer';\nimport {\n UnresolvedFileHunksRenderer,\n type UnresolvedFileHunksRendererOptions,\n} from '../renderers/UnresolvedFileHunksRenderer';\nimport type {\n FileContents,\n FileDiffMetadata,\n MergeConflictActionPayload,\n MergeConflictMarkerRow,\n MergeConflictRegion,\n MergeConflictResolution,\n PostRenderPhase,\n} from '../types';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areMergeConflictActionsEqual } from '../utils/areMergeConflictActionsEqual';\nimport { createAnnotationWrapperNode } from '../utils/createAnnotationWrapperNode';\nimport { getMergeConflictActionSlotName } from '../utils/getMergeConflictActionSlotName';\nimport {\n buildMergeConflictMarkerRows,\n getMergeConflictActionAnchor,\n type MergeConflictDiffAction,\n parseMergeConflictDiffFromFile,\n} from '../utils/parseMergeConflictDiffFromFile';\nimport { resolveConflict as resolveConflictDiff } from '../utils/resolveConflict';\nimport { splitFileContents } from '../utils/splitFileContents';\nimport type { WorkerPoolManager } from '../worker';\nimport {\n FileDiff,\n type FileDiffOptions,\n type FileDiffRenderBaseProps,\n} from './FileDiff';\n\nexport type RenderMergeConflictActions<LAnnotation> = (\n action: MergeConflictDiffAction,\n instance: UnresolvedFile<LAnnotation>\n) => HTMLElement | DocumentFragment | null | undefined;\n\nexport type MergeConflictActionsTypeOption<LAnnotation> =\n | 'none'\n | 'default'\n | RenderMergeConflictActions<LAnnotation>;\n\nexport interface UnresolvedFileOptions<LAnnotation> extends Omit<\n FileDiffOptions<LAnnotation>,\n 'diffStyle' | 'onPostRender'\n> {\n onPostRender?(\n node: HTMLElement,\n instance: UnresolvedFile<LAnnotation>,\n phase: PostRenderPhase\n ): unknown;\n mergeConflictActionsType?: MergeConflictActionsTypeOption<LAnnotation>;\n onMergeConflictAction?(\n payload: MergeConflictActionPayload,\n instance: UnresolvedFile<LAnnotation>\n ): void;\n onMergeConflictResolve?(\n file: FileContents,\n payload: MergeConflictActionPayload\n ): void;\n maxContextLines?: number;\n}\n\nexport interface UnresolvedFileRenderProps<\n LAnnotation,\n> extends FileDiffRenderBaseProps<LAnnotation> {\n file?: FileContents;\n actions?: (MergeConflictDiffAction | undefined)[];\n markerRows?: MergeConflictMarkerRow[];\n}\n\nexport interface UnresolvedFileHydrationProps<LAnnotation> extends Omit<\n UnresolvedFileRenderProps<LAnnotation>,\n 'file'\n> {\n file?: FileContents;\n fileContainer: HTMLElement;\n prerenderedHTML?: string;\n}\n\ninterface MergeConflictActionElementCache {\n element: HTMLElement;\n action: MergeConflictDiffAction;\n}\n\ninterface GetOrComputeDiffProps {\n file: FileContents | undefined;\n fileDiff: FileDiffMetadata | undefined;\n actions: (MergeConflictDiffAction | undefined)[] | undefined;\n markerRows: MergeConflictMarkerRow[] | undefined;\n}\n\ninterface GetOrComputeDiffResult {\n fileDiff: FileDiffMetadata;\n actions: (MergeConflictDiffAction | undefined)[];\n markerRows: MergeConflictMarkerRow[];\n}\n\ninterface ResolveConflictReturn {\n file: FileContents;\n fileDiff: FileDiffMetadata;\n actions: (MergeConflictDiffAction | undefined)[];\n markerRows: MergeConflictMarkerRow[];\n}\n\ntype UnresolvedFileDataCache = GetOrComputeDiffProps;\n\nlet instanceId = -1;\n\nexport class UnresolvedFile<\n LAnnotation = undefined,\n> extends FileDiff<LAnnotation> {\n override readonly __id: string = `unresolved-file:${++instanceId}`;\n override readonly type = 'unresolved-file';\n\n protected computedCache: UnresolvedFileDataCache = {\n file: undefined,\n fileDiff: undefined,\n actions: undefined,\n markerRows: undefined,\n };\n private conflictActions: (MergeConflictDiffAction | undefined)[] = [];\n private markerRows: MergeConflictMarkerRow[] = [];\n private conflictActionCache: Map<string, MergeConflictActionElementCache> =\n new Map();\n\n constructor(\n public override options: UnresolvedFileOptions<LAnnotation> = {\n theme: DEFAULT_THEMES,\n },\n workerManager?: WorkerPoolManager | undefined,\n isContainerManaged = false\n ) {\n super(undefined, workerManager, isContainerManaged);\n this.setOptions(options);\n }\n\n override setOptions(\n options: UnresolvedFileOptions<LAnnotation> | undefined\n ): void {\n if (options == null) {\n return;\n }\n\n if (\n options.onMergeConflictAction != null &&\n options.onMergeConflictResolve != null\n ) {\n throw new Error(\n 'UnresolvedFile: onMergeConflictAction and onMergeConflictResolve are mutually exclusive. Use only one callback.'\n );\n }\n\n this.options = options;\n this.hunksRenderer.setOptions(this.getHunksRendererOptions(options));\n this.syncInteractionOptions();\n }\n\n // UnresolvedFile adds a merge-conflict-action click handler to the\n // InteractionManager. FileDiff.syncInteractionOptions() re-runs on every\n // re-render and during hydration; without this override it would rebuild the\n // interaction options without that handler, so resolving one conflict (which\n // re-renders the diff) would silently disable every remaining action button.\n protected override syncInteractionOptions(): void {\n this.interactionManager.setOptions(\n pluckInteractionOptions(\n this.options,\n typeof this.options.hunkSeparators === 'function' ||\n (this.options.hunkSeparators ?? 'line-info') === 'line-info' ||\n this.options.hunkSeparators === 'line-info-basic'\n ? this.handleExpandHunk\n : undefined,\n this.getLineIndex,\n this.handleMergeConflictActionClick\n )\n );\n }\n\n protected override createHunksRenderer(\n options: UnresolvedFileOptions<LAnnotation>\n ): UnresolvedFileHunksRenderer<LAnnotation> {\n const renderer = new UnresolvedFileHunksRenderer<LAnnotation>(\n this.getHunksRendererOptions(options),\n this.handleHighlightRender,\n this.workerManager\n );\n return renderer;\n }\n\n protected override getHunksRendererOptions(\n options: UnresolvedFileOptions<LAnnotation>\n ): UnresolvedFileHunksRendererOptions {\n return getUnresolvedDiffHunksRendererOptions(options, this.options);\n }\n\n protected override applyPreNodeAttributes(\n pre: HTMLPreElement,\n result: HunksRenderResult\n ): void {\n super.applyPreNodeAttributes(pre, result, {\n 'data-has-merge-conflict': '',\n });\n }\n\n override cleanUp(): void {\n this.emitPostRender(true);\n this.clearMergeConflictActionCache();\n this.computedCache = {\n file: undefined,\n fileDiff: undefined,\n actions: undefined,\n markerRows: undefined,\n };\n this.conflictActions = [];\n super.cleanUp();\n }\n\n private getOrComputeDiff({\n file,\n fileDiff,\n actions,\n markerRows,\n }: GetOrComputeDiffProps): GetOrComputeDiffResult | undefined {\n const { maxContextLines, onMergeConflictAction } = this.options;\n wrapper: {\n // We are dealing with a controlled component\n if (onMergeConflictAction != null) {\n const hasFileDiff = fileDiff != null;\n const hasActions = actions != null;\n const hasMarkerRows = markerRows != null;\n if (hasFileDiff !== hasActions || hasFileDiff !== hasMarkerRows) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: fileDiff, actions, and markerRows must be passed together'\n );\n }\n // If we were provided a new fileDiff/actions/markerRows, we are a FULLY\n // controlled component, which means we will not do any computation\n if (fileDiff != null && actions != null && markerRows != null) {\n this.computedCache = {\n file: file ?? this.computedCache.file,\n fileDiff,\n actions,\n markerRows,\n };\n break wrapper;\n }\n // If we were provided a new file, we should attempt to parse out a new\n // diff/actions if we haven't computed it before. Once we initialize from\n // a file, later updates must flow through fileDiff/actions instead of\n // reparsing from a new file input.\n else if (file != null || this.computedCache.file != null) {\n if (\n file != null &&\n this.computedCache.file != null &&\n !areFilesEqual(file, this.computedCache.file) &&\n this.computedCache.fileDiff != null &&\n this.computedCache.actions != null\n ) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: file can only be used to initialize unresolved state once. Pass fileDiff and actions for subsequent updates.'\n );\n }\n file ??= this.computedCache.file;\n if (file == null) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: file is null, should be impossible'\n );\n }\n if (\n !areFilesEqual(file, this.computedCache.file) ||\n this.computedCache.fileDiff == null ||\n this.computedCache.actions == null\n ) {\n const computed = parseMergeConflictDiffFromFile(\n file,\n maxContextLines\n );\n this.computedCache = {\n file,\n fileDiff: computed.fileDiff,\n actions: computed.actions,\n markerRows: computed.markerRows,\n };\n }\n fileDiff = this.computedCache.fileDiff;\n actions = this.computedCache.actions;\n markerRows = this.computedCache.markerRows;\n break wrapper;\n }\n // Otherwise we should fall through and try to use the cache if it exists\n else {\n fileDiff = this.computedCache.fileDiff;\n actions = this.computedCache.actions;\n markerRows = this.computedCache.markerRows;\n break wrapper;\n }\n }\n // If we are uncontrolled we only rely on the file and only use the first\n // version. After that, the cached diff/action pair is the source of\n // truth and we should not accept a new file input.\n else {\n if (fileDiff != null || actions != null || markerRows != null) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: fileDiff, actions, and markerRows are only usable in controlled mode, you must pass in `onMergeConflictAction`'\n );\n }\n if (\n file != null &&\n this.computedCache.file != null &&\n !areFilesEqual(file, this.computedCache.file)\n ) {\n throw new Error(\n 'UnresolvedFile.getOrComputeDiff: uncontrolled unresolved files parse the file only once. Later updates must come from the cached diff state.'\n );\n }\n this.computedCache.file ??= file;\n if (\n this.computedCache.fileDiff == null &&\n this.computedCache.file != null\n ) {\n const computed = parseMergeConflictDiffFromFile(\n this.computedCache.file,\n maxContextLines\n );\n this.computedCache.fileDiff = computed.fileDiff;\n this.computedCache.actions = computed.actions;\n this.computedCache.markerRows = computed.markerRows;\n }\n // Because we are uncontrolled, the source of truth is the\n // computedCache\n fileDiff = this.computedCache.fileDiff;\n actions = this.computedCache.actions;\n markerRows = this.computedCache.markerRows;\n break wrapper;\n }\n }\n if (fileDiff == null || actions == null || markerRows == null) {\n return undefined;\n }\n return { fileDiff, actions, markerRows };\n }\n\n override hydrate(props: UnresolvedFileHydrationProps<LAnnotation>): void {\n const {\n file,\n fileDiff,\n actions,\n markerRows,\n lineAnnotations,\n fileContainer,\n prerenderedHTML,\n preventEmit = false,\n } = props;\n const source = this.getOrComputeDiff({\n file,\n fileDiff,\n actions,\n markerRows,\n });\n if (source == null) {\n return;\n }\n this.hydrateElements(fileContainer, prerenderedHTML);\n this.setActiveMergeConflictState(source.actions, source.markerRows);\n // If necessary hydration elements don't exist, we should assume a full\n // render\n if (\n shouldRenderCode(this.pre, source.fileDiff, this.options.collapsed) ||\n shouldRenderHeader(\n this.headerElement,\n source.fileDiff,\n this.options.disableFileHeader\n )\n ) {\n this.render({ ...props, preventEmit: true });\n }\n // Otherwise orchestrate our setup\n else {\n this.hydrationSetup({ fileDiff: source.fileDiff, lineAnnotations });\n if (this.pre != null) {\n this.renderMergeConflictActionSlots();\n }\n }\n if (!preventEmit) {\n this.emitPostRender();\n }\n }\n\n override rerender(): void {\n if (!this.enabled || this.fileDiff == null) {\n return;\n }\n this.render({ forceRender: true, renderRange: this.renderRange });\n }\n\n override render(props: UnresolvedFileRenderProps<LAnnotation> = {}): boolean {\n const {\n file,\n fileDiff,\n actions,\n markerRows,\n lineAnnotations,\n preventEmit = false,\n ...rest\n } = props;\n const source = this.getOrComputeDiff({\n file,\n fileDiff,\n actions,\n markerRows,\n });\n if (source == null) {\n return false;\n }\n this.setActiveMergeConflictState(source.actions, source.markerRows);\n const didRender = super.render({\n ...rest,\n fileDiff: source.fileDiff,\n lineAnnotations,\n preventEmit: true,\n });\n if (didRender) {\n this.renderMergeConflictActionSlots();\n if (!preventEmit) {\n this.emitPostRender();\n }\n }\n return didRender;\n }\n\n public resolveConflict(\n conflictIndex: number,\n resolution: MergeConflictResolution,\n fileDiff: FileDiffMetadata | undefined = this.computedCache.fileDiff\n ): ResolveConflictReturn | undefined {\n const action = this.conflictActions[conflictIndex];\n if (fileDiff == null || action == null) {\n return undefined;\n }\n\n if (action.conflictIndex !== conflictIndex) {\n console.error({ conflictIndex, action });\n throw new Error(\n \"UnresolvedFile.resolveConflict: conflictIndex and conflictAction don't match\"\n );\n }\n\n const newFileDiff = resolveConflictDiff(fileDiff, action, resolution);\n const previousFile = this.computedCache.file;\n const { file, actions, markerRows } = rebuildFileAndActions({\n fileDiff: newFileDiff,\n previousActions: this.conflictActions,\n resolvedConflictIndex: conflictIndex,\n previousFile,\n resolution,\n });\n\n return {\n file,\n fileDiff: newFileDiff,\n actions,\n markerRows,\n };\n }\n\n private resolveConflictAndRender(\n conflictIndex: number,\n resolution: MergeConflictResolution\n ): void {\n const action = this.conflictActions[conflictIndex];\n if (action == null) {\n return;\n }\n if (action.conflictIndex !== conflictIndex) {\n console.error({ conflictIndex, action });\n throw new Error(\n \"UnresolvedFile.resolveConflictAndRender: conflictIndex and conflictAction don't match\"\n );\n }\n const payload: MergeConflictActionPayload = {\n resolution,\n conflict: action.conflict,\n };\n const { file, fileDiff, actions, markerRows } =\n this.resolveConflict(conflictIndex, resolution) ?? {};\n if (\n file == null ||\n fileDiff == null ||\n actions == null ||\n markerRows == null\n ) {\n return;\n }\n\n this.computedCache = { file, fileDiff, actions, markerRows };\n this.setActiveMergeConflictState(actions, markerRows);\n // NOTE(amadeus): This is a bit jank, but helps to ensure we don't see a\n // bunch of jittery re-renders as things resolve out. In a more perfect\n // world we would have a more elegant way to kick off a render to the\n // highlighter and then resolve actions in a cleaner way, but time is short\n // right now. Can't let perfect be the enemy of good\n if (this.workerManager != null) {\n // Because we are using a workerManager, if we fire off the renderDiff\n // call, it will eventually get back to us in a callback which will\n // trigger a re-render\n this.hunksRenderer.renderDiff(fileDiff);\n } else {\n this.render({ forceRender: true });\n }\n this.options.onMergeConflictResolve?.(file, payload);\n }\n\n private setActiveMergeConflictState(\n actions: (MergeConflictDiffAction | undefined)[] = this.conflictActions,\n markerRows: MergeConflictMarkerRow[] = this.markerRows\n ): void {\n this.conflictActions = actions;\n this.markerRows = markerRows;\n if (\n this.computedCache.fileDiff != null &&\n this.hunksRenderer instanceof UnresolvedFileHunksRenderer\n ) {\n this.hunksRenderer.setConflictState(\n this.options.mergeConflictActionsType === 'none' ? [] : actions,\n markerRows,\n this.computedCache.fileDiff\n );\n }\n }\n\n private handleMergeConflictActionClick = (\n target: MergeConflictActionTarget\n ): void => {\n const action = this.conflictActions[target.conflictIndex];\n if (action == null) {\n return;\n }\n if (action.conflictIndex !== target.conflictIndex) {\n console.error({ conflictIndex: target.conflictIndex, action });\n throw new Error(\n \"UnresolvedFile.handleMergeConflictActionClick: conflictIndex and conflictAction don't match\"\n );\n }\n const payload: MergeConflictActionPayload = {\n resolution: target.resolution,\n conflict: action.conflict,\n };\n if (this.options.onMergeConflictAction != null) {\n this.options.onMergeConflictAction(payload, this);\n return;\n }\n this.resolveConflictAndRender(target.conflictIndex, target.resolution);\n };\n\n private renderMergeConflictActionSlots(): void {\n const { fileDiff } = this.computedCache;\n if (\n this.isContainerManaged ||\n this.fileContainer == null ||\n typeof this.options.mergeConflictActionsType !== 'function' ||\n this.conflictActions.length === 0 ||\n fileDiff == null\n ) {\n this.clearMergeConflictActionCache();\n return;\n }\n const staleActions = new Map(this.conflictActionCache);\n for (\n let actionIndex = 0;\n actionIndex < this.conflictActions.length;\n actionIndex++\n ) {\n const action = this.conflictActions[actionIndex];\n if (action == null) {\n continue;\n }\n if (action.conflictIndex !== actionIndex) {\n console.error({ conflictIndex: actionIndex, action });\n throw new Error(\n \"UnresolvedFile.renderMergeConflictActionSlots: conflictIndex and conflictAction don't match\"\n );\n }\n const anchor = getMergeConflictActionAnchor(action, fileDiff);\n if (anchor == null) {\n continue;\n }\n const conflictIndex = action.conflictIndex;\n const slotName = getMergeConflictActionSlotName({\n hunkIndex: anchor.hunkIndex,\n lineIndex: anchor.lineIndex,\n conflictIndex,\n });\n const id = `${actionIndex}-${slotName}`;\n let cache = this.conflictActionCache.get(id);\n if (\n cache == null ||\n !areMergeConflictActionsEqual(cache.action, action)\n ) {\n cache?.element.remove();\n const rendered = this.renderMergeConflictAction(action);\n if (rendered == null) {\n continue;\n }\n const element = createAnnotationWrapperNode(slotName);\n element.appendChild(rendered);\n this.fileContainer.appendChild(element);\n cache = { element, action };\n this.conflictActionCache.set(id, cache);\n }\n staleActions.delete(id);\n }\n for (const [id, { element }] of staleActions.entries()) {\n this.conflictActionCache.delete(id);\n element.remove();\n }\n }\n\n private renderMergeConflictAction(\n action: MergeConflictDiffAction\n ): HTMLElement | undefined {\n if (typeof this.options.mergeConflictActionsType !== 'function') {\n return undefined;\n }\n const rendered = this.options.mergeConflictActionsType(action, this);\n if (rendered == null) {\n return undefined;\n }\n if (rendered instanceof HTMLElement) {\n return rendered;\n }\n if (\n typeof DocumentFragment !== 'undefined' &&\n rendered instanceof DocumentFragment\n ) {\n const wrapper = document.createElement('div');\n wrapper.style.display = 'contents';\n wrapper.appendChild(rendered);\n return wrapper;\n }\n return undefined;\n }\n\n private clearMergeConflictActionCache(): void {\n for (const { element } of this.conflictActionCache.values()) {\n element.remove();\n }\n this.conflictActionCache.clear();\n }\n}\n\ninterface RebuildFileAndActionsProps {\n fileDiff: FileDiffMetadata;\n previousActions: (MergeConflictDiffAction | undefined)[];\n resolvedConflictIndex: number;\n // FIXME: Probably should remove this...\n // additionOffset: number;\n // deletionOffset: number;\n previousFile: FileContents | undefined;\n resolution: MergeConflictResolution;\n}\n\n// Rebuild the emitted unresolved file contents and remaining action anchors in\n// one pass over the post-resolution diff state.\nfunction rebuildFileAndActions({\n fileDiff,\n previousActions,\n resolvedConflictIndex,\n previousFile,\n resolution,\n}: RebuildFileAndActionsProps): Pick<\n ResolveConflictReturn,\n 'file' | 'actions' | 'markerRows'\n> {\n const resolvedAction = previousActions[resolvedConflictIndex];\n if (resolvedAction == null) {\n throw new Error(\n 'rebuildFileAndActions: missing resolved action for unresolved file rebuild'\n );\n }\n\n const actions = updateConflictActionsAfterResolution(\n previousActions,\n resolvedConflictIndex,\n resolvedAction,\n resolution\n );\n const markerRows = buildMergeConflictMarkerRows(fileDiff, actions);\n\n const file = rebuildUnresolvedFile({\n fileDiff,\n resolvedAction,\n resolvedConflictIndex,\n previousFile,\n resolution,\n });\n\n return {\n file,\n actions,\n markerRows,\n };\n}\n\ninterface RebuildUnresolvedFileProps {\n fileDiff: FileDiffMetadata;\n resolvedAction: MergeConflictDiffAction;\n resolvedConflictIndex: number;\n previousFile: FileContents | undefined;\n resolution: MergeConflictResolution;\n}\n\n// Rebuild the unresolved file text from the previous unresolved source so we\n// preserve remaining marker blocks exactly while the diff state stays in-place.\nfunction rebuildUnresolvedFile({\n resolvedAction,\n resolvedConflictIndex,\n previousFile,\n fileDiff,\n resolution,\n}: RebuildUnresolvedFileProps): FileContents {\n const previousContents = previousFile?.contents ?? '';\n const lines = splitFileContents(previousContents);\n const { conflict } = resolvedAction;\n const replacementLines = getResolvedConflictReplacementLines(\n lines,\n conflict,\n resolution\n );\n const contents = [\n ...lines.slice(0, conflict.startLineIndex),\n ...replacementLines,\n ...lines.slice(conflict.endLineIndex + 1),\n ].join('');\n\n return {\n name: previousFile?.name ?? fileDiff.name,\n contents,\n cacheKey:\n previousFile?.cacheKey != null\n ? `${previousFile.cacheKey}:mc-${resolvedConflictIndex}-${resolution}`\n : undefined,\n };\n}\n\nfunction getResolvedConflictReplacementLines(\n lines: string[],\n conflict: MergeConflictDiffAction['conflict'],\n resolution: MergeConflictResolution\n): string[] {\n const currentLines = lines.slice(\n conflict.startLineIndex + 1,\n conflict.baseMarkerLineIndex ?? conflict.separatorLineIndex\n );\n const incomingLines = lines.slice(\n conflict.separatorLineIndex + 1,\n conflict.endLineIndex\n );\n\n if (resolution === 'current') {\n return currentLines;\n }\n if (resolution === 'incoming') {\n return incomingLines;\n }\n return [...currentLines, ...incomingLines];\n}\n\n// The diff resolver keeps hunk/content group indexes stable, so the only\n// follow-up update we need here is shifting unresolved source-region line\n// numbers for later conflicts in the rebuilt file text.\nfunction updateConflictActionsAfterResolution(\n previousActions: (MergeConflictDiffAction | undefined)[],\n resolvedConflictIndex: number,\n resolvedAction: MergeConflictDiffAction,\n resolution: MergeConflictResolution\n): (MergeConflictDiffAction | undefined)[] {\n const lineDelta = getResolvedConflictLineDelta(\n resolvedAction.conflict,\n resolution\n );\n\n return previousActions.map((action, index) => {\n if (index === resolvedConflictIndex) {\n return undefined;\n }\n if (action == null) {\n return undefined;\n }\n if (action.conflict.startLineIndex > resolvedAction.conflict.endLineIndex) {\n return {\n ...action,\n conflict: shiftMergeConflictRegion(action.conflict, lineDelta),\n };\n }\n return action;\n });\n}\n\nfunction getResolvedConflictLineDelta(\n conflict: MergeConflictRegion,\n resolution: MergeConflictResolution\n): number {\n const currentLineCount =\n (conflict.baseMarkerLineIndex ?? conflict.separatorLineIndex) -\n conflict.startLineIndex -\n 1;\n const incomingLineCount =\n conflict.endLineIndex - conflict.separatorLineIndex - 1;\n const replacementLineCount =\n resolution === 'current'\n ? currentLineCount\n : resolution === 'incoming'\n ? incomingLineCount\n : currentLineCount + incomingLineCount;\n const conflictLineCount = conflict.endLineIndex - conflict.startLineIndex + 1;\n return replacementLineCount - conflictLineCount;\n}\n\nfunction shiftMergeConflictRegion(\n conflict: MergeConflictRegion,\n lineDelta: number\n): MergeConflictRegion {\n return {\n ...conflict,\n startLineIndex: conflict.startLineIndex + lineDelta,\n startLineNumber: conflict.startLineNumber + lineDelta,\n separatorLineIndex: conflict.separatorLineIndex + lineDelta,\n separatorLineNumber: conflict.separatorLineNumber + lineDelta,\n endLineIndex: conflict.endLineIndex + lineDelta,\n endLineNumber: conflict.endLineNumber + lineDelta,\n baseMarkerLineIndex:\n conflict.baseMarkerLineIndex != null\n ? conflict.baseMarkerLineIndex + lineDelta\n : undefined,\n baseMarkerLineNumber:\n conflict.baseMarkerLineNumber != null\n ? conflict.baseMarkerLineNumber + lineDelta\n : undefined,\n };\n}\n\nfunction shouldRenderCode(\n pre: HTMLPreElement | undefined,\n fileDiff: FileDiffMetadata | undefined,\n collapsed = false\n): boolean {\n return !collapsed && pre == null && fileDiff != null;\n}\n\nfunction shouldRenderHeader(\n headerElement: HTMLElement | undefined,\n fileDiff: FileDiffMetadata | undefined,\n disableFileHeader = false\n): boolean {\n return headerElement == null && fileDiff != null && !disableFileHeader;\n}\n\n// NOTE(amadeus): Should probably pull this out into a util, and make variants\n// for all component types\nexport function getUnresolvedDiffHunksRendererOptions<LAnnotation>(\n options?: UnresolvedFileOptions<LAnnotation>,\n baseOptions?: UnresolvedFileOptions<LAnnotation>\n): UnresolvedFileHunksRendererOptions {\n return {\n ...baseOptions,\n ...options,\n hunkSeparators:\n typeof options?.hunkSeparators === 'function'\n ? 'custom'\n : options?.hunkSeparators,\n mergeConflictActionsType:\n typeof options?.mergeConflictActionsType === 'function'\n ? 'custom'\n : options?.mergeConflictActionsType,\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualizedFile.d.ts","names":[],"sources":["../../src/components/VirtualizedFile.ts"],"mappings":";;;;;;;cAoEa,eAAA,kCAEH,IAAA,CAAK,WAAA;EAAA,QAkBH,WAAA;EAAA,QACA,OAAA;EAAA,SAlBQ,IAAA;EAEX,GAAA;EACA,MAAA;EAAA,QACC,KAAA;EAAA,QAKA,SAAA;EAAA,QACA,OAAA;EAAA,QACA,WAAA;EAAA,QACA,mBAAA;EAAA,QACA,gBAAA;EAER,WAAA,CACE,OAAA,EAAS,WAAA,CAAY,WAAA,eACb,WAAA,EAAa,WAAA,GAAc,QAAA,CAAS,WAAA,GACpC,OAAA,GAAS,kBAAA,EACjB,aAAA,GAAgB,iBAAA,EAChB,kBAAA;EAKK,UAAA,CAAW,OAAA,EAAS,kBAAA,EAAoB,KAAA;EAStC,kBAAA,CACP,eAAA,EAAiB,cAAA,CAAe,WAAA;EAAA,QAO1B,mBAAA;EAAA,QAcA,kBAAA;EASD,aAAA,CAAc,SAAA,UAAmB,eAAA;EAS/B,UAAA,CAAW,OAAA,EAAS,WAAA,CAAY,WAAA;EA2BhC,YAAA,CAAa,SAAA,EAAW,UAAA;EAAA,QAUzB,gBAAA;EAqBD,gBAAA;EA+FA,QAAA,GAAQ,KAAA;EAcR,mBAAA,CACL,IAAA,EAAM,YAAA,EACN,GAAA,UACA,KAAA,GAAQ,0BAAA,EACR,eAAA,GAAkB,cAAA,CAAe,WAAA;EA6B5B,eAAA,CACL,UAAA;IACG,GAAA;IAAa,MAAA;EAAA;EA6CX,sBAAA,CACL,gBAAA,WACC,uBAAA;EAmFI,oBAAA;EAIA,sBAAA,CACL,WAAA,GAAc,YAAA,GACb,WAAA;EAwCM,OAAA,CAAQ,OAAA;EAAA,QAaT,sBAAA;EAoED,aAAA,CAAc,OAAA;EAaZ,QAAA;EASA,mBAAA,CACP,YAAA,EAAc,iBAAA,EACd,kBAAA,GAAqB,cAAA,CAAe,WAAA,KACpC,kBAAA;EAuCO,MAAA;IACP,aAAA;IACA,IAAA;IACA,WAAA;IACA,eAAA;IAAA,GACG;EAAA,GACF,eAAA,CAAgB,WAAA;EAoEZ,kBAAA;EAAA,UAIY,kCAAA;EAAA,QAIX,YAAA;EAAA,QAIA,cAAA;EAAA,QAIA,mBAAA;EAAA,QAWA,kCAAA;EAAA,QAiCA,4BAAA;EAAA,QAuCA,iBAAA;EAAA,QASA,oBAAA;EAAA,QAIA,wBAAA;EAAA,QAIA,4BAAA;AAAA"}
1
+ {"version":3,"file":"VirtualizedFile.d.ts","names":[],"sources":["../../src/components/VirtualizedFile.ts"],"mappings":";;;;;;;cAoEa,eAAA,kCAEH,IAAA,CAAK,WAAA;EAAA,QAkBH,WAAA;EAAA,QACA,OAAA;EAAA,SAlBQ,IAAA;EAEX,GAAA;EACA,MAAA;EAAA,QACC,KAAA;EAAA,QAKA,SAAA;EAAA,QACA,OAAA;EAAA,QACA,WAAA;EAAA,QACA,mBAAA;EAAA,QACA,gBAAA;EAER,WAAA,CACE,OAAA,EAAS,WAAA,CAAY,WAAA,eACb,WAAA,EAAa,WAAA,GAAc,QAAA,CAAS,WAAA,GACpC,OAAA,GAAS,kBAAA,EACjB,aAAA,GAAgB,iBAAA,EAChB,kBAAA;EAKK,UAAA,CAAW,OAAA,EAAS,kBAAA,EAAoB,KAAA;EAStC,kBAAA,CACP,eAAA,EAAiB,cAAA,CAAe,WAAA;EAAA,QAO1B,mBAAA;EAAA,QAcA,kBAAA;EASD,aAAA,CAAc,SAAA,UAAmB,eAAA;EAS/B,UAAA,CAAW,OAAA,EAAS,WAAA,CAAY,WAAA;EA2BhC,YAAA,CAAa,SAAA,EAAW,UAAA;EAAA,QAUzB,gBAAA;EAqBD,gBAAA;EA+FA,QAAA,GAAQ,KAAA;EAcR,mBAAA,CACL,IAAA,EAAM,YAAA,EACN,GAAA,UACA,KAAA,GAAQ,0BAAA,EACR,eAAA,GAAkB,cAAA,CAAe,WAAA;EA6B5B,eAAA,CACL,UAAA;IACG,GAAA;IAAa,MAAA;EAAA;EA6CX,sBAAA,CACL,gBAAA,WACC,uBAAA;EAmFI,oBAAA;EAIA,sBAAA,CACL,WAAA,GAAc,YAAA,GACb,WAAA;EAwCM,OAAA,CAAQ,OAAA;EAAA,QAaT,sBAAA;EAoED,aAAA,CAAc,OAAA;EAaZ,QAAA;EASA,mBAAA,CACP,YAAA,EAAc,iBAAA,EACd,kBAAA,GAAqB,cAAA,CAAe,WAAA,KACpC,kBAAA;EA6BO,MAAA;IACP,aAAA;IACA,IAAA;IACA,WAAA;IACA,eAAA;IAAA,GACG;EAAA,GACF,eAAA,CAAgB,WAAA;EAoEZ,kBAAA;EAAA,UAIY,kCAAA;EAAA,QAIX,YAAA;EAAA,QAIA,cAAA;EAAA,QAIA,mBAAA;EAAA,QAWA,kCAAA;EAAA,QAiCA,4BAAA;EAAA,QAuCA,iBAAA;EAAA,QASA,oBAAA;EAAA,QAIA,wBAAA;EAAA,QAIA,4BAAA;AAAA"}
@@ -70,12 +70,12 @@ var VirtualizedFile = class extends File {
70
70
  if (this.isAdvancedMode()) throw new Error("VirtualizedFile.setThemeType cannot be used inside CodeView. Update CodeView options instead.");
71
71
  super.setThemeType(themeType);
72
72
  }
73
- resetLayoutCache(recompute = false) {
73
+ resetLayoutCache(recompute = false, resetRenderRange = true) {
74
74
  this.layoutDirty = true;
75
75
  this.cache.fileAnnotationHeight = 0;
76
76
  if (this.cache.heights.size > 0) this.cache.heights.clear();
77
77
  if (this.cache.checkpoints.length > 0) this.cache.checkpoints.length = 0;
78
- if (this.renderRange != null) this.renderRange = void 0;
78
+ if (this.renderRange != null && resetRenderRange) this.renderRange = void 0;
79
79
  if (recompute && this.isSimpleMode()) this.computeApproximateSize();
80
80
  }
81
81
  reconcileHeights() {
@@ -283,14 +283,10 @@ var VirtualizedFile = class extends File {
283
283
  this.virtualizer.instanceChanged(this, false);
284
284
  }
285
285
  applyDocumentChange(textDocument, newLineAnnotations, shouldUpdateBuffer = false) {
286
- const { heights, checkpoints } = this.cache;
287
286
  const previousRenderRange = this.renderRange;
288
287
  super.applyDocumentChange(textDocument, newLineAnnotations);
289
288
  this.getSimpleVirtualizer()?.markDOMDirty();
290
- this.layoutDirty = true;
291
- if (heights.size > 0) heights.clear();
292
- if (checkpoints.length > 0) checkpoints.length = 0;
293
- if (this.isSimpleMode()) this.computeApproximateSize();
289
+ this.resetLayoutCache(this.isSimpleMode(), false);
294
290
  if (shouldUpdateBuffer && previousRenderRange !== void 0 && this.file !== void 0) {
295
291
  const windowSpecs = this.virtualizer.getWindowSpecs();
296
292
  const renderRange = this.computeRenderRangeFromWindow(this.file, this.top ?? 0, windowSpecs);
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualizedFile.js","names":[],"sources":["../../src/components/VirtualizedFile.ts"],"sourcesContent":["import { DEFAULT_VIRTUAL_FILE_METRICS } from '../constants';\nimport type {\n DiffsTextDocument,\n FileContents,\n LineAnnotation,\n NumericScrollLineAnchor,\n PendingCodeViewLayoutReset,\n RenderRange,\n RenderWindow,\n StickySpecs,\n ThemeTypes,\n VirtualFileMetrics,\n} from '../types';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areObjectsEqual } from '../utils/areObjectsEqual';\nimport { areOptionsEqual } from '../utils/areOptionsEqual';\nimport {\n getVirtualFileHeaderRegion,\n getVirtualFilePaddingBottom,\n} from '../utils/computeVirtualFileMetrics';\nimport {\n FILE_ANNOTATION_DOM_KEY,\n FILE_ANNOTATION_LINE_NUMBER,\n includesFileAnnotations,\n shouldRenderFileAnnotations,\n} from '../utils/includesFileAnnotations';\nimport type { WorkerPoolManager } from '../worker';\nimport type { CodeView } from './CodeView';\nimport { File, type FileOptions, type FileRenderProps } from './File';\nimport type { Virtualizer } from './Virtualizer';\n\ninterface FileLayoutCheckpoint {\n lineIndex: number;\n top: number;\n}\n\ninterface FileLayoutCache {\n // Sparse map: line index -> measured height. Only stores lines that differ\n // from what is returned by `getLineHeight`.\n heights: Map<number, number>;\n // Sparse measured positions used to resume deep geometry scans near a target\n // line or scroll offset instead of replaying layout from the start.\n checkpoints: FileLayoutCheckpoint[];\n // Measured height for the file-level annotation row. Starts at 0 so\n // unmeasured annotations behave like all other unmeasured annotations.\n fileAnnotationHeight: number;\n}\n\nconst LAYOUT_CHECKPOINT_INTERVAL = 5_000;\n\nlet instanceId = -1;\n\nfunction hasFileLayoutOptionChanged<LAnnotation>(\n previousOptions: FileOptions<LAnnotation>,\n nextOptions: FileOptions<LAnnotation>\n): boolean {\n return (\n (previousOptions.overflow ?? 'scroll') !==\n (nextOptions.overflow ?? 'scroll') ||\n (previousOptions.collapsed ?? false) !== (nextOptions.collapsed ?? false) ||\n (previousOptions.disableLineNumbers ?? false) !==\n (nextOptions.disableLineNumbers ?? false) ||\n (previousOptions.disableFileHeader ?? false) !==\n (nextOptions.disableFileHeader ?? false) ||\n previousOptions.unsafeCSS !== nextOptions.unsafeCSS\n );\n}\n\nexport class VirtualizedFile<\n LAnnotation = undefined,\n> extends File<LAnnotation> {\n override readonly __id: string = `virtualized-file:${++instanceId}`;\n\n public top: number | undefined;\n public height: number = 0;\n private cache: FileLayoutCache = {\n heights: new Map(),\n checkpoints: [],\n fileAnnotationHeight: 0,\n };\n private isVisible: boolean = false;\n private isSetup: boolean = false;\n private layoutDirty = true;\n private forceRenderOverride: true | undefined;\n private currentCollapsed: boolean | undefined;\n\n constructor(\n options: FileOptions<LAnnotation> | undefined,\n private virtualizer: Virtualizer | CodeView<LAnnotation>,\n private metrics: VirtualFileMetrics = DEFAULT_VIRTUAL_FILE_METRICS,\n workerManager?: WorkerPoolManager,\n isContainerManaged = false\n ) {\n super(options, workerManager, isContainerManaged);\n }\n\n public setMetrics(metrics: VirtualFileMetrics, force = false): void {\n if (!force && areObjectsEqual(this.metrics, metrics)) {\n return;\n }\n\n this.metrics = metrics;\n this.resetLayoutCache();\n }\n\n override setLineAnnotations(\n lineAnnotations: LineAnnotation<LAnnotation>[]\n ): void {\n if (this.syncLineAnnotations(lineAnnotations)) {\n this.resetLayoutCache();\n }\n }\n\n private syncLineAnnotations(\n lineAnnotations: LineAnnotation<LAnnotation>[] | undefined\n ): boolean {\n if (lineAnnotations == null || lineAnnotations === this.lineAnnotations) {\n return false;\n }\n if (lineAnnotations.length === 0 && this.lineAnnotations.length === 0) {\n return false;\n }\n\n super.setLineAnnotations(lineAnnotations);\n return true;\n }\n\n private hasLineAnnotations(): boolean {\n return this.lineAnnotations.some(\n (annotation) => annotation.lineNumber > FILE_ANNOTATION_LINE_NUMBER\n );\n }\n\n // Get the height for a line, using cached value if available.\n // If not cached and hasMetadataLine is true, adds lineHeight for the\n // metadata.\n public getLineHeight(lineIndex: number, hasMetadataLine = false): number {\n const cached = this.cache.heights.get(lineIndex);\n if (cached != null) {\n return cached;\n }\n const multiplier = hasMetadataLine ? 2 : 1;\n return this.metrics.lineHeight * multiplier;\n }\n\n override setOptions(options: FileOptions<LAnnotation> | undefined): void {\n if (this.isAdvancedMode()) {\n throw new Error(\n 'VirtualizedFile.setOptions cannot be used inside CodeView. Update CodeView options instead.'\n );\n }\n\n if (options == null) return;\n const { options: previousOptions } = this;\n const optionsChanged = !areOptionsEqual(previousOptions, options);\n const layoutChanged = hasFileLayoutOptionChanged(previousOptions, options);\n\n super.setOptions(options);\n\n if (layoutChanged) {\n this.resetLayoutCache(true);\n }\n // Any option can affect rendered DOM; only layout-affecting options clear\n // the measured height cache above.\n if (optionsChanged) {\n this.forceRenderOverride = true;\n }\n if (optionsChanged) {\n this.virtualizer.instanceChanged(this, layoutChanged);\n }\n }\n\n override setThemeType(themeType: ThemeTypes): void {\n if (this.isAdvancedMode()) {\n throw new Error(\n 'VirtualizedFile.setThemeType cannot be used inside CodeView. Update CodeView options instead.'\n );\n }\n\n super.setThemeType(themeType);\n }\n\n private resetLayoutCache(recompute = false): void {\n this.layoutDirty = true;\n this.cache.fileAnnotationHeight = 0;\n if (this.cache.heights.size > 0) {\n this.cache.heights.clear();\n }\n if (this.cache.checkpoints.length > 0) {\n this.cache.checkpoints.length = 0;\n }\n if (this.renderRange != null) {\n this.renderRange = undefined;\n }\n // NOTE(amadeus): In CodeView we intentionally batch computes to all happen\n // at the same time, so we shouldn't trigger this there.\n if (recompute && this.isSimpleMode()) {\n this.computeApproximateSize();\n }\n }\n\n // Measure rendered lines and update height cache.\n // Called after render to reconcile estimated vs actual heights.\n public reconcileHeights(): boolean {\n let hasHeightChange = false;\n if (this.fileContainer == null || this.file == null) {\n if (this.height !== 0) {\n hasHeightChange = true;\n }\n this.height = 0;\n return hasHeightChange;\n }\n const { overflow = 'scroll' } = this.options;\n this.top = this.getVirtualizedTop();\n\n // If the file has no annotations and we are using the scroll variant, then\n // we can probably skip everything\n if (\n overflow === 'scroll' &&\n this.lineAnnotations.length === 0 &&\n !this.isResizeDebuggingEnabled()\n ) {\n return hasHeightChange;\n }\n\n // Single code element (no split mode)\n if (this.code == null) {\n return hasHeightChange;\n }\n const content = this.code.children[1]; // Content column (gutter is [0])\n if (!(content instanceof HTMLElement)) {\n return hasHeightChange;\n }\n\n const hasFileAnnotations = includesFileAnnotations(this.lineAnnotations);\n if (\n this.renderRange != null &&\n hasFileAnnotations &&\n shouldRenderFileAnnotations(this.renderRange)\n ) {\n const fileAnnotationHeight = measureFileAnnotationHeight(content);\n const nextFileAnnotationHeight = fileAnnotationHeight ?? 0;\n if (nextFileAnnotationHeight !== this.cache.fileAnnotationHeight) {\n this.cache.fileAnnotationHeight = nextFileAnnotationHeight;\n hasHeightChange = true;\n }\n } else if (!hasFileAnnotations && this.cache.fileAnnotationHeight !== 0) {\n this.cache.fileAnnotationHeight = 0;\n hasHeightChange = true;\n }\n\n for (const line of content.children) {\n if (!(line instanceof HTMLElement)) continue;\n\n const lineIndexAttr = line.dataset.lineIndex;\n if (lineIndexAttr == null) continue;\n\n const lineIndex = Number(lineIndexAttr);\n let measuredHeight = line.getBoundingClientRect().height;\n let hasMetadata = false;\n\n // Annotations or noNewline metadata increase the size of their attached line\n if (\n line.nextElementSibling instanceof HTMLElement &&\n ('lineAnnotation' in line.nextElementSibling.dataset ||\n 'noNewline' in line.nextElementSibling.dataset)\n ) {\n if ('noNewline' in line.nextElementSibling.dataset) {\n hasMetadata = true;\n }\n measuredHeight +=\n line.nextElementSibling.getBoundingClientRect().height;\n }\n\n const expectedHeight = this.getLineHeight(lineIndex, hasMetadata);\n\n if (measuredHeight === expectedHeight) {\n continue;\n }\n\n hasHeightChange = true;\n // Line is back to standard height (e.g., after window resize)\n // Remove from cache\n if (measuredHeight === this.metrics.lineHeight * (hasMetadata ? 2 : 1)) {\n this.cache.heights.delete(lineIndex);\n }\n // Non-standard height, cache it\n else {\n this.cache.heights.set(lineIndex, measuredHeight);\n }\n }\n\n if (hasHeightChange || this.isResizeDebuggingEnabled()) {\n this.computeApproximateSize(true);\n }\n return hasHeightChange;\n }\n\n public onRender = (dirty: boolean): boolean => {\n if (this.fileContainer == null || this.file == null) {\n return false;\n }\n if (dirty) {\n this.top = this.getVirtualizedTop();\n }\n return this.render({ file: this.file });\n };\n\n // Prepares this item for CodeView layout by binding the latest file, syncing\n // its virtualized top, and returning an approximate height. This method is\n // called while downstream items are being re-positioned, so later changes\n // should keep clean instances on a cached-height fast path.\n public prepareCodeViewItem(\n file: FileContents,\n top: number,\n reset?: PendingCodeViewLayoutReset,\n lineAnnotations?: LineAnnotation<LAnnotation>[]\n ): number {\n const annotationsChanged = this.syncLineAnnotations(lineAnnotations);\n let shouldResetLayoutCache =\n reset?.resetFileLayoutCache === true || annotationsChanged;\n if (reset?.metrics != null) {\n this.metrics = reset.metrics;\n shouldResetLayoutCache = true;\n }\n\n const { collapsed = false } = this.options;\n if (this.currentCollapsed !== collapsed) {\n this.currentCollapsed = collapsed;\n shouldResetLayoutCache = true;\n }\n\n if (shouldResetLayoutCache) {\n this.resetLayoutCache();\n }\n\n if (this.file !== file) {\n this.layoutDirty = true;\n }\n this.file = file;\n this.top = top;\n this.computeApproximateSize();\n return this.height;\n }\n\n public getLinePosition(\n lineNumber: number\n ): { top: number; height: number } | undefined {\n if (this.file == null || lineNumber < 1) {\n return undefined;\n }\n\n const { disableFileHeader = false, collapsed = false } = this.options;\n const lastLineIndex = this.fileRenderer.getLineCount(this.file) - 1;\n let top = getVirtualFileHeaderRegion(this.metrics, disableFileHeader);\n\n if (collapsed || lastLineIndex < 0) {\n return { top, height: 0 };\n }\n\n const clampedLineIndex = Math.min(\n Math.max(lineNumber - 1, 0),\n lastLineIndex\n );\n const { overflow = 'scroll' } = this.options;\n const { lineHeight } = this.metrics;\n top += this.cache.fileAnnotationHeight;\n\n if (overflow === 'scroll' && !this.hasLineAnnotations()) {\n return {\n top: top + clampedLineIndex * lineHeight,\n height: lineHeight,\n };\n }\n\n const checkpoint =\n this.getLayoutCheckpointBeforeLineIndex(clampedLineIndex);\n top = checkpoint?.top ?? top;\n for (\n let lineIndex = checkpoint?.lineIndex ?? 0;\n lineIndex < clampedLineIndex;\n lineIndex++\n ) {\n top += this.getLineHeight(lineIndex, false);\n }\n\n return {\n top,\n height: this.getLineHeight(clampedLineIndex, false),\n };\n }\n\n public getNumericScrollAnchor(\n localViewportTop: number\n ): NumericScrollLineAnchor | undefined {\n if (this.file == null || this.renderRange == null) {\n return undefined;\n }\n\n const {\n disableFileHeader = false,\n collapsed = false,\n overflow = 'scroll',\n } = this.options;\n if (collapsed || this.renderRange.totalLines <= 0) {\n return undefined;\n }\n\n const lastLineIndex = this.fileRenderer.getLineCount(this.file) - 1;\n if (lastLineIndex < 0) {\n return undefined;\n }\n\n const headerRegion = getVirtualFileHeaderRegion(\n this.metrics,\n disableFileHeader\n );\n const firstRenderedLineIndex = Math.min(\n this.renderRange.startingLine,\n lastLineIndex\n );\n const lastRenderedLineIndex = Math.min(\n firstRenderedLineIndex + this.renderRange.totalLines - 1,\n lastLineIndex\n );\n if (lastRenderedLineIndex < firstRenderedLineIndex) {\n return undefined;\n }\n const { fileAnnotationHeight } = this.cache;\n\n // If we don't allow line wrapping and have no annotations, we can just\n // multiply our way to the the correct value\n if (overflow === 'scroll' && !this.hasLineAnnotations()) {\n const { lineHeight } = this.metrics;\n const firstRenderedLineTop =\n headerRegion +\n (firstRenderedLineIndex === 0\n ? fileAnnotationHeight\n : this.renderRange.bufferBefore);\n const deltaLineCount = Math.max(\n Math.ceil((localViewportTop - firstRenderedLineTop) / lineHeight),\n 0\n );\n const lineIndex = firstRenderedLineIndex + deltaLineCount;\n if (lineIndex > lastRenderedLineIndex) {\n return undefined;\n }\n\n return {\n lineNumber: lineIndex + 1,\n top: headerRegion + fileAnnotationHeight + lineIndex * lineHeight,\n };\n }\n\n // Otherwise we gotta iterate through the range\n let top =\n headerRegion +\n (firstRenderedLineIndex === 0\n ? fileAnnotationHeight\n : this.renderRange.bufferBefore);\n for (\n let lineIndex = firstRenderedLineIndex;\n lineIndex <= lastRenderedLineIndex;\n lineIndex++\n ) {\n if (top >= localViewportTop) {\n return {\n lineNumber: lineIndex + 1,\n top,\n };\n }\n top += this.getLineHeight(lineIndex);\n }\n\n return undefined;\n }\n\n public getVirtualizedHeight(): number {\n return this.height;\n }\n\n public getAdvancedStickySpecs(\n windowSpecs?: RenderWindow\n ): StickySpecs | undefined {\n if (this.top == null || this.file == null) {\n return undefined;\n }\n if (this.options.collapsed === true) {\n return { topOffset: this.top, height: this.height };\n }\n const renderRange =\n windowSpecs != null\n ? this.computeRenderRangeFromWindow(this.file, this.top, windowSpecs)\n : this.renderRange;\n if (renderRange == null) {\n return undefined;\n }\n const { bufferBefore, bufferAfter, totalLines } = renderRange;\n // Rendered items flow contiguously in the sticky container with no buffer\n // spacers, so a header-only item (totalLines === 0, none of its rows fall\n // inside the window) must report where its header actually sits in that\n // flow, which depends on which side of the window its content is on:\n // - content ABOVE the window (item starts above window.top): the header\n // sits at the item's bottom so the following item connects, so offset by\n // bufferAfter.\n // - content BELOW the window (item starts at/after window.top, e.g. a\n // trailing header peeking in at the bottom): the header renders at the\n // item's top with nothing after it, so no offset. Always adding\n // bufferAfter here made getStickyBounds over-measure the sticky\n // container for that trailing case.\n let headerOnlyOffset = 0;\n if (totalLines === 0) {\n const activeWindow = windowSpecs ?? this.virtualizer.getWindowSpecs();\n if (this.top < activeWindow.top) {\n headerOnlyOffset = bufferAfter;\n }\n }\n return {\n topOffset: this.top + bufferBefore + headerOnlyOffset,\n height: this.height - (bufferBefore + bufferAfter),\n };\n }\n\n override cleanUp(recycle = false): void {\n if (this.fileContainer != null && this.isSimpleMode()) {\n this.getSimpleVirtualizer()?.disconnect(this.fileContainer);\n }\n if (!recycle) {\n this.resetLayoutCache();\n }\n this.isSetup = false;\n super.cleanUp(recycle);\n }\n\n // Compute the approximate size of the file using cached line heights.\n // Uses lineHeight for lines without cached measurements.\n private computeApproximateSize(force = false): void {\n const shouldValidateSize = this.isResizeDebuggingEnabled();\n if (!force && !this.layoutDirty && !shouldValidateSize) {\n return;\n }\n\n const isFirstCompute = this.height === 0;\n this.height = 0;\n this.cache.checkpoints = [];\n if (this.file == null) {\n this.layoutDirty = false;\n return;\n }\n\n const {\n disableFileHeader = false,\n collapsed = false,\n overflow = 'scroll',\n } = this.options;\n const { lineHeight } = this.metrics;\n const lineCount = this.fileRenderer.getLineCount(this.file);\n const headerRegion = getVirtualFileHeaderRegion(\n this.metrics,\n disableFileHeader\n );\n const paddingBottom = getVirtualFilePaddingBottom(this.metrics);\n\n this.height += headerRegion;\n if (collapsed) {\n this.layoutDirty = false;\n return;\n }\n\n this.height += this.cache.fileAnnotationHeight;\n\n if (overflow === 'scroll' && !this.hasLineAnnotations()) {\n this.height += lineCount * lineHeight;\n } else {\n for (let lineIndex = 0; lineIndex < lineCount; lineIndex++) {\n this.addLayoutCheckpoint(lineIndex, this.height);\n this.height += this.getLineHeight(lineIndex, false);\n }\n }\n\n if (lineCount > 0) {\n this.height += paddingBottom;\n }\n\n if (this.fileContainer != null && shouldValidateSize && !isFirstCompute) {\n const rect = this.fileContainer.getBoundingClientRect();\n if (rect.height !== this.height) {\n console.log(\n 'VirtualizedFile.computeApproximateSize: computed height doesnt match',\n {\n name: this.file.name,\n elementHeight: rect.height,\n computedHeight: this.height,\n }\n );\n } else {\n console.log(\n 'VirtualizedFile.computeApproximateSize: computed height IS CORRECT'\n );\n }\n }\n this.layoutDirty = false;\n }\n\n public setVisibility(visible: boolean): void {\n if (this.isAdvancedMode() || this.fileContainer == null) {\n return;\n }\n if (visible && !this.isVisible) {\n this.top = this.getVirtualizedTop();\n this.isVisible = true;\n } else if (!visible && this.isVisible) {\n this.isVisible = false;\n this.rerender();\n }\n }\n\n override rerender(): void {\n if (!this.enabled || this.file == null) {\n return;\n }\n this.forceRenderOverride = true;\n this.virtualizer.instanceChanged(this, false);\n }\n\n // normally triggered by the editor when the document line count changes\n override applyDocumentChange(\n textDocument: DiffsTextDocument,\n newLineAnnotations?: LineAnnotation<LAnnotation>[],\n shouldUpdateBuffer = false\n ): void {\n const { heights, checkpoints } = this.cache;\n const previousRenderRange = this.renderRange;\n\n super.applyDocumentChange(textDocument, newLineAnnotations);\n\n // reset the layout cache\n this.getSimpleVirtualizer()?.markDOMDirty();\n this.layoutDirty = true;\n if (heights.size > 0) {\n heights.clear();\n }\n if (checkpoints.length > 0) {\n checkpoints.length = 0;\n }\n if (this.isSimpleMode()) {\n this.computeApproximateSize();\n }\n\n // Update the buffers caused by the line-count change to ensure the editor\n // scrolls to the correct position before re-rendering\n if (\n shouldUpdateBuffer &&\n previousRenderRange !== undefined &&\n this.file !== undefined\n ) {\n const windowSpecs = this.virtualizer.getWindowSpecs();\n const renderRange = this.computeRenderRangeFromWindow(\n this.file,\n this.top ?? 0,\n windowSpecs\n );\n if (renderRange.bufferAfter !== previousRenderRange.bufferAfter) {\n this.updateBuffers(renderRange);\n }\n }\n }\n\n override render({\n fileContainer,\n file,\n forceRender = false,\n lineAnnotations,\n ...props\n }: FileRenderProps<LAnnotation>): boolean {\n const didFileChange = this.file == null || !areFilesEqual(this.file, file);\n const { forceRenderOverride, isSetup } = this;\n this.forceRenderOverride = undefined;\n const annotationsChanged = this.syncLineAnnotations(lineAnnotations);\n if (annotationsChanged) {\n this.resetLayoutCache();\n }\n\n this.file = file;\n\n fileContainer = this.getOrCreateFileContainerNode(fileContainer);\n\n if (this.file == null) {\n console.error(\n 'VirtualizedFile.render: attempting to virtually render when we dont have file'\n );\n return false;\n }\n\n if (!isSetup) {\n this.computeApproximateSize();\n const virtualizer = this.getSimpleVirtualizer();\n this.top ??= this.getVirtualizedTop();\n if (this.isAdvancedMode()) {\n this.isVisible = true;\n } else {\n if (virtualizer == null) {\n throw new Error(\n 'VirtualizedFile.render: simple virtualizer is not available'\n );\n }\n virtualizer.connect(fileContainer, this);\n this.isVisible = virtualizer.isInstanceVisible(\n this.top ?? 0,\n this.height\n );\n }\n this.isSetup = true;\n } else {\n this.top ??= this.getVirtualizedTop();\n if (didFileChange && this.isSimpleMode()) {\n this.getSimpleVirtualizer()?.markDOMDirty();\n this.resetLayoutCache(true);\n }\n }\n\n if (!this.isVisible && this.isSimpleMode()) {\n return this.renderPlaceholder(this.height);\n }\n\n const windowSpecs = this.virtualizer.getWindowSpecs();\n const fileTop = this.top ?? 0;\n const renderRange = this.computeRenderRangeFromWindow(\n this.file,\n fileTop,\n windowSpecs\n );\n return super.render({\n file: this.file,\n fileContainer,\n renderRange,\n lineAnnotations,\n forceRender: (forceRenderOverride ?? forceRender) || annotationsChanged,\n ...props,\n });\n }\n\n public syncVirtualizedTop(): void {\n this.top = this.getVirtualizedTop();\n }\n\n protected override shouldDisableVirtualizationBuffers(): boolean {\n return this.isAdvancedMode() || super.shouldDisableVirtualizationBuffers();\n }\n\n private isSimpleMode(): boolean {\n return this.virtualizer.type === 'simple';\n }\n\n private isAdvancedMode(): boolean {\n return this.virtualizer.type === 'advanced';\n }\n\n private addLayoutCheckpoint(lineIndex: number, top: number): void {\n if (lineIndex % LAYOUT_CHECKPOINT_INTERVAL !== 0) {\n return;\n }\n this.cache.checkpoints.push({ lineIndex, top });\n }\n\n // Find the nearest sparse layout checkpoint at or before a raw file line.\n // Checkpoints store measured `top` offsets every few thousand lines, so a\n // binary search lets deep line-position lookups resume from that checkpoint\n // instead of replaying layout from the start of the file.\n private getLayoutCheckpointBeforeLineIndex(\n lineIndex: number\n ): FileLayoutCheckpoint | undefined {\n if (lineIndex <= 0 || this.cache.checkpoints.length === 0) {\n return undefined;\n }\n\n let low = 0;\n let high = this.cache.checkpoints.length - 1;\n let result: FileLayoutCheckpoint | undefined;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n const checkpoint = this.cache.checkpoints[mid];\n if (checkpoint == null) {\n throw new Error('VirtualizedFile: invalid checkpoint index');\n }\n if (checkpoint.lineIndex <= lineIndex) {\n result = checkpoint;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n return result;\n }\n\n // Find the nearest sparse layout checkpoint at or before a scroll offset.\n // Render-range scans start from this checkpoint so variable-height files\n // only replay the nearby measured rows. When `hunkLineCount` is provided,\n // step backward to a hunk boundary so hooks that depend on grouped lines\n // still see a complete hunk.\n private getLayoutCheckpointBeforeTop(\n top: number,\n hunkLineCount?: number\n ): FileLayoutCheckpoint | undefined {\n let low = 0;\n let high = this.cache.checkpoints.length - 1;\n let resultIndex = -1;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n const checkpoint = this.cache.checkpoints[mid];\n if (checkpoint == null) {\n throw new Error('VirtualizedFile: invalid checkpoint index');\n }\n if (checkpoint.top <= top) {\n resultIndex = mid;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n if (hunkLineCount == null) {\n return resultIndex >= 0 ? this.cache.checkpoints[resultIndex] : undefined;\n }\n\n for (let index = resultIndex; index >= 0; index--) {\n const checkpoint = this.cache.checkpoints[index];\n if (checkpoint == null) {\n throw new Error('VirtualizedFile: invalid checkpoint index');\n }\n if (checkpoint.lineIndex % hunkLineCount === 0) {\n return checkpoint;\n }\n }\n\n return undefined;\n }\n\n private getVirtualizedTop(): number {\n if (this.virtualizer.type === 'advanced') {\n return this.virtualizer.getLocalTopForInstance(this);\n }\n return this.fileContainer != null\n ? this.virtualizer.getOffsetInScrollContainer(this.fileContainer)\n : 0;\n }\n\n private getSimpleVirtualizer(): Virtualizer | undefined {\n return this.virtualizer.type === 'simple' ? this.virtualizer : undefined;\n }\n\n private isResizeDebuggingEnabled(): boolean {\n return this.getSimpleVirtualizer()?.config.resizeDebugging ?? false;\n }\n\n private computeRenderRangeFromWindow(\n file: FileContents,\n fileTop: number,\n { top, bottom }: RenderWindow\n ): RenderRange {\n const { disableFileHeader = false, overflow = 'scroll' } = this.options;\n const { hunkLineCount, lineHeight } = this.metrics;\n const lineCount = this.fileRenderer.getLineCount(file);\n const fileHeight = this.height;\n const headerRegion = getVirtualFileHeaderRegion(\n this.metrics,\n disableFileHeader\n );\n const paddingBottom =\n lineCount > 0 ? getVirtualFilePaddingBottom(this.metrics) : 0;\n const { fileAnnotationHeight } = this.cache;\n const codeRegionTop = headerRegion + fileAnnotationHeight;\n const codeRowsHeight = Math.max(\n 0,\n fileHeight - headerRegion - fileAnnotationHeight - paddingBottom\n );\n const hasFileAnnotations = includesFileAnnotations(this.lineAnnotations);\n const fileAnnotationTop = fileTop + headerRegion;\n const measuredFileAnnotationVisible =\n fileAnnotationHeight > 0 &&\n hasFileAnnotations &&\n fileAnnotationTop < bottom &&\n fileAnnotationTop + fileAnnotationHeight > top;\n\n // File is outside render window\n if (fileTop < top - fileHeight || fileTop > bottom) {\n return {\n startingLine: 0,\n totalLines: 0,\n bufferBefore: 0,\n bufferAfter: fileHeight - headerRegion - paddingBottom,\n };\n }\n\n // Small file, just render it all\n if (lineCount <= hunkLineCount) {\n return {\n startingLine: 0,\n totalLines: hunkLineCount,\n bufferBefore: 0,\n bufferAfter: 0,\n };\n }\n\n // Calculate totalLines based on viewport size\n const estimatedTargetLines = Math.ceil(\n Math.max(bottom - top, 0) / lineHeight\n );\n const totalLines =\n Math.ceil(estimatedTargetLines / hunkLineCount) * hunkLineCount +\n hunkLineCount * 2;\n const totalHunks = totalLines / hunkLineCount;\n const viewportCenter = (top + bottom) / 2;\n // Simple case: overflow scroll with no annotations - pure math!\n if (overflow === 'scroll' && !this.hasLineAnnotations()) {\n const sourceRowsTop = fileTop + codeRegionTop;\n const sourceRowsBottom = sourceRowsTop + codeRowsHeight;\n const sourceRowsVisible =\n sourceRowsTop < bottom && sourceRowsBottom > top;\n if (!measuredFileAnnotationVisible && !sourceRowsVisible) {\n return {\n startingLine: 0,\n totalLines: 0,\n bufferBefore: 0,\n bufferAfter: fileHeight - headerRegion - paddingBottom,\n };\n }\n\n // Find which line is at viewport center\n const centerLine = Math.floor(\n measuredFileAnnotationVisible &&\n viewportCenter < fileTop + codeRegionTop\n ? 0\n : (viewportCenter - (fileTop + codeRegionTop)) / lineHeight\n );\n const centerHunk = Math.floor(centerLine / hunkLineCount);\n\n // Calculate ideal start centered around viewport\n const idealStartHunk = centerHunk - Math.floor(totalHunks / 2);\n const totalHunksInFile = Math.ceil(lineCount / hunkLineCount);\n const startingLine =\n Math.max(0, Math.min(idealStartHunk, totalHunksInFile)) * hunkLineCount;\n\n const clampedTotalLines =\n idealStartHunk < 0\n ? totalLines + idealStartHunk * hunkLineCount\n : totalLines;\n\n const bufferBefore =\n startingLine === 0\n ? 0\n : fileAnnotationHeight + startingLine * lineHeight;\n const renderedLines = Math.min(\n clampedTotalLines,\n lineCount - startingLine\n );\n const bufferAfter = Math.max(\n 0,\n (lineCount - startingLine - renderedLines) * lineHeight\n );\n\n return {\n startingLine,\n totalLines: clampedTotalLines,\n bufferBefore,\n bufferAfter,\n };\n }\n\n // Complex case: need to account for line annotations or wrap overflow\n const overflowHunks = totalHunks;\n const hunkOffsets: number[] = [];\n // Start the scan before the viewport so we collect hunk offsets that may be\n // needed for bufferBefore. This only chooses the scan origin; the returned\n // render range is still computed from the visible window below.\n const checkpoint = this.getLayoutCheckpointBeforeTop(\n Math.max(0, top - fileTop - totalLines * lineHeight * 2),\n hunkLineCount\n );\n\n let absoluteLineTop = fileTop + (checkpoint?.top ?? codeRegionTop);\n let currentLine = checkpoint?.lineIndex ?? 0;\n let firstVisibleHunk: number | undefined;\n let centerHunk: number | undefined;\n let overflowCounter: number | undefined;\n\n const startingLineIndex = checkpoint?.lineIndex ?? 0;\n for (\n let lineIndex = startingLineIndex;\n lineIndex < lineCount;\n lineIndex++\n ) {\n const isAtHunkBoundary = currentLine % hunkLineCount === 0;\n const currentHunk = Math.floor(currentLine / hunkLineCount);\n\n if (isAtHunkBoundary) {\n hunkOffsets[currentHunk] = absoluteLineTop - (fileTop + codeRegionTop);\n\n if (overflowCounter != null) {\n if (overflowCounter <= 0) {\n break;\n }\n overflowCounter--;\n }\n }\n\n const lineHeight = this.getLineHeight(lineIndex, false);\n\n // Track visible region\n if (absoluteLineTop > top - lineHeight && absoluteLineTop < bottom) {\n firstVisibleHunk ??= currentHunk;\n }\n\n // Track which hunk contains the viewport center\n if (absoluteLineTop + lineHeight > viewportCenter) {\n centerHunk ??= currentHunk;\n }\n\n // Start overflow when we are out of the viewport at a hunk boundary\n if (\n overflowCounter == null &&\n absoluteLineTop >= bottom &&\n isAtHunkBoundary\n ) {\n overflowCounter = overflowHunks;\n }\n\n currentLine++;\n absoluteLineTop += lineHeight;\n }\n\n // No visible lines found\n if (firstVisibleHunk == null) {\n if (measuredFileAnnotationVisible) {\n firstVisibleHunk = 0;\n centerHunk = 0;\n } else {\n return {\n startingLine: 0,\n totalLines: 0,\n bufferBefore: 0,\n bufferAfter: fileHeight - headerRegion - paddingBottom,\n };\n }\n }\n\n // Calculate balanced startingLine centered around the viewport center\n centerHunk ??= firstVisibleHunk;\n const idealStartHunk = Math.round(centerHunk - totalHunks / 2);\n\n // Clamp startHunk: at the beginning, reduce totalLines; at the end, shift\n // startHunk back\n const maxStartHunk = Math.max(\n 0,\n Math.ceil(lineCount / hunkLineCount) - totalHunks\n );\n const startHunk = Math.max(0, Math.min(idealStartHunk, maxStartHunk));\n const startingLine = startHunk * hunkLineCount;\n\n // If we wanted to start before 0, reduce totalLines by the clamped amount\n const clampedTotalLines =\n idealStartHunk < 0\n ? totalLines + idealStartHunk * hunkLineCount\n : totalLines;\n\n // Use hunkOffsets array for efficient buffer calculations\n const codeBufferBefore = hunkOffsets[startHunk] ?? 0;\n const bufferBefore =\n startingLine === 0 ? 0 : fileAnnotationHeight + codeBufferBefore;\n\n // Calculate bufferAfter\n const finalHunkIndex = startHunk + clampedTotalLines / hunkLineCount;\n const bufferAfter =\n finalHunkIndex < hunkOffsets.length\n ? codeRowsHeight - hunkOffsets[finalHunkIndex]\n : codeRowsHeight - (absoluteLineTop - fileTop - codeRegionTop);\n\n return {\n startingLine,\n totalLines: clampedTotalLines,\n bufferBefore,\n bufferAfter: Math.max(0, bufferAfter),\n };\n }\n}\n\nfunction measureFileAnnotationHeight(content: HTMLElement): number | undefined {\n let height: number | undefined;\n for (const child of content.children) {\n if (!(child instanceof HTMLElement)) {\n continue;\n }\n if (child.dataset.lineAnnotation !== FILE_ANNOTATION_DOM_KEY) {\n continue;\n }\n height = Math.max(height ?? 0, child.getBoundingClientRect().height);\n }\n return height;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"VirtualizedFile.js","names":[],"sources":["../../src/components/VirtualizedFile.ts"],"sourcesContent":["import { DEFAULT_VIRTUAL_FILE_METRICS } from '../constants';\nimport type {\n DiffsTextDocument,\n FileContents,\n LineAnnotation,\n NumericScrollLineAnchor,\n PendingCodeViewLayoutReset,\n RenderRange,\n RenderWindow,\n StickySpecs,\n ThemeTypes,\n VirtualFileMetrics,\n} from '../types';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areObjectsEqual } from '../utils/areObjectsEqual';\nimport { areOptionsEqual } from '../utils/areOptionsEqual';\nimport {\n getVirtualFileHeaderRegion,\n getVirtualFilePaddingBottom,\n} from '../utils/computeVirtualFileMetrics';\nimport {\n FILE_ANNOTATION_DOM_KEY,\n FILE_ANNOTATION_LINE_NUMBER,\n includesFileAnnotations,\n shouldRenderFileAnnotations,\n} from '../utils/includesFileAnnotations';\nimport type { WorkerPoolManager } from '../worker';\nimport type { CodeView } from './CodeView';\nimport { File, type FileOptions, type FileRenderProps } from './File';\nimport type { Virtualizer } from './Virtualizer';\n\ninterface FileLayoutCheckpoint {\n lineIndex: number;\n top: number;\n}\n\ninterface FileLayoutCache {\n // Sparse map: line index -> measured height. Only stores lines that differ\n // from what is returned by `getLineHeight`.\n heights: Map<number, number>;\n // Sparse measured positions used to resume deep geometry scans near a target\n // line or scroll offset instead of replaying layout from the start.\n checkpoints: FileLayoutCheckpoint[];\n // Measured height for the file-level annotation row. Starts at 0 so\n // unmeasured annotations behave like all other unmeasured annotations.\n fileAnnotationHeight: number;\n}\n\nconst LAYOUT_CHECKPOINT_INTERVAL = 5_000;\n\nlet instanceId = -1;\n\nfunction hasFileLayoutOptionChanged<LAnnotation>(\n previousOptions: FileOptions<LAnnotation>,\n nextOptions: FileOptions<LAnnotation>\n): boolean {\n return (\n (previousOptions.overflow ?? 'scroll') !==\n (nextOptions.overflow ?? 'scroll') ||\n (previousOptions.collapsed ?? false) !== (nextOptions.collapsed ?? false) ||\n (previousOptions.disableLineNumbers ?? false) !==\n (nextOptions.disableLineNumbers ?? false) ||\n (previousOptions.disableFileHeader ?? false) !==\n (nextOptions.disableFileHeader ?? false) ||\n previousOptions.unsafeCSS !== nextOptions.unsafeCSS\n );\n}\n\nexport class VirtualizedFile<\n LAnnotation = undefined,\n> extends File<LAnnotation> {\n override readonly __id: string = `virtualized-file:${++instanceId}`;\n\n public top: number | undefined;\n public height: number = 0;\n private cache: FileLayoutCache = {\n heights: new Map(),\n checkpoints: [],\n fileAnnotationHeight: 0,\n };\n private isVisible: boolean = false;\n private isSetup: boolean = false;\n private layoutDirty = true;\n private forceRenderOverride: true | undefined;\n private currentCollapsed: boolean | undefined;\n\n constructor(\n options: FileOptions<LAnnotation> | undefined,\n private virtualizer: Virtualizer | CodeView<LAnnotation>,\n private metrics: VirtualFileMetrics = DEFAULT_VIRTUAL_FILE_METRICS,\n workerManager?: WorkerPoolManager,\n isContainerManaged = false\n ) {\n super(options, workerManager, isContainerManaged);\n }\n\n public setMetrics(metrics: VirtualFileMetrics, force = false): void {\n if (!force && areObjectsEqual(this.metrics, metrics)) {\n return;\n }\n\n this.metrics = metrics;\n this.resetLayoutCache();\n }\n\n override setLineAnnotations(\n lineAnnotations: LineAnnotation<LAnnotation>[]\n ): void {\n if (this.syncLineAnnotations(lineAnnotations)) {\n this.resetLayoutCache();\n }\n }\n\n private syncLineAnnotations(\n lineAnnotations: LineAnnotation<LAnnotation>[] | undefined\n ): boolean {\n if (lineAnnotations == null || lineAnnotations === this.lineAnnotations) {\n return false;\n }\n if (lineAnnotations.length === 0 && this.lineAnnotations.length === 0) {\n return false;\n }\n\n super.setLineAnnotations(lineAnnotations);\n return true;\n }\n\n private hasLineAnnotations(): boolean {\n return this.lineAnnotations.some(\n (annotation) => annotation.lineNumber > FILE_ANNOTATION_LINE_NUMBER\n );\n }\n\n // Get the height for a line, using cached value if available.\n // If not cached and hasMetadataLine is true, adds lineHeight for the\n // metadata.\n public getLineHeight(lineIndex: number, hasMetadataLine = false): number {\n const cached = this.cache.heights.get(lineIndex);\n if (cached != null) {\n return cached;\n }\n const multiplier = hasMetadataLine ? 2 : 1;\n return this.metrics.lineHeight * multiplier;\n }\n\n override setOptions(options: FileOptions<LAnnotation> | undefined): void {\n if (this.isAdvancedMode()) {\n throw new Error(\n 'VirtualizedFile.setOptions cannot be used inside CodeView. Update CodeView options instead.'\n );\n }\n\n if (options == null) return;\n const { options: previousOptions } = this;\n const optionsChanged = !areOptionsEqual(previousOptions, options);\n const layoutChanged = hasFileLayoutOptionChanged(previousOptions, options);\n\n super.setOptions(options);\n\n if (layoutChanged) {\n this.resetLayoutCache(true);\n }\n // Any option can affect rendered DOM; only layout-affecting options clear\n // the measured height cache above.\n if (optionsChanged) {\n this.forceRenderOverride = true;\n }\n if (optionsChanged) {\n this.virtualizer.instanceChanged(this, layoutChanged);\n }\n }\n\n override setThemeType(themeType: ThemeTypes): void {\n if (this.isAdvancedMode()) {\n throw new Error(\n 'VirtualizedFile.setThemeType cannot be used inside CodeView. Update CodeView options instead.'\n );\n }\n\n super.setThemeType(themeType);\n }\n\n private resetLayoutCache(recompute = false, resetRenderRange = true): void {\n this.layoutDirty = true;\n this.cache.fileAnnotationHeight = 0;\n if (this.cache.heights.size > 0) {\n this.cache.heights.clear();\n }\n if (this.cache.checkpoints.length > 0) {\n this.cache.checkpoints.length = 0;\n }\n if (this.renderRange != null && resetRenderRange) {\n this.renderRange = undefined;\n }\n // NOTE(amadeus): In CodeView we intentionally batch computes to all happen\n // at the same time, so we shouldn't trigger this there.\n if (recompute && this.isSimpleMode()) {\n this.computeApproximateSize();\n }\n }\n\n // Measure rendered lines and update height cache.\n // Called after render to reconcile estimated vs actual heights.\n public reconcileHeights(): boolean {\n let hasHeightChange = false;\n if (this.fileContainer == null || this.file == null) {\n if (this.height !== 0) {\n hasHeightChange = true;\n }\n this.height = 0;\n return hasHeightChange;\n }\n const { overflow = 'scroll' } = this.options;\n this.top = this.getVirtualizedTop();\n\n // If the file has no annotations and we are using the scroll variant, then\n // we can probably skip everything\n if (\n overflow === 'scroll' &&\n this.lineAnnotations.length === 0 &&\n !this.isResizeDebuggingEnabled()\n ) {\n return hasHeightChange;\n }\n\n // Single code element (no split mode)\n if (this.code == null) {\n return hasHeightChange;\n }\n const content = this.code.children[1]; // Content column (gutter is [0])\n if (!(content instanceof HTMLElement)) {\n return hasHeightChange;\n }\n\n const hasFileAnnotations = includesFileAnnotations(this.lineAnnotations);\n if (\n this.renderRange != null &&\n hasFileAnnotations &&\n shouldRenderFileAnnotations(this.renderRange)\n ) {\n const fileAnnotationHeight = measureFileAnnotationHeight(content);\n const nextFileAnnotationHeight = fileAnnotationHeight ?? 0;\n if (nextFileAnnotationHeight !== this.cache.fileAnnotationHeight) {\n this.cache.fileAnnotationHeight = nextFileAnnotationHeight;\n hasHeightChange = true;\n }\n } else if (!hasFileAnnotations && this.cache.fileAnnotationHeight !== 0) {\n this.cache.fileAnnotationHeight = 0;\n hasHeightChange = true;\n }\n\n for (const line of content.children) {\n if (!(line instanceof HTMLElement)) continue;\n\n const lineIndexAttr = line.dataset.lineIndex;\n if (lineIndexAttr == null) continue;\n\n const lineIndex = Number(lineIndexAttr);\n let measuredHeight = line.getBoundingClientRect().height;\n let hasMetadata = false;\n\n // Annotations or noNewline metadata increase the size of their attached line\n if (\n line.nextElementSibling instanceof HTMLElement &&\n ('lineAnnotation' in line.nextElementSibling.dataset ||\n 'noNewline' in line.nextElementSibling.dataset)\n ) {\n if ('noNewline' in line.nextElementSibling.dataset) {\n hasMetadata = true;\n }\n measuredHeight +=\n line.nextElementSibling.getBoundingClientRect().height;\n }\n\n const expectedHeight = this.getLineHeight(lineIndex, hasMetadata);\n\n if (measuredHeight === expectedHeight) {\n continue;\n }\n\n hasHeightChange = true;\n // Line is back to standard height (e.g., after window resize)\n // Remove from cache\n if (measuredHeight === this.metrics.lineHeight * (hasMetadata ? 2 : 1)) {\n this.cache.heights.delete(lineIndex);\n }\n // Non-standard height, cache it\n else {\n this.cache.heights.set(lineIndex, measuredHeight);\n }\n }\n\n if (hasHeightChange || this.isResizeDebuggingEnabled()) {\n this.computeApproximateSize(true);\n }\n return hasHeightChange;\n }\n\n public onRender = (dirty: boolean): boolean => {\n if (this.fileContainer == null || this.file == null) {\n return false;\n }\n if (dirty) {\n this.top = this.getVirtualizedTop();\n }\n return this.render({ file: this.file });\n };\n\n // Prepares this item for CodeView layout by binding the latest file, syncing\n // its virtualized top, and returning an approximate height. This method is\n // called while downstream items are being re-positioned, so later changes\n // should keep clean instances on a cached-height fast path.\n public prepareCodeViewItem(\n file: FileContents,\n top: number,\n reset?: PendingCodeViewLayoutReset,\n lineAnnotations?: LineAnnotation<LAnnotation>[]\n ): number {\n const annotationsChanged = this.syncLineAnnotations(lineAnnotations);\n let shouldResetLayoutCache =\n reset?.resetFileLayoutCache === true || annotationsChanged;\n if (reset?.metrics != null) {\n this.metrics = reset.metrics;\n shouldResetLayoutCache = true;\n }\n\n const { collapsed = false } = this.options;\n if (this.currentCollapsed !== collapsed) {\n this.currentCollapsed = collapsed;\n shouldResetLayoutCache = true;\n }\n\n if (shouldResetLayoutCache) {\n this.resetLayoutCache();\n }\n\n if (this.file !== file) {\n this.layoutDirty = true;\n }\n this.file = file;\n this.top = top;\n this.computeApproximateSize();\n return this.height;\n }\n\n public getLinePosition(\n lineNumber: number\n ): { top: number; height: number } | undefined {\n if (this.file == null || lineNumber < 1) {\n return undefined;\n }\n\n const { disableFileHeader = false, collapsed = false } = this.options;\n const lastLineIndex = this.fileRenderer.getLineCount(this.file) - 1;\n let top = getVirtualFileHeaderRegion(this.metrics, disableFileHeader);\n\n if (collapsed || lastLineIndex < 0) {\n return { top, height: 0 };\n }\n\n const clampedLineIndex = Math.min(\n Math.max(lineNumber - 1, 0),\n lastLineIndex\n );\n const { overflow = 'scroll' } = this.options;\n const { lineHeight } = this.metrics;\n top += this.cache.fileAnnotationHeight;\n\n if (overflow === 'scroll' && !this.hasLineAnnotations()) {\n return {\n top: top + clampedLineIndex * lineHeight,\n height: lineHeight,\n };\n }\n\n const checkpoint =\n this.getLayoutCheckpointBeforeLineIndex(clampedLineIndex);\n top = checkpoint?.top ?? top;\n for (\n let lineIndex = checkpoint?.lineIndex ?? 0;\n lineIndex < clampedLineIndex;\n lineIndex++\n ) {\n top += this.getLineHeight(lineIndex, false);\n }\n\n return {\n top,\n height: this.getLineHeight(clampedLineIndex, false),\n };\n }\n\n public getNumericScrollAnchor(\n localViewportTop: number\n ): NumericScrollLineAnchor | undefined {\n if (this.file == null || this.renderRange == null) {\n return undefined;\n }\n\n const {\n disableFileHeader = false,\n collapsed = false,\n overflow = 'scroll',\n } = this.options;\n if (collapsed || this.renderRange.totalLines <= 0) {\n return undefined;\n }\n\n const lastLineIndex = this.fileRenderer.getLineCount(this.file) - 1;\n if (lastLineIndex < 0) {\n return undefined;\n }\n\n const headerRegion = getVirtualFileHeaderRegion(\n this.metrics,\n disableFileHeader\n );\n const firstRenderedLineIndex = Math.min(\n this.renderRange.startingLine,\n lastLineIndex\n );\n const lastRenderedLineIndex = Math.min(\n firstRenderedLineIndex + this.renderRange.totalLines - 1,\n lastLineIndex\n );\n if (lastRenderedLineIndex < firstRenderedLineIndex) {\n return undefined;\n }\n const { fileAnnotationHeight } = this.cache;\n\n // If we don't allow line wrapping and have no annotations, we can just\n // multiply our way to the the correct value\n if (overflow === 'scroll' && !this.hasLineAnnotations()) {\n const { lineHeight } = this.metrics;\n const firstRenderedLineTop =\n headerRegion +\n (firstRenderedLineIndex === 0\n ? fileAnnotationHeight\n : this.renderRange.bufferBefore);\n const deltaLineCount = Math.max(\n Math.ceil((localViewportTop - firstRenderedLineTop) / lineHeight),\n 0\n );\n const lineIndex = firstRenderedLineIndex + deltaLineCount;\n if (lineIndex > lastRenderedLineIndex) {\n return undefined;\n }\n\n return {\n lineNumber: lineIndex + 1,\n top: headerRegion + fileAnnotationHeight + lineIndex * lineHeight,\n };\n }\n\n // Otherwise we gotta iterate through the range\n let top =\n headerRegion +\n (firstRenderedLineIndex === 0\n ? fileAnnotationHeight\n : this.renderRange.bufferBefore);\n for (\n let lineIndex = firstRenderedLineIndex;\n lineIndex <= lastRenderedLineIndex;\n lineIndex++\n ) {\n if (top >= localViewportTop) {\n return {\n lineNumber: lineIndex + 1,\n top,\n };\n }\n top += this.getLineHeight(lineIndex);\n }\n\n return undefined;\n }\n\n public getVirtualizedHeight(): number {\n return this.height;\n }\n\n public getAdvancedStickySpecs(\n windowSpecs?: RenderWindow\n ): StickySpecs | undefined {\n if (this.top == null || this.file == null) {\n return undefined;\n }\n if (this.options.collapsed === true) {\n return { topOffset: this.top, height: this.height };\n }\n const renderRange =\n windowSpecs != null\n ? this.computeRenderRangeFromWindow(this.file, this.top, windowSpecs)\n : this.renderRange;\n if (renderRange == null) {\n return undefined;\n }\n const { bufferBefore, bufferAfter, totalLines } = renderRange;\n // Rendered items flow contiguously in the sticky container with no buffer\n // spacers, so a header-only item (totalLines === 0, none of its rows fall\n // inside the window) must report where its header actually sits in that\n // flow, which depends on which side of the window its content is on:\n // - content ABOVE the window (item starts above window.top): the header\n // sits at the item's bottom so the following item connects, so offset by\n // bufferAfter.\n // - content BELOW the window (item starts at/after window.top, e.g. a\n // trailing header peeking in at the bottom): the header renders at the\n // item's top with nothing after it, so no offset. Always adding\n // bufferAfter here made getStickyBounds over-measure the sticky\n // container for that trailing case.\n let headerOnlyOffset = 0;\n if (totalLines === 0) {\n const activeWindow = windowSpecs ?? this.virtualizer.getWindowSpecs();\n if (this.top < activeWindow.top) {\n headerOnlyOffset = bufferAfter;\n }\n }\n return {\n topOffset: this.top + bufferBefore + headerOnlyOffset,\n height: this.height - (bufferBefore + bufferAfter),\n };\n }\n\n override cleanUp(recycle = false): void {\n if (this.fileContainer != null && this.isSimpleMode()) {\n this.getSimpleVirtualizer()?.disconnect(this.fileContainer);\n }\n if (!recycle) {\n this.resetLayoutCache();\n }\n this.isSetup = false;\n super.cleanUp(recycle);\n }\n\n // Compute the approximate size of the file using cached line heights.\n // Uses lineHeight for lines without cached measurements.\n private computeApproximateSize(force = false): void {\n const shouldValidateSize = this.isResizeDebuggingEnabled();\n if (!force && !this.layoutDirty && !shouldValidateSize) {\n return;\n }\n\n const isFirstCompute = this.height === 0;\n this.height = 0;\n this.cache.checkpoints = [];\n if (this.file == null) {\n this.layoutDirty = false;\n return;\n }\n\n const {\n disableFileHeader = false,\n collapsed = false,\n overflow = 'scroll',\n } = this.options;\n const { lineHeight } = this.metrics;\n const lineCount = this.fileRenderer.getLineCount(this.file);\n const headerRegion = getVirtualFileHeaderRegion(\n this.metrics,\n disableFileHeader\n );\n const paddingBottom = getVirtualFilePaddingBottom(this.metrics);\n\n this.height += headerRegion;\n if (collapsed) {\n this.layoutDirty = false;\n return;\n }\n\n this.height += this.cache.fileAnnotationHeight;\n\n if (overflow === 'scroll' && !this.hasLineAnnotations()) {\n this.height += lineCount * lineHeight;\n } else {\n for (let lineIndex = 0; lineIndex < lineCount; lineIndex++) {\n this.addLayoutCheckpoint(lineIndex, this.height);\n this.height += this.getLineHeight(lineIndex, false);\n }\n }\n\n if (lineCount > 0) {\n this.height += paddingBottom;\n }\n\n if (this.fileContainer != null && shouldValidateSize && !isFirstCompute) {\n const rect = this.fileContainer.getBoundingClientRect();\n if (rect.height !== this.height) {\n console.log(\n 'VirtualizedFile.computeApproximateSize: computed height doesnt match',\n {\n name: this.file.name,\n elementHeight: rect.height,\n computedHeight: this.height,\n }\n );\n } else {\n console.log(\n 'VirtualizedFile.computeApproximateSize: computed height IS CORRECT'\n );\n }\n }\n this.layoutDirty = false;\n }\n\n public setVisibility(visible: boolean): void {\n if (this.isAdvancedMode() || this.fileContainer == null) {\n return;\n }\n if (visible && !this.isVisible) {\n this.top = this.getVirtualizedTop();\n this.isVisible = true;\n } else if (!visible && this.isVisible) {\n this.isVisible = false;\n this.rerender();\n }\n }\n\n override rerender(): void {\n if (!this.enabled || this.file == null) {\n return;\n }\n this.forceRenderOverride = true;\n this.virtualizer.instanceChanged(this, false);\n }\n\n // normally triggered by the host when the document line count changes\n override applyDocumentChange(\n textDocument: DiffsTextDocument,\n newLineAnnotations?: LineAnnotation<LAnnotation>[],\n shouldUpdateBuffer = false\n ): void {\n const previousRenderRange = this.renderRange;\n\n super.applyDocumentChange(textDocument, newLineAnnotations);\n\n // reset the layout cache\n this.getSimpleVirtualizer()?.markDOMDirty();\n this.resetLayoutCache(this.isSimpleMode(), false);\n\n // Update the buffers caused by the line-count change to ensure the host\n // scrolls to the correct position before re-rendering\n if (\n shouldUpdateBuffer &&\n previousRenderRange !== undefined &&\n this.file !== undefined\n ) {\n const windowSpecs = this.virtualizer.getWindowSpecs();\n const renderRange = this.computeRenderRangeFromWindow(\n this.file,\n this.top ?? 0,\n windowSpecs\n );\n if (renderRange.bufferAfter !== previousRenderRange.bufferAfter) {\n this.updateBuffers(renderRange);\n }\n }\n }\n\n override render({\n fileContainer,\n file,\n forceRender = false,\n lineAnnotations,\n ...props\n }: FileRenderProps<LAnnotation>): boolean {\n const didFileChange = this.file == null || !areFilesEqual(this.file, file);\n const { forceRenderOverride, isSetup } = this;\n this.forceRenderOverride = undefined;\n const annotationsChanged = this.syncLineAnnotations(lineAnnotations);\n if (annotationsChanged) {\n this.resetLayoutCache();\n }\n\n this.file = file;\n\n fileContainer = this.getOrCreateFileContainerNode(fileContainer);\n\n if (this.file == null) {\n console.error(\n 'VirtualizedFile.render: attempting to virtually render when we dont have file'\n );\n return false;\n }\n\n if (!isSetup) {\n this.computeApproximateSize();\n const virtualizer = this.getSimpleVirtualizer();\n this.top ??= this.getVirtualizedTop();\n if (this.isAdvancedMode()) {\n this.isVisible = true;\n } else {\n if (virtualizer == null) {\n throw new Error(\n 'VirtualizedFile.render: simple virtualizer is not available'\n );\n }\n virtualizer.connect(fileContainer, this);\n this.isVisible = virtualizer.isInstanceVisible(\n this.top ?? 0,\n this.height\n );\n }\n this.isSetup = true;\n } else {\n this.top ??= this.getVirtualizedTop();\n if (didFileChange && this.isSimpleMode()) {\n this.getSimpleVirtualizer()?.markDOMDirty();\n this.resetLayoutCache(true);\n }\n }\n\n if (!this.isVisible && this.isSimpleMode()) {\n return this.renderPlaceholder(this.height);\n }\n\n const windowSpecs = this.virtualizer.getWindowSpecs();\n const fileTop = this.top ?? 0;\n const renderRange = this.computeRenderRangeFromWindow(\n this.file,\n fileTop,\n windowSpecs\n );\n return super.render({\n file: this.file,\n fileContainer,\n renderRange,\n lineAnnotations,\n forceRender: (forceRenderOverride ?? forceRender) || annotationsChanged,\n ...props,\n });\n }\n\n public syncVirtualizedTop(): void {\n this.top = this.getVirtualizedTop();\n }\n\n protected override shouldDisableVirtualizationBuffers(): boolean {\n return this.isAdvancedMode() || super.shouldDisableVirtualizationBuffers();\n }\n\n private isSimpleMode(): boolean {\n return this.virtualizer.type === 'simple';\n }\n\n private isAdvancedMode(): boolean {\n return this.virtualizer.type === 'advanced';\n }\n\n private addLayoutCheckpoint(lineIndex: number, top: number): void {\n if (lineIndex % LAYOUT_CHECKPOINT_INTERVAL !== 0) {\n return;\n }\n this.cache.checkpoints.push({ lineIndex, top });\n }\n\n // Find the nearest sparse layout checkpoint at or before a raw file line.\n // Checkpoints store measured `top` offsets every few thousand lines, so a\n // binary search lets deep line-position lookups resume from that checkpoint\n // instead of replaying layout from the start of the file.\n private getLayoutCheckpointBeforeLineIndex(\n lineIndex: number\n ): FileLayoutCheckpoint | undefined {\n if (lineIndex <= 0 || this.cache.checkpoints.length === 0) {\n return undefined;\n }\n\n let low = 0;\n let high = this.cache.checkpoints.length - 1;\n let result: FileLayoutCheckpoint | undefined;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n const checkpoint = this.cache.checkpoints[mid];\n if (checkpoint == null) {\n throw new Error('VirtualizedFile: invalid checkpoint index');\n }\n if (checkpoint.lineIndex <= lineIndex) {\n result = checkpoint;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n return result;\n }\n\n // Find the nearest sparse layout checkpoint at or before a scroll offset.\n // Render-range scans start from this checkpoint so variable-height files\n // only replay the nearby measured rows. When `hunkLineCount` is provided,\n // step backward to a hunk boundary so hooks that depend on grouped lines\n // still see a complete hunk.\n private getLayoutCheckpointBeforeTop(\n top: number,\n hunkLineCount?: number\n ): FileLayoutCheckpoint | undefined {\n let low = 0;\n let high = this.cache.checkpoints.length - 1;\n let resultIndex = -1;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n const checkpoint = this.cache.checkpoints[mid];\n if (checkpoint == null) {\n throw new Error('VirtualizedFile: invalid checkpoint index');\n }\n if (checkpoint.top <= top) {\n resultIndex = mid;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n if (hunkLineCount == null) {\n return resultIndex >= 0 ? this.cache.checkpoints[resultIndex] : undefined;\n }\n\n for (let index = resultIndex; index >= 0; index--) {\n const checkpoint = this.cache.checkpoints[index];\n if (checkpoint == null) {\n throw new Error('VirtualizedFile: invalid checkpoint index');\n }\n if (checkpoint.lineIndex % hunkLineCount === 0) {\n return checkpoint;\n }\n }\n\n return undefined;\n }\n\n private getVirtualizedTop(): number {\n if (this.virtualizer.type === 'advanced') {\n return this.virtualizer.getLocalTopForInstance(this);\n }\n return this.fileContainer != null\n ? this.virtualizer.getOffsetInScrollContainer(this.fileContainer)\n : 0;\n }\n\n private getSimpleVirtualizer(): Virtualizer | undefined {\n return this.virtualizer.type === 'simple' ? this.virtualizer : undefined;\n }\n\n private isResizeDebuggingEnabled(): boolean {\n return this.getSimpleVirtualizer()?.config.resizeDebugging ?? false;\n }\n\n private computeRenderRangeFromWindow(\n file: FileContents,\n fileTop: number,\n { top, bottom }: RenderWindow\n ): RenderRange {\n const { disableFileHeader = false, overflow = 'scroll' } = this.options;\n const { hunkLineCount, lineHeight } = this.metrics;\n const lineCount = this.fileRenderer.getLineCount(file);\n const fileHeight = this.height;\n const headerRegion = getVirtualFileHeaderRegion(\n this.metrics,\n disableFileHeader\n );\n const paddingBottom =\n lineCount > 0 ? getVirtualFilePaddingBottom(this.metrics) : 0;\n const { fileAnnotationHeight } = this.cache;\n const codeRegionTop = headerRegion + fileAnnotationHeight;\n const codeRowsHeight = Math.max(\n 0,\n fileHeight - headerRegion - fileAnnotationHeight - paddingBottom\n );\n const hasFileAnnotations = includesFileAnnotations(this.lineAnnotations);\n const fileAnnotationTop = fileTop + headerRegion;\n const measuredFileAnnotationVisible =\n fileAnnotationHeight > 0 &&\n hasFileAnnotations &&\n fileAnnotationTop < bottom &&\n fileAnnotationTop + fileAnnotationHeight > top;\n\n // File is outside render window\n if (fileTop < top - fileHeight || fileTop > bottom) {\n return {\n startingLine: 0,\n totalLines: 0,\n bufferBefore: 0,\n bufferAfter: fileHeight - headerRegion - paddingBottom,\n };\n }\n\n // Small file, just render it all\n if (lineCount <= hunkLineCount) {\n return {\n startingLine: 0,\n totalLines: hunkLineCount,\n bufferBefore: 0,\n bufferAfter: 0,\n };\n }\n\n // Calculate totalLines based on viewport size\n const estimatedTargetLines = Math.ceil(\n Math.max(bottom - top, 0) / lineHeight\n );\n const totalLines =\n Math.ceil(estimatedTargetLines / hunkLineCount) * hunkLineCount +\n hunkLineCount * 2;\n const totalHunks = totalLines / hunkLineCount;\n const viewportCenter = (top + bottom) / 2;\n // Simple case: overflow scroll with no annotations - pure math!\n if (overflow === 'scroll' && !this.hasLineAnnotations()) {\n const sourceRowsTop = fileTop + codeRegionTop;\n const sourceRowsBottom = sourceRowsTop + codeRowsHeight;\n const sourceRowsVisible =\n sourceRowsTop < bottom && sourceRowsBottom > top;\n if (!measuredFileAnnotationVisible && !sourceRowsVisible) {\n return {\n startingLine: 0,\n totalLines: 0,\n bufferBefore: 0,\n bufferAfter: fileHeight - headerRegion - paddingBottom,\n };\n }\n\n // Find which line is at viewport center\n const centerLine = Math.floor(\n measuredFileAnnotationVisible &&\n viewportCenter < fileTop + codeRegionTop\n ? 0\n : (viewportCenter - (fileTop + codeRegionTop)) / lineHeight\n );\n const centerHunk = Math.floor(centerLine / hunkLineCount);\n\n // Calculate ideal start centered around viewport\n const idealStartHunk = centerHunk - Math.floor(totalHunks / 2);\n const totalHunksInFile = Math.ceil(lineCount / hunkLineCount);\n const startingLine =\n Math.max(0, Math.min(idealStartHunk, totalHunksInFile)) * hunkLineCount;\n\n const clampedTotalLines =\n idealStartHunk < 0\n ? totalLines + idealStartHunk * hunkLineCount\n : totalLines;\n\n const bufferBefore =\n startingLine === 0\n ? 0\n : fileAnnotationHeight + startingLine * lineHeight;\n const renderedLines = Math.min(\n clampedTotalLines,\n lineCount - startingLine\n );\n const bufferAfter = Math.max(\n 0,\n (lineCount - startingLine - renderedLines) * lineHeight\n );\n\n return {\n startingLine,\n totalLines: clampedTotalLines,\n bufferBefore,\n bufferAfter,\n };\n }\n\n // Complex case: need to account for line annotations or wrap overflow\n const overflowHunks = totalHunks;\n const hunkOffsets: number[] = [];\n // Start the scan before the viewport so we collect hunk offsets that may be\n // needed for bufferBefore. This only chooses the scan origin; the returned\n // render range is still computed from the visible window below.\n const checkpoint = this.getLayoutCheckpointBeforeTop(\n Math.max(0, top - fileTop - totalLines * lineHeight * 2),\n hunkLineCount\n );\n\n let absoluteLineTop = fileTop + (checkpoint?.top ?? codeRegionTop);\n let currentLine = checkpoint?.lineIndex ?? 0;\n let firstVisibleHunk: number | undefined;\n let centerHunk: number | undefined;\n let overflowCounter: number | undefined;\n\n const startingLineIndex = checkpoint?.lineIndex ?? 0;\n for (\n let lineIndex = startingLineIndex;\n lineIndex < lineCount;\n lineIndex++\n ) {\n const isAtHunkBoundary = currentLine % hunkLineCount === 0;\n const currentHunk = Math.floor(currentLine / hunkLineCount);\n\n if (isAtHunkBoundary) {\n hunkOffsets[currentHunk] = absoluteLineTop - (fileTop + codeRegionTop);\n\n if (overflowCounter != null) {\n if (overflowCounter <= 0) {\n break;\n }\n overflowCounter--;\n }\n }\n\n const lineHeight = this.getLineHeight(lineIndex, false);\n\n // Track visible region\n if (absoluteLineTop > top - lineHeight && absoluteLineTop < bottom) {\n firstVisibleHunk ??= currentHunk;\n }\n\n // Track which hunk contains the viewport center\n if (absoluteLineTop + lineHeight > viewportCenter) {\n centerHunk ??= currentHunk;\n }\n\n // Start overflow when we are out of the viewport at a hunk boundary\n if (\n overflowCounter == null &&\n absoluteLineTop >= bottom &&\n isAtHunkBoundary\n ) {\n overflowCounter = overflowHunks;\n }\n\n currentLine++;\n absoluteLineTop += lineHeight;\n }\n\n // No visible lines found\n if (firstVisibleHunk == null) {\n if (measuredFileAnnotationVisible) {\n firstVisibleHunk = 0;\n centerHunk = 0;\n } else {\n return {\n startingLine: 0,\n totalLines: 0,\n bufferBefore: 0,\n bufferAfter: fileHeight - headerRegion - paddingBottom,\n };\n }\n }\n\n // Calculate balanced startingLine centered around the viewport center\n centerHunk ??= firstVisibleHunk;\n const idealStartHunk = Math.round(centerHunk - totalHunks / 2);\n\n // Clamp startHunk: at the beginning, reduce totalLines; at the end, shift\n // startHunk back\n const maxStartHunk = Math.max(\n 0,\n Math.ceil(lineCount / hunkLineCount) - totalHunks\n );\n const startHunk = Math.max(0, Math.min(idealStartHunk, maxStartHunk));\n const startingLine = startHunk * hunkLineCount;\n\n // If we wanted to start before 0, reduce totalLines by the clamped amount\n const clampedTotalLines =\n idealStartHunk < 0\n ? totalLines + idealStartHunk * hunkLineCount\n : totalLines;\n\n // Use hunkOffsets array for efficient buffer calculations\n const codeBufferBefore = hunkOffsets[startHunk] ?? 0;\n const bufferBefore =\n startingLine === 0 ? 0 : fileAnnotationHeight + codeBufferBefore;\n\n // Calculate bufferAfter\n const finalHunkIndex = startHunk + clampedTotalLines / hunkLineCount;\n const bufferAfter =\n finalHunkIndex < hunkOffsets.length\n ? codeRowsHeight - hunkOffsets[finalHunkIndex]\n : codeRowsHeight - (absoluteLineTop - fileTop - codeRegionTop);\n\n return {\n startingLine,\n totalLines: clampedTotalLines,\n bufferBefore,\n bufferAfter: Math.max(0, bufferAfter),\n };\n }\n}\n\nfunction measureFileAnnotationHeight(content: HTMLElement): number | undefined {\n let height: number | undefined;\n for (const child of content.children) {\n if (!(child instanceof HTMLElement)) {\n continue;\n }\n if (child.dataset.lineAnnotation !== FILE_ANNOTATION_DOM_KEY) {\n continue;\n }\n height = Math.max(height ?? 0, child.getBoundingClientRect().height);\n }\n return height;\n}\n"],"mappings":"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"}
@@ -1,10 +1,11 @@
1
- import { DiffLineAnnotation, DiffsTextDocument, ExpansionDirections, FileDiffMetadata, NumericScrollLineAnchor, PendingCodeViewLayoutReset, RenderWindow, SelectionSide, StickySpecs, ThemeTypes, VirtualFileMetrics } from "../types.js";
1
+ import { BaseDiffOptions, DiffLineAnnotation, DiffsTextDocument, ExpansionDirections, FileDiffMetadata, NumericScrollLineAnchor, PendingCodeViewLayoutReset, RenderWindow, SelectionSide, StickySpecs, ThemeTypes, VirtualFileMetrics } from "../types.js";
2
2
  import { WorkerPoolManager } from "../worker/WorkerPoolManager.js";
3
3
  import { FileDiff, FileDiffOptions, FileDiffRenderProps } from "./FileDiff.js";
4
4
  import { Virtualizer } from "./Virtualizer.js";
5
5
  import { CodeView } from "./CodeView.js";
6
6
 
7
7
  //#region src/components/VirtualizedFileDiff.d.ts
8
+ type LoadedPartialDiffContents = Awaited<ReturnType<NonNullable<BaseDiffOptions['loadDiffFiles']>>>;
8
9
  declare class VirtualizedFileDiff<LAnnotation = undefined> extends FileDiff<LAnnotation> {
9
10
  readonly __id: string;
10
11
  top: number | undefined;
@@ -17,6 +18,8 @@ declare class VirtualizedFileDiff<LAnnotation = undefined> extends FileDiff<LAnn
17
18
  private layoutDirty;
18
19
  private forceRenderOverride;
19
20
  private currentCollapsed;
21
+ private pendingHydratedDiff;
22
+ private pendingExpansions;
20
23
  constructor(options: FileDiffOptions<LAnnotation> | undefined, virtualizer: Virtualizer | CodeView<LAnnotation>, metrics?: Partial<VirtualFileMetrics>, workerManager?: WorkerPoolManager, isContainerManaged?: boolean);
21
24
  setMetrics(metrics?: Partial<VirtualFileMetrics>, force?: boolean): void;
22
25
  setLineAnnotations(lineAnnotations: DiffLineAnnotation<LAnnotation>[]): void;
@@ -28,6 +31,7 @@ declare class VirtualizedFileDiff<LAnnotation = undefined> extends FileDiff<LAnn
28
31
  setOptions(options: FileDiffOptions<LAnnotation> | undefined): void;
29
32
  setThemeType(themeType: ThemeTypes): void;
30
33
  private resetLayoutCache;
34
+ private invalidateDerivedLayoutCache;
31
35
  reconcileHeights(): boolean;
32
36
  onRender: (dirty: boolean) => boolean;
33
37
  prepareCodeViewItem(fileDiff: FileDiffMetadata, top: number, reset?: PendingCodeViewLayoutReset, lineAnnotations?: DiffLineAnnotation<LAnnotation>[]): number;
@@ -40,6 +44,9 @@ declare class VirtualizedFileDiff<LAnnotation = undefined> extends FileDiff<LAnn
40
44
  getAdvancedStickySpecs(windowSpecs?: RenderWindow): StickySpecs | undefined;
41
45
  cleanUp(recycle?: boolean): void;
42
46
  expandHunk: (hunkIndex: number, direction: ExpansionDirections, expansionLineCountOverride?: number) => void;
47
+ protected handleFilesLoaded(expectedDiff: FileDiffMetadata, files: LoadedPartialDiffContents): Promise<void>;
48
+ consumeCodeViewLayoutChanges(expectedFileDiff: FileDiffMetadata): FileDiffMetadata | undefined;
49
+ protected loadFilesIfNecessary(): void;
43
50
  setVisibility(visible: boolean): void;
44
51
  rerender(): void;
45
52
  applyDocumentChange(textDocument: DiffsTextDocument, newLineAnnotations?: DiffLineAnnotation<LAnnotation>[], shouldUpdateBuffer?: boolean): void;
@@ -49,12 +56,10 @@ declare class VirtualizedFileDiff<LAnnotation = undefined> extends FileDiff<LAnn
49
56
  private validateComputedHeight;
50
57
  render({
51
58
  fileContainer,
52
- oldFile,
53
- newFile,
54
59
  fileDiff,
55
60
  forceRender,
56
61
  lineAnnotations,
57
- ...props
62
+ ...fileInputProps
58
63
  }?: FileDiffRenderProps<LAnnotation>): boolean;
59
64
  syncVirtualizedTop(): void;
60
65
  protected shouldDisableVirtualizationBuffers(): boolean;
@@ -69,6 +74,7 @@ declare class VirtualizedFileDiff<LAnnotation = undefined> extends FileDiff<LAnn
69
74
  private getLayoutCheckpointBeforeLineIndex;
70
75
  private getLayoutCheckpointBeforeTop;
71
76
  private getExpandedLineCount;
77
+ private getLayoutLineCount;
72
78
  private computeRenderRangeFromWindow;
73
79
  }
74
80
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualizedFileDiff.d.ts","names":[],"sources":["../../src/components/VirtualizedFileDiff.ts"],"mappings":";;;;;;;cAsFa,mBAAA,kCAEH,QAAA,CAAS,WAAA;EAAA,SACC,IAAA;EAEX,GAAA;EACA,MAAA;EAAA,QACC,OAAA;EAAA,QACA,KAAA;EAAA,QASA,SAAA;EAAA,QACA,OAAA;EAAA,QACA,WAAA;EAAA,QACA,WAAA;EAAA,QACA,mBAAA;EAAA,QACA,gBAAA;EAER,WAAA,CACE,OAAA,EAAS,eAAA,CAAgB,WAAA,eACzB,WAAA,EAAa,WAAA,GAAc,QAAA,CAAS,WAAA,GACpC,OAAA,GAAU,OAAA,CAAQ,kBAAA,GAClB,aAAA,GAAgB,iBAAA,EAChB,kBAAA;EAOK,UAAA,CACL,OAAA,GAAU,OAAA,CAAQ,kBAAA,GAClB,KAAA;EAWO,kBAAA,CACP,eAAA,EAAiB,kBAAA,CAAmB,WAAA;EAAA,QAO9B,mBAAA;EAAA,QAcA,uBAAA;EAAA,QAWA,kBAAA;EAAA,QAuBA,aAAA;EAAA,QAOA,sBAAA;EAKC,UAAA,CAAW,OAAA,EAAS,eAAA,CAAgB,WAAA;EAkCpC,YAAA,CAAa,SAAA,EAAW,UAAA;EAAA,QAUzB,gBAAA;EAoCD,gBAAA;EA6FA,QAAA,GAAQ,KAAA;EAcR,mBAAA,CACL,QAAA,EAAU,gBAAA,EACV,GAAA,UACA,KAAA,GAAQ,0BAAA,EACR,eAAA,GAAkB,kBAAA,CAAmB,WAAA;EAkChC,eAAA,CACL,UAAA,UACA,IAAA,GAAM,aAAA;IACH,GAAA;IAAa,MAAA;EAAA;EA2HX,sBAAA,CACL,gBAAA,WACC,uBAAA;EA8GI,oBAAA;EAIA,sBAAA,CACL,WAAA,GAAc,YAAA,GACb,WAAA;EA4CM,OAAA,CAAQ,OAAA;EAWR,UAAA,GAAU,SAAA,UACA,SAAA,EACN,mBAAA,EAAmB,0BAAA;EAgBzB,aAAA,CAAc,OAAA;EAcZ,QAAA;EAcA,mBAAA,CACP,YAAA,EAAc,iBAAA,EACd,kBAAA,GAAqB,kBAAA,CAAmB,WAAA,KACxC,kBAAA;EAAA,QAoCM,sBAAA;EAAA,QAoCA,wBAAA;EAAA,QAcA,0BAAA;EAAA,QA+BA,sBAAA;EAsBC,MAAA;IACP,aAAA;IACA,OAAA;IACA,OAAA;IACA,QAAA;IACA,WAAA;IACA,eAAA;IAAA,GACG;EAAA,IACF,mBAAA,CAAoB,WAAA;EAyEhB,kBAAA;EAAA,UAIY,kCAAA;EAAA,QAIX,YAAA;EAAA,QAIA,cAAA;EAAA,QAIA,iBAAA;EAAA,QASA,oBAAA;EAAA,QAIA,wBAAA;EAAA,QAIA,YAAA;EAAA,QAIA,oBAAA;EAAA,QAIA,4BAAA;EAAA,QA2LA,kCAAA;EAAA,QAiCA,4BAAA;EAAA,QAuCA,oBAAA;EAAA,QAoDA,4BAAA;AAAA"}
1
+ {"version":3,"file":"VirtualizedFileDiff.d.ts","names":[],"sources":["../../src/components/VirtualizedFileDiff.ts"],"mappings":";;;;;;;KAuDK,yBAAA,GAA4B,OAAA,CAC/B,UAAA,CAAW,WAAA,CAAY,eAAA;AAAA,cAqDZ,mBAAA,kCAEH,QAAA,CAAS,WAAA;EAAA,SACC,IAAA;EAEX,GAAA;EACA,MAAA;EAAA,QACC,OAAA;EAAA,QACA,KAAA;EAAA,QASA,SAAA;EAAA,QACA,OAAA;EAAA,QACA,WAAA;EAAA,QACA,WAAA;EAAA,QACA,mBAAA;EAAA,QACA,gBAAA;EAAA,QACA,mBAAA;EAAA,QACA,iBAAA;EAER,WAAA,CACE,OAAA,EAAS,eAAA,CAAgB,WAAA,eACzB,WAAA,EAAa,WAAA,GAAc,QAAA,CAAS,WAAA,GACpC,OAAA,GAAU,OAAA,CAAQ,kBAAA,GAClB,aAAA,GAAgB,iBAAA,EAChB,kBAAA;EAOK,UAAA,CACL,OAAA,GAAU,OAAA,CAAQ,kBAAA,GAClB,KAAA;EAWO,kBAAA,CACP,eAAA,EAAiB,kBAAA,CAAmB,WAAA;EAAA,QAO9B,mBAAA;EAAA,QAcA,uBAAA;EAAA,QAWA,kBAAA;EAAA,QAuBA,aAAA;EAAA,QAOA,sBAAA;EAKC,UAAA,CAAW,OAAA,EAAS,eAAA,CAAgB,WAAA;EAkCpC,YAAA,CAAa,SAAA,EAAW,UAAA;EAAA,QAUzB,gBAAA;EAAA,QAwBA,4BAAA;EAwBD,gBAAA;EA6FA,QAAA,GAAQ,KAAA;EAcR,mBAAA,CACL,QAAA,EAAU,gBAAA,EACV,GAAA,UACA,KAAA,GAAQ,0BAAA,EACR,eAAA,GAAkB,kBAAA,CAAmB,WAAA;EAkChC,eAAA,CACL,UAAA,UACA,IAAA,GAAM,aAAA;IACH,GAAA;IAAa,MAAA;EAAA;EA2HX,sBAAA,CACL,gBAAA,WACC,uBAAA;EA8GI,oBAAA;EAIA,sBAAA,CACL,WAAA,GAAc,YAAA,GACb,WAAA;EA4CM,OAAA,CAAQ,OAAA;EAaR,UAAA,GAAU,SAAA,UACA,SAAA,EACN,mBAAA,EAAmB,0BAAA;EAAA,UA2BP,iBAAA,CACvB,YAAA,EAAc,gBAAA,EACd,KAAA,EAAO,yBAAA,GACN,OAAA;EAiCI,4BAAA,CACL,gBAAA,EAAkB,gBAAA,GACjB,gBAAA;EAAA,UAoCgB,oBAAA;EAWZ,aAAA,CAAc,OAAA;EAcZ,QAAA;EAcA,mBAAA,CACP,YAAA,EAAc,iBAAA,EACd,kBAAA,GAAqB,kBAAA,CAAmB,WAAA,KACxC,kBAAA;EAAA,QAyCM,sBAAA;EAAA,QAwCA,wBAAA;EAAA,QAgBA,0BAAA;EAAA,QAqCA,sBAAA;EAwBC,MAAA;IACP,aAAA;IACA,QAAA;IACA,WAAA;IACA,eAAA;IAAA,GACG;EAAA,IACF,mBAAA,CAAoB,WAAA;EA0GhB,kBAAA;EAAA,UAIY,kCAAA;EAAA,QAIX,YAAA;EAAA,QAIA,cAAA;EAAA,QAIA,iBAAA;EAAA,QASA,oBAAA;EAAA,QAIA,wBAAA;EAAA,QAIA,YAAA;EAAA,QAIA,oBAAA;EAAA,QAIA,4BAAA;EAAA,QAkMA,kCAAA;EAAA,QAiCA,4BAAA;EAAA,QAuCA,oBAAA;EAAA,QAuDA,kBAAA;EAAA,QAkBA,4BAAA;AAAA"}