superdoc 2.0.0-next.24 → 2.0.0-next.25

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.
@@ -5,7 +5,7 @@ import { t as v4_default } from "./chunks/uuid-B2Sqk-3p.es.js";
5
5
  import { a as init_dist, i as global, n as init_dist$1, r as process$1, t as require_jszip_min } from "./chunks/jszip-DzmwAHr3.es.js";
6
6
  import { t as __plugin_vue_export_helper_default } from "./chunks/_plugin-vue_export-helper-CInC0bKI.es.js";
7
7
  import { n as PDF_TO_CSS_UNITS } from "./chunks/constants-CY3R3_kF.es.js";
8
- import { a as createV2ReviewMutationReconciler, i as isV2EditableTextMutationEvent, o as getV2TrackedChangeMutationImpact, t as createSuperDocUI } from "./chunks/create-super-doc-ui-BMpP-iB6.es.js";
8
+ import { a as createV2ReviewMutationReconciler, i as isV2EditableTextMutationEvent, o as getV2TrackedChangeMutationImpact, t as createSuperDocUI } from "./chunks/create-super-doc-ui-CBs8xQUw.es.js";
9
9
  import * as Vue from "vue";
10
10
  import { Fragment, Teleport, Transition, computed, createApp, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineAsyncComponent, defineComponent, getCurrentInstance, h, inject, markRaw, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onActivated, onBeforeUnmount, onDeactivated, onMounted, openBlock, reactive, ref, renderList, renderSlot, resolveDirective, resolveDynamicComponent, shallowRef, toDisplayString, toRaw, toRef, unref, useAttrs, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
11
11
  import "y-websocket";
@@ -1733,7 +1733,13 @@ function useSelection(params) {
1733
1733
  };
1734
1734
  }
1735
1735
  const DOCUMENT_EDITOR_SELECTION_SOURCE = "document-editor";
1736
+ const COMMENT_RECONCILIATION_TOKEN = Symbol("comment-reconciliation");
1736
1737
  var getCommentIds = (comment) => [comment?.commentId, comment?.importedId].filter((id) => id != null).map((id) => String(id));
