@pierre/diffs 1.5.2 → 1.6.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 (359) hide show
  1. package/README.md +4 -3
  2. package/dist/components/CodeView.d.ts +3 -2
  3. package/dist/components/CodeView.d.ts.map +1 -1
  4. package/dist/components/CodeView.js +24 -19
  5. package/dist/components/CodeView.js.map +1 -1
  6. package/dist/components/File.d.ts +31 -9
  7. package/dist/components/File.d.ts.map +1 -1
  8. package/dist/components/File.js +176 -90
  9. package/dist/components/File.js.map +1 -1
  10. package/dist/components/FileDiff.d.ts +32 -9
  11. package/dist/components/FileDiff.d.ts.map +1 -1
  12. package/dist/components/FileDiff.js +225 -131
  13. package/dist/components/FileDiff.js.map +1 -1
  14. package/dist/components/FileStream.d.ts +6 -4
  15. package/dist/components/FileStream.d.ts.map +1 -1
  16. package/dist/components/FileStream.js +49 -36
  17. package/dist/components/FileStream.js.map +1 -1
  18. package/dist/components/UnresolvedFile.d.ts +14 -4
  19. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  20. package/dist/components/UnresolvedFile.js +35 -16
  21. package/dist/components/UnresolvedFile.js.map +1 -1
  22. package/dist/components/VirtualizedFile.d.ts +3 -2
  23. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  24. package/dist/components/VirtualizedFile.js +28 -20
  25. package/dist/components/VirtualizedFile.js.map +1 -1
  26. package/dist/components/VirtualizedFileDiff.d.ts +3 -2
  27. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  28. package/dist/components/VirtualizedFileDiff.js +31 -24
  29. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  30. package/dist/constants.d.ts +4 -2
  31. package/dist/constants.d.ts.map +1 -1
  32. package/dist/constants.js +3 -1
  33. package/dist/constants.js.map +1 -1
  34. package/dist/editor/editor.d.ts +2 -1
  35. package/dist/editor/editor.d.ts.map +1 -1
  36. package/dist/editor/editor.js +5 -1
  37. package/dist/editor/editor.js.map +1 -1
  38. package/dist/editor/platform.d.ts +1 -1
  39. package/dist/editor/platform.js +5 -4
  40. package/dist/editor/platform.js.map +1 -1
  41. package/dist/editor/selection.d.ts +2 -2
  42. package/dist/editor/selection.d.ts.map +1 -1
  43. package/dist/editor/selection.js +31 -6
  44. package/dist/editor/selection.js.map +1 -1
  45. package/dist/editor/tokenizer.d.ts +6 -4
  46. package/dist/editor/tokenizer.d.ts.map +1 -1
  47. package/dist/editor/tokenizer.js +25 -470
  48. package/dist/editor/tokenizer.js.map +1 -1
  49. package/dist/highlighter/DiffsEditorTokenizer.d.ts +16 -0
  50. package/dist/highlighter/DiffsEditorTokenizer.d.ts.map +1 -0
  51. package/dist/highlighter/DiffsEditorTokenizer.js +0 -0
  52. package/dist/highlighter/DiffsHighlighter.d.ts +41 -0
  53. package/dist/highlighter/DiffsHighlighter.d.ts.map +1 -0
  54. package/dist/highlighter/DiffsHighlighter.js +39 -0
  55. package/dist/highlighter/DiffsHighlighter.js.map +1 -0
  56. package/dist/highlighter/backends/highlights.d.ts +26 -0
  57. package/dist/highlighter/backends/highlights.d.ts.map +1 -0
  58. package/dist/highlighter/backends/highlights.js +71 -0
  59. package/dist/highlighter/backends/highlights.js.map +1 -0
  60. package/dist/highlighter/backends/shiki.d.ts +27 -0
  61. package/dist/highlighter/backends/shiki.d.ts.map +1 -0
  62. package/dist/highlighter/backends/shiki.js +107 -0
  63. package/dist/highlighter/backends/shiki.js.map +1 -0
  64. package/dist/highlighter/highlighterType.d.ts +13 -0
  65. package/dist/highlighter/highlighterType.d.ts.map +1 -0
  66. package/dist/highlighter/highlighterType.js +32 -0
  67. package/dist/highlighter/highlighterType.js.map +1 -0
  68. package/dist/highlighter/highlights-editor.d.ts +24 -0
  69. package/dist/highlighter/highlights-editor.d.ts.map +1 -0
  70. package/dist/highlighter/highlights-editor.js +166 -0
  71. package/dist/highlighter/highlights-editor.js.map +1 -0
  72. package/dist/highlighter/highlights-stream.d.ts +20 -0
  73. package/dist/highlighter/highlights-stream.d.ts.map +1 -0
  74. package/dist/highlighter/highlights-stream.js +93 -0
  75. package/dist/highlighter/highlights-stream.js.map +1 -0
  76. package/dist/highlighter/languages/areLanguagesAttached.d.ts +2 -1
  77. package/dist/highlighter/languages/areLanguagesAttached.d.ts.map +1 -1
  78. package/dist/highlighter/languages/areLanguagesAttached.js +4 -6
  79. package/dist/highlighter/languages/areLanguagesAttached.js.map +1 -1
  80. package/dist/highlighter/languages/attachResolvedLanguages.d.ts +6 -1
  81. package/dist/highlighter/languages/attachResolvedLanguages.d.ts.map +1 -1
  82. package/dist/highlighter/languages/attachResolvedLanguages.js +6 -11
  83. package/dist/highlighter/languages/attachResolvedLanguages.js.map +1 -1
  84. package/dist/highlighter/languages/constants.d.ts +1 -1
  85. package/dist/highlighter/languages/getResolvedLanguages.d.ts +1 -1
  86. package/dist/highlighter/languages/getResolvedOrResolveLanguage.d.ts +1 -1
  87. package/dist/highlighter/languages/resolveLanguage.d.ts +1 -1
  88. package/dist/highlighter/languages/resolveLanguage.d.ts.map +1 -1
  89. package/dist/highlighter/languages/resolveLanguage.js +19 -16
  90. package/dist/highlighter/languages/resolveLanguage.js.map +1 -1
  91. package/dist/highlighter/languages/resolveLanguages.d.ts +1 -1
  92. package/dist/highlighter/shared_highlighter.d.ts +24 -9
  93. package/dist/highlighter/shared_highlighter.d.ts.map +1 -1
  94. package/dist/highlighter/shared_highlighter.js +59 -47
  95. package/dist/highlighter/shared_highlighter.js.map +1 -1
  96. package/dist/highlighter/shiki-editor.d.ts +25 -0
  97. package/dist/highlighter/shiki-editor.d.ts.map +1 -0
  98. package/dist/highlighter/shiki-editor.js +483 -0
  99. package/dist/highlighter/shiki-editor.js.map +1 -0
  100. package/dist/highlighter/shiki-stream.d.ts +20 -0
  101. package/dist/highlighter/shiki-stream.d.ts.map +1 -0
  102. package/dist/highlighter/shiki-stream.js +60 -0
  103. package/dist/highlighter/shiki-stream.js.map +1 -0
  104. package/dist/highlighter/stream-tokenizer.d.ts +40 -0
  105. package/dist/highlighter/stream-tokenizer.d.ts.map +1 -0
  106. package/dist/highlighter/stream-tokenizer.js +70 -0
  107. package/dist/highlighter/stream-tokenizer.js.map +1 -0
  108. package/dist/highlighter/themes/areThemesAttached.d.ts +3 -2
  109. package/dist/highlighter/themes/areThemesAttached.d.ts.map +1 -1
  110. package/dist/highlighter/themes/areThemesAttached.js +5 -4
  111. package/dist/highlighter/themes/areThemesAttached.js.map +1 -1
  112. package/dist/highlighter/themes/attachResolvedThemes.d.ts +5 -2
  113. package/dist/highlighter/themes/attachResolvedThemes.d.ts.map +1 -1
  114. package/dist/highlighter/themes/attachResolvedThemes.js +4 -16
  115. package/dist/highlighter/themes/attachResolvedThemes.js.map +1 -1
  116. package/dist/highlighter/themes/cleanUpResolvedThemes.d.ts +3 -1
  117. package/dist/highlighter/themes/cleanUpResolvedThemes.d.ts.map +1 -1
  118. package/dist/highlighter/themes/cleanUpResolvedThemes.js +8 -5
  119. package/dist/highlighter/themes/cleanUpResolvedThemes.js.map +1 -1
  120. package/dist/highlighter/themes/createCSSVariablesTheme.d.ts +7 -0
  121. package/dist/highlighter/themes/createCSSVariablesTheme.d.ts.map +1 -0
  122. package/dist/highlighter/themes/createCSSVariablesTheme.js +89 -0
  123. package/dist/highlighter/themes/createCSSVariablesTheme.js.map +1 -0
  124. package/dist/highlighter/themes/createCachedLoader.d.ts +5 -0
  125. package/dist/highlighter/themes/createCachedLoader.d.ts.map +1 -0
  126. package/dist/highlighter/themes/createCachedLoader.js +15 -0
  127. package/dist/highlighter/themes/createCachedLoader.js.map +1 -0
  128. package/dist/highlighter/themes/getResolvedOrResolveTheme.d.ts +3 -2
  129. package/dist/highlighter/themes/getResolvedOrResolveTheme.d.ts.map +1 -1
  130. package/dist/highlighter/themes/getResolvedOrResolveTheme.js +4 -4
  131. package/dist/highlighter/themes/getResolvedOrResolveTheme.js.map +1 -1
  132. package/dist/highlighter/themes/getResolvedThemes.d.ts +3 -2
  133. package/dist/highlighter/themes/getResolvedThemes.d.ts.map +1 -1
  134. package/dist/highlighter/themes/getResolvedThemes.js +4 -3
  135. package/dist/highlighter/themes/getResolvedThemes.js.map +1 -1
  136. package/dist/highlighter/themes/hasResolvedThemes.d.ts +2 -2
  137. package/dist/highlighter/themes/hasResolvedThemes.d.ts.map +1 -1
  138. package/dist/highlighter/themes/hasResolvedThemes.js +4 -3
  139. package/dist/highlighter/themes/hasResolvedThemes.js.map +1 -1
  140. package/dist/highlighter/themes/registerCustomCSSVariableTheme.d.ts.map +1 -1
  141. package/dist/highlighter/themes/registerCustomCSSVariableTheme.js +3 -3
  142. package/dist/highlighter/themes/registerCustomCSSVariableTheme.js.map +1 -1
  143. package/dist/highlighter/themes/registerCustomTheme.d.ts +9 -4
  144. package/dist/highlighter/themes/registerCustomTheme.d.ts.map +1 -1
  145. package/dist/highlighter/themes/registerCustomTheme.js +8 -16
  146. package/dist/highlighter/themes/registerCustomTheme.js.map +1 -1
  147. package/dist/highlighter/themes/resolveTheme.d.ts +3 -2
  148. package/dist/highlighter/themes/resolveTheme.d.ts.map +1 -1
  149. package/dist/highlighter/themes/resolveTheme.js +4 -7
  150. package/dist/highlighter/themes/resolveTheme.js.map +1 -1
  151. package/dist/highlighter/themes/resolveThemes.d.ts +3 -2
  152. package/dist/highlighter/themes/resolveThemes.d.ts.map +1 -1
  153. package/dist/highlighter/themes/resolveThemes.js +4 -7
  154. package/dist/highlighter/themes/resolveThemes.js.map +1 -1
  155. package/dist/highlighter/themes/themeResolver.d.ts +10 -4
  156. package/dist/highlighter/themes/themeResolver.d.ts.map +1 -1
  157. package/dist/highlighter/themes/themeResolver.js +141 -2
  158. package/dist/highlighter/themes/themeResolver.js.map +1 -1
  159. package/dist/highlighter/themes/types.d.ts +23 -0
  160. package/dist/highlighter/themes/types.d.ts.map +1 -0
  161. package/dist/highlighter/themes/types.js +0 -0
  162. package/dist/highlighter/tokenizer-types.d.ts +35 -0
  163. package/dist/highlighter/tokenizer-types.d.ts.map +1 -0
  164. package/dist/highlighter/tokenizer-types.js +0 -0
  165. package/dist/highlighter/types.d.ts +55 -0
  166. package/dist/highlighter/types.d.ts.map +1 -0
  167. package/dist/highlighter/types.js +0 -0
  168. package/dist/index.d.ts +22 -13
  169. package/dist/index.js +21 -18
  170. package/dist/managers/InteractionManager.d.ts.map +1 -1
  171. package/dist/managers/InteractionManager.js +2 -2
  172. package/dist/managers/InteractionManager.js.map +1 -1
  173. package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts +9 -1
  174. package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts.map +1 -1
  175. package/dist/react/CodeView.d.ts +4 -3
  176. package/dist/react/CodeView.d.ts.map +1 -1
  177. package/dist/react/CodeView.js +47 -38
  178. package/dist/react/CodeView.js.map +1 -1
  179. package/dist/react/File.js +3 -3
  180. package/dist/react/File.js.map +1 -1
  181. package/dist/react/FileDiff.js +3 -3
  182. package/dist/react/FileDiff.js.map +1 -1
  183. package/dist/react/MultiFileDiff.js +2 -2
  184. package/dist/react/MultiFileDiff.js.map +1 -1
  185. package/dist/react/PatchDiff.js +3 -3
  186. package/dist/react/PatchDiff.js.map +1 -1
  187. package/dist/react/UnresolvedFile.js +2 -2
  188. package/dist/react/UnresolvedFile.js.map +1 -1
  189. package/dist/react/index.d.ts +9 -4
  190. package/dist/react/types.d.ts +4 -2
  191. package/dist/react/types.d.ts.map +1 -1
  192. package/dist/react/utils/renderDiffChildren.js +1 -1
  193. package/dist/react/utils/renderDiffChildren.js.map +1 -1
  194. package/dist/react/utils/renderFileChildren.js +1 -1
  195. package/dist/react/utils/renderFileChildren.js.map +1 -1
  196. package/dist/react/utils/useFileDiffInstance.d.ts +1 -0
  197. package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
  198. package/dist/react/utils/useFileDiffInstance.js +29 -24
  199. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  200. package/dist/react/utils/useFileInstance.d.ts +2 -0
  201. package/dist/react/utils/useFileInstance.d.ts.map +1 -1
  202. package/dist/react/utils/useFileInstance.js +38 -28
  203. package/dist/react/utils/useFileInstance.js.map +1 -1
  204. package/dist/react/utils/useForceUpdate.d.ts +5 -0
  205. package/dist/react/utils/useForceUpdate.d.ts.map +1 -0
  206. package/dist/react/utils/useForceUpdate.js +27 -0
  207. package/dist/react/utils/useForceUpdate.js.map +1 -0
  208. package/dist/react/utils/useNextRenderData.d.ts +9 -0
  209. package/dist/react/utils/useNextRenderData.d.ts.map +1 -0
  210. package/dist/react/utils/useNextRenderData.js +9 -0
  211. package/dist/react/utils/useNextRenderData.js.map +1 -0
  212. package/dist/react/utils/useUnresolvedFileInstance.d.ts +1 -0
  213. package/dist/react/utils/useUnresolvedFileInstance.d.ts.map +1 -1
  214. package/dist/react/utils/useUnresolvedFileInstance.js +26 -11
  215. package/dist/react/utils/useUnresolvedFileInstance.js.map +1 -1
  216. package/dist/renderers/DiffHunksRenderer.d.ts +4 -2
  217. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  218. package/dist/renderers/DiffHunksRenderer.js +82 -43
  219. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  220. package/dist/renderers/FileRenderer.d.ts +6 -2
  221. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  222. package/dist/renderers/FileRenderer.js +77 -43
  223. package/dist/renderers/FileRenderer.js.map +1 -1
  224. package/dist/renderers/UnresolvedFileHunksRenderer.d.ts.map +1 -1
  225. package/dist/renderers/UnresolvedFileHunksRenderer.js +1 -1
  226. package/dist/renderers/UnresolvedFileHunksRenderer.js.map +1 -1
  227. package/dist/shiki-stream/index.d.ts +3 -3
  228. package/dist/shiki-stream/index.js +1 -2
  229. package/dist/shiki-stream/stream.d.ts +4 -4
  230. package/dist/shiki-stream/stream.d.ts.map +1 -1
  231. package/dist/shiki-stream/stream.js +20 -9
  232. package/dist/shiki-stream/stream.js.map +1 -1
  233. package/dist/shiki-stream/types.d.ts +7 -38
  234. package/dist/shiki-stream/types.d.ts.map +1 -1
  235. package/dist/ssr/index.d.ts +7 -2
  236. package/dist/ssr/renderHTML.js +2 -2
  237. package/dist/ssr/renderHTML.js.map +1 -1
  238. package/dist/style.js +1 -1
  239. package/dist/style.js.map +1 -1
  240. package/dist/types.d.ts +20 -11
  241. package/dist/types.d.ts.map +1 -1
  242. package/dist/utils/canUseWASM.d.ts +13 -0
  243. package/dist/utils/canUseWASM.d.ts.map +1 -0
  244. package/dist/utils/canUseWASM.js +59 -0
  245. package/dist/utils/canUseWASM.js.map +1 -0
  246. package/dist/utils/createSpanNodeFromToken.d.ts +3 -2
  247. package/dist/utils/createSpanNodeFromToken.d.ts.map +1 -1
  248. package/dist/utils/createSpanNodeFromToken.js +4 -5
  249. package/dist/utils/createSpanNodeFromToken.js.map +1 -1
  250. package/dist/utils/cssWrappers.d.ts.map +1 -1
  251. package/dist/utils/cssWrappers.js +12 -0
  252. package/dist/utils/cssWrappers.js.map +1 -1
  253. package/dist/utils/getCodeViewItemRenderData.d.ts +10 -0
  254. package/dist/utils/getCodeViewItemRenderData.d.ts.map +1 -0
  255. package/dist/utils/getCodeViewItemRenderData.js +19 -0
  256. package/dist/utils/getCodeViewItemRenderData.js.map +1 -0
  257. package/dist/utils/getHighlighterOptions.d.ts.map +1 -1
  258. package/dist/utils/getHighlighterOptions.js +3 -2
  259. package/dist/utils/getHighlighterOptions.js.map +1 -1
  260. package/dist/utils/getHighlighterThemeStyles.d.ts +2 -1
  261. package/dist/utils/getHighlighterThemeStyles.d.ts.map +1 -1
  262. package/dist/utils/getHighlighterThemeStyles.js +13 -3
  263. package/dist/utils/getHighlighterThemeStyles.js.map +1 -1
  264. package/dist/utils/getTokenOptions.d.ts +7 -0
  265. package/dist/utils/getTokenOptions.d.ts.map +1 -0
  266. package/dist/utils/getTokenOptions.js +16 -0
  267. package/dist/utils/getTokenOptions.js.map +1 -0
  268. package/dist/utils/hastToHtml.d.ts +10 -0
  269. package/dist/utils/hastToHtml.d.ts.map +1 -0
  270. package/dist/utils/hastToHtml.js +125 -0
  271. package/dist/utils/hastToHtml.js.map +1 -0
  272. package/dist/utils/hydratePartialDiff.js +4 -0
  273. package/dist/utils/hydratePartialDiff.js.map +1 -1
  274. package/dist/utils/parseDiffDecorations.d.ts +2 -1
  275. package/dist/utils/parseDiffDecorations.d.ts.map +1 -1
  276. package/dist/utils/parseMergeConflictDiffFromFile.d.ts.map +1 -1
  277. package/dist/utils/parseMergeConflictDiffFromFile.js +2 -0
  278. package/dist/utils/parseMergeConflictDiffFromFile.js.map +1 -1
  279. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  280. package/dist/utils/parsePatchFiles.js +24 -4
  281. package/dist/utils/parsePatchFiles.js.map +1 -1
  282. package/dist/utils/renderDiffWithHighlighter.d.ts +3 -2
  283. package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
  284. package/dist/utils/renderDiffWithHighlighter.js +33 -48
  285. package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
  286. package/dist/utils/renderFileWithHighlighter.d.ts +3 -2
  287. package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
  288. package/dist/utils/renderFileWithHighlighter.js +10 -26
  289. package/dist/utils/renderFileWithHighlighter.js.map +1 -1
  290. package/dist/utils/renderTokenLines.d.ts +22 -0
  291. package/dist/utils/renderTokenLines.d.ts.map +1 -0
  292. package/dist/utils/renderTokenLines.js +250 -0
  293. package/dist/utils/renderTokenLines.js.map +1 -0
  294. package/dist/utils/resolvePreferredHighlighter.d.ts +13 -0
  295. package/dist/utils/resolvePreferredHighlighter.d.ts.map +1 -0
  296. package/dist/utils/resolvePreferredHighlighter.js +11 -0
  297. package/dist/utils/resolvePreferredHighlighter.js.map +1 -0
  298. package/dist/utils/resolveRegion.js +20 -10
  299. package/dist/utils/resolveRegion.js.map +1 -1
  300. package/dist/utils/setDeferredArrayItem.d.ts +5 -0
  301. package/dist/utils/setDeferredArrayItem.d.ts.map +1 -0
  302. package/dist/utils/setDeferredArrayItem.js +39 -0
  303. package/dist/utils/setDeferredArrayItem.js.map +1 -0
  304. package/dist/utils/tokenStyle.d.ts +11 -0
  305. package/dist/utils/tokenStyle.d.ts.map +1 -0
  306. package/dist/utils/tokenStyle.js +32 -0
  307. package/dist/utils/tokenStyle.js.map +1 -0
  308. package/dist/utils/tokensToHtml.d.ts +11 -0
  309. package/dist/utils/tokensToHtml.d.ts.map +1 -0
  310. package/dist/utils/tokensToHtml.js +48 -0
  311. package/dist/utils/tokensToHtml.js.map +1 -0
  312. package/dist/utils/updateDiffHunks.d.ts +2 -2
  313. package/dist/utils/updateDiffHunks.d.ts.map +1 -1
  314. package/dist/utils/updateDiffHunks.js +7 -3
  315. package/dist/utils/updateDiffHunks.js.map +1 -1
  316. package/dist/utils/wrapTokenFragments.js.map +1 -1
  317. package/dist/worker/WorkerPoolManager.d.ts +14 -2
  318. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  319. package/dist/worker/WorkerPoolManager.js +155 -67
  320. package/dist/worker/WorkerPoolManager.js.map +1 -1
  321. package/dist/worker/hastLinesTransport.d.ts +14 -0
  322. package/dist/worker/hastLinesTransport.d.ts.map +1 -0
  323. package/dist/worker/hastLinesTransport.js +156 -0
  324. package/dist/worker/hastLinesTransport.js.map +1 -0
  325. package/dist/worker/highlights-CpZm9DAR.js +317 -0
  326. package/dist/worker/highlights-CpZm9DAR.js.map +1 -0
  327. package/dist/worker/index.d.ts +1 -1
  328. package/dist/worker/shiki-Ci4cdHsM.js +697 -0
  329. package/dist/worker/shiki-Ci4cdHsM.js.map +1 -0
  330. package/dist/worker/stream-tokenizer-DK9xp5M5.js +427 -0
  331. package/dist/worker/stream-tokenizer-DK9xp5M5.js.map +1 -0
  332. package/dist/worker/types.d.ts +16 -3
  333. package/dist/worker/types.d.ts.map +1 -1
  334. package/dist/worker/worker-portable.js +41 -13337
  335. package/dist/worker/worker-portable.js.map +1 -1
  336. package/dist/worker/worker.js +681 -349
  337. package/dist/worker/worker.js.map +1 -1
  338. package/dist/worker/workerMessage.d.ts +24 -0
  339. package/dist/worker/workerMessage.d.ts.map +1 -0
  340. package/dist/worker/workerMessage.js +0 -0
  341. package/package.json +5 -3
  342. package/dist/highlighter/themes/constants.d.ts +0 -5
  343. package/dist/highlighter/themes/constants.d.ts.map +0 -1
  344. package/dist/highlighter/themes/constants.js +0 -6
  345. package/dist/highlighter/themes/constants.js.map +0 -1
  346. package/dist/highlighter/themes/themeResolution.d.ts +0 -7
  347. package/dist/highlighter/themes/themeResolution.d.ts.map +0 -1
  348. package/dist/highlighter/themes/themeResolution.js +0 -21
  349. package/dist/highlighter/themes/themeResolution.js.map +0 -1
  350. package/dist/shiki-stream/tokenizer.d.ts +0 -23
  351. package/dist/shiki-stream/tokenizer.d.ts.map +0 -1
  352. package/dist/shiki-stream/tokenizer.js +0 -72
  353. package/dist/shiki-stream/tokenizer.js.map +0 -1
  354. package/dist/utils/createTransformerWithState.d.ts +0 -12
  355. package/dist/utils/createTransformerWithState.d.ts.map +0 -1
  356. package/dist/utils/createTransformerWithState.js +0 -89
  357. package/dist/utils/createTransformerWithState.js.map +0 -1
  358. package/dist/worker/wasm-B9ZqxnKj.js +0 -8
  359. package/dist/worker/wasm-B9ZqxnKj.js.map +0 -1
