@pierre/diffs 1.3.6 → 1.4.0

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 (254) hide show
  1. package/dist/components/CodeView.d.ts +113 -68
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +153 -58
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts +75 -15
  6. package/dist/components/File.d.ts.map +1 -1
  7. package/dist/components/File.js +223 -62
  8. package/dist/components/File.js.map +1 -1
  9. package/dist/components/FileDiff.d.ts +97 -21
  10. package/dist/components/FileDiff.d.ts.map +1 -1
  11. package/dist/components/FileDiff.js +400 -100
  12. package/dist/components/FileDiff.js.map +1 -1
  13. package/dist/components/UnresolvedFile.d.ts +2 -2
  14. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  15. package/dist/components/UnresolvedFile.js +2 -2
  16. package/dist/components/UnresolvedFile.js.map +1 -1
  17. package/dist/components/VirtualizedFile.d.ts +16 -7
  18. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  19. package/dist/components/VirtualizedFile.js +140 -51
  20. package/dist/components/VirtualizedFile.js.map +1 -1
  21. package/dist/components/VirtualizedFileDiff.d.ts +14 -8
  22. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  23. package/dist/components/VirtualizedFileDiff.js +183 -93
  24. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  25. package/dist/components/VirtulizerDevelopment.d.ts +1 -1
  26. package/dist/components/VirtulizerDevelopment.d.ts.map +1 -1
  27. package/dist/edit/index.d.ts +7 -4
  28. package/dist/edit/index.js +5 -1
  29. package/dist/editor/EditStateManager.d.ts +56 -0
  30. package/dist/editor/EditStateManager.d.ts.map +1 -0
  31. package/dist/editor/EditStateManager.js +135 -0
  32. package/dist/editor/EditStateManager.js.map +1 -0
  33. package/dist/editor/cloneRetainedDiffSessionSnapshot.d.ts +7 -0
  34. package/dist/editor/cloneRetainedDiffSessionSnapshot.d.ts.map +1 -0
  35. package/dist/editor/cloneRetainedDiffSessionSnapshot.js +16 -0
  36. package/dist/editor/cloneRetainedDiffSessionSnapshot.js.map +1 -0
  37. package/dist/editor/editPrediction.d.ts +76 -0
  38. package/dist/editor/editPrediction.d.ts.map +1 -0
  39. package/dist/editor/editPrediction.js +365 -0
  40. package/dist/editor/editPrediction.js.map +1 -0
  41. package/dist/editor/editStack.d.ts +19 -40
  42. package/dist/editor/editStack.d.ts.map +1 -1
  43. package/dist/editor/editStack.js +67 -4
  44. package/dist/editor/editStack.js.map +1 -1
  45. package/dist/editor/editor.d.ts +118 -29
  46. package/dist/editor/editor.d.ts.map +1 -1
  47. package/dist/editor/editor.js +1103 -383
  48. package/dist/editor/editor.js.map +1 -1
  49. package/dist/editor/editor2.js +1 -1
  50. package/dist/editor/languages.d.ts +3 -3
  51. package/dist/editor/languages.d.ts.map +1 -1
  52. package/dist/editor/languages.js.map +1 -1
  53. package/dist/editor/lineAnnotations.d.ts +3 -3
  54. package/dist/editor/lineAnnotations.d.ts.map +1 -1
  55. package/dist/editor/lineAnnotations.js +16 -7
  56. package/dist/editor/lineAnnotations.js.map +1 -1
  57. package/dist/editor/marker.d.ts +2 -2
  58. package/dist/editor/marker.d.ts.map +1 -1
  59. package/dist/editor/marker.js.map +1 -1
  60. package/dist/editor/matchBrackets.d.ts +2 -2
  61. package/dist/editor/matchBrackets.d.ts.map +1 -1
  62. package/dist/editor/matchBrackets.js.map +1 -1
  63. package/dist/editor/pieceTable.d.ts +1 -1
  64. package/dist/editor/pieceTable.js.map +1 -1
  65. package/dist/editor/searchPanel.d.ts +2 -2
  66. package/dist/editor/searchPanel.js +1 -1
  67. package/dist/editor/searchPanel.js.map +1 -1
  68. package/dist/editor/selection.d.ts +32 -23
  69. package/dist/editor/selection.d.ts.map +1 -1
  70. package/dist/editor/selection.js +3 -3
  71. package/dist/editor/selection.js.map +1 -1
  72. package/dist/editor/selectionAction.d.ts +3 -3
  73. package/dist/editor/selectionAction.d.ts.map +1 -1
  74. package/dist/editor/selectionAction.js.map +1 -1
  75. package/dist/editor/textDocument.d.ts +11 -8
  76. package/dist/editor/textDocument.d.ts.map +1 -1
  77. package/dist/editor/textDocument.js +28 -5
  78. package/dist/editor/textDocument.js.map +1 -1
  79. package/dist/editor/textDocumentChangeTransaction.d.ts +15 -0
  80. package/dist/editor/textDocumentChangeTransaction.d.ts.map +1 -0
  81. package/dist/editor/textDocumentChangeTransaction.js +12 -0
  82. package/dist/editor/textDocumentChangeTransaction.js.map +1 -0
  83. package/dist/editor/textMeasure.d.ts +5 -0
  84. package/dist/editor/textMeasure.d.ts.map +1 -1
  85. package/dist/editor/textMeasure.js +10 -0
  86. package/dist/editor/textMeasure.js.map +1 -1
  87. package/dist/editor/tokenizer.d.ts +1 -1
  88. package/dist/editor/tokenizer.js.map +1 -1
  89. package/dist/editor/types.d.ts +267 -0
  90. package/dist/editor/types.d.ts.map +1 -0
  91. package/dist/editor/types.js +0 -0
  92. package/dist/editor/utils.d.ts +2 -1
  93. package/dist/editor/utils.d.ts.map +1 -1
  94. package/dist/editor/utils.js +4 -1
  95. package/dist/editor/utils.js.map +1 -1
  96. package/dist/index.d.ts +8 -6
  97. package/dist/index.js +9 -8
  98. package/dist/managers/InteractionManager.d.ts.map +1 -1
  99. package/dist/managers/InteractionManager.js +7 -0
  100. package/dist/managers/InteractionManager.js.map +1 -1
  101. package/dist/react/CodeView.d.ts +36 -25
  102. package/dist/react/CodeView.d.ts.map +1 -1
  103. package/dist/react/CodeView.js +15 -14
  104. package/dist/react/CodeView.js.map +1 -1
  105. package/dist/react/EditContext.d.ts +8 -11
  106. package/dist/react/EditContext.d.ts.map +1 -1
  107. package/dist/react/EditContext.js +2 -9
  108. package/dist/react/EditContext.js.map +1 -1
  109. package/dist/react/File.d.ts +10 -6
  110. package/dist/react/File.d.ts.map +1 -1
  111. package/dist/react/File.js +8 -4
  112. package/dist/react/File.js.map +1 -1
  113. package/dist/react/FileDiff.d.ts +10 -5
  114. package/dist/react/FileDiff.d.ts.map +1 -1
  115. package/dist/react/FileDiff.js +8 -4
  116. package/dist/react/FileDiff.js.map +1 -1
  117. package/dist/react/MultiFileDiff.d.ts +8 -5
  118. package/dist/react/MultiFileDiff.d.ts.map +1 -1
  119. package/dist/react/MultiFileDiff.js +8 -12
  120. package/dist/react/MultiFileDiff.js.map +1 -1
  121. package/dist/react/PatchDiff.d.ts +7 -4
  122. package/dist/react/PatchDiff.d.ts.map +1 -1
  123. package/dist/react/PatchDiff.js +8 -4
  124. package/dist/react/PatchDiff.js.map +1 -1
  125. package/dist/react/UnresolvedFile.d.ts +3 -3
  126. package/dist/react/UnresolvedFile.d.ts.map +1 -1
  127. package/dist/react/UnresolvedFile.js.map +1 -1
  128. package/dist/react/index.d.ts +8 -5
  129. package/dist/react/types.d.ts +46 -9
  130. package/dist/react/types.d.ts.map +1 -1
  131. package/dist/react/utils/renderDiffChildren.d.ts +14 -12
  132. package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
  133. package/dist/react/utils/renderDiffChildren.js +2 -2
  134. package/dist/react/utils/renderDiffChildren.js.map +1 -1
  135. package/dist/react/utils/renderFileChildren.d.ts +14 -12
  136. package/dist/react/utils/renderFileChildren.d.ts.map +1 -1
  137. package/dist/react/utils/renderFileChildren.js +2 -2
  138. package/dist/react/utils/renderFileChildren.js.map +1 -1
  139. package/dist/react/utils/useFileDiffInstance.d.ts +22 -10
  140. package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
  141. package/dist/react/utils/useFileDiffInstance.js +112 -22
  142. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  143. package/dist/react/utils/useFileInstance.d.ts +15 -9
  144. package/dist/react/utils/useFileInstance.d.ts.map +1 -1
  145. package/dist/react/utils/useFileInstance.js +84 -25
  146. package/dist/react/utils/useFileInstance.js.map +1 -1
  147. package/dist/renderers/DiffHunksRenderer.d.ts +30 -15
  148. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  149. package/dist/renderers/DiffHunksRenderer.js +172 -108
  150. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  151. package/dist/renderers/FileRenderer.d.ts +27 -11
  152. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  153. package/dist/renderers/FileRenderer.js +138 -64
  154. package/dist/renderers/FileRenderer.js.map +1 -1
  155. package/dist/renderers/UnresolvedFileHunksRenderer.d.ts +2 -2
  156. package/dist/renderers/UnresolvedFileHunksRenderer.d.ts.map +1 -1
  157. package/dist/renderers/UnresolvedFileHunksRenderer.js +2 -2
  158. package/dist/renderers/UnresolvedFileHunksRenderer.js.map +1 -1
  159. package/dist/shiki-stream/tokenizer.d.ts.map +1 -1
  160. package/dist/shiki-stream/tokenizer.js +2 -1
  161. package/dist/shiki-stream/tokenizer.js.map +1 -1
  162. package/dist/ssr/index.d.ts +2 -2
  163. package/dist/ssr/preloadDiffs.d.ts +21 -21
  164. package/dist/ssr/preloadDiffs.d.ts.map +1 -1
  165. package/dist/ssr/preloadDiffs.js +1 -1
  166. package/dist/ssr/preloadDiffs.js.map +1 -1
  167. package/dist/ssr/preloadFile.d.ts +6 -6
  168. package/dist/ssr/preloadFile.d.ts.map +1 -1
  169. package/dist/ssr/preloadFile.js.map +1 -1
  170. package/dist/ssr/preloadPatchFile.d.ts +4 -4
  171. package/dist/ssr/preloadPatchFile.d.ts.map +1 -1
  172. package/dist/ssr/preloadPatchFile.js.map +1 -1
  173. package/dist/style.js +1 -1
  174. package/dist/types.d.ts +13 -263
  175. package/dist/types.d.ts.map +1 -1
  176. package/dist/utils/appendItems.d.ts +5 -0
  177. package/dist/utils/appendItems.d.ts.map +1 -0
  178. package/dist/utils/appendItems.js +8 -0
  179. package/dist/utils/appendItems.js.map +1 -0
  180. package/dist/utils/areDiffTargetsEqual.js +1 -1
  181. package/dist/utils/areDiffTargetsEqual.js.map +1 -1
  182. package/dist/utils/areFileTargetsEqual.d.ts +7 -0
  183. package/dist/utils/areFileTargetsEqual.d.ts.map +1 -0
  184. package/dist/utils/areFileTargetsEqual.js +8 -0
  185. package/dist/utils/areFileTargetsEqual.js.map +1 -0
  186. package/dist/utils/areManagedSnapshotsEqual.d.ts +1 -1
  187. package/dist/utils/areManagedSnapshotsEqual.d.ts.map +1 -1
  188. package/dist/utils/areManagedSnapshotsEqual.js.map +1 -1
  189. package/dist/utils/areOptionsEqual.d.ts +3 -3
  190. package/dist/utils/areOptionsEqual.d.ts.map +1 -1
  191. package/dist/utils/areOptionsEqual.js.map +1 -1
  192. package/dist/utils/cloneFileDiffMetadata.d.ts +3 -2
  193. package/dist/utils/cloneFileDiffMetadata.d.ts.map +1 -1
  194. package/dist/utils/cloneFileDiffMetadata.js +8 -5
  195. package/dist/utils/cloneFileDiffMetadata.js.map +1 -1
  196. package/dist/utils/composeCacheKey.d.ts +6 -0
  197. package/dist/utils/composeCacheKey.d.ts.map +1 -0
  198. package/dist/utils/composeCacheKey.js +10 -0
  199. package/dist/utils/composeCacheKey.js.map +1 -0
  200. package/dist/utils/editSessionAnnotations.d.ts +69 -0
  201. package/dist/utils/editSessionAnnotations.d.ts.map +1 -0
  202. package/dist/utils/editSessionAnnotations.js +64 -0
  203. package/dist/utils/editSessionAnnotations.js.map +1 -0
  204. package/dist/utils/editSessionHunks.d.ts +5 -3
  205. package/dist/utils/editSessionHunks.d.ts.map +1 -1
  206. package/dist/utils/editSessionHunks.js +7 -5
  207. package/dist/utils/editSessionHunks.js.map +1 -1
  208. package/dist/utils/getDiffHunksRendererOptions.d.ts +1 -1
  209. package/dist/utils/getDiffHunksRendererOptions.d.ts.map +1 -1
  210. package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
  211. package/dist/utils/getFileRendererOptions.d.ts +1 -1
  212. package/dist/utils/getFileRendererOptions.d.ts.map +1 -1
  213. package/dist/utils/getFileRendererOptions.js.map +1 -1
  214. package/dist/utils/hydratePartialDiff.d.ts.map +1 -1
  215. package/dist/utils/hydratePartialDiff.js +2 -1
  216. package/dist/utils/hydratePartialDiff.js.map +1 -1
  217. package/dist/utils/lineAnnotationIdentity.d.ts +16 -0
  218. package/dist/utils/lineAnnotationIdentity.d.ts.map +1 -0
  219. package/dist/utils/lineAnnotationIdentity.js +17 -0
  220. package/dist/utils/lineAnnotationIdentity.js.map +1 -0
  221. package/dist/utils/parseDiffFromFile.d.ts +2 -2
  222. package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  223. package/dist/utils/parseDiffFromFile.js +6 -6
  224. package/dist/utils/parseDiffFromFile.js.map +1 -1
  225. package/dist/utils/parsePatchFiles.d.ts +6 -3
  226. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  227. package/dist/utils/parsePatchFiles.js +34 -9
  228. package/dist/utils/parsePatchFiles.js.map +1 -1
  229. package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
  230. package/dist/utils/renderDiffWithHighlighter.js +6 -5
  231. package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
  232. package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
  233. package/dist/utils/renderFileWithHighlighter.js +7 -4
  234. package/dist/utils/renderFileWithHighlighter.js.map +1 -1
  235. package/dist/utils/trimPatchContext.d.ts.map +1 -1
  236. package/dist/utils/trimPatchContext.js +3 -2
  237. package/dist/utils/trimPatchContext.js.map +1 -1
  238. package/dist/utils/updateDiffHunks.js +1 -1
  239. package/dist/utils/virtualDiffLayout.js +1 -1
  240. package/dist/worker/WorkerPoolManager.d.ts +4 -3
  241. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  242. package/dist/worker/WorkerPoolManager.js +33 -4
  243. package/dist/worker/WorkerPoolManager.js.map +1 -1
  244. package/dist/worker/types.d.ts +5 -0
  245. package/dist/worker/types.d.ts.map +1 -1
  246. package/dist/worker/worker-portable.js +14 -6
  247. package/dist/worker/worker-portable.js.map +1 -1
  248. package/dist/worker/worker.js +14 -6
  249. package/dist/worker/worker.js.map +1 -1
  250. package/package.json +9 -1
  251. package/dist/editor/stateStorage.d.ts +0 -15
  252. package/dist/editor/stateStorage.d.ts.map +0 -1
  253. package/dist/editor/stateStorage.js +0 -65
  254. package/dist/editor/stateStorage.js.map +0 -1