1738
+ var readOnlyMutationOutcome = () => ({
1739
+ ok: false,
1740
+ reason: "read-only-document"
1741
+ });
1742
+ var commentsAreReadOnly = (superdoc) => superdoc?.commentsStore?.getConfig?.readOnly === true || superdoc?.config?.modules?.comments?.readOnly === true;
1737
1743
  function getThreadDescendants(superdoc, rootComment) {
1738
1744
  const store = superdoc?.commentsStore;
1739
1745
  if (!store) return [];
@@ -1813,7 +1819,9 @@ function useComment(params) {
1813
1819
  const resolvedByEmail = ref(params.resolvedByEmail || null);
1814
1820
  const resolvedByName = ref(params.resolvedByName || null);
1815
1821
  const trackedChangeDecision = ref(params.trackedChangeDecision || null);
1816
- const resolveComment = ({ id, email, name, superdoc, decision }) => {
1822
+ const resolveComment = ({ id, email, name, superdoc, decision, reconciliationToken }) => {
1823
+ const isCanonicalReconciliation = reconciliationToken === COMMENT_RECONCILIATION_TOKEN;
1824
+ if (commentsAreReadOnly(superdoc) && !isCanonicalReconciliation) return readOnlyMutationOutcome();
1817
1825
  if (resolvedTime.value) return;
1818
1826
  resolvedTime.value = Date.now();
1819
1827
  resolvedById.value = id ?? null;
@@ -1851,6 +1859,7 @@ function useComment(params) {
1851
1859
  });
1852
1860
  };
1853
1861
  const setIsInternal = ({ isInternal: newIsInternal, superdoc }) => {
1862
+ if (commentsAreReadOnly(superdoc)) return readOnlyMutationOutcome();
1854
1863
  const previousValue = isInternal.value;
1855
1864
  if (previousValue === newIsInternal) return;
1856
1865
  isInternal.value = newIsInternal;
@@ -1879,6 +1888,7 @@ function useComment(params) {
1879
1888
  });
1880
1889
  };
1881
1890
  const setText = ({ text, superdoc, suppressUpdate }) => {
1891
+ if (!suppressUpdate && commentsAreReadOnly(superdoc)) return readOnlyMutationOutcome();
1882
1892
  commentText.value = text;
1883
1893
  mentions.value = extractMentions(text);
1884
1894
  if (suppressUpdate) return;
@@ -2859,6 +2869,11 @@ const useCommentsStore = defineStore("comments", () => {
2859
2869
  allowResolve: true,
2860
2870
  showResolved: false
2861
2871
  });
2872
+ const readOnlyMutationOutcome$1 = () => ({
2873
+ ok: false,
2874
+ reason: "read-only-document"
2875
+ });
2876
+ const commentsAreReadOnly$1 = () => commentsConfig.readOnly === true;
2862
2877
  const viewingVisibility = reactive({
2863
2878
  documentMode: "editing",
2864
2879
  commentsVisible: false,
@@ -2867,6 +2882,8 @@ const useCommentsStore = defineStore("comments", () => {
2867
2882
  const isDebugging = false;
2868
2883
  const debounceTimers = {};
2869
2884
  const trackedChangeResolutionSnapshots = /* @__PURE__ */ new WeakMap();
2885
+ const importedTrackedChangeBootstrapTasks = /* @__PURE__ */ new Map();
2886
+ let importedTrackedChangeBootstrapGeneration = 0;
2870
2887
  const isPreviewCommentsDebugEnabled = () => {
2871
2888
  if (typeof window === "undefined") return false;
2872
2889
  return "__labsSuperDocV2PreviewDebug" in window;
@@ -3306,7 +3323,7 @@ const useCommentsStore = defineStore("comments", () => {
3306
3323
  }
3307
3324
  activeEditor?.commands?.setActiveComment({ commentId: activeComment.value });
3308
3325
  };
3309
- const handleTrackedChangeUpdate = ({ superdoc, params, broadcastChanges = true }) => {
3326
+ const handleTrackedChangeUpdate = ({ superdoc, params, broadcastChanges = true, documentState = void 0 }) => {
3310
3327
  const span = startInteractionSpan("store.trackedChanges.handleUpdate", "store-reconciliation", {
3311
3328
  event: params?.event ?? null,
3312
3329
  changeId: params?.changeId ?? null,
@@ -3321,7 +3338,8 @@ const useCommentsStore = defineStore("comments", () => {
3321
3338
  const normalizedDocumentId = documentId != null ? String(documentId) : null;
3322
3339
  if (!(trackedChangeDisplayType === "tableInsert" || trackedChangeDisplayType === "tableDelete") && normalizedChangeId) {
3323
3340
  const effectiveDocumentId = normalizedDocumentId ?? (superdoc?.activeEditor?.options?.documentId != null ? String(superdoc.activeEditor.options.documentId) : null);
3324
- const docState = (effectiveDocumentId ? superdocStore.getDocument(effectiveDocumentId)?.getEditor?.() : null)?.state ?? superdoc?.activeEditor?.state ?? null;
3341
+ const docEditor = effectiveDocumentId ? superdocStore.getDocument(effectiveDocumentId)?.getEditor?.() : null;
3342
+ const docState = documentState !== void 0 ? documentState : docEditor?.state ?? superdoc?.activeEditor?.state ?? null;
3325
3343
  if (docState) {
3326
3344
  const { ranges: tableRanges, ids: structuralIds } = computeTrackedTableSummaryForState(docState);
3327
3345
  const ranges = trackChangesHelpers.getTrackChanges(docState, normalizedChangeId);
@@ -3455,7 +3473,7 @@ const useCommentsStore = defineStore("comments", () => {
3455
3473
  });
3456
3474
  return;
3457
3475
  }
3458
- addComment({
3476
+ addHydratedComment({
3459
3477
  superdoc,
3460
3478
  comment,
3461
3479
  broadcastChanges
@@ -3477,7 +3495,10 @@ const useCommentsStore = defineStore("comments", () => {
3477
3495
  decision: params.decision ?? null,
3478
3496
  superdoc
3479
3497
  };
3480
- if (existingTrackedChange && !existingTrackedChange.resolvedTime) existingTrackedChange.resolveComment(resolveArgs);
3498
+ if (existingTrackedChange && !existingTrackedChange.resolvedTime) existingTrackedChange.resolveComment({
3499
+ ...resolveArgs,
3500
+ reconciliationToken: COMMENT_RECONCILIATION_TOKEN
3501
+ });
3481
3502
  }
3482
3503
  } finally {
3483
3504
  endInteractionSpan(span);
@@ -3712,8 +3733,9 @@ const useCommentsStore = defineStore("comments", () => {
3712
3733
  if (isV2EditorActive(superdoc)) return;
3713
3734
  superdoc?.activeEditor?.commands?.removeComment({ commentId: "pending" });
3714
3735
  };
3715
- const addComment = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true }) => {
3716
- const v2Adapter = !skipEditorUpdate ? getV2CommentsAdapter(superdoc) : null;
3736
+ const addCommentInternal = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true, isHydration = false }) => {
3737
+ if (commentsAreReadOnly$1() && !isHydration) return readOnlyMutationOutcome$1();
3738
+ const v2Adapter = !skipEditorUpdate && !isHydration ? getV2CommentsAdapter(superdoc) : null;
3717
3739
  if (v2Adapter && !comment.trackedChange) {
3718
3740
  const text = normalizeV2CommentDraftText(pendingComment.value ? currentCommentText.value : comment.commentText);
3719
3741
  const target = pendingComment.value ? pendingV2CommentTarget.value : null;
@@ -3798,7 +3820,21 @@ const useCommentsStore = defineStore("comments", () => {
3798
3820
  comment: newComment
3799
3821
  };
3800
3822
  };
3823
+ const addComment = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true }) => addCommentInternal({
3824
+ superdoc,
3825
+ comment,
3826
+ skipEditorUpdate,
3827
+ broadcastChanges
3828
+ });
3829
+ const addHydratedComment = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true }) => addCommentInternal({
3830
+ superdoc,
3831
+ comment,
3832
+ skipEditorUpdate,
3833
+ broadcastChanges,
3834
+ isHydration: true
3835
+ });
3801
3836
  const deleteComment = ({ commentId: commentIdToDelete, superdoc }) => {
3837
+ if (commentsAreReadOnly$1()) return Promise.resolve(readOnlyMutationOutcome$1());
3802
3838
  const commentIndex = commentsList.value.findIndex((c) => c.commentId === commentIdToDelete);
3803
3839
  const comment = commentsList.value[commentIndex];
3804
3840
  if (!comment) return Promise.resolve({
@@ -3987,6 +4023,7 @@ const useCommentsStore = defineStore("comments", () => {
3987
4023
  };
3988
4024
  };
3989
4025
  const replyCommentV2 = async ({ superdoc, parentCommentId, text } = {}) => {
4026
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
3990
4027
  const v2Adapter = getV2CommentsAdapter(superdoc);
3991
4028
  if (!v2Adapter) return {
3992
4029
  ok: false,
@@ -4021,6 +4058,7 @@ const useCommentsStore = defineStore("comments", () => {
4021
4058
  });
4022
4059
  };
4023
4060
  const editCommentV2 = async ({ superdoc, commentId, text } = {}) => {
4061
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
4024
4062
  const v2Adapter = getV2CommentsAdapter(superdoc);
4025
4063
  if (!v2Adapter) return {
4026
4064
  ok: false,
@@ -4069,6 +4107,7 @@ const useCommentsStore = defineStore("comments", () => {
4069
4107
  });
4070
4108
  };
4071
4109
  const resolveCommentV2 = async ({ superdoc, commentId } = {}) => {
4110
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
4072
4111
  const v2Adapter = getV2CommentsAdapter(superdoc);
4073
4112
  if (!v2Adapter) return {
4074
4113
  ok: false,
@@ -4115,6 +4154,7 @@ const useCommentsStore = defineStore("comments", () => {
4115
4154
  return result;
4116
4155
  };
4117
4156
  const reopenCommentV2 = async ({ superdoc, commentId } = {}) => {
4157
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
4118
4158
  const v2Adapter = getV2CommentsAdapter(superdoc);
4119
4159
  if (!v2Adapter) return {
4120
4160
  ok: false,
@@ -4337,21 +4377,139 @@ const useCommentsStore = defineStore("comments", () => {
4337
4377
  if (typeof creatorName !== "string") return null;
4338
4378
  return creatorName.replace(/\s*\(imported\)\s*$/u, "").trim() || null;
4339
4379
  };
4340
- const bootstrapImportedTrackedChangeComments = (editor, superdoc) => {
4341
- if (!editor || !superdoc) return;
4342
- createCommentForTrackChanges(editor, superdoc);
4380
+ const readMountedEditorSnapshot = (editor) => {
4381
+ if (!editor) return null;
4382
+ try {
4383
+ if (editor.isDestroyed === true) return null;
4384
+ const view = editor.view;
4385
+ if (!view || view.isDestroyed === true || view.destroyed === true) return null;
4386
+ const state = view.state;
4387
+ if (!state) return null;
4388
+ return {
4389
+ view,
4390
+ state
4391
+ };
4392
+ } catch {
4393
+ return null;
4394
+ }
4395
+ };
4396
+ const normalizeBootstrapDocumentId = (documentId) => documentId !== void 0 && documentId !== null && String(documentId).length > 0 ? String(documentId) : null;
4397
+ const cancelImportedTrackedChangeBootstrap = (documentId) => {
4398
+ const normalizedDocumentId = normalizeBootstrapDocumentId(documentId);
4399
+ const entries = normalizedDocumentId ? [[normalizedDocumentId, importedTrackedChangeBootstrapTasks.get(normalizedDocumentId)]] : Array.from(importedTrackedChangeBootstrapTasks.entries());
4400
+ let canceled = 0;
4401
+ for (const [taskDocumentId, task] of entries) {
4402
+ if (!task) continue;
4403
+ importedTrackedChangeBootstrapTasks.delete(taskDocumentId);
4404
+ if (task.timeoutHandle !== null && task.timeoutHandle !== void 0) clearTimeout(task.timeoutHandle);
4405
+ canceled += 1;
4406
+ }
4407
+ return canceled;
4408
+ };
4409
+ const captureImportedTrackedChangeBootstrapSnapshot = (editor) => {
4410
+ const mountedEditor = readMountedEditorSnapshot(editor);
4411
+ if (!mountedEditor) return null;
4412
+ let trackedChanges = [];
4413
+ try {
4414
+ trackedChanges = trackChangesHelpers.getTrackChanges(mountedEditor.state) ?? [];
4415
+ } catch {
4416
+ return null;
4417
+ }
4418
+ const enumerateStructuralChanges = trackChangesHelpers?.enumerateStructuralRowChanges;
4419
+ let structuralChanges = [];
4420
+ if (typeof enumerateStructuralChanges === "function") try {
4421
+ structuralChanges = enumerateStructuralChanges(mountedEditor.state) ?? [];
4422
+ } catch {
4423
+ structuralChanges = [];
4424
+ }
4425
+ let storySnapshots = [];
4426
+ if (typeof getTrackedChangeIndex === "function") try {
4427
+ storySnapshots = getTrackedChangeIndex(editor)?.getAll?.() ?? [];
4428
+ } catch {
4429
+ storySnapshots = [];
4430
+ }
4431
+ return {
4432
+ ...mountedEditor,
4433
+ trackedChanges,
4434
+ structuralChanges,
4435
+ storySnapshots
4436
+ };
4437
+ };
4438
+ const bootstrapImportedTrackedChangeComments = (editor, superdoc, snapshot = null) => {
4439
+ if (!editor || !superdoc) return false;
4440
+ const captured = snapshot ?? captureImportedTrackedChangeBootstrapSnapshot(editor);
4441
+ if (!captured) return false;
4442
+ createCommentForTrackChanges(editor, superdoc, captured.trackedChanges, {
4443
+ editorState: captured.state,
4444
+ editorView: captured.view
4445
+ });
4343
4446
  syncStoryTrackedChangeComments({
4344
4447
  superdoc,
4345
- editor
4448
+ editor,
4449
+ snapshots: captured.storySnapshots,
4450
+ documentState: captured.state,
4451
+ resolveFromEditor: false
4346
4452
  });
4347
4453
  syncStructuralTrackedChangeComments({
4348
4454
  superdoc,
4349
- editor
4455
+ editor,
4456
+ structuralChanges: captured.structuralChanges
4350
4457
  });
4458
+ return true;
4459
+ };
4460
+ const isCurrentImportedTrackedChangeBootstrap = (task) => {
4461
+ if (!task) return false;
4462
+ if (importedTrackedChangeBootstrapTasks.get(task.documentId) !== task) return false;
4463
+ try {
4464
+ const editorDocumentId = task.editor?.options?.documentId;
4465
+ if (editorDocumentId != null && String(editorDocumentId) !== task.documentId) return false;
4466
+ const mountedDocument = superdocStore.getDocument(task.documentId);
4467
+ if (!mountedDocument) return false;
4468
+ if (mountedDocument.getEditor?.() !== task.editor) return false;
4469
+ } catch {
4470
+ return false;
4471
+ }
4472
+ return true;
4473
+ };
4474
+ const runImportedTrackedChangeBootstrap = (task) => {
4475
+ if (!isCurrentImportedTrackedChangeBootstrap(task)) {
4476
+ if (importedTrackedChangeBootstrapTasks.get(task?.documentId) === task) importedTrackedChangeBootstrapTasks.delete(task.documentId);
4477
+ return false;
4478
+ }
4479
+ const snapshot = captureImportedTrackedChangeBootstrapSnapshot(task.editor);
4480
+ if (!snapshot || !isCurrentImportedTrackedChangeBootstrap(task)) {
4481
+ if (importedTrackedChangeBootstrapTasks.get(task.documentId) === task) importedTrackedChangeBootstrapTasks.delete(task.documentId);
4482
+ return false;
4483
+ }
4484
+ try {
4485
+ return bootstrapImportedTrackedChangeComments(task.editor, task.superdoc, snapshot);
4486
+ } finally {
4487
+ if (importedTrackedChangeBootstrapTasks.get(task.documentId) === task) importedTrackedChangeBootstrapTasks.delete(task.documentId);
4488
+ }
4489
+ };
4490
+ const scheduleImportedTrackedChangeBootstrap = ({ editor, superdoc, documentId, defer = true }) => {
4491
+ const normalizedDocumentId = normalizeBootstrapDocumentId(documentId);
4492
+ if (!normalizedDocumentId || !editor || !superdoc) return false;
4493
+ cancelImportedTrackedChangeBootstrap(normalizedDocumentId);
4494
+ const task = {
4495
+ documentId: normalizedDocumentId,
4496
+ editor,
4497
+ superdoc,
4498
+ generation: ++importedTrackedChangeBootstrapGeneration,
4499
+ timeoutHandle: null
4500
+ };
4501
+ importedTrackedChangeBootstrapTasks.set(normalizedDocumentId, task);
4502
+ if (!defer) return runImportedTrackedChangeBootstrap(task);
4503
+ task.timeoutHandle = setTimeout(() => {
4504
+ task.timeoutHandle = null;
4505
+ runImportedTrackedChangeBootstrap(task);
4506
+ }, 0);
4507
+ return true;
4351
4508
  };
4352
4509
  function removeCommentsForDocument(documentId) {
4353
4510
  const activeDocumentId = documentId != null ? String(documentId) : null;
4354
4511
  if (!activeDocumentId) return;
4512
+ cancelImportedTrackedChangeBootstrap(activeDocumentId);
4355
4513
  const removedComments = commentsList.value.filter((comment) => belongsToDocument(comment, activeDocumentId, { allowSingleDocumentMismatch: true }));
4356
4514
  if (!removedComments.length) return;
4357
4515
  const removedAliasIds = /* @__PURE__ */ new Set();
@@ -4382,7 +4540,7 @@ const useCommentsStore = defineStore("comments", () => {
4382
4540
  if (!htmlContent && !comment.trackedChange) return;
4383
4541
  const creatorName = normalizeImportedCreatorName(comment.creatorName);
4384
4542
  const importedName = creatorName ? `${creatorName} (imported)` : null;
4385
- addComment({
4543
+ addHydratedComment({
4386
4544
  superdoc,
4387
4545
  comment: useComment({
4388
4546
  fileId: documentId,
@@ -4419,16 +4577,29 @@ const useCommentsStore = defineStore("comments", () => {
4419
4577
  });
4420
4578
  });
4421
4579
  if (replacedFile) {
4422
- bootstrapImportedTrackedChangeComments(editor, superdoc);
4580
+ scheduleImportedTrackedChangeBootstrap({
4581
+ editor,
4582
+ superdoc,
4583
+ documentId,
4584
+ defer: false
4585
+ });
4423
4586
  return;
4424
4587
  }
4425
- setTimeout(() => {
4426
- bootstrapImportedTrackedChangeComments(editor, superdoc);
4427
- }, 0);
4588
+ scheduleImportedTrackedChangeBootstrap({
4589
+ editor,
4590
+ superdoc,
4591
+ documentId
4592
+ });
4428
4593
  };
4429
4594
  const createCommentForTrackChanges = (editor, superdoc, trackedChangesOverride = null, options = {}) => {
4430
- const { reopenResolved = false, refreshExisting = false, broadcastChanges = true } = options;
4431
- const trackedChanges = trackedChangesOverride ?? trackChangesHelpers.getTrackChanges(editor.state);
4595
+ const { reopenResolved = false, refreshExisting = false, broadcastChanges = true, editorState: editorStateOverride = null, editorView: editorViewOverride = null } = options;
4596
+ const mountedEditor = editorStateOverride ? {
4597
+ state: editorStateOverride,
4598
+ view: editorViewOverride
4599
+ } : readMountedEditorSnapshot(editor);
4600
+ if (!mountedEditor?.state) return;
4601
+ const editorState = mountedEditor.state;
4602
+ const trackedChanges = trackedChangesOverride ?? trackChangesHelpers.getTrackChanges(editorState);
4432
4603
  const groupedChanges = groupChanges(trackedChanges);
4433
4604
  const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
4434
4605
  if (!activeDocumentId) return;
@@ -4473,7 +4644,7 @@ const useCommentsStore = defineStore("comments", () => {
4473
4644
  event: existingTrackedChange ? "update" : "add",
4474
4645
  marks,
4475
4646
  nodes: [],
4476
- newEditorState: editor.state,
4647
+ newEditorState: editorState,
4477
4648
  documentId,
4478
4649
  trackedChangesForId: changesByIdMap.get(id) || []
4479
4650
  });
@@ -4486,7 +4657,8 @@ const useCommentsStore = defineStore("comments", () => {
4486
4657
  handleTrackedChangeUpdate({
4487
4658
  superdoc,
4488
4659
  params,
4489
- broadcastChanges
4660
+ broadcastChanges,
4661
+ documentState: editorState
4490
4662
  });
4491
4663
  if (!existingTrackedChange) {
4492
4664
  skipIds.add(normalizedId);
@@ -4495,9 +4667,15 @@ const useCommentsStore = defineStore("comments", () => {
4495
4667
  }
4496
4668
  }
4497
4669
  });
4498
- const { tr } = editor.view.state;
4670
+ const editorView = mountedEditor.view;
4671
+ try {
4672
+ if (!editorView || editor.view !== editorView || editorView.isDestroyed === true || editorView.destroyed === true) return;
4673
+ } catch {
4674
+ return;
4675
+ }
4676
+ const { tr } = editorState;
4499
4677
  tr.setMeta(CommentsPluginKey, { type: "force" });
4500
- editor.view.dispatch(tr);
4678
+ editorView.dispatch(tr);
4501
4679
  };
4502
4680
  const pruneSuppressedInlineTableComments = ({ suppressedIds, activeDocumentId, superdoc = null, broadcastChanges = true }) => {
4503
4681
  if (!(suppressedIds instanceof Set) || !suppressedIds.size || !activeDocumentId) return;
@@ -4870,6 +5048,10 @@ const useCommentsStore = defineStore("comments", () => {
4870
5048
  return reconcilePromise;
4871
5049
  };
4872
5050
  const decideTrackedChangeFromSidebar = ({ superdoc, comment, decision }) => {
5051
+ if (commentsAreReadOnly$1()) return {
5052
+ ok: false,
5053
+ reason: "read-only-document"
5054
+ };
4873
5055
  if (!comment?.trackedChange) return { ok: false };
4874
5056
  const v2Adapter = getV2TrackedChangesAdapter(superdoc);
4875
5057
  if (v2Adapter) {
@@ -5214,46 +5396,52 @@ const useCommentsStore = defineStore("comments", () => {
5214
5396
  if (!superdoc || !editor) return;
5215
5397
  const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
5216
5398
  if (!activeDocumentId) return;
5217
- const trackedChanges = trackChangesHelpers.getTrackChanges(editor.state);
5399
+ const captured = captureImportedTrackedChangeBootstrapSnapshot(editor);
5400
+ if (!captured) return;
5401
+ const trackedChanges = captured.trackedChanges;
5218
5402
  const liveTrackedChangeIds = /* @__PURE__ */ new Set();
5219
5403
  trackedChanges.forEach((change) => {
5220
5404
  const id = change?.mark?.attrs?.id;
5221
5405
  if (id == null) return;
5222
5406
  liveTrackedChangeIds.add(String(id));
5223
5407
  });
5224
- const trackedChangeIndex = typeof getTrackedChangeIndex === "function" ? getTrackedChangeIndex(editor) : null;
5225
- let storySnapshots = [];
5226
- try {
5227
- storySnapshots = trackedChangeIndex?.getAll?.() ?? [];
5228
- } catch {}
5408
+ const storySnapshots = captured.storySnapshots;
5229
5409
  pruneStaleTrackedChangeComments(liveTrackedChangeIds, new Set(storySnapshots.map((snapshot) => snapshot?.anchorKey).filter((anchorKey) => typeof anchorKey === "string" && anchorKey.length > 0)), activeDocumentId, superdoc, { broadcastChanges });
5230
5410
  createCommentForTrackChanges(editor, superdoc, trackedChanges, {
5231
5411
  reopenResolved: true,
5232
5412
  refreshExisting: true,
5233
- broadcastChanges
5413
+ broadcastChanges,
5414
+ editorState: captured.state,
5415
+ editorView: captured.view
5234
5416
  });
5235
5417
  syncStoryTrackedChangeComments({
5236
5418
  superdoc,
5237
5419
  editor,
5238
5420
  broadcastChanges,
5239
- snapshots: storySnapshots
5421
+ snapshots: storySnapshots,
5422
+ documentState: captured.state
5240
5423
  });
5241
5424
  syncStructuralTrackedChangeComments({
5242
5425
  superdoc,
5243
5426
  editor,
5244
- broadcastChanges
5427
+ broadcastChanges,
5428
+ structuralChanges: captured.structuralChanges
5245
5429
  });
5246
5430
  };
5247
- const syncStructuralTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true }) => {
5431
+ const syncStructuralTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true, structuralChanges: structuralChangesOverride = null }) => {
5248
5432
  const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
5249
5433
  if (!activeDocumentId) return;
5250
5434
  const enumerate = trackChangesHelpers?.enumerateStructuralRowChanges;
5251
5435
  if (typeof enumerate !== "function") return;
5252
- let structuralChanges = [];
5253
- try {
5254
- structuralChanges = enumerate(editor.state) ?? [];
5255
- } catch {
5256
- structuralChanges = [];
5436
+ let structuralChanges = structuralChangesOverride;
5437
+ if (!Array.isArray(structuralChanges)) {
5438
+ const mountedEditor = readMountedEditorSnapshot(editor);
5439
+ if (!mountedEditor) return;
5440
+ try {
5441
+ structuralChanges = enumerate(mountedEditor.state) ?? [];
5442
+ } catch {
5443
+ structuralChanges = [];
5444
+ }
5257
5445
  }
5258
5446
  for (const structural of structuralChanges) {
5259
5447
  if (!structural?.decidable || !structural?.wholeTable) continue;
@@ -5300,13 +5488,19 @@ const useCommentsStore = defineStore("comments", () => {
5300
5488
  });
5301
5489
  }
5302
5490
  };
5303
- const syncStoryTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true, snapshots = null }) => {
5491
+ const syncStoryTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true, snapshots = null, documentState = void 0, resolveFromEditor = true }) => {
5304
5492
  const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
5305
5493
  if (!activeDocumentId) return;
5306
5494
  let resolvedSnapshots = snapshots;
5307
5495
  if (!Array.isArray(resolvedSnapshots)) {
5308
5496
  if (typeof getTrackedChangeIndex !== "function") return;
5309
- const index = getTrackedChangeIndex(editor);
5497
+ if (!readMountedEditorSnapshot(editor)) return;
5498
+ let index = null;
5499
+ try {
5500
+ index = getTrackedChangeIndex(editor);
5501
+ } catch {
5502
+ return;
5503
+ }
5310
5504
  if (!index) return;
5311
5505
  try {
5312
5506
  resolvedSnapshots = index.getAll();
@@ -5321,7 +5515,9 @@ const useCommentsStore = defineStore("comments", () => {
5321
5515
  editor,
5322
5516
  snapshot,
5323
5517
  documentId: activeDocumentId,
5324
- broadcastChanges
5518
+ broadcastChanges,
5519
+ documentState,
5520
+ resolveFromEditor
5325
5521
  });
5326
5522
  }
5327
5523
  };
@@ -5338,7 +5534,7 @@ const useCommentsStore = defineStore("comments", () => {
5338
5534
  if (snapshot.type === "delete") return true;
5339
5535
  return snapshot.type === "structural" && snapshot.subtype === "table-delete";
5340
5536
  };
5341
- const buildStoryTrackedChangeParams = ({ editor, snapshot, documentId, event }) => {
5537
+ const buildStoryTrackedChangeParams = ({ editor, snapshot, documentId, event, resolveFromEditor = true }) => {
5342
5538
  const trackedChangeType = getStoryTrackedChangeType(snapshot);
5343
5539
  const trackedChangeDisplayType = getStoryTrackedChangeDisplayType(snapshot);
5344
5540
  const fallbackParams = {
@@ -5362,7 +5558,7 @@ const useCommentsStore = defineStore("comments", () => {
5362
5558
  trackedChangeStoryLabel: snapshot.storyLabel,
5363
5559
  trackedChangeAnchorKey: snapshot.anchorKey
5364
5560
  };
5365
- if (typeof resolveTrackedChangeInStory !== "function") return fallbackParams;
5561
+ if (!resolveFromEditor || typeof resolveTrackedChangeInStory !== "function") return fallbackParams;
5366
5562
  let resolvedChange = null;
5367
5563
  try {
5368
5564
  resolvedChange = resolveTrackedChangeInStory(editor, {
@@ -5399,7 +5595,7 @@ const useCommentsStore = defineStore("comments", () => {
5399
5595
  resolvedParams.trackedChangeAnchorKey = snapshot.anchorKey;
5400
5596
  return resolvedParams;
5401
5597
  };
5402
- const upsertStoryTrackedChangeComment = ({ superdoc, editor, snapshot, documentId, broadcastChanges }) => {
5598
+ const upsertStoryTrackedChangeComment = ({ superdoc, editor, snapshot, documentId, broadcastChanges, documentState, resolveFromEditor }) => {
5403
5599
  if (!snapshot?.runtimeRef?.rawId) return;
5404
5600
  const existingComment = commentsList.value.find((comment) => {
5405
5601
  if (!comment?.trackedChange) return false;
@@ -5414,9 +5610,11 @@ const useCommentsStore = defineStore("comments", () => {
5414
5610
  editor,
5415
5611
  snapshot,
5416
5612
  documentId,
5417
- event: existingComment ? "update" : "add"
5613
+ event: existingComment ? "update" : "add",
5614
+ resolveFromEditor
5418
5615
  }),
5419
- broadcastChanges
5616
+ broadcastChanges,
5617
+ documentState
5420
5618
  });
5421
5619
  if (existingComment) {
5422
5620
  existingComment.trackedChangeStory = snapshot.story;
@@ -5732,9 +5930,11 @@ const useCommentsStore = defineStore("comments", () => {
5732
5930
  getPendingComment,
5733
5931
  showAddComment,
5734
5932
  addComment,
5933
+ addHydratedComment,
5735
5934
  cancelComment,
5736
5935
  deleteComment,
5737
5936
  removePendingComment,
5937
+ cancelImportedTrackedChangeBootstrap,
5738
5938
  removeCommentsForDocument,
5739
5939
  processLoadedDocxComments,
5740
5940
  translateCommentsForExport,
@@ -6361,7 +6561,9 @@ var CommentHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6361
6561
  key: "delete"
6362
6562
  }
6363
6563
  });
6564
+ const reviewMutationsVisible = computed(() => props.config.readOnly !== true);
6364
6565
  const generallyAllowed = computed(() => {
6566
+ if (!reviewMutationsVisible.value) return false;
6365
6567
  if (!props.comment) return false;
6366
6568
  if (props.comment.resolvedTime) return false;
6367
6569
  if (commentsStore.pendingComment) return false;
@@ -6370,6 +6572,7 @@ var CommentHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6370
6572
  });
6371
6573
  const allowResolve = computed(() => {
6372
6574
  if (!generallyAllowed.value) return false;
6575
+ if (!props.comment.trackedChange && props.config.allowResolve === false) return false;
6373
6576
  if (props.comment.parentCommentId) return false;
6374
6577
  if (props.comment.trackedChangeParentId) return false;
6375
6578
  const context = {
@@ -6392,6 +6595,8 @@ var CommentHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6392
6595
  else return isAllowed(PERMISSIONS.REJECT_OTHER, role, isInternal, context);
6393
6596
  });
6394
6597
  const allowReopen = computed(() => {
6598
+ if (!reviewMutationsVisible.value) return false;
6599
+ if (props.config.allowResolve === false) return false;
6395
6600
  if (!props.reopenSupported) return false;
6396
6601
  if (!props.comment) return false;
6397
6602
  if (!props.comment.resolvedTime) return false;
@@ -6416,11 +6621,12 @@ var CommentHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6416
6621
  return true;
6417
6622
  });
6418
6623
  const getOverflowOptions = computed(() => {
6419
- if (!generallyAllowed.value) return false;
6624
+ if (!reviewMutationsVisible.value) return [];
6625
+ if (!generallyAllowed.value) return [];
6420
6626
  if (props.writeDisabledReason) return [];
6421
6627
  const allowedOptions = [];
6422
6628
  const options = /* @__PURE__ */ new Set();
6423
- if (!props.config.readOnly && isCommentOwnedByCurrentUser(props.comment)) options.add("edit");
6629
+ if (isCommentOwnedByCurrentUser(props.comment)) options.add("edit");
6424
6630
  const isOwnComment$1 = isCommentOwnedByCurrentUser(props.comment);
6425
6631
  const context = {
6426
6632
  comment: props.comment,
@@ -6433,18 +6639,25 @@ var CommentHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6433
6639
  return allowedOptions;
6434
6640
  });
6435
6641
  const handleResolve = () => {
6642
+ if (!reviewMutationsVisible.value) return;
6643
+ if (!props.comment?.trackedChange && props.config.allowResolve === false) return;
6436
6644
  if (props.resolveDisabledReason) return;
6437
6645
  emit("resolve");
6438
6646
  };
6439
6647
  const handleReject = () => {
6648
+ if (!reviewMutationsVisible.value) return;
6440
6649
  if (props.rejectDisabledReason) return;
6441
6650
  emit("reject");
6442
6651
  };
6443
6652
  const handleReopen = () => {
6653
+ if (!reviewMutationsVisible.value || props.config.allowResolve === false) return;
6444
6654
  if (props.reopenDisabledReason) return;
6445
6655
  emit("reopen");
6446
6656
  };
6447
- const handleSelect = (value) => emit("overflow-select", value);
6657
+ const handleSelect = (value) => {
6658
+ if (!reviewMutationsVisible.value) return;
6659
+ emit("overflow-select", value);
6660
+ };
6448
6661
  const isImported = computed(() => {
6449
6662
  if (!(props.comment.origin != null || !!props.comment.importedAuthor?.name)) return false;
6450
6663
  if (isCommentOwnedByCurrentUser(props.comment)) return false;
@@ -6470,6 +6683,7 @@ var CommentHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6470
6683
  allowResolve.value ? (openBlock(), createElementBlock("div", {
6471
6684
  key: 0,
6472
6685
  class: normalizeClass(["overflow-menu__icon", { "sd-is-disabled": Boolean(__props.resolveDisabledReason) }]),
6686
+ "data-comment-action": "resolve",
6473
6687
  "data-disabled-reason": __props.resolveDisabledReason || null,
6474
6688
  "aria-disabled": Boolean(__props.resolveDisabledReason),
6475
6689
  innerHTML: unref(superdocIcons).markDone,
@@ -6478,6 +6692,7 @@ var CommentHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6478
6692
  allowReject.value ? (openBlock(), createElementBlock("div", {
6479
6693
  key: 1,
6480
6694
  class: normalizeClass(["overflow-menu__icon", { "sd-is-disabled": Boolean(__props.rejectDisabledReason) }]),
6695
+ "data-comment-action": "reject",
6481
6696
  "data-disabled-reason": __props.rejectDisabledReason || null,
6482
6697
  "aria-disabled": Boolean(__props.rejectDisabledReason),
6483
6698
  innerHTML: unref(superdocIcons).rejectChange,
@@ -6495,6 +6710,7 @@ var CommentHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6495
6710
  }, null, 10, _hoisted_9$3)) : createCommentVNode("", true),
6496
6711
  allowOverflow.value ? (openBlock(), createBlock(CommentsDropdown_default, {
6497
6712
  key: 3,
6713
+ "data-comment-action": "overflow",
6498
6714
  options: getOverflowOptions.value,
6499
6715
  onSelect: handleSelect,
6500
6716
  "content-style": { fontFamily: unref(uiFontFamily) }
@@ -6508,7 +6724,7 @@ var CommentHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6508
6724
  ], 2)]);
6509
6725
  };
6510
6726
  }
6511
- }, [["__scopeId", "data-v-49c3f013"]]);
6727
+ }, [["__scopeId", "data-v-359c13bb"]]);
6512
6728
  var _hoisted_1$26 = { class: "input-section" };
6513
6729
  var TEXTAREA_MIN_HEIGHT = 28;
6514
6730
  var TEXTAREA_MAX_HEIGHT = 132;
@@ -6930,8 +7146,14 @@ var CommentDialog_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6930
7146
  const showInputSection = computed(() => {
6931
7147
  return !getConfig.readOnly && isDialogActive.value && !props.comment.resolvedTime && !isEditingAnyComment.value;
6932
7148
  });
7149
+ const readOnlyMutationOutcome$1 = () => ({
7150
+ ok: false,
7151
+ reason: "read-only-document"
7152
+ });
7153
+ const commentsAreReadOnly$1 = () => getConfig.value?.readOnly === true;
6933
7154
  const isReplying = ref(false);
6934
7155
  const startReply = () => {
7156
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
6935
7157
  isReplying.value = true;
6936
7158
  nextTick(() => {
6937
7159
  commentInput.value?.focus?.();
@@ -7033,6 +7255,7 @@ var CommentDialog_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
7033
7255
  return comments.value.some((c) => c.commentId === editingCommentId.value);
7034
7256
  });
7035
7257
  const shouldShowInternalExternal = computed(() => {
7258
+ if (getConfig.value.readOnly) return false;
7036
7259
  if (!proxy.$superdoc.config.isInternal) return false;
7037
7260
  if (isV2Mode.value) return false;
7038
7261
  return !suppressInternalExternal.value && !props.comment.trackedChange;
@@ -7121,6 +7344,7 @@ var CommentDialog_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
7121
7344
  isCommentHighlighted.value = false;
7122
7345
  };
7123
7346
  const handleAddComment = async () => {
7347
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7124
7348
  if (isV2Mode.value && v2CommentsAdapter.value && !isPendingNewComment.value) {
7125
7349
  const outcome = await commentsStore.replyCommentV2({
7126
7350
  superdoc: proxy.$superdoc,
@@ -7211,6 +7435,7 @@ var CommentDialog_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
7211
7435
  return v2WriteCapability.value?.reason ?? "v2-write-unavailable";
7212
7436
  });
7213
7437
  const handleReject = async () => {
7438
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7214
7439
  const customHandler = proxy.$superdoc.config.onTrackedChangeBubbleReject;
7215
7440
  if (props.comment.trackedChange) {
7216
7441
  if (isV2Mode.value) {
@@ -7263,6 +7488,11 @@ var CommentDialog_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
7263
7488
  });
7264
7489
  };
7265
7490
  const handleResolve = async () => {
7491
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7492
+ if (!props.comment.trackedChange && getConfig.value?.allowResolve === false) return {
7493
+ ok: false,
7494
+ reason: "resolve-disabled"
7495
+ };
7266
7496
  const customHandler = proxy.$superdoc.config.onTrackedChangeBubbleAccept;
7267
7497
  if (props.comment.trackedChange && isV2Mode.value) {
7268
7498
  const outcome = await commentsStore.decideTrackedChangeFromSidebar({
@@ -7315,6 +7545,11 @@ var CommentDialog_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
7315
7545
  });
7316
7546
  };
7317
7547
  const handleReopen = async () => {
7548
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7549
+ if (getConfig.value?.allowResolve === false) return {
7550
+ ok: false,
7551
+ reason: "resolve-disabled"
7552
+ };
7318
7553
  if (!isV2Mode.value || !v2CommentsAdapter.value) return;
7319
7554
  if (!(await commentsStore.reopenCommentV2({
7320
7555
  superdoc: proxy.$superdoc,
@@ -7327,6 +7562,7 @@ var CommentDialog_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
7327
7562
  });
7328
7563
  };
7329
7564
  const handleOverflowSelect = (value, comment) => {
7565
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7330
7566
  switch (value) {
7331
7567
  case "edit":
7332
7568
  currentCommentText.value = comment?.commentText?.value ?? comment?.commentText ?? "";
@@ -7347,6 +7583,7 @@ var CommentDialog_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
7347
7583
  }
7348
7584
  };
7349
7585
  const handleCommentUpdate = async (comment) => {
7586
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7350
7587
  if (isV2Mode.value && v2CommentsAdapter.value) {
7351
7588
  const outcome = await commentsStore.editCommentV2({
7352
7589
  superdoc: proxy.$superdoc,
@@ -7366,6 +7603,7 @@ var CommentDialog_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
7366
7603
  removePendingComment(proxy.$superdoc);
7367
7604
  };
7368
7605
  const handleInternalExternalSelect = (value) => {
7606
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7369
7607
  const isPendingComment = !!pendingComment.value;
7370
7608
  const isInternal$1 = value.toLowerCase() === "internal";
7371
7609
  if (!isPendingComment) props.comment.setIsInternal({
@@ -7419,6 +7657,13 @@ var CommentDialog_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
7419
7657
  focusEditInput(commentId);
7420
7658
  });
7421
7659
  });
7660
+ watch(() => getConfig.value?.readOnly === true, (readOnly) => {
7661
+ if (!readOnly) return;
7662
+ isReplying.value = false;
7663
+ if (comments.value.some((comment) => comment.commentId === editingCommentId.value)) editingCommentId.value = null;
7664
+ if (isPendingNewComment.value) cancelComment(proxy.$superdoc);
7665
+ nextTick(() => emit("resize"));
7666
+ }, { immediate: true });
7422
7667
  return (_ctx, _cache) => {
7423
7668
  const _directive_click_outside = resolveDirective("click-outside");
7424
7669
  return withDirectives((openBlock(), createElementBlock("div", {
@@ -7634,7 +7879,7 @@ var CommentDialog_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
7634
7879
  ], 64))], 14, _hoisted_1$25)), [[_directive_click_outside, handleClickOutside]]);
7635
7880
  };
7636
7881
  }
7637
- }, [["__scopeId", "data-v-a2a29e0c"]]);
7882
+ }, [["__scopeId", "data-v-67a03ee2"]]);
7638
7883
  var _hoisted_1$24 = { class: "comments-list" };
7639
7884
  var _hoisted_2$19 = { key: 0 };
7640
7885
  var _hoisted_3$15 = [
@@ -13109,7 +13354,7 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
13109
13354
  }
13110
13355
  });
13111
13356
  const { getConfig, documentsWithConverations, commentsList, pendingComment, activeComment, skipSelectionUpdate, commentsByDocument, isCommentsListVisible, isFloatingCommentsReady, generalCommentIds, hasSyncedCollaborationComments, editorCommentPositions, hasInitializedLocations, isCommentHighlighted } = storeToRefs(commentsStore);
13112
- const { showAddComment, handleEditorLocationsUpdate, handleTrackedChangeUpdate, refreshTrackedChangeCommentsByIds, syncTrackedChangePositionsWithDocument, syncTrackedChangeComments, addComment, getComment, resolveCommentPositionEntry, belongsToDocument, COMMENT_EVENTS, requestInstantSidebarAlignment, peekInstantSidebarAlignment, clearInstantSidebarAlignment } = commentsStore;
13357
+ const { showAddComment, handleEditorLocationsUpdate, handleTrackedChangeUpdate, refreshTrackedChangeCommentsByIds, syncTrackedChangePositionsWithDocument, syncTrackedChangeComments, addComment, addHydratedComment, getComment, resolveCommentPositionEntry, belongsToDocument, COMMENT_EVENTS, requestInstantSidebarAlignment, peekInstantSidebarAlignment, clearInstantSidebarAlignment } = commentsStore;
13113
13358
  const { proxy } = getCurrentInstance();
13114
13359
  commentsStore.proxy = proxy;
13115
13360
  const resolvedEditorIntegration = resolveV2Integration(proxy.$superdoc.config);
@@ -13292,7 +13537,7 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
13292
13537
  const openLinkWorkflow = resolveV2LinkWorkflowOpener();
13293
13538
  const unbind = bindEditShortcuts({
13294
13539
  commandRoute: {
13295
- execute: (commandId, payload) => ui.commands.execute(commandId, payload),
13540
+ executeAsync: (commandId, payload) => ui.commands.executeAsync(commandId, payload),
13296
13541
  getState: (commandId) => ui.commands.get(commandId).getState()
13297
13542
  },
13298
13543
  ...openLinkWorkflow ? { openLinkWorkflow } : {}
@@ -14107,6 +14352,7 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
14107
14352
  resetSelection();
14108
14353
  v2PageMetricsSnapshot.value = null;
14109
14354
  const clearedDocumentId = payload?.documentId == null ? null : String(payload.documentId);
14355
+ commentsStore.cancelImportedTrackedChangeBootstrap?.(clearedDocumentId ?? void 0);
14110
14356
  if (clearedDocumentId) v2MountStagesByDocumentId.delete(clearedDocumentId);
14111
14357
  if (latestV2MountStage && (clearedDocumentId == null || latestV2MountStage.dataset?.superdocV2DocumentId === clearedDocumentId)) latestV2MountStage = null;
14112
14358
  v2ReviewHydrationController.reset("render-cleared");
@@ -14557,7 +14803,7 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
14557
14803
  const { id, existingComment } = resolveDocumentScopedCommentMatch(commentPayload);
14558
14804
  if (id && !existingComment) {
14559
14805
  const commentModel = useComment(commentPayload);
14560
- addComment({
14806
+ addHydratedComment({
14561
14807
  superdoc: proxy.$superdoc,
14562
14808
  comment: commentModel,
14563
14809
  skipEditorUpdate: true
@@ -14571,7 +14817,7 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
14571
14817
  if (existingComment) applyReplayUpdateToComment(existingComment, commentPayload, resolvedText);
14572
14818
  else {
14573
14819
  const commentModel = useComment(normalizeReplayCommentModelPayload(commentPayload));
14574
- addComment({
14820
+ addHydratedComment({
14575
14821
  superdoc: proxy.$superdoc,
14576
14822
  comment: commentModel,
14577
14823
  skipEditorUpdate: true
@@ -14845,6 +15091,7 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
14845
15091
  handleFormattingMarksShortcut(e);
14846
15092
  }
14847
15093
  onBeforeUnmount(() => {
15094
+ commentsStore.cancelImportedTrackedChangeBootstrap?.();
14848
15095
  passwordPrompt.destroy();
14849
15096
  findReplace.destroy();
14850
15097
  linkPopover.destroy();
@@ -15368,7 +15615,7 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
15368
15615
  ], 38);
15369
15616
  };
15370
15617
  }
15371
- }, [["__scopeId", "data-v-9bcd0709"]]);
15618
+ }, [["__scopeId", "data-v-8d8777e2"]]);
15372
15619
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
15373
15620
  var PINIA_DEVTOOLS_PLUGIN_ID = "dev.esm.pinia";
15374
15621
  var piniaDevtoolsSuppressionState = {
@@ -33914,7 +34161,7 @@ var SuperDoc = class extends import_eventemitter3.default {
33914
34161
  this.config.colors = shuffleArray(this.config.colors);
33915
34162
  this.userColorMap = /* @__PURE__ */ new Map();
33916
34163
  this.colorIndex = 0;
33917
- this.version = "2.0.0-next.24";
34164
+ this.version = "2.0.0-next.25";
33918
34165
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
33919
34166
  this.superdocId = config.superdocId || v4_default();
33920
34167
  this.colors = this.config.colors ?? [];