superdoc 2.4.0-next.16 → 2.4.0-next.18

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
  /**
@@ -8561,6 +8562,61 @@ var useCommentsStore = defineStore("comments", () => {
8561
8562
  syncCommentsToClients(superdoc, event);
8562
8563
  return Promise.resolve({ ok: true });
8563
8564
  };
8565
+ const applyV2ThreadLifecycleReceipt = ({ superdoc, documentId, lifecycle } = {}) => {
8566
+ const commentId = normalizeCommentId(lifecycle?.commentId);
8567
+ const status = lifecycle?.status;
8568
+ if (!commentId || status !== "open" && status !== "resolved") return null;
8569
+ const normalizedDocumentId = normalizeCommentId(documentId);
8570
+ const rows = commentsList.value.filter((comment) => {
8571
+ if (!comment || comment.trackedChange === true || isV2SyntheticTrackedChangeRow(comment)) return false;
8572
+ const rowDocumentId = normalizeCommentId(comment.fileId);
8573
+ return normalizedDocumentId == null || rowDocumentId == null || rowDocumentId === normalizedDocumentId;
8574
+ });
8575
+ const byAlias = /* @__PURE__ */ new Map();
8576
+ const childrenByParentAlias = /* @__PURE__ */ new Map();
8577
+ for (const row of rows) {
8578
+ for (const alias of [row.commentId, row.importedId].map(normalizeCommentId).filter(Boolean)) if (!byAlias.has(alias)) byAlias.set(alias, row);
8579
+ const parentId = normalizeCommentId(row.parentCommentId);
8580
+ if (parentId) {
8581
+ const children = childrenByParentAlias.get(parentId) ?? [];
8582
+ children.push(row);
8583
+ childrenByParentAlias.set(parentId, children);
8584
+ }
8585
+ }
8586
+ let root = byAlias.get(commentId) ?? null;
8587
+ const seenParents = /* @__PURE__ */ new Set();
8588
+ while (root?.parentCommentId != null) {
8589
+ const parentId = normalizeCommentId(root.parentCommentId);
8590
+ if (!parentId || seenParents.has(parentId)) break;
8591
+ seenParents.add(parentId);
8592
+ const parent = byAlias.get(parentId);
8593
+ if (!parent) break;
8594
+ root = parent;
8595
+ }
8596
+ if (!root) return null;
8597
+ const family = [];
8598
+ const queue = [root];
8599
+ const visited = /* @__PURE__ */ new Set();
8600
+ while (queue.length > 0) {
8601
+ const row = queue.shift();
8602
+ if (!row || visited.has(row)) continue;
8603
+ visited.add(row);
8604
+ family.push(row);
8605
+ for (const alias of [row.commentId, row.importedId].map(normalizeCommentId).filter(Boolean)) queue.push(...childrenByParentAlias.get(alias) ?? []);
8606
+ }
8607
+ const isResolved = status === "resolved";
8608
+ const resolvedAt = Date.now();
8609
+ for (const row of family) {
8610
+ row.resolvedTime = isResolved ? row.resolvedTime ?? resolvedAt : null;
8611
+ row.resolvedById = isResolved ? superdoc?.user?.id ?? null : null;
8612
+ row.resolvedByEmail = isResolved ? superdoc?.user?.email ?? null : null;
8613
+ row.resolvedByName = isResolved ? superdoc?.user?.name ?? null : null;
8614
+ }
8615
+ return {
8616
+ added: null,
8617
+ lifecycleUpdated: family.length
8618
+ };
8619
+ };
8564
8620
  const runV2CommentMutation = async ({ superdoc, adapter, fileId, operation, eventType, rejectionFallbackReason, rejectionEventExtras = {}, validateOutcome, successEventBuilder }) => {
8565
8621
  let outcome;
8566
8622
  try {
@@ -8610,11 +8666,17 @@ var useCommentsStore = defineStore("comments", () => {
8610
8666
  superdoc?.emit?.("comments-update", rejectedEvent);
8611
8667
  return failedOutcome;
8612
8668
  }
8613
- const reconciled = reconcileCommentsFromV2({
8669
+ const documentId = adapter.documentId ?? fileId;
8670
+ const reconciled = applyV2ThreadLifecycleReceipt({
8671
+ superdoc,
8672
+ documentId,
8673
+ lifecycle: outcome.threadLifecycle
8674
+ }) ?? reconcileCommentsFromV2({
8614
8675
  superdoc,
8615
8676
  adapter,
8616
- documentId: adapter.documentId ?? fileId,
8617
- items: outcome.items ?? []
8677
+ documentId,
8678
+ items: outcome.items ?? [],
8679
+ pruneStale: outcome.complete !== false
8618
8680
  });
8619
8681
  const successEvent = successEventBuilder?.({
8620
8682
  outcome,
@@ -8624,7 +8686,11 @@ var useCommentsStore = defineStore("comments", () => {
8624
8686
  return {
8625
8687
  ok: true,
8626
8688
  items: outcome.items ?? [],
8627
- reconciled
8689
+ reconciled,
8690
+ ...outcome.complete === false ? { complete: false } : {},
8691
+ ...outcome.visibleWindowSource != null ? { visibleWindowSource: outcome.visibleWindowSource } : {},
8692
+ ...outcome.threadLifecycle != null ? { threadLifecycle: outcome.threadLifecycle } : {},
8693
+ ...outcome.mutationPath != null ? { mutationPath: outcome.mutationPath } : {}
8628
8694
  };
8629
8695
  };
8630
8696
  const mapV2OutcomeCommentInputs = ({ outcome, adapter, fileId }) => {
@@ -8640,6 +8706,23 @@ var useCommentsStore = defineStore("comments", () => {
8640
8706
  const commentInputParentId = (input) => input?.parentCommentId != null ? String(input.parentCommentId) : null;
8641
8707
  const validateV2ThreadLifecycleRefresh = ({ outcome, adapter, fileId, commentId, expectedResolved, operation }) => {
8642
8708
  const id = commentId != null ? String(commentId) : null;
8709
+ const receiptLifecycle = outcome?.threadLifecycle;
8710
+ if (receiptLifecycle != null) {
8711
+ const observedId = normalizeCommentId(receiptLifecycle.commentId);
8712
+ const observedResolved = receiptLifecycle.status === "resolved";
8713
+ if (observedId === id && observedResolved === expectedResolved) return { ok: true };
8714
+ return {
8715
+ ok: false,
8716
+ reason: `v2-${operation}-receipt-lifecycle-mismatch`,
8717
+ detail: {
8718
+ expected: {
8719
+ commentId: id,
8720
+ status: expectedResolved ? "resolved" : "open"
8721
+ },
8722
+ observed: receiptLifecycle
8723
+ }
8724
+ };
8725
+ }
8643
8726
  const inputs = mapV2OutcomeCommentInputs({
8644
8727
  outcome,
8645
8728
  adapter,
@@ -8785,8 +8868,8 @@ var useCommentsStore = defineStore("comments", () => {
8785
8868
  * Resolve an existing comment through the v2 adapter.
8786
8869
  *
8787
8870
  * Plan §4.3 rules:
8788
- * - successful resolve refreshes from v2 list and clears the active
8789
- * comment / dialog target if the resolved comment was active
8871
+ * - successful resolve applies the committed lifecycle receipt to the
8872
+ * hydrated thread and clears the active comment / dialog target
8790
8873
  * - rejection leaves the row active, emits a rejected event
8791
8874
  * - active state must never reference a deleted/missing anchor — the
8792
8875
  * reconciler is already family-scoped (see TCS 001 §5)
@@ -8844,18 +8927,19 @@ var useCommentsStore = defineStore("comments", () => {
8844
8927
  *
8845
8928
  * Symmetric inverse of {@link resolveCommentV2}. The adapter routes the
8846
8929
  * reopen through `activeEditor.doc.comments.patch({ status: 'active' })`,
8847
- * which removes the resolved anchors and restores the live comment mark,
8848
- * then refreshes from the v2 comment list. Rules:
8930
+ * which removes the resolved anchors and restores the live comment mark.
8931
+ * The successful receipt updates the hydrated thread immediately while
8932
+ * normal review hydration remains the eventual reconciliation path. Rules:
8849
8933
  * - the store owns mutation gating (via the adapter capability state),
8850
- * adapter identity stamping, refresh reconciliation, and event emission
8934
+ * adapter identity stamping, local lifecycle projection, and event emission
8851
8935
  * - there is no dedicated REOPENED event in the comment event enum, so a
8852
- * successful reopen emits an UPDATE event with the refreshed (now open)
8936
+ * successful reopen emits an UPDATE event with the now-open
8853
8937
  * comment payload
8854
8938
  * - rejection is non-mutating and emits the same rejected-event shape as
8855
8939
  * the other v2 comment mutations; the row stays resolved so the user can
8856
8940
  * retry
8857
- * - body / replies / anchor identity are preserved by the reconciler; we
8858
- * only confirm the open state after the refreshed list lands
8941
+ * - body / replies / anchor identity are preserved; only lifecycle metadata
8942
+ * changes on the hydrated thread
8859
8943
  */
8860
8944
  const reopenCommentV2 = async ({ superdoc, commentId } = {}) => {
8861
8945
  if (commentsAreReadOnly()) return readOnlyMutationOutcome();
@@ -9020,7 +9104,7 @@ var useCommentsStore = defineStore("comments", () => {
9020
9104
  trackedItems: preparedParams.length
9021
9105
  };
9022
9106
  });
9023
- const hydrateCommentsFromV2 = async ({ superdoc, adapter, documentId, trackedChangesListMode = "all", isCurrent, signal, hydrationGeneration } = {}) => withInteractionSpan("store.comments.hydrateFromV2", "comments-list", { documentId: documentId ?? null }, async () => {
9107
+ const hydrateCommentsFromV2 = async ({ superdoc, adapter, documentId, trackedChangesListMode = "all", commentIds, isCurrent, signal, hydrationGeneration } = {}) => withInteractionSpan("store.comments.hydrateFromV2", "comments-list", { documentId: documentId ?? null }, async () => {
9024
9108
  const effectiveAdapter = adapter ?? getV2CommentsAdapter(superdoc);
9025
9109
  const visibleWindow = trackedChangesListMode === "visible-window";
9026
9110
  const read = visibleWindow ? effectiveAdapter?.selectVisibleReviewComments : effectiveAdapter?.refresh;
@@ -9042,6 +9126,7 @@ var useCommentsStore = defineStore("comments", () => {
9042
9126
  let result;
9043
9127
  try {
9044
9128
  const refreshOptions = {};
9129
+ if (visibleWindow && Array.isArray(commentIds)) refreshOptions.targetIds = commentIds;
9045
9130
  if (signal) refreshOptions.signal = signal;
9046
9131
  if (typeof hydrationGeneration === "number") refreshOptions.hydrationGeneration = hydrationGeneration;
9047
9132
  result = Object.keys(refreshOptions).length > 0 ? await read.call(effectiveAdapter, refreshOptions) : await read.call(effectiveAdapter);
@@ -9072,7 +9157,7 @@ var useCommentsStore = defineStore("comments", () => {
9072
9157
  adapter: effectiveAdapter,
9073
9158
  documentId,
9074
9159
  items: result.items ?? [],
9075
- pruneStale: !visibleWindow,
9160
+ pruneStale: !visibleWindow || Array.isArray(commentIds) && (!Array.isArray(result.unresolvedIds) || result.unresolvedIds.length === 0),
9076
9161
  hydrationGeneration
9077
9162
  });
9078
9163
  return {
@@ -9305,6 +9390,27 @@ var useCommentsStore = defineStore("comments", () => {
9305
9390
  storySnapshots
9306
9391
  };
9307
9392
  };
9393
+ const reconcileAuthoritativeV2TrackedChangeSidebar = ({ superdoc, editor, documentId, refreshReason = "tracked-change-sidebar-authoritative" } = {}) => {
9394
+ const adapter = getV2TrackedChangesAdapter(superdoc) ?? editor?.v2TrackedChanges ?? null;
9395
+ if (!adapter || typeof adapter.listTrackedChanges !== "function" || typeof adapter.mapV2TrackedChangeToCommentParams !== "function") return false;
9396
+ const effectiveDocumentId = documentId ?? adapter.documentId ?? editor?.documentId ?? editor?.options?.documentId ?? superdoc?.activeEditor?.documentId ?? superdoc?.activeEditor?.options?.documentId ?? null;
9397
+ if (effectiveDocumentId == null) return false;
9398
+ const normalizedDocumentId = String(effectiveDocumentId);
9399
+ hydrateTrackedChangesFromV2({
9400
+ superdoc,
9401
+ adapter,
9402
+ documentId: normalizedDocumentId,
9403
+ trackedChangesListMode: "background-reconcile",
9404
+ refreshReason,
9405
+ blocking: false,
9406
+ isCurrent: () => {
9407
+ const activeEditor = superdoc?.activeEditor ?? null;
9408
+ const activeDocumentId = activeEditor?.documentId ?? activeEditor?.options?.documentId ?? null;
9409
+ return activeDocumentId == null || String(activeDocumentId) === normalizedDocumentId;
9410
+ }
9411
+ });
9412
+ return true;
9413
+ };
9308
9414
  /**
9309
9415
  * Bootstrap tracked-change comment threads after a DOCX import finishes.
9310
9416
  *
@@ -9342,6 +9448,12 @@ var useCommentsStore = defineStore("comments", () => {
9342
9448
  editor,
9343
9449
  structuralChanges: captured.structuralChanges
9344
9450
  });
9451
+ reconcileAuthoritativeV2TrackedChangeSidebar({
9452
+ superdoc,
9453
+ editor,
9454
+ documentId: editor?.options?.documentId,
9455
+ refreshReason: "import-bootstrap-authoritative"
9456
+ });
9345
9457
  return true;
9346
9458
  };
9347
9459
  const isCurrentImportedTrackedChangeBootstrap = (task) => {
@@ -10327,7 +10439,8 @@ var useCommentsStore = defineStore("comments", () => {
10327
10439
  lateResultDropped: true
10328
10440
  };
10329
10441
  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;
10442
+ const partialListMode = trackedChangesListMode === "startup-page" || trackedChangesListMode === "interaction-prime" || trackedChangesListMode === "visible-window";
10443
+ 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
10444
  if (signal?.aborted || trackedChangeSyncGeneration(effectiveAdapter) !== syncGeneration) return {
10332
10445
  ok: false,
10333
10446
  reason: "review-hydration-superseded",
@@ -10731,6 +10844,12 @@ var useCommentsStore = defineStore("comments", () => {
10731
10844
  broadcastChanges,
10732
10845
  structuralChanges: captured.structuralChanges
10733
10846
  });
10847
+ reconcileAuthoritativeV2TrackedChangeSidebar({
10848
+ superdoc,
10849
+ editor,
10850
+ documentId: activeDocumentId,
10851
+ refreshReason: "sync-authoritative"
10852
+ });
10734
10853
  };
10735
10854
  /**
10736
10855
  * Surface decidable whole-table structural tracked changes (table insert /
@@ -11201,6 +11320,16 @@ var useCommentsStore = defineStore("comments", () => {
11201
11320
  const syncActiveFloatingInstanceWithComment = (commentId) => {
11202
11321
  if (!doesFloatingInstanceBelongToComment(activeFloatingCommentInstanceId.value, commentId)) setActiveFloatingCommentInstance(null);
11203
11322
  };
11323
+ function canonicalizeActiveCommentAlias() {
11324
+ const activeId = normalizeCommentId(activeComment.value);
11325
+ if (!activeId) return false;
11326
+ const comment = getComment(activeId);
11327
+ const canonicalId = normalizeCommentId(comment?.commentId);
11328
+ if (!canonicalId || canonicalId === activeId) return false;
11329
+ activeComment.value = canonicalId;
11330
+ syncActiveFloatingInstanceWithComment(canonicalId);
11331
+ return true;
11332
+ }
11204
11333
  const setViewingVisibility = ({ documentMode, commentsVisible, trackChangesVisible } = {}) => {
11205
11334
  if (typeof documentMode === "string") viewingVisibility.documentMode = documentMode;
11206
11335
  if (typeof commentsVisible === "boolean") viewingVisibility.commentsVisible = commentsVisible;
@@ -13904,6 +14033,12 @@ var _sfc_main$30 = {
13904
14033
  setup(__props) {
13905
14034
  const ESTIMATED_HEIGHT = 110;
13906
14035
  const OBSERVER_MARGIN = 600;
14036
+ const SCROLL_OWNER_OVERFLOW_VALUES = /* @__PURE__ */ new Set([
14037
+ "auto",
14038
+ "scroll",
14039
+ "hidden",
14040
+ "clip"
14041
+ ]);
13907
14042
  const resolveCollisions = (positions, activeIndex, gap) => {
13908
14043
  if (activeIndex >= 0) {
13909
14044
  positions[activeIndex].top = positions[activeIndex].anchorTop;
@@ -14308,6 +14443,8 @@ var _sfc_main$30 = {
14308
14443
  let activeLayoutContinuityFrame = null;
14309
14444
  let directDecisionContinuity = null;
14310
14445
  let directDecisionSourceId = null;
14446
+ let ownerScrollContinuityResetFrame = null;
14447
+ const ownerScrollTargets = /* @__PURE__ */ new Set();
14311
14448
  const releaseDirectDecisionContinuity = () => {
14312
14449
  directDecisionContinuity = null;
14313
14450
  directDecisionSourceId = null;
@@ -14371,6 +14508,36 @@ var _sfc_main$30 = {
14371
14508
  }
14372
14509
  setInstantLayoutTransitionsDisabled(false);
14373
14510
  };
14511
+ const releaseDecisionContinuityForOwnerScroll = () => {
14512
+ if (!directDecisionContinuity && !sidebarContinuityAnchor) return;
14513
+ releaseDirectDecisionContinuity();
14514
+ clearSidebarContinuityAnchor();
14515
+ setInstantLayoutTransitionsDisabled(true);
14516
+ sidebarOffsetY.value = 0;
14517
+ if (ownerScrollContinuityResetFrame != null) cancelAnimationFrame(ownerScrollContinuityResetFrame);
14518
+ ownerScrollContinuityResetFrame = requestAnimationFrame(() => {
14519
+ ownerScrollContinuityResetFrame = null;
14520
+ if (!directDecisionContinuity && !sidebarContinuityAnchor) setInstantLayoutTransitionsDisabled(false);
14521
+ });
14522
+ };
14523
+ const handleOwnerScroll = () => {
14524
+ releaseDecisionContinuityForOwnerScroll();
14525
+ refreshViewportWindow();
14526
+ };
14527
+ const registerOwnerScrollListeners = () => {
14528
+ const addTarget = (target) => {
14529
+ if (!target?.addEventListener || ownerScrollTargets.has(target)) return;
14530
+ target.addEventListener("scroll", handleOwnerScroll, { passive: true });
14531
+ ownerScrollTargets.add(target);
14532
+ };
14533
+ addTarget(props.parent);
14534
+ for (let ancestor = floatingCommentsContainer.value?.parentElement; ancestor; ancestor = ancestor.parentElement) if (SCROLL_OWNER_OVERFLOW_VALUES.has(window.getComputedStyle(ancestor).overflowY)) addTarget(ancestor);
14535
+ addTarget(window);
14536
+ };
14537
+ const unregisterOwnerScrollListeners = () => {
14538
+ for (const target of ownerScrollTargets) target.removeEventListener?.("scroll", handleOwnerScroll);
14539
+ ownerScrollTargets.clear();
14540
+ };
14374
14541
  const scheduleSidebarContinuityAlignment = () => {
14375
14542
  if (!sidebarContinuityAnchor || continuityAlignmentScheduled) return;
14376
14543
  continuityAlignmentScheduled = true;
@@ -14623,7 +14790,7 @@ var _sfc_main$30 = {
14623
14790
  });
14624
14791
  (0, vue.onMounted)(() => {
14625
14792
  setupObserver();
14626
- props.parent?.addEventListener?.("scroll", refreshViewportWindow, { passive: true });
14793
+ registerOwnerScrollListeners();
14627
14794
  window.addEventListener("resize", refreshViewportWindow, { passive: true });
14628
14795
  document.addEventListener("pointerdown", releaseDirectDecisionContinuityForUnrelatedPointer, true);
14629
14796
  (0, vue.nextTick)(observePlaceholders);
@@ -14637,7 +14804,11 @@ var _sfc_main$30 = {
14637
14804
  cancelAnimationFrame(activeLayoutContinuityFrame);
14638
14805
  activeLayoutContinuityFrame = null;
14639
14806
  }
14640
- props.parent?.removeEventListener?.("scroll", refreshViewportWindow);
14807
+ if (ownerScrollContinuityResetFrame != null) {
14808
+ cancelAnimationFrame(ownerScrollContinuityResetFrame);
14809
+ ownerScrollContinuityResetFrame = null;
14810
+ }
14811
+ unregisterOwnerScrollListeners();
14641
14812
  window.removeEventListener("resize", refreshViewportWindow);
14642
14813
  document.removeEventListener("pointerdown", releaseDirectDecisionContinuityForUnrelatedPointer, true);
14643
14814
  if (viewportFrame != null) {
@@ -14706,7 +14877,7 @@ var _sfc_main$30 = {
14706
14877
  };
14707
14878
  }
14708
14879
  };
14709
- var FloatingComments_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$30, [["__scopeId", "data-v-a0a841ce"]]);
14880
+ var FloatingComments_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$30, [["__scopeId", "data-v-d8d03209"]]);
14710
14881
  //#endregion
14711
14882
  //#region src/components/CommentsLayer/PdfCommentsLayer.vue
14712
14883
  var _hoisted_1$22 = {
@@ -15387,6 +15558,19 @@ var VALID_COMMENTS_DISPLAY_MODES = /* @__PURE__ */ new Set([
15387
15558
  "inline"
15388
15559
  ]);
15389
15560
  /**
15561
+ * Whether a context-menu event landed inside the tracked-change carrier that
15562
+ * is already visually active. The review visual owner maintains this marker,
15563
+ * so the right-click path can stay synchronous and avoid a catalog lookup or
15564
+ * document-wide DOM query.
15565
+ *
15566
+ * @param {EventTarget | null} target
15567
+ * @returns {boolean}
15568
+ */
15569
+ function isActiveTrackedChangeContextMenuTarget(target) {
15570
+ const element = target;
15571
+ return typeof element?.closest === "function" && element.closest(".track-change-focused") != null;
15572
+ }
15573
+ /**
15390
15574
  * Normalize adaptive comments UI policy fields.
15391
15575
  *
15392
15576
  * @param {false | Record<string, unknown> | undefined} commentsConfig
@@ -15822,74 +16006,6 @@ function resolveV2ReviewTargetCommentId(target, getComment) {
15822
16006
  return commentId != null ? String(commentId) : null;
15823
16007
  }
15824
16008
  //#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
16009
  //#region src/helpers/v2-author-required-rejection.js
15894
16010
  var NO_AUTHOR_SIGNAL = "no-author-configured";
15895
16011
  /** Stable, non-terminal exception code surfaced to consumers. */
@@ -20351,9 +20467,9 @@ var _hoisted_1$16 = {
20351
20467
  var _hoisted_2$13 = ["innerHTML"];
20352
20468
  var _hoisted_3$10 = { class: "superdoc__document document" };
20353
20469
  var _hoisted_4$7 = { class: "floating-comments" };
20470
+ var TRACKED_CHANGE_CARRIERS_RESTAMPED_EVENT = "superdoc:v2-tracked-change-carriers-restamped";
20354
20471
  var UNAVAILABLE_COMMAND_RESULT = false;
20355
20472
  var V2_SELECTION_TOOLBAR_SYNC_RETRY_FRAMES = 3;
20356
- var V2_TYPING_REVIEW_HYDRATION_IDLE_MS = 6500;
20357
20473
  var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default({
20358
20474
  __name: "SuperDoc",
20359
20475
  emits: ["selection-update"],
@@ -20516,6 +20632,27 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
20516
20632
  editor: proxy.$superdoc?.activeEditor
20517
20633
  });
20518
20634
  };
20635
+ const reconcileAuthoritativeV2TrackedChangeSidebar = ({ adapter, documentId, refreshReason = "startup-authoritative" } = {}) => {
20636
+ if (!adapter || typeof adapter.listTrackedChanges !== "function") return false;
20637
+ const normalizedDocumentId = documentId == null ? null : String(documentId);
20638
+ if (!normalizedDocumentId) return false;
20639
+ commentsStore.hydrateTrackedChangesFromV2?.({
20640
+ superdoc: proxy.$superdoc,
20641
+ adapter,
20642
+ documentId: normalizedDocumentId,
20643
+ trackedChangesListMode: "background-reconcile",
20644
+ refreshReason,
20645
+ blocking: false,
20646
+ isCurrent: () => {
20647
+ const activeEditor = proxy.$superdoc?.activeEditor ?? null;
20648
+ const activeDocumentId = activeEditor?.documentId ?? activeEditor?.options?.documentId ?? null;
20649
+ if (activeDocumentId != null && String(activeDocumentId) !== normalizedDocumentId) return false;
20650
+ const activeAdapter = activeEditor?.v2TrackedChanges ?? commentsStore.getV2TrackedChangesAdapter?.(proxy.$superdoc);
20651
+ return !activeAdapter || activeAdapter === adapter;
20652
+ }
20653
+ });
20654
+ return true;
20655
+ };
20519
20656
  const scheduleReplayTrackedChangeSync = () => {
20520
20657
  pendingReplayTrackedChangeSync.value = true;
20521
20658
  (0, vue.nextTick)(() => {
@@ -21059,7 +21196,11 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21059
21196
  pageFurniture: pageFurniture ?? null,
21060
21197
  presence: presence ?? null,
21061
21198
  lock: lock ?? null,
21062
- reviewHydration: { getDiagnostics: () => v2ReviewHydrationController.getDiagnostics() },
21199
+ reviewHydration: {
21200
+ getDiagnostics: () => v2ReviewHydrationController.getDiagnostics(),
21201
+ getSnapshot: () => v2ReviewHydrationController.getSnapshot?.() ?? null,
21202
+ subscribe: (listener) => v2ReviewHydrationController.subscribe?.(listener) ?? (() => void 0)
21203
+ },
21063
21204
  extensions: createV2ExtensionsFacet(host),
21064
21205
  fonts: fonts ?? host?.getFontRuntime?.() ?? null,
21065
21206
  /**
@@ -21115,6 +21256,11 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21115
21256
  console.warn("[SuperDoc][v2] initial render-readiness snapshot failed", err);
21116
21257
  }
21117
21258
  }
21259
+ if (commentsModuleEnabled && trackedChangesAdapter) reconcileAuthoritativeV2TrackedChangeSidebar({
21260
+ adapter: trackedChangesAdapter,
21261
+ documentId,
21262
+ refreshReason: "startup-authoritative"
21263
+ });
21118
21264
  if (areDocumentsReady.value && !proxy.$superdoc.config.collaboration) isReady.value = true;
21119
21265
  isFloatingCommentsReady.value = true;
21120
21266
  hasInitializedLocations.value = true;
@@ -21383,7 +21529,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21383
21529
  }
21384
21530
  },
21385
21531
  onCommittedPagePaint: (commit) => {
21386
- if (commit?.routeLane === "canonical.typing-mutation" || v2TypingReviewHydrationScheduler.isPending()) return;
21387
21532
  v2ReviewHydrationController.onCommittedPagePaint?.({
21388
21533
  ...commit,
21389
21534
  documentId: commit?.payload?.documentId ?? null
@@ -21428,7 +21573,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21428
21573
  const onV2RenderReadiness = (payload) => {
21429
21574
  const snapshot = payload?.snapshot ?? payload ?? null;
21430
21575
  if (!snapshot) return;
21431
- if (v2TypingReviewHydrationScheduler.isPending()) return;
21432
21576
  v2ReviewHydrationController.onRenderReadiness(snapshot);
21433
21577
  };
21434
21578
  const v2PageMetricsSnapshot = (0, vue.shallowRef)(null);
@@ -21478,8 +21622,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21478
21622
  if (latestV2MountStage && (clearedDocumentId == null || latestV2MountStage.dataset?.superdocV2DocumentId === clearedDocumentId)) latestV2MountStage = null;
21479
21623
  v2ReviewHydrationController.reset("render-cleared");
21480
21624
  v2ReviewMutationReconciler.reset();
21481
- clearV2TypingReviewHydrationTimer();
21482
- v2RemoteReviewHydrationScheduler.clear();
21483
21625
  commentsStore.setV2CommentsAdapter?.(null);
21484
21626
  commentsStore.setV2TrackedChangesAdapter?.(null);
21485
21627
  commentsStore.clearEditorCommentPositions?.();
@@ -21488,26 +21630,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21488
21630
  v2RulerHostStyle.value = {};
21489
21631
  v2RulerReady.value = false;
21490
21632
  };
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
21633
  const v2ReviewMutationReconciler = require_create_super_doc_ui.createV2ReviewMutationReconciler({
21512
21634
  getContext: () => {
21513
21635
  const activeEditor = proxy.$superdoc?.activeEditor ?? null;
@@ -21537,31 +21659,10 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21537
21659
  reason: "review-reconcile"
21538
21660
  })
21539
21661
  });
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
21662
  const onV2HostEvent = (document, event) => {
21561
21663
  if (!event) return;
21562
21664
  const documentId = document?.id ?? null;
21563
21665
  if (event.type === "review-mutation:started") {
21564
- clearV2TypingReviewHydrationTimer();
21565
21666
  const activeEditor = proxy.$superdoc?.activeEditor ?? null;
21566
21667
  commentsStore.supersedeV2ReviewHydration?.({
21567
21668
  commentsAdapter: activeEditor?.v2Comments ?? null,
@@ -21583,8 +21684,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21583
21684
  return;
21584
21685
  }
21585
21686
  if (event.type === "collaboration:remote-changed") {
21586
- v2ReviewHydrationController.invalidate("collaboration:remote-changed");
21587
- v2RemoteReviewHydrationScheduler.schedule(documentId);
21687
+ if (event.reviewChanged !== false) v2ReviewHydrationController.invalidate("collaboration:remote-review-changed");
21588
21688
  return;
21589
21689
  }
21590
21690
  if (event.type === "source:complete") {
@@ -21609,11 +21709,12 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21609
21709
  emitV2EditorUpdate();
21610
21710
  }
21611
21711
  if (event.type !== "mutation:committed") return;
21612
- v2ReviewHydrationController.invalidate("mutation-committed");
21712
+ if (event.reviewSidecarOnly === true) v2ReviewHydrationController.hydrateNow("review-sidecar-committed");
21613
21713
  const reviewImpact = require_create_super_doc_ui.getV2TrackedChangeMutationImpact(event);
21614
21714
  if (Array.isArray(reviewImpact?.remappedPairs) && reviewImpact.remappedPairs.length > 0) commentsStore.remapTrackedChangeIdentities?.(reviewImpact.remappedPairs, { documentId });
21615
21715
  if (reviewImpact) armV2TrackedChangeRestampGeometryRetention("tracked-change-mutation");
21616
- const readiness = (proxy.$superdoc?.activeEditor ?? null)?.documentMutationReadiness ?? null;
21716
+ const activeEditor = proxy.$superdoc?.activeEditor ?? null;
21717
+ const readiness = activeEditor?.documentMutationReadiness ?? null;
21617
21718
  const receipt = event.origin === "history" ? null : event.receipt;
21618
21719
  const canWaitForExactPaint = reviewImpact && typeof receipt?.txId === "string" && receipt.txId.length > 0 && typeof readiness?.whenPainted === "function";
21619
21720
  const reconciliation = v2ReviewMutationReconciler.enqueueAfterPaint(reviewImpact, canWaitForExactPaint ? () => readiness.whenPainted.call(readiness, receipt) : null);
@@ -21628,43 +21729,37 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21628
21729
  resumeDomains: reconciledAllResolved ? ["comments"] : ["comments", "trackedChanges"],
21629
21730
  trackedRowCount: commentsStore.getV2TrackedChangeRowCount?.(documentId) ?? null
21630
21731
  });
21732
+ if (!reconciledAllResolved) reconcileAuthoritativeV2TrackedChangeSidebar({
21733
+ adapter: activeEditor?.v2TrackedChanges ?? null,
21734
+ documentId,
21735
+ refreshReason: "mutation-authoritative"
21736
+ });
21631
21737
  };
21632
21738
  Promise.resolve(reconciliation).then(settleReviewMutation, () => settleReviewMutation(false));
21633
21739
  return;
21634
21740
  }
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
- }
21741
+ if (reviewImpact?.reconcileMode === "authoritative" && reviewImpact.upsertIds.size > 0) return;
21645
21742
  if (reviewImpact?.removedIds.size > 0 && reviewImpact.upsertIds.size === 0) return;
21646
- hydrateV2ReviewRowsFromHost();
21647
21743
  };
21648
21744
  const onV2LinkClick = (payload) => {
21649
21745
  linkPopover.handleLinkClick(payload);
21650
21746
  };
21651
- const recollectV2GeometryIfActive = () => {
21747
+ const recollectV2GeometryIfActive = (options = void 0) => {
21652
21748
  if (!isV2Mode.value) return;
21653
21749
  if (!v2GeometryPublisher.getLastPayload()) return;
21654
21750
  if (v2GeometryRafHandle && typeof cancelAnimationFrame === "function") cancelAnimationFrame(v2GeometryRafHandle);
21655
21751
  if (typeof requestAnimationFrame !== "function") {
21656
- v2GeometryPublisher.recollect();
21752
+ v2GeometryPublisher.recollect(resolveV2GeometryPublishOptions(options));
21657
21753
  return;
21658
21754
  }
21659
21755
  v2GeometryRafHandle = requestAnimationFrame(() => {
21660
21756
  v2GeometryRafHandle = 0;
21661
- v2GeometryPublisher.recollect();
21757
+ v2GeometryPublisher.recollect(resolveV2GeometryPublishOptions(options));
21662
21758
  });
21663
21759
  };
21664
21760
  const handleV2DocumentModeChange = () => {
21665
21761
  if (!isV2Mode.value) return;
21666
21762
  try {
21667
- clearV2TypingReviewHydrationTimer();
21668
21763
  v2ReviewHydrationController.hydrateNow("document-mode-change");
21669
21764
  } catch (err) {
21670
21765
  console.warn("[SuperDoc][v2] document-mode-change rehydrate failed", err);
@@ -21683,22 +21778,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21683
21778
  else republishGeometry();
21684
21779
  });
21685
21780
  };
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
21781
  const getV2EditorFailureMessage = (reason) => {
21703
21782
  switch (reason) {
21704
21783
  case "editing-mount-required": return "SuperDoc could not load the document editor because the page did not provide a mount container.";
@@ -21773,7 +21852,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21773
21852
  if (!root) return;
21774
21853
  if (!(event.target instanceof Node) || !root.contains(event.target)) return;
21775
21854
  if (layers.value?.contains(event.target)) {
21776
- commentsStore.setActiveComment(proxy.$superdoc, null);
21855
+ if (!isActiveTrackedChangeContextMenuTarget(event.target)) commentsStore.setActiveComment(proxy.$superdoc, null);
21777
21856
  commentsStore.removePendingComment(proxy.$superdoc);
21778
21857
  resetClickAnchor();
21779
21858
  }
@@ -21826,16 +21905,17 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
21826
21905
  onFontsResolved: onFontsResolvedFn,
21827
21906
  onPageCountKnown: proxy.$superdoc.config.onPageCountKnown ?? null,
21828
21907
  onReviewWindowPlanned: (payload) => {
21829
- if (payload?.routeLane === "canonical.typing-mutation") {
21830
- v2TypingReviewHydrationScheduler.schedule();
21831
- return;
21832
- }
21833
- if (v2TypingReviewHydrationScheduler.isPending()) return;
21834
21908
  v2ReviewHydrationController.onReviewWindowPlanned?.({
21835
21909
  ...payload,
21836
21910
  documentId: doc.id
21837
21911
  });
21838
21912
  },
21913
+ onReviewWindowCommitted: (payload) => {
21914
+ v2ReviewHydrationController.onCommittedPagePaint?.({
21915
+ ...payload,
21916
+ documentId: doc.id
21917
+ });
21918
+ },
21839
21919
  fontAssets: proxy.$superdoc.config.fonts,
21840
21920
  proofing: resolvedProofingConfig.value,
21841
21921
  isNewFile,
@@ -22163,8 +22243,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22163
22243
  });
22164
22244
  (0, vue.watch)(showCommentsSidebar, (value) => {
22165
22245
  proxy.$superdoc.broadcastSidebarToggle(value);
22166
- v2BuiltInReviewSurfaceOpen = value === true;
22167
- syncV2ReviewCatalogDemand();
22168
22246
  });
22169
22247
  useViewportFit({
22170
22248
  getSuperdoc: () => proxy.$superdoc,
@@ -22189,6 +22267,16 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22189
22267
  const handleViewportScrollOrResize = () => {
22190
22268
  recollectV2GeometryIfActive();
22191
22269
  };
22270
+ const handleV2TrackedChangeCarriersRestamped = (event) => {
22271
+ if (!isV2Mode.value) return;
22272
+ const itemIds = Array.isArray(event?.detail?.itemIds) ? event.detail.itemIds.map((id) => id == null ? "" : String(id)).filter(Boolean) : [];
22273
+ armV2TrackedChangeRestampGeometryRetention(event?.detail?.refreshReason ?? "tracked-change-restamp");
22274
+ recollectV2GeometryIfActive({
22275
+ retainMissingTrackedChangeGeometry: true,
22276
+ ...itemIds.length > 0 ? { retainedTrackedChangeIds: itemIds } : {},
22277
+ reason: "tracked-change-restamp"
22278
+ });
22279
+ };
22192
22280
  (0, vue.onMounted)(() => {
22193
22281
  document.addEventListener("contextmenu", handleDocumentContextMenu, true);
22194
22282
  document.addEventListener("keydown", handleDocumentShortcut, true);
@@ -22196,6 +22284,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22196
22284
  claimFindShortcut(findShortcutOwner);
22197
22285
  superdocRoot.value?.addEventListener("pointerdown", handleFindOwnershipInteraction, true);
22198
22286
  superdocRoot.value?.addEventListener("focusin", handleFindOwnershipInteraction, true);
22287
+ superdocRoot.value?.addEventListener(TRACKED_CHANGE_CARRIERS_RESTAMPED_EVENT, handleV2TrackedChangeCarriersRestamped);
22199
22288
  if (typeof window !== "undefined") {
22200
22289
  window.addEventListener("scroll", handleViewportScrollOrResize, true);
22201
22290
  window.addEventListener("resize", handleViewportScrollOrResize, true);
@@ -22312,6 +22401,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22312
22401
  proxy.$superdoc?.off?.("search:open", handleOpenFindRequest);
22313
22402
  superdocRoot.value?.removeEventListener("pointerdown", handleFindOwnershipInteraction, true);
22314
22403
  superdocRoot.value?.removeEventListener("focusin", handleFindOwnershipInteraction, true);
22404
+ superdocRoot.value?.removeEventListener(TRACKED_CHANGE_CARRIERS_RESTAMPED_EVENT, handleV2TrackedChangeCarriersRestamped);
22315
22405
  releaseFindShortcut(findShortcutOwner);
22316
22406
  if (typeof window !== "undefined") {
22317
22407
  window.removeEventListener("scroll", handleViewportScrollOrResize, true);
@@ -22321,8 +22411,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22321
22411
  cancelAnimationFrame(v2GeometryRafHandle);
22322
22412
  v2GeometryRafHandle = 0;
22323
22413
  }
22324
- clearV2TypingReviewHydrationTimer();
22325
- v2RemoteReviewHydrationScheduler.clear();
22326
22414
  document.removeEventListener("focusin", handleRuntimeFocusIn, true);
22327
22415
  document.removeEventListener("pointerdown", handleRuntimePointerDown, true);
22328
22416
  document.removeEventListener("mousedown", handleRuntimeMouseDown, true);
@@ -22330,7 +22418,6 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22330
22418
  document.removeEventListener("mouseup", handleDocumentSelectionChange, true);
22331
22419
  document.removeEventListener("selectionchange", handleDocumentSelectionChange);
22332
22420
  proxy.$superdoc?.off?.("document-mode-change", handleV2DocumentModeChange);
22333
- proxy.$superdoc?.off?.("comments-list-change", handleV2CommentsListChange);
22334
22421
  });
22335
22422
  const selectionLayer = (0, vue.ref)(null);
22336
22423
  const isDragging = (0, vue.ref)(false);
@@ -22826,7 +22913,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22826
22913
  ], 38);
22827
22914
  };
22828
22915
  }
22829
- }, [["__scopeId", "data-v-25570fd2"]]);
22916
+ }, [["__scopeId", "data-v-6833a014"]]);
22830
22917
  //#endregion
22831
22918
  //#region src/core/create-app.js
22832
22919
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -43330,7 +43417,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
43330
43417
  this.config.colors = shuffleArray(this.config.colors);
43331
43418
  this.userColorMap = /* @__PURE__ */ new Map();
43332
43419
  this.colorIndex = 0;
43333
- this.version = "2.4.0-next.16";
43420
+ this.version = "2.4.0-next.18";
43334
43421
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
43335
43422
  this.superdocId = config.superdocId || require_uuid.v4();
43336
43423
  this.colors = this.config.colors ?? [];