superdoc 2.28.0-next.5 → 2.28.0-next.7

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.
Files changed (45) hide show
  1. package/dist/chunks/{create-super-doc-ui-D1eOhAjv.cjs → create-super-doc-ui-B4c55pFy.cjs} +420 -84
  2. package/dist/chunks/{create-super-doc-ui-B29zw5qD.es.js → create-super-doc-ui-C4Ka5Ph3.es.js} +415 -85
  3. package/dist/collaboration-upgrade-engine.cjs +1 -1
  4. package/dist/collaboration-upgrade-engine.es.js +1 -1
  5. package/dist/document-api/src/content-controls/content-controls.types.d.ts +11 -0
  6. package/dist/document-api/src/contract/command-catalog.d.ts +1 -1
  7. package/dist/document-api/src/contract/operation-definitions.d.ts +41 -41
  8. package/dist/document-api/src/contract/operation-registry.d.ts +4 -0
  9. package/dist/document-api/src/export/export.d.ts +3 -1
  10. package/dist/document-api/src/export/export.types.d.ts +8 -0
  11. package/dist/document-api/src/get-node/get-node.d.ts +10 -4
  12. package/dist/document-api/src/index.d.ts +2 -1
  13. package/dist/document-api/src/replace/replace.d.ts +4 -1
  14. package/dist/document-api/src/types/mutation-plan.types.d.ts +2 -0
  15. package/dist/document-api/src/types/track-changes.types.d.ts +10 -2
  16. package/dist/layout-engine/contracts/src/index.d.ts +1 -0
  17. package/dist/public/ui-react.cjs +1 -1
  18. package/dist/public/ui-react.es.js +1 -1
  19. package/dist/public/ui-vue.cjs +1 -1
  20. package/dist/public/ui-vue.es.js +1 -1
  21. package/dist/public/ui.cjs +1 -1
  22. package/dist/public/ui.es.js +1 -1
  23. package/dist/style.css +1 -1
  24. package/dist/style.layered.css +1 -1
  25. package/dist/superdoc/src/core/SuperDoc.d.ts +2 -6
  26. package/dist/superdoc/src/core/collaboration/resolve-v2-collaboration-target.d.ts +2 -0
  27. package/dist/superdoc/src/core/editor-runtime/types.d.ts +1 -0
  28. package/dist/superdoc/src/core/editor-runtime/v2/v2-editor-runtime-adapter.d.ts +2 -2
  29. package/dist/superdoc/src/core/helpers/resolve-docx-export.d.ts +6 -0
  30. package/dist/superdoc/src/core/types/index.d.ts +10 -0
  31. package/dist/superdoc/src/public/export-types.d.ts +3 -0
  32. package/dist/superdoc/src/public/ui/entity-at.d.ts +1 -0
  33. package/dist/superdoc/src/public/ui/types.d.ts +16 -2
  34. package/dist/superdoc/src/public/ui.d.cts +14 -0
  35. package/dist/superdoc/src/public/ui.d.ts +1 -1
  36. package/dist/superdoc/src/stores/comments-store.d.ts +3 -57
  37. package/dist/superdoc/src/stores/superdoc-store.d.ts +9 -171
  38. package/dist/superdoc.cjs +352 -135
  39. package/dist/superdoc.es.js +352 -135
  40. package/dist-cdn/style.layered.css +1 -1
  41. package/dist-cdn/superdoc.min.css +1 -1
  42. package/dist-cdn/superdoc.min.js +42 -42
  43. package/package.json +2 -2
  44. package/dist/superdoc/src/index.d.cts +0 -18
  45. package/dist/superdoc/src/index.d.ts +0 -14
@@ -1,6 +1,6 @@
1
1
  import { i as __toESM$2 } from "./chunks/rolldown-runtime-0pSA04fp.es.js";
2
2
  import { t as blank_default } from "./chunks/blank-docx-DzQccOlW.es.js";
3
- import { _ as getWorkflowRecording, a as registerFirstPartyCommandMutation, c as getV2TrackedChangeMutationImpact, d as resolveImageSrc, g as createInteractionHistory, h as closeInteractionHistory, i as readFirstPartyPageNumbers, l as isPlainObject$1, m as DOM_CLASS_NAMES, n as executeFirstPartyCommandAsync, p as isSyntheticTrackedChangeCommentLaneItem, r as executeFirstPartyShortcutAsync, s as applyV2CommentInvalidationFromMutation, t as createSuperDocUI, u as createImageFilePicker, v as isWorkflowRecordingEnabled, y as recordInteraction } from "./chunks/create-super-doc-ui-B29zw5qD.es.js";
3
+ import { _ as createInteractionHistory, a as registerFirstPartyCommandMutation, b as recordInteraction, c as applyV2CommentInvalidationFromMutation, d as createImageFilePicker, f as resolveImageSrc, g as closeInteractionHistory, h as DOM_CLASS_NAMES, i as readFirstPartyPageNumbers, l as getV2TrackedChangeMutationImpact, m as isSyntheticTrackedChangeCommentLaneItem, n as executeFirstPartyCommandAsync, o as isRecord, r as executeFirstPartyShortcutAsync, t as createSuperDocUI, u as isPlainObject$1, v as getWorkflowRecording, y as isWorkflowRecordingEnabled } from "./chunks/create-super-doc-ui-C4Ka5Ph3.es.js";
4
4
  import { t as import_eventemitter3 } from "./chunks/eventemitter3-DEIiXiH2.es.js";
5
5
  import { t as v4 } from "./chunks/uuid-H0Xcmmhy.es.js";
6
6
  import { $ as vModelText, A as onActivated, B as renderSlot, C as isRef$1, D as normalizeClass, E as nextTick, F as openBlock, G as toRaw$2, H as resolveDynamicComponent, I as provide$1, J as unref, K as toRef, L as reactive, M as onDeactivated, N as onMounted, O as normalizeProps, P as onScopeDispose$1, Q as vModelSelect, R as ref, S as isReactive$1, T as mergeProps, U as shallowRef$1, V as resolveDirective, W as toDisplayString, X as useSlots, Y as useAttrs, Z as vModelCheckbox, _ as getCurrentInstance, a as computed$1, b as hasInjectionContext, c as createCommentVNode, d as createStaticVNode, et as watch$1, f as createTextVNode, g as effectScope, h as defineComponent, i as Transition, it as withModifiers, j as onBeforeUnmount, k as normalizeStyle, l as createElementBlock, m as defineAsyncComponent, n as Fragment, nt as withDirectives, o as createApp, p as createVNode, q as toRefs, r as Teleport, rt as withKeys, s as createBlock, t as _plugin_vue_export_helper_default, tt as withCtx, u as createElementVNode, v as getCurrentScope, w as markRaw, x as inject$1, y as h, z as renderList } from "./chunks/_plugin-vue_export-helper-7ZiLY07t.es.js";
@@ -258,7 +258,7 @@ var v_click_outside_default = {
258
258
  var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
259
259
  function getSuperdocVersion() {
260
260
  try {
261
- return "2.28.0-next.5";
261
+ return "2.28.0-next.7";
262
262
  } catch {
263
263
  return "unknown";
264
264
  }
@@ -5462,7 +5462,8 @@ function resolveWebsocketFamily(family, candidate) {
5462
5462
  roomMode,
5463
5463
  serverUrl,
5464
5464
  ...params ? { params } : {},
5465
- ...token ? { token } : {}
5465
+ ...token ? { token } : {},
5466
+ ...family === "hocuspocus" && candidate.retry !== void 0 ? { retry: candidate.retry } : {}
5466
5467
  }
5467
5468
  };
5468
5469
  }
