superdoc 2.4.0-next.16 → 2.4.0-next.17

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/dist/superdoc.cjs CHANGED
@@ -4,7 +4,7 @@ const require_blank_docx = require("./chunks/blank-docx-BuFAbRjs.cjs");
4
4
  const require_eventemitter3 = require("./chunks/eventemitter3-C_TAnXOl.cjs");
5
5
  const require_uuid = require("./chunks/uuid-BhG0ngwk.cjs");
6
6
  const require_jszip = require("./chunks/jszip-D8mAFF-r.cjs");
7
- const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-CTe12b19.cjs");
7
+ const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-CPuOlTWb.cjs");
8
8
  const require__plugin_vue_export_helper = require("./chunks/_plugin-vue_export-helper-SDR04tiH.cjs");
9
9
  const require_constants = require("./chunks/constants-DpXuDx_g.cjs");
10
10
  let vue = require("vue");
@@ -7762,6 +7762,7 @@ var useCommentsStore = defineStore("comments", () => {
7762
7762
  syncResolvedCommentsWithDocument();
7763
7763
  });
7764
7764
  (0, vue.watch)(commentsList, () => {
7765
+ canonicalizeActiveCommentAlias();
7765
7766
  syncResolvedCommentsWithDocument();
7766
7767
  }, { deep: false });
