superdoc 2.28.0-next.9 → 2.29.0-next.1

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 (94) hide show
  1. package/dist/chunks/{FindReplaceSurface-8V8AjgR4.cjs → FindReplaceSurface-BRs3JrCq.cjs} +1 -1
  2. package/dist/chunks/{FindReplaceSurface-RUiTFDt3.es.js → FindReplaceSurface-Dm043CZP.es.js} +1 -1
  3. package/dist/chunks/{PasswordPromptSurface-B5DHV6qr.cjs → PasswordPromptSurface-BpqP4pUa.cjs} +1 -1
  4. package/dist/chunks/{PasswordPromptSurface-BDpxqdzp.es.js → PasswordPromptSurface-DGjmN7A-.es.js} +1 -1
  5. package/dist/chunks/{PdfViewer-DjdsIh6n.es.js → PdfViewer-D4lVeOJu.es.js} +4 -3
  6. package/dist/chunks/{PdfViewer-omriDChK.cjs → PdfViewer-boENOZdF.cjs} +4 -3
  7. package/dist/chunks/{_plugin-vue_export-helper-BUdjGKyl.cjs → _plugin-vue_export-helper-6MBoygIY.cjs} +9 -0
  8. package/dist/chunks/{_plugin-vue_export-helper-7ZiLY07t.es.js → _plugin-vue_export-helper-CsJQtMvr.es.js} +4 -1
  9. package/dist/chunks/{create-super-doc-ui-B4c55pFy.cjs → create-super-doc-ui-0OA8hCNb.cjs} +390 -44
  10. package/dist/chunks/{create-super-doc-ui-C4Ka5Ph3.es.js → create-super-doc-ui-Duf65d0b.es.js} +357 -41
  11. package/dist/chunks/is-finite-number-BEXgTRgc.cjs +11 -0
  12. package/dist/chunks/is-finite-number-BpL4F38c.es.js +6 -0
  13. package/dist/collaboration-upgrade-engine.cjs +1 -1
  14. package/dist/collaboration-upgrade-engine.es.js +1 -1
  15. package/dist/document-api/src/capabilities/html-markdown-support.d.ts +3 -3
  16. package/dist/document-api/src/contract/operation-definitions.d.ts +2 -2
  17. package/dist/document-api/src/index.d.ts +1 -1
  18. package/dist/document-api/src/lists/lists.d.ts +79 -79
  19. package/dist/document-api/src/lists/lists.types.d.ts +1 -0
  20. package/dist/document-api/src/sections/sections.types.d.ts +5 -1
  21. package/dist/document-api/src/types/clipboard.d.ts +5 -1
  22. package/dist/document-api/src/types/receipt.d.ts +2 -1
  23. package/dist/document-api/src/write/write.d.ts +10 -9
  24. package/dist/layout-engine/contracts/src/index.d.ts +5 -1
  25. package/dist/layout-engine/contracts/src/run-helpers.d.ts +1 -0
  26. package/dist/layout-engine/layout-bridge/src/index.d.ts +1 -0
  27. package/dist/layout-engine/layout-bridge/src/place-inline-drawings.d.ts +9 -0
  28. package/dist/layout-engine/layout-engine/src/layout-drawing.d.ts +2 -1
  29. package/dist/layout-engine/layout-engine/src/paginator.d.ts +1 -0
  30. package/dist/layout-engine/painters/dom/src/page-content.d.ts +1 -1
  31. package/dist/layout-engine/painters/dom/src/persistent-page-surface.d.ts +2 -0
  32. package/dist/layout-engine/style-engine/src/ooxml/index.d.ts +1 -1
  33. package/dist/public/ui-react.cjs +1 -1
  34. package/dist/public/ui-react.es.js +1 -1
  35. package/dist/public/ui-vue.cjs +1 -1
  36. package/dist/public/ui-vue.es.js +1 -1
  37. package/dist/public/ui.cjs +3 -2
  38. package/dist/public/ui.es.js +3 -2
  39. package/dist/shared/font-system/src/resolver.d.ts +3 -3
  40. package/dist/style.css +1 -1
  41. package/dist/style.layered.css +1 -1
  42. package/dist/superdoc/src/SuperDoc.vue.d.ts +5 -3
  43. package/dist/superdoc/src/components/CommentsLayer/CommentDialog.vue.d.ts +1670 -24
  44. package/dist/superdoc/src/components/CommentsLayer/CommentHeader.vue.d.ts +2 -2
  45. package/dist/superdoc/src/components/CommentsLayer/CommentInput.vue.d.ts +2 -2
  46. package/dist/superdoc/src/components/CommentsLayer/FloatingComments.vue.d.ts +24 -0
  47. package/dist/superdoc/src/components/CommentsLayer/PdfCommentsLayer.vue.d.ts +4 -0
  48. package/dist/superdoc/src/components/general/Avatar.vue.d.ts +7 -0
  49. package/dist/superdoc/src/components/surfaces/SurfaceDialog.vue.d.ts +27 -9
  50. package/dist/superdoc/src/components/surfaces/SurfaceExternalMount.vue.d.ts +53 -16
  51. package/dist/superdoc/src/composables/use-high-contrast-mode.d.ts +8 -4
  52. package/dist/superdoc/src/composables/use-link-popover.d.ts +3 -3
  53. package/dist/superdoc/src/composables/use-superdoc-instance.d.ts +10 -0
  54. package/dist/superdoc/src/core/SuperDoc.d.ts +2 -6
  55. package/dist/superdoc/src/core/collaboration/helpers.d.ts +0 -5
  56. package/dist/superdoc/src/core/collaboration/permissions.d.ts +1 -0
  57. package/dist/superdoc/src/core/collaboration/resolve-v2-collaboration-target.d.ts +2 -1
  58. package/dist/superdoc/src/core/create-app.d.ts +2 -6
  59. package/dist/superdoc/src/core/editor-runtime/types.d.ts +2 -0
  60. package/dist/superdoc/src/core/editor-runtime/v2/v2-editor-runtime-adapter.d.ts +2 -0
  61. package/dist/superdoc/src/core/types/index.d.ts +10 -4
  62. package/dist/superdoc/src/core/v2-integration/internal-vue-runtime.d.ts +1 -0
  63. package/dist/superdoc/src/core/v2-integration/v2-integration.d.ts +104 -84
  64. package/dist/superdoc/src/helpers/is-finite-number.d.ts +1 -0
  65. package/dist/superdoc/src/helpers/v2-review-mutation-impact.d.ts +2 -0
  66. package/dist/superdoc/src/internal/diagnostics/diagnostic-dedupe.d.ts +2 -2
  67. package/dist/superdoc/src/internal/diagnostics/translate-diagnostic.d.ts +5 -0
  68. package/dist/superdoc/src/internal/toolbar/built-in/AIWriter.vue.d.ts +2 -2
  69. package/dist/superdoc/src/internal/toolbar/built-in/LinkInput.vue.d.ts +181 -36
  70. package/dist/superdoc/src/internal/toolbar/built-in/LinkedStyle.vue.d.ts +39 -10
  71. package/dist/superdoc/src/internal/toolbar/built-in/PageNumberMenu.vue.d.ts +133 -22
  72. package/dist/superdoc/src/internal/toolbar/built-in/SdTooltip.vue.d.ts +62 -23
  73. package/dist/superdoc/src/internal/toolbar/built-in/ToolbarButton.vue.d.ts +101 -16
  74. package/dist/superdoc/src/internal/toolbar/built-in/ToolbarButtonIcon.vue.d.ts +31 -10
  75. package/dist/superdoc/src/internal/toolbar/built-in/ToolbarComboBox.vue.d.ts +82 -11
  76. package/dist/superdoc/src/internal/toolbar/built-in/ToolbarDropdown.vue.d.ts +122 -33
  77. package/dist/superdoc/src/internal/toolbar/built-in/constants.d.ts +0 -48
  78. package/dist/superdoc/src/internal/toolbar/built-in/use-toolbar-item.d.ts +0 -1
  79. package/dist/superdoc/src/internal/toolbar/built-in-toolbar.d.ts +4 -1
  80. package/dist/superdoc/src/internal/toolbar/compatibility-catalog.d.ts +16 -0
  81. package/dist/superdoc/src/public/ui/types.d.ts +39 -1
  82. package/dist/superdoc/src/public/ui.d.cts +12 -0
  83. package/dist/superdoc/src/public/ui.d.ts +1 -1
  84. package/dist/superdoc/src/stores/comments-store.d.ts +158 -125
  85. package/dist/superdoc/src/stores/superdoc-store.d.ts +475 -376
  86. package/dist/superdoc.cjs +561 -1843
  87. package/dist/superdoc.es.js +766 -13144
  88. package/dist-cdn/style.layered.css +1 -1
  89. package/dist-cdn/superdoc.min.css +1 -1
  90. package/dist-cdn/superdoc.min.js +42 -42
  91. package/package.json +4 -3
  92. package/dist/superdoc/src/core/collaboration/collaboration.d.ts +0 -18
  93. package/dist/superdoc/src/helpers/group-changes.d.ts +0 -1
  94. package/dist/superdoc/src/internal/toolbar/built-in/OverflowMenu.vue.d.ts +0 -104