@@ -1,8 +1,11 @@
1
- import { AppliedThemeStyleCache, BaseCodeOptions, DiffsEditableComponent, DiffsEditor, DiffsTextDocument, EditorActiveLineOptions, FileContents, HighlightedToken, LineAnnotation, PostRenderPhase, PrePropertiesConfig, RenderFileMetadata, RenderRange, SelectedLineRange, ThemeTypes } from "../types.js";
1
+ import { AppliedThemeStyleCache, BaseCodeOptions, DiffLineAnnotation, FileContents, HighlightedToken, LineAnnotation, PostRenderPhase, PrePropertiesConfig, RenderFileMetadata, RenderRange, SelectedLineRange, ThemeTypes } from "../types.js";
2
+ import { EditCompletionDecision, EditorActiveLineOptions, EditorChangeEvent, FileEditCompleteEvent } from "../editor/types.js";
3
+ import { TextDocument } from "../editor/textDocument.js";
2
4
  import { GetHoveredLineResult, InteractionManager, InteractionManagerBaseOptions, SelectionWriteOptions } from "../managers/InteractionManager.js";
3
- import { WorkerPoolManager } from "../worker/WorkerPoolManager.js";
4
5
  import { ResizeManager } from "../managers/ResizeManager.js";
6
+ import { WorkerPoolManager } from "../worker/WorkerPoolManager.js";
5
7
  import { FileRenderer } from "../renderers/FileRenderer.js";