@@ -37,7 +37,8 @@ interface DiffBasePropsReact<LAnnotation, Caret> {
37
37
  metrics?: VirtualFileMetrics;
38
38
  lineAnnotations?: DiffLineAnnotation<LAnnotation>[];
39
39
  selectedLines?: SelectedLineRange | null;
40
- renderAnnotation?(annotations: DiffLineAnnotation<LAnnotation>): ReactNode;
40
+ /** Receives the matching diff. */
41
+ renderAnnotation?(annotation: DiffLineAnnotation<LAnnotation>, fileDiff: FileDiffMetadata): ReactNode;
41
42
  renderCustomHeader?(fileDiff: FileDiffMetadata): ReactNode;
42
43
  renderHeaderPrefix?(fileDiff: FileDiffMetadata): ReactNode;
43
44
  renderHeaderFilenameSuffix?(fileDiff: FileDiffMetadata): ReactNode;
@@ -72,7 +73,8 @@ interface FileProps<LAnnotation, Caret> {
72
73
  metrics?: VirtualFileMetrics;
73
74
  lineAnnotations?: LineAnnotation<LAnnotation>[];
74
75
  selectedLines?: SelectedLineRange | null;
75
- renderAnnotation?(annotations: LineAnnotation<LAnnotation>): ReactNode;
76
+ /** Receives the matching file. */
77
+ renderAnnotation?(annotation: LineAnnotation<LAnnotation>, file: FileContents): ReactNode;
76
78
  renderCustomHeader?(file: FileContents): ReactNode;
77
79
  renderHeaderPrefix?(file: FileContents): ReactNode;
78
80
  renderHeaderFilenameSuffix?(file: FileContents): ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/react/types.ts"],"mappings":";;;;;;;;KAuBK;KAEO,gBAAgB,aAAa,SAAS,KAChD,kBAAqB,aAAa,QAClC;KAGU,YAAY,aAAa,SAAS,KAC5C,cAAiB,aAAa,QAC9B;UAGe,mBAAmB,aAAa;EAC/C,UAAU,gBAAgB,aAAa;;EAEvC;;EAEA,gBAAgB,2BAA2B,aAAa;;EAExD;;;;;;;;;;EAUA,eAAe,0BAA0B,aAAa;;;;;;;EAOtD,iBAAiB,4BAA4B,aAAa;EAC1D,UAAU;EACV,kBAAkB,mBAAmB;EACrC,gBAAgB;EAChB,kBAAkB,aAAa,mBAAmB,eAAe;EACjE,oBAAoB,UAAU,mBAAmB;EACjD,oBAAoB,UAAU,mBAAmB;EACjD,4BAA4B,UAAU,mBAAmB;EACzD,sBAAsB,UAAU,mBAAmB;EACnD,qBACE,sBAAsB,2CACrB;EACH;EACA,QAAQ;EACR;;UAGe,UAAU,aAAa;EACtC,MAAM;EACN,UAAU,YAAY,aAAa;;EAEnC;;EAEA,gBAAgB,sBAAsB,aAAa;;EAEnD;;;;;;EAMA,eAAe,sBAAsB,aAAa;;;;;;;EAOlD,iBAAiB,wBAAwB,aAAa;EACtD,UAAU;EACV,kBAAkB,eAAe;EACjC,gBAAgB;EAChB,kBAAkB,aAAa,eAAe,eAAe;EAC7D,oBAAoB,MAAM,eAAe;EACzC,oBAAoB,MAAM,eAAe;EACzC,4BAA4B,MAAM,eAAe;EACjD,sBAAsB,MAAM,eAAe;EAC3C,qBACE,sBAAsB,2CACrB;EACH;EACA,QAAQ;EACR;EACA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/react/types.ts"],"mappings":";;;;;;;;KAuBK;KAEO,gBAAgB,aAAa,SAAS,KAChD,kBAAqB,aAAa,QAClC;KAGU,YAAY,aAAa,SAAS,KAC5C,cAAiB,aAAa,QAC9B;UAGe,mBAAmB,aAAa;EAC/C,UAAU,gBAAgB,aAAa;;EAEvC;;EAEA,gBAAgB,2BAA2B,aAAa;;EAExD;;;;;;;;;;EAUA,eAAe,0BAA0B,aAAa;;;;;;;EAOtD,iBAAiB,4BAA4B,aAAa;EAC1D,UAAU;EACV,kBAAkB,mBAAmB;EACrC,gBAAgB;;EAEhB,kBACE,YAAY,mBAAmB,cAC/B,UAAU,mBACT;EACH,oBAAoB,UAAU,mBAAmB;EACjD,oBAAoB,UAAU,mBAAmB;EACjD,4BAA4B,UAAU,mBAAmB;EACzD,sBAAsB,UAAU,mBAAmB;EACnD,qBACE,sBAAsB,2CACrB;EACH;EACA,QAAQ;EACR;;UAGe,UAAU,aAAa;EACtC,MAAM;EACN,UAAU,YAAY,aAAa;;EAEnC;;EAEA,gBAAgB,sBAAsB,aAAa;;EAEnD;;;;;;EAMA,eAAe,sBAAsB,aAAa;;;;;;;EAOlD,iBAAiB,wBAAwB,aAAa;EACtD,UAAU;EACV,kBAAkB,eAAe;EACjC,gBAAgB;;EAEhB,kBACE,YAAY,eAAe,cAC3B,MAAM,eACL;EACH,oBAAoB,MAAM,eAAe;EACzC,oBAAoB,MAAM,eAAe;EACzC,4BAA4B,MAAM,eAAe;EACjD,sBAAsB,MAAM,eAAe;EAC3C,qBACE,sBAAsB,2CACrB;EACH;EACA,QAAQ;EACR;EACA"}
@@ -30,7 +30,7 @@ function renderDiffChildren({ fileDiff, actions, renderCustomHeader, renderHeade
30
30
  ] }),
31
31
  renderAnnotation != null && lineAnnotations?.map((annotation, index) => /* @__PURE__ */ jsx("div", {
32
32
  slot: getAnnotationSlotName(annotation),
33
- children: renderAnnotation(annotation)
33
+ children: renderAnnotation(annotation, fileDiff)
34
34
  }, index)),
35
35
  actions != null && renderMergeConflictUtility != null && getInstance != null && actions.map((action) => {
36
36
  if (action == null) return;
@@ -1 +1 @@
1
- {"version":3,"file":"renderDiffChildren.js","names":[],"sources":["../../../src/react/utils/renderDiffChildren.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport {\n CUSTOM_HEADER_SLOT_ID,\n HEADER_FILENAME_SUFFIX_SLOT_ID,\n HEADER_METADATA_SLOT_ID,\n HEADER_PREFIX_SLOT_ID,\n} from '../../constants';\nimport type { GetHoveredLineResult } from '../../managers/InteractionManager';\nimport type { DiffLineAnnotation, FileDiffMetadata } from '../../types';\nimport { getLineAnnotationName } from '../../utils/getLineAnnotationName';\nimport { getMergeConflictActionSlotName } from '../../utils/getMergeConflictActionSlotName';\nimport {\n getMergeConflictActionAnchor,\n type MergeConflictDiffAction,\n} from '../../utils/parseMergeConflictDiffFromFile';\nimport { GutterUtilitySlotStyles, MergeConflictSlotStyles } from '../constants';\nimport type { DiffBasePropsReact } from '../types';\n\ninterface RenderDiffChildrenProps<LAnnotation, Caret, T> {\n fileDiff: FileDiffMetadata;\n actions?: (MergeConflictDiffAction | undefined)[];\n renderCustomHeader: DiffBasePropsReact<\n LAnnotation,\n Caret\n >['renderCustomHeader'];\n renderHeaderPrefix: DiffBasePropsReact<\n LAnnotation,\n Caret\n >['renderHeaderPrefix'];\n renderHeaderFilenameSuffix?: DiffBasePropsReact<\n LAnnotation,\n Caret\n >['renderHeaderFilenameSuffix'];\n renderHeaderMetadata: DiffBasePropsReact<\n LAnnotation,\n Caret\n >['renderHeaderMetadata'];\n renderAnnotation: DiffBasePropsReact<LAnnotation, Caret>['renderAnnotation'];\n renderGutterUtility: DiffBasePropsReact<\n LAnnotation,\n Caret\n >['renderGutterUtility'];\n renderMergeConflictUtility?(\n action: MergeConflictDiffAction,\n getInstance: () => T | undefined\n ): ReactNode;\n lineAnnotations: DiffBasePropsReact<LAnnotation, Caret>['lineAnnotations'];\n getHoveredLine(): GetHoveredLineResult<'diff'> | undefined;\n getInstance?(): T | undefined;\n getAnnotationSlotName?(annotation: DiffLineAnnotation<LAnnotation>): string;\n}\n\nexport function renderDiffChildren<LAnnotation, Caret, T>({\n fileDiff,\n actions,\n renderCustomHeader,\n renderHeaderPrefix,\n renderHeaderFilenameSuffix,\n renderHeaderMetadata,\n renderAnnotation,\n renderGutterUtility,\n renderMergeConflictUtility,\n lineAnnotations,\n getHoveredLine,\n getInstance,\n getAnnotationSlotName = getLineAnnotationName,\n}: RenderDiffChildrenProps<LAnnotation, Caret, T>): ReactNode {\n const customHeader = renderCustomHeader?.(fileDiff);\n const prefix = renderHeaderPrefix?.(fileDiff);\n const suffix = renderHeaderFilenameSuffix?.(fileDiff);\n const metadata = renderHeaderMetadata?.(fileDiff);\n return (\n <>\n {customHeader != null ? (\n <div slot={CUSTOM_HEADER_SLOT_ID}>{customHeader}</div>\n ) : (\n <>\n {prefix != null && <div slot={HEADER_PREFIX_SLOT_ID}>{prefix}</div>}\n {suffix != null && (\n <div slot={HEADER_FILENAME_SUFFIX_SLOT_ID}>{suffix}</div>\n )}\n {metadata != null && (\n <div slot={HEADER_METADATA_SLOT_ID}>{metadata}</div>\n )}\n </>\n )}\n {renderAnnotation != null &&\n lineAnnotations?.map((annotation, index) => (\n <div key={index} slot={getAnnotationSlotName(annotation)}>\n {renderAnnotation(annotation)}\n </div>\n ))}\n {actions != null &&\n renderMergeConflictUtility != null &&\n getInstance != null &&\n actions.map((action) => {\n if (action == null) {\n return undefined;\n }\n const slot = getSlotName(action, fileDiff);\n return (\n <div key={slot} slot={slot} style={MergeConflictSlotStyles}>\n {renderMergeConflictUtility(action, getInstance)}\n </div>\n );\n })}\n {renderGutterUtility != null && (\n <div slot=\"gutter-utility-slot\" style={GutterUtilitySlotStyles}>\n {renderGutterUtility(getHoveredLine)}\n </div>\n )}\n </>\n );\n}\n\nfunction getSlotName(\n action: MergeConflictDiffAction,\n fileDiff: FileDiffMetadata\n): string | undefined {\n const anchor = getMergeConflictActionAnchor(action, fileDiff);\n return anchor != null\n ? getMergeConflictActionSlotName({\n hunkIndex: anchor.hunkIndex,\n lineIndex: anchor.lineIndex,\n conflictIndex: action.conflictIndex,\n })\n : undefined;\n}\n"],"mappings":";;;;;;;AAqDA,SAAgB,mBAA0C,EACxD,UACA,SACA,oBACA,oBACA,4BACA,sBACA,kBACA,qBACA,4BACA,iBACA,gBACA,aACA,wBAAwB,yBACoC;CAC5D,MAAM,eAAe,qBAAqB,QAAQ;CAClD,MAAM,SAAS,qBAAqB,QAAQ;CAC5C,MAAM,SAAS,6BAA6B,QAAQ;CACpD,MAAM,WAAW,uBAAuB,QAAQ;CAChD,OACE,qBAAA,UAAA,EAAA,UAAA;EACG,gBAAgB,OACf,oBAAC,OAAD;GAAK,MAAM;GAAwB,UAAA;EAAkB,CAAA,IAErD,qBAAA,UAAA,EAAA,UAAA;GACG,UAAU,QAAQ,oBAAC,OAAD;IAAK,MAAA;IAA8B,UAAA;GAAY,CAAA;GACjE,UAAU,QACT,oBAAC,OAAD;IAAK,MAAA;IAAuC,UAAA;GAAY,CAAA;GAEzD,YAAY,QACX,oBAAC,OAAD;IAAK,MAAA;IAAgC,UAAA;GAAc,CAAA;EAErD,EAAA,CAAA;EAEH,oBAAoB,QACnB,iBAAiB,KAAK,YAAY,UAChC,oBAAC,OAAD;GAAiB,MAAM,sBAAsB,UAAU;GACpD,UAAA,iBAAiB,UAAU;EACzB,GAFK,KAEL,CACN;EACF,WAAW,QACV,8BAA8B,QAC9B,eAAe,QACf,QAAQ,KAAK,WAAW;GACtB,IAAI,UAAU,MACZ;GAEF,MAAM,OAAO,YAAY,QAAQ,QAAQ;GACzC,OACE,oBAAC,OAAD;IAAsB;IAAM,OAAO;IAChC,UAAA,2BAA2B,QAAQ,WAAW;GAC5C,GAFK,IAEL;EAET,CAAC;EACF,uBAAuB,QACtB,oBAAC,OAAD;GAAK,MAAK;GAAsB,OAAO;GACpC,UAAA,oBAAoB,cAAc;EAChC,CAAA;CAEP,EAAA,CAAA;AAEN;AAEA,SAAS,YACP,QACA,UACoB;CACpB,MAAM,SAAS,6BAA6B,QAAQ,QAAQ;CAC5D,OAAO,UAAU,OACb,+BAA+B;EAC7B,WAAW,OAAO;EAClB,WAAW,OAAO;EAClB,eAAe,OAAO;CACxB,CAAC,IACD,KAAA;AACN"}
1
+ {"version":3,"file":"renderDiffChildren.js","names":[],"sources":["../../../src/react/utils/renderDiffChildren.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport {\n CUSTOM_HEADER_SLOT_ID,\n HEADER_FILENAME_SUFFIX_SLOT_ID,\n HEADER_METADATA_SLOT_ID,\n HEADER_PREFIX_SLOT_ID,\n} from '../../constants';\nimport type { GetHoveredLineResult } from '../../managers/InteractionManager';\nimport type { DiffLineAnnotation, FileDiffMetadata } from '../../types';\nimport { getLineAnnotationName } from '../../utils/getLineAnnotationName';\nimport { getMergeConflictActionSlotName } from '../../utils/getMergeConflictActionSlotName';\nimport {\n getMergeConflictActionAnchor,\n type MergeConflictDiffAction,\n} from '../../utils/parseMergeConflictDiffFromFile';\nimport { GutterUtilitySlotStyles, MergeConflictSlotStyles } from '../constants';\nimport type { DiffBasePropsReact } from '../types';\n\ninterface RenderDiffChildrenProps<LAnnotation, Caret, T> {\n fileDiff: FileDiffMetadata;\n actions?: (MergeConflictDiffAction | undefined)[];\n renderCustomHeader: DiffBasePropsReact<\n LAnnotation,\n Caret\n >['renderCustomHeader'];\n renderHeaderPrefix: DiffBasePropsReact<\n LAnnotation,\n Caret\n >['renderHeaderPrefix'];\n renderHeaderFilenameSuffix?: DiffBasePropsReact<\n LAnnotation,\n Caret\n >['renderHeaderFilenameSuffix'];\n renderHeaderMetadata: DiffBasePropsReact<\n LAnnotation,\n Caret\n >['renderHeaderMetadata'];\n renderAnnotation: DiffBasePropsReact<LAnnotation, Caret>['renderAnnotation'];\n renderGutterUtility: DiffBasePropsReact<\n LAnnotation,\n Caret\n >['renderGutterUtility'];\n renderMergeConflictUtility?(\n action: MergeConflictDiffAction,\n getInstance: () => T | undefined\n ): ReactNode;\n lineAnnotations: DiffBasePropsReact<LAnnotation, Caret>['lineAnnotations'];\n getHoveredLine(): GetHoveredLineResult<'diff'> | undefined;\n getInstance?(): T | undefined;\n getAnnotationSlotName?(annotation: DiffLineAnnotation<LAnnotation>): string;\n}\n\nexport function renderDiffChildren<LAnnotation, Caret, T>({\n fileDiff,\n actions,\n renderCustomHeader,\n renderHeaderPrefix,\n renderHeaderFilenameSuffix,\n renderHeaderMetadata,\n renderAnnotation,\n renderGutterUtility,\n renderMergeConflictUtility,\n lineAnnotations,\n getHoveredLine,\n getInstance,\n getAnnotationSlotName = getLineAnnotationName,\n}: RenderDiffChildrenProps<LAnnotation, Caret, T>): ReactNode {\n const customHeader = renderCustomHeader?.(fileDiff);\n const prefix = renderHeaderPrefix?.(fileDiff);\n const suffix = renderHeaderFilenameSuffix?.(fileDiff);\n const metadata = renderHeaderMetadata?.(fileDiff);\n return (\n <>\n {customHeader != null ? (\n <div slot={CUSTOM_HEADER_SLOT_ID}>{customHeader}</div>\n ) : (\n <>\n {prefix != null && <div slot={HEADER_PREFIX_SLOT_ID}>{prefix}</div>}\n {suffix != null && (\n <div slot={HEADER_FILENAME_SUFFIX_SLOT_ID}>{suffix}</div>\n )}\n {metadata != null && (\n <div slot={HEADER_METADATA_SLOT_ID}>{metadata}</div>\n )}\n </>\n )}\n {renderAnnotation != null &&\n lineAnnotations?.map((annotation, index) => (\n <div key={index} slot={getAnnotationSlotName(annotation)}>\n {renderAnnotation(annotation, fileDiff)}\n </div>\n ))}\n {actions != null &&\n renderMergeConflictUtility != null &&\n getInstance != null &&\n actions.map((action) => {\n if (action == null) {\n return undefined;\n }\n const slot = getSlotName(action, fileDiff);\n return (\n <div key={slot} slot={slot} style={MergeConflictSlotStyles}>\n {renderMergeConflictUtility(action, getInstance)}\n </div>\n );\n })}\n {renderGutterUtility != null && (\n <div slot=\"gutter-utility-slot\" style={GutterUtilitySlotStyles}>\n {renderGutterUtility(getHoveredLine)}\n </div>\n )}\n </>\n );\n}\n\nfunction getSlotName(\n action: MergeConflictDiffAction,\n fileDiff: FileDiffMetadata\n): string | undefined {\n const anchor = getMergeConflictActionAnchor(action, fileDiff);\n return anchor != null\n ? getMergeConflictActionSlotName({\n hunkIndex: anchor.hunkIndex,\n lineIndex: anchor.lineIndex,\n conflictIndex: action.conflictIndex,\n })\n : undefined;\n}\n"],"mappings":";;;;;;;AAqDA,SAAgB,mBAA0C,EACxD,UACA,SACA,oBACA,oBACA,4BACA,sBACA,kBACA,qBACA,4BACA,iBACA,gBACA,aACA,wBAAwB,yBACoC;CAC5D,MAAM,eAAe,qBAAqB,QAAQ;CAClD,MAAM,SAAS,qBAAqB,QAAQ;CAC5C,MAAM,SAAS,6BAA6B,QAAQ;CACpD,MAAM,WAAW,uBAAuB,QAAQ;CAChD,OACE,qBAAA,UAAA,EAAA,UAAA;EACG,gBAAgB,OACf,oBAAC,OAAD;GAAK,MAAM;GAAwB,UAAA;EAAkB,CAAA,IAErD,qBAAA,UAAA,EAAA,UAAA;GACG,UAAU,QAAQ,oBAAC,OAAD;IAAK,MAAA;IAA8B,UAAA;GAAY,CAAA;GACjE,UAAU,QACT,oBAAC,OAAD;IAAK,MAAA;IAAuC,UAAA;GAAY,CAAA;GAEzD,YAAY,QACX,oBAAC,OAAD;IAAK,MAAA;IAAgC,UAAA;GAAc,CAAA;EAErD,EAAA,CAAA;EAEH,oBAAoB,QACnB,iBAAiB,KAAK,YAAY,UAChC,oBAAC,OAAD;GAAiB,MAAM,sBAAsB,UAAU;GACpD,UAAA,iBAAiB,YAAY,QAAQ;EACnC,GAFK,KAEL,CACN;EACF,WAAW,QACV,8BAA8B,QAC9B,eAAe,QACf,QAAQ,KAAK,WAAW;GACtB,IAAI,UAAU,MACZ;GAEF,MAAM,OAAO,YAAY,QAAQ,QAAQ;GACzC,OACE,oBAAC,OAAD;IAAsB;IAAM,OAAO;IAChC,UAAA,2BAA2B,QAAQ,WAAW;GAC5C,GAFK,IAEL;EAET,CAAC;EACF,uBAAuB,QACtB,oBAAC,OAAD;GAAK,MAAK;GAAsB,OAAO;GACpC,UAAA,oBAAoB,cAAc;EAChC,CAAA;CAEP,EAAA,CAAA;AAEN;AAEA,SAAS,YACP,QACA,UACoB;CACpB,MAAM,SAAS,6BAA6B,QAAQ,QAAQ;CAC5D,OAAO,UAAU,OACb,+BAA+B;EAC7B,WAAW,OAAO;EAClB,WAAW,OAAO;EAClB,eAAe,OAAO;CACxB,CAAC,IACD,KAAA;AACN"}
@@ -28,7 +28,7 @@ function renderFileChildren({ file, renderCustomHeader, renderHeaderPrefix, rend
28
28
  ] }),
29
29
  renderAnnotation != null && lineAnnotations?.map((annotation, index) => /* @__PURE__ */ jsx("div", {
30
30
  slot: getAnnotationSlotName(annotation),
31
- children: renderAnnotation(annotation)
31
+ children: renderAnnotation(annotation, file)
32
32
  }, index)),
33
33
  renderGutterUtility != null && /* @__PURE__ */ jsx("div", {
34
34
  slot: "gutter-utility-slot",
@@ -1 +1 @@
1
- {"version":3,"file":"renderFileChildren.js","names":[],"sources":["../../../src/react/utils/renderFileChildren.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport {\n CUSTOM_HEADER_SLOT_ID,\n HEADER_FILENAME_SUFFIX_SLOT_ID,\n HEADER_METADATA_SLOT_ID,\n HEADER_PREFIX_SLOT_ID,\n} from '../../constants';\nimport type { GetHoveredLineResult } from '../../managers/InteractionManager';\nimport type { FileContents, LineAnnotation } from '../../types';\nimport { getLineAnnotationName } from '../../utils/getLineAnnotationName';\nimport { GutterUtilitySlotStyles } from '../constants';\nimport type { FileProps } from '../types';\n\ninterface RenderFileChildrenProps<LAnnotation, Caret> {\n file: FileContents;\n renderCustomHeader: FileProps<LAnnotation, Caret>['renderCustomHeader'];\n renderHeaderPrefix: FileProps<LAnnotation, Caret>['renderHeaderPrefix'];\n renderHeaderFilenameSuffix?: FileProps<\n LAnnotation,\n Caret\n >['renderHeaderFilenameSuffix'];\n renderHeaderMetadata: FileProps<LAnnotation, Caret>['renderHeaderMetadata'];\n renderAnnotation: FileProps<LAnnotation, Caret>['renderAnnotation'];\n lineAnnotations: FileProps<LAnnotation, Caret>['lineAnnotations'];\n renderGutterUtility: FileProps<LAnnotation, Caret>['renderGutterUtility'];\n getHoveredLine(): GetHoveredLineResult<'file'> | undefined;\n getAnnotationSlotName?(annotation: LineAnnotation<LAnnotation>): string;\n}\n\nexport function renderFileChildren<LAnnotation, Caret>({\n file,\n renderCustomHeader,\n renderHeaderPrefix,\n renderHeaderFilenameSuffix,\n renderHeaderMetadata,\n renderAnnotation,\n lineAnnotations,\n renderGutterUtility,\n getHoveredLine,\n getAnnotationSlotName = getLineAnnotationName,\n}: RenderFileChildrenProps<LAnnotation, Caret>): ReactNode {\n const customHeader = renderCustomHeader?.(file);\n const prefix = renderHeaderPrefix?.(file);\n const suffix = renderHeaderFilenameSuffix?.(file);\n const metadata = renderHeaderMetadata?.(file);\n return (\n <>\n {customHeader != null ? (\n <div slot={CUSTOM_HEADER_SLOT_ID}>{customHeader}</div>\n ) : (\n <>\n {prefix != null && <div slot={HEADER_PREFIX_SLOT_ID}>{prefix}</div>}\n {suffix != null && (\n <div slot={HEADER_FILENAME_SUFFIX_SLOT_ID}>{suffix}</div>\n )}\n {metadata != null && (\n <div slot={HEADER_METADATA_SLOT_ID}>{metadata}</div>\n )}\n </>\n )}\n {renderAnnotation != null &&\n lineAnnotations?.map((annotation, index) => (\n <div key={index} slot={getAnnotationSlotName(annotation)}>\n {renderAnnotation(annotation)}\n </div>\n ))}\n {renderGutterUtility != null && (\n <div slot=\"gutter-utility-slot\" style={GutterUtilitySlotStyles}>\n {renderGutterUtility(getHoveredLine)}\n </div>\n )}\n </>\n );\n}\n"],"mappings":";;;;;AA8BA,SAAgB,mBAAuC,EACrD,MACA,oBACA,oBACA,4BACA,sBACA,kBACA,iBACA,qBACA,gBACA,wBAAwB,yBACiC;CACzD,MAAM,eAAe,qBAAqB,IAAI;CAC9C,MAAM,SAAS,qBAAqB,IAAI;CACxC,MAAM,SAAS,6BAA6B,IAAI;CAChD,MAAM,WAAW,uBAAuB,IAAI;CAC5C,OACE,qBAAA,UAAA,EAAA,UAAA;EACG,gBAAgB,OACf,oBAAC,OAAD;GAAK,MAAM;GAAwB,UAAA;EAAkB,CAAA,IAErD,qBAAA,UAAA,EAAA,UAAA;GACG,UAAU,QAAQ,oBAAC,OAAD;IAAK,MAAA;IAA8B,UAAA;GAAY,CAAA;GACjE,UAAU,QACT,oBAAC,OAAD;IAAK,MAAA;IAAuC,UAAA;GAAY,CAAA;GAEzD,YAAY,QACX,oBAAC,OAAD;IAAK,MAAA;IAAgC,UAAA;GAAc,CAAA;EAErD,EAAA,CAAA;EAEH,oBAAoB,QACnB,iBAAiB,KAAK,YAAY,UAChC,oBAAC,OAAD;GAAiB,MAAM,sBAAsB,UAAU;GACpD,UAAA,iBAAiB,UAAU;EACzB,GAFK,KAEL,CACN;EACF,uBAAuB,QACtB,oBAAC,OAAD;GAAK,MAAK;GAAsB,OAAO;GACpC,UAAA,oBAAoB,cAAc;EAChC,CAAA;CAEP,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"renderFileChildren.js","names":[],"sources":["../../../src/react/utils/renderFileChildren.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport {\n CUSTOM_HEADER_SLOT_ID,\n HEADER_FILENAME_SUFFIX_SLOT_ID,\n HEADER_METADATA_SLOT_ID,\n HEADER_PREFIX_SLOT_ID,\n} from '../../constants';\nimport type { GetHoveredLineResult } from '../../managers/InteractionManager';\nimport type { FileContents, LineAnnotation } from '../../types';\nimport { getLineAnnotationName } from '../../utils/getLineAnnotationName';\nimport { GutterUtilitySlotStyles } from '../constants';\nimport type { FileProps } from '../types';\n\ninterface RenderFileChildrenProps<LAnnotation, Caret> {\n file: FileContents;\n renderCustomHeader: FileProps<LAnnotation, Caret>['renderCustomHeader'];\n renderHeaderPrefix: FileProps<LAnnotation, Caret>['renderHeaderPrefix'];\n renderHeaderFilenameSuffix?: FileProps<\n LAnnotation,\n Caret\n >['renderHeaderFilenameSuffix'];\n renderHeaderMetadata: FileProps<LAnnotation, Caret>['renderHeaderMetadata'];\n renderAnnotation: FileProps<LAnnotation, Caret>['renderAnnotation'];\n lineAnnotations: FileProps<LAnnotation, Caret>['lineAnnotations'];\n renderGutterUtility: FileProps<LAnnotation, Caret>['renderGutterUtility'];\n getHoveredLine(): GetHoveredLineResult<'file'> | undefined;\n getAnnotationSlotName?(annotation: LineAnnotation<LAnnotation>): string;\n}\n\nexport function renderFileChildren<LAnnotation, Caret>({\n file,\n renderCustomHeader,\n renderHeaderPrefix,\n renderHeaderFilenameSuffix,\n renderHeaderMetadata,\n renderAnnotation,\n lineAnnotations,\n renderGutterUtility,\n getHoveredLine,\n getAnnotationSlotName = getLineAnnotationName,\n}: RenderFileChildrenProps<LAnnotation, Caret>): ReactNode {\n const customHeader = renderCustomHeader?.(file);\n const prefix = renderHeaderPrefix?.(file);\n const suffix = renderHeaderFilenameSuffix?.(file);\n const metadata = renderHeaderMetadata?.(file);\n return (\n <>\n {customHeader != null ? (\n <div slot={CUSTOM_HEADER_SLOT_ID}>{customHeader}</div>\n ) : (\n <>\n {prefix != null && <div slot={HEADER_PREFIX_SLOT_ID}>{prefix}</div>}\n {suffix != null && (\n <div slot={HEADER_FILENAME_SUFFIX_SLOT_ID}>{suffix}</div>\n )}\n {metadata != null && (\n <div slot={HEADER_METADATA_SLOT_ID}>{metadata}</div>\n )}\n </>\n )}\n {renderAnnotation != null &&\n lineAnnotations?.map((annotation, index) => (\n <div key={index} slot={getAnnotationSlotName(annotation)}>\n {renderAnnotation(annotation, file)}\n </div>\n ))}\n {renderGutterUtility != null && (\n <div slot=\"gutter-utility-slot\" style={GutterUtilitySlotStyles}>\n {renderGutterUtility(getHoveredLine)}\n </div>\n )}\n </>\n );\n}\n"],"mappings":";;;;;AA8BA,SAAgB,mBAAuC,EACrD,MACA,oBACA,oBACA,4BACA,sBACA,kBACA,iBACA,qBACA,gBACA,wBAAwB,yBACiC;CACzD,MAAM,eAAe,qBAAqB,IAAI;CAC9C,MAAM,SAAS,qBAAqB,IAAI;CACxC,MAAM,SAAS,6BAA6B,IAAI;CAChD,MAAM,WAAW,uBAAuB,IAAI;CAC5C,OACE,qBAAA,UAAA,EAAA,UAAA;EACG,gBAAgB,OACf,oBAAC,OAAD;GAAK,MAAM;GAAwB,UAAA;EAAkB,CAAA,IAErD,qBAAA,UAAA,EAAA,UAAA;GACG,UAAU,QAAQ,oBAAC,OAAD;IAAK,MAAA;IAA8B,UAAA;GAAY,CAAA;GACjE,UAAU,QACT,oBAAC,OAAD;IAAK,MAAA;IAAuC,UAAA;GAAY,CAAA;GAEzD,YAAY,QACX,oBAAC,OAAD;IAAK,MAAA;IAAgC,UAAA;GAAc,CAAA;EAErD,EAAA,CAAA;EAEH,oBAAoB,QACnB,iBAAiB,KAAK,YAAY,UAChC,oBAAC,OAAD;GAAiB,MAAM,sBAAsB,UAAU;GACpD,UAAA,iBAAiB,YAAY,IAAI;EAC/B,GAFK,KAEL,CACN;EACF,uBAAuB,QACtB,oBAAC,OAAD;GAAK,MAAK;GAAsB,OAAO;GACpC,UAAA,oBAAoB,cAAc;EAChC,CAAA;CAEP,EAAA,CAAA;AAEN"}
@@ -23,6 +23,7 @@ interface UseFileDiffInstanceProps<LAnnotation, Caret> {
23
23
  onEditComplete?: FileDiffEditCompleteHandler<LAnnotation, Caret>;
24
24
  }
25
25
  interface UseFileDiffInstanceReturn<LAnnotation> {
26
+ lineAnnotations: DiffLineAnnotation<LAnnotation>[];
26
27
  fileDiff: FileDiffMetadata;
27
28
  ref(node: HTMLElement | null): void;
28
29
  getHoveredLine(): GetHoveredLineResult<'diff'> | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"useFileDiffInstance.d.ts","names":[],"sources":["../../../src/react/utils/useFileDiffInstance.ts"],"mappings":";;;;;;UA+DU,yBAAyB,aAAa;EAC9C,WAAW;EACX,UAAU;EACV,UAAU;EACV,SAAS,gBAAgB,aAAa;EACtC,eAAe,2BAA2B,aAAa;EACvD;EACA,iBAAiB,mBAAmB;EACpC,eAAe;EACf;EACA,UAAU;EACV;EACA;EACA;EACA;EACA,eAAe,0BAA0B,aAAa;EACtD,iBAAiB,4BAA4B,aAAa;;UAGlD,0BAA0B;EAClC,UAAU;EACV,IAAI,MAAM;EACV,kBAAkB;EAClB,sBAAsB,YAAY,mBAAmB;;iBAGvC,oBAAoB,aAAa,SAC/C,UACA,SACA,SACA,SACA,eACA,cACA,iBACA,eACA,iBACA,SACA,wBACA,iBACA,mBACA,MACA,cAAc,eACd,gBAAgB,mBACf,yBACD,aACA,SACE,0BAA0B"}
1
+ {"version":3,"file":"useFileDiffInstance.d.ts","names":[],"sources":["../../../src/react/utils/useFileDiffInstance.ts"],"mappings":";;;;;;UAmEU,yBAAyB,aAAa;EAC9C,WAAW;EACX,UAAU;EACV,UAAU;EACV,SAAS,gBAAgB,aAAa;EACtC,eAAe,2BAA2B,aAAa;EACvD;EACA,iBAAiB,mBAAmB;EACpC,eAAe;EACf;EACA,UAAU;EACV;EACA;EACA;EACA;EACA,eAAe,0BAA0B,aAAa;EACtD,iBAAiB,4BAA4B,aAAa;;UAGlD,0BAA0B;EAClC,iBAAiB,mBAAmB;EACpC,UAAU;EACV,IAAI,MAAM;EACV,kBAAkB;EAClB,sBAAsB,YAAY,mBAAmB;;iBAGvC,oBAAoB,aAAa,SAC/C,UACA,SACA,SACA,SACA,eACA,cACA,iBACA,eACA,iBACA,SACA,wBACA,iBACA,mBACA,MACA,cAAc,eACd,gBAAgB,mBACf,yBACD,aACA,SACE,0BAA0B"}
@@ -1,3 +1,4 @@
1
+ import { EMPTY_LINE_ANNOTATIONS } from "../../constants.js";
1
2
  import { areOptionsEqual } from "../../utils/areOptionsEqual.js";
2
3
  import { areFileTargetsEqual } from "../../utils/areFileTargetsEqual.js";
3
4
  import { getLineAnnotationName } from "../../utils/getLineAnnotationName.js";
@@ -10,6 +11,8 @@ import { useCreateEditor } from "../EditContext.js";
10
11
  import { noopRender } from "../constants.js";
11
12
  import { WorkerPoolContext } from "../WorkerPoolContext.js";
12
13
  import { useVirtualizer } from "../Virtualizer.js";
14
+ import { useForceUpdate } from "./useForceUpdate.js";
15
+ import { useNextRenderData } from "./useNextRenderData.js";
13
16
  import { useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
14
17
  //#region src/react/utils/useFileDiffInstance.ts
15
18
  const useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
@@ -56,6 +59,12 @@ function useFileDiffInstance({ fileDiff, oldFile, newFile, options, editorOption
56
59
  parseDiffOptions: options?.parseDiffOptions
57
60
  });
58
61
  const instanceRef = useRef(null);
62
+ const forceUpdate = useForceUpdate();
63
+ const accepted = useAcceptedValues(acceptedCache, effectiveFileDiff, lineAnnotations);
64
+ const renderData = useNextRenderData(instanceRef, accepted) ?? {
65
+ fileDiff: effectiveFileDiff,
66
+ lineAnnotations: lineAnnotations ?? EMPTY_LINE_ANNOTATIONS
67
+ };
59
68
  const disposeEditorRef = useRef(null);
60
69
  const pendingAttachRef = useRef(null);
61
70
  const getEditor = useStableCallback(() => {
@@ -72,7 +81,7 @@ function useFileDiffInstance({ fileDiff, oldFile, newFile, options, editorOption
72
81
  onEditChange,
73
82
  onEditComplete,
74
83
  options
75
- }), simpleVirtualizer, metrics, !disableWorkerPool ? poolManager : void 0, true);
84
+ }), simpleVirtualizer, metrics, !disableWorkerPool ? poolManager : void 0, forceUpdate);
76
85
  else instanceRef.current = new FileDiff(mergeFileDiffOptions({
77
86
  controlledSelection,
78
87
  hasCustomHeader,
@@ -80,7 +89,7 @@ function useFileDiffInstance({ fileDiff, oldFile, newFile, options, editorOption
80
89
  onEditChange,
81
90
  onEditComplete,
82
91
  options
83
- }), !disableWorkerPool ? poolManager : void 0, true);
92
+ }), !disableWorkerPool ? poolManager : void 0, forceUpdate);
84
93
  instanceRef.current.hydrate({
85
94
  fileDiff: effectiveFileDiff,
86
95
  fileContainer,
@@ -106,7 +115,7 @@ function useFileDiffInstance({ fileDiff, oldFile, newFile, options, editorOption
106
115
  onEditComplete,
107
116
  options
108
117
  });
109
- const forceRender = newOptions !== void 0 && !areOptionsEqual(instance.options, newOptions);
118
+ const forceRender = !areOptionsEqual(instance.options, newOptions);
110
119
  instance.setOptions(newOptions);
111
120
  if (!edit) {
112
121
  pendingAttachRef.current = null;
@@ -128,6 +137,7 @@ function useFileDiffInstance({ fileDiff, oldFile, newFile, options, editorOption
128
137
  const attach = () => {
129
138
  if (instanceRef.current !== instance || disposeEditorRef.current != null || !instance.__canAttachEditor()) return;
130
139
  disposeEditorRef.current = applyEdit(instance, getEditor);
140
+ forceUpdate();
131
141
  };
132
142
  if (instance.__canAttachEditor()) {
133
143
  pendingAttachRef.current = null;
@@ -159,7 +169,7 @@ function useFileDiffInstance({ fileDiff, oldFile, newFile, options, editorOption
159
169
  const getAnnotationSlotName = useCallback((annotation) => instanceRef.current?.getAnnotationSlotName(annotation) ?? getLineAnnotationName(annotation), []);
160
170
  if (asyncAttachError != null) throw asyncAttachError;
161
171
  return {
162
- fileDiff: effectiveFileDiff,
172
+ ...renderData,
163
173
  ref,
164
174
  getHoveredLine,
165
175
  getAnnotationSlotName
@@ -186,31 +196,26 @@ function useEffectiveFileDiff({ acceptedCache, fileDiff, newFile, oldFile, parse
186
196
  function isSameFilePair(oldFile, newFile, filePair) {
187
197
  return areFileTargetsEqual(oldFile ?? void 0, filePair.oldFile ?? void 0) && areFileTargetsEqual(newFile ?? void 0, filePair.newFile ?? void 0);
188
198
  }
199
+ function useAcceptedValues(acceptedCache, fileDiff, lineAnnotations) {
200
+ "use no memo";
201
+ return getAcceptedValues(fileDiff, lineAnnotations, acceptedCache.current);
202
+ }
203
+ function getAcceptedValues(fileDiff, lineAnnotations, accepted) {
204
+ return {
205
+ fileDiff: accepted?.fileDiff != null && areDiffTargetsEqual(fileDiff, accepted.fileDiff.stale) ? accepted.fileDiff.installed : fileDiff,
206
+ lineAnnotations: accepted?.annotations != null && lineAnnotations === accepted.annotations.stale ? accepted.annotations.installed : lineAnnotations
207
+ };
208
+ }
189
209
  function resolveAcceptedValues(fileDiff, lineAnnotations, acceptedCache) {
190
210
  const { current: accepted } = acceptedCache;
191
- if (accepted == null) return {
192
- fileDiff,
193
- lineAnnotations
194
- };
195
- const { fileDiff: acceptedDiff, annotations: acceptedAnnotations } = accepted;
196
- let resolvedFileDiff = fileDiff;
197
- if (acceptedDiff != null) {
198
- if (areDiffTargetsEqual(fileDiff, acceptedDiff.stale)) resolvedFileDiff = acceptedDiff.installed;
199
- else accepted.fileDiff = null;
200
- }
201
- let resolvedAnnotations = lineAnnotations;
202
- if (acceptedAnnotations != null) {
203
- if (lineAnnotations === acceptedAnnotations.stale) resolvedAnnotations = acceptedAnnotations.installed;
204
- else accepted.annotations = null;
205
- }
211
+ const resolved = getAcceptedValues(fileDiff, lineAnnotations, accepted);
212
+ if (accepted == null) return resolved;
213
+ if (accepted.fileDiff != null && !areDiffTargetsEqual(fileDiff, accepted.fileDiff.stale)) accepted.fileDiff = null;
214
+ if (lineAnnotations !== accepted.annotations?.stale) accepted.annotations = null;
206
215
  if (accepted.fileDiff == null && accepted.annotations == null && accepted.filePair == null) acceptedCache.current = null;
207
- return {
208
- fileDiff: resolvedFileDiff,
209
- lineAnnotations: resolvedAnnotations
210
- };
216
+ return resolved;
211
217
  }
212
218
  function mergeFileDiffOptions({ options, controlledSelection, hasCustomHeader, hasGutterRenderUtility, onEditChange, onEditComplete }) {
213
- if (!(controlledSelection || hasGutterRenderUtility || hasCustomHeader || onEditChange != null || onEditComplete != null)) return options;
214
219
  return {
215
220
  ...options,
216
221
  controlledSelection,
@@ -1 +1 @@
1
- {"version":3,"file":"useFileDiffInstance.js","names":[],"sources":["../../../src/react/utils/useFileDiffInstance.ts"],"sourcesContent":["import {\n type RefObject,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport {\n FileDiff,\n type FileDiffEditChangeHandler,\n type FileDiffEditCompleteEvent,\n type FileDiffEditCompleteHandler,\n type FileDiffOptions,\n} from '../../components/FileDiff';\nimport { VirtualizedFileDiff } from '../../components/VirtualizedFileDiff';\nimport type { Editor, EditorChangeEvent, EditorOptions } from '../../edit';\nimport type { GetHoveredLineResult } from '../../managers/InteractionManager';\nimport type {\n DiffLineAnnotation,\n FileContents,\n FileDiffMetadata,\n SelectedLineRange,\n VirtualFileMetrics,\n} from '../../types';\nimport { areDiffTargetsEqual } from '../../utils/areDiffTargetsEqual';\nimport { areFileTargetsEqual } from '../../utils/areFileTargetsEqual';\nimport { areOptionsEqual } from '../../utils/areOptionsEqual';\nimport { getLineAnnotationName } from '../../utils/getLineAnnotationName';\nimport { parseDiffFromFile } from '../../utils/parseDiffFromFile';\nimport { noopRender } from '../constants';\nimport { useCreateEditor } from '../EditContext';\nimport { useVirtualizer } from '../Virtualizer';\nimport { WorkerPoolContext } from '../WorkerPoolContext';\nimport { useStableCallback } from './useStableCallback';\n\nconst useIsomorphicLayoutEffect =\n typeof window === 'undefined' ? useEffect : useLayoutEffect;\n\ninterface AcceptedFilePair {\n oldFile: FileContents | null;\n newFile: FileContents | null;\n}\n\ninterface AcceptedCompletion<LAnnotation> {\n fileDiff: {\n installed: FileDiffMetadata;\n stale: FileDiffMetadata;\n } | null;\n filePair: {\n fileDiff: FileDiffMetadata;\n installed: AcceptedFilePair;\n stale: AcceptedFilePair;\n } | null;\n annotations: {\n installed: DiffLineAnnotation<LAnnotation>[] | undefined;\n stale: DiffLineAnnotation<LAnnotation>[];\n } | null;\n}\n\ninterface UseFileDiffInstanceProps<LAnnotation, Caret> {\n fileDiff?: FileDiffMetadata;\n oldFile?: FileContents | null;\n newFile?: FileContents | null;\n options: FileDiffOptions<LAnnotation, Caret> | undefined;\n editorOptions: EditorOptions<'file-diff', LAnnotation, Caret> | undefined;\n editStateKey: string | undefined;\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined;\n selectedLines: SelectedLineRange | null | undefined;\n prerenderedHTML: string | undefined;\n metrics?: VirtualFileMetrics;\n hasGutterRenderUtility: boolean;\n hasCustomHeader: boolean;\n disableWorkerPool: boolean;\n edit: boolean;\n onEditChange?: FileDiffEditChangeHandler<LAnnotation, Caret>;\n onEditComplete?: FileDiffEditCompleteHandler<LAnnotation, Caret>;\n}\n\ninterface UseFileDiffInstanceReturn<LAnnotation> {\n fileDiff: FileDiffMetadata;\n ref(node: HTMLElement | null): void;\n getHoveredLine(): GetHoveredLineResult<'diff'> | undefined;\n getAnnotationSlotName(annotation: DiffLineAnnotation<LAnnotation>): string;\n}\n\nexport function useFileDiffInstance<LAnnotation, Caret>({\n fileDiff,\n oldFile,\n newFile,\n options,\n editorOptions,\n editStateKey,\n lineAnnotations,\n selectedLines,\n prerenderedHTML,\n metrics,\n hasGutterRenderUtility,\n hasCustomHeader,\n disableWorkerPool,\n edit,\n onEditChange: _onEditChange,\n onEditComplete: _onEditComplete,\n}: UseFileDiffInstanceProps<\n LAnnotation,\n Caret\n>): UseFileDiffInstanceReturn<LAnnotation> {\n const simpleVirtualizer = useVirtualizer();\n const controlledSelection = selectedLines !== undefined;\n const poolManager = useContext(WorkerPoolContext);\n const createEditor = useCreateEditor<LAnnotation, Caret>();\n const [asyncAttachError, setAsyncAttachError] = useState<unknown>();\n const handleOnEditChange = useStableCallback(\n (event: EditorChangeEvent<'file-diff', LAnnotation, Caret>) =>\n _onEditChange?.(event)\n );\n const onEditChange = _onEditChange != null ? handleOnEditChange : undefined;\n // An accepted completion installs its diff on the instance immediately,\n // but the fileDiff/lineAnnotations props stay pre-edit until the owner's\n // state update lands. This holds the accepted values so the renders in\n // between do not repaint pre-edit state.\n const acceptedCache = useRef<AcceptedCompletion<LAnnotation> | null>(null);\n const handleOnEditComplete = useStableCallback(\n (event: FileDiffEditCompleteEvent<LAnnotation, Caret>) => {\n const decision = _onEditComplete?.(event) ?? 'reject';\n if (decision === 'accept') {\n acceptedCache.current = {\n fileDiff: {\n installed: event.fileDiff,\n stale: event.originalFileDiff,\n },\n filePair:\n fileDiff == null\n ? {\n fileDiff: event.fileDiff,\n installed: { oldFile: event.oldFile, newFile: event.newFile },\n stale: { oldFile: oldFile ?? null, newFile: newFile ?? null },\n }\n : null,\n annotations: {\n installed: event.lineAnnotations,\n stale: event.originalLineAnnotations,\n },\n };\n }\n return decision;\n }\n );\n const onEditComplete =\n _onEditComplete != null ? handleOnEditComplete : undefined;\n // File-pair inputs parse here. While the file props still match the pair\n // from acceptance time (stale) or the completion event's files (installed),\n // the parse is the accepted diff itself; any other pair clears the record\n // and parses fresh.\n const effectiveFileDiff = useEffectiveFileDiff({\n acceptedCache,\n fileDiff,\n newFile,\n oldFile,\n parseDiffOptions: options?.parseDiffOptions,\n });\n const instanceRef = useRef<\n | FileDiff<LAnnotation, Caret>\n | VirtualizedFileDiff<LAnnotation, Caret>\n | null\n >(null);\n const disposeEditorRef = useRef<() => void>(null);\n const pendingAttachRef = useRef<{ promise: Promise<void> } | null>(null);\n const getEditor = useStableCallback(() => {\n if (createEditor == null) {\n throw new Error('FileDiff: EditContext is not attached');\n }\n return createEditor('file-diff', editorOptions ?? {}, editStateKey);\n });\n const ref = useStableCallback((fileContainer: HTMLElement | null) => {\n if (fileContainer != null) {\n if (instanceRef.current != null) {\n throw new Error(\n 'useFileDiffInstance: An instance should not already exist when a node is created'\n );\n }\n if (simpleVirtualizer != null) {\n instanceRef.current = new VirtualizedFileDiff(\n mergeFileDiffOptions({\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n options,\n }),\n simpleVirtualizer,\n metrics,\n !disableWorkerPool ? poolManager : undefined,\n true\n );\n } else {\n instanceRef.current = new FileDiff(\n mergeFileDiffOptions({\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n options,\n }),\n !disableWorkerPool ? poolManager : undefined,\n true\n );\n }\n void instanceRef.current.hydrate({\n fileDiff: effectiveFileDiff,\n fileContainer,\n lineAnnotations,\n prerenderedHTML,\n });\n } else {\n if (instanceRef.current == null) {\n throw new Error(\n 'useFileDiffInstance: A FileDiff instance should exist when unmounting'\n );\n }\n pendingAttachRef.current = null;\n instanceRef.current.cleanUp();\n instanceRef.current = null;\n disposeEditorRef.current = null;\n }\n });\n\n useIsomorphicLayoutEffect(() => {\n const { current: instance } = instanceRef;\n if (instance == null) return;\n const newOptions = mergeFileDiffOptions({\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n options,\n });\n // setOptions(undefined) is a no-op, so an undefined merge result never\n // requires a forced render — comparing it against the instance's\n // constructor-default options would force a full render on every commit.\n const forceRender =\n newOptions !== undefined &&\n !areOptionsEqual(instance.options, newOptions);\n instance.setOptions(newOptions);\n // Detach editor before rendering if required\n if (!edit) {\n pendingAttachRef.current = null;\n if (disposeEditorRef.current != null) {\n const { current: disposeEditor } = disposeEditorRef;\n disposeEditorRef.current = null;\n disposeEditor();\n }\n }\n const resolved = resolveAcceptedValues(\n effectiveFileDiff,\n lineAnnotations,\n acceptedCache\n );\n void instance.render({\n forceRender,\n fileDiff: resolved.fileDiff,\n lineAnnotations: resolved.lineAnnotations,\n });\n if (selectedLines !== undefined) {\n instance.setSelectedLines(selectedLines);\n }\n if (!edit || disposeEditorRef.current != null) {\n return;\n }\n if (createEditor == null) {\n throw new Error('FileDiff: EditContext is not attached');\n }\n\n const attach = (): void => {\n if (\n instanceRef.current !== instance ||\n disposeEditorRef.current != null ||\n !instance.__canAttachEditor()\n ) {\n return;\n }\n disposeEditorRef.current = applyEdit(instance, getEditor);\n };\n // If we're all ready to attach the editor, lets go ahead\n // and do that synchronously\n if (instance.__canAttachEditor()) {\n pendingAttachRef.current = null;\n attach();\n return;\n }\n const promise = instance.__prepareForEditing();\n // If we can't hydrate the files... this will come back undefined,\n // which means there's nothing we can do\n if (promise == null) {\n pendingAttachRef.current = null;\n return;\n }\n // If we are already waiting on a hydration to finish, then there's nothing\n // we need to do\n if (pendingAttachRef.current?.promise === promise) {\n return;\n }\n const pending = { promise };\n pendingAttachRef.current = pending;\n void promise\n .then(() => {\n if (pendingAttachRef.current !== pending) {\n return;\n }\n attach();\n pendingAttachRef.current = null;\n })\n .catch((error: unknown) => {\n if (pendingAttachRef.current === pending) {\n pendingAttachRef.current = null;\n setAsyncAttachError(error);\n }\n });\n });\n\n const getHoveredLine = useCallback(():\n | GetHoveredLineResult<'diff'>\n | undefined => {\n return instanceRef.current?.getHoveredLine();\n }, []);\n const getAnnotationSlotName = useCallback(\n (annotation: DiffLineAnnotation<LAnnotation>): string =>\n instanceRef.current?.getAnnotationSlotName(annotation) ??\n getLineAnnotationName(annotation),\n []\n );\n\n if (asyncAttachError != null) {\n throw asyncAttachError;\n }\n\n return {\n fileDiff: effectiveFileDiff,\n ref,\n getHoveredLine,\n getAnnotationSlotName,\n };\n}\n\ninterface UseEffectiveFileDiffProps<LAnnotation, Caret> {\n acceptedCache: RefObject<AcceptedCompletion<LAnnotation> | null>;\n fileDiff: FileDiffMetadata | undefined;\n newFile: FileContents | null | undefined;\n oldFile: FileContents | null | undefined;\n parseDiffOptions: FileDiffOptions<LAnnotation, Caret>['parseDiffOptions'];\n}\n\n// Resolves the diff the instance renders: the `fileDiff` prop when given;\n// otherwise the accepted edit's cached diff while the file props still name the\n// pair it was accepted against; otherwise a fresh parse of the file props. A\n// cached pair that no longer matches is dropped on the way. Kept in its own hook\n// because the render-time ref read and write are deliberate; the boundary lets\n// the calling hook stay compilable.\nfunction useEffectiveFileDiff<LAnnotation, Caret>({\n acceptedCache,\n fileDiff,\n newFile,\n oldFile,\n parseDiffOptions,\n}: UseEffectiveFileDiffProps<LAnnotation, Caret>): FileDiffMetadata {\n /* oxlint-disable react/immutability react/refs -- accepted edit output must\n * replace stale file-pair props during render */\n const effectiveFileDiff = useMemo(() => {\n if (fileDiff != null) {\n return fileDiff;\n }\n const { current: accepted } = acceptedCache;\n const filePair = accepted?.filePair;\n if (accepted != null && filePair != null) {\n if (\n isSameFilePair(oldFile, newFile, filePair.stale) ||\n isSameFilePair(oldFile, newFile, filePair.installed)\n ) {\n return filePair.fileDiff;\n }\n accepted.filePair = null;\n }\n return parseDiffFromFile(\n oldFile ?? null,\n newFile ?? null,\n parseDiffOptions\n );\n }, [acceptedCache, fileDiff, oldFile, newFile, parseDiffOptions]);\n /* oxlint-enable react/immutability react/refs */\n\n return effectiveFileDiff;\n}\n\n// Whether the file props name the same files as a recorded pair.\nfunction isSameFilePair(\n oldFile: FileContents | null | undefined,\n newFile: FileContents | null | undefined,\n filePair: AcceptedFilePair\n): boolean {\n return (\n areFileTargetsEqual(oldFile ?? undefined, filePair.oldFile ?? undefined) &&\n areFileTargetsEqual(newFile ?? undefined, filePair.newFile ?? undefined)\n );\n}\n\n// Render the installed values in place of props that still match their stale\n// counterparts. Any other prop value clears its slot — filePair settles in\n// the parse memo instead — and the ref clears once all three have.\nfunction resolveAcceptedValues<LAnnotation>(\n fileDiff: FileDiffMetadata,\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined,\n acceptedCache: RefObject<AcceptedCompletion<LAnnotation> | null>\n): {\n fileDiff: FileDiffMetadata;\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined;\n} {\n const { current: accepted } = acceptedCache;\n if (accepted == null) {\n return { fileDiff, lineAnnotations };\n }\n const { fileDiff: acceptedDiff, annotations: acceptedAnnotations } = accepted;\n let resolvedFileDiff = fileDiff;\n if (acceptedDiff != null) {\n if (areDiffTargetsEqual(fileDiff, acceptedDiff.stale)) {\n resolvedFileDiff = acceptedDiff.installed;\n } else {\n accepted.fileDiff = null;\n }\n }\n let resolvedAnnotations = lineAnnotations;\n if (acceptedAnnotations != null) {\n if (lineAnnotations === acceptedAnnotations.stale) {\n resolvedAnnotations = acceptedAnnotations.installed;\n } else {\n accepted.annotations = null;\n }\n }\n if (\n accepted.fileDiff == null &&\n accepted.annotations == null &&\n accepted.filePair == null\n ) {\n acceptedCache.current = null;\n }\n return { fileDiff: resolvedFileDiff, lineAnnotations: resolvedAnnotations };\n}\n\ninterface MergeFileDiffOptionsProps<LAnnotation, Caret> {\n controlledSelection: boolean;\n hasCustomHeader: boolean;\n hasGutterRenderUtility: boolean;\n onEditChange?: FileDiffEditChangeHandler<LAnnotation, Caret>;\n onEditComplete?: FileDiffEditCompleteHandler<LAnnotation, Caret>;\n options: FileDiffOptions<LAnnotation, Caret> | undefined;\n}\n\nfunction mergeFileDiffOptions<LAnnotation, Caret>({\n options,\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n}: MergeFileDiffOptionsProps<LAnnotation, Caret>):\n | FileDiffOptions<LAnnotation, Caret>\n | undefined {\n const needsReactOverrides =\n controlledSelection ||\n hasGutterRenderUtility ||\n hasCustomHeader ||\n onEditChange != null ||\n onEditComplete != null;\n\n if (!needsReactOverrides) {\n return options;\n }\n\n return {\n ...options,\n controlledSelection,\n renderCustomHeader: hasCustomHeader\n ? noopRender\n : options?.renderCustomHeader,\n renderGutterUtility: hasGutterRenderUtility\n ? noopRender\n : options?.renderGutterUtility,\n onEditChange,\n onEditComplete,\n };\n}\n\nfunction applyEdit<LAnnotation, Caret>(\n instance: FileDiff<LAnnotation, Caret>,\n getEditor: () => Editor<'file-diff', LAnnotation, Caret>\n): () => void {\n const editor = getEditor();\n try {\n return editor.edit(instance);\n } catch (error) {\n editor.cleanUp();\n throw error;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useFileDiffInstance.js","names":[],"sources":["../../../src/react/utils/useFileDiffInstance.ts"],"sourcesContent":["import {\n type RefObject,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport {\n FileDiff,\n type FileDiffEditChangeHandler,\n type FileDiffEditCompleteEvent,\n type FileDiffEditCompleteHandler,\n type FileDiffOptions,\n type FileDiffRenderInput,\n} from '../../components/FileDiff';\nimport { VirtualizedFileDiff } from '../../components/VirtualizedFileDiff';\nimport { EMPTY_LINE_ANNOTATIONS } from '../../constants';\nimport type { Editor, EditorChangeEvent, EditorOptions } from '../../edit';\nimport type { GetHoveredLineResult } from '../../managers/InteractionManager';\nimport type {\n DiffLineAnnotation,\n FileContents,\n FileDiffMetadata,\n SelectedLineRange,\n VirtualFileMetrics,\n} from '../../types';\nimport { areDiffTargetsEqual } from '../../utils/areDiffTargetsEqual';\nimport { areFileTargetsEqual } from '../../utils/areFileTargetsEqual';\nimport { areOptionsEqual } from '../../utils/areOptionsEqual';\nimport { getLineAnnotationName } from '../../utils/getLineAnnotationName';\nimport { parseDiffFromFile } from '../../utils/parseDiffFromFile';\nimport { noopRender } from '../constants';\nimport { useCreateEditor } from '../EditContext';\nimport { useVirtualizer } from '../Virtualizer';\nimport { WorkerPoolContext } from '../WorkerPoolContext';\nimport { useForceUpdate } from './useForceUpdate';\nimport { useNextRenderData } from './useNextRenderData';\nimport { useStableCallback } from './useStableCallback';\n\nconst useIsomorphicLayoutEffect =\n typeof window === 'undefined' ? useEffect : useLayoutEffect;\n\ninterface AcceptedFilePair {\n oldFile: FileContents | null;\n newFile: FileContents | null;\n}\n\ninterface AcceptedCompletion<LAnnotation> {\n fileDiff: {\n installed: FileDiffMetadata;\n stale: FileDiffMetadata;\n } | null;\n filePair: {\n fileDiff: FileDiffMetadata;\n installed: AcceptedFilePair;\n stale: AcceptedFilePair;\n } | null;\n annotations: {\n installed: DiffLineAnnotation<LAnnotation>[] | undefined;\n stale: DiffLineAnnotation<LAnnotation>[];\n } | null;\n}\n\ninterface UseFileDiffInstanceProps<LAnnotation, Caret> {\n fileDiff?: FileDiffMetadata;\n oldFile?: FileContents | null;\n newFile?: FileContents | null;\n options: FileDiffOptions<LAnnotation, Caret> | undefined;\n editorOptions: EditorOptions<'file-diff', LAnnotation, Caret> | undefined;\n editStateKey: string | undefined;\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined;\n selectedLines: SelectedLineRange | null | undefined;\n prerenderedHTML: string | undefined;\n metrics?: VirtualFileMetrics;\n hasGutterRenderUtility: boolean;\n hasCustomHeader: boolean;\n disableWorkerPool: boolean;\n edit: boolean;\n onEditChange?: FileDiffEditChangeHandler<LAnnotation, Caret>;\n onEditComplete?: FileDiffEditCompleteHandler<LAnnotation, Caret>;\n}\n\ninterface UseFileDiffInstanceReturn<LAnnotation> {\n lineAnnotations: DiffLineAnnotation<LAnnotation>[];\n fileDiff: FileDiffMetadata;\n ref(node: HTMLElement | null): void;\n getHoveredLine(): GetHoveredLineResult<'diff'> | undefined;\n getAnnotationSlotName(annotation: DiffLineAnnotation<LAnnotation>): string;\n}\n\nexport function useFileDiffInstance<LAnnotation, Caret>({\n fileDiff,\n oldFile,\n newFile,\n options,\n editorOptions,\n editStateKey,\n lineAnnotations,\n selectedLines,\n prerenderedHTML,\n metrics,\n hasGutterRenderUtility,\n hasCustomHeader,\n disableWorkerPool,\n edit,\n onEditChange: _onEditChange,\n onEditComplete: _onEditComplete,\n}: UseFileDiffInstanceProps<\n LAnnotation,\n Caret\n>): UseFileDiffInstanceReturn<LAnnotation> {\n const simpleVirtualizer = useVirtualizer();\n const controlledSelection = selectedLines !== undefined;\n const poolManager = useContext(WorkerPoolContext);\n const createEditor = useCreateEditor<LAnnotation, Caret>();\n const [asyncAttachError, setAsyncAttachError] = useState<unknown>();\n const handleOnEditChange = useStableCallback(\n (event: EditorChangeEvent<'file-diff', LAnnotation, Caret>) =>\n _onEditChange?.(event)\n );\n const onEditChange = _onEditChange != null ? handleOnEditChange : undefined;\n // An accepted completion installs its diff on the instance immediately,\n // but the fileDiff/lineAnnotations props stay pre-edit until the owner's\n // state update lands. This holds the accepted values so the renders in\n // between do not repaint pre-edit state.\n const acceptedCache = useRef<AcceptedCompletion<LAnnotation> | null>(null);\n const handleOnEditComplete = useStableCallback(\n (event: FileDiffEditCompleteEvent<LAnnotation, Caret>) => {\n const decision = _onEditComplete?.(event) ?? 'reject';\n if (decision === 'accept') {\n acceptedCache.current = {\n fileDiff: {\n installed: event.fileDiff,\n stale: event.originalFileDiff,\n },\n filePair:\n fileDiff == null\n ? {\n fileDiff: event.fileDiff,\n installed: { oldFile: event.oldFile, newFile: event.newFile },\n stale: { oldFile: oldFile ?? null, newFile: newFile ?? null },\n }\n : null,\n annotations: {\n installed: event.lineAnnotations,\n stale: event.originalLineAnnotations,\n },\n };\n }\n return decision;\n }\n );\n const onEditComplete =\n _onEditComplete != null ? handleOnEditComplete : undefined;\n const effectiveFileDiff = useEffectiveFileDiff({\n acceptedCache,\n fileDiff,\n newFile,\n oldFile,\n parseDiffOptions: options?.parseDiffOptions,\n });\n const instanceRef = useRef<\n | FileDiff<LAnnotation, Caret>\n | VirtualizedFileDiff<LAnnotation, Caret>\n | null\n >(null);\n const forceUpdate = useForceUpdate();\n const accepted = useAcceptedValues(\n acceptedCache,\n effectiveFileDiff,\n lineAnnotations\n );\n const renderData = useNextRenderData(instanceRef, accepted) ?? {\n fileDiff: effectiveFileDiff,\n lineAnnotations: lineAnnotations ?? EMPTY_LINE_ANNOTATIONS,\n };\n const disposeEditorRef = useRef<() => void>(null);\n const pendingAttachRef = useRef<{ promise: Promise<void> } | null>(null);\n const getEditor = useStableCallback(() => {\n if (createEditor == null) {\n throw new Error('FileDiff: EditContext is not attached');\n }\n return createEditor('file-diff', editorOptions ?? {}, editStateKey);\n });\n const ref = useStableCallback((fileContainer: HTMLElement | null) => {\n if (fileContainer != null) {\n if (instanceRef.current != null) {\n throw new Error(\n 'useFileDiffInstance: An instance should not already exist when a node is created'\n );\n }\n if (simpleVirtualizer != null) {\n instanceRef.current = new VirtualizedFileDiff(\n mergeFileDiffOptions({\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n options,\n }),\n simpleVirtualizer,\n metrics,\n !disableWorkerPool ? poolManager : undefined,\n forceUpdate\n );\n } else {\n instanceRef.current = new FileDiff(\n mergeFileDiffOptions({\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n options,\n }),\n !disableWorkerPool ? poolManager : undefined,\n forceUpdate\n );\n }\n void instanceRef.current.hydrate({\n fileDiff: effectiveFileDiff,\n fileContainer,\n lineAnnotations,\n prerenderedHTML,\n });\n } else {\n if (instanceRef.current == null) {\n throw new Error(\n 'useFileDiffInstance: A FileDiff instance should exist when unmounting'\n );\n }\n pendingAttachRef.current = null;\n instanceRef.current.cleanUp();\n instanceRef.current = null;\n disposeEditorRef.current = null;\n }\n });\n\n useIsomorphicLayoutEffect(() => {\n const { current: instance } = instanceRef;\n if (instance == null) return;\n const newOptions = mergeFileDiffOptions({\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n options,\n });\n const forceRender = !areOptionsEqual(instance.options, newOptions);\n instance.setOptions(newOptions);\n // Detach editor before rendering if required\n if (!edit) {\n pendingAttachRef.current = null;\n if (disposeEditorRef.current != null) {\n const { current: disposeEditor } = disposeEditorRef;\n disposeEditorRef.current = null;\n disposeEditor();\n }\n }\n const resolved = resolveAcceptedValues(\n effectiveFileDiff,\n lineAnnotations,\n acceptedCache\n );\n void instance.render({\n forceRender,\n fileDiff: resolved.fileDiff,\n lineAnnotations: resolved.lineAnnotations,\n });\n if (selectedLines !== undefined) {\n instance.setSelectedLines(selectedLines);\n }\n if (!edit || disposeEditorRef.current != null) {\n return;\n }\n if (createEditor == null) {\n throw new Error('FileDiff: EditContext is not attached');\n }\n\n const attach = (): void => {\n if (\n instanceRef.current !== instance ||\n disposeEditorRef.current != null ||\n !instance.__canAttachEditor()\n ) {\n return;\n }\n disposeEditorRef.current = applyEdit(instance, getEditor);\n // The editor can show content that is still highlighting, so render the\n // children again from the edit session.\n forceUpdate();\n };\n // If we're all ready to attach the editor, lets go ahead\n // and do that synchronously\n if (instance.__canAttachEditor()) {\n pendingAttachRef.current = null;\n attach();\n return;\n }\n const promise = instance.__prepareForEditing();\n // If we can't hydrate the files... this will come back undefined,\n // which means there's nothing we can do\n if (promise == null) {\n pendingAttachRef.current = null;\n return;\n }\n // If we are already waiting on a hydration to finish, then there's nothing\n // we need to do\n if (pendingAttachRef.current?.promise === promise) {\n return;\n }\n const pending = { promise };\n pendingAttachRef.current = pending;\n void promise\n .then(() => {\n if (pendingAttachRef.current !== pending) {\n return;\n }\n attach();\n pendingAttachRef.current = null;\n })\n .catch((error: unknown) => {\n if (pendingAttachRef.current === pending) {\n pendingAttachRef.current = null;\n setAsyncAttachError(error);\n }\n });\n });\n\n const getHoveredLine = useCallback(():\n | GetHoveredLineResult<'diff'>\n | undefined => {\n return instanceRef.current?.getHoveredLine();\n }, []);\n const getAnnotationSlotName = useCallback(\n (annotation: DiffLineAnnotation<LAnnotation>): string =>\n instanceRef.current?.getAnnotationSlotName(annotation) ??\n getLineAnnotationName(annotation),\n []\n );\n\n if (asyncAttachError != null) {\n throw asyncAttachError;\n }\n\n return {\n ...renderData,\n ref,\n getHoveredLine,\n getAnnotationSlotName,\n };\n}\n\ninterface UseEffectiveFileDiffProps<LAnnotation, Caret> {\n acceptedCache: RefObject<AcceptedCompletion<LAnnotation> | null>;\n fileDiff: FileDiffMetadata | undefined;\n newFile: FileContents | null | undefined;\n oldFile: FileContents | null | undefined;\n parseDiffOptions: FileDiffOptions<LAnnotation, Caret>['parseDiffOptions'];\n}\n\n// Return the diff to render: the fileDiff prop, or a parse of the file props.\n// While the file props still match the accepted edit's original or completed\n// files, return the accepted diff instead. Other files remove the filePair\n// entry. The ref is read and written during render on purpose, so that stays\n// in this hook instead of the caller.\nfunction useEffectiveFileDiff<LAnnotation, Caret>({\n acceptedCache,\n fileDiff,\n newFile,\n oldFile,\n parseDiffOptions,\n}: UseEffectiveFileDiffProps<LAnnotation, Caret>): FileDiffMetadata {\n /* oxlint-disable react/immutability react/refs -- accepted edit output must\n * replace stale file-pair props during render */\n const effectiveFileDiff = useMemo(() => {\n if (fileDiff != null) {\n return fileDiff;\n }\n const { current: accepted } = acceptedCache;\n const filePair = accepted?.filePair;\n if (accepted != null && filePair != null) {\n if (\n isSameFilePair(oldFile, newFile, filePair.stale) ||\n isSameFilePair(oldFile, newFile, filePair.installed)\n ) {\n return filePair.fileDiff;\n }\n accepted.filePair = null;\n }\n return parseDiffFromFile(\n oldFile ?? null,\n newFile ?? null,\n parseDiffOptions\n );\n }, [acceptedCache, fileDiff, oldFile, newFile, parseDiffOptions]);\n /* oxlint-enable react/immutability react/refs */\n\n return effectiveFileDiff;\n}\n\n// Whether the file props name the same files as a recorded pair.\nfunction isSameFilePair(\n oldFile: FileContents | null | undefined,\n newFile: FileContents | null | undefined,\n filePair: AcceptedFilePair\n): boolean {\n return (\n areFileTargetsEqual(oldFile ?? undefined, filePair.oldFile ?? undefined) &&\n areFileTargetsEqual(newFile ?? undefined, filePair.newFile ?? undefined)\n );\n}\n\n// Read the accepted values on every render. Entries are only removed in the\n// effect, by resolveAcceptedValues. The cache changes without new props, so\n// this must not be memoized.\nfunction useAcceptedValues<LAnnotation>(\n acceptedCache: RefObject<AcceptedCompletion<LAnnotation> | null>,\n fileDiff: FileDiffMetadata,\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined\n): FileDiffRenderInput<LAnnotation> {\n 'use no memo';\n // oxlint-disable-next-line react/refs -- the cache changes without new props\n return getAcceptedValues(fileDiff, lineAnnotations, acceptedCache.current);\n}\n\n// Use the accepted values for props that still hold their pre-edit values.\nfunction getAcceptedValues<LAnnotation>(\n fileDiff: FileDiffMetadata,\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined,\n accepted: AcceptedCompletion<LAnnotation> | null\n): FileDiffRenderInput<LAnnotation> {\n return {\n fileDiff:\n accepted?.fileDiff != null &&\n areDiffTargetsEqual(fileDiff, accepted.fileDiff.stale)\n ? accepted.fileDiff.installed\n : fileDiff,\n lineAnnotations:\n accepted?.annotations != null &&\n lineAnnotations === accepted.annotations.stale\n ? accepted.annotations.installed\n : lineAnnotations,\n };\n}\n\n// Return the accepted values, and drop each one once its prop no longer holds\n// the pre-edit value. useEffectiveFileDiff drops the filePair entry. The cache\n// is cleared once every entry is dropped.\nfunction resolveAcceptedValues<LAnnotation>(\n fileDiff: FileDiffMetadata,\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined,\n acceptedCache: RefObject<AcceptedCompletion<LAnnotation> | null>\n): FileDiffRenderInput<LAnnotation> {\n const { current: accepted } = acceptedCache;\n const resolved = getAcceptedValues(fileDiff, lineAnnotations, accepted);\n if (accepted == null) {\n return resolved;\n }\n if (\n accepted.fileDiff != null &&\n !areDiffTargetsEqual(fileDiff, accepted.fileDiff.stale)\n ) {\n accepted.fileDiff = null;\n }\n if (lineAnnotations !== accepted.annotations?.stale) {\n accepted.annotations = null;\n }\n if (\n accepted.fileDiff == null &&\n accepted.annotations == null &&\n accepted.filePair == null\n ) {\n acceptedCache.current = null;\n }\n return resolved;\n}\n\ninterface MergeFileDiffOptionsProps<LAnnotation, Caret> {\n controlledSelection: boolean;\n hasCustomHeader: boolean;\n hasGutterRenderUtility: boolean;\n onEditChange?: FileDiffEditChangeHandler<LAnnotation, Caret>;\n onEditComplete?: FileDiffEditCompleteHandler<LAnnotation, Caret>;\n options: FileDiffOptions<LAnnotation, Caret> | undefined;\n}\n\nfunction mergeFileDiffOptions<LAnnotation, Caret>({\n options,\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n}: MergeFileDiffOptionsProps<LAnnotation, Caret>): FileDiffOptions<\n LAnnotation,\n Caret\n> {\n return {\n ...options,\n controlledSelection,\n renderCustomHeader: hasCustomHeader\n ? noopRender\n : options?.renderCustomHeader,\n renderGutterUtility: hasGutterRenderUtility\n ? noopRender\n : options?.renderGutterUtility,\n onEditChange,\n onEditComplete,\n };\n}\n\nfunction applyEdit<LAnnotation, Caret>(\n instance: FileDiff<LAnnotation, Caret>,\n getEditor: () => Editor<'file-diff', LAnnotation, Caret>\n): () => void {\n const editor = getEditor();\n try {\n return editor.edit(instance);\n } catch (error) {\n editor.cleanUp();\n throw error;\n }\n}\n"],"mappings":"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"}
@@ -21,6 +21,8 @@ interface UseFileInstanceProps<LAnnotation, Caret> {
21
21
  onEditComplete?: FileEditCompleteHandler<LAnnotation, Caret>;
22
22
  }
23
23
  interface UseFileInstanceReturn<LAnnotation> {
24
+ file: FileContents;
25
+ lineAnnotations: LineAnnotation<LAnnotation>[];
24
26
  ref(node: HTMLElement | null): void;
25
27
  getHoveredLine(): GetHoveredLineResult<'file'> | undefined;
26
28
  getAnnotationSlotName(annotation: LineAnnotation<LAnnotation>): string;
@@ -1 +1 @@
1
- {"version":3,"file":"useFileInstance.d.ts","names":[],"sources":["../../../src/react/utils/useFileInstance.ts"],"mappings":";;;;;;UAgDU,qBAAqB,aAAa;EAC1C,MAAM;EACN,SAAS,YAAY,aAAa;EAClC,eAAe,sBAAsB,aAAa;EAClD;EACA,iBAAiB,eAAe;EAChC,eAAe;EACf;EACA,UAAU;EACV;EACA;EACA;EACA;EACA,eAAe,sBAAsB,aAAa;EAClD,iBAAiB,wBAAwB,aAAa;;UAG9C,sBAAsB;EAC9B,IAAI,MAAM;EACV,kBAAkB;EAClB,sBAAsB,YAAY,eAAe;;iBAGnC,gBAAgB,aAAa,SAC3C,MACA,SACA,eACA,cACA,iBACA,eACA,iBACA,SACA,wBACA,iBACA,mBACA,MACA,cAAc,eACd,gBAAgB,mBACf,qBACD,aACA,SACE,sBAAsB"}
1
+ {"version":3,"file":"useFileInstance.d.ts","names":[],"sources":["../../../src/react/utils/useFileInstance.ts"],"mappings":";;;;;;UAoDU,qBAAqB,aAAa;EAC1C,MAAM;EACN,SAAS,YAAY,aAAa;EAClC,eAAe,sBAAsB,aAAa;EAClD;EACA,iBAAiB,eAAe;EAChC,eAAe;EACf;EACA,UAAU;EACV;EACA;EACA;EACA;EACA,eAAe,sBAAsB,aAAa;EAClD,iBAAiB,wBAAwB,aAAa;;UAG9C,sBAAsB;EAC9B,MAAM;EACN,iBAAiB,eAAe;EAChC,IAAI,MAAM;EACV,kBAAkB;EAClB,sBAAsB,YAAY,eAAe;;iBAGnC,gBAAgB,aAAa,SAC3C,MACA,SACA,eACA,cACA,iBACA,eACA,iBACA,SACA,wBACA,iBACA,mBACA,MACA,cAAc,eACd,gBAAgB,mBACf,qBACD,aACA,SACE,sBAAsB"}
@@ -1,3 +1,4 @@
1
+ import { EMPTY_LINE_ANNOTATIONS } from "../../constants.js";
1
2
  import { areOptionsEqual } from "../../utils/areOptionsEqual.js";
2
3
  import { areFileTargetsEqual } from "../../utils/areFileTargetsEqual.js";
3
4
  import { getLineAnnotationName } from "../../utils/getLineAnnotationName.js";
@@ -8,6 +9,8 @@ import { useCreateEditor } from "../EditContext.js";
8
9
  import { noopRender } from "../constants.js";
9
10
  import { WorkerPoolContext } from "../WorkerPoolContext.js";
10
11
  import { useVirtualizer } from "../Virtualizer.js";
12
+ import { useForceUpdate } from "./useForceUpdate.js";
13
+ import { useNextRenderData } from "./useNextRenderData.js";
11
14
  import { useCallback, useContext, useEffect, useLayoutEffect, useRef } from "react";
12
15
  //#region src/react/utils/useFileInstance.ts
13
16
  const useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
@@ -35,6 +38,12 @@ function useFileInstance({ file, options, editorOptions, editStateKey, lineAnnot
35
38
  });
36
39
  const onEditComplete = _onEditComplete != null ? handleOnEditComplete : void 0;
37
40
  const instanceRef = useRef(null);
41
+ const forceUpdate = useForceUpdate();
42
+ const accepted = useAcceptedValues(acceptedCache, file, lineAnnotations);
43
+ const renderData = useNextRenderData(instanceRef, accepted) ?? {
44
+ file,
45
+ lineAnnotations: lineAnnotations ?? EMPTY_LINE_ANNOTATIONS
46
+ };
38
47
  const disposeEditorRef = useRef(null);
39
48
  const getEditor = useStableCallback(() => {
40
49
  if (createEditor == null) throw new Error("File: EditContext is not attached");
@@ -50,7 +59,7 @@ function useFileInstance({ file, options, editorOptions, editStateKey, lineAnnot
50
59
  onEditChange,
51
60
  onEditComplete,
52
61
  options
53
- }), simpleVirtualizer, metrics, !disableWorkerPool ? poolManager : void 0, true);
62
+ }), simpleVirtualizer, metrics, !disableWorkerPool ? poolManager : void 0, forceUpdate);
54
63
  else instanceRef.current = new File(mergeFileOptions({
55
64
  controlledSelection,
56
65
  hasCustomHeader,
@@ -58,7 +67,7 @@ function useFileInstance({ file, options, editorOptions, editStateKey, lineAnnot
58
67
  onEditChange,
59
68
  onEditComplete,
60
69
  options
61
- }), !disableWorkerPool ? poolManager : void 0, true);
70
+ }), !disableWorkerPool ? poolManager : void 0, forceUpdate);
62
71
  if (edit && disposeEditorRef.current == null) disposeEditorRef.current = applyEdit(instanceRef.current, getEditor);
63
72
  instanceRef.current.hydrate({
64
73
  file,
@@ -84,7 +93,7 @@ function useFileInstance({ file, options, editorOptions, editStateKey, lineAnnot
84
93
  onEditComplete,
85
94
  options
86
95
  });
87
- const forceRender = newOptions !== void 0 && !areOptionsEqual(instance.options, newOptions);
96
+ const forceRender = !areOptionsEqual(instance.options, newOptions);
88
97
  instance.setOptions(newOptions);
89
98
  if (!edit && disposeEditorRef.current != null) {
90
99
  const { current: disposeEditor } = disposeEditorRef;
@@ -98,41 +107,42 @@ function useFileInstance({ file, options, editorOptions, editStateKey, lineAnnot
98
107
  forceRender
99
108
  });
100
109
  if (selectedLines !== void 0) instance.setSelectedLines(selectedLines);
101
- if (edit && disposeEditorRef.current == null) disposeEditorRef.current = applyEdit(instance, getEditor);
110
+ if (edit && disposeEditorRef.current == null) {
111
+ disposeEditorRef.current = applyEdit(instance, getEditor);
112
+ forceUpdate();
113
+ }
102
114
  });
115
+ const getHoveredLine = useCallback(() => {
116
+ return instanceRef.current?.getHoveredLine();
117
+ }, []);
118
+ const getAnnotationSlotName = useCallback((annotation) => instanceRef.current?.getAnnotationSlotName(annotation) ?? getLineAnnotationName(annotation), []);
103
119
  return {
120
+ ...renderData,
104
121
  ref,
105
- getHoveredLine: useCallback(() => {
106
- return instanceRef.current?.getHoveredLine();
107
- }, []),
108
- getAnnotationSlotName: useCallback((annotation) => instanceRef.current?.getAnnotationSlotName(annotation) ?? getLineAnnotationName(annotation), [])
122
+ getHoveredLine,
123
+ getAnnotationSlotName
124
+ };
125
+ }
126
+ function useAcceptedValues(acceptedCache, file, lineAnnotations) {
127
+ "use no memo";
128
+ return getAcceptedValues(file, lineAnnotations, acceptedCache.current);
129
+ }
130
+ function getAcceptedValues(file, lineAnnotations, accepted) {
131
+ return {
132
+ file: accepted?.file != null && areFileTargetsEqual(file, accepted.file.stale) ? accepted.file.installed : file,
133
+ lineAnnotations: accepted?.annotations != null && lineAnnotations === accepted.annotations.stale ? accepted.annotations.installed : lineAnnotations
109
134
  };
110
135
  }
111
136
  function resolveAcceptedValues(file, lineAnnotations, acceptedCache) {
112
137
  const { current: accepted } = acceptedCache;
113
- if (accepted == null) return {
114
- file,
115
- lineAnnotations
116
- };
117
- const { file: acceptedFiles, annotations: acceptedAnnotations } = accepted;
118
- let resolvedFile = file;
119
- if (acceptedFiles != null) {
120
- if (areFileTargetsEqual(file, acceptedFiles.stale)) resolvedFile = acceptedFiles.installed;
121
- else accepted.file = null;
122
- }
123
- let resolvedAnnotations = lineAnnotations;
124
- if (acceptedAnnotations != null) {
125
- if (lineAnnotations === acceptedAnnotations.stale) resolvedAnnotations = acceptedAnnotations.installed;
126
- else accepted.annotations = null;
127
- }
138
+ const resolved = getAcceptedValues(file, lineAnnotations, accepted);
139
+ if (accepted == null) return resolved;
140
+ if (accepted.file != null && !areFileTargetsEqual(file, accepted.file.stale)) accepted.file = null;
141
+ if (lineAnnotations !== accepted.annotations?.stale) accepted.annotations = null;
128
142
  if (accepted.file == null && accepted.annotations == null) acceptedCache.current = null;
129
- return {
130
- file: resolvedFile,
131
- lineAnnotations: resolvedAnnotations
132
- };
143
+ return resolved;
133
144
  }
134
145
  function mergeFileOptions({ options, controlledSelection, hasCustomHeader, hasGutterRenderUtility, onEditChange, onEditComplete }) {
135
- if (!(controlledSelection || hasGutterRenderUtility || hasCustomHeader || onEditChange != null || onEditComplete != null)) return options;
136
146
  return {
137
147
  ...options,
138
148
  controlledSelection,
@@ -1 +1 @@
1
- {"version":3,"file":"useFileInstance.js","names":[],"sources":["../../../src/react/utils/useFileInstance.ts"],"sourcesContent":["import {\n type RefObject,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useRef,\n} from 'react';\n\nimport {\n File,\n type FileEditChangeHandler,\n type FileEditCompleteEvent,\n type FileEditCompleteHandler,\n type FileOptions,\n} from '../../components/File';\nimport { VirtualizedFile } from '../../components/VirtualizedFile';\nimport type { Editor, EditorChangeEvent, EditorOptions } from '../../edit';\nimport type { GetHoveredLineResult } from '../../managers/InteractionManager';\nimport type {\n FileContents,\n LineAnnotation,\n SelectedLineRange,\n VirtualFileMetrics,\n} from '../../types';\nimport { areFileTargetsEqual } from '../../utils/areFileTargetsEqual';\nimport { areOptionsEqual } from '../../utils/areOptionsEqual';\nimport { getLineAnnotationName } from '../../utils/getLineAnnotationName';\nimport { noopRender } from '../constants';\nimport { useCreateEditor } from '../EditContext';\nimport { useVirtualizer } from '../Virtualizer';\nimport { WorkerPoolContext } from '../WorkerPoolContext';\nimport { useStableCallback } from './useStableCallback';\n\nconst useIsomorphicLayoutEffect =\n typeof window === 'undefined' ? useEffect : useLayoutEffect;\n\ninterface AcceptedCompletion<LAnnotation> {\n file: {\n installed: FileContents;\n stale: FileContents;\n } | null;\n annotations: {\n installed: LineAnnotation<LAnnotation>[] | undefined;\n stale: LineAnnotation<LAnnotation>[];\n } | null;\n}\n\ninterface UseFileInstanceProps<LAnnotation, Caret> {\n file: FileContents;\n options: FileOptions<LAnnotation, Caret> | undefined;\n editorOptions: EditorOptions<'file', LAnnotation, Caret> | undefined;\n editStateKey: string | undefined;\n lineAnnotations: LineAnnotation<LAnnotation>[] | undefined;\n selectedLines: SelectedLineRange | null | undefined;\n prerenderedHTML: string | undefined;\n metrics?: VirtualFileMetrics;\n hasGutterRenderUtility: boolean;\n hasCustomHeader: boolean;\n disableWorkerPool: boolean;\n edit: boolean;\n onEditChange?: FileEditChangeHandler<LAnnotation, Caret>;\n onEditComplete?: FileEditCompleteHandler<LAnnotation, Caret>;\n}\n\ninterface UseFileInstanceReturn<LAnnotation> {\n ref(node: HTMLElement | null): void;\n getHoveredLine(): GetHoveredLineResult<'file'> | undefined;\n getAnnotationSlotName(annotation: LineAnnotation<LAnnotation>): string;\n}\n\nexport function useFileInstance<LAnnotation, Caret>({\n file,\n options,\n editorOptions,\n editStateKey,\n lineAnnotations,\n selectedLines,\n prerenderedHTML,\n metrics,\n hasGutterRenderUtility,\n hasCustomHeader,\n disableWorkerPool,\n edit,\n onEditChange: _onEditChange,\n onEditComplete: _onEditComplete,\n}: UseFileInstanceProps<\n LAnnotation,\n Caret\n>): UseFileInstanceReturn<LAnnotation> {\n const simpleVirtualizer = useVirtualizer();\n const controlledSelection = selectedLines !== undefined;\n const poolManager = useContext(WorkerPoolContext);\n const createEditor = useCreateEditor<LAnnotation, Caret>();\n const handleOnEditChange = useStableCallback(\n (event: EditorChangeEvent<'file', LAnnotation, Caret>) =>\n _onEditChange?.(event)\n );\n const onEditChange = _onEditChange != null ? handleOnEditChange : undefined;\n // An accepted completion installs its file on the instance immediately,\n // but the file/lineAnnotations props stay pre-edit until the owner's state\n // update lands. This holds the accepted values so the renders in between do\n // not repaint pre-edit state.\n const acceptedCache = useRef<AcceptedCompletion<LAnnotation> | null>(null);\n const handleOnEditComplete = useStableCallback(\n (event: FileEditCompleteEvent<LAnnotation, Caret>) => {\n const decision = _onEditComplete?.(event) ?? 'reject';\n if (decision === 'accept') {\n acceptedCache.current = {\n file: { installed: event.file, stale: event.originalFile },\n annotations: {\n installed: event.lineAnnotations,\n stale: event.originalLineAnnotations,\n },\n };\n }\n return decision;\n }\n );\n const onEditComplete =\n _onEditComplete != null ? handleOnEditComplete : undefined;\n const instanceRef = useRef<\n File<LAnnotation, Caret> | VirtualizedFile<LAnnotation, Caret> | null\n >(null);\n const disposeEditorRef = useRef<() => void>(null);\n const getEditor = useStableCallback(() => {\n if (createEditor == null) {\n throw new Error('File: EditContext is not attached');\n }\n return createEditor('file', editorOptions ?? {}, editStateKey);\n });\n const ref = useStableCallback((node: HTMLElement | null) => {\n if (node != null) {\n if (instanceRef.current != null) {\n throw new Error(\n 'File: An instance should not already exist when a node is created'\n );\n }\n if (simpleVirtualizer != null) {\n instanceRef.current = new VirtualizedFile(\n mergeFileOptions({\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n options,\n }),\n simpleVirtualizer,\n metrics,\n !disableWorkerPool ? poolManager : undefined,\n true\n );\n } else {\n instanceRef.current = new File(\n mergeFileOptions({\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n options,\n }),\n !disableWorkerPool ? poolManager : undefined,\n true\n );\n }\n if (edit && disposeEditorRef.current == null) {\n disposeEditorRef.current = applyEdit(instanceRef.current, getEditor);\n }\n void instanceRef.current.hydrate({\n file,\n fileContainer: node,\n lineAnnotations,\n prerenderedHTML,\n });\n } else {\n if (instanceRef.current == null) {\n throw new Error('File: A File instance should exist when unmounting');\n }\n instanceRef.current.cleanUp();\n instanceRef.current = null;\n disposeEditorRef.current = null;\n }\n });\n\n useIsomorphicLayoutEffect(() => {\n const { current: instance } = instanceRef;\n if (instance == null) return;\n const newOptions = mergeFileOptions({\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n options,\n });\n // setOptions(undefined) is a no-op, so an undefined merge result never\n // requires a forced render — comparing it against the instance's\n // constructor-default options would force a full render on every commit.\n const forceRender =\n newOptions !== undefined &&\n !areOptionsEqual(instance.options, newOptions);\n instance.setOptions(newOptions);\n // Detach editor before rendering if required\n if (!edit && disposeEditorRef.current != null) {\n const { current: disposeEditor } = disposeEditorRef;\n disposeEditorRef.current = null;\n disposeEditor();\n }\n const resolved = resolveAcceptedValues(\n file,\n lineAnnotations,\n acceptedCache\n );\n void instance.render({\n file: resolved.file,\n lineAnnotations: resolved.lineAnnotations,\n forceRender,\n });\n if (selectedLines !== undefined) {\n instance.setSelectedLines(selectedLines);\n }\n // Attach editor after rendering if required\n if (edit && disposeEditorRef.current == null) {\n disposeEditorRef.current = applyEdit(instance, getEditor);\n }\n });\n\n const getHoveredLine = useCallback(():\n | GetHoveredLineResult<'file'>\n | undefined => {\n return instanceRef.current?.getHoveredLine();\n }, []);\n const getAnnotationSlotName = useCallback(\n (annotation: LineAnnotation<LAnnotation>): string =>\n instanceRef.current?.getAnnotationSlotName(annotation) ??\n getLineAnnotationName(annotation),\n []\n );\n return { ref, getHoveredLine, getAnnotationSlotName };\n}\n\n// Return the installed values in place of props that still match their stale\n// counterparts. Any other prop value clears its half, and the ref clears once\n// both halves have.\nfunction resolveAcceptedValues<LAnnotation>(\n file: FileContents,\n lineAnnotations: LineAnnotation<LAnnotation>[] | undefined,\n acceptedCache: RefObject<AcceptedCompletion<LAnnotation> | null>\n): {\n file: FileContents;\n lineAnnotations: LineAnnotation<LAnnotation>[] | undefined;\n} {\n const { current: accepted } = acceptedCache;\n if (accepted == null) {\n return { file, lineAnnotations };\n }\n const { file: acceptedFiles, annotations: acceptedAnnotations } = accepted;\n let resolvedFile = file;\n if (acceptedFiles != null) {\n if (areFileTargetsEqual(file, acceptedFiles.stale)) {\n resolvedFile = acceptedFiles.installed;\n } else {\n accepted.file = null;\n }\n }\n let resolvedAnnotations = lineAnnotations;\n if (acceptedAnnotations != null) {\n if (lineAnnotations === acceptedAnnotations.stale) {\n resolvedAnnotations = acceptedAnnotations.installed;\n } else {\n accepted.annotations = null;\n }\n }\n if (accepted.file == null && accepted.annotations == null) {\n acceptedCache.current = null;\n }\n return { file: resolvedFile, lineAnnotations: resolvedAnnotations };\n}\n\ninterface MergeFileOptionsProps<LAnnotation, Caret> {\n options: FileOptions<LAnnotation, Caret> | undefined;\n controlledSelection: boolean;\n hasGutterRenderUtility: boolean;\n hasCustomHeader: boolean;\n onEditChange: FileEditChangeHandler<LAnnotation, Caret> | undefined;\n onEditComplete: FileEditCompleteHandler<LAnnotation, Caret> | undefined;\n}\n\nfunction mergeFileOptions<LAnnotation, Caret>({\n options,\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n}: MergeFileOptionsProps<LAnnotation, Caret>):\n | FileOptions<LAnnotation, Caret>\n | undefined {\n const needsReactOverrides =\n controlledSelection ||\n hasGutterRenderUtility ||\n hasCustomHeader ||\n onEditChange != null ||\n onEditComplete != null;\n\n if (!needsReactOverrides) {\n return options;\n }\n\n return {\n ...options,\n controlledSelection,\n renderCustomHeader: hasCustomHeader\n ? noopRender\n : options?.renderCustomHeader,\n renderGutterUtility: hasGutterRenderUtility\n ? noopRender\n : options?.renderGutterUtility,\n onEditChange,\n onEditComplete,\n };\n}\n\nfunction applyEdit<LAnnotation, Caret>(\n instance: File<LAnnotation, Caret>,\n getEditor: () => Editor<'file', LAnnotation, Caret>\n): () => void {\n const editor = getEditor();\n try {\n return editor.edit(instance);\n } catch (error) {\n editor.cleanUp();\n throw error;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useFileInstance.js","names":[],"sources":["../../../src/react/utils/useFileInstance.ts"],"sourcesContent":["import {\n type RefObject,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useRef,\n} from 'react';\n\nimport {\n File,\n type FileEditChangeHandler,\n type FileEditCompleteEvent,\n type FileEditCompleteHandler,\n type FileOptions,\n type FileRenderInput,\n} from '../../components/File';\nimport { VirtualizedFile } from '../../components/VirtualizedFile';\nimport { EMPTY_LINE_ANNOTATIONS } from '../../constants';\nimport type { Editor, EditorChangeEvent, EditorOptions } from '../../edit';\nimport type { GetHoveredLineResult } from '../../managers/InteractionManager';\nimport type {\n FileContents,\n LineAnnotation,\n SelectedLineRange,\n VirtualFileMetrics,\n} from '../../types';\nimport { areFileTargetsEqual } from '../../utils/areFileTargetsEqual';\nimport { areOptionsEqual } from '../../utils/areOptionsEqual';\nimport { getLineAnnotationName } from '../../utils/getLineAnnotationName';\nimport { noopRender } from '../constants';\nimport { useCreateEditor } from '../EditContext';\nimport { useVirtualizer } from '../Virtualizer';\nimport { WorkerPoolContext } from '../WorkerPoolContext';\nimport { useForceUpdate } from './useForceUpdate';\nimport { useNextRenderData } from './useNextRenderData';\nimport { useStableCallback } from './useStableCallback';\n\nconst useIsomorphicLayoutEffect =\n typeof window === 'undefined' ? useEffect : useLayoutEffect;\n\ninterface AcceptedCompletion<LAnnotation> {\n file: {\n installed: FileContents;\n stale: FileContents;\n } | null;\n annotations: {\n installed: LineAnnotation<LAnnotation>[] | undefined;\n stale: LineAnnotation<LAnnotation>[];\n } | null;\n}\n\ninterface UseFileInstanceProps<LAnnotation, Caret> {\n file: FileContents;\n options: FileOptions<LAnnotation, Caret> | undefined;\n editorOptions: EditorOptions<'file', LAnnotation, Caret> | undefined;\n editStateKey: string | undefined;\n lineAnnotations: LineAnnotation<LAnnotation>[] | undefined;\n selectedLines: SelectedLineRange | null | undefined;\n prerenderedHTML: string | undefined;\n metrics?: VirtualFileMetrics;\n hasGutterRenderUtility: boolean;\n hasCustomHeader: boolean;\n disableWorkerPool: boolean;\n edit: boolean;\n onEditChange?: FileEditChangeHandler<LAnnotation, Caret>;\n onEditComplete?: FileEditCompleteHandler<LAnnotation, Caret>;\n}\n\ninterface UseFileInstanceReturn<LAnnotation> {\n file: FileContents;\n lineAnnotations: LineAnnotation<LAnnotation>[];\n ref(node: HTMLElement | null): void;\n getHoveredLine(): GetHoveredLineResult<'file'> | undefined;\n getAnnotationSlotName(annotation: LineAnnotation<LAnnotation>): string;\n}\n\nexport function useFileInstance<LAnnotation, Caret>({\n file,\n options,\n editorOptions,\n editStateKey,\n lineAnnotations,\n selectedLines,\n prerenderedHTML,\n metrics,\n hasGutterRenderUtility,\n hasCustomHeader,\n disableWorkerPool,\n edit,\n onEditChange: _onEditChange,\n onEditComplete: _onEditComplete,\n}: UseFileInstanceProps<\n LAnnotation,\n Caret\n>): UseFileInstanceReturn<LAnnotation> {\n const simpleVirtualizer = useVirtualizer();\n const controlledSelection = selectedLines !== undefined;\n const poolManager = useContext(WorkerPoolContext);\n const createEditor = useCreateEditor<LAnnotation, Caret>();\n const handleOnEditChange = useStableCallback(\n (event: EditorChangeEvent<'file', LAnnotation, Caret>) =>\n _onEditChange?.(event)\n );\n const onEditChange = _onEditChange != null ? handleOnEditChange : undefined;\n // When an edit is accepted, the instance switches to the edited file right\n // away, but the file and lineAnnotations props keep their pre-edit values\n // until the parent passes new ones. This keeps the accepted values so the\n // renders in between don't show the pre-edit file again.\n const acceptedCache = useRef<AcceptedCompletion<LAnnotation> | null>(null);\n const handleOnEditComplete = useStableCallback(\n (event: FileEditCompleteEvent<LAnnotation, Caret>) => {\n const decision = _onEditComplete?.(event) ?? 'reject';\n if (decision === 'accept') {\n acceptedCache.current = {\n file: { installed: event.file, stale: event.originalFile },\n annotations: {\n installed: event.lineAnnotations,\n stale: event.originalLineAnnotations,\n },\n };\n }\n return decision;\n }\n );\n const onEditComplete =\n _onEditComplete != null ? handleOnEditComplete : undefined;\n const instanceRef = useRef<\n File<LAnnotation, Caret> | VirtualizedFile<LAnnotation, Caret> | null\n >(null);\n const forceUpdate = useForceUpdate();\n const accepted = useAcceptedValues(acceptedCache, file, lineAnnotations);\n const renderData = useNextRenderData(instanceRef, accepted) ?? {\n file,\n lineAnnotations: lineAnnotations ?? EMPTY_LINE_ANNOTATIONS,\n };\n const disposeEditorRef = useRef<() => void>(null);\n const getEditor = useStableCallback(() => {\n if (createEditor == null) {\n throw new Error('File: EditContext is not attached');\n }\n return createEditor('file', editorOptions ?? {}, editStateKey);\n });\n const ref = useStableCallback((node: HTMLElement | null) => {\n if (node != null) {\n if (instanceRef.current != null) {\n throw new Error(\n 'File: An instance should not already exist when a node is created'\n );\n }\n if (simpleVirtualizer != null) {\n instanceRef.current = new VirtualizedFile(\n mergeFileOptions({\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n options,\n }),\n simpleVirtualizer,\n metrics,\n !disableWorkerPool ? poolManager : undefined,\n forceUpdate\n );\n } else {\n instanceRef.current = new File(\n mergeFileOptions({\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n options,\n }),\n !disableWorkerPool ? poolManager : undefined,\n forceUpdate\n );\n }\n if (edit && disposeEditorRef.current == null) {\n disposeEditorRef.current = applyEdit(instanceRef.current, getEditor);\n }\n void instanceRef.current.hydrate({\n file,\n fileContainer: node,\n lineAnnotations,\n prerenderedHTML,\n });\n } else {\n if (instanceRef.current == null) {\n throw new Error('File: A File instance should exist when unmounting');\n }\n instanceRef.current.cleanUp();\n instanceRef.current = null;\n disposeEditorRef.current = null;\n }\n });\n\n useIsomorphicLayoutEffect(() => {\n const { current: instance } = instanceRef;\n if (instance == null) return;\n const newOptions = mergeFileOptions({\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n options,\n });\n const forceRender = !areOptionsEqual(instance.options, newOptions);\n instance.setOptions(newOptions);\n // Detach the editor before rendering when editing turns off\n if (!edit && disposeEditorRef.current != null) {\n const { current: disposeEditor } = disposeEditorRef;\n disposeEditorRef.current = null;\n disposeEditor();\n }\n const resolved = resolveAcceptedValues(\n file,\n lineAnnotations,\n acceptedCache\n );\n void instance.render({\n file: resolved.file,\n lineAnnotations: resolved.lineAnnotations,\n forceRender,\n });\n if (selectedLines !== undefined) {\n instance.setSelectedLines(selectedLines);\n }\n // Attach the editor after rendering when editing turns on. The editor can\n // show content that is still highlighting, so render the children again\n // from the edit session.\n if (edit && disposeEditorRef.current == null) {\n disposeEditorRef.current = applyEdit(instance, getEditor);\n forceUpdate();\n }\n });\n\n const getHoveredLine = useCallback(():\n | GetHoveredLineResult<'file'>\n | undefined => {\n return instanceRef.current?.getHoveredLine();\n }, []);\n const getAnnotationSlotName = useCallback(\n (annotation: LineAnnotation<LAnnotation>): string =>\n instanceRef.current?.getAnnotationSlotName(annotation) ??\n getLineAnnotationName(annotation),\n []\n );\n return { ...renderData, ref, getHoveredLine, getAnnotationSlotName };\n}\n\n// Read the accepted values on every render. Entries are only removed in the\n// effect, by resolveAcceptedValues. The cache changes without new props, so\n// this must not be memoized.\nfunction useAcceptedValues<LAnnotation>(\n acceptedCache: RefObject<AcceptedCompletion<LAnnotation> | null>,\n file: FileContents,\n lineAnnotations: LineAnnotation<LAnnotation>[] | undefined\n): FileRenderInput<LAnnotation> {\n 'use no memo';\n // oxlint-disable-next-line react/refs -- the cache changes without new props\n return getAcceptedValues(file, lineAnnotations, acceptedCache.current);\n}\n\n// Use the accepted values for props that still hold their pre-edit values.\nfunction getAcceptedValues<LAnnotation>(\n file: FileContents,\n lineAnnotations: LineAnnotation<LAnnotation>[] | undefined,\n accepted: AcceptedCompletion<LAnnotation> | null\n): FileRenderInput<LAnnotation> {\n return {\n file:\n accepted?.file != null && areFileTargetsEqual(file, accepted.file.stale)\n ? accepted.file.installed\n : file,\n lineAnnotations:\n accepted?.annotations != null &&\n lineAnnotations === accepted.annotations.stale\n ? accepted.annotations.installed\n : lineAnnotations,\n };\n}\n\n// Return the accepted values, and drop each one once its prop no longer holds\n// the pre-edit value. The cache is cleared once both are dropped.\nfunction resolveAcceptedValues<LAnnotation>(\n file: FileContents,\n lineAnnotations: LineAnnotation<LAnnotation>[] | undefined,\n acceptedCache: RefObject<AcceptedCompletion<LAnnotation> | null>\n): FileRenderInput<LAnnotation> {\n const { current: accepted } = acceptedCache;\n const resolved = getAcceptedValues(file, lineAnnotations, accepted);\n if (accepted == null) {\n return resolved;\n }\n if (\n accepted.file != null &&\n !areFileTargetsEqual(file, accepted.file.stale)\n ) {\n accepted.file = null;\n }\n if (lineAnnotations !== accepted.annotations?.stale) {\n accepted.annotations = null;\n }\n if (accepted.file == null && accepted.annotations == null) {\n acceptedCache.current = null;\n }\n return resolved;\n}\n\ninterface MergeFileOptionsProps<LAnnotation, Caret> {\n options: FileOptions<LAnnotation, Caret> | undefined;\n controlledSelection: boolean;\n hasGutterRenderUtility: boolean;\n hasCustomHeader: boolean;\n onEditChange: FileEditChangeHandler<LAnnotation, Caret> | undefined;\n onEditComplete: FileEditCompleteHandler<LAnnotation, Caret> | undefined;\n}\n\nfunction mergeFileOptions<LAnnotation, Caret>({\n options,\n controlledSelection,\n hasCustomHeader,\n hasGutterRenderUtility,\n onEditChange,\n onEditComplete,\n}: MergeFileOptionsProps<LAnnotation, Caret>): FileOptions<LAnnotation, Caret> {\n return {\n ...options,\n controlledSelection,\n renderCustomHeader: hasCustomHeader\n ? noopRender\n : options?.renderCustomHeader,\n renderGutterUtility: hasGutterRenderUtility\n ? noopRender\n : options?.renderGutterUtility,\n onEditChange,\n onEditComplete,\n };\n}\n\n// Attach an editor to the instance, cleaning the editor up if attaching throws.\nfunction applyEdit<LAnnotation, Caret>(\n instance: File<LAnnotation, Caret>,\n getEditor: () => Editor<'file', LAnnotation, Caret>\n): () => void {\n const editor = getEditor();\n try {\n return editor.edit(instance);\n } catch (error) {\n editor.cleanUp();\n throw error;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAsCA,MAAM,4BACJ,OAAO,WAAW,cAAc,YAAY;AAsC9C,SAAgB,gBAAoC,EAClD,MACA,SACA,eACA,cACA,iBACA,eACA,iBACA,SACA,wBACA,iBACA,mBACA,MACA,cAAc,eACd,gBAAgB,mBAIqB;CACrC,MAAM,oBAAoB,eAAe;CACzC,MAAM,sBAAsB,kBAAkB,KAAA;CAC9C,MAAM,cAAc,WAAW,iBAAiB;CAChD,MAAM,eAAe,gBAAoC;CACzD,MAAM,qBAAqB,mBACxB,UACC,gBAAgB,KAAK,CACzB;CACA,MAAM,eAAe,iBAAiB,OAAO,qBAAqB,KAAA;CAKlE,MAAM,gBAAgB,OAA+C,IAAI;CACzE,MAAM,uBAAuB,mBAC1B,UAAqD;EACpD,MAAM,WAAW,kBAAkB,KAAK,KAAK;EAC7C,IAAI,aAAa,UACf,cAAc,UAAU;GACtB,MAAM;IAAE,WAAW,MAAM;IAAM,OAAO,MAAM;GAAa;GACzD,aAAa;IACX,WAAW,MAAM;IACjB,OAAO,MAAM;GACf;EACF;EAEF,OAAO;CACT,CACF;CACA,MAAM,iBACJ,mBAAmB,OAAO,uBAAuB,KAAA;CACnD,MAAM,cAAc,OAElB,IAAI;CACN,MAAM,cAAc,eAAe;CACnC,MAAM,WAAW,kBAAkB,eAAe,MAAM,eAAe;CACvE,MAAM,aAAa,kBAAkB,aAAa,QAAQ,KAAK;EAC7D;EACA,iBAAiB,mBAAmB;CACtC;CACA,MAAM,mBAAmB,OAAmB,IAAI;CAChD,MAAM,YAAY,wBAAwB;EACxC,IAAI,gBAAgB,MAClB,MAAM,IAAI,MAAM,mCAAmC;EAErD,OAAO,aAAa,QAAQ,iBAAiB,CAAC,GAAG,YAAY;CAC/D,CAAC;CACD,MAAM,MAAM,mBAAmB,SAA6B;EAC1D,IAAI,QAAQ,MAAM;GAChB,IAAI,YAAY,WAAW,MACzB,MAAM,IAAI,MACR,mEACF;GAEF,IAAI,qBAAqB,MACvB,YAAY,UAAU,IAAI,gBACxB,iBAAiB;IACf;IACA;IACA;IACA;IACA;IACA;GACF,CAAC,GACD,mBACA,SACA,CAAC,oBAAoB,cAAc,KAAA,GACnC,WACF;QAEA,YAAY,UAAU,IAAI,KACxB,iBAAiB;IACf;IACA;IACA;IACA;IACA;IACA;GACF,CAAC,GACD,CAAC,oBAAoB,cAAc,KAAA,GACnC,WACF;GAEF,IAAI,QAAQ,iBAAiB,WAAW,MACtC,iBAAiB,UAAU,UAAU,YAAY,SAAS,SAAS;GAErE,YAAiB,QAAQ,QAAQ;IAC/B;IACA,eAAe;IACf;IACA;GACF,CAAC;EACH,OAAO;GACL,IAAI,YAAY,WAAW,MACzB,MAAM,IAAI,MAAM,oDAAoD;GAEtE,YAAY,QAAQ,QAAQ;GAC5B,YAAY,UAAU;GACtB,iBAAiB,UAAU;EAC7B;CACF,CAAC;CAED,gCAAgC;EAC9B,MAAM,EAAE,SAAS,aAAa;EAC9B,IAAI,YAAY,MAAM;EACtB,MAAM,aAAa,iBAAiB;GAClC;GACA;GACA;GACA;GACA;GACA;EACF,CAAC;EACD,MAAM,cAAc,CAAC,gBAAgB,SAAS,SAAS,UAAU;EACjE,SAAS,WAAW,UAAU;EAE9B,IAAI,CAAC,QAAQ,iBAAiB,WAAW,MAAM;GAC7C,MAAM,EAAE,SAAS,kBAAkB;GACnC,iBAAiB,UAAU;GAC3B,cAAc;EAChB;EACA,MAAM,WAAW,sBACf,MACA,iBACA,aACF;EACA,SAAc,OAAO;GACnB,MAAM,SAAS;GACf,iBAAiB,SAAS;GAC1B;EACF,CAAC;EACD,IAAI,kBAAkB,KAAA,GACpB,SAAS,iBAAiB,aAAa;EAKzC,IAAI,QAAQ,iBAAiB,WAAW,MAAM;GAC5C,iBAAiB,UAAU,UAAU,UAAU,SAAS;GACxD,YAAY;EACd;CACF,CAAC;CAED,MAAM,iBAAiB,kBAEN;EACf,OAAO,YAAY,SAAS,eAAe;CAC7C,GAAG,CAAC,CAAC;CACL,MAAM,wBAAwB,aAC3B,eACC,YAAY,SAAS,sBAAsB,UAAU,KACrD,sBAAsB,UAAU,GAClC,CAAC,CACH;CACA,OAAO;EAAE,GAAG;EAAY;EAAK;EAAgB;CAAsB;AACrE;AAKA,SAAS,kBACP,eACA,MACA,iBAC8B;CAC9B;CAEA,OAAO,kBAAkB,MAAM,iBAAiB,cAAc,OAAO;AACvE;AAGA,SAAS,kBACP,MACA,iBACA,UAC8B;CAC9B,OAAO;EACL,MACE,UAAU,QAAQ,QAAQ,oBAAoB,MAAM,SAAS,KAAK,KAAK,IACnE,SAAS,KAAK,YACd;EACN,iBACE,UAAU,eAAe,QACzB,oBAAoB,SAAS,YAAY,QACrC,SAAS,YAAY,YACrB;CACR;AACF;AAIA,SAAS,sBACP,MACA,iBACA,eAC8B;CAC9B,MAAM,EAAE,SAAS,aAAa;CAC9B,MAAM,WAAW,kBAAkB,MAAM,iBAAiB,QAAQ;CAClE,IAAI,YAAY,MACd,OAAO;CAET,IACE,SAAS,QAAQ,QACjB,CAAC,oBAAoB,MAAM,SAAS,KAAK,KAAK,GAE9C,SAAS,OAAO;CAElB,IAAI,oBAAoB,SAAS,aAAa,OAC5C,SAAS,cAAc;CAEzB,IAAI,SAAS,QAAQ,QAAQ,SAAS,eAAe,MACnD,cAAc,UAAU;CAE1B,OAAO;AACT;AAWA,SAAS,iBAAqC,EAC5C,SACA,qBACA,iBACA,wBACA,cACA,kBAC6E;CAC7E,OAAO;EACL,GAAG;EACH;EACA,oBAAoB,kBAChB,aACA,SAAS;EACb,qBAAqB,yBACjB,aACA,SAAS;EACb;EACA;CACF;AACF;AAGA,SAAS,UACP,UACA,WACY;CACZ,MAAM,SAAS,UAAU;CACzB,IAAI;EACF,OAAO,OAAO,KAAK,QAAQ;CAC7B,SAAS,OAAO;EACd,OAAO,QAAQ;EACf,MAAM;CACR;AACF"}
@@ -0,0 +1,5 @@
1
+ //#region src/react/utils/useForceUpdate.d.ts
2
+ declare function useForceUpdate(): () => void;
3
+ //#endregion
4
+ export { useForceUpdate };
5
+ //# sourceMappingURL=useForceUpdate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useForceUpdate.d.ts","names":[],"sources":["../../../src/react/utils/useForceUpdate.ts"],"mappings":";iBAGgB"}
@@ -0,0 +1,27 @@
1
+ import { useState, useSyncExternalStore } from "react";
2
+ //#region src/react/utils/useForceUpdate.ts
3
+ function useForceUpdate() {
4
+ const [store] = useState(() => {
5
+ let version = 0;
6
+ let listener;
7
+ return {
8
+ getSnapshot: () => version,
9
+ subscribe(next) {
10
+ listener = next;
11
+ return () => {
12
+ listener = void 0;
13
+ };
14
+ },
15
+ forceUpdate() {
16
+ version++;
17
+ listener?.();
18
+ }
19
+ };
20
+ });
21
+ useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
22
+ return store.forceUpdate;
23
+ }
24
+ //#endregion
25
+ export { useForceUpdate };
26
+
27
+ //# sourceMappingURL=useForceUpdate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useForceUpdate.js","names":[],"sources":["../../../src/react/utils/useForceUpdate.ts"],"sourcesContent":["import { useState, useSyncExternalStore } from 'react';\n\n// A helper hook to force a react component to re-render\nexport function useForceUpdate(): () => void {\n const [store] = useState(() => {\n let version = 0;\n let listener: (() => void) | undefined;\n return {\n getSnapshot: () => version,\n subscribe(next: () => void) {\n listener = next;\n return () => {\n listener = undefined;\n };\n },\n forceUpdate() {\n version++;\n listener?.();\n },\n };\n });\n useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n return store.forceUpdate;\n}\n"],"mappings":";;AAGA,SAAgB,iBAA6B;CAC3C,MAAM,CAAC,SAAS,eAAe;EAC7B,IAAI,UAAU;EACd,IAAI;EACJ,OAAO;GACL,mBAAmB;GACnB,UAAU,MAAkB;IAC1B,WAAW;IACX,aAAa;KACX,WAAW,KAAA;IACb;GACF;GACA,cAAc;IACZ;IACA,WAAW;GACb;EACF;CACF,CAAC;CACD,qBAAqB,MAAM,WAAW,MAAM,aAAa,MAAM,WAAW;CAC1E,OAAO,MAAM;AACf"}
@@ -0,0 +1,9 @@
1
+ import { RefObject } from "react";
2
+ //#region src/react/utils/useNextRenderData.d.ts
3
+ interface NextRenderDataSource<TInput, TData> {
4
+ __getNextRenderData(input: TInput): TData;
5
+ }
6
+ declare function useNextRenderData<TInput, TData>(instanceRef: RefObject<NextRenderDataSource<TInput, TData> | null>, input: TInput): TData | undefined;
7
+ //#endregion
8
+ export { useNextRenderData };
9
+ //# sourceMappingURL=useNextRenderData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useNextRenderData.d.ts","names":[],"sources":["../../../src/react/utils/useNextRenderData.ts"],"mappings":";;UAEU,qBAAqB,QAAQ;EACrC,oBAAoB,OAAO,SAAS;;iBAMtB,kBAAkB,QAAQ,OACxC,aAAa,UAAU,qBAAqB,QAAQ,gBACpD,OAAO,SACN"}