@@ -7753,6 +7754,7 @@ var useCommentsStore = defineStore("comments", () => {
7753
7754
  const instantSidebarAlignmentInstanceId = ref(null);
7754
7755
  const pendingComment = ref(null);
7755
7756
  const pendingV2CommentTarget = shallowRef$1(null);
7757
+ let pendingCommentRequest = 0;
7756
7758
  const isViewingMode = computed$1(() => viewingVisibility.documentMode === "viewing");
7757
7759
  const shouldRenderReviewInViewing = computed$1(() => {
7758
7760
  if (!isViewingMode.value) return true;
@@ -7760,6 +7762,7 @@ var useCommentsStore = defineStore("comments", () => {
7760
7762
  });
7761
7763
  const v2CommentsAdapter = shallowRef$1(null);
7762
7764
  const setV2CommentsAdapter = (adapter) => {
7765
+ if (v2CommentsAdapter.value !== (adapter ?? null)) pendingCommentRequest += 1;
7763
7766
  v2CommentsAdapter.value = adapter ?? null;
7764
7767
  };
7765
7768
  const getV2CommentsAdapter = (superdoc) => {
@@ -8618,26 +8621,41 @@ var useCommentsStore = defineStore("comments", () => {
8618
8621
  }
8619
8622
  if (typeof currentSelection !== "function") return null;
8620
8623
  try {
8621
- return currentSelection();
8624
+ const snapshot = currentSelection();
8625
+ return typeof snapshot?.then === "function" ? Promise.resolve(snapshot).catch(() => null) : snapshot;
8622
8626
  } catch {
8623
8627
  return null;
8624
8628
  }
8625
8629
  };
8626
8630
  const showAddComment = (superdoc, targetClientY = null) => {
8631
+ const request = ++pendingCommentRequest;
8632
+ const editor = superdoc?.activeEditor;
8627
8633
  const v2Adapter = getV2CommentsAdapter(superdoc);
8628
- const pendingSelection = getPendingSelectionSnapshot(superdoc, superdocStore.activeSelection);
8629
- const event = {
8630
- type: COMMENT_EVENTS.PENDING,
8631
- pendingSelection
8634
+ const ownsRequest = () => pendingCommentRequest === request;
8635
+ const emitPending = (snapshot) => {
8636
+ if (!ownsRequest()) return;
8637
+ superdoc.emit("comments-update", {
8638
+ type: COMMENT_EVENTS.PENDING,
8639
+ pendingSelection: superdoc?.activeEditor === editor ? snapshot : null
8640
+ });
8632
8641
  };
8633
- superdoc.emit("comments-update", event);
8634
8642
  if (v2Adapter) {
8635
8643
  const cap = v2Adapter.getCapabilityState?.();
8636
8644
  if (cap && cap.canWrite === false) return {
8637
8645
  ok: false,
8638
8646
  reason: cap.reason
8639
8647
  };
8640
- return Promise.resolve(v2Adapter.captureCurrentSelection?.()).then((capture) => {
8648
+ return Promise.resolve(v2Adapter.captureCurrentSelection?.({ beforeReady: (snapshot) => {
8649
+ if (superdoc?.activeEditor === editor && getV2CommentsAdapter(superdoc) === v2Adapter) emitPending(snapshot);
8650
+ } })).then((capture) => {
8651
+ if (!ownsRequest()) return {
8652
+ ok: false,
8653
+ reason: "pending-comment-superseded"
8654
+ };
8655
+ if (superdoc?.activeEditor !== editor || getV2CommentsAdapter(superdoc) !== v2Adapter) return {
8656
+ ok: false,
8657
+ reason: "document-replaced"
8658
+ };
8641
8659
  if (!capture?.ok) return {
8642
8660
  ok: false,
8643
8661
  reason: capture?.reason ?? "editing-range-required",
@@ -8666,25 +8684,52 @@ var useCommentsStore = defineStore("comments", () => {
8666
8684
  detail: err?.message ?? String(err)
8667
8685
  }));
8668
8686
  }
8669
- const selection = { ...superdocStore.activeSelection };
8670
- selection.selectionBounds = { ...selection.selectionBounds };
8671
- if (superdocStore.selectionPosition?.source && superdocStore.selectionPosition.source !== "pdf") superdocStore.selectionPosition.source = null;
8672
- pendingComment.value = getPendingComment({
8673
- selection,
8674
- documentId: selection.documentId,
8675
- parentCommentId: null
8676
- });
8677
- if (!superdoc.config.isInternal) pendingComment.value.isInternal = false;
8678
- if (superdoc.activeEditor?.commands) superdoc.activeEditor.commands.insertComment({
8679
- ...pendingComment.value.getValues(),
8680
- commentId: "pending",
8681
- skipEmit: true
8682
- });
8683
- if (pendingComment.value.selection.source === "document-editor" && superdocStore.selectionPosition) superdocStore.selectionPosition.source = DOCUMENT_EDITOR_SELECTION_SOURCE;
8684
- requestInstantSidebarAlignment(targetClientY, "pending");
8685
- setActiveFloatingCommentInstance(null);
8686
- activeComment.value = pendingComment.value.commentId;
8687
- return { ok: true };
8687
+ const pendingSelection = getPendingSelectionSnapshot(superdoc, superdocStore.activeSelection);
8688
+ const asyncSnapshot = typeof pendingSelection?.then === "function";
8689
+ if (!asyncSnapshot) emitPending(pendingSelection);
8690
+ const showLegacyPending = (selection) => {
8691
+ selection.selectionBounds = { ...selection.selectionBounds };
8692
+ if (superdocStore.selectionPosition?.source && superdocStore.selectionPosition.source !== "pdf") superdocStore.selectionPosition.source = null;
8693
+ pendingComment.value = getPendingComment({
8694
+ selection,
8695
+ documentId: selection.documentId,
8696
+ parentCommentId: null
8697
+ });
8698
+ if (!superdoc.config.isInternal) pendingComment.value.isInternal = false;
8699
+ if (superdoc.activeEditor?.commands) superdoc.activeEditor.commands.insertComment({
8700
+ ...pendingComment.value.getValues(),
8701
+ commentId: "pending",
8702
+ skipEmit: true
8703
+ });
8704
+ if (pendingComment.value.selection.source === "document-editor" && superdocStore.selectionPosition) superdocStore.selectionPosition.source = DOCUMENT_EDITOR_SELECTION_SOURCE;
8705
+ requestInstantSidebarAlignment(targetClientY, "pending");
8706
+ setActiveFloatingCommentInstance(null);
8707
+ activeComment.value = pendingComment.value.commentId;
8708
+ return { ok: true };
8709
+ };
8710
+ if (asyncSnapshot) {
8711
+ const selection = { ...superdocStore.activeSelection };
8712
+ selection.selectionBounds = { ...selection.selectionBounds };
8713
+ return pendingSelection.then((snapshot) => {
8714
+ if (!ownsRequest()) return {
8715
+ ok: false,
8716
+ reason: "pending-comment-superseded"
8717
+ };
8718
+ emitPending(snapshot);
8719
+ if (!ownsRequest()) return {
8720
+ ok: false,
8721
+ reason: "pending-comment-superseded"
8722
+ };
8723
+ return superdoc?.activeEditor === editor ? showLegacyPending(selection) : {
8724
+ ok: false,
8725
+ reason: "document-replaced"
8726
+ };
8727
+ });
8728
+ }
8729
+ return ownsRequest() ? showLegacyPending({ ...superdocStore.activeSelection }) : {
8730
+ ok: false,
8731
+ reason: "pending-comment-superseded"
8732
+ };
8688
8733
  };
8689
8734
  /**
8690
8735
  * Get the numeric position value for sorting a comment by document order.
@@ -8839,7 +8884,7 @@ var useCommentsStore = defineStore("comments", () => {
8839
8884
  *
8840
8885
  * @returns {void}
8841
8886
  */
8842
- const removePendingComment = (superdoc) => {
8887
+ const resetPendingCommentState = (superdoc, clearViewingSelection = true) => {
8843
8888
  const hadPending = !!pendingComment.value;
8844
8889
  currentCommentText.value = "";
8845
8890
  currentCommentMentions.value = [];
@@ -8848,13 +8893,17 @@ var useCommentsStore = defineStore("comments", () => {
8848
8893
  superdocStore.selectionPosition = null;
8849
8894
  if (hadPending) clearActiveCommentSelection();
8850
8895
  if (isV2EditorActive(superdoc)) {
8851
- if (hadPending && isViewingMode.value) try {
8896
+ if (hadPending && clearViewingSelection && isViewingMode.value) try {
8852
8897
  superdoc?.activeEditor?.host?.getHandles?.()?.selection?.clear?.();
8853
8898
  } catch {}
8854
8899
  return;
8855
8900
  }
8856
8901
  superdoc?.activeEditor?.commands?.removeComment({ commentId: "pending" });
8857
8902
  };
8903
+ const removePendingComment = (superdoc) => {
8904
+ pendingCommentRequest += 1;
8905
+ resetPendingCommentState(superdoc);
8906
+ };
8858
8907
  const getV2CreatedComment = ({ outcome, reconciled, documentId }) => {
8859
8908
  const createdId = normalizeCommentId(outcome?.createdCommentId);
8860
8909
  if (!createdId) return reconciled?.added ?? null;
@@ -8872,6 +8921,7 @@ var useCommentsStore = defineStore("comments", () => {
8872
8921
  const v2Adapter = !skipEditorUpdate && !isHydration ? getV2CommentsAdapter(superdoc) : null;
8873
8922
  if (v2Adapter && !comment.trackedChange) {
8874
8923
  const submittedPendingComment = pendingComment.value;
8924
+ const submittedPendingRequest = pendingCommentRequest;
8875
8925
  const text = normalizeV2CommentDraftText(submittedPendingComment ? currentCommentText.value : comment.commentText);
8876
8926
  const mentions = pendingComment.value ? currentCommentMentions.value : comment.mentions ?? [];
8877
8927
  const target = pendingComment.value ? pendingV2CommentTarget.value : null;
@@ -8920,9 +8970,11 @@ var useCommentsStore = defineStore("comments", () => {
8920
8970
  documentId: v2Adapter.documentId
8921
8971
  });
8922
8972
  const hadPendingComment = submittedPendingComment != null && pendingComment.value?.commentId === submittedPendingComment.commentId;
8923
- if (hadPendingComment) removePendingComment(superdoc);
8973
+ const ownsSubmittedRequest = pendingCommentRequest === submittedPendingRequest;
8974
+ if (hadPendingComment) if (ownsSubmittedRequest) removePendingComment(superdoc);
8975
+ else resetPendingCommentState(superdoc, false);
8924
8976
  const createdId = created?.commentId ?? null;
8925
- if (hadPendingComment && createdId) {
8977
+ if (hadPendingComment && ownsSubmittedRequest && createdId) {
8926
8978
  setActiveComment(superdoc, createdId);
8927
8979
  setActiveFloatingCommentInstance(createdId);
8928
8980
  }
@@ -9019,6 +9071,8 @@ var useCommentsStore = defineStore("comments", () => {
9019
9071
  rejected: true,
9020
9072
  comment: comment.getValues(),
9021
9073
  reason: outcome?.reason ?? "v2-delete-failed",
9074
+ ...outcome?.code !== void 0 ? { code: outcome.code } : {},
9075
+ ...outcome?.detail !== void 0 ? { detail: outcome.detail } : {},
9022
9076
  ...outcome?.committed ? { committed: true } : {}
9023
9077
  });
9024
9078
  return outcome;
@@ -13331,97 +13385,107 @@ var _hoisted_2$19 = {
13331
13385
  class: "existing-internal-input"
13332
13386
  };
13333
13387
  var _hoisted_3$16 = { class: "new-comment-input-wrapper" };
13334
- var _hoisted_4$11 = { class: "reply-actions" };
13335
- var _hoisted_5$8 = ["disabled"];
13336
- var _hoisted_6$6 = {
13388
+ var _hoisted_4$11 = {
13389
+ key: 1,
13390
+ class: "tracked-change-decision-alert",
13391
+ role: "alert"
13392
+ };
13393
+ var _hoisted_5$8 = { class: "reply-actions" };
13394
+ var _hoisted_6$6 = ["disabled"];
13395
+ var _hoisted_7$4 = {
13337
13396
  key: 0,
13338
13397
  class: "resolved-badge"
13339
13398
  };
13340
- var _hoisted_7$4 = ["innerHTML"];
13341
- var _hoisted_8$4 = {
13399
+ var _hoisted_8$4 = ["innerHTML"];
13400
+ var _hoisted_9$3 = {
13342
13401
  key: 1,
13343
13402
  class: "existing-internal-input"
13344
13403
  };
13345
- var _hoisted_9$3 = {
13404
+ var _hoisted_10$3 = {
13405
+ key: 2,
13406
+ class: "tracked-change-decision-alert",
13407
+ role: "alert"
13408
+ };
13409
+ var _hoisted_11$3 = {
13346
13410
  key: 0,
13347
13411
  class: "card-section comment-body"
13348
13412
  };
13349
- var _hoisted_10$3 = ["data-track-change-semantic-color-key"];
13350
- var _hoisted_11$3 = { key: 0 };
13351
- var _hoisted_12$2 = { class: "change-type tracked-change-label" };
13352
- var _hoisted_13$2 = {
13413
+ var _hoisted_12$2 = ["data-track-change-semantic-color-key"];
13414
+ var _hoisted_13$2 = { key: 0 };
13415
+ var _hoisted_14$2 = { class: "change-type tracked-change-label" };
13416
+ var _hoisted_15$2 = {
13353
13417
  key: 0,
13354
13418
  class: "tracked-change-detail-lines"
13355
13419
  };
13356
- var _hoisted_14$2 = {
13420
+ var _hoisted_16$2 = {
13357
13421
  key: 0,
13358
13422
  class: "tracked-change-text"
13359
13423
  };
13360
- var _hoisted_15$2 = {
13424
+ var _hoisted_17$2 = {
13361
13425
  key: 1,
13362
13426
  class: "change-type"
13363
13427
  };
13364
- var _hoisted_16$2 = { class: "change-type" };
13365
- var _hoisted_17$2 = { key: 1 };
13366
- var _hoisted_18$2 = { class: "tracked-change-text is-inserted" };
13367
- var _hoisted_19$1 = { key: 2 };
13428
+ var _hoisted_18$2 = { class: "change-type" };
13429
+ var _hoisted_19$1 = { key: 1 };
13368
13430
  var _hoisted_20$1 = { class: "tracked-change-text is-inserted" };
13369
- var _hoisted_21$1 = { key: 3 };
13370
- var _hoisted_22$1 = { key: 4 };
13371
- var _hoisted_23$1 = { key: 5 };
13372
- var _hoisted_24 = { key: 6 };
13373
- var _hoisted_25 = { class: "tracked-change-text" };
13374
- var _hoisted_26 = { key: 7 };
13375
- var _hoisted_27 = { class: "tracked-change-text is-deleted" };
13376
- var _hoisted_28 = { class: "tracked-change-text is-inserted" };
13377
- var _hoisted_29 = { key: 8 };
13378
- var _hoisted_30 = { key: 9 };
13379
- var _hoisted_31 = { key: 10 };
13380
- var _hoisted_32 = { class: "tracked-change-text is-deleted" };
13381
- var _hoisted_33 = { key: 11 };
13382
- var _hoisted_34 = { class: "tracked-change-text is-inserted" };
13383
- var _hoisted_35 = ["data-track-change-image-preview-role"];
13384
- var _hoisted_36 = ["src", "alt"];
13385
- var _hoisted_37 = {
13431
+ var _hoisted_21$1 = { key: 2 };
13432
+ var _hoisted_22$1 = { class: "tracked-change-text is-inserted" };
13433
+ var _hoisted_23$1 = { key: 3 };
13434
+ var _hoisted_24 = { key: 4 };
13435
+ var _hoisted_25 = { key: 5 };
13436
+ var _hoisted_26 = { key: 6 };
13437
+ var _hoisted_27 = { class: "tracked-change-text" };
13438
+ var _hoisted_28 = { key: 7 };
13439
+ var _hoisted_29 = { class: "tracked-change-text is-deleted" };
13440
+ var _hoisted_30 = { class: "tracked-change-text is-inserted" };
13441
+ var _hoisted_31 = { key: 8 };
13442
+ var _hoisted_32 = { key: 9 };
13443
+ var _hoisted_33 = { key: 10 };
13444
+ var _hoisted_34 = { class: "tracked-change-text is-deleted" };
13445
+ var _hoisted_35 = { key: 11 };
13446
+ var _hoisted_36 = { class: "tracked-change-text is-inserted" };
13447
+ var _hoisted_37 = ["data-track-change-image-preview-role"];
13448
+ var _hoisted_38 = ["src", "alt"];
13449
+ var _hoisted_39 = {
13386
13450
  key: 1,
13387
13451
  class: "card-section comment-body"
13388
13452
  };
13389
- var _hoisted_38 = ["innerHTML"];
13390
- var _hoisted_39 = {
13453
+ var _hoisted_40 = ["innerHTML"];
13454
+ var _hoisted_41 = {
13391
13455
  key: 1,
13392
13456
  class: "comment"
13393
13457
  };
13394
- var _hoisted_40 = {
13458
+ var _hoisted_42 = {
13395
13459
  key: 2,
13396
13460
  class: "reply-expanded"
13397
13461
  };
13398
- var _hoisted_41 = { class: "reply-input-wrapper" };
13399
- var _hoisted_42 = { class: "reply-actions" };
13400
- var _hoisted_43 = ["onClick"];
13401
- var _hoisted_44 = [
13462
+ var _hoisted_43 = { class: "reply-input-wrapper" };
13463
+ var _hoisted_44 = { class: "reply-actions" };
13464
+ var _hoisted_45 = ["onClick"];
13465
+ var _hoisted_46 = [
13402
13466
  "onClick",
13403
13467
  "disabled",
13404
13468
  "data-disabled-reason"
13405
13469
  ];
13406
- var _hoisted_45 = { class: "collapsed-avatars" };
13407
- var _hoisted_46 = {
13470
+ var _hoisted_47 = { class: "collapsed-avatars" };
13471
+ var _hoisted_48 = {
13408
13472
  key: 3,
13409
13473
  class: "comment-separator"
13410
13474
  };
13411
- var _hoisted_47 = {
13412
- key: 2,
13475
+ var _hoisted_49 = {
13476
+ key: 3,
13413
13477
  class: "tracked-change-decision-alert",
13414
13478
  role: "alert"
13415
13479
  };
13416
- var _hoisted_48 = { class: "tracked-change-decision-alert__message" };
13417
- var _hoisted_49 = ["disabled", "data-disabled-reason"];
13418
- var _hoisted_50 = {
13480
+ var _hoisted_50 = { class: "tracked-change-decision-alert__message" };
13481
+ var _hoisted_51 = ["disabled", "data-disabled-reason"];
13482
+ var _hoisted_52 = {
13419
13483
  key: 1,
13420
13484
  class: "reply-expanded"
13421
13485
  };
13422
- var _hoisted_51 = { class: "reply-input-wrapper" };
13423
- var _hoisted_52 = { class: "reply-actions" };
13424
- var _hoisted_53 = ["disabled", "data-disabled-reason"];
13486
+ var _hoisted_53 = { class: "reply-input-wrapper" };
13487
+ var _hoisted_54 = { class: "reply-actions" };
13488
+ var _hoisted_55 = ["disabled", "data-disabled-reason"];
13425
13489
  var commentEditSessions = /* @__PURE__ */ new WeakMap();
13426
13490
  var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
13427
13491
  __name: "CommentDialog",
@@ -13501,6 +13565,7 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
13501
13565
  };
13502
13566
  };
13503
13567
  const CLICK_OUTSIDE_IGNORED_SELECTORS = [
13568
+ ".superdoc__tools [data-id=\"is-tool\"]",
13504
13569
  ".comments-dropdown__option-label",
13505
13570
  ".comments-dropdown__menu",
13506
13571
  ".comments-dropdown__option",
@@ -13674,12 +13739,17 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
13674
13739
  const isReplying = ref(false);
13675
13740
  const isSubmittingReply = ref(false);
13676
13741
  const isSubmittingNewComment = ref(false);
13742
+ const commentSaveFailure = ref("");
13743
+ const commentSaveFailureMessage = (outcome, hasDraft = true) => {
13744
+ return `Your comment could not be saved${outcome?.detail === "document-mode-read-only" ? " because the document or connection is read-only" : outcome?.code === "PERMISSION_DENIED" ? " because you do not have permission" : ""}.${hasDraft ? " Your draft is still here. Try again or cancel." : " Try again."}`;
13745
+ };
13677
13746
  const startReply = () => {
13678
13747
  if (commentsAreReadOnly()) return readOnlyMutationOutcome();
13679
13748
  if (isV2WriteDisabled.value) return {
13680
13749
  ok: false,
13681
13750
  reason: v2WriteCapability.value?.reason ?? "v2-write-unavailable"
13682
13751
  };
13752
+ commentSaveFailure.value = "";
13683
13753
  isReplying.value = true;
13684
13754
  nextTick(() => {
13685
13755
  commentInput.value?.focus?.();
@@ -13929,6 +13999,7 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
13929
13999
  reason: "reply-submit-in-flight"
13930
14000
  };
13931
14001
  isSubmittingReply.value = true;
14002
+ commentSaveFailure.value = "";
13932
14003
  try {
13933
14004
  const parentCommentId = getV2ExistingReplyParentId(props.comment);
13934
14005
  const trackedChangeTarget = getV2TrackedChangeCommentTarget(props.comment);
@@ -13940,6 +14011,7 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
13940
14011
  ...trackedChangeTarget ? { trackedChangeTarget } : {}
13941
14012
  });
13942
14013
  if (!outcome?.ok) {
14014
+ commentSaveFailure.value = commentSaveFailureMessage(outcome);
13943
14015
  nextTick(() => emit("resize"));
13944
14016
  return outcome;
13945
14017
  }
@@ -13958,6 +14030,7 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
13958
14030
  reason: "comment-submit-in-flight"
13959
14031
  };
13960
14032
  isSubmittingNewComment.value = true;
14033
+ commentSaveFailure.value = "";
13961
14034
  }
13962
14035
  const options = {
13963
14036
  documentId: props.comment.fileId,
@@ -13973,7 +14046,10 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
13973
14046
  Promise.resolve().then(() => addComment({
13974
14047
  superdoc: proxy.$superdoc,
13975
14048
  comment
13976
- })).catch((err) => {
14049
+ })).then((outcome) => {
14050
+ if (isPendingNewComment.value && outcome?.ok === false) commentSaveFailure.value = commentSaveFailureMessage(outcome);
14051
+ }).catch((err) => {
14052
+ commentSaveFailure.value = commentSaveFailureMessage();
13977
14053
  console.error("[SuperDoc] addComment failed", err);
13978
14054
  }).finally(() => {
13979
14055
  isSubmittingNewComment.value = false;
@@ -14198,10 +14274,15 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14198
14274
  });
14199
14275
  v1TrackedChangeDecisionApplied = Boolean(outcome?.ok) && outcome.success !== false;
14200
14276
  } else if (isV2Mode.value && v2CommentsAdapter.value) {
14201
- if (!(await commentsStore.resolveCommentV2({
14277
+ const outcome = await commentsStore.resolveCommentV2({
14202
14278
  superdoc: proxy.$superdoc,
14203
14279
  commentId: props.comment.commentId
14204
- }))?.ok) return;
14280
+ });
14281
+ if (!outcome?.ok) {
14282
+ commentSaveFailure.value = commentSaveFailureMessage(outcome, false);
14283
+ return outcome;
14284
+ }
14285
+ commentSaveFailure.value = "";
14205
14286
  } else props.comment.resolveComment({
14206
14287
  id: superdocStore.user.id,
14207
14288
  email: superdocStore.user.email,
@@ -14230,17 +14311,22 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14230
14311
  reason: "resolve-disabled"
14231
14312
  };
14232
14313
  if (!isV2Mode.value || !v2CommentsAdapter.value) return;
14233
- if (!(await commentsStore.reopenCommentV2({
14314
+ const outcome = await commentsStore.reopenCommentV2({
14234
14315
  superdoc: proxy.$superdoc,
14235
14316
  commentId: props.comment.commentId
14236
- }))?.ok) return;
14317
+ });
14318
+ if (!outcome?.ok) {
14319
+ commentSaveFailure.value = commentSaveFailureMessage(outcome, false);
14320
+ return outcome;
14321
+ }
14322
+ commentSaveFailure.value = "";
14237
14323
  nextTick(() => {
14238
14324
  commentsStore.lastUpdate = /* @__PURE__ */ new Date();
14239
14325
  commentsStore.setActiveComment(proxy.$superdoc, activeComment.value);
14240
14326
  proxy.$superdoc.focus?.();
14241
14327
  });
14242
14328
  };
14243
- const handleOverflowSelect = (value, comment) => {
14329
+ const handleOverflowSelect = async (value, comment) => {
14244
14330
  if (commentsAreReadOnly()) return readOnlyMutationOutcome();
14245
14331
  switch (value) {
14246
14332
  case "edit":
@@ -14259,10 +14345,13 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14259
14345
  });
14260
14346
  break;
14261
14347
  case "delete":
14262
- deleteComment({
14263
- superdoc: proxy.$superdoc,
14264
- commentId: comment.commentId
14265
- });
14348
+ {
14349
+ const outcome = await deleteComment({
14350
+ superdoc: proxy.$superdoc,
14351
+ commentId: comment.commentId
14352
+ });
14353
+ commentSaveFailure.value = outcome?.ok ? "" : commentSaveFailureMessage(outcome, false);
14354
+ }
14266
14355
  break;
14267
14356
  }
14268
14357
  };
@@ -14283,8 +14372,12 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14283
14372
  commentId: comment.commentId,
14284
14373
  text: draft
14285
14374
  });
14286
- if (!outcome?.ok) return outcome;
14287
14375
  if (session?.owner !== editSessionOwner || commentEditSessions.get(commentsStore) !== session || session.submission !== submission || proxy.$superdoc.activeEditor !== editor || editor.v2Comments !== adapter || adapter.documentId !== documentId || editor.doc !== document || props.comment !== thread || editingCommentId.value !== comment.commentId || currentCommentText.value !== draft) return outcome;
14376
+ if (!outcome?.ok) {
14377
+ commentSaveFailure.value = commentSaveFailureMessage(outcome);
14378
+ return outcome;
14379
+ }
14380
+ commentSaveFailure.value = "";
14288
14381
  retireOwnEditSession();
14289
14382
  editingCommentId.value = null;
14290
14383
  removePendingComment(proxy.$superdoc);
@@ -14316,6 +14409,7 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14316
14409
  return typeof timestamp === "string" ? new Date(timestamp).getTime() : timestamp;
14317
14410
  };
14318
14411
  const handleCancel = (comment) => {
14412
+ commentSaveFailure.value = "";
14319
14413
  retireOwnEditSession();
14320
14414
  editingCommentId.value = null;
14321
14415
  isReplying.value = false;
@@ -14415,26 +14509,28 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14415
14509
  "config",
14416
14510
  "comment"
14417
14511
  ])]),
14418
- createElementVNode("div", _hoisted_4$11, [createElementVNode("button", {
14512
+ commentSaveFailure.value ? (openBlock(), createElementBlock("p", _hoisted_4$11, toDisplayString(commentSaveFailure.value), 1)) : createCommentVNode("", true),
14513
+ createElementVNode("div", _hoisted_5$8, [createElementVNode("button", {
14419
14514
  class: "sd-button reply-btn-cancel",
14420
14515
  onClick: withModifiers(handleCancel, ["stop", "prevent"])
14421
14516
  }, "Cancel"), createElementVNode("button", {
14422
14517
  class: normalizeClass(["sd-button primary reply-btn-primary", { "sd-is-disabled": !hasTextContent.value || isSubmittingNewComment.value }]),
14423
14518
  onClick: withModifiers(handleAddComment, ["stop", "prevent"]),
14424
14519
  disabled: !hasTextContent.value || isSubmittingNewComment.value
14425
- }, " Comment ", 10, _hoisted_5$8)])
14520
+ }, " Comment ", 10, _hoisted_6$6)])
14426
14521
  ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
14427
- resolvedBadgeLabel.value ? (openBlock(), createElementBlock("div", _hoisted_6$6, [createElementVNode("span", {
14522
+ resolvedBadgeLabel.value ? (openBlock(), createElementBlock("div", _hoisted_7$4, [createElementVNode("span", {
14428
14523
  class: "resolved-badge__icon",
14429
14524
  innerHTML: unref(superdocIcons).markDone
14430
- }, null, 8, _hoisted_7$4), createTextVNode(" " + toDisplayString(resolvedBadgeLabel.value), 1)])) : createCommentVNode("", true),
14431
- shouldShowInternalExternal.value ? (openBlock(), createElementBlock("div", _hoisted_8$4, [createVNode(InternalDropdown_default, {
14525
+ }, null, 8, _hoisted_8$4), createTextVNode(" " + toDisplayString(resolvedBadgeLabel.value), 1)])) : createCommentVNode("", true),
14526
+ shouldShowInternalExternal.value ? (openBlock(), createElementBlock("div", _hoisted_9$3, [createVNode(InternalDropdown_default, {
14432
14527
  onClick: _cache[1] || (_cache[1] = withModifiers(() => {}, ["stop", "prevent"])),
14433
14528
  class: "sd-internal-dropdown",
14434
14529
  "is-disabled": isInternalDropdownDisabled.value,
14435
14530
  state: __props.comment.isInternal ? "internal" : "external",
14436
14531
  onSelect: handleInternalExternalSelect
14437
14532
  }, null, 8, ["is-disabled", "state"])])) : createCommentVNode("", true),
14533
+ commentSaveFailure.value ? (openBlock(), createElementBlock("p", _hoisted_10$3, toDisplayString(commentSaveFailure.value), 1)) : createCommentVNode("", true),
14438
14534
  (openBlock(true), createElementBlock(Fragment, null, renderList(visibleComments.value, (comment, index) => {
14439
14535
  return openBlock(), createElementBlock("div", {
14440
14536
  key: comment.commentId,
@@ -14466,27 +14562,27 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14466
14562
  "write-disabled-reason",
14467
14563
  "onOverflowSelect"
14468
14564
  ]),
14469
- comment.trackedChange ? (openBlock(), createElementBlock("div", _hoisted_9$3, [
14565
+ comment.trackedChange ? (openBlock(), createElementBlock("div", _hoisted_11$3, [
14470
14566
  createElementVNode("div", {
14471
14567
  class: normalizeClass(["tracked-change", index === 0 ? bodyOverflowClass.value : void 0]),
14472
14568
  "data-track-change-semantic-color-key": comment.semanticColorKey ?? void 0,
14473
14569
  ref_for: true,
14474
14570
  ref: index === 0 ? setParentBodyRef : void 0
14475
- }, [comment.trackedChangeLabel ? (openBlock(), createElementBlock("div", _hoisted_11$3, [createElementVNode("span", _hoisted_12$2, toDisplayString(comment.trackedChangeLabel), 1), comment.trackedChangeDetailLines && comment.trackedChangeDetailLines.length ? (openBlock(), createElementBlock("div", _hoisted_13$2, [(openBlock(true), createElementBlock(Fragment, null, renderList(comment.trackedChangeDetailLines, (line, lineIndex) => {
14571
+ }, [comment.trackedChangeLabel ? (openBlock(), createElementBlock("div", _hoisted_13$2, [createElementVNode("span", _hoisted_14$2, toDisplayString(comment.trackedChangeLabel), 1), comment.trackedChangeDetailLines && comment.trackedChangeDetailLines.length ? (openBlock(), createElementBlock("div", _hoisted_15$2, [(openBlock(true), createElementBlock(Fragment, null, renderList(comment.trackedChangeDetailLines, (line, lineIndex) => {
14476
14572
  return openBlock(), createElementBlock("div", {
14477
14573
  key: lineIndex,
14478
14574
  class: "tracked-change-detail-line"
14479
14575
  }, [
14480
- line.excerpt ? (openBlock(), createElementBlock("span", _hoisted_14$2, "\"" + toDisplayString(line.excerpt) + "\"", 1)) : createCommentVNode("", true),
14481
- line.excerpt ? (openBlock(), createElementBlock("span", _hoisted_15$2, " — ")) : createCommentVNode("", true),
14482
- createElementVNode("span", _hoisted_16$2, toDisplayString(line.label), 1)
14576
+ line.excerpt ? (openBlock(), createElementBlock("span", _hoisted_16$2, "\"" + toDisplayString(line.excerpt) + "\"", 1)) : createCommentVNode("", true),
14577
+ line.excerpt ? (openBlock(), createElementBlock("span", _hoisted_17$2, " — ")) : createCommentVNode("", true),
14578
+ createElementVNode("span", _hoisted_18$2, toDisplayString(line.label), 1)
14483
14579
  ]);
14484
- }), 128))])) : createCommentVNode("", true)])) : comment.trackedChangeDisplayType === "hyperlinkAdded" ? (openBlock(), createElementBlock("div", _hoisted_17$2, [_cache[2] || (_cache[2] = createElementVNode("span", { class: "change-type" }, "Added hyperlink ", -1)), createElementVNode("span", _hoisted_18$2, "\"" + toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "hyperlinkModified" ? (openBlock(), createElementBlock("div", _hoisted_19$1, [_cache[3] || (_cache[3] = createElementVNode("span", { class: "change-type" }, "Changed hyperlink to ", -1)), createElementVNode("span", _hoisted_20$1, "\"" + toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "paragraphSplit" ? (openBlock(), createElementBlock("div", _hoisted_21$1, [..._cache[4] || (_cache[4] = [createElementVNode("span", { class: "change-type" }, "Added new line", -1)])])) : comment.trackedChangeDisplayType === "tableInsert" ? (openBlock(), createElementBlock("div", _hoisted_22$1, [..._cache[5] || (_cache[5] = [createElementVNode("span", { class: "change-type" }, "Added table", -1)])])) : comment.trackedChangeDisplayType === "tableDelete" ? (openBlock(), createElementBlock("div", _hoisted_23$1, [..._cache[6] || (_cache[6] = [createElementVNode("span", { class: "change-type" }, "Deleted table", -1)])])) : comment.trackedChangeType === "trackFormat" ? (openBlock(), createElementBlock("div", _hoisted_24, [_cache[7] || (_cache[7] = createElementVNode("span", { class: "change-type" }, "Format: ", -1)), createElementVNode("span", _hoisted_25, toDisplayString(comment.trackedChangeText), 1)])) : comment.trackedChangeType === "both" ? (openBlock(), createElementBlock("div", _hoisted_26, [
14580
+ }), 128))])) : createCommentVNode("", true)])) : comment.trackedChangeDisplayType === "hyperlinkAdded" ? (openBlock(), createElementBlock("div", _hoisted_19$1, [_cache[2] || (_cache[2] = createElementVNode("span", { class: "change-type" }, "Added hyperlink ", -1)), createElementVNode("span", _hoisted_20$1, "\"" + toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "hyperlinkModified" ? (openBlock(), createElementBlock("div", _hoisted_21$1, [_cache[3] || (_cache[3] = createElementVNode("span", { class: "change-type" }, "Changed hyperlink to ", -1)), createElementVNode("span", _hoisted_22$1, "\"" + toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "paragraphSplit" ? (openBlock(), createElementBlock("div", _hoisted_23$1, [..._cache[4] || (_cache[4] = [createElementVNode("span", { class: "change-type" }, "Added new line", -1)])])) : comment.trackedChangeDisplayType === "tableInsert" ? (openBlock(), createElementBlock("div", _hoisted_24, [..._cache[5] || (_cache[5] = [createElementVNode("span", { class: "change-type" }, "Added table", -1)])])) : comment.trackedChangeDisplayType === "tableDelete" ? (openBlock(), createElementBlock("div", _hoisted_25, [..._cache[6] || (_cache[6] = [createElementVNode("span", { class: "change-type" }, "Deleted table", -1)])])) : comment.trackedChangeType === "trackFormat" ? (openBlock(), createElementBlock("div", _hoisted_26, [_cache[7] || (_cache[7] = createElementVNode("span", { class: "change-type" }, "Format: ", -1)), createElementVNode("span", _hoisted_27, toDisplayString(comment.trackedChangeText), 1)])) : comment.trackedChangeType === "both" ? (openBlock(), createElementBlock("div", _hoisted_28, [
14485
14581
  _cache[8] || (_cache[8] = createElementVNode("span", { class: "change-type" }, "Replaced ", -1)),
14486
- createElementVNode("span", _hoisted_27, "\"" + toDisplayString(comment.deletedText) + "\"", 1),
14582
+ createElementVNode("span", _hoisted_29, "\"" + toDisplayString(comment.deletedText) + "\"", 1),
14487
14583
  _cache[9] || (_cache[9] = createElementVNode("span", { class: "change-type" }, " with ", -1)),
14488
- createElementVNode("span", _hoisted_28, "\"" + toDisplayString(comment.trackedChangeText) + "\"", 1)
14489
- ])) : comment.deletedText && comment.deletedText === "\n" ? (openBlock(), createElementBlock("div", _hoisted_29, [..._cache[10] || (_cache[10] = [createElementVNode("span", { class: "change-type" }, "Deleted line break", -1)])])) : comment.trackedChangeText && comment.trackedChangeText === "\n" ? (openBlock(), createElementBlock("div", _hoisted_30, [..._cache[11] || (_cache[11] = [createElementVNode("span", { class: "change-type" }, "Added line break", -1)])])) : comment.deletedText ? (openBlock(), createElementBlock("div", _hoisted_31, [_cache[12] || (_cache[12] = createElementVNode("span", { class: "change-type" }, "Deleted ", -1)), createElementVNode("span", _hoisted_32, "\"" + toDisplayString(comment.deletedText) + "\"", 1)])) : comment.trackedChangeText ? (openBlock(), createElementBlock("div", _hoisted_33, [_cache[13] || (_cache[13] = createElementVNode("span", { class: "change-type" }, "Added ", -1)), createElementVNode("span", _hoisted_34, "\"" + toDisplayString(comment.trackedChangeText) + "\"", 1)])) : createCommentVNode("", true), comment.trackedChangeImagePreview?.src ? (openBlock(), createElementBlock("div", {
14584
+ createElementVNode("span", _hoisted_30, "\"" + toDisplayString(comment.trackedChangeText) + "\"", 1)
14585
+ ])) : comment.deletedText && comment.deletedText === "\n" ? (openBlock(), createElementBlock("div", _hoisted_31, [..._cache[10] || (_cache[10] = [createElementVNode("span", { class: "change-type" }, "Deleted line break", -1)])])) : comment.trackedChangeText && comment.trackedChangeText === "\n" ? (openBlock(), createElementBlock("div", _hoisted_32, [..._cache[11] || (_cache[11] = [createElementVNode("span", { class: "change-type" }, "Added line break", -1)])])) : comment.deletedText ? (openBlock(), createElementBlock("div", _hoisted_33, [_cache[12] || (_cache[12] = createElementVNode("span", { class: "change-type" }, "Deleted ", -1)), createElementVNode("span", _hoisted_34, "\"" + toDisplayString(comment.deletedText) + "\"", 1)])) : comment.trackedChangeText ? (openBlock(), createElementBlock("div", _hoisted_35, [_cache[13] || (_cache[13] = createElementVNode("span", { class: "change-type" }, "Added ", -1)), createElementVNode("span", _hoisted_36, "\"" + toDisplayString(comment.trackedChangeText) + "\"", 1)])) : createCommentVNode("", true), comment.trackedChangeImagePreview?.src ? (openBlock(), createElementBlock("div", {
14490
14586
  key: 12,
14491
14587
  class: "tracked-change-image-preview",
14492
14588
  "data-track-change-image-preview-role": comment.trackedChangeImagePreview.role ?? void 0
@@ -14497,7 +14593,7 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14497
14593
  style: normalizeStyle(trackedChangeImagePreviewStyle(comment.trackedChangeImagePreview)),
14498
14594
  loading: "lazy",
14499
14595
  decoding: "async"
14500
- }, null, 12, _hoisted_36)], 8, _hoisted_35)) : createCommentVNode("", true)], 10, _hoisted_10$3),
14596
+ }, null, 12, _hoisted_38)], 8, _hoisted_37)) : createCommentVNode("", true)], 10, _hoisted_12$2),
14501
14597
  shouldTruncate.value && isTextOverflowing.value && index === 0 ? (openBlock(), createElementBlock("div", {
14502
14598
  key: 0,
14503
14599
  class: "show-more-toggle",
@@ -14509,29 +14605,29 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14509
14605
  onClick: withModifiers(toggleTruncation, ["stop", "prevent"])
14510
14606
  }, " Show less ")) : createCommentVNode("", true)
14511
14607
  ])) : createCommentVNode("", true),
14512
- !comment.trackedChange ? (openBlock(), createElementBlock("div", _hoisted_37, [
14608
+ !comment.trackedChange ? (openBlock(), createElementBlock("div", _hoisted_39, [
14513
14609
  !unref(isDebugging) && !isEditingThisComment.value(comment) ? (openBlock(), createElementBlock("div", {
14514
14610
  key: 0,
14515
14611
  class: normalizeClass(["comment", index === 0 ? bodyOverflowClass.value : void 0]),
14516
14612
  ref_for: true,
14517
14613
  ref: index === 0 ? setParentBodyRef : void 0,
14518
14614
  innerHTML: renderedCommentTexts.value.get(comment.commentId)
14519
- }, null, 10, _hoisted_38)) : unref(isDebugging) && !isEditingThisComment.value(comment) ? (openBlock(), createElementBlock("div", _hoisted_39, toDisplayString(unref(editorCommentPositions)[comment.importedId !== void 0 ? comment.importedId : comment.commentId]?.bounds), 1)) : (openBlock(), createElementBlock("div", _hoisted_40, [createElementVNode("div", _hoisted_41, [createVNode(CommentInput_default, {
14615
+ }, null, 10, _hoisted_40)) : unref(isDebugging) && !isEditingThisComment.value(comment) ? (openBlock(), createElementBlock("div", _hoisted_41, toDisplayString(unref(editorCommentPositions)[comment.importedId !== void 0 ? comment.importedId : comment.commentId]?.bounds), 1)) : (openBlock(), createElementBlock("div", _hoisted_42, [createElementVNode("div", _hoisted_43, [createVNode(CommentInput_default, {
14520
14616
  ref_for: true,
14521
14617
  ref: setEditCommentInputRef(comment.commentId),
14522
14618
  users: [],
14523
14619
  config: unref(getConfig),
14524
14620
  "include-header": false,
14525
14621
  comment
14526
- }, null, 8, ["config", "comment"])]), createElementVNode("div", _hoisted_42, [createElementVNode("button", {
14622
+ }, null, 8, ["config", "comment"])]), createElementVNode("div", _hoisted_44, [createElementVNode("button", {
14527
14623
  class: "sd-button reply-btn-cancel",
14528
14624
  onClick: withModifiers(($event) => handleCancel(comment), ["stop", "prevent"])
14529
- }, "Cancel", 8, _hoisted_43), createElementVNode("button", {
14625
+ }, "Cancel", 8, _hoisted_45), createElementVNode("button", {
14530
14626
  class: normalizeClass(["sd-button primary reply-btn-primary", { "sd-is-disabled": !hasTextContent.value || isV2WriteDisabled.value }]),
14531
14627
  onClick: withModifiers(($event) => handleCommentUpdate(comment), ["stop", "prevent"]),
14532
14628
  disabled: !hasTextContent.value || isV2WriteDisabled.value,
14533
14629
  "data-disabled-reason": isV2WriteDisabled.value ? v2WriteCapability.value?.reason ?? null : null
14534
- }, " Update ", 10, _hoisted_44)])])),
14630
+ }, " Update ", 10, _hoisted_46)])])),
14535
14631
  shouldTruncate.value && isTextOverflowing.value && index === 0 && !isEditingThisComment.value(comment) ? (openBlock(), createElementBlock("div", {
14536
14632
  key: 3,
14537
14633
  class: "show-more-toggle",
@@ -14546,29 +14642,29 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14546
14642
  shouldCollapseThread.value && index === 0 ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [_cache[14] || (_cache[14] = createElementVNode("div", { class: "comment-separator" }, null, -1)), createElementVNode("div", {
14547
14643
  class: "collapsed-replies",
14548
14644
  onClick: withModifiers(expandThread, ["stop", "prevent"])
14549
- }, [createElementVNode("div", _hoisted_45, [(openBlock(true), createElementBlock(Fragment, null, renderList(collapsedReplyAuthors.value, (author) => {
14645
+ }, [createElementVNode("div", _hoisted_47, [(openBlock(true), createElementBlock(Fragment, null, renderList(collapsedReplyAuthors.value, (author) => {
14550
14646
  return openBlock(), createBlock(Avatar_default, {
14551
14647
  key: author.email || author.name,
14552
14648
  user: author,
14553
14649
  class: "mini-avatar"
14554
14650
  }, null, 8, ["user"]);
14555
14651
  }), 128))]), createElementVNode("span", null, toDisplayString(collapsedReplyCount.value) + " more " + toDisplayString(collapsedReplyCount.value === 1 ? "reply" : "replies"), 1)])], 64)) : createCommentVNode("", true),
14556
- showSeparator.value(index) ? (openBlock(), createElementBlock("div", _hoisted_46)) : createCommentVNode("", true)
14652
+ showSeparator.value(index) ? (openBlock(), createElementBlock("div", _hoisted_48)) : createCommentVNode("", true)
14557
14653
  ]);
14558
14654
  }), 128)),
14559
- trackedChangeDecisionFailure.value ? (openBlock(), createElementBlock("div", _hoisted_47, [createElementVNode("span", _hoisted_48, toDisplayString(trackedChangeDecisionFailureMessage.value), 1), createElementVNode("button", {
14655
+ trackedChangeDecisionFailure.value ? (openBlock(), createElementBlock("div", _hoisted_49, [createElementVNode("span", _hoisted_50, toDisplayString(trackedChangeDecisionFailureMessage.value), 1), createElementVNode("button", {
14560
14656
  type: "button",
14561
14657
  class: "sd-button tracked-change-decision-alert__retry",
14562
14658
  onClick: withModifiers(retryTrackedChangeDecision, ["stop", "prevent"])
14563
14659
  }, " Retry ")])) : createCommentVNode("", true),
14564
- showInputSection.value && !unref(getConfig).readOnly ? (openBlock(), createElementBlock(Fragment, { key: 3 }, [!isReplying.value ? (openBlock(), createElementBlock("button", {
14660
+ showInputSection.value && !unref(getConfig).readOnly ? (openBlock(), createElementBlock(Fragment, { key: 4 }, [!isReplying.value ? (openBlock(), createElementBlock("button", {
14565
14661
  key: 0,
14566
14662
  type: "button",
14567
14663
  class: normalizeClass(["reply-pill", { "sd-is-disabled": isV2WriteDisabled.value }]),
14568
14664
  onClick: withModifiers(startReply, ["stop", "prevent"]),
14569
14665
  disabled: isV2WriteDisabled.value,
14570
14666
  "data-disabled-reason": isV2WriteDisabled.value ? v2WriteCapability.value?.reason ?? null : null
14571
- }, " Reply or add others with @ ", 10, _hoisted_49)) : (openBlock(), createElementBlock("div", _hoisted_50, [createElementVNode("div", _hoisted_51, [createVNode(CommentInput_default, {
14667
+ }, " Reply or add others with @ ", 10, _hoisted_51)) : (openBlock(), createElementBlock("div", _hoisted_52, [createElementVNode("div", _hoisted_53, [createVNode(CommentInput_default, {
14572
14668
  ref_key: "commentInput",
14573
14669
  ref: commentInput,
14574
14670
  users: usersFiltered.value,
@@ -14579,7 +14675,7 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14579
14675
  "users",
14580
14676
  "config",
14581
14677
  "comment"
14582
- ])]), createElementVNode("div", _hoisted_52, [createElementVNode("button", {
14678
+ ])]), createElementVNode("div", _hoisted_54, [createElementVNode("button", {
14583
14679
  class: "sd-button reply-btn-cancel",
14584
14680
  onClick: withModifiers(handleCancel, ["stop", "prevent"])
14585
14681
  }, "Cancel"), createElementVNode("button", {
@@ -14587,11 +14683,11 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14587
14683
  onClick: withModifiers(handleAddComment, ["stop", "prevent"]),
14588
14684
  disabled: !hasTextContent.value || isV2WriteDisabled.value || isSubmittingReply.value,
14589
14685
  "data-disabled-reason": v2ReplyDisabledReason.value
14590
- }, " Reply ", 10, _hoisted_53)])]))], 64)) : createCommentVNode("", true)
14686
+ }, " Reply ", 10, _hoisted_55)])]))], 64)) : createCommentVNode("", true)
14591
14687
  ], 64))], 14, _hoisted_1$26)), [[_directive_click_outside, handleClickOutside]]);
14592
14688
  };
14593
14689
  }
14594
- }, [["__scopeId", "data-v-939045c1"]]);
14690
+ }, [["__scopeId", "data-v-f8b79c74"]]);
14595
14691
  //#endregion
14596
14692
  //#region src/components/CommentsLayer/commentsList/ReviewDirectoryListItem.vue
14597
14693
  var _hoisted_1$25 = [
@@ -15314,6 +15410,80 @@ var composeAuthorColorResolver = (config) => {
15314
15410
  };
15315
15411
  };
15316
15412
  //#endregion
15413
+ //#region ../document-api/src/errors.ts
15414
+ /**
15415
+ * Structured validation error thrown by document-api execute* functions.
15416
+ *
15417
+ * Consumers should prefer checking `error.code` over `instanceof` for resilience
15418
+ * across package boundaries and bundling scenarios.
15419
+ */
15420
+ var DocumentApiValidationError = class DocumentApiValidationError extends Error {
15421
+ constructor(code, message, details) {
15422
+ super(message);
15423
+ this.name = "DocumentApiValidationError";
15424
+ this.code = code;
15425
+ this.details = details;
15426
+ Object.setPrototypeOf(this, DocumentApiValidationError.prototype);
15427
+ }
15428
+ };
15429
+ //#endregion
15430
+ //#region ../document-api/src/export/export.types.ts
15431
+ /** Canonical tracked-change export modes accepted by every public export surface. */
15432
+ var SD_EXPORT_MODES = [
15433
+ "review-preserving",
15434
+ "final",
15435
+ "original"
15436
+ ];
15437
+ /** Default mode for modeful DOCX export. */
15438
+ var DEFAULT_SD_EXPORT_MODE = "review-preserving";
15439
+ var SD_COMMENT_EXPORT_POLICIES = [
15440
+ "preserve",
15441
+ "resolve",
15442
+ "remove"
15443
+ ];
15444
+ var SD_CONTENT_CONTROL_EXPORT_POLICIES = ["preserve", "flatten"];
15445
+ //#endregion
15446
+ //#region ../document-api/src/export/export.ts
15447
+ /**
15448
+ * Export namespace: engine-agnostic public API and adapter contract.
15449
+ *
15450
+ * Validates the requested mode at the public boundary so an invalid mode fails
15451
+ * closed with `INVALID_INPUT` before any document work happens, then delegates
15452
+ * byte production and degradation reporting to the engine adapter.
15453
+ */
15454
+ function resolveMode$1(input) {
15455
+ if (input != null && !isRecord(input)) throw new DocumentApiValidationError("INVALID_INPUT", "export.toDocx input must be an object.");
15456
+ const raw = input?.mode;
15457
+ if (raw === void 0) return DEFAULT_SD_EXPORT_MODE;
15458
+ if (typeof raw !== "string" || !SD_EXPORT_MODES.includes(raw)) throw new DocumentApiValidationError("INVALID_INPUT", `export.toDocx mode must be one of: ${SD_EXPORT_MODES.join(", ")}.`, {
15459
+ mode: raw,
15460
+ allowedModes: [...SD_EXPORT_MODES]
15461
+ });
15462
+ return raw;
15463
+ }
15464
+ function resolveDocxExportPolicies(input = {}) {
15465
+ if (!isRecord(input)) throw new DocumentApiValidationError("INVALID_INPUT", "DOCX export input must be an object.");
15466
+ const mode = resolveMode$1(input);
15467
+ const policies = input.policies;
15468
+ if (policies !== void 0 && !isRecord(policies)) throw new DocumentApiValidationError("INVALID_INPUT", "DOCX export policies must be an object.");
15469
+ const allowed = {
15470
+ trackedChanges: SD_EXPORT_MODES,
15471
+ comments: SD_COMMENT_EXPORT_POLICIES,
15472
+ contentControls: SD_CONTENT_CONTROL_EXPORT_POLICIES
15473
+ };
15474
+ for (const [key, value] of Object.entries(policies ?? {})) if (!Object.prototype.hasOwnProperty.call(allowed, key) || value !== void 0 && !allowed[key].includes(value)) throw new DocumentApiValidationError("INVALID_INPUT", `Unsupported DOCX export policy: ${key}.`, {
15475
+ policy: key,
15476
+ value
15477
+ });
15478
+ const requested = policies;
15479
+ if (input.mode !== void 0 && requested?.trackedChanges !== void 0 && mode !== requested.trackedChanges) throw new DocumentApiValidationError("INVALID_INPUT", "mode conflicts with policies.trackedChanges.");
15480
+ return {
15481
+ trackedChanges: requested?.trackedChanges ?? mode,
15482
+ comments: requested?.comments ?? "preserve",
15483
+ contentControls: requested?.contentControls ?? "preserve"
15484
+ };
15485
+ }
15486
+ //#endregion
15317
15487
  //#region ../document-api/src/permission-ranges/permission-ranges.ts
15318
15488
  function editorKey(editor) {
15319
15489
  return editor.id?.trim() ? editor.id : editor.email?.trim() || void 0;
@@ -20051,6 +20221,28 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getActivati
20051
20221
  };
20052
20222
  }
20053
20223
  //#endregion
20224
+ //#region src/core/helpers/resolve-docx-export.ts
20225
+ function resolveV2DocxExportOptions(options = {}) {
20226
+ const policies = resolveDocxExportPolicies({ policies: options.policies });
20227
+ if (options.isFinalDoc !== void 0) {
20228
+ if (typeof options.isFinalDoc !== "boolean") throw new DocumentApiValidationError("INVALID_INPUT", "isFinalDoc must be a boolean.");
20229
+ const legacy = options.isFinalDoc ? "final" : "review-preserving";
20230
+ if (options.policies?.trackedChanges !== void 0 && policies.trackedChanges !== legacy) throw new DocumentApiValidationError("INVALID_INPUT", "isFinalDoc conflicts with policies.trackedChanges.");
20231
+ policies.trackedChanges = legacy;
20232
+ }
20233
+ if (options.commentsType !== void 0) {
20234
+ if (options.commentsType !== "external" && options.commentsType !== "clean") throw new DocumentApiValidationError("INVALID_INPUT", "commentsType must be external or clean.");
20235
+ const legacy = options.commentsType === "clean" ? "remove" : "preserve";
20236
+ if (options.policies?.comments !== void 0 && policies.comments !== legacy) throw new DocumentApiValidationError("INVALID_INPUT", "commentsType conflicts with policies.comments.");
20237
+ policies.comments = legacy;
20238
+ }
20239
+ return {
20240
+ mode: policies.trackedChanges,
20241
+ commentExportMode: policies.comments === "remove" ? "strip" : policies.comments,
20242
+ contentControlExportMode: policies.contentControls
20243
+ };
20244
+ }
20245
+ //#endregion
20054
20246
  //#region src/core/editor-runtime/v2/v2-editor-runtime-adapter.ts
20055
20247
  var DEFAULT_V2_LEGACY_PROJECTION = Object.freeze({
20056
20248
  editorVersion: 2,
@@ -20690,7 +20882,7 @@ function createV2EditorRuntimeAdapter(options) {
20690
20882
  save: () => host.save(),
20691
20883
  exportDocx: (options) => host.save({
20692
20884
  format: "docx",
20693
- commentExportMode: options?.commentsType === "clean" ? "strip" : "preserve"
20885
+ ...resolveV2DocxExportOptions(options)
20694
20886
  }),
20695
20887
  async setZoom(percent) {
20696
20888
  const result = host.setZoom(percent);
@@ -22083,6 +22275,10 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
22083
22275
  return layers.value.getBoundingClientRect().top + top * zoom;
22084
22276
  };
22085
22277
  const handleCommentToolClick = async () => {
22278
+ if (isV2Mode.value) {
22279
+ cancelScheduledV2DomSelectionSync();
22280
+ if (applyCurrentV2DomSelection()?.ok === false) return;
22281
+ }
22086
22282
  if ((await showAddComment(proxy.$superdoc, getPendingCommentTargetClientY()))?.ok === false) return;
22087
22283
  if (!isV2Mode.value) return;
22088
22284
  const pendingPosition = buildV2PendingPositionEntry();
@@ -22355,10 +22551,9 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
22355
22551
  return host.save(saveOptions);
22356
22552
  });
22357
22553
  const exportV2Docx = async (options = {}) => {
22358
- const commentExportMode = options?.commentsType === "clean" ? "strip" : "preserve";
22359
22554
  const bytes = await saveV2Bytes({
22360
22555
  format: "docx",
22361
- commentExportMode
22556
+ ...resolveV2DocxExportOptions(options)
22362
22557
  });
22363
22558
  return new Blob([bytes], { type: DOCX });
22364
22559
  };
@@ -22633,6 +22828,9 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
22633
22828
  subscribe: (listener) => v2ReviewWindowController.subscribe?.(listener) ?? (() => void 0)
22634
22829
  },
22635
22830
  extensions: createV2ExtensionsFacet(host),
22831
+ get visuals() {
22832
+ return typeof host?.getHostVisuals === "function" ? host.getHostVisuals() : null;
22833
+ },
22636
22834
  fonts: fonts ?? host?.getFontRuntime?.() ?? null,
22637
22835
  /**
22638
22836
  * The v2 active-editor facade explicitly does NOT carry v1 commands /
@@ -22798,7 +22996,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
22798
22996
  const result = handles?.selection?.applyDomSelection?.(selection);
22799
22997
  if (!result?.ok || result.mode !== "range") {
22800
22998
  clearV2SelectionToolbarState();
22801
- return;
22999
+ return { ok: false };
22802
23000
  }
22803
23001
  v2DomMirroredRange.value = true;
22804
23002
  v2HasRangeSelection.value = true;
@@ -23260,7 +23458,8 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
23260
23458
  return;
23261
23459
  }
23262
23460
  const collaborationException = createCollaborationException(reason, documentId);
23263
- const message = collaborationException?.error.message ?? getV2EditorFailureMessage(reason);
23461
+ const baseMessage = collaborationException?.error.message ?? getV2EditorFailureMessage(reason);
23462
+ const message = reason === "collaboration-config-invalid" && detail ? `${baseMessage} ${detail}` : baseMessage;
23264
23463
  const workerFailure = payload?.workerFailure && typeof payload.workerFailure === "object" ? payload.workerFailure : null;
23265
23464
  setV2EditorFailure(documentId, {
23266
23465
  reason,
@@ -23276,7 +23475,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
23276
23475
  };
23277
23476
  if (reason === "collaboration-v1-config-unsupported" || reason === "collaboration-room-format-unsupported" || reason === "collaboration-room-format-conflict" || reason === "collaboration-room-corrupt" || reason === "collaboration-v2-room-missing" || reason === "collaboration-v2-room-already-exists" || reason === "collaboration-v2-room-initializing" || reason === "collaboration-v2-room-bootstrap-stalled" || reason === "collaboration-open-intent-invalid" || reason === "collaboration-config-invalid") console.warn(`[SuperDoc] ${message}`, logContext);
23278
23477
  else console.error(`[SuperDoc] ${message}`, logContext);
23279
- proxy.$superdoc.emit("exception", collaborationException ?? {
23478
+ proxy.$superdoc.emit("exception", collaborationException && reason !== "collaboration-config-invalid" ? collaborationException : {
23280
23479
  error: new Error(message),
23281
23480
  code: reason,
23282
23481
  ...documentId ? { documentId } : {},
@@ -24504,7 +24703,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
24504
24703
  ], 46, _hoisted_1$17);
24505
24704
  };
24506
24705
  }
24507
- }, [["__scopeId", "data-v-143de6c8"]]);
24706
+ }, [["__scopeId", "data-v-0f22e103"]]);
24508
24707
  //#endregion
24509
24708
  //#region src/core/create-app.js
24510
24709
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -46201,7 +46400,7 @@ var SuperDoc = class extends import_eventemitter3.default {
46201
46400
  }
46202
46401
  this.userColorMap = /* @__PURE__ */ new Map();
46203
46402
  this.colorIndex = 0;
46204
- this.version = "2.28.0-next.5";
46403
+ this.version = "2.28.0-next.7";
46205
46404
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
46206
46405
  this.superdocId = config.superdocId || v4();
46207
46406
  this.colors = this.config.colors ?? [];
@@ -46917,7 +47116,8 @@ var SuperDoc = class extends import_eventemitter3.default {
46917
47116
  ...syncTimeoutOption,
46918
47117
  ...target.serverUrl ? { serverUrl: target.serverUrl } : {},
46919
47118
  ...target.params ? { params: target.params } : {},
46920
- ...target.token ? { token: target.token } : {}
47119
+ ...target.token ? { token: target.token } : {},
47120
+ ...target.retry !== void 0 ? { retry: target.retry } : {}
46921
47121
  };
46922
47122
  return {
46923
47123
  providerType: "y-websocket",
@@ -48154,12 +48354,13 @@ var SuperDoc = class extends import_eventemitter3.default {
48154
48354
  * Export the superdoc to a file
48155
48355
  * @param params - Export configuration
48156
48356
  */
48157
- async export({ exportType = ["docx"], commentsType = "external", exportedName, additionalFiles = [], additionalFileNames = [], isFinalDoc = false, triggerDownload = true, fieldsHighlightColor = null } = {}) {
48357
+ async export({ exportType = ["docx"], commentsType, exportedName, additionalFiles = [], additionalFileNames = [], isFinalDoc, policies, triggerDownload = true, fieldsHighlightColor = null } = {}) {
48158
48358
  if (!Array.isArray(exportType) || exportType.length !== 1 || exportType[0] !== "docx") throw new TypeError("SuperDoc.export() only supports exportType: [\"docx\"].");
48159
48359
  const baseFileName = exportedName ? cleanName(exportedName) : cleanName(this.config.title);
48160
48360
  const docxFiles = await this.exportEditorsToDOCX({
48161
48361
  commentsType,
48162
48362
  isFinalDoc,
48363
+ policies,
48163
48364
  fieldsHighlightColor
48164
48365
  });
48165
48366
  const blobsToZip = [...additionalFiles];
@@ -48245,7 +48446,12 @@ var SuperDoc = class extends import_eventemitter3.default {
48245
48446
  * Export editors to DOCX format.
48246
48447
  * @param [options]
48247
48448
  */
48248
- async exportEditorsToDOCX({ commentsType, isFinalDoc, fieldsHighlightColor } = {}) {
48449
+ async exportEditorsToDOCX({ commentsType, isFinalDoc, policies, fieldsHighlightColor } = {}) {
48450
+ if (policies !== void 0) resolveV2DocxExportOptions({
48451
+ policies,
48452
+ commentsType,
48453
+ isFinalDoc
48454
+ });
48249
48455
  const uiStoreHydrated = this.config?.modules?.comments !== false;
48250
48456
  let legacyComments;
48251
48457
  let legacyCommentsComputed = false;
@@ -48265,7 +48471,13 @@ var SuperDoc = class extends import_eventemitter3.default {
48265
48471
  };
48266
48472
  this.on("exception", rememberBridgedExportError);
48267
48473
  try {
48268
- const docxPromises = this.#requireSuperdocStore("exportEditorsToDOCX").documents.map(async (doc) => {
48474
+ const documents = this.#requireSuperdocStore("exportEditorsToDOCX").documents;
48475
+ if (policies !== void 0 && documents.some((doc) => {
48476
+ if (doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return false;
48477
+ const editor = doc.getEditor?.();
48478
+ return editor?.editorVersion !== 2 || typeof editor.exportDocx !== "function";
48479
+ })) throw new Error("Independent DOCX export policies require a mounted V2 exporter for every document.");
48480
+ const docxPromises = documents.map(async (doc) => {
48269
48481
  if (!doc || doc.type !== "application/vnd.openxmlformats-officedocument.wordprocessingml.document") return null;
48270
48482
  const editor = typeof doc.getEditor === "function" ? doc.getEditor() : null;
48271
48483
  const fallbackDocx = () => {
@@ -48282,6 +48494,7 @@ var SuperDoc = class extends import_eventemitter3.default {
48282
48494
  const exported = await editor.exportDocx(isV2Editor ? {
48283
48495
  isFinalDoc,
48284
48496
  commentsType,
48497
+ policies,
48285
48498
  fieldsHighlightColor
48286
48499
  } : {
48287
48500
  isFinalDoc,
@@ -48610,4 +48823,8 @@ function defineSuperDocExtension(extension) {
48610
48823
  return extension;
48611
48824
  }
48612
48825
  //#endregion
48613
- export { blank_default as BlankDOCX, DOCX, DocumentLoadError, HTML, PDF, SuperDoc, buildTheme, compareVersions, createTheme, defineSuperDocExtension, getFileObject, listPermissionRangeEditors, resolvePermissionRangeEditor };
48826
+ //#region src/public/index.ts
48827
+ /** URL to the blank DOCX template. */
48828
+ var BlankDOCX = blank_default;
48829
+ //#endregion
48830
+ export { BlankDOCX, DOCX, DocumentLoadError, HTML, PDF, SuperDoc, buildTheme, compareVersions, createTheme, defineSuperDocExtension, getFileObject, listPermissionRangeEditors, resolvePermissionRangeEditor };