7767
7768
  /**
@@ -8614,7 +8615,8 @@ var useCommentsStore = defineStore("comments", () => {
8614
8615
  superdoc,
8615
8616
  adapter,
8616
8617
  documentId: adapter.documentId ?? fileId,
8617
- items: outcome.items ?? []
8618
+ items: outcome.items ?? [],
8619
+ pruneStale: outcome.complete !== false
8618
8620
  });
8619
8621
  const successEvent = successEventBuilder?.({
8620
8622
  outcome,
@@ -9020,7 +9022,7 @@ var useCommentsStore = defineStore("comments", () => {
9020
9022
  trackedItems: preparedParams.length
9021
9023
  };
9022
9024
  });
9023
- const hydrateCommentsFromV2 = async ({ superdoc, adapter, documentId, trackedChangesListMode = "all", isCurrent, signal, hydrationGeneration } = {}) => withInteractionSpan("store.comments.hydrateFromV2", "comments-list", { documentId: documentId ?? null }, async () => {
9025
+ const hydrateCommentsFromV2 = async ({ superdoc, adapter, documentId, trackedChangesListMode = "all", commentIds, isCurrent, signal, hydrationGeneration } = {}) => withInteractionSpan("store.comments.hydrateFromV2", "comments-list", { documentId: documentId ?? null }, async () => {
9024
9026
  const effectiveAdapter = adapter ?? getV2CommentsAdapter(superdoc);
9025
9027
  const visibleWindow = trackedChangesListMode === "visible-window";
9026
9028
  const read = visibleWindow ? effectiveAdapter?.selectVisibleReviewComments : effectiveAdapter?.refresh;
@@ -9042,6 +9044,7 @@ var useCommentsStore = defineStore("comments", () => {
9042
9044
  let result;
9043
9045
  try {
9044
9046
  const refreshOptions = {};
9047
+ if (visibleWindow && Array.isArray(commentIds)) refreshOptions.targetIds = commentIds;
9045
9048
  if (signal) refreshOptions.signal = signal;
9046
9049
  if (typeof hydrationGeneration === "number") refreshOptions.hydrationGeneration = hydrationGeneration;
9047
9050
  result = Object.keys(refreshOptions).length > 0 ? await read.call(effectiveAdapter, refreshOptions) : await read.call(effectiveAdapter);
@@ -9072,7 +9075,7 @@ var useCommentsStore = defineStore("comments", () => {
9072
9075
  adapter: effectiveAdapter,
9073
9076
  documentId,
9074
9077
  items: result.items ?? [],
9075
- pruneStale: !visibleWindow,
9078
+ pruneStale: !visibleWindow || Array.isArray(commentIds) && (!Array.isArray(result.unresolvedIds) || result.unresolvedIds.length === 0),
9076
9079
  hydrationGeneration
9077
9080
  });
9078
9081
  return {
@@ -9305,6 +9308,27 @@ var useCommentsStore = defineStore("comments", () => {
9305
9308
  storySnapshots
9306
9309
  };
9307
9310
  };
9311
+ const reconcileAuthoritativeV2TrackedChangeSidebar = ({ superdoc, editor, documentId, refreshReason = "tracked-change-sidebar-authoritative" } = {}) => {
9312
+ const adapter = getV2TrackedChangesAdapter(superdoc) ?? editor?.v2TrackedChanges ?? null;
9313
+ if (!adapter || typeof adapter.listTrackedChanges !== "function" || typeof adapter.mapV2TrackedChangeToCommentParams !== "function") return false;
9314
+ const effectiveDocumentId = documentId ?? adapter.documentId ?? editor?.documentId ?? editor?.options?.documentId ?? superdoc?.activeEditor?.documentId ?? superdoc?.activeEditor?.options?.documentId ?? null;
9315
+ if (effectiveDocumentId == null) return false;
9316
+ const normalizedDocumentId = String(effectiveDocumentId);
9317
+ hydrateTrackedChangesFromV2({
9318
+ superdoc,
9319
+ adapter,
9320
+ documentId: normalizedDocumentId,
9321
+ trackedChangesListMode: "background-reconcile",
9322
+ refreshReason,
9323
+ blocking: false,
9324
+ isCurrent: () => {
9325
+ const activeEditor = superdoc?.activeEditor ?? null;
9326
+ const activeDocumentId = activeEditor?.documentId ?? activeEditor?.options?.documentId ?? null;
9327
+ return activeDocumentId == null || String(activeDocumentId) === normalizedDocumentId;
9328
+ }
9329
+ });
9330
+ return true;
9331
+ };
9308
9332
  /**
9309
9333
  * Bootstrap tracked-change comment threads after a DOCX import finishes.
9310
9334
  *
@@ -9342,6 +9366,12 @@ var useCommentsStore = defineStore("comments", () => {
9342
9366
  editor,
9343
9367
  structuralChanges: captured.structuralChanges
9344
9368
  });
9369
+ reconcileAuthoritativeV2TrackedChangeSidebar({
9370
+ superdoc,
9371
+ editor,
9372
+ documentId: editor?.options?.documentId,
9373
+ refreshReason: "import-bootstrap-authoritative"
9374
+ });
9345
9375
  return true;
9346
9376
  };
9347
9377
  const isCurrentImportedTrackedChangeBootstrap = (task) => {
@@ -10327,7 +10357,8 @@ var useCommentsStore = defineStore("comments", () => {
10327
10357
  lateResultDropped: true
10328
10358
  };
10329
10359
  if (!result?.ok) return result;
10330
- const pruneStale = !(trackedChangesListMode === "startup-page" || trackedChangesListMode === "interaction-prime" || trackedChangesListMode === "visible-window") && result.visibleWindowSource == null && result.complete === true && result.sourceCoverageComplete === true;
10360
+ const partialListMode = trackedChangesListMode === "startup-page" || trackedChangesListMode === "interaction-prime" || trackedChangesListMode === "visible-window";
10361
+ const pruneStale = trackedChangesListMode === "visible-window" && Array.isArray(targetIds) && (!Array.isArray(result.visibleTrackedChangeFailedIds) || result.visibleTrackedChangeFailedIds.length === 0) || !partialListMode && result.visibleWindowSource == null && result.complete === true && result.sourceCoverageComplete === true;
10331
10362
  if (signal?.aborted || trackedChangeSyncGeneration(effectiveAdapter) !== syncGeneration) return {
10332
10363
  ok: false,
10333
10364
  reason: "review-hydration-superseded",
@@ -10731,6 +10762,12 @@ var useCommentsStore = defineStore("comments", () => {
10731
10762
  broadcastChanges,
10732
10763
  structuralChanges: captured.structuralChanges
10733
10764
  });
10765
+ reconcileAuthoritativeV2TrackedChangeSidebar({
10766
+ superdoc,
10767
+ editor,
10768
+ documentId: activeDocumentId,
10769
+ refreshReason: "sync-authoritative"
10770
+ });
10734
10771
  };
10735
10772
  /**
10736
10773
  * Surface decidable whole-table structural tracked changes (table insert /
@@ -11201,6 +11238,16 @@ var useCommentsStore = defineStore("comments", () => {
11201
11238
  const syncActiveFloatingInstanceWithComment = (commentId) => {
11202
11239
  if (!doesFloatingInstanceBelongToComment(activeFloatingCommentInstanceId.value, commentId)) setActiveFloatingCommentInstance(null);
11203
11240
  };
11241
+ function canonicalizeActiveCommentAlias() {
11242
+ const activeId = normalizeCommentId(activeComment.value);
11243
+ if (!activeId) return false;
11244
+ const comment = getComment(activeId);
11245
+ const canonicalId = normalizeCommentId(comment?.commentId);
11246
+ if (!canonicalId || canonicalId === activeId) return false;
11247
+ activeComment.value = canonicalId;
11248
+ syncActiveFloatingInstanceWithComment(canonicalId);
11249
+ return true;
11250
+ }
11204
11251
  const setViewingVisibility = ({ documentMode, commentsVisible, trackChangesVisible } = {}) => {
11205
11252
  if (typeof documentMode === "string") viewingVisibility.documentMode = documentMode;
11206
11253
  if (typeof commentsVisible === "boolean") viewingVisibility.commentsVisible = commentsVisible;
@@ -13904,6 +13951,12 @@ var _sfc_main$30 = {
13904
13951
  setup(__props) {
13905
13952
  const ESTIMATED_HEIGHT = 110;
13906
13953
  const OBSERVER_MARGIN = 600;
13954
+ const SCROLL_OWNER_OVERFLOW_VALUES = /* @__PURE__ */ new Set([
13955
+ "auto",
13956
+ "scroll",
13957
+ "hidden",
13958
+ "clip"
13959
+ ]);
13907
13960
  const resolveCollisions = (positions, activeIndex, gap) => {
13908
13961
  if (activeIndex >= 0) {
13909
13962
  positions[activeIndex].top = positions[activeIndex].anchorTop;
@@ -14308,6 +14361,8 @@ var _sfc_main$30 = {
14308
14361
  let activeLayoutContinuityFrame = null;
14309
14362
  let directDecisionContinuity = null;
14310
14363
  let directDecisionSourceId = null;
14364
+ let ownerScrollContinuityResetFrame = null;
14365
+ const ownerScrollTargets = /* @__PURE__ */ new Set();
14311
14366
  const releaseDirectDecisionContinuity = () => {
14312
14367
  directDecisionContinuity = null;
14313
14368
  directDecisionSourceId = null;
@@ -14371,6 +14426,36 @@ var _sfc_main$30 = {
14371
14426
  }
14372
14427
  setInstantLayoutTransitionsDisabled(false);
14373
14428
  };
14429
+ const releaseDecisionContinuityForOwnerScroll = () => {
14430
+ if (!directDecisionContinuity && !sidebarContinuityAnchor) return;
14431
+ releaseDirectDecisionContinuity();
14432
+ clearSidebarContinuityAnchor();
14433
+ setInstantLayoutTransitionsDisabled(true);
14434
+ sidebarOffsetY.value = 0;
14435
+ if (ownerScrollContinuityResetFrame != null) cancelAnimationFrame(ownerScrollContinuityResetFrame);
14436
+ ownerScrollContinuityResetFrame = requestAnimationFrame(() => {
14437
+ ownerScrollContinuityResetFrame = null;
14438
+ if (!directDecisionContinuity && !sidebarContinuityAnchor) setInstantLayoutTransitionsDisabled(false);
14439
+ });
14440
+ };
14441
+ const handleOwnerScroll = () => {
14442
+ releaseDecisionContinuityForOwnerScroll();
14443
+ refreshViewportWindow();
14444
+ };
14445
+ const registerOwnerScrollListeners = () => {
14446
+ const addTarget = (target) => {
14447
+ if (!target?.addEventListener || ownerScrollTargets.has(target)) return;
14448
+ target.addEventListener("scroll", handleOwnerScroll, { passive: true });
14449
+ ownerScrollTargets.add(target);
14450
+ };
14451
+ addTarget(props.parent);
14452
+ for (let ancestor = floatingCommentsContainer.value?.parentElement; ancestor; ancestor = ancestor.parentElement) if (SCROLL_OWNER_OVERFLOW_VALUES.has(window.getComputedStyle(ancestor).overflowY)) addTarget(ancestor);
14453
+ addTarget(window);
14454
+ };
14455
+ const unregisterOwnerScrollListeners = () => {
14456
+ for (const target of ownerScrollTargets) target.removeEventListener?.("scroll", handleOwnerScroll);
14457
+ ownerScrollTargets.clear();
14458
+ };
14374
14459
  const scheduleSidebarContinuityAlignment = () => {
14375
14460
  if (!sidebarContinuityAnchor || continuityAlignmentScheduled) return;
14376
14461
  continuityAlignmentScheduled = true;
@@ -14623,7 +14708,7 @@ var _sfc_main$30 = {
14623
14708
  });
14624
14709
  (0, vue.onMounted)(() => {
14625
14710
  setupObserver();
14626
- props.parent?.addEventListener?.("scroll", refreshViewportWindow, { passive: true });
14711
+ registerOwnerScrollListeners();
14627
14712
  window.addEventListener("resize", refreshViewportWindow, { passive: true });
14628
14713
  document.addEventListener("pointerdown", releaseDirectDecisionContinuityForUnrelatedPointer, true);
14629
14714
  (0, vue.nextTick)(observePlaceholders);
@@ -14637,7 +14722,11 @@ var _sfc_main$30 = {
14637
14722
  cancelAnimationFrame(activeLayoutContinuityFrame);
14638
14723
  activeLayoutContinuityFrame = null;
14639
14724
  }
14640
- props.parent?.removeEventListener?.("scroll", refreshViewportWindow);
14725
+ if (ownerScrollContinuityResetFrame != null) {
14726
+ cancelAnimationFrame(ownerScrollContinuityResetFrame);
14727
+ ownerScrollContinuityResetFrame = null;
14728
+ }
14729
+ unregisterOwnerScrollListeners();
14641
14730
  window.removeEventListener("resize", refreshViewportWindow);
14642
14731
  document.removeEventListener("pointerdown", releaseDirectDecisionContinuityForUnrelatedPointer, true);
14643
14732
  if (viewportFrame != null) {
@@ -14706,7 +14795,7 @@ var _sfc_main$30 = {
14706
14795
  };
14707
14796
  }
14708
14797
  };
14709
- var FloatingComments_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$30, [["__scopeId", "data-v-a0a841ce"]]);
14798
+ var FloatingComments_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$30, [["__scopeId", "data-v-d8d03209"]]);
14710
14799
  //#endregion
14711
14800
  //#region src/components/CommentsLayer/PdfCommentsLayer.vue
14712
14801
  var _hoisted_1$22 = {
@@ -15387,6 +15476,19 @@ var VALID_COMMENTS_DISPLAY_MODES = /* @__PURE__ */ new Set([
15387
15476
  "inline"
15388
15477
  ]);
15389
15478
  /**
15479
+ * Whether a context-menu event landed inside the tracked-change carrier that
15480
+ * is already visually active. The review visual owner maintains this marker,
15481
+ * so the right-click path can stay synchronous and avoid a catalog lookup or
15482
+ * document-wide DOM query.
15483
+ *
15484
+ * @param {EventTarget | null} target
15485
+ * @returns {boolean}
15486
+ */
15487
+ function isActiveTrackedChangeContextMenuTarget(target) {
15488
+ const element = target;
15489
+ return typeof element?.closest === "function" && element.closest(".track-change-focused") != null;
15490
+ }
15491
+ /**
15390
15492
  * Normalize adaptive comments UI policy fields.
15391
15493
  *
15392
15494
  * @param {false | Record<string, unknown> | undefined} commentsConfig
@@ -15822,74 +15924,6 @@ function resolveV2ReviewTargetCommentId(target, getComment) {
15822
15924
  return commentId != null ? String(commentId) : null;
15823
15925
  }
15824
15926
  //#endregion
15825
- //#region src/helpers/v2-remote-review-hydration.js
15826
- function normalizeDocumentId(value) {
15827
- return value == null ? null : String(value);
15828
- }
15829
- function createV2RemoteReviewHydrationScheduler({ hydrate, getActiveDocumentId, debounceMs = 250, ceilingMs = 1e3, now = () => Date.now(), setTimer = (callback, delay) => setTimeout(callback, delay), clearTimer = (timer) => clearTimeout(timer) }) {
15830
- let timer = null;
15831
- let heldSinceMs = null;
15832
- let pendingDocumentId = null;
15833
- const matchesActiveDocument = (documentId) => {
15834
- return normalizeDocumentId(getActiveDocumentId()) === documentId;
15835
- };
15836
- const clear = () => {
15837
- if (timer != null) clearTimer(timer);
15838
- timer = null;
15839
- heldSinceMs = null;
15840
- pendingDocumentId = null;
15841
- };
15842
- const schedule = (documentId) => {
15843
- const normalizedDocumentId = normalizeDocumentId(documentId);
15844
- if (!matchesActiveDocument(normalizedDocumentId)) return false;
15845
- if (pendingDocumentId !== normalizedDocumentId) clear();
15846
- const scheduledAtMs = now();
15847
- pendingDocumentId = normalizedDocumentId;
15848
- heldSinceMs ??= scheduledAtMs;
15849
- if (timer != null) clearTimer(timer);
15850
- const ceilingRemainingMs = Math.max(0, ceilingMs - (scheduledAtMs - heldSinceMs));
15851
- timer = setTimer(() => {
15852
- const deliveredDocumentId = pendingDocumentId;
15853
- timer = null;
15854
- heldSinceMs = null;
15855
- pendingDocumentId = null;
15856
- if (matchesActiveDocument(deliveredDocumentId)) hydrate();
15857
- }, Math.min(debounceMs, ceilingRemainingMs));
15858
- return true;
15859
- };
15860
- return {
15861
- schedule,
15862
- clear
15863
- };
15864
- }
15865
- //#endregion
15866
- //#region src/helpers/v2-typing-review-hydration.js
15867
- /**
15868
- * Coalesce automatic review-catalog reconciliation behind a genuine typing
15869
- * quiet period. Every typing signal restarts the trailing timer; there is no
15870
- * maximum-wait escape hatch because that would deliberately run the expensive
15871
- * catalog reads in the middle of a sustained input burst.
15872
- */
15873
- function createV2TypingReviewHydrationScheduler({ hydrate, idleMs = 6500, setTimer = (callback, delay) => setTimeout(callback, delay), clearTimer = (timer) => clearTimeout(timer) }) {
15874
- let timer = null;
15875
- const clear = () => {
15876
- if (timer != null) clearTimer(timer);
15877
- timer = null;
15878
- };
15879
- const schedule = () => {
15880
- clear();
15881
- timer = setTimer(() => {
15882
- timer = null;
15883
- hydrate();
15884
- }, idleMs);
15885
- };
15886
- return {
15887
- schedule,
15888
- clear,
15889
- isPending: () => timer != null
15890
- };
15891
- }
15892
- //#endregion
15893
15927
  //#region src/helpers/v2-author-required-rejection.js
15894
15928
  var NO_AUTHOR_SIGNAL = "no-author-configured";
15895
15929
  /** Stable, non-terminal exception code surfaced to consumers. */
@@ -20351,9 +20385,9 @@ var _hoisted_1$16 = {
20351
20385
  var _hoisted_2$13 = ["innerHTML"];
20352
20386
  var _hoisted_3$10 = { class: "superdoc__document document" };
20353
20387
  var _hoisted_4$7 = { class: "floating-comments" };
20388
+ var TRACKED_CHANGE_CARRIERS_RESTAMPED_EVENT = "superdoc:v2-tracked-change-carriers-restamped";
20354
20389
  var UNAVAILABLE_COMMAND_RESULT = false;
20355
20390
  var V2_SELECTION_TOOLBAR_SYNC_RETRY_FRAMES = 3;
20356
- var V2_TYPING_REVIEW_HYDRATION_IDLE_MS = 6500;
20357
20391
  var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default({
20358
20392
  __name: "SuperDoc",
20359
20393
  emits: ["selection-update"],
@@ -20516,6 +20550,27 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
20516
20550
  editor: proxy.$superdoc?.activeEditor
20517
20551
  });
20518
20552
  };
20553
+ const reconcileAuthoritativeV2TrackedChangeSidebar = ({ adapter, documentId, refreshReason = "startup-authoritative" } = {}) => {
20554
+ if (!adapter || typeof adapter.listTrackedChanges !== "function") return false;
20555
+ const normalizedDocumentId = documentId == null ? null : String(documentId);
20556
+ if (!normalizedDocumentId) return false;
20557
+ commentsStore.hydrateTrackedChangesFromV2?.({
20558
+ superdoc: proxy.$superdoc,
20559
+ adapter,
20560
+ documentId: normalizedDocumentId,
20561
+ trackedChangesListMode: "background-reconcile",
20562
+ refreshReason,
20563
+ blocking: false,
20564
+ isCurrent: () => {
20565
+ const activeEditor = proxy.$superdoc?.activeEditor ?? null;
20566
+ const activeDocumentId = activeEditor?.documentId ?? activeEditor?.options?.documentId ?? null;
20567
+ if (activeDocumentId != null && String(activeDocumentId) !== normalizedDocumentId) return false;
20568
+ const activeAdapter = activeEditor?.v2TrackedChanges ?? commentsStore.getV2TrackedChangesAdapter?.(proxy.$superdoc);
20569
+ return !activeAdapter || activeAdapter === adapter;
20570
+ }
20571
+ });
20572
+ return true;
20573
+ };
20519
20574
  const scheduleReplayTrackedChangeSync = () => {
20520
20575
  pendingReplayTrackedChangeSync.value = true;
20521
20576
  (0, vue.nextTick)(() => {
@@ -21059,7 +21114,11 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21059
21114
  pageFurniture: pageFurniture ?? null,
21060
21115
  presence: presence ?? null,
21061
21116
  lock: lock ?? null,
21062
- reviewHydration: { getDiagnostics: () => v2ReviewHydrationController.getDiagnostics() },
21117
+ reviewHydration: {
21118
+ getDiagnostics: () => v2ReviewHydrationController.getDiagnostics(),
21119
+ getSnapshot: () => v2ReviewHydrationController.getSnapshot?.() ?? null,
21120
+ subscribe: (listener) => v2ReviewHydrationController.subscribe?.(listener) ?? (() => void 0)
21121
+ },
21063
21122
  extensions: createV2ExtensionsFacet(host),
21064
21123
  fonts: fonts ?? host?.getFontRuntime?.() ?? null,
21065
21124
  /**
@@ -21115,6 +21174,11 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21115
21174
  console.warn("[SuperDoc][v2] initial render-readiness snapshot failed", err);
21116
21175
  }
21117
21176
  }
21177
+ if (commentsModuleEnabled && trackedChangesAdapter) reconcileAuthoritativeV2TrackedChangeSidebar({
21178
+ adapter: trackedChangesAdapter,
21179
+ documentId,
21180
+ refreshReason: "startup-authoritative"
21181
+ });
21118
21182
  if (areDocumentsReady.value && !proxy.$superdoc.config.collaboration) isReady.value = true;
21119
21183
  isFloatingCommentsReady.value = true;
21120
21184
  hasInitializedLocations.value = true;
@@ -21383,7 +21447,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21383
21447
  }
21384
21448
  },
21385
21449
  onCommittedPagePaint: (commit) => {
21386
- if (commit?.routeLane === "canonical.typing-mutation" || v2TypingReviewHydrationScheduler.isPending()) return;
21387
21450
  v2ReviewHydrationController.onCommittedPagePaint?.({
21388
21451
  ...commit,
21389
21452
  documentId: commit?.payload?.documentId ?? null
@@ -21428,7 +21491,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21428
21491
  const onV2RenderReadiness = (payload) => {
21429
21492
  const snapshot = payload?.snapshot ?? payload ?? null;
21430
21493
  if (!snapshot) return;
21431
- if (v2TypingReviewHydrationScheduler.isPending()) return;
21432
21494
  v2ReviewHydrationController.onRenderReadiness(snapshot);
21433
21495
  };
21434
21496
  const v2PageMetricsSnapshot = (0, vue.shallowRef)(null);
@@ -21478,8 +21540,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21478
21540
  if (latestV2MountStage && (clearedDocumentId == null || latestV2MountStage.dataset?.superdocV2DocumentId === clearedDocumentId)) latestV2MountStage = null;
21479
21541
  v2ReviewHydrationController.reset("render-cleared");
21480
21542
  v2ReviewMutationReconciler.reset();
21481
- clearV2TypingReviewHydrationTimer();
21482
- v2RemoteReviewHydrationScheduler.clear();
21483
21543
  commentsStore.setV2CommentsAdapter?.(null);
21484
21544
  commentsStore.setV2TrackedChangesAdapter?.(null);
21485
21545
  commentsStore.clearEditorCommentPositions?.();
@@ -21488,26 +21548,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21488
21548
  v2RulerHostStyle.value = {};
21489
21549
  v2RulerReady.value = false;
21490
21550
  };
21491
- const hydrateV2CommentRowsFromHost = () => {
21492
- const commentsAdapter = proxy.$superdoc?.activeEditor?.v2Comments ?? null;
21493
- if (!commentsAdapter) return;
21494
- commentsStore.hydrateCommentsFromV2?.({
21495
- superdoc: proxy.$superdoc,
21496
- adapter: commentsAdapter,
21497
- documentId: proxy.$superdoc?.activeEditor?.documentId ?? null
21498
- });
21499
- };
21500
- const hydrateV2ReviewRowsFromHost = (options = {}) => {
21501
- hydrateV2CommentRowsFromHost();
21502
- const trackedChangesAdapter = proxy.$superdoc?.activeEditor?.v2TrackedChanges ?? null;
21503
- if (!trackedChangesAdapter) return;
21504
- commentsStore.hydrateTrackedChangesFromV2?.({
21505
- superdoc: proxy.$superdoc,
21506
- adapter: trackedChangesAdapter,
21507
- documentId: proxy.$superdoc?.activeEditor?.documentId ?? null,
21508
- ...options
21509
- });
21510
- };
21511
21551
  const v2ReviewMutationReconciler = require_create_super_doc_ui.createV2ReviewMutationReconciler({
21512
21552
  getContext: () => {
21513
21553
  const activeEditor = proxy.$superdoc?.activeEditor ?? null;
@@ -21537,31 +21577,10 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21537
21577
  reason: "review-reconcile"
21538
21578
  })
21539
21579
  });
21540
- const v2TypingReviewHydrationScheduler = createV2TypingReviewHydrationScheduler({
21541
- idleMs: V2_TYPING_REVIEW_HYDRATION_IDLE_MS,
21542
- hydrate: () => v2ReviewHydrationController.reconcileInBackground?.("typing-idle")
21543
- });
21544
- const clearV2TypingReviewHydrationTimer = () => {
21545
- v2TypingReviewHydrationScheduler.clear();
21546
- };
21547
- const scheduleV2TypingReviewHydration = () => {
21548
- v2TypingReviewHydrationScheduler.schedule();
21549
- };
21550
- const v2RemoteReviewHydrationScheduler = createV2RemoteReviewHydrationScheduler({
21551
- hydrate: () => {
21552
- if (v2TypingReviewHydrationScheduler.isPending()) return false;
21553
- return v2ReviewHydrationController.reconcileInBackground?.("remote-review-change");
21554
- },
21555
- getActiveDocumentId: () => {
21556
- const activeEditor = proxy.$superdoc?.activeEditor ?? null;
21557
- return activeEditor?.documentId ?? activeEditor?.options?.documentId ?? null;
21558
- }
21559
- });
21560
21580
  const onV2HostEvent = (document, event) => {
21561
21581
  if (!event) return;
21562
21582
  const documentId = document?.id ?? null;
21563
21583
  if (event.type === "review-mutation:started") {
21564
- clearV2TypingReviewHydrationTimer();
21565
21584
  const activeEditor = proxy.$superdoc?.activeEditor ?? null;
21566
21585
  commentsStore.supersedeV2ReviewHydration?.({
21567
21586
  commentsAdapter: activeEditor?.v2Comments ?? null,
@@ -21583,8 +21602,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21583
21602
  return;
21584
21603
  }
21585
21604
  if (event.type === "collaboration:remote-changed") {
21586
- v2ReviewHydrationController.invalidate("collaboration:remote-changed");
21587
- v2RemoteReviewHydrationScheduler.schedule(documentId);
21605
+ if (event.reviewChanged !== false) v2ReviewHydrationController.invalidate("collaboration:remote-review-changed");
21588
21606
  return;
21589
21607
  }
21590
21608
  if (event.type === "source:complete") {
@@ -21609,11 +21627,12 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21609
21627
  emitV2EditorUpdate();
21610
21628
  }
21611
21629
  if (event.type !== "mutation:committed") return;
21612
- v2ReviewHydrationController.invalidate("mutation-committed");
21630
+ if (event.reviewSidecarOnly === true) v2ReviewHydrationController.hydrateNow("review-sidecar-committed");
21613
21631
  const reviewImpact = require_create_super_doc_ui.getV2TrackedChangeMutationImpact(event);
21614
21632
  if (Array.isArray(reviewImpact?.remappedPairs) && reviewImpact.remappedPairs.length > 0) commentsStore.remapTrackedChangeIdentities?.(reviewImpact.remappedPairs, { documentId });
21615
21633
  if (reviewImpact) armV2TrackedChangeRestampGeometryRetention("tracked-change-mutation");
21616
- const readiness = (proxy.$superdoc?.activeEditor ?? null)?.documentMutationReadiness ?? null;
21634
+ const activeEditor = proxy.$superdoc?.activeEditor ?? null;
21635
+ const readiness = activeEditor?.documentMutationReadiness ?? null;
21617
21636
  const receipt = event.origin === "history" ? null : event.receipt;
21618
21637
  const canWaitForExactPaint = reviewImpact && typeof receipt?.txId === "string" && receipt.txId.length > 0 && typeof readiness?.whenPainted === "function";
21619
21638
  const reconciliation = v2ReviewMutationReconciler.enqueueAfterPaint(reviewImpact, canWaitForExactPaint ? () => readiness.whenPainted.call(readiness, receipt) : null);
@@ -21628,43 +21647,37 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21628
21647
  resumeDomains: reconciledAllResolved ? ["comments"] : ["comments", "trackedChanges"],
21629
21648
  trackedRowCount: commentsStore.getV2TrackedChangeRowCount?.(documentId) ?? null
21630
21649
  });
21650
+ if (!reconciledAllResolved) reconcileAuthoritativeV2TrackedChangeSidebar({
21651
+ adapter: activeEditor?.v2TrackedChanges ?? null,
21652
+ documentId,
21653
+ refreshReason: "mutation-authoritative"
21654
+ });
21631
21655
  };
21632
21656
  Promise.resolve(reconciliation).then(settleReviewMutation, () => settleReviewMutation(false));
21633
21657
  return;
21634
21658
  }
21635
- const isTypingMutation = require_create_super_doc_ui.isV2EditableTextMutationEvent(event);
21636
- if (!isTypingMutation) clearV2TypingReviewHydrationTimer();
21637
- if (reviewImpact?.reconcileMode === "authoritative" && reviewImpact.upsertIds.size > 0) {
21638
- hydrateV2CommentRowsFromHost();
21639
- return;
21640
- }
21641
- if (isTypingMutation) {
21642
- scheduleV2TypingReviewHydration();
21643
- return;
21644
- }
21659
+ if (reviewImpact?.reconcileMode === "authoritative" && reviewImpact.upsertIds.size > 0) return;
21645
21660
  if (reviewImpact?.removedIds.size > 0 && reviewImpact.upsertIds.size === 0) return;
21646
- hydrateV2ReviewRowsFromHost();
21647
21661
  };
21648
21662
  const onV2LinkClick = (payload) => {
21649
21663
  linkPopover.handleLinkClick(payload);
21650
21664
  };
21651
- const recollectV2GeometryIfActive = () => {
21665
+ const recollectV2GeometryIfActive = (options = void 0) => {
21652
21666
  if (!isV2Mode.value) return;
21653
21667
  if (!v2GeometryPublisher.getLastPayload()) return;
21654
21668
  if (v2GeometryRafHandle && typeof cancelAnimationFrame === "function") cancelAnimationFrame(v2GeometryRafHandle);
21655
21669
  if (typeof requestAnimationFrame !== "function") {
21656
- v2GeometryPublisher.recollect();
21670
+ v2GeometryPublisher.recollect(resolveV2GeometryPublishOptions(options));
21657
21671
  return;
21658
21672
  }
21659
21673
  v2GeometryRafHandle = requestAnimationFrame(() => {
21660
21674
  v2GeometryRafHandle = 0;
21661
- v2GeometryPublisher.recollect();
21675
+ v2GeometryPublisher.recollect(resolveV2GeometryPublishOptions(options));
21662
21676
  });
21663
21677
  };
21664
21678
  const handleV2DocumentModeChange = () => {
21665
21679
  if (!isV2Mode.value) return;
21666
21680
  try {
21667
- clearV2TypingReviewHydrationTimer();
21668
21681
  v2ReviewHydrationController.hydrateNow("document-mode-change");
21669
21682
  } catch (err) {
21670
21683
  console.warn("[SuperDoc][v2] document-mode-change rehydrate failed", err);
@@ -21683,22 +21696,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21683
21696
  else republishGeometry();
21684
21697
  });
21685
21698
  };
21686
- let v2BuiltInReviewSurfaceOpen = false;
21687
- let v2ExternalReviewSurfaceOpen = false;
21688
- const syncV2ReviewCatalogDemand = () => {
21689
- if (!isV2Mode.value) return;
21690
- if (!v2BuiltInReviewSurfaceOpen && !v2ExternalReviewSurfaceOpen) {
21691
- v2ReviewHydrationController.releaseCatalogDemand();
21692
- return;
21693
- }
21694
- clearV2TypingReviewHydrationTimer();
21695
- v2ReviewHydrationController.demandCatalog("review-sidebar-visible");
21696
- };
21697
- const handleV2CommentsListChange = ({ isRendered } = {}) => {
21698
- v2ExternalReviewSurfaceOpen = isRendered === true;
21699
- syncV2ReviewCatalogDemand();
21700
- };
21701
- proxy.$superdoc?.on?.("comments-list-change", handleV2CommentsListChange);
21702
21699
  const getV2EditorFailureMessage = (reason) => {
21703
21700
  switch (reason) {
21704
21701
  case "editing-mount-required": return "SuperDoc could not load the document editor because the page did not provide a mount container.";
@@ -21773,7 +21770,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21773
21770
  if (!root) return;
21774
21771
  if (!(event.target instanceof Node) || !root.contains(event.target)) return;
21775
21772
  if (layers.value?.contains(event.target)) {
21776
- commentsStore.setActiveComment(proxy.$superdoc, null);
21773
+ if (!isActiveTrackedChangeContextMenuTarget(event.target)) commentsStore.setActiveComment(proxy.$superdoc, null);
21777
21774
  commentsStore.removePendingComment(proxy.$superdoc);
21778
21775
  resetClickAnchor();
21779
21776
  }
@@ -21826,16 +21823,17 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21826
21823
  onFontsResolved: onFontsResolvedFn,
21827
21824
  onPageCountKnown: proxy.$superdoc.config.onPageCountKnown ?? null,
21828
21825
  onReviewWindowPlanned: (payload) => {
21829
- if (payload?.routeLane === "canonical.typing-mutation") {
21830
- v2TypingReviewHydrationScheduler.schedule();
21831
- return;
21832
- }
21833
- if (v2TypingReviewHydrationScheduler.isPending()) return;
21834
21826
  v2ReviewHydrationController.onReviewWindowPlanned?.({
21835
21827
  ...payload,
21836
21828
  documentId: doc.id
21837
21829
  });
21838
21830
  },
21831
+ onReviewWindowCommitted: (payload) => {
21832
+ v2ReviewHydrationController.onCommittedPagePaint?.({
21833
+ ...payload,
21834
+ documentId: doc.id
21835
+ });
21836
+ },
21839
21837
  fontAssets: proxy.$superdoc.config.fonts,
21840
21838
  proofing: resolvedProofingConfig.value,
21841
21839
  isNewFile,
@@ -22163,8 +22161,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22163
22161
  });
22164
22162
  (0, vue.watch)(showCommentsSidebar, (value) => {
22165
22163
  proxy.$superdoc.broadcastSidebarToggle(value);
22166
- v2BuiltInReviewSurfaceOpen = value === true;
22167
- syncV2ReviewCatalogDemand();
22168
22164
  });
22169
22165
  useViewportFit({
22170
22166
  getSuperdoc: () => proxy.$superdoc,
@@ -22189,6 +22185,16 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22189
22185
  const handleViewportScrollOrResize = () => {
22190
22186
  recollectV2GeometryIfActive();
22191
22187
  };
22188
+ const handleV2TrackedChangeCarriersRestamped = (event) => {
22189
+ if (!isV2Mode.value) return;
22190
+ const itemIds = Array.isArray(event?.detail?.itemIds) ? event.detail.itemIds.map((id) => id == null ? "" : String(id)).filter(Boolean) : [];
22191
+ armV2TrackedChangeRestampGeometryRetention(event?.detail?.refreshReason ?? "tracked-change-restamp");
22192
+ recollectV2GeometryIfActive({
22193
+ retainMissingTrackedChangeGeometry: true,
22194
+ ...itemIds.length > 0 ? { retainedTrackedChangeIds: itemIds } : {},
22195
+ reason: "tracked-change-restamp"
22196
+ });
22197
+ };
22192
22198
  (0, vue.onMounted)(() => {
22193
22199
  document.addEventListener("contextmenu", handleDocumentContextMenu, true);
22194
22200
  document.addEventListener("keydown", handleDocumentShortcut, true);
@@ -22196,6 +22202,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22196
22202
  claimFindShortcut(findShortcutOwner);
22197
22203
  superdocRoot.value?.addEventListener("pointerdown", handleFindOwnershipInteraction, true);
22198
22204
  superdocRoot.value?.addEventListener("focusin", handleFindOwnershipInteraction, true);
22205
+ superdocRoot.value?.addEventListener(TRACKED_CHANGE_CARRIERS_RESTAMPED_EVENT, handleV2TrackedChangeCarriersRestamped);
22199
22206
  if (typeof window !== "undefined") {
22200
22207
  window.addEventListener("scroll", handleViewportScrollOrResize, true);
22201
22208
  window.addEventListener("resize", handleViewportScrollOrResize, true);
@@ -22312,6 +22319,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22312
22319
  proxy.$superdoc?.off?.("search:open", handleOpenFindRequest);
22313
22320
  superdocRoot.value?.removeEventListener("pointerdown", handleFindOwnershipInteraction, true);
22314
22321
  superdocRoot.value?.removeEventListener("focusin", handleFindOwnershipInteraction, true);
22322
+ superdocRoot.value?.removeEventListener(TRACKED_CHANGE_CARRIERS_RESTAMPED_EVENT, handleV2TrackedChangeCarriersRestamped);
22315
22323
  releaseFindShortcut(findShortcutOwner);
22316
22324
  if (typeof window !== "undefined") {
22317
22325
  window.removeEventListener("scroll", handleViewportScrollOrResize, true);
@@ -22321,8 +22329,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22321
22329
  cancelAnimationFrame(v2GeometryRafHandle);
22322
22330
  v2GeometryRafHandle = 0;
22323
22331
  }
22324
- clearV2TypingReviewHydrationTimer();
22325
- v2RemoteReviewHydrationScheduler.clear();
22326
22332
  document.removeEventListener("focusin", handleRuntimeFocusIn, true);
22327
22333
  document.removeEventListener("pointerdown", handleRuntimePointerDown, true);
22328
22334
  document.removeEventListener("mousedown", handleRuntimeMouseDown, true);
@@ -22330,7 +22336,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22330
22336
  document.removeEventListener("mouseup", handleDocumentSelectionChange, true);
22331
22337
  document.removeEventListener("selectionchange", handleDocumentSelectionChange);
22332
22338
  proxy.$superdoc?.off?.("document-mode-change", handleV2DocumentModeChange);
22333
- proxy.$superdoc?.off?.("comments-list-change", handleV2CommentsListChange);
22334
22339
  });
22335
22340
  const selectionLayer = (0, vue.ref)(null);
22336
22341
  const isDragging = (0, vue.ref)(false);
@@ -22826,7 +22831,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22826
22831
  ], 38);
22827
22832
  };
22828
22833
  }
22829
- }, [["__scopeId", "data-v-25570fd2"]]);
22834
+ }, [["__scopeId", "data-v-6833a014"]]);
22830
22835
  //#endregion
22831
22836
  //#region src/core/create-app.js
22832
22837
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -43330,7 +43335,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
43330
43335
  this.config.colors = shuffleArray(this.config.colors);
43331
43336
  this.userColorMap = /* @__PURE__ */ new Map();
43332
43337
  this.colorIndex = 0;
43333
- this.version = "2.4.0-next.16";
43338
+ this.version = "2.4.0-next.17";
43334
43339
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
43335
43340
  this.superdocId = config.superdocId || require_uuid.v4();
43336
43341
  this.colors = this.config.colors ?? [];