@pierre/diffs 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/components/CodeView.d.ts +2 -0
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +36 -1
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts +7 -3
  6. package/dist/components/File.d.ts.map +1 -1
  7. package/dist/components/File.js +70 -53
  8. package/dist/components/File.js.map +1 -1
  9. package/dist/components/FileDiff.d.ts +7 -3
  10. package/dist/components/FileDiff.d.ts.map +1 -1
  11. package/dist/components/FileDiff.js +79 -49
  12. package/dist/components/FileDiff.js.map +1 -1
  13. package/dist/components/FileStream.js +1 -1
  14. package/dist/components/VirtualizedFile.d.ts +1 -0
  15. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  16. package/dist/components/VirtualizedFile.js +8 -8
  17. package/dist/components/VirtualizedFile.js.map +1 -1
  18. package/dist/components/VirtualizedFileDiff.d.ts +1 -0
  19. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  20. package/dist/components/VirtualizedFileDiff.js +8 -8
  21. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  22. package/dist/editor/editor.d.ts +1 -1
  23. package/dist/editor/editor.d.ts.map +1 -1
  24. package/dist/editor/editor.js +8 -4
  25. package/dist/editor/editor.js.map +1 -1
  26. package/dist/highlighter/shared_highlighter.d.ts +6 -2
  27. package/dist/highlighter/shared_highlighter.d.ts.map +1 -1
  28. package/dist/highlighter/shared_highlighter.js +7 -3
  29. package/dist/highlighter/shared_highlighter.js.map +1 -1
  30. package/dist/highlighter/themes/areThemesAttached.js +1 -1
  31. package/dist/index.js +13 -13
  32. package/dist/renderers/DiffHunksRenderer.d.ts +1 -1
  33. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  34. package/dist/renderers/DiffHunksRenderer.js +8 -9
  35. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  36. package/dist/renderers/FileRenderer.d.ts +1 -1
  37. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  38. package/dist/renderers/FileRenderer.js +5 -5
  39. package/dist/renderers/FileRenderer.js.map +1 -1
  40. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  41. package/dist/worker/WorkerPoolManager.js +11 -2
  42. package/dist/worker/WorkerPoolManager.js.map +1 -1
  43. package/package.json +1 -1
@@ -1,4 +1,6 @@
1
1
  import { CUSTOM_HEADER_SLOT_ID, DEFAULT_THEMES, EMPTY_RENDER_RANGE, HEADER_FILENAME_SUFFIX_SLOT_ID, HEADER_METADATA_SLOT_ID, HEADER_PREFIX_SLOT_ID } from "../constants.js";
2
+ import { getThemes } from "../utils/getThemes.js";
3
+ import { getHighlighterIfLoaded, getSharedHighlighter } from "../highlighter/shared_highlighter.js";
2
4
  import { dequeueRender, queueRender } from "../managers/UniversalRenderingManager.js";
3
5
  import { areThemesEqual } from "../utils/areThemesEqual.js";
4
6
  import { isStyleNode } from "../utils/isStyleNode.js";