@@ -1,4 +1,5 @@
1
- import { D as normalizeClass, E as nextTick, F as openBlock, J as unref, N as onMounted, R as ref, U as shallowRef, W as toDisplayString, a as computed, c as createCommentVNode, et as watch, f as createTextVNode, h as defineComponent, it as withModifiers, j as onBeforeUnmount, l as createElementBlock, n as Fragment, t as _plugin_vue_export_helper_default, u as createElementVNode, z as renderList } from "./_plugin-vue_export-helper-7ZiLY07t.es.js";
1
+ import { B as renderList, D as normalizeClass, E as nextTick, F as openBlock, G as toDisplayString, N as onMounted, W as shallowRef, Y as unref, a as computed, at as withModifiers, c as createCommentVNode, f as createTextVNode, h as defineComponent, j as onBeforeUnmount, l as createElementBlock, n as Fragment, t as _plugin_vue_export_helper_default, tt as watch, u as createElementVNode, z as ref } from "./_plugin-vue_export-helper-CsJQtMvr.es.js";
2
+ import { t as isFiniteNumber } from "./is-finite-number-BpL4F38c.es.js";
2
3
  //#region src/internal/diagnostics/workflow-recording.ts
3
4
  var fields$1 = /* @__PURE__ */ new Set([
4
5
  "documentId",
@@ -1087,6 +1088,172 @@ function isSyntheticTrackedChangeCommentLaneItem(item) {
1087
1088
  return typeof itemId === "string" && itemId.startsWith(TRACKED_CHANGE_COMMENT_LANE_ID_PREFIX);
1088
1089
  }
1089
1090
  //#endregion
1091
+ //#region src/helpers/object-guards.js
1092
+ /**
1093
+ * @param {unknown} value
1094
+ * @returns {value is Record<string, unknown>}
1095
+ */
1096
+ function isPlainObject(value) {
1097
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1098
+ }
1099
+ //#endregion
1100
+ //#region src/core/collaboration/permissions.js
1101
+ var PERMISSIONS = Object.freeze({
1102
+ RESOLVE_OWN: "RESOLVE_OWN",
1103
+ RESOLVE_OTHER: "RESOLVE_OTHER",
1104
+ REJECT_OWN: "REJECT_OWN",
1105
+ REJECT_OTHER: "REJECT_OTHER",
1106
+ COMMENTS_OVERFLOW_OWN: "COMMENTS_OVERFLOW",
1107
+ COMMENTS_OVERFLOW_OTHER: "COMMENTS_OVERFLOW_OTHER",
1108
+ COMMENTS_DELETE_OWN: "COMMENTS_DELETE_OWN",
1109
+ COMMENTS_DELETE_OTHER: "COMMENTS_DELETE_OTHER",
1110
+ UPLOAD_VERSION: "UPLOAD_VERSION",
1111
+ VERSION_HISTORY: "VERSION_HISTORY"
1112
+ });
1113
+ var ROLES = Object.freeze({
1114
+ EDITOR: "editor",
1115
+ SUGGESTER: "suggester",
1116
+ VIEWER: "viewer"
1117
+ });
1118
+ var PERMISSION_MATRIX = Object.freeze({
1119
+ [PERMISSIONS.RESOLVE_OWN]: {
1120
+ internal: [ROLES.EDITOR],
1121
+ external: [ROLES.EDITOR]
1122
+ },
1123
+ [PERMISSIONS.RESOLVE_OTHER]: {
1124
+ internal: [ROLES.EDITOR],
1125
+ external: [ROLES.EDITOR]
1126
+ },
1127
+ [PERMISSIONS.REJECT_OWN]: {
1128
+ internal: [ROLES.EDITOR, ROLES.SUGGESTER],
1129
+ external: [ROLES.EDITOR, ROLES.SUGGESTER]
1130
+ },
1131
+ [PERMISSIONS.REJECT_OTHER]: {
1132
+ internal: [ROLES.EDITOR],
1133
+ external: [ROLES.EDITOR]
1134
+ },
1135
+ [PERMISSIONS.COMMENTS_OVERFLOW_OWN]: {
1136
+ internal: [ROLES.EDITOR, ROLES.SUGGESTER],
1137
+ external: [ROLES.EDITOR, ROLES.SUGGESTER]
1138
+ },
1139
+ [PERMISSIONS.COMMENTS_OVERFLOW_OTHER]: {
1140
+ internal: [ROLES.EDITOR],
1141
+ external: [ROLES.EDITOR]
1142
+ },
1143
+ [PERMISSIONS.COMMENTS_DELETE_OWN]: {
1144
+ internal: [ROLES.EDITOR, ROLES.SUGGESTER],
1145
+ external: [ROLES.EDITOR, ROLES.SUGGESTER]
1146
+ },
1147
+ [PERMISSIONS.COMMENTS_DELETE_OTHER]: {
1148
+ internal: [ROLES.EDITOR],
1149
+ external: [ROLES.EDITOR]
1150
+ },
1151
+ [PERMISSIONS.UPLOAD_VERSION]: {
1152
+ internal: [ROLES.EDITOR],
1153
+ external: []
1154
+ },
1155
+ [PERMISSIONS.VERSION_HISTORY]: {
1156
+ internal: [ROLES.EDITOR],
1157
+ external: []
1158
+ }
1159
+ });
1160
+ var pickResolver = (context = {}) => {
1161
+ if (typeof context.permissionResolver === "function") return context.permissionResolver;
1162
+ if (typeof context.superdoc?.config?.permissionResolver === "function") return context.superdoc.config.permissionResolver;
1163
+ const deprecatedResolver = context.superdoc?.config?.modules?.comments?.permissionResolver;
1164
+ if (typeof deprecatedResolver === "function") return deprecatedResolver;
1165
+ return null;
1166
+ };
1167
+ var BUILT_IN_PERMISSION_METHOD = Symbol.for("superdoc.internal.permission-method.builtin");
1168
+ var BUILT_IN_PERMISSION_RESOLVER = Symbol.for("superdoc.internal.permission-resolver.builtin");
1169
+ /** Create the shell's internal, live tracked-change permission shim. */
1170
+ var createTrackedChangePermissionResolver = (superdoc) => {
1171
+ const isBuiltInPolicy = () => superdoc.canPerformPermission?.[BUILT_IN_PERMISSION_METHOD] === true && pickResolver({ superdoc }) === null;
1172
+ const resolver = (payload = {}) => isBuiltInPolicy() ? defaultDecisionFor(payload.permission, superdoc.config.role, superdoc.config.isInternal) : superdoc.canPerformPermission({
1173
+ ...payload,
1174
+ role: superdoc.config.role,
1175
+ isInternal: superdoc.config.isInternal
1176
+ });
1177
+ Object.defineProperty(resolver, BUILT_IN_PERMISSION_RESOLVER, { value: isBuiltInPolicy });
1178
+ return resolver;
1179
+ };
1180
+ var defaultDecisionFor = (permission, role, isInternal) => {
1181
+ const internalExternal = isInternal ? "internal" : "external";
1182
+ return PERMISSION_MATRIX[permission]?.[internalExternal]?.includes(role) ?? false;
1183
+ };
1184
+ var NON_DATA_PERMISSION_PROPERTY = Symbol();
1185
+ var readPermissionDataProperty = (source, key) => {
1186
+ if (source == null) return void 0;
1187
+ if (typeof source !== "object" && typeof source !== "function") return NON_DATA_PERMISSION_PROPERTY;
1188
+ for (let owner = source; owner !== null; owner = Object.getPrototypeOf(owner)) {
1189
+ const descriptor = Object.getOwnPropertyDescriptor(owner, key);
1190
+ if (descriptor) return "value" in descriptor ? descriptor.value : NON_DATA_PERMISSION_PROPERTY;
1191
+ }
1192
+ };
1193
+ var readBuiltInTrackedChangePermissionDecision = (superdoc, canPerform, permission, trackedChange) => {
1194
+ try {
1195
+ if (readPermissionDataProperty(superdoc, "canPerformPermission") !== canPerform || readPermissionDataProperty(canPerform, BUILT_IN_PERMISSION_METHOD) !== true) return null;
1196
+ const config = readPermissionDataProperty(superdoc, "config");
1197
+ if (!config || typeof config !== "object") return null;
1198
+ const role = readPermissionDataProperty(config, "role");
1199
+ const isInternal = readPermissionDataProperty(config, "isInternal");
1200
+ const user = readPermissionDataProperty(config, "user");
1201
+ const resolver = readPermissionDataProperty(config, "permissionResolver");
1202
+ const modules = readPermissionDataProperty(config, "modules");
1203
+ const comments = readPermissionDataProperty(modules, "comments");
1204
+ const deprecatedResolver = readPermissionDataProperty(comments, "permissionResolver");
1205
+ const commentsStore = readPermissionDataProperty(superdoc, "commentsStore");
1206
+ if ([
1207
+ role,
1208
+ isInternal,
1209
+ user,
1210
+ resolver,
1211
+ modules,
1212
+ comments,
1213
+ deprecatedResolver,
1214
+ commentsStore,
1215
+ readPermissionDataProperty(commentsStore, "getComment"),
1216
+ readPermissionDataProperty(trackedChange, "comment"),
1217
+ readPermissionDataProperty(trackedChange, "commentId"),
1218
+ readPermissionDataProperty(trackedChange, "id")
1219
+ ].includes(NON_DATA_PERMISSION_PROPERTY) || typeof resolver === "function" || typeof deprecatedResolver === "function") return null;
1220
+ return defaultDecisionFor(permission, role, isInternal);
1221
+ } catch {
1222
+ return null;
1223
+ }
1224
+ };
1225
+ /**
1226
+ * Resolve a client-side permission through the built-in matrix and optional
1227
+ * resolver.
1228
+ *
1229
+ * @param {string} permission The permission to check
1230
+ * @param {string} role The role to check
1231
+ * @param {boolean} isInternal The internal/external flag
1232
+ * @param {object} [context] Context passed to the permission resolver
1233
+ * @param {object | null} [context.comment] The comment/tracked change being evaluated
1234
+ * @param {object | null} [context.superdoc] The SuperDoc instance
1235
+ * @param {object | null} [context.currentUser] The active user object performing the action
1236
+ * @param {Function} [context.permissionResolver] Explicit resolver override
1237
+ * @param {object | null} [context.trackedChange] Tracked change metadata (for tracked-change permissions)
1238
+ * @returns {boolean} Whether the permission is allowed
1239
+ */
1240
+ var isAllowed = (permission, role, isInternal, context = {}) => {
1241
+ const defaultDecision = defaultDecisionFor(permission, role, isInternal);
1242
+ const resolver = pickResolver(context);
1243
+ if (typeof resolver !== "function") return defaultDecision;
1244
+ const decision = resolver({
1245
+ permission,
1246
+ role,
1247
+ isInternal,
1248
+ defaultDecision,
1249
+ comment: context.comment ?? null,
1250
+ currentUser: context.currentUser ?? context.superdoc?.config?.user ?? null,
1251
+ superdoc: context.superdoc ?? null,
1252
+ trackedChange: context.trackedChange ?? null
1253
+ });
1254
+ return typeof decision === "boolean" ? decision : defaultDecision;
1255
+ };
1256
+ //#endregion
1090
1257
  //#region src/public/ui/viewport-batch.ts
1091
1258
  /** No rendering or scrolling: read only geometry already acknowledged by the host. */
1092
1259
  async function readViewportBatch(input, read, generation, disposed) {
@@ -2486,7 +2653,7 @@ function toStyleValue(key, value) {
2486
2653
  case "italic": return value === true;
2487
2654
  case "underline": return underlineValue(value);
2488
2655
  case "color": return typeof value === "string" && value.length > 0 ? { val: value.replace(/^#/, "") } : null;
2489
- case "fontSize": return typeof value === "number" && Number.isFinite(value) ? Math.round(value * 2) : null;
2656
+ case "fontSize": return isFiniteNumber(value) ? Math.round(value * 2) : null;
2490
2657
  case "rFonts": return fontsValue(value);
2491
2658
  default: return null;
2492
2659
  }
@@ -2640,16 +2807,17 @@ function selectionKey(selection) {
2640
2807
  }
2641
2808
  }
2642
2809
  //#endregion
2643
- //#region src/helpers/object-guards.js
2644
- /**
2645
- * @param {unknown} value
2646
- * @returns {value is Record<string, unknown>}
2647
- */
2648
- function isPlainObject(value) {
2649
- return typeof value === "object" && value !== null && !Array.isArray(value);
2650
- }
2651
- //#endregion
2652
2810
  //#region src/helpers/v2-review-mutation-impact.ts
2811
+ function mutationCommittedEventChangedVisibleContent(event) {
2812
+ if (event.dryRun === true) return false;
2813
+ if (isPlainObject(event.result) && event.result.noop === true) return false;
2814
+ const receipt = isPlainObject(event.receipt) ? event.receipt : null;
2815
+ if (receipt?.changed === false || receipt?.noop === true || receipt?.status === "NO_OP") return false;
2816
+ return true;
2817
+ }
2818
+ function mutationCommittedEventChangedDocument(event) {
2819
+ return event.cause !== "preview" && mutationCommittedEventChangedVisibleContent(event);
2820
+ }
2653
2821
  /**
2654
2822
  * Classify the tracked-change identities carried by a v2 mutation event.
2655
2823
  *
@@ -2977,7 +3145,7 @@ function normalizeZoomPayload(payload) {
2977
3145
  if (!Number.isFinite(parsed)) return payload;
2978
3146
  return normalizeNumber(parsed, isPercent);
2979
3147
  }
2980
- if (typeof payload === "number" && Number.isFinite(payload)) return normalizeNumber(payload, false);
3148
+ if (isFiniteNumber(payload)) return normalizeNumber(payload, false);
2981
3149
  return payload;
2982
3150
  }
2983
3151
  /**
@@ -5347,9 +5515,6 @@ var PARAGRAPH_INDENT_STEP_TWIPS = 720;
5347
5515
  function pointsToTwips(value) {
5348
5516
  return Math.round(value * 20);
5349
5517
  }
5350
- function isFiniteNumber(value) {
5351
- return typeof value === "number" && Number.isFinite(value);
5352
- }
5353
5518
  function readParagraphIndentationFromResult(result) {
5354
5519
  if (!result || typeof result !== "object") return null;
5355
5520
  const node = result.node;
@@ -5653,7 +5818,7 @@ function normalizeLayoutFontFamily(value) {
5653
5818
  }
5654
5819
  /** Convert a resolved run font size in CSS px to the toolbar's point value (SD-3652). */
5655
5820
  function normalizeLayoutFontSizePt(value) {
5656
- if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return void 0;
5821
+ if (!isFiniteNumber(value) || value <= 0) return void 0;
5657
5822
  const pt = Math.round(value * .75 * 2) / 2;
5658
5823
  if (pt <= 0) return void 0;
5659
5824
  return String(pt);
@@ -5762,17 +5927,42 @@ function commandResultFromOperationResult(result) {
5762
5927
  function isSuccessfulReceipt(result) {
5763
5928
  return Boolean(result) && typeof result === "object" && result.success === true;
5764
5929
  }
5765
- /**
5766
- * The host also emits `mutation:committed` for previews and no-op receipts;
5767
- * those events must not mark the document as having unsaved edits.
5768
- */
5769
- function mutationCommittedEventChangedDocument(event) {
5770
- if (event.dryRun === true) return false;
5771
- const receipt = event.receipt;
5772
- if (receipt && typeof receipt === "object" && receipt.changed === false) return false;
5773
- if (receipt && typeof receipt === "object" && receipt.noop === true) return false;
5774
- if (receipt && typeof receipt === "object" && receipt.status === "NO_OP") return false;
5775
- return true;
5930
+ function readTxId(value) {
5931
+ return typeof value === "string" && value.length > 0 ? value : null;
5932
+ }
5933
+ function documentChangeScope(stories) {
5934
+ return Array.isArray(stories) && stories.length > 0 ? {
5935
+ kind: "known",
5936
+ stories
5937
+ } : { kind: "unknown" };
5938
+ }
5939
+ function documentChangeFromHostEvent(event) {
5940
+ if (event.type === "collaboration:remote-changed") return {
5941
+ cause: "remote",
5942
+ changeTag: null,
5943
+ txId: null,
5944
+ scope: { kind: "unknown" }
5945
+ };
5946
+ if (event.type !== "mutation:committed") return null;
5947
+ if (event.origin === "history") {
5948
+ const result = isPlainObject(event.result) ? event.result : null;
5949
+ if (!result || result.noop === true) return null;
5950
+ const history = isPlainObject(result.history) ? result.history : null;
5951
+ return {
5952
+ cause: event.direction === "redo" ? "redo" : "undo",
5953
+ changeTag: null,
5954
+ txId: readTxId(history?.txId),
5955
+ scope: documentChangeScope(result.affectedStories)
5956
+ };
5957
+ }
5958
+ if (!mutationCommittedEventChangedDocument(event)) return null;
5959
+ const receipt = isPlainObject(event.receipt) ? event.receipt : {};
5960
+ return {
5961
+ cause: event.cause === "user" ? "user" : "api",
5962
+ changeTag: typeof receipt.changeTag === "string" ? receipt.changeTag : null,
5963
+ txId: readTxId(receipt.txId),
5964
+ scope: documentChangeScope(receipt.affectedStories)
5965
+ };
5776
5966
  }
5777
5967
  function commandResultSucceeded(result) {
5778
5968
  if (result === false) return false;
@@ -6366,7 +6556,7 @@ function createSuperDocUI(options) {
6366
6556
  if (!pending || !(method in pending)) return void 0;
6367
6557
  const value = pending[method];
6368
6558
  if (typeof value === "string" && value !== "") return value;
6369
- if (typeof value === "number" && Number.isFinite(value)) return String(value);
6559
+ if (isFiniteNumber(value)) return String(value);
6370
6560
  };
6371
6561
  /** Record / clear the stored inline mark for a collapsed-caret pick (SD-3654/SD-3652). */
6372
6562
  const setPendingInlineFormatOnHost = (method, value) => {
@@ -6681,9 +6871,19 @@ function createSuperDocUI(options) {
6681
6871
  if (seeded > 0) dirtyHosts.add(host);
6682
6872
  else if (revision === 0) dirtyHosts.delete(host);
6683
6873
  };
6684
- const hasLocalDocumentMutation = () => {
6874
+ const savedPoint = () => {
6685
6875
  const host = getHost();
6876
+ return {
6877
+ host,
6878
+ isDirty: hostMethod(host, "isDirty"),
6879
+ getDocumentVersion: hostMethod(host, "getDocumentVersion"),
6880
+ markSaved: hostMethod(host, "markSaved")
6881
+ };
6882
+ };
6883
+ const hasLocalDocumentMutation = () => {
6884
+ const { host, isDirty } = savedPoint();
6686
6885
  if (!host) return false;
6886
+ if (isDirty) return Boolean(safeCall(() => isDirty(), false));
6687
6887
  seedLocalDocumentMutation(host);
6688
6888
  return dirtyHosts.has(host);
6689
6889
  };
@@ -8094,6 +8294,33 @@ function createSuperDocUI(options) {
8094
8294
  sizeOptions: DEFAULT_FONT_SIZE_OPTIONS
8095
8295
  };
8096
8296
  };
8297
+ const EMPTY_HISTORY = {
8298
+ canUndo: false,
8299
+ canRedo: false,
8300
+ undoDepth: 0,
8301
+ redoDepth: 0
8302
+ };
8303
+ let historySlice = EMPTY_HISTORY;
8304
+ let historySource = null;
8305
+ const computeHistory = () => {
8306
+ const source = getEditCommands();
8307
+ if (source !== historySource) {
8308
+ historySource = source;
8309
+ historySlice = EMPTY_HISTORY;
8310
+ }
8311
+ const getSnapshot = hostMethod(source, "getSnapshot");
8312
+ const snapshot = getSnapshot ? safeCall(() => getSnapshot(), null) : null;
8313
+ const { undoDepth, redoDepth } = (isPlainObject(snapshot) && isPlainObject(snapshot.history) ? snapshot.history : null) ?? {};
8314
+ if (typeof undoDepth !== "number" || typeof redoDepth !== "number") return historySlice;
8315
+ const next = {
8316
+ canUndo: undoDepth > 0,
8317
+ canRedo: redoDepth > 0,
8318
+ undoDepth,
8319
+ redoDepth
8320
+ };
8321
+ if (!shallowEqual(next, historySlice)) historySlice = next;
8322
+ return historySlice;
8323
+ };
8097
8324
  let zoomFitWidth;
8098
8325
  const computeZoom = () => {
8099
8326
  const getZoomState = hostMethod(superdoc, "getZoomState");
@@ -8727,9 +8954,10 @@ function createSuperDocUI(options) {
8727
8954
  for (const candidate of permissions) {
8728
8955
  let allowed;
8729
8956
  try {
8730
- allowed = canPerform.call(superdoc, {
8957
+ const permissionChange = trackedChange ?? { id };
8958
+ allowed = readBuiltInTrackedChangePermissionDecision(superdoc, canPerform, candidate, permissionChange) ?? canPerform.call(superdoc, {
8731
8959
  permission: candidate,
8732
- trackedChange: trackedChange ?? { id },
8960
+ trackedChange: permissionChange,
8733
8961
  comment: null
8734
8962
  });
8735
8963
  } catch {
@@ -9622,7 +9850,7 @@ function createSuperDocUI(options) {
9622
9850
  };
9623
9851
  /** Validate normalized payloads before invoking public SuperDoc-instance methods. */
9624
9852
  const instanceCommandPayloadIsValid = (descriptor, payload) => {
9625
- if (descriptor.id === "zoom") return typeof payload === "number" && Number.isFinite(payload) && payload > 0;
9853
+ if (descriptor.id === "zoom") return isFiniteNumber(payload) && payload > 0;
9626
9854
  if (descriptor.id === "document-mode") return payload === "editing" || payload === "suggesting" || payload === "viewing";
9627
9855
  if (descriptor.id === "measurement-unit") return payload === "in" || payload === "cm";
9628
9856
  return true;
@@ -9906,6 +10134,7 @@ function createSuperDocUI(options) {
9906
10134
  trackChanges: measure("trackChanges", () => computeTrackChanges(selection)),
9907
10135
  contentControls: measure("contentControls", () => computeContentControls(selection)),
9908
10136
  zoom: measure("zoom", computeZoom),
10137
+ history: measure("history", computeHistory),
9909
10138
  fonts: measure("fonts", computeFonts),
9910
10139
  styles: measure("styles", () => computeStyles(selection))
9911
10140
  };
@@ -10009,7 +10238,7 @@ function createSuperDocUI(options) {
10009
10238
  const familyValue = state.toolbar.commands["font-family"]?.value;
10010
10239
  const sizeValue = state.toolbar.commands["font-size"]?.value;
10011
10240
  const hadFamily = typeof familyValue === "string" && familyValue.length > 0;
10012
- const hadSize = typeof sizeValue === "string" && sizeValue.length > 0 || typeof sizeValue === "number" && Number.isFinite(sizeValue);
10241
+ const hadSize = typeof sizeValue === "string" && sizeValue.length > 0 || isFiniteNumber(sizeValue);
10013
10242
  return hadFamily && projected.fontFamily === void 0 || hadSize && projected.fontSize === void 0;
10014
10243
  };
10015
10244
  const syncHostSelectionSubscription = () => {
@@ -10195,6 +10424,41 @@ function createSuperDocUI(options) {
10195
10424
  state = computeState("initial");
10196
10425
  lastOptimisticInlineSelectionSignature = selectionInlineValueSignature(state.selection);
10197
10426
  let scheduleActiveSearchRefresh = () => {};
10427
+ const documentChangeListeners = /* @__PURE__ */ new Set();
10428
+ const documentChangeCounters = /* @__PURE__ */ new WeakMap();
10429
+ let documentEpochCount = 0;
10430
+ const readDocumentReplacement = (host) => safeCall(() => hostMethod(host, "getDocumentReplacementVersion")?.(), null);
10431
+ const startDocumentChangeEpoch = (host) => {
10432
+ documentEpochCount += 1;
10433
+ const counter = {
10434
+ epoch: `document-${documentEpochCount}`,
10435
+ seq: 0,
10436
+ replacement: readDocumentReplacement(host)
10437
+ };
10438
+ documentChangeCounters.set(host, counter);
10439
+ return counter;
10440
+ };
10441
+ const currentDocumentChangeCounter = (host) => {
10442
+ const counter = documentChangeCounters.get(host);
10443
+ return counter && counter.replacement === readDocumentReplacement(host) ? counter : startDocumentChangeEpoch(host);
10444
+ };
10445
+ const publishDocumentChange = (host, event) => {
10446
+ if (event.type === "collaboration:document-replaced" || event.documentReplaced === true) {
10447
+ startDocumentChangeEpoch(host);
10448
+ return;
10449
+ }
10450
+ if (documentChangeListeners.size === 0) return;
10451
+ const facts = documentChangeFromHostEvent(event);
10452
+ if (!facts) return;
10453
+ const counter = currentDocumentChangeCounter(host);
10454
+ counter.seq += 1;
10455
+ const change = {
10456
+ documentEpoch: counter.epoch,
10457
+ seq: counter.seq,
10458
+ ...facts
10459
+ };
10460
+ for (const listener of Array.from(documentChangeListeners)) safeCall(() => listener(change), void 0);
10461
+ };
10198
10462
  const syncHostEventsSubscription = () => {
10199
10463
  const host = getEditor()?.host;
10200
10464
  const events = host?.events;
@@ -10213,15 +10477,19 @@ function createSuperDocUI(options) {
10213
10477
  try {
10214
10478
  const off = hostMethod(next, "subscribe")?.((event) => {
10215
10479
  const type = event?.type;
10480
+ if (host) publishDocumentChange(host, event);
10216
10481
  const isStandaloneDocumentMutation = type === "document:mutated" && event.hasCommitEvent !== true;
10217
- if (type === "collaboration:document-replaced" || isStandaloneDocumentMutation || type === "mutation:committed" && mutationCommittedEventChangedDocument(event) || type === "collaboration:remote-changed") {
10482
+ if (type === "collaboration:document-replaced" || isStandaloneDocumentMutation || type === "mutation:committed" && mutationCommittedEventChangedVisibleContent(event) || type === "collaboration:remote-changed") {
10218
10483
  for (const [commandId, optimistic] of optimisticInlineToggles) if (optimistic.settled || type === "collaboration:document-replaced") optimisticInlineToggles.delete(commandId);
10219
10484
  }
10220
- if (isStandaloneDocumentMutation || type === "mutation:committed" && mutationCommittedEventChangedDocument(event) || type === "collaboration:remote-changed" && Array.isArray(event.changedStoryIds) && event.changedStoryIds.length > 0) scheduleActiveSearchRefresh();
10221
- if ((type === "document:mutated" || type === "mutation:committed" && mutationCommittedEventChangedDocument(event)) && host && !dirtyHosts.has(host)) {
10485
+ if (isStandaloneDocumentMutation || type === "mutation:committed" && mutationCommittedEventChangedVisibleContent(event) || type === "collaboration:remote-changed" && Array.isArray(event.changedStoryIds) && event.changedStoryIds.length > 0) scheduleActiveSearchRefresh();
10486
+ const documentEdited = type === "document:mutated" || type === "mutation:committed" && mutationCommittedEventChangedDocument(event);
10487
+ if (documentEdited && host && hostMethod(host, "isDirty")) recompute("document-dirty");
10488
+ else if (documentEdited && host && !dirtyHosts.has(host)) {
10222
10489
  dirtyHosts.add(host);
10223
10490
  recompute("document-dirty");
10224
10491
  }
10492
+ if (type === "document:saved-point-changed") recompute("document-dirty");
10225
10493
  if (type === "collaboration:document-replaced" && host) {
10226
10494
  dirtyHosts.delete(host);
10227
10495
  hostSeededMutationRevision.delete(host);
@@ -10253,6 +10521,7 @@ function createSuperDocUI(options) {
10253
10521
  if (impact?.allResolved) {
10254
10522
  replaceTrackedChangeItemsInCache([]);
10255
10523
  publishAllTrackedChangesResolved(event.receipt);
10524
+ if (event.cause === "preview") invalidateDocumentContent();
10256
10525
  return;
10257
10526
  }
10258
10527
  if (impact?.removedIds.size) markPostDecisionTrackChanges(new Set(impact.removedIds), event.receipt);
@@ -10262,7 +10531,10 @@ function createSuperDocUI(options) {
10262
10531
  scheduleTypingDocumentContentInvalidation();
10263
10532
  return;
10264
10533
  }
10265
- if (impact?.removedIds.size && impact.upsertIds.size === 0) return;
10534
+ if (impact?.removedIds.size && impact.upsertIds.size === 0) {
10535
+ if (event.cause === "preview") invalidateDocumentContent();
10536
+ return;
10537
+ }
10266
10538
  if (isStandaloneDocumentMutation || type === "collaboration:remote-changed" || type === "mutation:committed" && !isTypingBurst) schedulePostPaintContentRefresh();
10267
10539
  const remoteCommentsPartChanged = type === "collaboration:remote-changed" && Array.isArray(event.changedPartUris) && event.changedPartUris.some((partUri) => typeof partUri === "string" && COMMENTS_CATALOG_PART_URIS.has(partUri));
10268
10540
  const loadedCommentAnchorsMayHaveChanged = type === "collaboration:remote-changed" && Array.isArray(event.changedStoryIds) && event.changedStoryIds.length > 0 && commentsCatalogMayHaveRows();
@@ -12171,6 +12443,16 @@ function createSuperDocUI(options) {
12171
12443
  mixedInlineKeys.add(patchKey);
12172
12444
  }
12173
12445
  }
12446
+ const fontFamily = effective?.fontFamily;
12447
+ if (fontFamily?.state === "uniform" && typeof fontFamily.value === "string") {
12448
+ inlinePatch.fontFamily = fontFamily.value;
12449
+ mixedInlineKeys.delete("fontFamily");
12450
+ } else if (fontFamily) {
12451
+ delete inlinePatch.fontFamily;
12452
+ delete inlinePatch.rFonts;
12453
+ mixedInlineKeys.add("fontFamily");
12454
+ mixedInlineKeys.add("rFonts");
12455
+ }
12174
12456
  const highlight = effective?.highlight;
12175
12457
  if (highlight?.state === "uniform") {
12176
12458
  inlinePatch.highlight = highlight.value;
@@ -12353,7 +12635,11 @@ function createSuperDocUI(options) {
12353
12635
  const node = (await readBlockNode(paragraphTarget(segment.blockId, targetStory)))?.node;
12354
12636
  const para = node ? getParagraphLikeData(node) : null;
12355
12637
  const runs = Array.isArray(para?.inlines) ? para.inlines : [];
12356
- for (const props of sliceRunProps(runs, segment.range)) for (const key of Object.keys(sdRunPropsToInlineRunPatch(props))) if (!(key in inline) && !snap.mixedInlineKeys.includes(key)) inline[key] = FORMAT_PAINTER_BOOLEAN_KEYS.has(key) ? false : null;
12638
+ for (const props of sliceRunProps(runs, segment.range)) for (const key of Object.keys(sdRunPropsToInlineRunPatch(props))) {
12639
+ const fontAlias = key === "rFonts" ? "fontFamily" : key === "fontFamily" ? "rFonts" : null;
12640
+ const capturedFontAlias = fontAlias && (fontAlias in inline || snap.mixedInlineKeys.includes(fontAlias));
12641
+ if (!(key in inline) && !snap.mixedInlineKeys.includes(key) && !capturedFontAlias) inline[key] = FORMAT_PAINTER_BOOLEAN_KEYS.has(key) ? false : null;
12642
+ }
12357
12643
  }
12358
12644
  if (disposed || painter.snapshot !== snap || getEditor() !== ownerEditor || ownerEditor?.doc !== ownerDoc || readDocumentMode() !== ownerMode) return;
12359
12645
  }
@@ -13694,6 +13980,7 @@ function createSuperDocUI(options) {
13694
13980
  getFamilyOptions: () => state.fonts.options,
13695
13981
  getSizeOptions: () => state.fonts.sizeOptions
13696
13982
  };
13983
+ const history = snapshotHandle(sliceHandle((s) => s.history));
13697
13984
  const zoomSnap = snapshotHandle(sliceHandle((s) => s.zoom));
13698
13985
  const zoom = {
13699
13986
  get: zoomSnap.get,
@@ -13754,6 +14041,28 @@ function createSuperDocUI(options) {
13754
14041
  } catch {
13755
14042
  return;
13756
14043
  }
14044
+ },
14045
+ onChange: (listener) => {
14046
+ if (disposed) return () => {};
14047
+ documentChangeListeners.add(listener);
14048
+ return () => documentChangeListeners.delete(listener);
14049
+ },
14050
+ getVersion: () => {
14051
+ const { getDocumentVersion } = savedPoint();
14052
+ const version = getDocumentVersion ? safeCall(() => getDocumentVersion(), null) : null;
14053
+ return typeof version === "string" ? version : null;
14054
+ },
14055
+ markClean: (version) => {
14056
+ const { markSaved } = savedPoint();
14057
+ if (!markSaved) return {
14058
+ ok: false,
14059
+ reason: "unavailable"
14060
+ };
14061
+ const result = safeCall(() => markSaved(version), null);
14062
+ return isPlainObject(result) && result.ok === true ? { ok: true } : {
14063
+ ok: false,
14064
+ reason: isPlainObject(result) && result.reason === "document-changed" ? "document-changed" : "unavailable"
14065
+ };
13757
14066
  }
13758
14067
  };
13759
14068
  const resolveVisibleHost = () => {
@@ -13765,7 +14074,7 @@ function createSuperDocUI(options) {
13765
14074
  return null;
13766
14075
  };
13767
14076
  const pointHitElements = (x, y) => {
13768
- if (typeof x !== "number" || typeof y !== "number" || !Number.isFinite(x) || !Number.isFinite(y)) return null;
14077
+ if (!isFiniteNumber(x) || !isFiniteNumber(y)) return null;
13769
14078
  const dom = globalThis.document;
13770
14079
  if (!dom || typeof dom.elementFromPoint !== "function") return null;
13771
14080
  const container = resolveVisibleHost();
@@ -14543,7 +14852,7 @@ function createSuperDocUI(options) {
14543
14852
  const record = result && typeof result === "object" ? result : null;
14544
14853
  if (!record) return null;
14545
14854
  const matches = Array.isArray(record.matches) ? record.matches : [];
14546
- const total = typeof record.total === "number" && Number.isFinite(record.total) ? record.total : matches.length;
14855
+ const total = isFiniteNumber(record.total) ? record.total : matches.length;
14547
14856
  const activeIndex = typeof record.activeMatchIndex === "number" ? record.activeMatchIndex : typeof record.activeIndex === "number" ? record.activeIndex : -1;
14548
14857
  const canReplace = record.canReplace === true || fallbackCanReplace;
14549
14858
  return {
@@ -15236,6 +15545,11 @@ function createSuperDocUI(options) {
15236
15545
  const scopeUnsubs = [];
15237
15546
  return {
15238
15547
  decorations: createDecorationsHandle((handle) => scopeUnsubs.push(() => handle.dispose())),
15548
+ document: { onChange: (listener) => {
15549
+ const unsub = documentHandle.onChange(listener);
15550
+ scopeUnsubs.push(unsub);
15551
+ return unsub;
15552
+ } },
15239
15553
  select: (selector, equality) => {
15240
15554
  const sub = select(selector, equality);
15241
15555
  return {
@@ -15322,6 +15636,7 @@ function createSuperDocUI(options) {
15322
15636
  painterCaptureEpoch += 1;
15323
15637
  painterCommandDoc = null;
15324
15638
  painterModeListeners.clear();
15639
+ documentChangeListeners.clear();
15325
15640
  searchRequestGeneration += 1;
15326
15641
  customCommands.clear();
15327
15642
  };
@@ -15339,6 +15654,7 @@ function createSuperDocUI(options) {
15339
15654
  bookmarks,
15340
15655
  fonts,
15341
15656
  zoom,
15657
+ history,
15342
15658
  document: documentHandle,
15343
15659
  viewport,
15344
15660
  decorations,
@@ -15560,4 +15876,4 @@ function commandIsActive(descriptor, selection) {
15560
15876
  return descriptor.activeMark ? selection.activeMarks.includes(descriptor.activeMark) : false;
15561
15877
  }
15562
15878
  //#endregion
15563
- export { createInteractionHistory as _, registerFirstPartyCommandMutation as a, recordInteraction as b, applyV2CommentInvalidationFromMutation as c, createImageFilePicker as d, resolveImageSrc as f, closeInteractionHistory as g, DOM_CLASS_NAMES as h, readFirstPartyPageNumbers as i, getV2TrackedChangeMutationImpact as l, isSyntheticTrackedChangeCommentLaneItem as m, executeFirstPartyCommandAsync as n, isRecord as o, shallowEqual as p, executeFirstPartyShortcutAsync as r, BUILT_IN_COMMAND_IDS as s, createSuperDocUI as t, isPlainObject as u, getWorkflowRecording as v, isWorkflowRecordingEnabled as y };
15879
+ export { getWorkflowRecording as C, createInteractionHistory as S, recordInteraction as T, isAllowed as _, registerFirstPartyCommandMutation as a, DOM_CLASS_NAMES as b, getCommandDescriptor as c, mutationCommittedEventChangedDocument as d, createImageFilePicker as f, createTrackedChangePermissionResolver as g, PERMISSIONS as h, readFirstPartyPageNumbers as i, applyV2CommentInvalidationFromMutation as l, shallowEqual as m, executeFirstPartyCommandAsync as n, isRecord as o, resolveImageSrc as p, executeFirstPartyShortcutAsync as r, BUILT_IN_COMMAND_IDS as s, createSuperDocUI as t, getV2TrackedChangeMutationImpact as u, isPlainObject as v, isWorkflowRecordingEnabled as w, closeInteractionHistory as x, isSyntheticTrackedChangeCommentLaneItem as y };
@@ -0,0 +1,11 @@
1
+ //#region src/helpers/is-finite-number.ts
2
+ function isFiniteNumber(value) {
3
+ return typeof value === "number" && Number.isFinite(value);
4
+ }
5
+ //#endregion
6
+ Object.defineProperty(exports, "isFiniteNumber", {
7
+ enumerable: true,
8
+ get: function() {
9
+ return isFiniteNumber;
10
+ }
11
+ });
@@ -0,0 +1,6 @@
1
+ //#region src/helpers/is-finite-number.ts
2
+ function isFiniteNumber(value) {
3
+ return typeof value === "number" && Number.isFinite(value);
4
+ }
5
+ //#endregion
6
+ export { isFiniteNumber as t };
@@ -19,7 +19,7 @@ var COLLABORATION_UPGRADE_ENGINE_MINIMUM_NODE_MAJOR = 20;
19
19
  var PRIVATE_ENGINE_INFO = (0, _superdoc_docx_engine_collaboration_upgrade_engine.getCollaborationUpgradeEngineInfo)();
20
20
  var ENGINE_INFO = Object.freeze({
21
21
  ...PRIVATE_ENGINE_INFO,
22
- superdocVersion: "2.28.0-next.9",
22
+ superdocVersion: "2.29.0-next.1",
23
23
  roomSchemaVersion: Object.freeze({ ...PRIVATE_ENGINE_INFO.roomSchemaVersion }),
24
24
  supportedBundleVersions: SUPPORTED_COLLABORATION_UPGRADE_BUNDLE_VERSIONS,
25
25
  supportedV1ReaderContractVersions: SUPPORTED_V1_READER_CONTRACT_VERSIONS
@@ -18,7 +18,7 @@ var COLLABORATION_UPGRADE_ENGINE_MINIMUM_NODE_MAJOR = 20;
18
18
  var PRIVATE_ENGINE_INFO = getCollaborationUpgradeEngineInfo$1();
19
19
  var ENGINE_INFO = Object.freeze({
20
20
  ...PRIVATE_ENGINE_INFO,
21
- superdocVersion: "2.28.0-next.9",
21
+ superdocVersion: "2.29.0-next.1",
22
22
  roomSchemaVersion: Object.freeze({ ...PRIVATE_ENGINE_INFO.roomSchemaVersion }),
23
23
  supportedBundleVersions: SUPPORTED_COLLABORATION_UPGRADE_BUNDLE_VERSIONS,
24
24
  supportedV1ReaderContractVersions: SUPPORTED_V1_READER_CONTRACT_VERSIONS
@@ -1,6 +1,6 @@
1
1
  import { RichContentInsertInput } from '../insert/insert.js';
2
2
  import { RichContentReplaceInput, ReplaceMutationOptions } from '../replace/replace.js';
3
- import { ChangeMode } from '../write/write.js';
3
+ import { ChangeMode, TrackedAttribution } from '../write/write.js';
4
4
  import { ProjectHtmlInput, ProjectMarkdownInput, SDContentProjectionResult, SDProjectionReviewMode, SDResolvedProjectionScope } from '../types/content-projection.js';
5
5
  import { SDFragment } from '../types/fragment.js';
6
6
  import { SDError, SDHtmlMarkdownOutcome, SDMutationConversionReport, SDMutationReceipt } from '../types/sd-contract.js';
@@ -17,11 +17,11 @@ export type SDHtmlMarkdownSupportCheckInput = {
17
17
  input: RichContentInsertInput;
18
18
  options?: {
19
19
  changeMode?: ChangeMode;
20
- };
20
+ } & TrackedAttribution;
21
21
  } | {
22
22
  operation: 'replace';
23
23
  input: RichContentReplaceInput;
24
- options?: Pick<ReplaceMutationOptions, 'changeMode' | 'replaceMode' | 'expectedSnapshotId'>;
24
+ options?: Pick<ReplaceMutationOptions, 'changeMode' | 'replaceMode' | 'expectedSnapshotId'> & TrackedAttribution;
25
25
  } | {
26
26
  operation: 'projectHtml';
27
27
  input?: ProjectHtmlInput;