8
+ import { Editor } from "../editor/editor.js";
6
9
 
7
10
  //#region src/components/File.d.ts
8
11
  interface FileRenderProps<LAnnotation> {
@@ -19,7 +22,17 @@ interface FileHydrateProps<LAnnotation> extends Omit<FileRenderProps<LAnnotation
19
22
  fileContainer: HTMLElement;
20
23
  prerenderedHTML?: string;
21
24
  }
22
- interface FileOptions<LAnnotation> extends BaseCodeOptions, InteractionManagerBaseOptions<'file'> {
25
+ type FileEditChangeHandler<LAnnotation, Caret> = (event: EditorChangeEvent<'file', LAnnotation, Caret>) => void;
26
+ /**
27
+ * Decides a completed edit synchronously: return `'accept'` to install the
28
+ * event's `file` and annotations, or `'reject'` to restore the original values.
29
+ * The event is frozen, so re-key the accepted file in place
30
+ * (`event.file.cacheKey = '…'`) before accepting. The event's editor is
31
+ * detached and returns its final state from `getViewState()`. A missing handler
32
+ * rejects.
33
+ */
34
+ type FileEditCompleteHandler<LAnnotation, Caret> = (event: FileEditCompleteEvent<LAnnotation, Caret>) => EditCompletionDecision;
35
+ interface FileOptions<LAnnotation, Caret> extends BaseCodeOptions, InteractionManagerBaseOptions<'file'> {
23
36
  disableFileHeader?: boolean;
24
37
  renderHeaderPrefix?: RenderFileMetadata;
25
38
  renderHeaderFilenameSuffix?: RenderFileMetadata;
@@ -33,7 +46,21 @@ interface FileOptions<LAnnotation> extends BaseCodeOptions, InteractionManagerBa
33
46
  disableErrorHandling?: boolean;
34
47
  renderAnnotation?(annotation: LineAnnotation<LAnnotation>): HTMLElement | undefined;
35
48
  renderGutterUtility?(getHoveredRow: () => GetHoveredLineResult<'file'> | undefined): HTMLElement | null | undefined;
36
- onPostRender?(node: HTMLElement, instance: File<LAnnotation>, phase: PostRenderPhase): unknown;
49
+ onPostRender?(node: HTMLElement, instance: File<LAnnotation, Caret>, phase: PostRenderPhase): unknown;
50
+ /**
51
+ * Fired for every document change of an active edit session on this
52
+ * component, with the same `EditorChangeEvent` the editor reports through
53
+ * its own `onChange`. Do not feed the event's file back into the component
54
+ * while the session is active.
55
+ */
56
+ onEditChange?: FileEditChangeHandler<LAnnotation, Caret>;
57
+ /**
58
+ * Fired when `edit` toggles false or a component unmounts, including when the
59
+ * final contents are unchanged. If no callback is provided, the component
60
+ * reverts to the last `file` and annotations passed into it. The callback
61
+ * receives the detached editor with its final pre-detach state.
62
+ */
63
+ onEditComplete?: FileEditCompleteHandler<LAnnotation, Caret>;
37
64
  }
38
65
  interface AnnotationElementCache<LAnnotation> {
39
66
  element: HTMLElement;
@@ -43,8 +70,8 @@ interface HydrationSetup<LAnnotation> {
43
70
  file: FileContents;
44
71
  lineAnnotations: LineAnnotation<LAnnotation>[] | undefined;
45
72
  }
46
- declare class File<LAnnotation = undefined> implements DiffsEditableComponent<LAnnotation> {
47
- options: FileOptions<LAnnotation>;
73
+ declare class File<LAnnotation = undefined, Caret = undefined> {
74
+ options: FileOptions<LAnnotation, Caret>;
48
75
  private workerManager?;
49
76
  private isContainerManaged;
50
77
  static LoadedCustomComponent: boolean;
@@ -81,15 +108,25 @@ declare class File<LAnnotation = undefined> implements DiffsEditableComponent<LA
81
108
  protected lineAnnotations: LineAnnotation<LAnnotation>[];
82
109
  protected managersDirty: boolean;
83
110
  file: FileContents | undefined;
111
+ private editSessionFile;
112
+ private editSessionAnnotations;
113
+ private outgoingSessionFile;
114
+ protected renderedFile: FileContents | undefined;
84
115
  protected renderRange: RenderRange | undefined;
85
116
  protected enabled: boolean;
86
- protected editor: DiffsEditor<LAnnotation> | undefined;
87
- constructor(options?: FileOptions<LAnnotation>, workerManager?: WorkerPoolManager | undefined, isContainerManaged?: boolean);
117
+ protected editor: Editor<'file', LAnnotation, Caret> | undefined;
118
+ constructor(options?: FileOptions<LAnnotation, Caret>, workerManager?: WorkerPoolManager | undefined, isContainerManaged?: boolean);
119
+ getAnnotationSlotName: (annotation: LineAnnotation<LAnnotation> | DiffLineAnnotation<LAnnotation>) => string;
88
120
  private handleHighlightRender;
89
121
  rerender(): void;
90
- __getCurrentFile(): FileContents | undefined;
122
+ protected getLatestFile(file?: FileContents | undefined): FileContents | undefined;
123
+ protected getRenderedFile(): FileContents | undefined;
124
+ protected getLatestAnnotations(): LineAnnotation<LAnnotation>[];
125
+ protected isNewAnnotations(lineAnnotations: LineAnnotation<LAnnotation>[]): boolean;
126
+ protected updateExternalFile(incomingFile: FileContents, lineAnnotations?: LineAnnotation<LAnnotation>[]): boolean;
127
+ private installEditSession;
91
128
  onThemeChange(): void;
92
- setOptions(options: FileOptions<LAnnotation> | undefined): void;
129
+ setOptions(options: FileOptions<LAnnotation, Caret> | undefined): void;
93
130
  protected syncInteractionOptions(): void;
94
131
  private mergeOptions;
95
132
  setThemeType(themeType: ThemeTypes): void;
@@ -97,6 +134,7 @@ declare class File<LAnnotation = undefined> implements DiffsEditableComponent<LA
97
134
  private hasThemeChanged;
98
135
  getHoveredLine: () => GetHoveredLineResult<'file'> | undefined;
99
136
  setLineAnnotations(lineAnnotations: LineAnnotation<LAnnotation>[]): void;
137
+ protected syncEditSessionAnnotationsFromEditor(lineAnnotations: LineAnnotation<LAnnotation>[]): boolean;
100
138
  setSelectedLines(range: SelectedLineRange | null, options?: SelectionWriteOptions): void;
101
139
  setEditorActiveLine(lineNumber: number | null, options?: EditorActiveLineOptions): void;
102
140
  getCodeScrollLeft(): number;
@@ -115,13 +153,35 @@ declare class File<LAnnotation = undefined> implements DiffsEditableComponent<LA
115
153
  getOrCreateLineCache(file?: FileContents | undefined): string[];
116
154
  protected updateBuffers(renderRange: RenderRange): void;
117
155
  private syncRenderViewToEditor;
118
- attachEditor(editor: DiffsEditor<LAnnotation>): () => void;
119
- applyDocumentChange(textDocument: DiffsTextDocument, newLineAnnotations?: LineAnnotation<LAnnotation>[]): void;
156
+ emitEditChange(event: EditorChangeEvent<'file', LAnnotation, Caret>): void;
157
+ /** @internal Plain files have no component-owned diff session state. */
158
+ __captureDocumentSessionState(): undefined;
159
+ /** @internal Associate this component with its editor for a render lifecycle. */
160
+ __attachEditor(editor: Editor<'file', LAnnotation, Caret>): () => void;
161
+ /** @internal Resume rendering for the editor already associated with this component. */
162
+ __resumeEditor(editor: Editor<'file', LAnnotation, Caret>): void;
163
+ private resumeEditorRendering;
164
+ /**
165
+ * @internal
166
+ *
167
+ * Ends the edit session and settles which file this component renders.
168
+ * Requires the editor to be detached first. Does nothing when no session
169
+ * exists, so callers can invoke it again safely after it has settled.
170
+ *
171
+ * `onEditComplete` receives the completed file, current external file, and
172
+ * both annotation collections even when the final text is unchanged. In
173
+ * `install` mode, accepting installs the completed file and its annotations;
174
+ * rejecting or having no handler restores the external values. `discard`
175
+ * mode always restores the external values. An accepted file cannot reuse
176
+ * the replaced file's `cacheKey`.
177
+ */
178
+ __completeEditSession(editor: Editor<'file', LAnnotation, Caret>, mode: 'install' | 'discard'): void;
179
+ private settleEditSession;
180
+ applyDocumentChange(textDocument: TextDocument<'file', LAnnotation>, newLineAnnotations?: LineAnnotation<LAnnotation>[]): void;
120
181
  updateRenderCache(dirtyLines: Map<number, Array<HighlightedToken>>, themeType: 'dark' | 'light', options?: {
121
182
  lineCountChangeInFlight?: boolean;
122
183
  }): void;
123
- render(props: FileRenderProps<LAnnotation>): boolean;
124
- protected renderPreparedFile({
184
+ render({
125
185
  file,
126
186
  fileContainer,
127
187
  forceRender,
@@ -167,5 +227,5 @@ declare class File<LAnnotation = undefined> implements DiffsEditableComponent<LA
167
227
  private cleanupErrorWrapper;
168
228
  }
169
229
  //#endregion
170
- export { File, FileHydrateProps, FileOptions, FileRenderProps };
230
+ export { File, FileEditChangeHandler, type FileEditCompleteEvent, FileEditCompleteHandler, FileHydrateProps, FileOptions, FileRenderProps };
171
231
  //# sourceMappingURL=File.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"File.d.ts","names":[],"sources":["../../src/components/File.ts"],"mappings":"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"}
1
+ {"version":3,"file":"File.d.ts","names":[],"sources":["../../src/components/File.ts"],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  import { CUSTOM_HEADER_SLOT_ID, DEFAULT_THEMES, EMPTY_RENDER_RANGE, HEADER_FILENAME_SUFFIX_SLOT_ID, HEADER_METADATA_SLOT_ID, HEADER_PREFIX_SLOT_ID } from "../constants.js";
2
2
  import { areThemesEqual } from "../utils/areThemesEqual.js";
3
3
  import { isStyleNode } from "../utils/isStyleNode.js";
4
- import { areFilesEqual } from "../utils/areFilesEqual.js";
4
+ import { areFileTargetsEqual } from "../utils/areFileTargetsEqual.js";
5
5
  import { InteractionManager, pluckInteractionOptions } from "../managers/InteractionManager.js";
6
6
  import { ResizeManager } from "../managers/ResizeManager.js";
7
7
  import { areRenderRangesEqual } from "../utils/areRenderRangesEqual.js";
8
+ import { getFiletypeFromFileName } from "../utils/getFiletypeFromFileName.js";
8
9
  import { getLineAnnotationName } from "../utils/getLineAnnotationName.js";
9
10
  import { isFilePlainText } from "../utils/isFilePlainText.js";
10
11
  import { FileRenderer } from "../renderers/FileRenderer.js";
@@ -16,6 +17,7 @@ import { createGutterUtilityContentNode } from "../utils/createGutterUtilityCont
16
17
  import { createUnsafeCSSStyleNode } from "../utils/createUnsafeCSSStyleNode.js";
17
18
  import { getMeasuredScrollbarGutter } from "../utils/scrollbarGutter.js";
18
19
  import { patchScrollbarGutterSize, wrapThemeCSS, wrapUnsafeCSS } from "../utils/cssWrappers.js";
20
+ import { adoptEditSessionAnnotations, resolveEditSessionSlotName, writeEditSessionAnnotations } from "../utils/editSessionAnnotations.js";
19
21
  import { getFileRendererOptions } from "../utils/getFileRendererOptions.js";
20
22
  import { getOrCreateCodeNode } from "../utils/getOrCreateCodeNode.js";
21
23
  import { guardWebKitScrollDuringRebuild } from "../utils/guardWebKitScrollDuringRebuild.js";
@@ -27,6 +29,16 @@ import "./web-components.js";
27
29
  import { toHtml } from "hast-util-to-html";
28
30
  //#region src/components/File.ts
29
31
  const EMPTY_STRINGS = [""];
32
+ function createEditSessionFile(file) {
33
+ const editSessionFile = { ...file };
34
+ delete editSessionFile.cacheKey;
35
+ return editSessionFile;
36
+ }
37
+ function shouldResetUndoState(previousFile, nextFile) {
38
+ const previousLanguage = previousFile.lang ?? getFiletypeFromFileName(previousFile.name);
39
+ const nextLanguage = nextFile.lang ?? getFiletypeFromFileName(nextFile.name);
40
+ return previousFile.name !== nextFile.name || previousLanguage !== nextLanguage;
41
+ }
30
42
  let instanceId = -1;
31
43
  var File = class {
32
44
  options;
@@ -66,6 +78,10 @@ var File = class {
66
78
  lineAnnotations = [];
67
79
  managersDirty = false;
68
80
  file;
81
+ editSessionFile;
82
+ editSessionAnnotations;
83
+ outgoingSessionFile;
84
+ renderedFile;
69
85
  renderRange;
70
86
  enabled = true;
71
87
  editor;
@@ -73,11 +89,14 @@ var File = class {
73
89
  this.options = options;
74
90
  this.workerManager = workerManager;
75
91
  this.isContainerManaged = isContainerManaged;
76
- this.fileRenderer = new FileRenderer(options, this.handleHighlightRender, this.workerManager);
92
+ this.fileRenderer = new FileRenderer(options, this.getAnnotationSlotName, this.handleHighlightRender, this.workerManager);
77
93
  this.resizeManager = new ResizeManager();
78
94
  this.interactionManager = new InteractionManager("file", pluckInteractionOptions(options));
79
95
  this.workerManager?.subscribeToThemeChanges(this);
80
96
  }
97
+ getAnnotationSlotName = (annotation) => {
98
+ return resolveEditSessionSlotName(this.editSessionAnnotations, annotation, getLineAnnotationName);
99
+ };
81
100
  handleHighlightRender = () => {
82
101
  this.rerender();
83
102
  };
@@ -89,8 +108,40 @@ var File = class {
89
108
  renderRange: this.renderRange
90
109
  });
91
110
  }
92
- __getCurrentFile() {
93
- return this.file;
111
+ getLatestFile(file = this.file) {
112
+ return this.editSessionFile ?? file;
113
+ }
114
+ getRenderedFile() {
115
+ return this.renderedFile;
116
+ }
117
+ getLatestAnnotations() {
118
+ return this.editSessionAnnotations?.current ?? this.lineAnnotations;
119
+ }
120
+ isNewAnnotations(lineAnnotations) {
121
+ const { editSessionAnnotations: session, lineAnnotations: externalAnnotations } = this;
122
+ if (lineAnnotations === externalAnnotations) return false;
123
+ return session == null || lineAnnotations !== session.provided && lineAnnotations !== session.current;
124
+ }
125
+ updateExternalFile(incomingFile, lineAnnotations) {
126
+ if (areFileTargetsEqual(this.file, incomingFile)) return false;
127
+ const previousEditSessionFile = this.outgoingSessionFile ?? this.editSessionFile;
128
+ this.file = incomingFile;
129
+ this.outgoingSessionFile = void 0;
130
+ if (previousEditSessionFile != null || this.editor != null) {
131
+ this.outgoingSessionFile = previousEditSessionFile;
132
+ this.installEditSession(incomingFile, previousEditSessionFile == null ? this.editor?.__getDocumentContents(incomingFile) : void 0);
133
+ } else this.editSessionFile = void 0;
134
+ if (this.editSessionAnnotations != null && lineAnnotations != null) {
135
+ this.lineAnnotations = lineAnnotations;
136
+ this.editSessionAnnotations = adoptEditSessionAnnotations(lineAnnotations, getLineAnnotationName, this.editSessionAnnotations);
137
+ }
138
+ return true;
139
+ }
140
+ installEditSession(externalFile, retainedDocument) {
141
+ const usesExternalDocument = retainedDocument == null || retainedDocument.name === externalFile.name && retainedDocument.lang === externalFile.lang && retainedDocument.contents === externalFile.contents;
142
+ const editSessionFile = createEditSessionFile(retainedDocument ?? externalFile);
143
+ this.editSessionFile = editSessionFile;
144
+ this.fileRenderer.beginEditSession(editSessionFile, usesExternalDocument ? externalFile : void 0);
94
145
  }
95
146
  onThemeChange() {
96
147
  this.fileRenderer.clearRenderCache();
@@ -130,7 +181,22 @@ var File = class {
130
181
  return this.interactionManager.getHoveredLine();
131
182
  };
132
183
  setLineAnnotations(lineAnnotations) {
184
+ const { editSessionAnnotations: sessionAnnotations } = this;
185
+ if (sessionAnnotations == null) {
186
+ this.lineAnnotations = lineAnnotations;
187
+ return;
188
+ }
189
+ if (!this.isNewAnnotations(lineAnnotations)) return;
133
190
  this.lineAnnotations = lineAnnotations;
191
+ writeEditSessionAnnotations(sessionAnnotations, lineAnnotations, getLineAnnotationName);
192
+ }
193
+ syncEditSessionAnnotationsFromEditor(lineAnnotations) {
194
+ const { editSessionAnnotations: session } = this;
195
+ if (session == null || lineAnnotations === session.current) return false;
196
+ session.current = lineAnnotations;
197
+ this.fileRenderer.setLineAnnotations(lineAnnotations);
198
+ this.renderAnnotations();
199
+ return true;
134
200
  }
135
201
  setSelectedLines(range, options) {
136
202
  this.interactionManager.setSelection(range, options);
@@ -167,12 +233,13 @@ var File = class {
167
233
  this.managersDirty = false;
168
234
  }
169
235
  shouldApplyColumnVariables(overflow) {
170
- return overflow === "scroll" && this.lineAnnotations.length > 0;
236
+ return overflow === "scroll" && this.getLatestAnnotations().length > 0;
171
237
  }
172
238
  cleanUp(recycle = false) {
239
+ const editor = this.editor;
173
240
  this.emitPostRender(true);
174
- this.editor?.cleanUp(recycle);
175
- this.editor = void 0;
241
+ editor?.cleanUp(recycle ? "recycle" : "discard");
242
+ if (!recycle) this.editor = void 0;
176
243
  this.resizeManager.cleanUp();
177
244
  this.interactionManager.cleanUp();
178
245
  this.managersDirty = false;
@@ -213,6 +280,10 @@ var File = class {
213
280
  this.fileRenderer.cleanUp();
214
281
  this.workerManager = void 0;
215
282
  this.file = void 0;
283
+ this.editSessionFile = void 0;
284
+ this.editSessionAnnotations = void 0;
285
+ this.outgoingSessionFile = void 0;
286
+ this.renderedFile = void 0;
216
287
  }
217
288
  this.enabled = false;
218
289
  }
@@ -225,8 +296,10 @@ var File = class {
225
296
  if (!this.enabled) throw new Error("File.hydrate: attempting to call hydrate after cleaned up");
226
297
  if (this.fileContainer != null) throw new Error("File.hydrate: hydrate can only be called before the instance has rendered or hydrated");
227
298
  this.hydrateElements(fileContainer, prerenderedHTML);
228
- if (shouldRenderCode(this.pre, file, this.options.collapsed) || shouldRenderHeader(this.headerElement, file, this.options.disableFileHeader)) this.render({
299
+ const forceEditorRender = this.editor != null;
300
+ if (forceEditorRender || shouldRenderCode(this.pre, file, this.options.collapsed) || shouldRenderHeader(this.headerElement, file, this.options.disableFileHeader)) this.render({
229
301
  ...props,
302
+ forceRender: forceEditorRender || props.forceRender,
230
303
  preventEmit: true
231
304
  });
232
305
  else this.hydrationSetup({
@@ -278,82 +351,168 @@ var File = class {
278
351
  this.syncInteractionOptions();
279
352
  if (this.pre == null) return;
280
353
  this.fileRenderer.hydrate(file);
354
+ this.renderedFile = file;
281
355
  this.renderAnnotations();
282
356
  this.renderGutterUtility();
283
357
  this.injectUnsafeCSS();
284
358
  this.managersDirty = true;
285
359
  this.flushManagers();
286
360
  }
287
- getOrCreateLineCache(file = this.file) {
361
+ getOrCreateLineCache(file = this.getLatestFile()) {
288
362
  return file != null ? this.fileRenderer.getOrCreateLineCache(file) : EMPTY_STRINGS;
289
363
  }
290
364
  updateBuffers(renderRange) {
291
365
  if (this.pre != null) this.applyBuffers(this.pre, renderRange);
292
366
  }
293
367
  syncRenderViewToEditor() {
294
- const editor = this.editor;
295
- const fileContainer = this.fileContainer;
296
- const file = this.file;
297
- const lineAnnotations = this.lineAnnotations;
298
- const renderRange = this.renderRange;
299
- if (editor != null && fileContainer != null && file != null) this.fileRenderer.initializeHighlighter().then((highlighter) => {
300
- if (!this.enabled || this.editor !== editor || this.fileContainer !== fileContainer || this.file !== file) return;
301
- editor.__syncRenderView(highlighter, fileContainer, file, lineAnnotations, renderRange);
368
+ const { editor, fileContainer, renderRange } = this;
369
+ const lineAnnotations = this.getLatestAnnotations();
370
+ const file = this.getLatestFile();
371
+ if (editor == null || fileContainer == null || file == null) return;
372
+ this.fileRenderer.initializeHighlighter().then((highlighter) => {
373
+ if (!this.enabled || this.editor !== editor || this.fileContainer !== fileContainer || this.getLatestFile() !== file) return;
374
+ const { outgoingSessionFile: replacement, file: externalFile } = this;
375
+ const externalDocument = replacement != null && externalFile != null && replacement !== file;
376
+ const resetHistory = externalDocument ? shouldResetUndoState(replacement, externalFile) : false;
377
+ if (externalDocument) this.outgoingSessionFile = void 0;
378
+ editor.__syncRenderView({
379
+ highlighter,
380
+ fileContainer,
381
+ file,
382
+ lineAnnotations,
383
+ renderRange,
384
+ externalDocument,
385
+ resetHistory
386
+ });
302
387
  });
303
388
  }
304
- attachEditor(editor) {
305
- this.editor?.cleanUp();
389
+ emitEditChange(event) {
390
+ const { lineAnnotations } = event;
391
+ if (lineAnnotations != null) this.syncEditSessionAnnotationsFromEditor(lineAnnotations);
392
+ const { onEditChange } = this.options;
393
+ onEditChange?.(event);
394
+ }
395
+ /** @internal Plain files have no component-owned diff session state. */
396
+ __captureDocumentSessionState() {}
397
+ /** @internal Associate this component with its editor for a render lifecycle. */
398
+ __attachEditor(editor) {
399
+ if (this.editor != null) throw new Error("File.__attachEditor: an editor is already attached");
306
400
  this.editor = editor;
307
- this.fileRenderer.beginEditSession();
308
- const preparedFile = this.file == null ? void 0 : editor.__prepareFile?.(this.file);
309
- if (preparedFile !== void 0 && preparedFile !== this.file) this.renderPreparedFile({
310
- file: preparedFile,
311
- forceRender: true,
312
- preventEmit: true,
313
- renderRange: this.renderRange
314
- });
315
- else if (this.fileRenderer.editorRenderReady()) this.syncRenderViewToEditor();
316
- else this.rerender();
317
- return () => {
401
+ const detach = () => {
318
402
  this.editor = void 0;
319
403
  this.fileRenderer.endEditSession();
320
404
  };
405
+ try {
406
+ this.resumeEditorRendering(editor);
407
+ return detach;
408
+ } catch (error) {
409
+ detach();
410
+ throw error;
411
+ }
412
+ }
413
+ /** @internal Resume rendering for the editor already associated with this component. */
414
+ __resumeEditor(editor) {
415
+ if (this.editor !== editor) throw new Error("File.__resumeEditor: editor association changed");
416
+ this.resumeEditorRendering(editor);
417
+ }
418
+ resumeEditorRendering(editor) {
419
+ this.editSessionAnnotations ??= adoptEditSessionAnnotations(this.lineAnnotations, getLineAnnotationName);
420
+ if (this.editSessionFile == null && this.file != null) this.installEditSession(this.file, editor.__getDocumentContents(this.file));
421
+ else this.fileRenderer.beginEditSession(this.editSessionFile);
422
+ if (this.fileRenderer.editorRenderReady()) {
423
+ if (this.fileRenderer.fileCache === this.editSessionFile) this.renderedFile = this.editSessionFile;
424
+ this.syncRenderViewToEditor();
425
+ } else this.rerender();
426
+ }
427
+ /**
428
+ * @internal
429
+ *
430
+ * Ends the edit session and settles which file this component renders.
431
+ * Requires the editor to be detached first. Does nothing when no session
432
+ * exists, so callers can invoke it again safely after it has settled.
433
+ *
434
+ * `onEditComplete` receives the completed file, current external file, and
435
+ * both annotation collections even when the final text is unchanged. In
436
+ * `install` mode, accepting installs the completed file and its annotations;
437
+ * rejecting or having no handler restores the external values. `discard`
438
+ * mode always restores the external values. An accepted file cannot reuse
439
+ * the replaced file's `cacheKey`.
440
+ */
441
+ __completeEditSession(editor, mode) {
442
+ this.settleEditSession(mode === "install", editor);
443
+ }
444
+ settleEditSession(installResult, editor) {
445
+ const { editSessionFile, editSessionAnnotations, file: externalFile, lineAnnotations: externalAnnotations } = this;
446
+ if (editSessionFile == null || externalFile == null) return;
447
+ if (this.editor != null) throw new Error("File.__completeEditSession: detach the editor before completing the session");
448
+ const sessionAnnotationsCurrent = editSessionAnnotations?.current;
449
+ let acceptedFile;
450
+ let failed = false;
451
+ let failure;
452
+ if (editor == null) throw new Error("File.__completeEditSession: editor is required for completion");
453
+ const completedFile = { ...editSessionFile };
454
+ const event = {
455
+ file: completedFile,
456
+ editor,
457
+ originalFile: externalFile,
458
+ lineAnnotations: sessionAnnotationsCurrent,
459
+ originalLineAnnotations: externalAnnotations
460
+ };
461
+ Object.freeze(event);
462
+ try {
463
+ editor.__emitEditComplete(event);
464
+ if (this.options.onEditComplete?.(event) === "accept") {
465
+ if (completedFile.cacheKey != null && completedFile.cacheKey === externalFile.cacheKey) throw new Error("File.__completeEditSession: an accepted file must not reuse the replaced file cacheKey");
466
+ acceptedFile = completedFile;
467
+ }
468
+ } catch (error) {
469
+ failed = true;
470
+ failure = error;
471
+ }
472
+ if (installResult && acceptedFile != null) {
473
+ this.file = acceptedFile;
474
+ if (sessionAnnotationsCurrent != null) this.lineAnnotations = sessionAnnotationsCurrent;
475
+ }
476
+ this.editSessionFile = void 0;
477
+ this.editSessionAnnotations = void 0;
478
+ this.outgoingSessionFile = void 0;
479
+ const { renderedFile, file: settledFile } = this;
480
+ this.fileRenderer.endEditSession(settledFile);
481
+ if (renderedFile != null && settledFile != null && renderedFile !== settledFile && areFileTargetsEqual(renderedFile, settledFile)) this.renderedFile = settledFile;
482
+ if (installResult && this.fileContainer != null) this.rerender();
483
+ if (failed) throw failure;
321
484
  }
322
485
  applyDocumentChange(textDocument, newLineAnnotations) {
486
+ const { editSessionFile } = this;
487
+ if (editSessionFile == null) throw new Error("File.applyDocumentChange: requires an active edit session");
488
+ this.fileRenderer.beginEditSession(editSessionFile);
323
489
  this.fileRenderer.applyDocumentChange(textDocument);
324
- if (newLineAnnotations != null && newLineAnnotations !== this.lineAnnotations && this.file != null) {
325
- this.setLineAnnotations(newLineAnnotations);
326
- this.fileRenderer.setLineAnnotations(this.lineAnnotations);
327
- this.renderAnnotations();
328
- }
490
+ if (newLineAnnotations != null) this.syncEditSessionAnnotationsFromEditor(newLineAnnotations);
329
491
  }
330
492
  updateRenderCache(dirtyLines, themeType, options) {
493
+ const { editSessionFile } = this;
494
+ if (editSessionFile == null) throw new Error("File.updateRenderCache: requires an active edit session");
495
+ this.fileRenderer.beginEditSession(editSessionFile);
331
496
  this.fileRenderer.updateRenderCache(dirtyLines, themeType, options?.lineCountChangeInFlight);
332
497
  }
333
- render(props) {
498
+ render({ file, fileContainer, forceRender = false, preventEmit = false, containerWrapper, deferManagers = false, lineAnnotations, renderRange }) {
334
499
  if (!this.enabled) throw new Error("File.render: attempting to call render after cleaned up");
335
- const file = this.editor?.__prepareFile?.(props.file) ?? props.file;
336
- return this.renderPreparedFile(file === props.file ? props : {
337
- ...props,
338
- file
339
- });
340
- }
341
- renderPreparedFile({ file, fileContainer, forceRender = false, preventEmit = false, containerWrapper, deferManagers = false, lineAnnotations, renderRange }) {
342
500
  this.editor?.__postponeBgTokenizeToNextFrame();
343
501
  const { collapsed = false, themeType = "system" } = this.options;
344
502
  const nextRenderRange = collapsed ? void 0 : renderRange;
345
503
  const previousRenderRange = this.renderRange;
346
504
  const themeChanged = this.hasThemeChanged();
347
- const annotationsChanged = lineAnnotations != null && (lineAnnotations.length > 0 || this.lineAnnotations.length > 0) ? lineAnnotations !== this.lineAnnotations : false;
348
- const didFileChange = !areFilesEqual(this.file, file) || this.fileRenderer.hasUnkeyedFileContentsChanged(file);
505
+ const annotationsChanged = lineAnnotations != null && (lineAnnotations.length > 0 || this.getLatestAnnotations().length > 0) ? this.isNewAnnotations(lineAnnotations) : false;
506
+ const didFileChange = !areFileTargetsEqual(this.file, file);
507
+ if (didFileChange) this.updateExternalFile(file, lineAnnotations);
508
+ const latestFile = this.getLatestFile(file) ?? file;
349
509
  if (!collapsed && !forceRender && areRenderRangesEqual(nextRenderRange, this.renderRange) && !didFileChange && !annotationsChanged && !themeChanged) return this.applyCachedThemeState(themeType);
350
510
  this.renderRange = nextRenderRange;
351
511
  if (didFileChange) this.cachedHeaderHTML = void 0;
352
- this.file = file;
353
512
  this.fileRenderer.setOptions(getFileRendererOptions(this.options));
354
513
  this.syncInteractionOptions();
355
514
  if (lineAnnotations != null) this.setLineAnnotations(lineAnnotations);
356
- this.fileRenderer.setLineAnnotations(this.lineAnnotations);
515
+ this.fileRenderer.setLineAnnotations(this.getLatestAnnotations());
357
516
  const { disableErrorHandling = false, disableFileHeader = false } = this.options;
358
517
  if (disableFileHeader) {
359
518
  if (this.headerElement != null) {
@@ -369,9 +528,10 @@ var File = class {
369
528
  this.removeRenderedCode();
370
529
  this.clearAuxiliaryNodes();
371
530
  try {
372
- const fileResult = this.fileRenderer.renderFile(file, EMPTY_RENDER_RANGE);
531
+ const fileResult = this.fileRenderer.renderFile(latestFile, EMPTY_RENDER_RANGE);
373
532
  if (fileResult != null) this.applyThemeState(fileContainer, fileResult.themeStyles, themeType, fileResult.baseThemeType);
374
- if (fileResult?.headerAST != null) this.applyHeaderToDOM(fileResult.headerAST, fileContainer);
533
+ if (fileResult?.headerAST != null) this.applyHeaderToDOM(fileResult.headerAST, fileContainer, fileResult.file);
534
+ this.renderedFile = fileResult?.file ?? latestFile;
375
535
  this.injectUnsafeCSS();
376
536
  } catch (error) {
377
537
  if (disableErrorHandling) throw error;
@@ -383,15 +543,16 @@ var File = class {
383
543
  }
384
544
  try {
385
545
  const pre = this.getOrCreatePreNode(fileContainer);
386
- if (!this.canPartiallyRender(forceRender, annotationsChanged, didFileChange || themeChanged) || !this.applyPartialRender(previousRenderRange, nextRenderRange)) {
387
- const fileResult = this.fileRenderer.renderFile(file, nextRenderRange);
546
+ if (!this.canPartiallyRender(forceRender, annotationsChanged, didFileChange || themeChanged || !areFileTargetsEqual(this.renderedFile, latestFile)) || !this.applyPartialRender(latestFile, previousRenderRange, nextRenderRange)) {
547
+ const fileResult = this.fileRenderer.renderFile(latestFile, nextRenderRange);
388
548
  if (fileResult == null) {
389
- if (this.workerManager?.isInitialized() === false) this.workerManager.initialize().then(() => this.rerender());
549
+ if (this.workerManager?.isInitialized() === false && this.workerManager.isWorkingPool()) this.workerManager.initialize().catch(() => {}).then(() => this.rerender());
390
550
  return false;
391
551
  }
392
552
  this.applyThemeState(fileContainer, fileResult.themeStyles, themeType, fileResult.baseThemeType);
393
- if (fileResult.headerAST != null) this.applyHeaderToDOM(fileResult.headerAST, fileContainer);
553
+ if (fileResult.headerAST != null) this.applyHeaderToDOM(fileResult.headerAST, fileContainer, fileResult.file);
394
554
  this.applyFullRender(fileResult, pre);
555
+ this.renderedFile = fileResult.file;
395
556
  }
396
557
  this.applyBuffers(pre, nextRenderRange);
397
558
  this.injectUnsafeCSS();
@@ -513,15 +674,17 @@ var File = class {
513
674
  }
514
675
  const staleAnnotations = new Map(this.annotationCache);
515
676
  const { renderAnnotation } = this.options;
516
- if (renderAnnotation != null && this.lineAnnotations.length > 0) for (const [index, annotation] of this.lineAnnotations.entries()) {
517
- const id = `${index}-${getLineAnnotationName(annotation)}`;
677
+ const lineAnnotations = this.getLatestAnnotations();
678
+ if (renderAnnotation != null && lineAnnotations.length > 0) for (const [index, annotation] of lineAnnotations.entries()) {
679
+ const name = this.getAnnotationSlotName(annotation);
680
+ const id = `${index}-${name}`;
518
681
  let cache = this.annotationCache.get(id);
519
682
  if (cache == null || !areLineAnnotationsEqual(annotation, cache.annotation)) {
520
683
  cache?.element.remove();
521
684
  const content = renderAnnotation(annotation);
522
685
  if (content == null) continue;
523
686
  cache = {
524
- element: createAnnotationWrapperNode(getLineAnnotationName(annotation)),
687
+ element: createAnnotationWrapperNode(name),
525
688
  annotation
526
689
  };
527
690
  cache.element.appendChild(content);
@@ -634,11 +797,11 @@ var File = class {
634
797
  else applyColumns();
635
798
  this.lastRowCount = result.rowCount;
636
799
  }
637
- applyPartialRender(previousRenderRange, renderRange) {
800
+ applyPartialRender(file, previousRenderRange, renderRange) {
638
801
  if (previousRenderRange == null || renderRange == null) return false;
639
- const { file, code } = this;
802
+ const { code } = this;
640
803
  const columns = code != null ? this.getColumns(code) : void 0;
641
- if (file == null || code == null || columns == null) return false;
804
+ if (code == null || columns == null) return false;
642
805
  const previousStart = previousRenderRange.startingLine;
643
806
  const nextStart = renderRange.startingLine;
644
807
  const previousEnd = previousRenderRange.totalLines === Infinity ? Number.POSITIVE_INFINITY : previousStart + previousRenderRange.totalLines;
@@ -771,9 +934,7 @@ var File = class {
771
934
  shouldDisableVirtualizationBuffers() {
772
935
  return this.options.disableVirtualizationBuffers ?? false;
773
936
  }
774
- applyHeaderToDOM(headerAST, container) {
775
- const { file } = this;
776
- if (file == null) return;
937
+ applyHeaderToDOM(headerAST, container, file) {
777
938
  this.cleanupErrorWrapper();
778
939
  this.placeHolder?.remove();
779
940
  this.placeHolder = void 0;