@@ -109,9 +111,7 @@ var FileDiff = class {
109
111
  deletionFile;
110
112
  additionFile;
111
113
  fileDiff;
112
- editSessionDiff;
113
- editSessionAnnotations;
114
- outgoingSessionDiff;
114
+ editSession;
115
115
  renderedDiff;
116
116
  renderRange;
117
117
  pendingFiles;
@@ -143,6 +143,9 @@ var FileDiff = class {
143
143
  handleHighlightRender = () => {
144
144
  this.rerender();
145
145
  };
146
+ getTheme() {
147
+ return this.workerManager?.getDiffRenderOptions().theme ?? this.options.theme ?? DEFAULT_THEMES;
148
+ }
146
149
  getHunksRendererOptions(options) {
147
150
  return getDiffHunksRendererOptions(options);
148
151
  }
@@ -238,24 +241,24 @@ var FileDiff = class {
238
241
  return true;
239
242
  }
240
243
  hasThemeChanged() {
241
- return this.appliedThemeCSS != null && !areThemesEqual(this.appliedThemeCSS.theme, this.options.theme ?? DEFAULT_THEMES);
244
+ return this.appliedThemeCSS != null && !areThemesEqual(this.appliedThemeCSS.theme, this.getTheme());
242
245
  }
243
246
  getHoveredLine = () => {
244
247
  return this.interactionManager.getHoveredLine();
245
248
  };
246
249
  getAnnotationSlotName = (annotation) => {
247
- return resolveEditSessionSlotName(this.editSessionAnnotations, annotation, getLineAnnotationName);
250
+ return resolveEditSessionSlotName(this.editSession?.annotations, annotation, getLineAnnotationName);
248
251
  };
249
252
  getLatestAnnotations() {
250
- return this.editSessionAnnotations?.current ?? this.lineAnnotations;
253
+ return this.editSession?.annotations?.current ?? this.lineAnnotations;
251
254
  }
252
255
  isNewAnnotations(lineAnnotations) {
253
- const { editSessionAnnotations: session, lineAnnotations: externalAnnotations } = this;
254
- if (lineAnnotations === externalAnnotations) return false;
256
+ const session = this.editSession?.annotations;
257
+ if (lineAnnotations === this.lineAnnotations) return false;
255
258
  return session == null || lineAnnotations !== session.provided && lineAnnotations !== session.current;
256
259
  }
257
260
  setLineAnnotations(lineAnnotations) {
258
- const { editSessionAnnotations: sessionAnnotations } = this;
261
+ const sessionAnnotations = this.editSession?.annotations;
259
262
  if (sessionAnnotations == null) {
260
263
  this.lineAnnotations = lineAnnotations;
261
264
  return;
@@ -265,7 +268,7 @@ var FileDiff = class {
265
268
  writeEditSessionAnnotations(sessionAnnotations, lineAnnotations, getLineAnnotationName);
266
269
  }
267
270
  syncEditSessionAnnotationsFromEditor(lineAnnotations) {
268
- const { editSessionAnnotations: session } = this;
271
+ const session = this.editSession?.annotations;
269
272
  if (session == null || lineAnnotations === session.current) return false;
270
273
  session.current = lineAnnotations;
271
274
  this.hunksRenderer.setLineAnnotations(lineAnnotations);
@@ -379,9 +382,7 @@ var FileDiff = class {
379
382
  this.hunksRenderer.cleanUp();
380
383
  this.workerManager = void 0;
381
384
  this.fileDiff = void 0;
382
- this.editSessionDiff = void 0;
383
- this.editSessionAnnotations = void 0;
384
- this.outgoingSessionDiff = void 0;
385
+ this.editSession = void 0;
385
386
  this.renderedDiff = void 0;
386
387
  this.deletionFile = void 0;
387
388
  this.additionFile = void 0;
@@ -543,28 +544,27 @@ var FileDiff = class {
543
544
  if (expectedDiff.isPartial) throw new Error("FileDiff.startHydratedEditSession: diffs cannot be partial for editing");
544
545
  if (this.fileDiff !== expectedDiff) return false;
545
546
  const { editor } = this;
546
- if (this.outgoingSessionDiff != null) {
547
+ if (this.editSession?.outgoingDiff != null) {
547
548
  this.installEditSession(expectedDiff);
548
549
  return true;
549
550
  }
550
- if (editor == null || this.editSessionDiff != null) return false;
551
+ if (editor == null || this.editSession != null) return false;
551
552
  this.installEditSession(expectedDiff, editor.__getDocumentContents(getAdditionFile(expectedDiff)), editor.__getDocumentSessionState());
552
553
  return true;
553
554
  }
554
555
  updateExternalDiff(incomingExternalDiff, lineAnnotations) {
555
556
  if (areDiffTargetsEqual(this.fileDiff, incomingExternalDiff)) return false;
556
- const editSessionDiff = this.outgoingSessionDiff ?? this.editSessionDiff;
557
+ const outgoingDiff = this.editSession?.outgoingDiff ?? this.editSession?.diff;
557
558
  this.fileDiff = incomingExternalDiff;
558
- this.outgoingSessionDiff = void 0;
559
- if (editSessionDiff != null) {
560
- this.outgoingSessionDiff = editSessionDiff;
559
+ if (outgoingDiff != null) {
561
560
  if (incomingExternalDiff.isPartial) this.loadFilesIfNecessary();
562
561
  else this.installEditSession(incomingExternalDiff);
562
+ if (this.editSession != null) this.editSession.outgoingDiff = outgoingDiff;
563
563
  } else if (this.editor != null) if (incomingExternalDiff.isPartial) this.loadFilesIfNecessary();
564
564
  else this.installEditSession(incomingExternalDiff, this.editor.__getDocumentContents(getAdditionFile(incomingExternalDiff)), this.editor.__getDocumentSessionState());
565
- if (this.editSessionAnnotations != null && lineAnnotations != null) {
565
+ if (this.editSession?.annotations != null && lineAnnotations != null) {
566
566
  this.lineAnnotations = lineAnnotations;
567
- this.editSessionAnnotations = adoptEditSessionAnnotations(lineAnnotations, getLineAnnotationName, this.editSessionAnnotations);
567
+ this.editSession.annotations = adoptEditSessionAnnotations(lineAnnotations, getLineAnnotationName, this.editSession.annotations);
568
568
  }
569
569
  return true;
570
570
  }
@@ -587,7 +587,11 @@ var FileDiff = class {
587
587
  sessionDiff.editSessionDirty = true;
588
588
  recomputeDiffRenderLineCounts(sessionDiff);
589
589
  }
590
- this.editSessionDiff = sessionDiff;
590
+ this.editSession = {
591
+ diff: sessionDiff,
592
+ annotations: this.editSession?.annotations ?? adoptEditSessionAnnotations(this.lineAnnotations, getLineAnnotationName),
593
+ outgoingDiff: this.editSession?.outgoingDiff
594
+ };
591
595
  this.hunksRenderer.beginEditSession(sessionDiff, usesExternalDocument && !restoreRetainedSession ? externalDiff : void 0);
592
596
  }
593
597
  setHydratedState(files) {
@@ -609,7 +613,11 @@ var FileDiff = class {
609
613
  const filesDidChange = hasFileInput && (!areOptionalFilesEqual(oldFile, this.deletionFile) || !areOptionalFilesEqual(newFile, this.additionFile));
610
614
  let diffDidChange = fileDiff != null && !areDiffTargetsEqual(fileDiff, this.fileDiff);
611
615
  const annotationsChanged = lineAnnotations != null && (lineAnnotations.length > 0 || this.getLatestAnnotations().length > 0) ? this.isNewAnnotations(lineAnnotations) : false;
612
- if (!collapsed && areRenderRangesEqual(nextRenderRange, this.renderRange) && !forceRender && !annotationsChanged && !themeChanged && (fileDiff != null && !diffDidChange || fileDiff == null && !filesDidChange)) return this.applyCachedThemeState(themeType);
616
+ if (!collapsed && areRenderRangesEqual(nextRenderRange, this.renderRange) && !forceRender && !annotationsChanged && !themeChanged && (fileDiff != null && !diffDidChange || fileDiff == null && !filesDidChange)) {
617
+ const rendered = this.applyCachedThemeState(themeType);
618
+ if (rendered) this.finalizeRender();
619
+ return rendered;
620
+ }
613
621
  let nextParsedFileDiff;
614
622
  if (fileDiff == null && hasFileInput && (filesDidChange || this.fileDiff == null)) nextParsedFileDiff = parseDiffFromFile(fileInput.oldFile, fileInput.newFile, this.options.parseDiffOptions);
615
623
  const { renderRange: previousRenderRange } = this;
@@ -664,6 +672,7 @@ var FileDiff = class {
664
672
  console.error(error);
665
673
  if (error instanceof Error) this.applyErrorToDOM(error, fileContainer);
666
674
  }
675
+ this.finalizeRender();
667
676
  if (!preventEmit) this.emitPostRender();
668
677
  return true;
669
678
  }
@@ -695,6 +704,7 @@ var FileDiff = class {
695
704
  this.renderGutterUtility();
696
705
  this.managersDirty = true;
697
706
  if (!deferManagers) this.flushManagers();
707
+ this.finalizeRender();
698
708
  if (this.editor != null) this.syncRenderViewToEditor();
699
709
  } catch (error) {
700
710
  if (disableErrorHandling) throw error;
@@ -704,6 +714,7 @@ var FileDiff = class {
704
714
  if (!preventEmit) this.emitPostRender();
705
715
  return true;
706
716
  }
717
+ finalizeRender() {}
707
718
  emitPostRender(unmount = false) {
708
719
  const { fileContainer, options: { onPostRender } } = this;
709
720
  if (unmount) {
@@ -719,7 +730,7 @@ var FileDiff = class {
719
730
  onPostRender?.(fileContainer, this, phase);
720
731
  }
721
732
  getLatestDiff(fileDiff = this.fileDiff) {
722
- return this.editSessionDiff ?? fileDiff;
733
+ return this.editSession?.diff ?? fileDiff;
723
734
  }
724
735
  getRenderedDiff() {
725
736
  return this.renderedDiff;
@@ -730,12 +741,12 @@ var FileDiff = class {
730
741
  const renderRange = this.computeEditorRenderRange(this.renderRange);
731
742
  const fileDiff = this.getLatestDiff();
732
743
  if (editor == null || fileContainer == null || fileDiff == null || fileDiff.isPartial) return;
733
- this.hunksRenderer.initializeHighlighter().then((highlighter) => {
744
+ const sync = (highlighter) => {
734
745
  if (!this.enabled || this.editor !== editor || this.fileContainer !== fileContainer || this.getLatestDiff() !== fileDiff) return;
735
- const { outgoingSessionDiff: replacement, fileDiff: externalDiff } = this;
746
+ const replacement = this.editSession?.outgoingDiff;
747
+ const externalDiff = this.fileDiff;
736
748
  const externalDocument = replacement != null && externalDiff != null && replacement !== fileDiff;
737
749
  const resetHistory = externalDocument ? shouldResetUndoState(replacement, externalDiff) : false;
738
- if (externalDocument) this.outgoingSessionDiff = void 0;
739
750
  editor.__syncRenderView({
740
751
  highlighter,
741
752
  fileContainer,
@@ -745,7 +756,19 @@ var FileDiff = class {
745
756
  externalDocument,
746
757
  resetHistory
747
758
  });
759
+ };
760
+ const theme = this.getTheme();
761
+ const lang = fileDiff.lang ?? getFiletypeFromFileName(fileDiff.name);
762
+ const highlighter = getHighlighterIfLoaded({
763
+ theme,
764
+ lang
748
765
  });
766
+ if (highlighter != null) sync(highlighter);
767
+ else getSharedHighlighter({
768
+ themes: getThemes(theme),
769
+ langs: ["text", lang],
770
+ preferredHighlighter: this.workerManager?.getPreferredHighlighter() ?? this.options.preferredHighlighter
771
+ }).then(sync);
749
772
  }
750
773
  computeEditorRenderRange(renderRange) {
751
774
  const fileDiff = this.getLatestDiff();
@@ -778,9 +801,16 @@ var FileDiff = class {
778
801
  totalLines: lastLineNumber - firstLineNumber + 1
779
802
  };
780
803
  }
781
- emitEditChange(event) {
804
+ /** @internal The editor applied or edited past the pending external replacement. */
805
+ __acknowledgeDocumentUpdate() {
806
+ if (this.editSession != null) this.editSession.outgoingDiff = void 0;
807
+ }
808
+ /** @internal Settle annotations locally. */
809
+ __acceptEditorChange(event) {
782
810
  const { lineAnnotations } = event;
783
811
  if (lineAnnotations != null) this.syncEditSessionAnnotationsFromEditor(lineAnnotations);
812
+ }
813
+ emitEditChange(event) {
784
814
  const { onEditChange } = this.options;
785
815
  onEditChange?.(event);
786
816
  }
@@ -791,10 +821,10 @@ var FileDiff = class {
791
821
  * When `clone` is true, the returned lines and hunks are copied.
792
822
  */
793
823
  __captureDocumentSessionState(clone = true) {
794
- let { outgoingSessionDiff, fileDiff, editSessionDiff: sessionDiff } = this;
795
- if (outgoingSessionDiff != null && fileDiff != null) {
796
- if (!fileDiff.isPartial && shouldResetUndoState(outgoingSessionDiff, fileDiff)) return;
797
- sessionDiff = outgoingSessionDiff;
824
+ let { fileDiff, editSession: { diff: sessionDiff, outgoingDiff } = {} } = this;
825
+ if (outgoingDiff != null && fileDiff != null) {
826
+ if (!fileDiff.isPartial && shouldResetUndoState(outgoingDiff, fileDiff)) return;
827
+ sessionDiff = outgoingDiff;
798
828
  }
799
829
  if (sessionDiff == null || sessionDiff.isPartial) return;
800
830
  return {
@@ -831,16 +861,16 @@ var FileDiff = class {
831
861
  this.resumeEditorRendering(editor);
832
862
  }
833
863
  resumeEditorRendering(editor) {
834
- this.editSessionAnnotations ??= adoptEditSessionAnnotations(this.lineAnnotations, getLineAnnotationName);
835
- const { fileDiff: externalDiff, outgoingSessionDiff: pendingReplacement } = this;
836
- if (pendingReplacement != null && externalDiff != null && !externalDiff.isPartial && this.editSessionDiff === pendingReplacement) this.installEditSession(externalDiff);
837
- const initialExternalDiff = this.editSessionDiff == null && externalDiff != null && !externalDiff.isPartial ? externalDiff : void 0;
864
+ const { fileDiff: externalDiff } = this;
865
+ const pendingReplacement = this.editSession?.outgoingDiff;
866
+ if (pendingReplacement != null && externalDiff != null && !externalDiff.isPartial && this.editSession?.diff === pendingReplacement) this.installEditSession(externalDiff);
867
+ const initialExternalDiff = this.editSession == null && externalDiff != null && !externalDiff.isPartial ? externalDiff : void 0;
838
868
  if (initialExternalDiff != null) this.installEditSession(initialExternalDiff, editor.__getDocumentContents(getAdditionFile(initialExternalDiff)), editor.__getDocumentSessionState());
839
- else this.hunksRenderer.beginEditSession(this.editSessionDiff);
869
+ else if (this.editSession != null) this.hunksRenderer.beginEditSession(this.editSession.diff);
840
870
  this.editor = editor;
841
871
  if (this.fileDiff?.isPartial === true) this.loadFilesIfNecessary();
872
+ const editSessionDiff = this.editSession?.diff;
842
873
  if (this.hunksRenderer.editorRenderReady()) {
843
- const { editSessionDiff } = this;
844
874
  if (editSessionDiff != null && this.hunksRenderer.diffCache === editSessionDiff) this.renderedDiff = editSessionDiff;
845
875
  this.syncRenderViewToEditor();
846
876
  } else this.rerender();
@@ -867,8 +897,9 @@ var FileDiff = class {
867
897
  this.settleEditSession(mode === "install", editor);
868
898
  }
869
899
  settleEditSession(installResult, editor) {
870
- const { editSessionDiff, editSessionAnnotations, fileDiff: externalDiff, lineAnnotations: externalAnnotations } = this;
871
- if (editSessionDiff == null || externalDiff == null) return;
900
+ const { editSession, fileDiff: externalDiff, lineAnnotations: externalAnnotations } = this;
901
+ if (editSession == null || externalDiff == null) return;
902
+ const { diff: editSessionDiff, annotations: editSessionAnnotations } = editSession;
872
903
  if (this.editor != null) throw new Error("FileDiff.__completeEditSession: detach the editor before completing the session");
873
904
  this.hunksRenderer.endEditSession();
874
905
  this.finalizeEditSessionHunks();
@@ -918,9 +949,7 @@ var FileDiff = class {
918
949
  }
919
950
  if (sessionAnnotationsCurrent != null) this.lineAnnotations = sessionAnnotationsCurrent;
920
951
  }
921
- this.editSessionDiff = void 0;
922
- this.editSessionAnnotations = void 0;
923
- this.outgoingSessionDiff = void 0;
952
+ this.editSession = void 0;
924
953
  if (installResult && this.fileContainer != null) this.rerender();
925
954
  if (failed) throw failure;
926
955
  }
@@ -948,7 +977,7 @@ var FileDiff = class {
948
977
  return true;
949
978
  }
950
979
  applyDocumentChange(textDocument, newLineAnnotations) {
951
- const { editSessionDiff } = this;
980
+ const editSessionDiff = this.editSession?.diff;
952
981
  if (editSessionDiff == null) throw new Error("FileDiff.applyDocumentChange: requires an active edit session");
953
982
  this.detachAdditionLines();
954
983
  this.hunksRenderer.beginEditSession(editSessionDiff);
@@ -958,7 +987,7 @@ var FileDiff = class {
958
987
  this.interactionManager.setSelectionDirty();
959
988
  }
960
989
  updateRenderCache(dirtyLines, themeType, options = {}) {
961
- const { editSessionDiff } = this;
990
+ const editSessionDiff = this.editSession?.diff;
962
991
  if (editSessionDiff == null) throw new Error("FileDiff.updateRenderCache: requires an active edit session");
963
992
  this.detachAdditionLines();
964
993
  this.hunksRenderer.beginEditSession(editSessionDiff);
@@ -984,7 +1013,8 @@ var FileDiff = class {
984
1013
  }
985
1014
  }
986
1015
  detachAdditionLines() {
987
- const { editSessionDiff, fileDiff } = this;
1016
+ const editSessionDiff = this.editSession?.diff;
1017
+ const { fileDiff } = this;
988
1018
  if (editSessionDiff != null && (editSessionDiff.additionLines === fileDiff?.additionLines || editSessionDiff.additionLines === editSessionDiff.deletionLines)) editSessionDiff.additionLines = [...editSessionDiff.additionLines];
989
1019
  }
990
1020
  isLineRenderable(lineNumber) {
@@ -1304,8 +1334,8 @@ var FileDiff = class {
1304
1334
  this.cleanupErrorWrapper();
1305
1335
  this.placeHolder?.remove();
1306
1336
  this.placeHolder = void 0;
1307
- const { headerCache: { fileDiff: cachedHeaderDiff, html: cachedHeaderHTML, lastRenderedHTML }, editSessionDiff } = this;
1308
- const headerHTML = (fileDiff !== editSessionDiff && areDiffTargetsEqual(cachedHeaderDiff, fileDiff) ? cachedHeaderHTML : void 0) ?? toHtml(headerAST);
1337
+ const { headerCache: { fileDiff: cachedHeaderDiff, html: cachedHeaderHTML, lastRenderedHTML } } = this;
1338
+ const headerHTML = (fileDiff !== this.editSession?.diff && areDiffTargetsEqual(cachedHeaderDiff, fileDiff) ? cachedHeaderHTML : void 0) ?? toHtml(headerAST);
1309
1339
  this.headerCache.html = headerHTML;
1310
1340
  this.headerCache.fileDiff = fileDiff;
1311
1341
  if (headerHTML !== lastRenderedHTML) {
@@ -1395,7 +1425,7 @@ var FileDiff = class {
1395
1425
  applyThemeState(container, themeStyles, themeType, baseThemeType) {
1396
1426
  const shadowRoot = container.shadowRoot ?? container.attachShadow({ mode: "open" });
1397
1427
  const effectiveThemeType = baseThemeType ?? themeType;
1398
- const currentTheme = this.options.theme ?? DEFAULT_THEMES;
1428
+ const currentTheme = this.getTheme();
1399
1429
  const theme = typeof currentTheme === "string" ? currentTheme : { ...currentTheme };
1400
1430
  const scrollbarGutter = getMeasuredScrollbarGutter(shadowRoot);
1401
1431
  if (this.themeCSSStyle?.parentNode === shadowRoot && this.appliedThemeCSS?.themeStyles === themeStyles && this.appliedThemeCSS.themeType === effectiveThemeType && this.appliedThemeCSS.scrollbarGutter === scrollbarGutter) {