superdoc 2.0.0-next.24 → 2.0.0-next.26

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
@@ -6,7 +6,7 @@ const require_uuid = require("./chunks/uuid-CFp0WGVU.cjs");
6
6
  const require_jszip = require("./chunks/jszip-BdUBlUeG.cjs");
7
7
  const require__plugin_vue_export_helper = require("./chunks/_plugin-vue_export-helper-BTwbGDKw.cjs");
8
8
  const require_constants = require("./chunks/constants-sbCZ2O_A.cjs");
9
- const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-DbFtp705.cjs");
9
+ const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-CHZKlLiH.cjs");
10
10
  let vue = require("vue");
11
11
  vue = require_rolldown_runtime.__toESM(vue);
12
12
  require("y-websocket");
@@ -1736,7 +1736,13 @@ function useSelection(params) {
1736
1736
  };
1737
1737
  }
1738
1738
  const DOCUMENT_EDITOR_SELECTION_SOURCE = "document-editor";
1739
+ const COMMENT_RECONCILIATION_TOKEN = Symbol("comment-reconciliation");
1739
1740
  var getCommentIds = (comment) => [comment?.commentId, comment?.importedId].filter((id) => id != null).map((id) => String(id));
1741
+ var readOnlyMutationOutcome = () => ({
1742
+ ok: false,
1743
+ reason: "read-only-document"
1744
+ });
1745
+ var commentsAreReadOnly = (superdoc) => superdoc?.commentsStore?.getConfig?.readOnly === true || superdoc?.config?.modules?.comments?.readOnly === true;
1740
1746
  function getThreadDescendants(superdoc, rootComment) {
1741
1747
  const store = superdoc?.commentsStore;
1742
1748
  if (!store) return [];
@@ -1816,7 +1822,9 @@ function useComment(params) {
1816
1822
  const resolvedByEmail = (0, vue.ref)(params.resolvedByEmail || null);
1817
1823
  const resolvedByName = (0, vue.ref)(params.resolvedByName || null);
1818
1824
  const trackedChangeDecision = (0, vue.ref)(params.trackedChangeDecision || null);
1819
- const resolveComment = ({ id, email, name, superdoc, decision }) => {
1825
+ const resolveComment = ({ id, email, name, superdoc, decision, reconciliationToken }) => {
1826
+ const isCanonicalReconciliation = reconciliationToken === COMMENT_RECONCILIATION_TOKEN;
1827
+ if (commentsAreReadOnly(superdoc) && !isCanonicalReconciliation) return readOnlyMutationOutcome();
1820
1828
  if (resolvedTime.value) return;
1821
1829
  resolvedTime.value = Date.now();
1822
1830
  resolvedById.value = id ?? null;
@@ -1854,6 +1862,7 @@ function useComment(params) {
1854
1862
  });
1855
1863
  };
1856
1864
  const setIsInternal = ({ isInternal: newIsInternal, superdoc }) => {
1865
+ if (commentsAreReadOnly(superdoc)) return readOnlyMutationOutcome();
1857
1866
  const previousValue = isInternal.value;
1858
1867
  if (previousValue === newIsInternal) return;
1859
1868
  isInternal.value = newIsInternal;
@@ -1882,6 +1891,7 @@ function useComment(params) {
1882
1891
  });
1883
1892
  };
1884
1893
  const setText = ({ text, superdoc, suppressUpdate }) => {
1894
+ if (!suppressUpdate && commentsAreReadOnly(superdoc)) return readOnlyMutationOutcome();
1885
1895
  commentText.value = text;
1886
1896
  mentions.value = extractMentions(text);
1887
1897
  if (suppressUpdate) return;
@@ -2863,6 +2873,11 @@ const useCommentsStore = defineStore("comments", () => {
2863
2873
  allowResolve: true,
2864
2874
  showResolved: false
2865
2875
  });
2876
+ const readOnlyMutationOutcome$1 = () => ({
2877
+ ok: false,
2878
+ reason: "read-only-document"
2879
+ });
2880
+ const commentsAreReadOnly$1 = () => commentsConfig.readOnly === true;
2866
2881
  const viewingVisibility = (0, vue.reactive)({
2867
2882
  documentMode: "editing",
2868
2883
  commentsVisible: false,
@@ -2871,6 +2886,8 @@ const useCommentsStore = defineStore("comments", () => {
2871
2886
  const isDebugging = false;
2872
2887
  const debounceTimers = {};
2873
2888
  const trackedChangeResolutionSnapshots = /* @__PURE__ */ new WeakMap();
2889
+ const importedTrackedChangeBootstrapTasks = /* @__PURE__ */ new Map();
2890
+ let importedTrackedChangeBootstrapGeneration = 0;
2874
2891
  const isPreviewCommentsDebugEnabled = () => {
2875
2892
  if (typeof window === "undefined") return false;
2876
2893
  return "__labsSuperDocV2PreviewDebug" in window;
@@ -3310,7 +3327,7 @@ const useCommentsStore = defineStore("comments", () => {
3310
3327
  }
3311
3328
  activeEditor?.commands?.setActiveComment({ commentId: activeComment.value });
3312
3329
  };
3313
- const handleTrackedChangeUpdate = ({ superdoc, params, broadcastChanges = true }) => {
3330
+ const handleTrackedChangeUpdate = ({ superdoc, params, broadcastChanges = true, documentState = void 0 }) => {
3314
3331
  const span = startInteractionSpan("store.trackedChanges.handleUpdate", "store-reconciliation", {
3315
3332
  event: params?.event ?? null,
3316
3333
  changeId: params?.changeId ?? null,
@@ -3325,7 +3342,8 @@ const useCommentsStore = defineStore("comments", () => {
3325
3342
  const normalizedDocumentId = documentId != null ? String(documentId) : null;
3326
3343
  if (!(trackedChangeDisplayType === "tableInsert" || trackedChangeDisplayType === "tableDelete") && normalizedChangeId) {
3327
3344
  const effectiveDocumentId = normalizedDocumentId ?? (superdoc?.activeEditor?.options?.documentId != null ? String(superdoc.activeEditor.options.documentId) : null);
3328
- const docState = (effectiveDocumentId ? superdocStore.getDocument(effectiveDocumentId)?.getEditor?.() : null)?.state ?? superdoc?.activeEditor?.state ?? null;
3345
+ const docEditor = effectiveDocumentId ? superdocStore.getDocument(effectiveDocumentId)?.getEditor?.() : null;
3346
+ const docState = documentState !== void 0 ? documentState : docEditor?.state ?? superdoc?.activeEditor?.state ?? null;
3329
3347
  if (docState) {
3330
3348
  const { ranges: tableRanges, ids: structuralIds } = computeTrackedTableSummaryForState(docState);
3331
3349
  const ranges = trackChangesHelpers.getTrackChanges(docState, normalizedChangeId);
@@ -3459,7 +3477,7 @@ const useCommentsStore = defineStore("comments", () => {
3459
3477
  });
3460
3478
  return;
3461
3479
  }
3462
- addComment({
3480
+ addHydratedComment({
3463
3481
  superdoc,
3464
3482
  comment,
3465
3483
  broadcastChanges
@@ -3481,7 +3499,10 @@ const useCommentsStore = defineStore("comments", () => {
3481
3499
  decision: params.decision ?? null,
3482
3500
  superdoc
3483
3501
  };
3484
- if (existingTrackedChange && !existingTrackedChange.resolvedTime) existingTrackedChange.resolveComment(resolveArgs);
3502
+ if (existingTrackedChange && !existingTrackedChange.resolvedTime) existingTrackedChange.resolveComment({
3503
+ ...resolveArgs,
3504
+ reconciliationToken: COMMENT_RECONCILIATION_TOKEN
3505
+ });
3485
3506
  }
3486
3507
  } finally {
3487
3508
  endInteractionSpan(span);
@@ -3716,8 +3737,9 @@ const useCommentsStore = defineStore("comments", () => {
3716
3737
  if (isV2EditorActive(superdoc)) return;
3717
3738
  superdoc?.activeEditor?.commands?.removeComment({ commentId: "pending" });
3718
3739
  };
3719
- const addComment = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true }) => {
3720
- const v2Adapter = !skipEditorUpdate ? getV2CommentsAdapter(superdoc) : null;
3740
+ const addCommentInternal = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true, isHydration = false }) => {
3741
+ if (commentsAreReadOnly$1() && !isHydration) return readOnlyMutationOutcome$1();
3742
+ const v2Adapter = !skipEditorUpdate && !isHydration ? getV2CommentsAdapter(superdoc) : null;
3721
3743
  if (v2Adapter && !comment.trackedChange) {
3722
3744
  const text = normalizeV2CommentDraftText(pendingComment.value ? currentCommentText.value : comment.commentText);
3723
3745
  const target = pendingComment.value ? pendingV2CommentTarget.value : null;
@@ -3802,7 +3824,21 @@ const useCommentsStore = defineStore("comments", () => {
3802
3824
  comment: newComment
3803
3825
  };
3804
3826
  };
3827
+ const addComment = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true }) => addCommentInternal({
3828
+ superdoc,
3829
+ comment,
3830
+ skipEditorUpdate,
3831
+ broadcastChanges
3832
+ });
3833
+ const addHydratedComment = ({ superdoc, comment, skipEditorUpdate = false, broadcastChanges = true }) => addCommentInternal({
3834
+ superdoc,
3835
+ comment,
3836
+ skipEditorUpdate,
3837
+ broadcastChanges,
3838
+ isHydration: true
3839
+ });
3805
3840
  const deleteComment = ({ commentId: commentIdToDelete, superdoc }) => {
3841
+ if (commentsAreReadOnly$1()) return Promise.resolve(readOnlyMutationOutcome$1());
3806
3842
  const commentIndex = commentsList.value.findIndex((c) => c.commentId === commentIdToDelete);
3807
3843
  const comment = commentsList.value[commentIndex];
3808
3844
  if (!comment) return Promise.resolve({
@@ -3991,6 +4027,7 @@ const useCommentsStore = defineStore("comments", () => {
3991
4027
  };
3992
4028
  };
3993
4029
  const replyCommentV2 = async ({ superdoc, parentCommentId, text } = {}) => {
4030
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
3994
4031
  const v2Adapter = getV2CommentsAdapter(superdoc);
3995
4032
  if (!v2Adapter) return {
3996
4033
  ok: false,
@@ -4025,6 +4062,7 @@ const useCommentsStore = defineStore("comments", () => {
4025
4062
  });
4026
4063
  };
4027
4064
  const editCommentV2 = async ({ superdoc, commentId, text } = {}) => {
4065
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
4028
4066
  const v2Adapter = getV2CommentsAdapter(superdoc);
4029
4067
  if (!v2Adapter) return {
4030
4068
  ok: false,
@@ -4073,6 +4111,7 @@ const useCommentsStore = defineStore("comments", () => {
4073
4111
  });
4074
4112
  };
4075
4113
  const resolveCommentV2 = async ({ superdoc, commentId } = {}) => {
4114
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
4076
4115
  const v2Adapter = getV2CommentsAdapter(superdoc);
4077
4116
  if (!v2Adapter) return {
4078
4117
  ok: false,
@@ -4119,6 +4158,7 @@ const useCommentsStore = defineStore("comments", () => {
4119
4158
  return result;
4120
4159
  };
4121
4160
  const reopenCommentV2 = async ({ superdoc, commentId } = {}) => {
4161
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
4122
4162
  const v2Adapter = getV2CommentsAdapter(superdoc);
4123
4163
  if (!v2Adapter) return {
4124
4164
  ok: false,
@@ -4341,21 +4381,139 @@ const useCommentsStore = defineStore("comments", () => {
4341
4381
  if (typeof creatorName !== "string") return null;
4342
4382
  return creatorName.replace(/\s*\(imported\)\s*$/u, "").trim() || null;
4343
4383
  };
4344
- const bootstrapImportedTrackedChangeComments = (editor, superdoc) => {
4345
- if (!editor || !superdoc) return;
4346
- createCommentForTrackChanges(editor, superdoc);
4384
+ const readMountedEditorSnapshot = (editor) => {
4385
+ if (!editor) return null;
4386
+ try {
4387
+ if (editor.isDestroyed === true) return null;
4388
+ const view = editor.view;
4389
+ if (!view || view.isDestroyed === true || view.destroyed === true) return null;
4390
+ const state = view.state;
4391
+ if (!state) return null;
4392
+ return {
4393
+ view,
4394
+ state
4395
+ };
4396
+ } catch {
4397
+ return null;
4398
+ }
4399
+ };
4400
+ const normalizeBootstrapDocumentId = (documentId) => documentId !== void 0 && documentId !== null && String(documentId).length > 0 ? String(documentId) : null;
4401
+ const cancelImportedTrackedChangeBootstrap = (documentId) => {
4402
+ const normalizedDocumentId = normalizeBootstrapDocumentId(documentId);
4403
+ const entries = normalizedDocumentId ? [[normalizedDocumentId, importedTrackedChangeBootstrapTasks.get(normalizedDocumentId)]] : Array.from(importedTrackedChangeBootstrapTasks.entries());
4404
+ let canceled = 0;
4405
+ for (const [taskDocumentId, task] of entries) {
4406
+ if (!task) continue;
4407
+ importedTrackedChangeBootstrapTasks.delete(taskDocumentId);
4408
+ if (task.timeoutHandle !== null && task.timeoutHandle !== void 0) clearTimeout(task.timeoutHandle);
4409
+ canceled += 1;
4410
+ }
4411
+ return canceled;
4412
+ };
4413
+ const captureImportedTrackedChangeBootstrapSnapshot = (editor) => {
4414
+ const mountedEditor = readMountedEditorSnapshot(editor);
4415
+ if (!mountedEditor) return null;
4416
+ let trackedChanges = [];
4417
+ try {
4418
+ trackedChanges = trackChangesHelpers.getTrackChanges(mountedEditor.state) ?? [];
4419
+ } catch {
4420
+ return null;
4421
+ }
4422
+ const enumerateStructuralChanges = trackChangesHelpers?.enumerateStructuralRowChanges;
4423
+ let structuralChanges = [];
4424
+ if (typeof enumerateStructuralChanges === "function") try {
4425
+ structuralChanges = enumerateStructuralChanges(mountedEditor.state) ?? [];
4426
+ } catch {
4427
+ structuralChanges = [];
4428
+ }
4429
+ let storySnapshots = [];
4430
+ if (typeof getTrackedChangeIndex === "function") try {
4431
+ storySnapshots = getTrackedChangeIndex(editor)?.getAll?.() ?? [];
4432
+ } catch {
4433
+ storySnapshots = [];
4434
+ }
4435
+ return {
4436
+ ...mountedEditor,
4437
+ trackedChanges,
4438
+ structuralChanges,
4439
+ storySnapshots
4440
+ };
4441
+ };
4442
+ const bootstrapImportedTrackedChangeComments = (editor, superdoc, snapshot = null) => {
4443
+ if (!editor || !superdoc) return false;
4444
+ const captured = snapshot ?? captureImportedTrackedChangeBootstrapSnapshot(editor);
4445
+ if (!captured) return false;
4446
+ createCommentForTrackChanges(editor, superdoc, captured.trackedChanges, {
4447
+ editorState: captured.state,
4448
+ editorView: captured.view
4449
+ });
4347
4450
  syncStoryTrackedChangeComments({
4348
4451
  superdoc,
4349
- editor
4452
+ editor,
4453
+ snapshots: captured.storySnapshots,
4454
+ documentState: captured.state,
4455
+ resolveFromEditor: false
4350
4456
  });
4351
4457
  syncStructuralTrackedChangeComments({
4352
4458
  superdoc,
4353
- editor
4459
+ editor,
4460
+ structuralChanges: captured.structuralChanges
4354
4461
  });
4462
+ return true;
4463
+ };
4464
+ const isCurrentImportedTrackedChangeBootstrap = (task) => {
4465
+ if (!task) return false;
4466
+ if (importedTrackedChangeBootstrapTasks.get(task.documentId) !== task) return false;
4467
+ try {
4468
+ const editorDocumentId = task.editor?.options?.documentId;
4469
+ if (editorDocumentId != null && String(editorDocumentId) !== task.documentId) return false;
4470
+ const mountedDocument = superdocStore.getDocument(task.documentId);
4471
+ if (!mountedDocument) return false;
4472
+ if (mountedDocument.getEditor?.() !== task.editor) return false;
4473
+ } catch {
4474
+ return false;
4475
+ }
4476
+ return true;
4477
+ };
4478
+ const runImportedTrackedChangeBootstrap = (task) => {
4479
+ if (!isCurrentImportedTrackedChangeBootstrap(task)) {
4480
+ if (importedTrackedChangeBootstrapTasks.get(task?.documentId) === task) importedTrackedChangeBootstrapTasks.delete(task.documentId);
4481
+ return false;
4482
+ }
4483
+ const snapshot = captureImportedTrackedChangeBootstrapSnapshot(task.editor);
4484
+ if (!snapshot || !isCurrentImportedTrackedChangeBootstrap(task)) {
4485
+ if (importedTrackedChangeBootstrapTasks.get(task.documentId) === task) importedTrackedChangeBootstrapTasks.delete(task.documentId);
4486
+ return false;
4487
+ }
4488
+ try {
4489
+ return bootstrapImportedTrackedChangeComments(task.editor, task.superdoc, snapshot);
4490
+ } finally {
4491
+ if (importedTrackedChangeBootstrapTasks.get(task.documentId) === task) importedTrackedChangeBootstrapTasks.delete(task.documentId);
4492
+ }
4493
+ };
4494
+ const scheduleImportedTrackedChangeBootstrap = ({ editor, superdoc, documentId, defer = true }) => {
4495
+ const normalizedDocumentId = normalizeBootstrapDocumentId(documentId);
4496
+ if (!normalizedDocumentId || !editor || !superdoc) return false;
4497
+ cancelImportedTrackedChangeBootstrap(normalizedDocumentId);
4498
+ const task = {
4499
+ documentId: normalizedDocumentId,
4500
+ editor,
4501
+ superdoc,
4502
+ generation: ++importedTrackedChangeBootstrapGeneration,
4503
+ timeoutHandle: null
4504
+ };
4505
+ importedTrackedChangeBootstrapTasks.set(normalizedDocumentId, task);
4506
+ if (!defer) return runImportedTrackedChangeBootstrap(task);
4507
+ task.timeoutHandle = setTimeout(() => {
4508
+ task.timeoutHandle = null;
4509
+ runImportedTrackedChangeBootstrap(task);
4510
+ }, 0);
4511
+ return true;
4355
4512
  };
4356
4513
  function removeCommentsForDocument(documentId) {
4357
4514
  const activeDocumentId = documentId != null ? String(documentId) : null;
4358
4515
  if (!activeDocumentId) return;
4516
+ cancelImportedTrackedChangeBootstrap(activeDocumentId);
4359
4517
  const removedComments = commentsList.value.filter((comment) => belongsToDocument(comment, activeDocumentId, { allowSingleDocumentMismatch: true }));
4360
4518
  if (!removedComments.length) return;
4361
4519
  const removedAliasIds = /* @__PURE__ */ new Set();
@@ -4386,7 +4544,7 @@ const useCommentsStore = defineStore("comments", () => {
4386
4544
  if (!htmlContent && !comment.trackedChange) return;
4387
4545
  const creatorName = normalizeImportedCreatorName(comment.creatorName);
4388
4546
  const importedName = creatorName ? `${creatorName} (imported)` : null;
4389
- addComment({
4547
+ addHydratedComment({
4390
4548
  superdoc,
4391
4549
  comment: useComment({
4392
4550
  fileId: documentId,
@@ -4423,16 +4581,29 @@ const useCommentsStore = defineStore("comments", () => {
4423
4581
  });
4424
4582
  });
4425
4583
  if (replacedFile) {
4426
- bootstrapImportedTrackedChangeComments(editor, superdoc);
4584
+ scheduleImportedTrackedChangeBootstrap({
4585
+ editor,
4586
+ superdoc,
4587
+ documentId,
4588
+ defer: false
4589
+ });
4427
4590
  return;
4428
4591
  }
4429
- setTimeout(() => {
4430
- bootstrapImportedTrackedChangeComments(editor, superdoc);
4431
- }, 0);
4592
+ scheduleImportedTrackedChangeBootstrap({
4593
+ editor,
4594
+ superdoc,
4595
+ documentId
4596
+ });
4432
4597
  };
4433
4598
  const createCommentForTrackChanges = (editor, superdoc, trackedChangesOverride = null, options = {}) => {
4434
- const { reopenResolved = false, refreshExisting = false, broadcastChanges = true } = options;
4435
- const trackedChanges = trackedChangesOverride ?? trackChangesHelpers.getTrackChanges(editor.state);
4599
+ const { reopenResolved = false, refreshExisting = false, broadcastChanges = true, editorState: editorStateOverride = null, editorView: editorViewOverride = null } = options;
4600
+ const mountedEditor = editorStateOverride ? {
4601
+ state: editorStateOverride,
4602
+ view: editorViewOverride
4603
+ } : readMountedEditorSnapshot(editor);
4604
+ if (!mountedEditor?.state) return;
4605
+ const editorState = mountedEditor.state;
4606
+ const trackedChanges = trackedChangesOverride ?? trackChangesHelpers.getTrackChanges(editorState);
4436
4607
  const groupedChanges = groupChanges(trackedChanges);
4437
4608
  const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
4438
4609
  if (!activeDocumentId) return;
@@ -4477,7 +4648,7 @@ const useCommentsStore = defineStore("comments", () => {
4477
4648
  event: existingTrackedChange ? "update" : "add",
4478
4649
  marks,
4479
4650
  nodes: [],
4480
- newEditorState: editor.state,
4651
+ newEditorState: editorState,
4481
4652
  documentId,
4482
4653
  trackedChangesForId: changesByIdMap.get(id) || []
4483
4654
  });
@@ -4490,7 +4661,8 @@ const useCommentsStore = defineStore("comments", () => {
4490
4661
  handleTrackedChangeUpdate({
4491
4662
  superdoc,
4492
4663
  params,
4493
- broadcastChanges
4664
+ broadcastChanges,
4665
+ documentState: editorState
4494
4666
  });
4495
4667
  if (!existingTrackedChange) {
4496
4668
  skipIds.add(normalizedId);
@@ -4499,9 +4671,15 @@ const useCommentsStore = defineStore("comments", () => {
4499
4671
  }
4500
4672
  }
4501
4673
  });
4502
- const { tr } = editor.view.state;
4674
+ const editorView = mountedEditor.view;
4675
+ try {
4676
+ if (!editorView || editor.view !== editorView || editorView.isDestroyed === true || editorView.destroyed === true) return;
4677
+ } catch {
4678
+ return;
4679
+ }
4680
+ const { tr } = editorState;
4503
4681
  tr.setMeta(CommentsPluginKey, { type: "force" });
4504
- editor.view.dispatch(tr);
4682
+ editorView.dispatch(tr);
4505
4683
  };
4506
4684
  const pruneSuppressedInlineTableComments = ({ suppressedIds, activeDocumentId, superdoc = null, broadcastChanges = true }) => {
4507
4685
  if (!(suppressedIds instanceof Set) || !suppressedIds.size || !activeDocumentId) return;
@@ -4874,6 +5052,10 @@ const useCommentsStore = defineStore("comments", () => {
4874
5052
  return reconcilePromise;
4875
5053
  };
4876
5054
  const decideTrackedChangeFromSidebar = ({ superdoc, comment, decision }) => {
5055
+ if (commentsAreReadOnly$1()) return {
5056
+ ok: false,
5057
+ reason: "read-only-document"
5058
+ };
4877
5059
  if (!comment?.trackedChange) return { ok: false };
4878
5060
  const v2Adapter = getV2TrackedChangesAdapter(superdoc);
4879
5061
  if (v2Adapter) {
@@ -5218,46 +5400,52 @@ const useCommentsStore = defineStore("comments", () => {
5218
5400
  if (!superdoc || !editor) return;
5219
5401
  const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
5220
5402
  if (!activeDocumentId) return;
5221
- const trackedChanges = trackChangesHelpers.getTrackChanges(editor.state);
5403
+ const captured = captureImportedTrackedChangeBootstrapSnapshot(editor);
5404
+ if (!captured) return;
5405
+ const trackedChanges = captured.trackedChanges;
5222
5406
  const liveTrackedChangeIds = /* @__PURE__ */ new Set();
5223
5407
  trackedChanges.forEach((change) => {
5224
5408
  const id = change?.mark?.attrs?.id;
5225
5409
  if (id == null) return;
5226
5410
  liveTrackedChangeIds.add(String(id));
5227
5411
  });
5228
- const trackedChangeIndex = typeof getTrackedChangeIndex === "function" ? getTrackedChangeIndex(editor) : null;
5229
- let storySnapshots = [];
5230
- try {
5231
- storySnapshots = trackedChangeIndex?.getAll?.() ?? [];
5232
- } catch {}
5412
+ const storySnapshots = captured.storySnapshots;
5233
5413
  pruneStaleTrackedChangeComments(liveTrackedChangeIds, new Set(storySnapshots.map((snapshot) => snapshot?.anchorKey).filter((anchorKey) => typeof anchorKey === "string" && anchorKey.length > 0)), activeDocumentId, superdoc, { broadcastChanges });
5234
5414
  createCommentForTrackChanges(editor, superdoc, trackedChanges, {
5235
5415
  reopenResolved: true,
5236
5416
  refreshExisting: true,
5237
- broadcastChanges
5417
+ broadcastChanges,
5418
+ editorState: captured.state,
5419
+ editorView: captured.view
5238
5420
  });
5239
5421
  syncStoryTrackedChangeComments({
5240
5422
  superdoc,
5241
5423
  editor,
5242
5424
  broadcastChanges,
5243
- snapshots: storySnapshots
5425
+ snapshots: storySnapshots,
5426
+ documentState: captured.state
5244
5427
  });
5245
5428
  syncStructuralTrackedChangeComments({
5246
5429
  superdoc,
5247
5430
  editor,
5248
- broadcastChanges
5431
+ broadcastChanges,
5432
+ structuralChanges: captured.structuralChanges
5249
5433
  });
5250
5434
  };
5251
- const syncStructuralTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true }) => {
5435
+ const syncStructuralTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true, structuralChanges: structuralChangesOverride = null }) => {
5252
5436
  const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
5253
5437
  if (!activeDocumentId) return;
5254
5438
  const enumerate = trackChangesHelpers?.enumerateStructuralRowChanges;
5255
5439
  if (typeof enumerate !== "function") return;
5256
- let structuralChanges = [];
5257
- try {
5258
- structuralChanges = enumerate(editor.state) ?? [];
5259
- } catch {
5260
- structuralChanges = [];
5440
+ let structuralChanges = structuralChangesOverride;
5441
+ if (!Array.isArray(structuralChanges)) {
5442
+ const mountedEditor = readMountedEditorSnapshot(editor);
5443
+ if (!mountedEditor) return;
5444
+ try {
5445
+ structuralChanges = enumerate(mountedEditor.state) ?? [];
5446
+ } catch {
5447
+ structuralChanges = [];
5448
+ }
5261
5449
  }
5262
5450
  for (const structural of structuralChanges) {
5263
5451
  if (!structural?.decidable || !structural?.wholeTable) continue;
@@ -5304,13 +5492,19 @@ const useCommentsStore = defineStore("comments", () => {
5304
5492
  });
5305
5493
  }
5306
5494
  };
5307
- const syncStoryTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true, snapshots = null }) => {
5495
+ const syncStoryTrackedChangeComments = ({ superdoc, editor, broadcastChanges = true, snapshots = null, documentState = void 0, resolveFromEditor = true }) => {
5308
5496
  const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null;
5309
5497
  if (!activeDocumentId) return;
5310
5498
  let resolvedSnapshots = snapshots;
5311
5499
  if (!Array.isArray(resolvedSnapshots)) {
5312
5500
  if (typeof getTrackedChangeIndex !== "function") return;
5313
- const index = getTrackedChangeIndex(editor);
5501
+ if (!readMountedEditorSnapshot(editor)) return;
5502
+ let index = null;
5503
+ try {
5504
+ index = getTrackedChangeIndex(editor);
5505
+ } catch {
5506
+ return;
5507
+ }
5314
5508
  if (!index) return;
5315
5509
  try {
5316
5510
  resolvedSnapshots = index.getAll();
@@ -5325,7 +5519,9 @@ const useCommentsStore = defineStore("comments", () => {
5325
5519
  editor,
5326
5520
  snapshot,
5327
5521
  documentId: activeDocumentId,
5328
- broadcastChanges
5522
+ broadcastChanges,
5523
+ documentState,
5524
+ resolveFromEditor
5329
5525
  });
5330
5526
  }
5331
5527
  };
@@ -5342,7 +5538,7 @@ const useCommentsStore = defineStore("comments", () => {
5342
5538
  if (snapshot.type === "delete") return true;
5343
5539
  return snapshot.type === "structural" && snapshot.subtype === "table-delete";
5344
5540
  };
5345
- const buildStoryTrackedChangeParams = ({ editor, snapshot, documentId, event }) => {
5541
+ const buildStoryTrackedChangeParams = ({ editor, snapshot, documentId, event, resolveFromEditor = true }) => {
5346
5542
  const trackedChangeType = getStoryTrackedChangeType(snapshot);
5347
5543
  const trackedChangeDisplayType = getStoryTrackedChangeDisplayType(snapshot);
5348
5544
  const fallbackParams = {
@@ -5366,7 +5562,7 @@ const useCommentsStore = defineStore("comments", () => {
5366
5562
  trackedChangeStoryLabel: snapshot.storyLabel,
5367
5563
  trackedChangeAnchorKey: snapshot.anchorKey
5368
5564
  };
5369
- if (typeof resolveTrackedChangeInStory !== "function") return fallbackParams;
5565
+ if (!resolveFromEditor || typeof resolveTrackedChangeInStory !== "function") return fallbackParams;
5370
5566
  let resolvedChange = null;
5371
5567
  try {
5372
5568
  resolvedChange = resolveTrackedChangeInStory(editor, {
@@ -5403,7 +5599,7 @@ const useCommentsStore = defineStore("comments", () => {
5403
5599
  resolvedParams.trackedChangeAnchorKey = snapshot.anchorKey;
5404
5600
  return resolvedParams;
5405
5601
  };
5406
- const upsertStoryTrackedChangeComment = ({ superdoc, editor, snapshot, documentId, broadcastChanges }) => {
5602
+ const upsertStoryTrackedChangeComment = ({ superdoc, editor, snapshot, documentId, broadcastChanges, documentState, resolveFromEditor }) => {
5407
5603
  if (!snapshot?.runtimeRef?.rawId) return;
5408
5604
  const existingComment = commentsList.value.find((comment) => {
5409
5605
  if (!comment?.trackedChange) return false;
@@ -5418,9 +5614,11 @@ const useCommentsStore = defineStore("comments", () => {
5418
5614
  editor,
5419
5615
  snapshot,
5420
5616
  documentId,
5421
- event: existingComment ? "update" : "add"
5617
+ event: existingComment ? "update" : "add",
5618
+ resolveFromEditor
5422
5619
  }),
5423
- broadcastChanges
5620
+ broadcastChanges,
5621
+ documentState
5424
5622
  });
5425
5623
  if (existingComment) {
5426
5624
  existingComment.trackedChangeStory = snapshot.story;
@@ -5736,9 +5934,11 @@ const useCommentsStore = defineStore("comments", () => {
5736
5934
  getPendingComment,
5737
5935
  showAddComment,
5738
5936
  addComment,
5937
+ addHydratedComment,
5739
5938
  cancelComment,
5740
5939
  deleteComment,
5741
5940
  removePendingComment,
5941
+ cancelImportedTrackedChangeBootstrap,
5742
5942
  removeCommentsForDocument,
5743
5943
  processLoadedDocxComments,
5744
5944
  translateCommentsForExport,
@@ -6368,7 +6568,9 @@ var _sfc_main$34 = {
6368
6568
  key: "delete"
6369
6569
  }
6370
6570
  });
6571
+ const reviewMutationsVisible = (0, vue.computed)(() => props.config.readOnly !== true);
6371
6572
  const generallyAllowed = (0, vue.computed)(() => {
6573
+ if (!reviewMutationsVisible.value) return false;
6372
6574
  if (!props.comment) return false;
6373
6575
  if (props.comment.resolvedTime) return false;
6374
6576
  if (commentsStore.pendingComment) return false;
@@ -6377,6 +6579,7 @@ var _sfc_main$34 = {
6377
6579
  });
6378
6580
  const allowResolve = (0, vue.computed)(() => {
6379
6581
  if (!generallyAllowed.value) return false;
6582
+ if (!props.comment.trackedChange && props.config.allowResolve === false) return false;
6380
6583
  if (props.comment.parentCommentId) return false;
6381
6584
  if (props.comment.trackedChangeParentId) return false;
6382
6585
  const context = {
@@ -6399,6 +6602,8 @@ var _sfc_main$34 = {
6399
6602
  else return isAllowed(PERMISSIONS.REJECT_OTHER, role, isInternal, context);
6400
6603
  });
6401
6604
  const allowReopen = (0, vue.computed)(() => {
6605
+ if (!reviewMutationsVisible.value) return false;
6606
+ if (props.config.allowResolve === false) return false;
6402
6607
  if (!props.reopenSupported) return false;
6403
6608
  if (!props.comment) return false;
6404
6609
  if (!props.comment.resolvedTime) return false;
@@ -6423,11 +6628,12 @@ var _sfc_main$34 = {
6423
6628
  return true;
6424
6629
  });
6425
6630
  const getOverflowOptions = (0, vue.computed)(() => {
6426
- if (!generallyAllowed.value) return false;
6631
+ if (!reviewMutationsVisible.value) return [];
6632
+ if (!generallyAllowed.value) return [];
6427
6633
  if (props.writeDisabledReason) return [];
6428
6634
  const allowedOptions = [];
6429
6635
  const options = /* @__PURE__ */ new Set();
6430
- if (!props.config.readOnly && isCommentOwnedByCurrentUser(props.comment)) options.add("edit");
6636
+ if (isCommentOwnedByCurrentUser(props.comment)) options.add("edit");
6431
6637
  const isOwnComment$1 = isCommentOwnedByCurrentUser(props.comment);
6432
6638
  const context = {
6433
6639
  comment: props.comment,
@@ -6440,18 +6646,25 @@ var _sfc_main$34 = {
6440
6646
  return allowedOptions;
6441
6647
  });
6442
6648
  const handleResolve = () => {
6649
+ if (!reviewMutationsVisible.value) return;
6650
+ if (!props.comment?.trackedChange && props.config.allowResolve === false) return;
6443
6651
  if (props.resolveDisabledReason) return;
6444
6652
  emit("resolve");
6445
6653
  };
6446
6654
  const handleReject = () => {
6655
+ if (!reviewMutationsVisible.value) return;
6447
6656
  if (props.rejectDisabledReason) return;
6448
6657
  emit("reject");
6449
6658
  };
6450
6659
  const handleReopen = () => {
6660
+ if (!reviewMutationsVisible.value || props.config.allowResolve === false) return;
6451
6661
  if (props.reopenDisabledReason) return;
6452
6662
  emit("reopen");
6453
6663
  };
6454
- const handleSelect = (value) => emit("overflow-select", value);
6664
+ const handleSelect = (value) => {
6665
+ if (!reviewMutationsVisible.value) return;
6666
+ emit("overflow-select", value);
6667
+ };
6455
6668
  const isImported = (0, vue.computed)(() => {
6456
6669
  if (!(props.comment.origin != null || !!props.comment.importedAuthor?.name)) return false;
6457
6670
  if (isCommentOwnedByCurrentUser(props.comment)) return false;
@@ -6477,6 +6690,7 @@ var _sfc_main$34 = {
6477
6690
  allowResolve.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
6478
6691
  key: 0,
6479
6692
  class: (0, vue.normalizeClass)(["overflow-menu__icon", { "sd-is-disabled": Boolean(__props.resolveDisabledReason) }]),
6693
+ "data-comment-action": "resolve",
6480
6694
  "data-disabled-reason": __props.resolveDisabledReason || null,
6481
6695
  "aria-disabled": Boolean(__props.resolveDisabledReason),
6482
6696
  innerHTML: (0, vue.unref)(superdocIcons).markDone,
@@ -6485,6 +6699,7 @@ var _sfc_main$34 = {
6485
6699
  allowReject.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
6486
6700
  key: 1,
6487
6701
  class: (0, vue.normalizeClass)(["overflow-menu__icon", { "sd-is-disabled": Boolean(__props.rejectDisabledReason) }]),
6702
+ "data-comment-action": "reject",
6488
6703
  "data-disabled-reason": __props.rejectDisabledReason || null,
6489
6704
  "aria-disabled": Boolean(__props.rejectDisabledReason),
6490
6705
  innerHTML: (0, vue.unref)(superdocIcons).rejectChange,
@@ -6502,6 +6717,7 @@ var _sfc_main$34 = {
6502
6717
  }, null, 10, _hoisted_9$3)) : (0, vue.createCommentVNode)("", true),
6503
6718
  allowOverflow.value ? ((0, vue.openBlock)(), (0, vue.createBlock)(CommentsDropdown_default, {
6504
6719
  key: 3,
6720
+ "data-comment-action": "overflow",
6505
6721
  options: getOverflowOptions.value,
6506
6722
  onSelect: handleSelect,
6507
6723
  "content-style": { fontFamily: (0, vue.unref)(uiFontFamily) }
@@ -6516,7 +6732,7 @@ var _sfc_main$34 = {
6516
6732
  };
6517
6733
  }
6518
6734
  };
6519
- var CommentHeader_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$34, [["__scopeId", "data-v-49c3f013"]]);
6735
+ var CommentHeader_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$34, [["__scopeId", "data-v-359c13bb"]]);
6520
6736
  var _hoisted_1$26 = { class: "input-section" };
6521
6737
  var TEXTAREA_MIN_HEIGHT = 28;
6522
6738
  var TEXTAREA_MAX_HEIGHT = 132;
@@ -6939,8 +7155,14 @@ var _sfc_main$32 = {
6939
7155
  const showInputSection = (0, vue.computed)(() => {
6940
7156
  return !getConfig.readOnly && isDialogActive.value && !props.comment.resolvedTime && !isEditingAnyComment.value;
6941
7157
  });
7158
+ const readOnlyMutationOutcome$1 = () => ({
7159
+ ok: false,
7160
+ reason: "read-only-document"
7161
+ });
7162
+ const commentsAreReadOnly$1 = () => getConfig.value?.readOnly === true;
6942
7163
  const isReplying = (0, vue.ref)(false);
6943
7164
  const startReply = () => {
7165
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
6944
7166
  isReplying.value = true;
6945
7167
  (0, vue.nextTick)(() => {
6946
7168
  commentInput.value?.focus?.();
@@ -7042,6 +7264,7 @@ var _sfc_main$32 = {
7042
7264
  return comments.value.some((c) => c.commentId === editingCommentId.value);
7043
7265
  });
7044
7266
  const shouldShowInternalExternal = (0, vue.computed)(() => {
7267
+ if (getConfig.value.readOnly) return false;
7045
7268
  if (!proxy.$superdoc.config.isInternal) return false;
7046
7269
  if (isV2Mode.value) return false;
7047
7270
  return !suppressInternalExternal.value && !props.comment.trackedChange;
@@ -7130,6 +7353,7 @@ var _sfc_main$32 = {
7130
7353
  isCommentHighlighted.value = false;
7131
7354
  };
7132
7355
  const handleAddComment = async () => {
7356
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7133
7357
  if (isV2Mode.value && v2CommentsAdapter.value && !isPendingNewComment.value) {
7134
7358
  const outcome = await commentsStore.replyCommentV2({
7135
7359
  superdoc: proxy.$superdoc,
@@ -7220,6 +7444,7 @@ var _sfc_main$32 = {
7220
7444
  return v2WriteCapability.value?.reason ?? "v2-write-unavailable";
7221
7445
  });
7222
7446
  const handleReject = async () => {
7447
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7223
7448
  const customHandler = proxy.$superdoc.config.onTrackedChangeBubbleReject;
7224
7449
  if (props.comment.trackedChange) {
7225
7450
  if (isV2Mode.value) {
@@ -7272,6 +7497,11 @@ var _sfc_main$32 = {
7272
7497
  });
7273
7498
  };
7274
7499
  const handleResolve = async () => {
7500
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7501
+ if (!props.comment.trackedChange && getConfig.value?.allowResolve === false) return {
7502
+ ok: false,
7503
+ reason: "resolve-disabled"
7504
+ };
7275
7505
  const customHandler = proxy.$superdoc.config.onTrackedChangeBubbleAccept;
7276
7506
  if (props.comment.trackedChange && isV2Mode.value) {
7277
7507
  const outcome = await commentsStore.decideTrackedChangeFromSidebar({
@@ -7324,6 +7554,11 @@ var _sfc_main$32 = {
7324
7554
  });
7325
7555
  };
7326
7556
  const handleReopen = async () => {
7557
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7558
+ if (getConfig.value?.allowResolve === false) return {
7559
+ ok: false,
7560
+ reason: "resolve-disabled"
7561
+ };
7327
7562
  if (!isV2Mode.value || !v2CommentsAdapter.value) return;
7328
7563
  if (!(await commentsStore.reopenCommentV2({
7329
7564
  superdoc: proxy.$superdoc,
@@ -7336,6 +7571,7 @@ var _sfc_main$32 = {
7336
7571
  });
7337
7572
  };
7338
7573
  const handleOverflowSelect = (value, comment) => {
7574
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7339
7575
  switch (value) {
7340
7576
  case "edit":
7341
7577
  currentCommentText.value = comment?.commentText?.value ?? comment?.commentText ?? "";
@@ -7356,6 +7592,7 @@ var _sfc_main$32 = {
7356
7592
  }
7357
7593
  };
7358
7594
  const handleCommentUpdate = async (comment) => {
7595
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7359
7596
  if (isV2Mode.value && v2CommentsAdapter.value) {
7360
7597
  const outcome = await commentsStore.editCommentV2({
7361
7598
  superdoc: proxy.$superdoc,
@@ -7375,6 +7612,7 @@ var _sfc_main$32 = {
7375
7612
  removePendingComment(proxy.$superdoc);
7376
7613
  };
7377
7614
  const handleInternalExternalSelect = (value) => {
7615
+ if (commentsAreReadOnly$1()) return readOnlyMutationOutcome$1();
7378
7616
  const isPendingComment = !!pendingComment.value;
7379
7617
  const isInternal$1 = value.toLowerCase() === "internal";
7380
7618
  if (!isPendingComment) props.comment.setIsInternal({
@@ -7428,6 +7666,13 @@ var _sfc_main$32 = {
7428
7666
  focusEditInput(commentId);
7429
7667
  });
7430
7668
  });
7669
+ (0, vue.watch)(() => getConfig.value?.readOnly === true, (readOnly) => {
7670
+ if (!readOnly) return;
7671
+ isReplying.value = false;
7672
+ if (comments.value.some((comment) => comment.commentId === editingCommentId.value)) editingCommentId.value = null;
7673
+ if (isPendingNewComment.value) cancelComment(proxy.$superdoc);
7674
+ (0, vue.nextTick)(() => emit("resize"));
7675
+ }, { immediate: true });
7431
7676
  return (_ctx, _cache) => {
7432
7677
  const _directive_click_outside = (0, vue.resolveDirective)("click-outside");
7433
7678
  return (0, vue.withDirectives)(((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
@@ -7644,7 +7889,7 @@ var _sfc_main$32 = {
7644
7889
  };
7645
7890
  }
7646
7891
  };
7647
- var CommentDialog_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$32, [["__scopeId", "data-v-a2a29e0c"]]);
7892
+ var CommentDialog_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$32, [["__scopeId", "data-v-67a03ee2"]]);
7648
7893
  var _hoisted_1$24 = { class: "comments-list" };
7649
7894
  var _hoisted_2$19 = { key: 0 };
7650
7895
  var _hoisted_3$15 = [
@@ -13367,7 +13612,7 @@ var _sfc_main$20 = {
13367
13612
  }
13368
13613
  });
13369
13614
  const { getConfig, documentsWithConverations, commentsList, pendingComment, activeComment, skipSelectionUpdate, commentsByDocument, isCommentsListVisible, isFloatingCommentsReady, generalCommentIds, hasSyncedCollaborationComments, editorCommentPositions, hasInitializedLocations, isCommentHighlighted } = storeToRefs(commentsStore);
13370
- const { showAddComment, handleEditorLocationsUpdate, handleTrackedChangeUpdate, refreshTrackedChangeCommentsByIds, syncTrackedChangePositionsWithDocument, syncTrackedChangeComments, addComment, getComment, resolveCommentPositionEntry, belongsToDocument, COMMENT_EVENTS, requestInstantSidebarAlignment, peekInstantSidebarAlignment, clearInstantSidebarAlignment } = commentsStore;
13615
+ const { showAddComment, handleEditorLocationsUpdate, handleTrackedChangeUpdate, refreshTrackedChangeCommentsByIds, syncTrackedChangePositionsWithDocument, syncTrackedChangeComments, addComment, addHydratedComment, getComment, resolveCommentPositionEntry, belongsToDocument, COMMENT_EVENTS, requestInstantSidebarAlignment, peekInstantSidebarAlignment, clearInstantSidebarAlignment } = commentsStore;
13371
13616
  const { proxy } = (0, vue.getCurrentInstance)();
13372
13617
  commentsStore.proxy = proxy;
13373
13618
  const resolvedEditorIntegration = resolveV2Integration(proxy.$superdoc.config);
@@ -13550,7 +13795,7 @@ var _sfc_main$20 = {
13550
13795
  const openLinkWorkflow = resolveV2LinkWorkflowOpener();
13551
13796
  const unbind = bindEditShortcuts({
13552
13797
  commandRoute: {
13553
- execute: (commandId, payload) => ui.commands.execute(commandId, payload),
13798
+ executeAsync: (commandId, payload) => ui.commands.executeAsync(commandId, payload),
13554
13799
  getState: (commandId) => ui.commands.get(commandId).getState()
13555
13800
  },
13556
13801
  ...openLinkWorkflow ? { openLinkWorkflow } : {}
@@ -14365,6 +14610,7 @@ var _sfc_main$20 = {
14365
14610
  resetSelection();
14366
14611
  v2PageMetricsSnapshot.value = null;
14367
14612
  const clearedDocumentId = payload?.documentId == null ? null : String(payload.documentId);
14613
+ commentsStore.cancelImportedTrackedChangeBootstrap?.(clearedDocumentId ?? void 0);
14368
14614
  if (clearedDocumentId) v2MountStagesByDocumentId.delete(clearedDocumentId);
14369
14615
  if (latestV2MountStage && (clearedDocumentId == null || latestV2MountStage.dataset?.superdocV2DocumentId === clearedDocumentId)) latestV2MountStage = null;
14370
14616
  v2ReviewHydrationController.reset("render-cleared");
@@ -14815,7 +15061,7 @@ var _sfc_main$20 = {
14815
15061
  const { id, existingComment } = resolveDocumentScopedCommentMatch(commentPayload);
14816
15062
  if (id && !existingComment) {
14817
15063
  const commentModel = useComment(commentPayload);
14818
- addComment({
15064
+ addHydratedComment({
14819
15065
  superdoc: proxy.$superdoc,
14820
15066
  comment: commentModel,
14821
15067
  skipEditorUpdate: true
@@ -14829,7 +15075,7 @@ var _sfc_main$20 = {
14829
15075
  if (existingComment) applyReplayUpdateToComment(existingComment, commentPayload, resolvedText);
14830
15076
  else {
14831
15077
  const commentModel = useComment(normalizeReplayCommentModelPayload(commentPayload));
14832
- addComment({
15078
+ addHydratedComment({
14833
15079
  superdoc: proxy.$superdoc,
14834
15080
  comment: commentModel,
14835
15081
  skipEditorUpdate: true
@@ -15103,6 +15349,7 @@ var _sfc_main$20 = {
15103
15349
  handleFormattingMarksShortcut(e);
15104
15350
  }
15105
15351
  (0, vue.onBeforeUnmount)(() => {
15352
+ commentsStore.cancelImportedTrackedChangeBootstrap?.();
15106
15353
  passwordPrompt.destroy();
15107
15354
  findReplace.destroy();
15108
15355
  linkPopover.destroy();
@@ -15627,7 +15874,7 @@ var _sfc_main$20 = {
15627
15874
  };
15628
15875
  }
15629
15876
  };
15630
- var SuperDoc_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$20, [["__scopeId", "data-v-9bcd0709"]]);
15877
+ var SuperDoc_default = /* @__PURE__ */ require__plugin_vue_export_helper.__plugin_vue_export_helper_default(_sfc_main$20, [["__scopeId", "data-v-8d8777e2"]]);
15631
15878
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
15632
15879
  var PINIA_DEVTOOLS_PLUGIN_ID = "dev.esm.pinia";
15633
15880
  var piniaDevtoolsSuppressionState = {
@@ -34196,7 +34443,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
34196
34443
  this.config.colors = shuffleArray(this.config.colors);
34197
34444
  this.userColorMap = /* @__PURE__ */ new Map();
34198
34445
  this.colorIndex = 0;
34199
- this.version = "2.0.0-next.24";
34446
+ this.version = "2.0.0-next.26";
34200
34447
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
34201
34448
  this.superdocId = config.superdocId || require_uuid.v4_default();
34202
34449
  this.colors = this.config.colors ?? [];