@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.
- package/README.md +4 -3
- package/dist/components/CodeView.d.ts +3 -2
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +24 -19
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/File.d.ts +31 -9
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/File.js +176 -90
- package/dist/components/File.js.map +1 -1
- package/dist/components/FileDiff.d.ts +32 -9
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js +225 -131
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/FileStream.d.ts +6 -4
- package/dist/components/FileStream.d.ts.map +1 -1
- package/dist/components/FileStream.js +49 -36
- package/dist/components/FileStream.js.map +1 -1
- package/dist/components/UnresolvedFile.d.ts +14 -4
- package/dist/components/UnresolvedFile.d.ts.map +1 -1
- package/dist/components/UnresolvedFile.js +35 -16
- package/dist/components/UnresolvedFile.js.map +1 -1
- package/dist/components/VirtualizedFile.d.ts +3 -2
- package/dist/components/VirtualizedFile.d.ts.map +1 -1
- package/dist/components/VirtualizedFile.js +28 -20
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.d.ts +3 -2
- package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +31 -24
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/constants.d.ts +4 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -1
- package/dist/constants.js.map +1 -1
- package/dist/editor/editor.d.ts +2 -1
- package/dist/editor/editor.d.ts.map +1 -1
- package/dist/editor/editor.js +5 -1
- package/dist/editor/editor.js.map +1 -1
- package/dist/editor/platform.d.ts +1 -1
- package/dist/editor/platform.js +5 -4
- package/dist/editor/platform.js.map +1 -1
- package/dist/editor/selection.d.ts +2 -2
- package/dist/editor/selection.d.ts.map +1 -1
- package/dist/editor/selection.js +31 -6
- package/dist/editor/selection.js.map +1 -1
- package/dist/editor/tokenizer.d.ts +6 -4
- package/dist/editor/tokenizer.d.ts.map +1 -1
- package/dist/editor/tokenizer.js +25 -470
- package/dist/editor/tokenizer.js.map +1 -1
- package/dist/highlighter/DiffsEditorTokenizer.d.ts +16 -0
- package/dist/highlighter/DiffsEditorTokenizer.d.ts.map +1 -0
- package/dist/highlighter/DiffsEditorTokenizer.js +0 -0
- package/dist/highlighter/DiffsHighlighter.d.ts +41 -0
- package/dist/highlighter/DiffsHighlighter.d.ts.map +1 -0
- package/dist/highlighter/DiffsHighlighter.js +39 -0
- package/dist/highlighter/DiffsHighlighter.js.map +1 -0
- package/dist/highlighter/backends/highlights.d.ts +26 -0
- package/dist/highlighter/backends/highlights.d.ts.map +1 -0
- package/dist/highlighter/backends/highlights.js +71 -0
- package/dist/highlighter/backends/highlights.js.map +1 -0
- package/dist/highlighter/backends/shiki.d.ts +27 -0
- package/dist/highlighter/backends/shiki.d.ts.map +1 -0
- package/dist/highlighter/backends/shiki.js +107 -0
- package/dist/highlighter/backends/shiki.js.map +1 -0
- package/dist/highlighter/highlighterType.d.ts +13 -0
- package/dist/highlighter/highlighterType.d.ts.map +1 -0
- package/dist/highlighter/highlighterType.js +32 -0
- package/dist/highlighter/highlighterType.js.map +1 -0
- package/dist/highlighter/highlights-editor.d.ts +24 -0
- package/dist/highlighter/highlights-editor.d.ts.map +1 -0
- package/dist/highlighter/highlights-editor.js +166 -0
- package/dist/highlighter/highlights-editor.js.map +1 -0
- package/dist/highlighter/highlights-stream.d.ts +20 -0
- package/dist/highlighter/highlights-stream.d.ts.map +1 -0
- package/dist/highlighter/highlights-stream.js +93 -0
- package/dist/highlighter/highlights-stream.js.map +1 -0
- package/dist/highlighter/languages/areLanguagesAttached.d.ts +2 -1
- package/dist/highlighter/languages/areLanguagesAttached.d.ts.map +1 -1
- package/dist/highlighter/languages/areLanguagesAttached.js +4 -6
- package/dist/highlighter/languages/areLanguagesAttached.js.map +1 -1
- package/dist/highlighter/languages/attachResolvedLanguages.d.ts +6 -1
- package/dist/highlighter/languages/attachResolvedLanguages.d.ts.map +1 -1
- package/dist/highlighter/languages/attachResolvedLanguages.js +6 -11
- package/dist/highlighter/languages/attachResolvedLanguages.js.map +1 -1
- package/dist/highlighter/languages/constants.d.ts +1 -1
- package/dist/highlighter/languages/getResolvedLanguages.d.ts +1 -1
- package/dist/highlighter/languages/getResolvedOrResolveLanguage.d.ts +1 -1
- package/dist/highlighter/languages/resolveLanguage.d.ts +1 -1
- package/dist/highlighter/languages/resolveLanguage.d.ts.map +1 -1
- package/dist/highlighter/languages/resolveLanguage.js +19 -16
- package/dist/highlighter/languages/resolveLanguage.js.map +1 -1
- package/dist/highlighter/languages/resolveLanguages.d.ts +1 -1
- package/dist/highlighter/shared_highlighter.d.ts +24 -9
- package/dist/highlighter/shared_highlighter.d.ts.map +1 -1
- package/dist/highlighter/shared_highlighter.js +59 -47
- package/dist/highlighter/shared_highlighter.js.map +1 -1
- package/dist/highlighter/shiki-editor.d.ts +25 -0
- package/dist/highlighter/shiki-editor.d.ts.map +1 -0
- package/dist/highlighter/shiki-editor.js +483 -0
- package/dist/highlighter/shiki-editor.js.map +1 -0
- package/dist/highlighter/shiki-stream.d.ts +20 -0
- package/dist/highlighter/shiki-stream.d.ts.map +1 -0
- package/dist/highlighter/shiki-stream.js +60 -0
- package/dist/highlighter/shiki-stream.js.map +1 -0
- package/dist/highlighter/stream-tokenizer.d.ts +40 -0
- package/dist/highlighter/stream-tokenizer.d.ts.map +1 -0
- package/dist/highlighter/stream-tokenizer.js +70 -0
- package/dist/highlighter/stream-tokenizer.js.map +1 -0
- package/dist/highlighter/themes/areThemesAttached.d.ts +3 -2
- package/dist/highlighter/themes/areThemesAttached.d.ts.map +1 -1
- package/dist/highlighter/themes/areThemesAttached.js +5 -4
- package/dist/highlighter/themes/areThemesAttached.js.map +1 -1
- package/dist/highlighter/themes/attachResolvedThemes.d.ts +5 -2
- package/dist/highlighter/themes/attachResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/attachResolvedThemes.js +4 -16
- package/dist/highlighter/themes/attachResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/cleanUpResolvedThemes.d.ts +3 -1
- package/dist/highlighter/themes/cleanUpResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/cleanUpResolvedThemes.js +8 -5
- package/dist/highlighter/themes/cleanUpResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/createCSSVariablesTheme.d.ts +7 -0
- package/dist/highlighter/themes/createCSSVariablesTheme.d.ts.map +1 -0
- package/dist/highlighter/themes/createCSSVariablesTheme.js +89 -0
- package/dist/highlighter/themes/createCSSVariablesTheme.js.map +1 -0
- package/dist/highlighter/themes/createCachedLoader.d.ts +5 -0
- package/dist/highlighter/themes/createCachedLoader.d.ts.map +1 -0
- package/dist/highlighter/themes/createCachedLoader.js +15 -0
- package/dist/highlighter/themes/createCachedLoader.js.map +1 -0
- package/dist/highlighter/themes/getResolvedOrResolveTheme.d.ts +3 -2
- package/dist/highlighter/themes/getResolvedOrResolveTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/getResolvedOrResolveTheme.js +4 -4
- package/dist/highlighter/themes/getResolvedOrResolveTheme.js.map +1 -1
- package/dist/highlighter/themes/getResolvedThemes.d.ts +3 -2
- package/dist/highlighter/themes/getResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/getResolvedThemes.js +4 -3
- package/dist/highlighter/themes/getResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/hasResolvedThemes.d.ts +2 -2
- package/dist/highlighter/themes/hasResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/hasResolvedThemes.js +4 -3
- package/dist/highlighter/themes/hasResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/registerCustomCSSVariableTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/registerCustomCSSVariableTheme.js +3 -3
- package/dist/highlighter/themes/registerCustomCSSVariableTheme.js.map +1 -1
- package/dist/highlighter/themes/registerCustomTheme.d.ts +9 -4
- package/dist/highlighter/themes/registerCustomTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/registerCustomTheme.js +8 -16
- package/dist/highlighter/themes/registerCustomTheme.js.map +1 -1
- package/dist/highlighter/themes/resolveTheme.d.ts +3 -2
- package/dist/highlighter/themes/resolveTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/resolveTheme.js +4 -7
- package/dist/highlighter/themes/resolveTheme.js.map +1 -1
- package/dist/highlighter/themes/resolveThemes.d.ts +3 -2
- package/dist/highlighter/themes/resolveThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/resolveThemes.js +4 -7
- package/dist/highlighter/themes/resolveThemes.js.map +1 -1
- package/dist/highlighter/themes/themeResolver.d.ts +10 -4
- package/dist/highlighter/themes/themeResolver.d.ts.map +1 -1
- package/dist/highlighter/themes/themeResolver.js +141 -2
- package/dist/highlighter/themes/themeResolver.js.map +1 -1
- package/dist/highlighter/themes/types.d.ts +23 -0
- package/dist/highlighter/themes/types.d.ts.map +1 -0
- package/dist/highlighter/themes/types.js +0 -0
- package/dist/highlighter/tokenizer-types.d.ts +35 -0
- package/dist/highlighter/tokenizer-types.d.ts.map +1 -0
- package/dist/highlighter/tokenizer-types.js +0 -0
- package/dist/highlighter/types.d.ts +55 -0
- package/dist/highlighter/types.d.ts.map +1 -0
- package/dist/highlighter/types.js +0 -0
- package/dist/index.d.ts +22 -13
- package/dist/index.js +21 -18
- package/dist/managers/InteractionManager.d.ts.map +1 -1
- package/dist/managers/InteractionManager.js +2 -2
- package/dist/managers/InteractionManager.js.map +1 -1
- package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts +9 -1
- package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts.map +1 -1
- package/dist/react/CodeView.d.ts +4 -3
- package/dist/react/CodeView.d.ts.map +1 -1
- package/dist/react/CodeView.js +47 -38
- package/dist/react/CodeView.js.map +1 -1
- package/dist/react/File.js +3 -3
- package/dist/react/File.js.map +1 -1
- package/dist/react/FileDiff.js +3 -3
- package/dist/react/FileDiff.js.map +1 -1
- package/dist/react/MultiFileDiff.js +2 -2
- package/dist/react/MultiFileDiff.js.map +1 -1
- package/dist/react/PatchDiff.js +3 -3
- package/dist/react/PatchDiff.js.map +1 -1
- package/dist/react/UnresolvedFile.js +2 -2
- package/dist/react/UnresolvedFile.js.map +1 -1
- package/dist/react/index.d.ts +9 -4
- package/dist/react/types.d.ts +4 -2
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/utils/renderDiffChildren.js +1 -1
- package/dist/react/utils/renderDiffChildren.js.map +1 -1
- package/dist/react/utils/renderFileChildren.js +1 -1
- package/dist/react/utils/renderFileChildren.js.map +1 -1
- package/dist/react/utils/useFileDiffInstance.d.ts +1 -0
- package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileDiffInstance.js +29 -24
- package/dist/react/utils/useFileDiffInstance.js.map +1 -1
- package/dist/react/utils/useFileInstance.d.ts +2 -0
- package/dist/react/utils/useFileInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileInstance.js +38 -28
- package/dist/react/utils/useFileInstance.js.map +1 -1
- package/dist/react/utils/useForceUpdate.d.ts +5 -0
- package/dist/react/utils/useForceUpdate.d.ts.map +1 -0
- package/dist/react/utils/useForceUpdate.js +27 -0
- package/dist/react/utils/useForceUpdate.js.map +1 -0
- package/dist/react/utils/useNextRenderData.d.ts +9 -0
- package/dist/react/utils/useNextRenderData.d.ts.map +1 -0
- package/dist/react/utils/useNextRenderData.js +9 -0
- package/dist/react/utils/useNextRenderData.js.map +1 -0
- package/dist/react/utils/useUnresolvedFileInstance.d.ts +1 -0
- package/dist/react/utils/useUnresolvedFileInstance.d.ts.map +1 -1
- package/dist/react/utils/useUnresolvedFileInstance.js +26 -11
- package/dist/react/utils/useUnresolvedFileInstance.js.map +1 -1
- package/dist/renderers/DiffHunksRenderer.d.ts +4 -2
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +82 -43
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.d.ts +6 -2
- package/dist/renderers/FileRenderer.d.ts.map +1 -1
- package/dist/renderers/FileRenderer.js +77 -43
- package/dist/renderers/FileRenderer.js.map +1 -1
- package/dist/renderers/UnresolvedFileHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/UnresolvedFileHunksRenderer.js +1 -1
- package/dist/renderers/UnresolvedFileHunksRenderer.js.map +1 -1
- package/dist/shiki-stream/index.d.ts +3 -3
- package/dist/shiki-stream/index.js +1 -2
- package/dist/shiki-stream/stream.d.ts +4 -4
- package/dist/shiki-stream/stream.d.ts.map +1 -1
- package/dist/shiki-stream/stream.js +20 -9
- package/dist/shiki-stream/stream.js.map +1 -1
- package/dist/shiki-stream/types.d.ts +7 -38
- package/dist/shiki-stream/types.d.ts.map +1 -1
- package/dist/ssr/index.d.ts +7 -2
- package/dist/ssr/renderHTML.js +2 -2
- package/dist/ssr/renderHTML.js.map +1 -1
- package/dist/style.js +1 -1
- package/dist/style.js.map +1 -1
- package/dist/types.d.ts +20 -11
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/canUseWASM.d.ts +13 -0
- package/dist/utils/canUseWASM.d.ts.map +1 -0
- package/dist/utils/canUseWASM.js +59 -0
- package/dist/utils/canUseWASM.js.map +1 -0
- package/dist/utils/createSpanNodeFromToken.d.ts +3 -2
- package/dist/utils/createSpanNodeFromToken.d.ts.map +1 -1
- package/dist/utils/createSpanNodeFromToken.js +4 -5
- package/dist/utils/createSpanNodeFromToken.js.map +1 -1
- package/dist/utils/cssWrappers.d.ts.map +1 -1
- package/dist/utils/cssWrappers.js +12 -0
- package/dist/utils/cssWrappers.js.map +1 -1
- package/dist/utils/getCodeViewItemRenderData.d.ts +10 -0
- package/dist/utils/getCodeViewItemRenderData.d.ts.map +1 -0
- package/dist/utils/getCodeViewItemRenderData.js +19 -0
- package/dist/utils/getCodeViewItemRenderData.js.map +1 -0
- package/dist/utils/getHighlighterOptions.d.ts.map +1 -1
- package/dist/utils/getHighlighterOptions.js +3 -2
- package/dist/utils/getHighlighterOptions.js.map +1 -1
- package/dist/utils/getHighlighterThemeStyles.d.ts +2 -1
- package/dist/utils/getHighlighterThemeStyles.d.ts.map +1 -1
- package/dist/utils/getHighlighterThemeStyles.js +13 -3
- package/dist/utils/getHighlighterThemeStyles.js.map +1 -1
- package/dist/utils/getTokenOptions.d.ts +7 -0
- package/dist/utils/getTokenOptions.d.ts.map +1 -0
- package/dist/utils/getTokenOptions.js +16 -0
- package/dist/utils/getTokenOptions.js.map +1 -0
- package/dist/utils/hastToHtml.d.ts +10 -0
- package/dist/utils/hastToHtml.d.ts.map +1 -0
- package/dist/utils/hastToHtml.js +125 -0
- package/dist/utils/hastToHtml.js.map +1 -0
- package/dist/utils/hydratePartialDiff.js +4 -0
- package/dist/utils/hydratePartialDiff.js.map +1 -1
- package/dist/utils/parseDiffDecorations.d.ts +2 -1
- package/dist/utils/parseDiffDecorations.d.ts.map +1 -1
- package/dist/utils/parseMergeConflictDiffFromFile.d.ts.map +1 -1
- package/dist/utils/parseMergeConflictDiffFromFile.js +2 -0
- package/dist/utils/parseMergeConflictDiffFromFile.js.map +1 -1
- package/dist/utils/parsePatchFiles.d.ts.map +1 -1
- package/dist/utils/parsePatchFiles.js +24 -4
- package/dist/utils/parsePatchFiles.js.map +1 -1
- package/dist/utils/renderDiffWithHighlighter.d.ts +3 -2
- package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
- package/dist/utils/renderDiffWithHighlighter.js +33 -48
- package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
- package/dist/utils/renderFileWithHighlighter.d.ts +3 -2
- package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
- package/dist/utils/renderFileWithHighlighter.js +10 -26
- package/dist/utils/renderFileWithHighlighter.js.map +1 -1
- package/dist/utils/renderTokenLines.d.ts +22 -0
- package/dist/utils/renderTokenLines.d.ts.map +1 -0
- package/dist/utils/renderTokenLines.js +250 -0
- package/dist/utils/renderTokenLines.js.map +1 -0
- package/dist/utils/resolvePreferredHighlighter.d.ts +13 -0
- package/dist/utils/resolvePreferredHighlighter.d.ts.map +1 -0
- package/dist/utils/resolvePreferredHighlighter.js +11 -0
- package/dist/utils/resolvePreferredHighlighter.js.map +1 -0
- package/dist/utils/resolveRegion.js +20 -10
- package/dist/utils/resolveRegion.js.map +1 -1
- package/dist/utils/setDeferredArrayItem.d.ts +5 -0
- package/dist/utils/setDeferredArrayItem.d.ts.map +1 -0
- package/dist/utils/setDeferredArrayItem.js +39 -0
- package/dist/utils/setDeferredArrayItem.js.map +1 -0
- package/dist/utils/tokenStyle.d.ts +11 -0
- package/dist/utils/tokenStyle.d.ts.map +1 -0
- package/dist/utils/tokenStyle.js +32 -0
- package/dist/utils/tokenStyle.js.map +1 -0
- package/dist/utils/tokensToHtml.d.ts +11 -0
- package/dist/utils/tokensToHtml.d.ts.map +1 -0
- package/dist/utils/tokensToHtml.js +48 -0
- package/dist/utils/tokensToHtml.js.map +1 -0
- package/dist/utils/updateDiffHunks.d.ts +2 -2
- package/dist/utils/updateDiffHunks.d.ts.map +1 -1
- package/dist/utils/updateDiffHunks.js +7 -3
- package/dist/utils/updateDiffHunks.js.map +1 -1
- package/dist/utils/wrapTokenFragments.js.map +1 -1
- package/dist/worker/WorkerPoolManager.d.ts +14 -2
- package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
- package/dist/worker/WorkerPoolManager.js +155 -67
- package/dist/worker/WorkerPoolManager.js.map +1 -1
- package/dist/worker/hastLinesTransport.d.ts +14 -0
- package/dist/worker/hastLinesTransport.d.ts.map +1 -0
- package/dist/worker/hastLinesTransport.js +156 -0
- package/dist/worker/hastLinesTransport.js.map +1 -0
- package/dist/worker/highlights-CpZm9DAR.js +317 -0
- package/dist/worker/highlights-CpZm9DAR.js.map +1 -0
- package/dist/worker/index.d.ts +1 -1
- package/dist/worker/shiki-Ci4cdHsM.js +697 -0
- package/dist/worker/shiki-Ci4cdHsM.js.map +1 -0
- package/dist/worker/stream-tokenizer-DK9xp5M5.js +427 -0
- package/dist/worker/stream-tokenizer-DK9xp5M5.js.map +1 -0
- package/dist/worker/types.d.ts +16 -3
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/worker-portable.js +41 -13337
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +681 -349
- package/dist/worker/worker.js.map +1 -1
- package/dist/worker/workerMessage.d.ts +24 -0
- package/dist/worker/workerMessage.d.ts.map +1 -0
- package/dist/worker/workerMessage.js +0 -0
- package/package.json +5 -3
- package/dist/highlighter/themes/constants.d.ts +0 -5
- package/dist/highlighter/themes/constants.d.ts.map +0 -1
- package/dist/highlighter/themes/constants.js +0 -6
- package/dist/highlighter/themes/constants.js.map +0 -1
- package/dist/highlighter/themes/themeResolution.d.ts +0 -7
- package/dist/highlighter/themes/themeResolution.d.ts.map +0 -1
- package/dist/highlighter/themes/themeResolution.js +0 -21
- package/dist/highlighter/themes/themeResolution.js.map +0 -1
- package/dist/shiki-stream/tokenizer.d.ts +0 -23
- package/dist/shiki-stream/tokenizer.d.ts.map +0 -1
- package/dist/shiki-stream/tokenizer.js +0 -72
- package/dist/shiki-stream/tokenizer.js.map +0 -1
- package/dist/utils/createTransformerWithState.d.ts +0 -12
- package/dist/utils/createTransformerWithState.d.ts.map +0 -1
- package/dist/utils/createTransformerWithState.js +0 -89
- package/dist/utils/createTransformerWithState.js.map +0 -1
- package/dist/worker/wasm-B9ZqxnKj.js +0 -8
- package/dist/worker/wasm-B9ZqxnKj.js.map +0 -1
package/dist/react/types.d.ts
CHANGED
|
@@ -37,7 +37,8 @@ interface DiffBasePropsReact<LAnnotation, Caret> {
|
|
|
37
37
|
metrics?: VirtualFileMetrics;
|
|
38
38
|
lineAnnotations?: DiffLineAnnotation<LAnnotation>[];
|
|
39
39
|
selectedLines?: SelectedLineRange | null;
|
|
40
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
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,
|
|
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":";;;;;;
|
|
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,
|
|
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,
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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":";;;;;;
|
|
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,
|
|
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,
|
|
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 =
|
|
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)
|
|
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
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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":"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"}
|
|
@@ -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"}
|