superdoc 2.0.0-next.26 → 2.0.0-next.27

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-CBs8xQUw.es.js";
8
+ import { a as createV2ReviewMutationReconciler, i as isV2EditableTextMutationEvent, o as getV2TrackedChangeMutationImpact, t as createSuperDocUI } from "./chunks/create-super-doc-ui-Dvl3EZsv.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";
@@ -1768,6 +1768,7 @@ function useComment(params) {
1768
1768
  const importedId = params.importedId;
1769
1769
  const parentCommentId = params.parentCommentId;
1770
1770
  const trackedChangeParentId = params.trackedChangeParentId;
1771
+ const trackedChangeThreadParentId = ref(params.trackedChangeThreadParentId);
1771
1772
  const fileId = params.fileId;
1772
1773
  const fileType = params.fileType;
1773
1774
  const createdAtVersionNumber = params.createdAtVersionNumber;
@@ -1948,6 +1949,7 @@ function useComment(params) {
1948
1949
  importedId,
1949
1950
  parentCommentId,
1950
1951
  trackedChangeParentId,
1952
+ trackedChangeThreadParentId: trackedChangeThreadParentId.value,
1951
1953
  fileId,
1952
1954
  fileType,
1953
1955
  mentions: mentions.value.map((u) => {
@@ -2000,6 +2002,7 @@ function useComment(params) {
2000
2002
  importedId,
2001
2003
  parentCommentId,
2002
2004
  trackedChangeParentId,
2005
+ trackedChangeThreadParentId,
2003
2006
  fileId,
2004
2007
  fileType,
2005
2008
  mentions,
@@ -2750,6 +2753,12 @@ function withInteractionSpan(stage, branch, meta, fn) {
2750
2753
  throw error;
2751
2754
  }
2752
2755
  }
2756
+ const hasLegacyTrackedChangeThreadSignal = (comment) => Boolean(comment?.trackedChangeLink) || Boolean(comment?.trackedChangeType) || Boolean(comment?.trackedChangeDisplayType) || Boolean(comment?.trackedChangeText) || Boolean(comment?.deletedText) || comment?.trackedChange === true;
2757
+ const trackedChangeThreadParentIdForComment = (comment) => {
2758
+ if (comment?.trackedChangeThreadParentId != null) return comment.trackedChangeThreadParentId;
2759
+ if (comment?.trackedChangeParentId != null && hasLegacyTrackedChangeThreadSignal(comment)) return comment.trackedChangeParentId;
2760
+ return null;
2761
+ };
2753
2762
  var Editor = class {
2754
2763
  constructor() {
2755
2764
  throw new Error("SuperDoc v2 beta: v1 editor-backed comment import paths are not available.");
@@ -3042,9 +3051,15 @@ const useCommentsStore = defineStore("comments", () => {
3042
3051
  if (!comment?.parentCommentId) return comment;
3043
3052
  return getComment(comment.parentCommentId);
3044
3053
  };
3054
+ const trackedChangeThreadParentIdForComment$1 = (comment) => {
3055
+ if (comment?.trackedChangeThreadParentId) return comment.trackedChangeThreadParentId;
3056
+ if (isV2SyntheticTrackedChangeRow(comment) && comment?.trackedChange === true) return null;
3057
+ return trackedChangeThreadParentIdForComment(comment);
3058
+ };
3045
3059
  const shouldThreadWithTrackedChange = (comment) => {
3046
- if (!comment?.trackedChangeParentId) return false;
3047
- const trackedChange = getComment(comment.trackedChangeParentId);
3060
+ const trackedChangeParentId = trackedChangeThreadParentIdForComment$1(comment);
3061
+ if (!trackedChangeParentId) return false;
3062
+ const trackedChange = getComment(trackedChangeParentId);
3048
3063
  return Boolean(trackedChange?.trackedChange);
3049
3064
  };
3050
3065
  const getCommentPositionKey = (commentOrId) => {
@@ -3141,7 +3156,7 @@ const useCommentsStore = defineStore("comments", () => {
3141
3156
  if (source == null) return true;
3142
3157
  return source === DOCUMENT_EDITOR_SELECTION_SOURCE;
3143
3158
  };
3144
- const isTrackedChangeThread = (comment) => Boolean(comment?.trackedChange) || Boolean(comment?.trackedChangeParentId);
3159
+ const isTrackedChangeThread = (comment) => Boolean(comment?.trackedChange) || Boolean(trackedChangeThreadParentIdForComment$1(comment));
3145
3160
  const syncTrackedChangePositionsWithDocument = ({ documentId, editor } = {}) => {
3146
3161
  if (!editor?.state) return 0;
3147
3162
  if (!commentsList.value?.length) return 0;
@@ -3184,7 +3199,11 @@ const useCommentsStore = defineStore("comments", () => {
3184
3199
  commentsList.value.forEach((comment) => {
3185
3200
  const normalizedPositionKey = resolveExistingPositionKey(getCommentAliasIds(comment));
3186
3201
  if (!normalizedPositionKey) return;
3187
- if ([comment?.trackedChangeParentId, comment?.parentCommentId].map((id) => normalizeCommentId(id)).filter(Boolean).some((id) => staleRootAliasIds.has(id))) stalePositionKeys.add(normalizedPositionKey);
3202
+ if ([
3203
+ trackedChangeThreadParentIdForComment$1(comment),
3204
+ comment?.threadingParentCommentId,
3205
+ comment?.parentCommentId
3206
+ ].map((id) => normalizeCommentId(id)).filter(Boolean).some((id) => staleRootAliasIds.has(id))) stalePositionKeys.add(normalizedPositionKey);
3188
3207
  });
3189
3208
  const nextPositions = { ...currentPositions };
3190
3209
  stalePositionKeys.forEach((key) => {
@@ -3194,7 +3213,11 @@ const useCommentsStore = defineStore("comments", () => {
3194
3213
  if (activeComment.value !== void 0 && activeComment.value !== null) {
3195
3214
  const activeCommentModel = getComment(activeComment.value);
3196
3215
  const activeAliases = new Set(getCommentAliasIds(activeCommentModel ?? activeComment.value));
3197
- const activeParentKeys = [activeCommentModel?.trackedChangeParentId, activeCommentModel?.parentCommentId].map((id) => normalizeCommentId(id)).filter(Boolean);
3216
+ const activeParentKeys = [
3217
+ trackedChangeThreadParentIdForComment$1(activeCommentModel),
3218
+ activeCommentModel?.threadingParentCommentId,
3219
+ activeCommentModel?.parentCommentId
3220
+ ].map((id) => normalizeCommentId(id)).filter(Boolean);
3198
3221
  if (Array.from(activeAliases).some((id) => staleRootAliasIds.has(id)) || activeParentKeys.some((id) => staleRootAliasIds.has(id))) clearActiveCommentSelection();
3199
3222
  }
3200
3223
  return stalePositionKeys.size;
@@ -3299,7 +3322,7 @@ const useCommentsStore = defineStore("comments", () => {
3299
3322
  if (!isViewingMode.value) return true;
3300
3323
  const parent = getThreadParent(comment);
3301
3324
  if (!parent && comment?.parentCommentId) return false;
3302
- return Boolean(parent?.trackedChange) || Boolean(comment?.trackedChangeParentId) ? viewingVisibility.trackChangesVisible : viewingVisibility.commentsVisible;
3325
+ return Boolean(parent?.trackedChange) || Boolean(trackedChangeThreadParentIdForComment$1(comment)) ? viewingVisibility.trackChangesVisible : viewingVisibility.commentsVisible;
3303
3326
  };
3304
3327
  const setActiveComment = (superdoc, id) => {
3305
3328
  const activeEditor = superdoc?.activeEditor;
@@ -3667,8 +3690,8 @@ const useCommentsStore = defineStore("comments", () => {
3667
3690
  const childCommentMap = /* @__PURE__ */ new Map();
3668
3691
  commentsList.value.forEach((comment) => {
3669
3692
  if (!isThreadVisible(comment)) return;
3670
- const trackedChangeParentId = shouldThreadWithTrackedChange(comment) ? comment.trackedChangeParentId : null;
3671
- const parentId = comment.parentCommentId || trackedChangeParentId;
3693
+ const trackedChangeThreadParentId = shouldThreadWithTrackedChange(comment) ? trackedChangeThreadParentIdForComment$1(comment) : null;
3694
+ const parentId = comment.parentCommentId || trackedChangeThreadParentId;
3672
3695
  if (comment.resolvedTime) resolvedComments.push(comment);
3673
3696
  else if (!parentId && !comment.resolvedTime) parentComments.push({ ...comment });
3674
3697
  else if (parentId) {
@@ -4261,7 +4284,7 @@ const useCommentsStore = defineStore("comments", () => {
4261
4284
  };
4262
4285
  const isV2TrackedChangeSidecarCommentInput = (input) => {
4263
4286
  if (!input || input.trackedChange === true) return false;
4264
- if (!input.trackedChangeParentId || input.parentCommentId) return false;
4287
+ if (!input.trackedChangeThreadParentId || input.parentCommentId) return false;
4265
4288
  return isBlankV2CommentText(input.commentText);
4266
4289
  };
4267
4290
  const activeKey = activeComment.value != null ? String(activeComment.value) : null;
@@ -4279,12 +4302,13 @@ const useCommentsStore = defineStore("comments", () => {
4279
4302
  });
4280
4303
  if (!input) continue;
4281
4304
  if (isV2TrackedChangeSidecarCommentInput(input)) {
4282
- trackedChangeSidecarParentByCommentId.set(String(input.commentId), String(input.trackedChangeParentId));
4305
+ trackedChangeSidecarParentByCommentId.set(String(input.commentId), String(input.trackedChangeThreadParentId));
4283
4306
  tracePreviewComments("hydrate:drop-v2-sidecar-comment", {
4284
4307
  commentId: input.commentId ?? null,
4285
4308
  importedId: input.importedId ?? null,
4286
4309
  parentCommentId: input.parentCommentId ?? null,
4287
4310
  trackedChangeParentId: input.trackedChangeParentId ?? null,
4311
+ trackedChangeThreadParentId: input.trackedChangeThreadParentId ?? null,
4288
4312
  trackedChangeSide: input.trackedChangeSide ?? null,
4289
4313
  commentText: input.commentText ?? null
4290
4314
  });
@@ -4297,7 +4321,7 @@ const useCommentsStore = defineStore("comments", () => {
4297
4321
  const trackedChangeThreadId = parentId ? trackedChangeSidecarParentByCommentId.get(parentId) : null;
4298
4322
  if (trackedChangeThreadId) {
4299
4323
  input.threadingParentCommentId = trackedChangeThreadId;
4300
- if (input.trackedChangeParentId == null) input.trackedChangeParentId = trackedChangeThreadId;
4324
+ if (input.trackedChangeThreadParentId == null) input.trackedChangeThreadParentId = trackedChangeThreadId;
4301
4325
  }
4302
4326
  const cid = input.commentId != null ? String(input.commentId) : null;
4303
4327
  if (!cid) continue;
@@ -4339,6 +4363,8 @@ const useCommentsStore = defineStore("comments", () => {
4339
4363
  else delete existing.parentCommentId;
4340
4364
  if (input.trackedChangeParentId !== void 0) existing.trackedChangeParentId = input.trackedChangeParentId;
4341
4365
  else delete existing.trackedChangeParentId;
4366
+ if (input.trackedChangeThreadParentId !== void 0) existing.trackedChangeThreadParentId = input.trackedChangeThreadParentId;
4367
+ else existing.trackedChangeThreadParentId = void 0;
4342
4368
  if (input.trackedChangeSide !== void 0) existing.trackedChangeSide = input.trackedChangeSide;
4343
4369
  else delete existing.trackedChangeSide;
4344
4370
  if (input.threadingParentCommentId !== void 0) existing.threadingParentCommentId = input.threadingParentCommentId;
@@ -4550,6 +4576,7 @@ const useCommentsStore = defineStore("comments", () => {
4550
4576
  isInternal: false,
4551
4577
  parentCommentId: comment.parentCommentId,
4552
4578
  trackedChangeParentId: comment.trackedChangeParentId,
4579
+ trackedChangeThreadParentId: comment.trackedChangeThreadParentId,
4553
4580
  creatorId: null,
4554
4581
  creatorName,
4555
4582
  createdTime: comment.createdTime,
@@ -4809,8 +4836,8 @@ const useCommentsStore = defineStore("comments", () => {
4809
4836
  commentsList.value = commentsList.value.filter((comment) => {
4810
4837
  if (!belongsToTrackedChangeSyncDocument(comment, activeDocumentId)) return true;
4811
4838
  const parentCommentId = comment.parentCommentId != null ? String(comment.parentCommentId) : null;
4812
- const trackedChangeParentId = comment.trackedChangeParentId != null ? String(comment.trackedChangeParentId) : null;
4813
- if (!(parentCommentId && removedIds.has(parentCommentId) || trackedChangeParentId && removedIds.has(trackedChangeParentId))) return true;
4839
+ const trackedChangeThreadParentId = trackedChangeThreadParentIdForComment$1(comment) != null ? String(trackedChangeThreadParentIdForComment$1(comment)) : null;
4840
+ if (!(parentCommentId && removedIds.has(parentCommentId) || trackedChangeThreadParentId && removedIds.has(trackedChangeThreadParentId))) return true;
4814
4841
  if (comment.resolvedTime) return true;
4815
4842
  const commentId = comment.commentId != null ? String(comment.commentId) : null;
4816
4843
  const importedId = comment.importedId != null ? String(comment.importedId) : null;
@@ -4866,7 +4893,11 @@ const useCommentsStore = defineStore("comments", () => {
4866
4893
  commentsList.value.forEach((linkedComment) => {
4867
4894
  if (!linkedComment || linkedComment === comment) return;
4868
4895
  if (linkedComment.resolvedTime) return;
4869
- if (![linkedComment.trackedChangeParentId, linkedComment.parentCommentId].map((id) => normalizeCommentId(id)).filter(Boolean).some((id) => trackedChangeIds.has(id))) return;
4896
+ if (![
4897
+ trackedChangeThreadParentIdForComment$1(linkedComment),
4898
+ linkedComment.threadingParentCommentId,
4899
+ linkedComment.parentCommentId
4900
+ ].map((id) => normalizeCommentId(id)).filter(Boolean).some((id) => trackedChangeIds.has(id))) return;
4870
4901
  if (typeof linkedComment.resolveComment === "function") {
4871
4902
  linkedComment.resolveComment(resolveArgs);
4872
4903
  resolvedCount += 1;
@@ -4921,10 +4952,12 @@ const useCommentsStore = defineStore("comments", () => {
4921
4952
  commentsList.value.forEach((linkedComment) => {
4922
4953
  if (!linkedComment || linkedComment === comment) return;
4923
4954
  const trackedChangeParentId = normalizeCommentId(linkedComment.trackedChangeParentId);
4955
+ const trackedChangeThreadParentId = normalizeCommentId(linkedComment.trackedChangeThreadParentId);
4924
4956
  const threadingParentCommentId = normalizeCommentId(linkedComment.threadingParentCommentId);
4925
4957
  const parentCommentId = normalizeCommentId(linkedComment.parentCommentId);
4926
- if (!(trackedChangeParentId && trackedChangeIds.has(trackedChangeParentId) || threadingParentCommentId && trackedChangeIds.has(threadingParentCommentId) || parentCommentId && trackedChangeIds.has(parentCommentId))) return;
4958
+ if (!(trackedChangeParentId && trackedChangeIds.has(trackedChangeParentId) || trackedChangeThreadParentId && trackedChangeIds.has(trackedChangeThreadParentId) || threadingParentCommentId && trackedChangeIds.has(threadingParentCommentId) || parentCommentId && trackedChangeIds.has(parentCommentId))) return;
4927
4959
  delete linkedComment.trackedChangeParentId;
4960
+ linkedComment.trackedChangeThreadParentId = void 0;
4928
4961
  delete linkedComment.trackedChangeSide;
4929
4962
  delete linkedComment.threadingParentCommentId;
4930
4963
  if (parentCommentId && trackedChangeIds.has(parentCommentId)) delete linkedComment.parentCommentId;
@@ -6550,6 +6583,7 @@ var CommentHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6550
6583
  return Boolean(currentName && commentName && currentName === commentName);
6551
6584
  };
6552
6585
  const isOwnComment = computed(() => isCommentOwnedByCurrentUser(props.comment));
6586
+ const trackedChangeThreadParentId = computed(() => trackedChangeThreadParentIdForComment(props.comment));
6553
6587
  const { uiFontFamily } = useUiFontFamily();
6554
6588
  const OVERFLOW_OPTIONS = Object.freeze({
6555
6589
  edit: {
@@ -6574,7 +6608,7 @@ var CommentHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6574
6608
  if (!generallyAllowed.value) return false;
6575
6609
  if (!props.comment.trackedChange && props.config.allowResolve === false) return false;
6576
6610
  if (props.comment.parentCommentId) return false;
6577
- if (props.comment.trackedChangeParentId) return false;
6611
+ if (trackedChangeThreadParentId.value) return false;
6578
6612
  const context = {
6579
6613
  comment: props.comment,
6580
6614
  currentUser: proxy.$superdoc.config.user,
@@ -6603,7 +6637,7 @@ var CommentHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6603
6637
  if (commentsStore.pendingComment) return false;
6604
6638
  if (props.isPendingInput) return false;
6605
6639
  if (props.comment.parentCommentId) return false;
6606
- if (props.comment.trackedChangeParentId) return false;
6640
+ if (trackedChangeThreadParentId.value) return false;
6607
6641
  if (props.comment.trackedChange) return false;
6608
6642
  const context = {
6609
6643
  comment: props.comment,
@@ -6724,7 +6758,7 @@ var CommentHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
6724
6758
  ], 2)]);
6725
6759
  };
6726
6760
  }
6727
- }, [["__scopeId", "data-v-359c13bb"]]);
6761
+ }, [["__scopeId", "data-v-ca6050aa"]]);
6728
6762
  var _hoisted_1$26 = { class: "input-section" };
6729
6763
  var TEXTAREA_MIN_HEIGHT = 28;
6730
6764
  var TEXTAREA_MAX_HEIGHT = 132;
@@ -6824,8 +6858,8 @@ const collectTrackedChangeThread = (parentComment, allComments) => {
6824
6858
  allComments.forEach((comment) => {
6825
6859
  if (comment.commentId === trackedChangeId) return;
6826
6860
  const isDirectChild = [comment.parentCommentId, comment.threadingParentCommentId].filter((id) => id != null).map((id) => String(id)).includes(trackedChangeId);
6827
- const isTrackedChangeAnchoredRoot = comment.trackedChangeParentId === trackedChangeId && !comment.parentCommentId;
6828
- if (isDirectChild || isTrackedChangeAnchoredRoot) {
6861
+ const isTrackedChangeThreadRoot = String(trackedChangeThreadParentIdForComment(comment) ?? "") === trackedChangeId && !comment.parentCommentId;
6862
+ if (isDirectChild || isTrackedChangeThreadRoot) {
6829
6863
  threadIds.add(comment.commentId);
6830
6864
  queue.push(comment.commentId);
6831
6865
  }
@@ -9444,6 +9478,38 @@ var HtmlViewer_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
9444
9478
  };
9445
9479
  }
9446
9480
  }, [["__scopeId", "data-v-da3494ba"]]);
9481
+ const collectRemovedCommentIds = (comments, targetIds, isInScope = () => true) => {
9482
+ const targets = new Set(targetIds.map(String));
9483
+ const removedIds = /* @__PURE__ */ new Set();
9484
+ comments.forEach((comment) => {
9485
+ if (!isInScope(comment)) return;
9486
+ const commentId = comment.commentId != null ? String(comment.commentId) : null;
9487
+ const importedId = comment.importedId != null ? String(comment.importedId) : null;
9488
+ if (!(commentId && targets.has(commentId)) && !(importedId && targets.has(importedId))) return;
9489
+ if (commentId) removedIds.add(commentId);
9490
+ if (importedId) removedIds.add(importedId);
9491
+ });
9492
+ let expanded = true;
9493
+ while (expanded) {
9494
+ expanded = false;
9495
+ comments.forEach((comment) => {
9496
+ if (!isInScope(comment)) return;
9497
+ const commentId = comment.commentId != null ? String(comment.commentId) : null;
9498
+ const importedId = comment.importedId != null ? String(comment.importedId) : null;
9499
+ const parentCommentId = comment.parentCommentId != null ? String(comment.parentCommentId) : null;
9500
+ const trackedChangeThreadParentIdValue = trackedChangeThreadParentIdForComment(comment);
9501
+ const trackedChangeThreadParentId = trackedChangeThreadParentIdValue != null ? String(trackedChangeThreadParentIdValue) : null;
9502
+ const isRemovedComment = commentId && removedIds.has(commentId) || importedId && removedIds.has(importedId);
9503
+ const isDescendant = parentCommentId && removedIds.has(parentCommentId) || trackedChangeThreadParentId && removedIds.has(trackedChangeThreadParentId);
9504
+ if (!isRemovedComment && !isDescendant) return;
9505
+ const sizeBefore = removedIds.size;
9506
+ if (commentId) removedIds.add(commentId);
9507
+ if (importedId) removedIds.add(importedId);
9508
+ if (removedIds.size > sizeBefore) expanded = true;
9509
+ });
9510
+ }
9511
+ return removedIds;
9512
+ };
9447
9513
  var isHighContrastMode = ref(false);
9448
9514
  function useHighContrastMode() {
9449
9515
  const setHighContrastMode = (value) => {
@@ -9826,6 +9892,45 @@ function resolveV2ReviewTargetCommentId(target, getComment) {
9826
9892
  const commentId = comment?.commentId ?? comment?.importedId ?? target.entityId;
9827
9893
  return commentId != null ? String(commentId) : null;
9828
9894
  }
9895
+ function normalizeDocumentId(value) {
9896
+ return value == null ? null : String(value);
9897
+ }
9898
+ function createV2RemoteReviewHydrationScheduler({ hydrate, getActiveDocumentId, debounceMs = 250, ceilingMs = 1e3, now: now$2 = () => Date.now(), setTimer = (callback, delay) => setTimeout(callback, delay), clearTimer = (timer$1) => clearTimeout(timer$1) }) {
9899
+ let timer = null;
9900
+ let heldSinceMs = null;
9901
+ let pendingDocumentId = null;
9902
+ const matchesActiveDocument = (documentId) => {
9903
+ return normalizeDocumentId(getActiveDocumentId()) === documentId;
9904
+ };
9905
+ const clear = () => {
9906
+ if (timer != null) clearTimer(timer);
9907
+ timer = null;
9908
+ heldSinceMs = null;
9909
+ pendingDocumentId = null;
9910
+ };
9911
+ const schedule = (documentId) => {
9912
+ const normalizedDocumentId = normalizeDocumentId(documentId);
9913
+ if (!matchesActiveDocument(normalizedDocumentId)) return false;
9914
+ if (pendingDocumentId !== normalizedDocumentId) clear();
9915
+ const scheduledAtMs = now$2();
9916
+ pendingDocumentId = normalizedDocumentId;
9917
+ heldSinceMs ??= scheduledAtMs;
9918
+ if (timer != null) clearTimer(timer);
9919
+ const ceilingRemainingMs = Math.max(0, ceilingMs - (scheduledAtMs - heldSinceMs));
9920
+ timer = setTimer(() => {
9921
+ const deliveredDocumentId = pendingDocumentId;
9922
+ timer = null;
9923
+ heldSinceMs = null;
9924
+ pendingDocumentId = null;
9925
+ if (matchesActiveDocument(deliveredDocumentId)) hydrate();
9926
+ }, Math.min(debounceMs, ceilingRemainingMs));
9927
+ return true;
9928
+ };
9929
+ return {
9930
+ schedule,
9931
+ clear
9932
+ };
9933
+ }
9829
9934
  var NO_AUTHOR_SIGNAL = "no-author-configured";
9830
9935
  const V2_AUTHOR_REQUIRED_CODE = "author-required";
9831
9936
  const V2_AUTHOR_REQUIRED_MESSAGE = "This edit needs an author identity. Set `user.name` in your SuperDoc configuration and reopen the document to make tracked or revision-overlapping edits.";
@@ -14357,6 +14462,8 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
14357
14462
  if (latestV2MountStage && (clearedDocumentId == null || latestV2MountStage.dataset?.superdocV2DocumentId === clearedDocumentId)) latestV2MountStage = null;
14358
14463
  v2ReviewHydrationController.reset("render-cleared");
14359
14464
  v2ReviewMutationReconciler.reset();
14465
+ clearV2TypingReviewHydrationTimer();
14466
+ v2RemoteReviewHydrationScheduler.clear();
14360
14467
  commentsStore.setV2CommentsAdapter?.(null);
14361
14468
  commentsStore.setV2TrackedChangesAdapter?.(null);
14362
14469
  commentsStore.clearEditorCommentPositions?.();
@@ -14409,6 +14516,12 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
14409
14516
  });
14410
14517
  let v2LastTypingMutationAtMs = 0;
14411
14518
  let v2TypingReviewHydrationHeldSinceMs = 0;
14519
+ const clearV2TypingReviewHydrationTimer = () => {
14520
+ if (v2TypingReviewHydrationTimer && typeof clearTimeout === "function") clearTimeout(v2TypingReviewHydrationTimer);
14521
+ v2TypingReviewHydrationTimer = 0;
14522
+ v2LastTypingMutationAtMs = 0;
14523
+ v2TypingReviewHydrationHeldSinceMs = 0;
14524
+ };
14412
14525
  const scheduleV2TypingReviewHydration = () => {
14413
14526
  v2LastTypingMutationAtMs = Date.now();
14414
14527
  if (!v2TypingReviewHydrationHeldSinceMs) v2TypingReviewHydrationHeldSinceMs = v2LastTypingMutationAtMs;
@@ -14429,6 +14542,13 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
14429
14542
  const ceilingRemainingMs = Math.max(0, V2_TYPING_REVIEW_HYDRATION_CEILING_MS - (Date.now() - v2TypingReviewHydrationHeldSinceMs));
14430
14543
  v2TypingReviewHydrationTimer = setTimeout(attempt, Math.min(V2_TYPING_REVIEW_HYDRATION_IDLE_MS, ceilingRemainingMs));
14431
14544
  };
14545
+ const v2RemoteReviewHydrationScheduler = createV2RemoteReviewHydrationScheduler({
14546
+ hydrate: () => hydrateV2ReviewRowsFromHost(),
14547
+ getActiveDocumentId: () => {
14548
+ const activeEditor = proxy.$superdoc?.activeEditor ?? null;
14549
+ return activeEditor?.documentId ?? activeEditor?.options?.documentId ?? null;
14550
+ }
14551
+ });
14432
14552
  const onV2HostEvent = (document$1, event) => {
14433
14553
  if (!event) return;
14434
14554
  const documentId = document$1?.id ?? null;
@@ -14436,6 +14556,10 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
14436
14556
  syncSidebarActiveCommentFromV2ReviewTarget(event.next);
14437
14557
  return;
14438
14558
  }
14559
+ if (event.type === "collaboration:remote-changed") {
14560
+ v2RemoteReviewHydrationScheduler.schedule(documentId);
14561
+ return;
14562
+ }
14439
14563
  if (event.type === "source:complete") {
14440
14564
  proxy.$superdoc.broadcastSourceComplete();
14441
14565
  return;
@@ -14669,6 +14793,7 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
14669
14793
  "isInternal",
14670
14794
  "parentCommentId",
14671
14795
  "trackedChangeParentId",
14796
+ "trackedChangeThreadParentId",
14672
14797
  "threadingParentCommentId",
14673
14798
  "trackedChange",
14674
14799
  "trackedChangeType",
@@ -14833,34 +14958,8 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
14833
14958
  if (!activeDocumentId || typeof belongsToDocument !== "function") return true;
14834
14959
  return belongsToDocument(comment, activeDocumentId);
14835
14960
  };
14836
- const removedCommentIds = /* @__PURE__ */ new Set();
14837
- commentsList.value.forEach((comment) => {
14838
- if (!isInActiveDocument(comment)) return;
14839
- const commentId = comment.commentId != null ? String(comment.commentId) : null;
14840
- const importedId = comment.importedId != null ? String(comment.importedId) : null;
14841
- if (!(commentId && targetIds.includes(commentId) || importedId && targetIds.includes(importedId))) return;
14842
- if (commentId) removedCommentIds.add(commentId);
14843
- if (importedId) removedCommentIds.add(importedId);
14844
- });
14961
+ const removedCommentIds = collectRemovedCommentIds(commentsList.value, targetIds, isInActiveDocument);
14845
14962
  if (removedCommentIds.size) {
14846
- let expanded = true;
14847
- while (expanded) {
14848
- expanded = false;
14849
- commentsList.value.forEach((comment) => {
14850
- if (!isInActiveDocument(comment)) return;
14851
- const commentId = comment.commentId != null ? String(comment.commentId) : null;
14852
- const importedId = comment.importedId != null ? String(comment.importedId) : null;
14853
- const parentCommentId = comment.parentCommentId != null ? String(comment.parentCommentId) : null;
14854
- const trackedChangeParentId = comment.trackedChangeParentId != null ? String(comment.trackedChangeParentId) : null;
14855
- const isRemovedComment = commentId && removedCommentIds.has(commentId) || importedId && removedCommentIds.has(importedId);
14856
- const isDescendantOfRemovedComment = parentCommentId && removedCommentIds.has(parentCommentId) || trackedChangeParentId && removedCommentIds.has(trackedChangeParentId);
14857
- if (!isRemovedComment && !isDescendantOfRemovedComment) return;
14858
- const sizeBefore = removedCommentIds.size;
14859
- if (commentId) removedCommentIds.add(commentId);
14860
- if (importedId) removedCommentIds.add(importedId);
14861
- if (removedCommentIds.size > sizeBefore) expanded = true;
14862
- });
14863
- }
14864
14963
  const previousComments = [...commentsList.value];
14865
14964
  commentsList.value = commentsList.value.filter((comment) => {
14866
14965
  if (!isInActiveDocument(comment)) return true;
@@ -15118,11 +15217,8 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
15118
15217
  cancelAnimationFrame(v2GeometryRafHandle);
15119
15218
  v2GeometryRafHandle = 0;
15120
15219
  }
15121
- if (v2TypingReviewHydrationTimer && typeof clearTimeout === "function") {
15122
- clearTimeout(v2TypingReviewHydrationTimer);
15123
- v2TypingReviewHydrationTimer = 0;
15124
- }
15125
- v2TypingReviewHydrationHeldSinceMs = 0;
15220
+ clearV2TypingReviewHydrationTimer();
15221
+ v2RemoteReviewHydrationScheduler.clear();
15126
15222
  document.removeEventListener("focusin", handleRuntimeFocusIn, true);
15127
15223
  document.removeEventListener("pointerdown", handleRuntimePointerDown, true);
15128
15224
  document.removeEventListener("mousedown", handleRuntimeMouseDown, true);
@@ -15615,7 +15711,7 @@ var SuperDoc_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
15615
15711
  ], 38);
15616
15712
  };
15617
15713
  }
15618
- }, [["__scopeId", "data-v-8d8777e2"]]);
15714
+ }, [["__scopeId", "data-v-c4ab995e"]]);
15619
15715
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
15620
15716
  var PINIA_DEVTOOLS_PLUGIN_ID = "dev.esm.pinia";
15621
15717
  var piniaDevtoolsSuppressionState = {
@@ -34161,7 +34257,7 @@ var SuperDoc = class extends import_eventemitter3.default {
34161
34257
  this.config.colors = shuffleArray(this.config.colors);
34162
34258
  this.userColorMap = /* @__PURE__ */ new Map();
34163
34259
  this.colorIndex = 0;
34164
- this.version = "2.0.0-next.26";
34260
+ this.version = "2.0.0-next.27";
34165
34261
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
34166
34262
  this.superdocId = config.superdocId || v4_default();
34167
34263
  this.colors = this.config.colors ?? [];