@superdoc-dev/mcp 0.12.0-next.26 → 0.12.0-next.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +704 -138
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -52172,7 +52172,7 @@ var init_remark_gfm_BhnWr3yf_es = __esm(() => {
52172
52172
  emptyOptions2 = {};
52173
52173
  });
52174
52174
 
52175
- // ../../packages/superdoc/dist/chunks/SuperConverter-WQVqM0th.es.js
52175
+ // ../../packages/superdoc/dist/chunks/SuperConverter-DK5WIHuy.es.js
52176
52176
  function getExtensionConfigField(extension$1, field, context = { name: "" }) {
52177
52177
  const fieldValue = extension$1.config[field];
52178
52178
  if (typeof fieldValue === "function")
@@ -74459,8 +74459,11 @@ function trackRevisions(editor) {
74459
74459
  return;
74460
74460
  subscribedEditors.add(editor);
74461
74461
  editor.on("transaction", ({ transaction }) => {
74462
- if (transaction.docChanged)
74463
- incrementRevision(editor);
74462
+ if (transaction.getMeta?.("superdoc/block-identity-repair"))
74463
+ return;
74464
+ if (!transaction.docChanged)
74465
+ return;
74466
+ incrementRevision(editor);
74464
74467
  });
74465
74468
  }
74466
74469
  function checkRevision(editor, expectedRevision) {
@@ -84396,19 +84399,22 @@ function toIdentityValue(value) {
84396
84399
  if (typeof value === "number" && Number.isFinite(value))
84397
84400
  return String(value);
84398
84401
  }
84399
- function getBlockIdentityAttrs(node2) {
84400
- if (!node2 || typeof node2 !== "object")
84402
+ function getBlockIdentityAttrsForType(typeName) {
84403
+ if (!typeName)
84401
84404
  return [];
84402
- return BLOCK_IDENTITY_ATTRS[node2.type] ?? [];
84405
+ return BLOCK_IDENTITY_ATTRS[typeName] ?? [];
84406
+ }
84407
+ function shouldSynthesizeParaIdForType(typeName) {
84408
+ return Boolean(typeName && SYNTHETIC_PARA_ID_TYPES.has(typeName));
84403
84409
  }
84404
- function getExplicitIdentityEntries(node2) {
84405
- const attrPriority = getBlockIdentityAttrs(node2);
84410
+ function getExplicitIdentityEntries(attrs, typeName) {
84411
+ const attrPriority = getBlockIdentityAttrsForType(typeName);
84406
84412
  if (attrPriority.length === 0)
84407
84413
  return [];
84408
- const attrs = typeof node2.attrs === "object" && node2.attrs ? node2.attrs : {};
84414
+ const safeAttrs = attrs && typeof attrs === "object" ? attrs : {};
84409
84415
  const identityEntries = [];
84410
84416
  for (const attr of attrPriority) {
84411
- const value = toIdentityValue(attrs[attr]);
84417
+ const value = toIdentityValue(safeAttrs[attr]);
84412
84418
  if (value)
84413
84419
  identityEntries.push({
84414
84420
  attr,
@@ -84432,18 +84438,6 @@ function groupIdentityEntriesByValue(identityEntries) {
84432
84438
  }
84433
84439
  return [...groupsByValue.values()];
84434
84440
  }
84435
- function shouldSynthesizeParaId(node2) {
84436
- return Boolean(node2 && typeof node2 === "object" && SYNTHETIC_PARA_ID_TYPES.has(node2.type));
84437
- }
84438
- function collectExplicitBlockIdentities(node2, reservedIds) {
84439
- if (!node2 || typeof node2 !== "object")
84440
- return;
84441
- const identityEntries = getExplicitIdentityEntries(node2);
84442
- for (const { value } of groupIdentityEntriesByValue(identityEntries))
84443
- reservedIds.add(value);
84444
- if (Array.isArray(node2.content))
84445
- node2.content.forEach((child) => collectExplicitBlockIdentities(child, reservedIds));
84446
- }
84447
84441
  function createDeterministicDocxIdAllocator(reservedIds) {
84448
84442
  let nextValue = 1;
84449
84443
  return () => {
@@ -84458,6 +84452,15 @@ function createDeterministicDocxIdAllocator(reservedIds) {
84458
84452
  throw new Error("Unable to allocate a unique synthetic DOCX block id.");
84459
84453
  };
84460
84454
  }
84455
+ function collectExplicitBlockIdentities(node2, reservedIds) {
84456
+ if (!node2 || typeof node2 !== "object")
84457
+ return;
84458
+ const identityEntries = getExplicitIdentityEntries(node2.attrs, node2?.type);
84459
+ for (const { value } of groupIdentityEntriesByValue(identityEntries))
84460
+ reservedIds.add(value);
84461
+ if (Array.isArray(node2.content))
84462
+ node2.content.forEach((child) => collectExplicitBlockIdentities(child, reservedIds));
84463
+ }
84461
84464
  function setBlockIdentity(node2, attrName, value) {
84462
84465
  node2.attrs = {
84463
84466
  ...node2.attrs ?? {},
@@ -84467,7 +84470,7 @@ function setBlockIdentity(node2, attrName, value) {
84467
84470
  function normalizeBlockIdentitiesInNode(node2, seenIds, allocateDocxId) {
84468
84471
  if (!node2 || typeof node2 !== "object")
84469
84472
  return;
84470
- const groupedIdentities = groupIdentityEntriesByValue(getExplicitIdentityEntries(node2));
84473
+ const groupedIdentities = groupIdentityEntriesByValue(getExplicitIdentityEntries(node2.attrs, node2?.type));
84471
84474
  if (groupedIdentities.length > 0)
84472
84475
  for (const identityGroup of groupedIdentities)
84473
84476
  if (seenIds.has(identityGroup.value)) {
@@ -84477,7 +84480,7 @@ function normalizeBlockIdentitiesInNode(node2, seenIds, allocateDocxId) {
84477
84480
  seenIds.add(replacementId);
84478
84481
  } else
84479
84482
  seenIds.add(identityGroup.value);
84480
- else if (shouldSynthesizeParaId(node2)) {
84483
+ else if (shouldSynthesizeParaIdForType(node2?.type)) {
84481
84484
  const syntheticParaId = allocateDocxId();
84482
84485
  setBlockIdentity(node2, "paraId", syntheticParaId);
84483
84486
  seenIds.add(syntheticParaId);
@@ -92095,6 +92098,7 @@ function buildBlockIndex(editor) {
92095
92098
  const byId = /* @__PURE__ */ new Map;
92096
92099
  const ambiguous = /* @__PURE__ */ new Set;
92097
92100
  const pathByNode = /* @__PURE__ */ new WeakMap;
92101
+ const explicitIdentities = /* @__PURE__ */ new Map;
92098
92102
  pathByNode.set(editor.state.doc, []);
92099
92103
  function registerKey(key, candidate) {
92100
92104
  if (byId.has(key)) {
@@ -92103,11 +92107,44 @@ function buildBlockIndex(editor) {
92103
92107
  } else if (!ambiguous.has(key))
92104
92108
  byId.set(key, candidate);
92105
92109
  }
92110
+ function recordExplicitIdentities(node2, pos) {
92111
+ const attrPriority = getBlockIdentityAttrsForType(node2.type?.name);
92112
+ if (attrPriority.length === 0)
92113
+ return;
92114
+ const attrs = node2.attrs ?? {};
92115
+ let nodeGroups;
92116
+ for (const attr of attrPriority) {
92117
+ const value = toIdentityValue(attrs[attr]);
92118
+ if (!value)
92119
+ continue;
92120
+ if (!nodeGroups)
92121
+ nodeGroups = /* @__PURE__ */ new Map;
92122
+ const existing = nodeGroups.get(value);
92123
+ if (existing)
92124
+ existing.push(attr);
92125
+ else
92126
+ nodeGroups.set(value, [attr]);
92127
+ }
92128
+ if (!nodeGroups)
92129
+ return;
92130
+ for (const [value, attrsForValue] of nodeGroups) {
92131
+ const observations = explicitIdentities.get(value);
92132
+ const observation = {
92133
+ pos,
92134
+ attrs: attrsForValue
92135
+ };
92136
+ if (observations)
92137
+ observations.push(observation);
92138
+ else
92139
+ explicitIdentities.set(value, [observation]);
92140
+ }
92141
+ }
92106
92142
  editor.state.doc.descendants((node2, pos, parent, index2) => {
92107
92143
  const parentPath = parent ? pathByNode.get(parent) ?? [] : [];
92108
92144
  const path2 = typeof index2 === "number" && Number.isInteger(index2) && index2 >= 0 ? [...parentPath, index2] : undefined;
92109
92145
  if (path2)
92110
92146
  pathByNode.set(node2, path2);
92147
+ recordExplicitIdentities(node2, pos);
92111
92148
  const nodeType = mapBlockNodeType(node2);
92112
92149
  if (!nodeType)
92113
92150
  return;
@@ -92130,7 +92167,8 @@ function buildBlockIndex(editor) {
92130
92167
  return {
92131
92168
  candidates,
92132
92169
  byId,
92133
- ambiguous
92170
+ ambiguous,
92171
+ explicitIdentities
92134
92172
  };
92135
92173
  }
92136
92174
  function findBlockById(index2, address) {
@@ -95715,6 +95753,8 @@ function resolveStoryRuntime(hostEditor, locator, options = {}) {
95715
95753
  if (store && !hasHostStoreSyncListener(runtime.editor, storyKey)) {
95716
95754
  markHostStoreSyncListener(runtime.editor, storyKey);
95717
95755
  runtime.editor.on("transaction", ({ transaction }) => {
95756
+ if (transaction.getMeta?.("superdoc/block-identity-repair"))
95757
+ return;
95718
95758
  if (transaction.docChanged)
95719
95759
  incrementStoryRevision(store, storyKey);
95720
95760
  });
@@ -118774,7 +118814,7 @@ var isRegExp = (value) => {
118774
118814
  state.kern = kernNode.attributes["w:val"];
118775
118815
  }
118776
118816
  }, SuperConverter;
118777
- var init_SuperConverter_WQVqM0th_es = __esm(() => {
118817
+ var init_SuperConverter_DK5WIHuy_es = __esm(() => {
118778
118818
  init_rolldown_runtime_Bg48TavK_es();
118779
118819
  init_jszip_C49i9kUs_es();
118780
118820
  init_xml_js_CqGKpaft_es();
@@ -159518,7 +159558,7 @@ var init_SuperConverter_WQVqM0th_es = __esm(() => {
159518
159558
  };
159519
159559
  });
159520
159560
 
159521
- // ../../packages/superdoc/dist/chunks/create-headless-toolbar-B8OXKxcw.es.js
159561
+ // ../../packages/superdoc/dist/chunks/create-headless-toolbar-BLN1v7eO.es.js
159522
159562
  function parseSizeUnit(val = "0") {
159523
159563
  const length = val.toString() || "0";
159524
159564
  const value = Number.parseFloat(length);
@@ -161001,6 +161041,194 @@ function applySetMarksToResolved(editor, existingMarks, setMarks) {
161001
161041
  }
161002
161042
  return marks;
161003
161043
  }
161044
+ function planRepairs(doc3, identityMap) {
161045
+ if (identityMap)
161046
+ return planRepairsFromIdentityMap(identityMap);
161047
+ return planRepairsByWalk(doc3);
161048
+ }
161049
+ function planRepairsFromIdentityMap(identityMap) {
161050
+ let hasDuplicates = false;
161051
+ for (const observations of identityMap.values())
161052
+ if (observations.length > 1) {
161053
+ hasDuplicates = true;
161054
+ break;
161055
+ }
161056
+ if (!hasDuplicates)
161057
+ return {
161058
+ plans: [],
161059
+ report: {
161060
+ repairedBlockCount: 0,
161061
+ duplicateBlockIds: [],
161062
+ renames: []
161063
+ }
161064
+ };
161065
+ const rewrites = [];
161066
+ for (const [value, observations] of identityMap) {
161067
+ if (observations.length <= 1)
161068
+ continue;
161069
+ for (let i4 = 1;i4 < observations.length; i4 += 1) {
161070
+ const { pos, attrs } = observations[i4];
161071
+ rewrites.push({
161072
+ pos,
161073
+ value,
161074
+ attrs
161075
+ });
161076
+ }
161077
+ }
161078
+ rewrites.sort((a, b) => a.pos - b.pos);
161079
+ const allocateDocxId = createDeterministicDocxIdAllocator(new Set(identityMap.keys()));
161080
+ const plansByPos = /* @__PURE__ */ new Map;
161081
+ const duplicateBlockIds = [];
161082
+ const renames = [];
161083
+ for (const { pos, value, attrs } of rewrites) {
161084
+ const replacementValue = allocateDocxId();
161085
+ let plan = plansByPos.get(pos);
161086
+ if (!plan) {
161087
+ plan = {
161088
+ pos,
161089
+ rewrittenGroups: []
161090
+ };
161091
+ plansByPos.set(pos, plan);
161092
+ }
161093
+ const attrsCopy = [...attrs];
161094
+ plan.rewrittenGroups.push({
161095
+ originalValue: value,
161096
+ replacementValue,
161097
+ attrs: attrsCopy
161098
+ });
161099
+ duplicateBlockIds.push(value);
161100
+ renames.push({
161101
+ originalValue: value,
161102
+ replacementValue,
161103
+ attrs: attrsCopy
161104
+ });
161105
+ }
161106
+ const plans = [...plansByPos.values()].sort((a, b) => a.pos - b.pos);
161107
+ return {
161108
+ plans,
161109
+ report: {
161110
+ repairedBlockCount: plans.length,
161111
+ duplicateBlockIds,
161112
+ renames
161113
+ }
161114
+ };
161115
+ }
161116
+ function planRepairsByWalk(doc3) {
161117
+ const reservedIds = /* @__PURE__ */ new Set;
161118
+ let hasDuplicates = false;
161119
+ doc3.descendants((node2) => {
161120
+ const entries = getExplicitIdentityEntries(node2.attrs, node2.type?.name);
161121
+ for (const { value } of groupIdentityEntriesByValue(entries))
161122
+ if (reservedIds.has(value))
161123
+ hasDuplicates = true;
161124
+ else
161125
+ reservedIds.add(value);
161126
+ });
161127
+ if (!hasDuplicates)
161128
+ return {
161129
+ plans: [],
161130
+ report: {
161131
+ repairedBlockCount: 0,
161132
+ duplicateBlockIds: [],
161133
+ renames: []
161134
+ }
161135
+ };
161136
+ const allocateDocxId = createDeterministicDocxIdAllocator(reservedIds);
161137
+ const seenIds = /* @__PURE__ */ new Set;
161138
+ const plans = [];
161139
+ const duplicateBlockIds = [];
161140
+ const renames = [];
161141
+ doc3.descendants((node2, pos) => {
161142
+ const groups = groupIdentityEntriesByValue(getExplicitIdentityEntries(node2.attrs, node2.type?.name));
161143
+ if (groups.length === 0)
161144
+ return;
161145
+ let plan = null;
161146
+ for (const group of groups)
161147
+ if (seenIds.has(group.value)) {
161148
+ if (!plan)
161149
+ plan = {
161150
+ pos,
161151
+ rewrittenGroups: []
161152
+ };
161153
+ const replacementValue = allocateDocxId();
161154
+ plan.rewrittenGroups.push({
161155
+ originalValue: group.value,
161156
+ replacementValue,
161157
+ attrs: [...group.attrs]
161158
+ });
161159
+ duplicateBlockIds.push(group.value);
161160
+ renames.push({
161161
+ originalValue: group.value,
161162
+ replacementValue,
161163
+ attrs: [...group.attrs]
161164
+ });
161165
+ seenIds.add(replacementValue);
161166
+ } else
161167
+ seenIds.add(group.value);
161168
+ if (plan)
161169
+ plans.push(plan);
161170
+ });
161171
+ return {
161172
+ plans,
161173
+ report: {
161174
+ repairedBlockCount: plans.length,
161175
+ duplicateBlockIds,
161176
+ renames
161177
+ }
161178
+ };
161179
+ }
161180
+ function repairDuplicateBlockIdentities(editor) {
161181
+ const doc3 = editor.state?.doc;
161182
+ if (!doc3 || typeof doc3.descendants !== "function")
161183
+ return null;
161184
+ if (typeof editor.state?.tr !== "object" || editor.state.tr === null)
161185
+ return null;
161186
+ if (typeof editor.dispatch !== "function")
161187
+ return null;
161188
+ let identityMap;
161189
+ try {
161190
+ identityMap = getBlockIndex(editor).explicitIdentities;
161191
+ } catch {
161192
+ identityMap = undefined;
161193
+ }
161194
+ const { plans, report } = planRepairs(doc3, identityMap);
161195
+ if (plans.length === 0)
161196
+ return null;
161197
+ const tr = editor.state.tr;
161198
+ tr.setMeta("addToHistory", false);
161199
+ tr.setMeta("superdoc/block-identity-repair", report);
161200
+ for (const plan of plans)
161201
+ for (const group of plan.rewrittenGroups)
161202
+ for (const attr of group.attrs)
161203
+ tr.setNodeAttribute(plan.pos, attr, group.replacementValue);
161204
+ editor.dispatch(tr);
161205
+ const blockedNodeIds = [];
161206
+ for (const plan of plans) {
161207
+ const node2 = editor.state.doc.nodeAt(plan.pos);
161208
+ if (!node2) {
161209
+ blockedNodeIds.push(`pos:${plan.pos}`);
161210
+ continue;
161211
+ }
161212
+ for (const group of plan.rewrittenGroups)
161213
+ for (const attr of group.attrs)
161214
+ if (node2.attrs?.[attr] !== group.replacementValue) {
161215
+ const observedId = typeof node2.attrs?.id === "string" && node2.attrs.id || typeof node2.attrs?.sdBlockId === "string" && node2.attrs.sdBlockId || `pos:${plan.pos}`;
161216
+ blockedNodeIds.push(observedId);
161217
+ }
161218
+ }
161219
+ if (blockedNodeIds.length > 0) {
161220
+ const unique = [...new Set(blockedNodeIds)];
161221
+ const MAX_ID_PREVIEW_LENGTH = 32;
161222
+ const truncate = (id) => id.length > MAX_ID_PREVIEW_LENGTH ? `${id.slice(0, MAX_ID_PREVIEW_LENGTH - 1)}…` : id;
161223
+ const preview = unique.slice(0, 4).map(truncate).join(", ");
161224
+ const previewSuffix = unique.length > 4 ? `, +${unique.length - 4} more` : "";
161225
+ throw planError("REPAIR_BLOCKED", `Runtime identity repair was rejected by a transaction filter (${unique.length} node${unique.length === 1 ? "" : "s"}: ${preview}${previewSuffix}). A structured-content lock or permission range likely covers one of the duplicate blocks. Re-import the document via doc.open to assign unique identities.`, undefined, {
161226
+ blockedNodeIds: unique,
161227
+ remediation: "Re-import the document via doc.open to assign unique identities."
161228
+ });
161229
+ }
161230
+ return report;
161231
+ }
161004
161232
  function getCandidateText(editor, candidate, options) {
161005
161233
  if (candidate.node.childCount > 0)
161006
161234
  return textContentInBlock(candidate.node, options);
@@ -162205,12 +162433,15 @@ function assertNoDuplicateBlockIds(index2) {
162205
162433
  if (count === 1)
162206
162434
  duplicates.push(candidate.nodeId);
162207
162435
  }
162208
- if (duplicates.length > 0)
162209
- throw planError("DOCUMENT_IDENTITY_CONFLICT", "Document contains blocks with duplicate identities. This must be resolved before mutations can be applied.", undefined, {
162436
+ if (duplicates.length > 0) {
162437
+ const preview = duplicates.slice(0, 4).join(", ");
162438
+ const previewSuffix = duplicates.length > 4 ? `, +${duplicates.length - 4} more` : "";
162439
+ throw planError("DOCUMENT_IDENTITY_CONFLICT", `Document contains ${duplicates.length} block identit${duplicates.length === 1 ? "y" : "ies"} shared by multiple blocks (${preview}${previewSuffix}). Re-import the document via doc.open to assign unique identities.`, undefined, {
162210
162440
  duplicateBlockIds: duplicates,
162211
162441
  blockCount: duplicates.length,
162212
- remediation: "Re-import the document or call document.repair() to assign unique identities."
162442
+ remediation: "Re-import the document via doc.open to assign unique identities."
162213
162443
  });
162444
+ }
162214
162445
  }
162215
162446
  function assertSingleStoryKey(steps) {
162216
162447
  let seenStoryKey;
@@ -162238,11 +162469,71 @@ function assertSingleStoryKey(steps) {
162238
162469
  });
162239
162470
  }
162240
162471
  }
162472
+ function collectReferencedBlockIds(step2) {
162473
+ const where = step2.where;
162474
+ const ids = [];
162475
+ const withinNodeId = where.within?.nodeId;
162476
+ if (withinNodeId)
162477
+ ids.push(withinNodeId);
162478
+ if (isRefWhere(where)) {
162479
+ const ref2 = where.ref;
162480
+ if (ref2.startsWith("text:")) {
162481
+ const decoded = decodeRef(ref2);
162482
+ if (decoded) {
162483
+ for (const seg of decoded.segments ?? [])
162484
+ if (seg?.blockId)
162485
+ ids.push(seg.blockId);
162486
+ const nodeId = decoded.node?.nodeId;
162487
+ if (nodeId)
162488
+ ids.push(nodeId);
162489
+ }
162490
+ } else
162491
+ ids.push(ref2);
162492
+ return ids;
162493
+ }
162494
+ if (isBlockWhere(where)) {
162495
+ ids.push(where.nodeId);
162496
+ return ids;
162497
+ }
162498
+ if (isTargetWhere(where))
162499
+ for (const point3 of [where.target?.start, where.target?.end]) {
162500
+ const blockId = point3?.blockId;
162501
+ if (blockId)
162502
+ ids.push(blockId);
162503
+ const edgeNodeId = point3?.node?.nodeId;
162504
+ if (edgeNodeId)
162505
+ ids.push(edgeNodeId);
162506
+ }
162507
+ return ids;
162508
+ }
162509
+ function assertNoStaleRefsAfterRepair(steps, repairedIds) {
162510
+ if (repairedIds.size === 0)
162511
+ return;
162512
+ for (const step2 of steps)
162513
+ for (const blockId of collectReferencedBlockIds(step2)) {
162514
+ if (!repairedIds.has(blockId))
162515
+ continue;
162516
+ throw planError("STALE_REF", `Step "${step2.id}" references block id "${blockId}", which was duplicated in this document and has just been repaired (the duplicate occurrence was renamed). The reference is ambiguous — it may have pointed at the renamed block. Re-run query.match / doc.find against the repaired document and retry with a fresh ref.`, step2.id, {
162517
+ blockId,
162518
+ repairedBlockIds: [...repairedIds],
162519
+ remediation: "Re-run query.match() or doc.find() to obtain fresh refs, then retry the mutation."
162520
+ });
162521
+ }
162522
+ }
162241
162523
  function compilePlan(editor, steps, options = {}) {
162242
162524
  if (steps.length > 200)
162243
162525
  throw planError("INVALID_INPUT", `plan contains ${steps.length} steps, maximum is 200`);
162526
+ let index2 = getBlockIndex(editor);
162527
+ if (!options.skipIdentityRepair) {
162528
+ const repair = repairDuplicateBlockIdentities(editor);
162529
+ if (repair) {
162530
+ clearIndexCache(editor);
162531
+ index2 = getBlockIndex(editor);
162532
+ console.warn(`[plan-engine] Repaired ${repair.repairedBlockCount} block(s) with duplicate identities before plan compilation. Original ids: ${repair.duplicateBlockIds.slice(0, 4).join(", ")}${repair.duplicateBlockIds.length > 4 ? `, +${repair.duplicateBlockIds.length - 4} more` : ""}.`);
162533
+ assertNoStaleRefsAfterRepair(steps, new Set(repair.duplicateBlockIds));
162534
+ }
162535
+ }
162244
162536
  const compiledRevision = getRevision(editor);
162245
- const index2 = getBlockIndex(editor);
162246
162537
  assertNoDuplicateBlockIds(index2);
162247
162538
  const mutationSteps = [];
162248
162539
  const assertSteps = [];
@@ -164335,6 +164626,7 @@ function executeCompiledPlan(editor, compiled, options = {}) {
164335
164626
  function executePlan(editor, input) {
164336
164627
  if (!input.steps?.length)
164337
164628
  throw planError("INVALID_INPUT", "plan must contain at least one step");
164629
+ checkRevision(editor, input.expectedRevision);
164338
164630
  return executeCompiledPlan(editor, compilePlan(editor, input.steps, { selectTextModel: input.changeMode === "tracked" ? "raw" : "visible" }), {
164339
164631
  changeMode: input.changeMode ?? "direct",
164340
164632
  expectedRevision: input.expectedRevision
@@ -165681,7 +165973,9 @@ function selectionMutationWrapper(editor, request, options) {
165681
165973
  ensureTrackedInlinePropertySupport(inlineKeys);
165682
165974
  }
165683
165975
  const stepId = v4_default();
165684
- const compiled = compilePlan(storyEditor, [buildSelectionStepDef(stepId, request, buildSelectionWhere(request))]);
165976
+ const step2 = buildSelectionStepDef(stepId, request, buildSelectionWhere(request));
165977
+ checkRevision(storyEditor, options?.expectedRevision);
165978
+ const compiled = compilePlan(storyEditor, [step2], options?.dryRun ? { skipIdentityRepair: true } : undefined);
165685
165979
  if (request.kind === "insert" && request.target) {
165686
165980
  if (request.target.start.kind === "nodeEdge" || request.target.end.kind === "nodeEdge")
165687
165981
  throw new DocumentApiAdapterError("INVALID_TARGET", "Text inserts do not support nodeEdge targets. Use a text-offset target inside a textblock.");
@@ -165711,7 +166005,6 @@ function selectionMutationWrapper(editor, request, options) {
165711
166005
  }
165712
166006
  }
165713
166007
  }
165714
- checkRevision(storyEditor, options?.expectedRevision);
165715
166008
  if (options?.dryRun) {
165716
166009
  const resolution$1 = buildSelectionResolutionFromCompiled(compiled, stepId);
165717
166010
  if (request.kind === "insert" && !request.text)
@@ -165929,6 +166222,7 @@ function insertStructuredInner(editor, input, options) {
165929
166222
  }
165930
166223
  };
165931
166224
  } else if (ref2) {
166225
+ checkRevision(editor, options?.expectedRevision);
165932
166226
  const dummyStepId = v4_default();
165933
166227
  const compiled = compilePlan(editor, [{
165934
166228
  id: dummyStepId,
@@ -165941,7 +166235,7 @@ function insertStructuredInner(editor, input, options) {
165941
166235
  position: "before",
165942
166236
  content: { text: "" }
165943
166237
  }
165944
- }]);
166238
+ }], options?.dryRun ? { skipIdentityRepair: true } : undefined);
165945
166239
  const compiledTarget = compiled.mutationSteps.find((s) => s.step.id === dummyStepId)?.targets[0];
165946
166240
  if (!compiledTarget)
165947
166241
  throw new DocumentApiAdapterError("TARGET_NOT_FOUND", "Structured insert ref could not be resolved.", { ref: ref2 });
@@ -169913,8 +170207,8 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, normalizeActorId = (value) => {
169913
170207
  }
169914
170208
  };
169915
170209
  };
169916
- var init_create_headless_toolbar_B8OXKxcw_es = __esm(() => {
169917
- init_SuperConverter_WQVqM0th_es();
170210
+ var init_create_headless_toolbar_BLN1v7eO_es = __esm(() => {
170211
+ init_SuperConverter_DK5WIHuy_es();
169918
170212
  init_uuid_B2wVPhPi_es();
169919
170213
  init_constants_D9qj59G2_es();
169920
170214
  init_dist_B8HfvhaK_es();
@@ -224604,7 +224898,7 @@ var init_remark_gfm_eZN6yzWQ_es = __esm(() => {
224604
224898
  init_remark_gfm_BhnWr3yf_es();
224605
224899
  });
224606
224900
 
224607
- // ../../packages/superdoc/dist/chunks/src-Bvhjxf8i.es.js
224901
+ // ../../packages/superdoc/dist/chunks/src-PJVnllcq.es.js
224608
224902
  function deleteProps(obj, propOrProps) {
224609
224903
  const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
224610
224904
  const removeNested = (target, pathParts, index2 = 0) => {
@@ -248130,7 +248424,7 @@ function previewPlan(editor, input2) {
248130
248424
  let currentPhase = "compile";
248131
248425
  let evaluatedRevision = getRevision(editor);
248132
248426
  try {
248133
- const compiled = compilePlan(editor, input2.steps);
248427
+ const compiled = compilePlan(editor, input2.steps, { skipIdentityRepair: true });
248134
248428
  evaluatedRevision = compiled.compiledRevision;
248135
248429
  currentPhase = "execute";
248136
248430
  const tr = editor.state.tr;
@@ -296365,7 +296659,8 @@ var Node$13 = class Node$14 {
296365
296659
  const ySyncMeta = tr.getMeta(ySyncPluginKey);
296366
296660
  const pendingDeadKeyPlaceholder = TrackChangesBasePluginKey.getState(state)?.pendingDeadKeyPlaceholder ?? null;
296367
296661
  const hasDisallowedMeta = tr.meta && Object.keys(tr.meta).some((meta4) => !ALLOWED_META_KEYS.has(meta4));
296368
- if (ySyncMeta?.isChangeOrigin || !tr.steps.length || hasDisallowedMeta && !isProgrammaticInput || notAllowedMeta.includes(tr.getMeta("inputType")) || tr.getMeta(CommentsPluginKey)) {
296662
+ const isBlockIdentityRepair = Boolean(tr.getMeta("superdoc/block-identity-repair"));
296663
+ if (ySyncMeta?.isChangeOrigin || !tr.steps.length || isBlockIdentityRepair || hasDisallowedMeta && !isProgrammaticInput || notAllowedMeta.includes(tr.getMeta("inputType")) || tr.getMeta(CommentsPluginKey)) {
296369
296664
  if (pendingDeadKeyPlaceholder && !isCompositionTransaction(tr))
296370
296665
  mergeTrackChangesMeta(tr, { pendingDeadKeyPlaceholder: null });
296371
296666
  return tr;
@@ -322713,13 +323008,13 @@ menclose::after {
322713
323008
  return;
322714
323009
  console.log(...args$1);
322715
323010
  }, HEADER_FOOTER_INIT_BUDGET_MS = 200, MAX_ZOOM_WARNING_THRESHOLD = 10, MAX_SELECTION_RECTS_PER_USER = 100, SEMANTIC_RESIZE_DEBOUNCE_MS = 120, MIN_SEMANTIC_CONTENT_WIDTH_PX = 1, GLOBAL_PERFORMANCE, PresentationEditor, ICONS, TEXTS, tableActionsOptions, TRACKED_MARK_NAMES;
322716
- var init_src_Bvhjxf8i_es = __esm(() => {
323011
+ var init_src_PJVnllcq_es = __esm(() => {
322717
323012
  init_rolldown_runtime_Bg48TavK_es();
322718
- init_SuperConverter_WQVqM0th_es();
323013
+ init_SuperConverter_DK5WIHuy_es();
322719
323014
  init_jszip_C49i9kUs_es();
322720
323015
  init_xml_js_CqGKpaft_es();
322721
323016
  init_uuid_B2wVPhPi_es();
322722
- init_create_headless_toolbar_B8OXKxcw_es();
323017
+ init_create_headless_toolbar_BLN1v7eO_es();
322723
323018
  init_constants_D9qj59G2_es();
322724
323019
  init_dist_B8HfvhaK_es();
322725
323020
  init_unified_Dsuw2be5_es();
@@ -358504,11 +358799,11 @@ function print() { __p += __j.call(arguments, '') }
358504
358799
  ]);
358505
358800
  });
358506
358801
 
358507
- // ../../packages/superdoc/dist/chunks/create-super-doc-ui-CCLA6uFG.es.js
358802
+ // ../../packages/superdoc/dist/chunks/create-super-doc-ui-CrjXK3s_.es.js
358508
358803
  var DEFAULT_TEXT_ALIGN_OPTIONS, DEFAULT_LINE_HEIGHT_OPTIONS, DEFAULT_ZOOM_OPTIONS, DEFAULT_DOCUMENT_MODE_OPTIONS, DEFAULT_FONT_SIZE_OPTIONS, headlessToolbarConstants, MOD_ALIASES, ALT_ALIASES, CTRL_ALIASES, SHIFT_ALIASES, BUILTIN_CONTEXT_MENU_GROUPS, BUILTIN_GROUP_ORDER, RESERVED_PROXY_PROPERTY_NAMES, ALL_TOOLBAR_COMMAND_IDS, EMPTY_ACTIVE_IDS, FONT_SIZE_OPTIONS;
358509
- var init_create_super_doc_ui_CCLA6uFG_es = __esm(() => {
358510
- init_SuperConverter_WQVqM0th_es();
358511
- init_create_headless_toolbar_B8OXKxcw_es();
358804
+ var init_create_super_doc_ui_CrjXK3s__es = __esm(() => {
358805
+ init_SuperConverter_DK5WIHuy_es();
358806
+ init_create_headless_toolbar_BLN1v7eO_es();
358512
358807
  DEFAULT_TEXT_ALIGN_OPTIONS = [
358513
358808
  {
358514
358809
  label: "Left",
@@ -358799,16 +359094,16 @@ var init_zipper_yaJVJ4z9_es = __esm(() => {
358799
359094
 
358800
359095
  // ../../packages/superdoc/dist/super-editor.es.js
358801
359096
  var init_super_editor_es = __esm(() => {
358802
- init_src_Bvhjxf8i_es();
358803
- init_SuperConverter_WQVqM0th_es();
359097
+ init_src_PJVnllcq_es();
359098
+ init_SuperConverter_DK5WIHuy_es();
358804
359099
  init_jszip_C49i9kUs_es();
358805
359100
  init_xml_js_CqGKpaft_es();
358806
- init_create_headless_toolbar_B8OXKxcw_es();
359101
+ init_create_headless_toolbar_BLN1v7eO_es();
358807
359102
  init_constants_D9qj59G2_es();
358808
359103
  init_dist_B8HfvhaK_es();
358809
359104
  init_unified_Dsuw2be5_es();
358810
359105
  init_DocxZipper_FUsfThjV_es();
358811
- init_create_super_doc_ui_CCLA6uFG_es();
359106
+ init_create_super_doc_ui_CrjXK3s__es();
358812
359107
  init_ui_C5PAS9hY_es();
358813
359108
  init_eventemitter3_BnGqBE_Q_es();
358814
359109
  init_errors_CNaD6vcg_es();
@@ -358928,6 +359223,81 @@ var init_errors4 = __esm(() => {
358928
359223
  };
358929
359224
  });
358930
359225
 
359226
+ // ../../packages/super-editor/src/editors/v1/core/super-converter/v2/importer/block-identity-renaming.js
359227
+ function toIdentityValue2(value) {
359228
+ if (typeof value === "string" && value.length > 0)
359229
+ return value;
359230
+ if (typeof value === "number" && Number.isFinite(value))
359231
+ return String(value);
359232
+ return;
359233
+ }
359234
+ function getBlockIdentityAttrsForType2(typeName) {
359235
+ if (!typeName)
359236
+ return [];
359237
+ return BLOCK_IDENTITY_ATTRS2[typeName] ?? [];
359238
+ }
359239
+ function shouldSynthesizeParaIdForType2(typeName) {
359240
+ return Boolean(typeName && SYNTHETIC_PARA_ID_TYPES2.has(typeName));
359241
+ }
359242
+ function getExplicitIdentityEntries2(attrs, typeName) {
359243
+ const attrPriority = getBlockIdentityAttrsForType2(typeName);
359244
+ if (attrPriority.length === 0)
359245
+ return [];
359246
+ const safeAttrs = attrs && typeof attrs === "object" ? attrs : {};
359247
+ const identityEntries = [];
359248
+ for (const attr of attrPriority) {
359249
+ const value = toIdentityValue2(safeAttrs[attr]);
359250
+ if (value) {
359251
+ identityEntries.push({ attr, value });
359252
+ }
359253
+ }
359254
+ return identityEntries;
359255
+ }
359256
+ function groupIdentityEntriesByValue2(identityEntries) {
359257
+ const groupsByValue = new Map;
359258
+ for (const entry of identityEntries) {
359259
+ const existingGroup = groupsByValue.get(entry.value);
359260
+ if (existingGroup) {
359261
+ existingGroup.attrs.push(entry.attr);
359262
+ continue;
359263
+ }
359264
+ groupsByValue.set(entry.value, { value: entry.value, attrs: [entry.attr] });
359265
+ }
359266
+ return [...groupsByValue.values()];
359267
+ }
359268
+ function createDeterministicDocxIdAllocator2(reservedIds) {
359269
+ let nextValue = 1;
359270
+ return () => {
359271
+ while (nextValue <= MAX_DOCX_ID2) {
359272
+ const id2 = nextValue.toString(16).toUpperCase().padStart(DOCX_ID_LENGTH2, "0");
359273
+ nextValue += 1;
359274
+ if (reservedIds.has(id2))
359275
+ continue;
359276
+ reservedIds.add(id2);
359277
+ return id2;
359278
+ }
359279
+ throw new Error("Unable to allocate a unique synthetic DOCX block id.");
359280
+ };
359281
+ }
359282
+ var PARAGRAPH_IDENTITY_ATTRS2, TABLE_IDENTITY_ATTRS2, DEFAULT_BLOCK_IDENTITY_ATTRS2, SYNTHETIC_PARA_ID_TYPES2, DOCX_ID_LENGTH2 = 8, MAX_DOCX_ID2 = 4294967295, BLOCK_IDENTITY_ATTRS2;
359283
+ var init_block_identity_renaming = __esm(() => {
359284
+ PARAGRAPH_IDENTITY_ATTRS2 = ["sdBlockId", "paraId"];
359285
+ TABLE_IDENTITY_ATTRS2 = ["sdBlockId", "paraId", "blockId"];
359286
+ DEFAULT_BLOCK_IDENTITY_ATTRS2 = ["sdBlockId", "blockId", "paraId"];
359287
+ SYNTHETIC_PARA_ID_TYPES2 = new Set(["paragraph", "tableRow"]);
359288
+ BLOCK_IDENTITY_ATTRS2 = {
359289
+ paragraph: PARAGRAPH_IDENTITY_ATTRS2,
359290
+ heading: DEFAULT_BLOCK_IDENTITY_ATTRS2,
359291
+ listItem: DEFAULT_BLOCK_IDENTITY_ATTRS2,
359292
+ table: TABLE_IDENTITY_ATTRS2,
359293
+ tableRow: TABLE_IDENTITY_ATTRS2,
359294
+ tableCell: TABLE_IDENTITY_ATTRS2,
359295
+ tableHeader: TABLE_IDENTITY_ATTRS2,
359296
+ sdt: DEFAULT_BLOCK_IDENTITY_ATTRS2,
359297
+ structuredContentBlock: DEFAULT_BLOCK_IDENTITY_ATTRS2
359298
+ };
359299
+ });
359300
+
358931
359301
  // ../../packages/super-editor/src/editors/v1/document-api-adapters/helpers/node-address-resolver.ts
358932
359302
  function isListItem3(attrs) {
358933
359303
  const numbering = attrs?.paragraphProperties?.numberingProperties;
@@ -359031,6 +359401,7 @@ function buildBlockIndex2(editor) {
359031
359401
  const byId = new Map;
359032
359402
  const ambiguous = new Set;
359033
359403
  const pathByNode = new WeakMap;
359404
+ const explicitIdentities = new Map;
359034
359405
  pathByNode.set(editor.state.doc, []);
359035
359406
  function registerKey(key2, candidate) {
359036
359407
  if (byId.has(key2)) {
@@ -359040,12 +359411,44 @@ function buildBlockIndex2(editor) {
359040
359411
  byId.set(key2, candidate);
359041
359412
  }
359042
359413
  }
359414
+ function recordExplicitIdentities(node2, pos) {
359415
+ const attrPriority = getBlockIdentityAttrsForType2(node2.type?.name);
359416
+ if (attrPriority.length === 0)
359417
+ return;
359418
+ const attrs = node2.attrs ?? {};
359419
+ let nodeGroups;
359420
+ for (const attr of attrPriority) {
359421
+ const value = toIdentityValue2(attrs[attr]);
359422
+ if (!value)
359423
+ continue;
359424
+ if (!nodeGroups)
359425
+ nodeGroups = new Map;
359426
+ const existing = nodeGroups.get(value);
359427
+ if (existing) {
359428
+ existing.push(attr);
359429
+ } else {
359430
+ nodeGroups.set(value, [attr]);
359431
+ }
359432
+ }
359433
+ if (!nodeGroups)
359434
+ return;
359435
+ for (const [value, attrsForValue] of nodeGroups) {
359436
+ const observations = explicitIdentities.get(value);
359437
+ const observation = { pos, attrs: attrsForValue };
359438
+ if (observations) {
359439
+ observations.push(observation);
359440
+ } else {
359441
+ explicitIdentities.set(value, [observation]);
359442
+ }
359443
+ }
359444
+ }
359043
359445
  editor.state.doc.descendants((node2, pos, parent, index2) => {
359044
359446
  const parentPath = parent ? pathByNode.get(parent) ?? [] : [];
359045
359447
  const path2 = typeof index2 === "number" && Number.isInteger(index2) && index2 >= 0 ? [...parentPath, index2] : undefined;
359046
359448
  if (path2) {
359047
359449
  pathByNode.set(node2, path2);
359048
359450
  }
359451
+ recordExplicitIdentities(node2, pos);
359049
359452
  const nodeType = mapBlockNodeType2(node2);
359050
359453
  if (!nodeType)
359051
359454
  return;
@@ -359066,7 +359469,7 @@ function buildBlockIndex2(editor) {
359066
359469
  registerKey(`${nodeType}:${aliasId}`, candidate);
359067
359470
  }
359068
359471
  });
359069
- return { candidates, byId, ambiguous };
359472
+ return { candidates, byId, ambiguous, explicitIdentities };
359070
359473
  }
359071
359474
  function findBlockById2(index2, address) {
359072
359475
  if (address.kind !== "block")
@@ -359151,6 +359554,7 @@ var SUPPORTED_BLOCK_NODE_TYPES, ALIAS_ELIGIBLE_TYPES2;
359151
359554
  var init_node_address_resolver = __esm(() => {
359152
359555
  init_deterministic_node_id();
359153
359556
  init_errors4();
359557
+ init_block_identity_renaming();
359154
359558
  SUPPORTED_BLOCK_NODE_TYPES = new Set([
359155
359559
  "paragraph",
359156
359560
  "heading",
@@ -391965,9 +392369,11 @@ function trackRevisions2(editor) {
391965
392369
  return;
391966
392370
  subscribedEditors2.add(editor);
391967
392371
  editor.on("transaction", ({ transaction }) => {
391968
- if (transaction.docChanged) {
391969
- incrementRevision2(editor);
391970
- }
392372
+ if (transaction.getMeta?.("superdoc/block-identity-repair"))
392373
+ return;
392374
+ if (!transaction.docChanged)
392375
+ return;
392376
+ incrementRevision2(editor);
391971
392377
  });
391972
392378
  }
391973
392379
  function checkRevision2(editor, expectedRevision) {
@@ -405287,6 +405693,8 @@ function resolveStoryRuntime2(hostEditor, locator, options = {}) {
405287
405693
  if (store && !hasHostStoreSyncListener2(runtime.editor, storyKey)) {
405288
405694
  markHostStoreSyncListener2(runtime.editor, storyKey);
405289
405695
  runtime.editor.on("transaction", ({ transaction }) => {
405696
+ if (transaction.getMeta?.("superdoc/block-identity-repair"))
405697
+ return;
405290
405698
  if (transaction.docChanged) {
405291
405699
  incrementStoryRevision2(store, storyKey);
405292
405700
  }
@@ -457234,54 +457642,10 @@ var init_math3 = __esm(() => {
457234
457642
  });
457235
457643
 
457236
457644
  // ../../packages/super-editor/src/editors/v1/core/super-converter/v2/importer/normalizeDuplicateBlockIdentitiesInContent.js
457237
- function toIdentityValue2(value) {
457238
- if (typeof value === "string" && value.length > 0)
457239
- return value;
457240
- if (typeof value === "number" && Number.isFinite(value))
457241
- return String(value);
457242
- return;
457243
- }
457244
- function getBlockIdentityAttrs2(node4) {
457245
- if (!node4 || typeof node4 !== "object")
457246
- return [];
457247
- return BLOCK_IDENTITY_ATTRS2[node4.type] ?? [];
457248
- }
457249
- function getExplicitIdentityEntries2(node4) {
457250
- const attrPriority = getBlockIdentityAttrs2(node4);
457251
- if (attrPriority.length === 0)
457252
- return [];
457253
- const attrs = typeof node4.attrs === "object" && node4.attrs ? node4.attrs : {};
457254
- const identityEntries = [];
457255
- for (const attr of attrPriority) {
457256
- const value = toIdentityValue2(attrs[attr]);
457257
- if (value) {
457258
- identityEntries.push({ attr, value });
457259
- }
457260
- }
457261
- return identityEntries;
457262
- }
457263
- function groupIdentityEntriesByValue2(identityEntries) {
457264
- const groupsByValue = new Map;
457265
- for (const entry of identityEntries) {
457266
- const existingGroup = groupsByValue.get(entry.value);
457267
- if (existingGroup) {
457268
- existingGroup.attrs.push(entry.attr);
457269
- continue;
457270
- }
457271
- groupsByValue.set(entry.value, {
457272
- value: entry.value,
457273
- attrs: [entry.attr]
457274
- });
457275
- }
457276
- return [...groupsByValue.values()];
457277
- }
457278
- function shouldSynthesizeParaId2(node4) {
457279
- return Boolean(node4 && typeof node4 === "object" && SYNTHETIC_PARA_ID_TYPES2.has(node4.type));
457280
- }
457281
457645
  function collectExplicitBlockIdentities2(node4, reservedIds) {
457282
457646
  if (!node4 || typeof node4 !== "object")
457283
457647
  return;
457284
- const identityEntries = getExplicitIdentityEntries2(node4);
457648
+ const identityEntries = getExplicitIdentityEntries2(node4.attrs, node4?.type);
457285
457649
  for (const { value } of groupIdentityEntriesByValue2(identityEntries)) {
457286
457650
  reservedIds.add(value);
457287
457651
  }
@@ -457289,27 +457653,13 @@ function collectExplicitBlockIdentities2(node4, reservedIds) {
457289
457653
  node4.content.forEach((child) => collectExplicitBlockIdentities2(child, reservedIds));
457290
457654
  }
457291
457655
  }
457292
- function createDeterministicDocxIdAllocator2(reservedIds) {
457293
- let nextValue = 1;
457294
- return () => {
457295
- while (nextValue <= MAX_DOCX_ID2) {
457296
- const id2 = nextValue.toString(16).toUpperCase().padStart(DOCX_ID_LENGTH2, "0");
457297
- nextValue += 1;
457298
- if (reservedIds.has(id2))
457299
- continue;
457300
- reservedIds.add(id2);
457301
- return id2;
457302
- }
457303
- throw new Error("Unable to allocate a unique synthetic DOCX block id.");
457304
- };
457305
- }
457306
457656
  function setBlockIdentity2(node4, attrName, value) {
457307
457657
  node4.attrs = { ...node4.attrs ?? {}, [attrName]: value };
457308
457658
  }
457309
457659
  function normalizeBlockIdentitiesInNode2(node4, seenIds, allocateDocxId) {
457310
457660
  if (!node4 || typeof node4 !== "object")
457311
457661
  return;
457312
- const identityEntries = getExplicitIdentityEntries2(node4);
457662
+ const identityEntries = getExplicitIdentityEntries2(node4.attrs, node4?.type);
457313
457663
  const groupedIdentities = groupIdentityEntriesByValue2(identityEntries);
457314
457664
  if (groupedIdentities.length > 0) {
457315
457665
  for (const identityGroup of groupedIdentities) {
@@ -457323,7 +457673,7 @@ function normalizeBlockIdentitiesInNode2(node4, seenIds, allocateDocxId) {
457323
457673
  seenIds.add(identityGroup.value);
457324
457674
  }
457325
457675
  }
457326
- } else if (shouldSynthesizeParaId2(node4)) {
457676
+ } else if (shouldSynthesizeParaIdForType2(node4?.type)) {
457327
457677
  const syntheticParaId = allocateDocxId();
457328
457678
  setBlockIdentity2(node4, "paraId", syntheticParaId);
457329
457679
  seenIds.add(syntheticParaId);
@@ -457342,23 +457692,8 @@ function normalizeDuplicateBlockIdentitiesInContent2(content4 = []) {
457342
457692
  content4.forEach((node4) => normalizeBlockIdentitiesInNode2(node4, seenIds, allocateDocxId));
457343
457693
  return content4;
457344
457694
  }
457345
- var PARAGRAPH_IDENTITY_ATTRS2, TABLE_IDENTITY_ATTRS2, DEFAULT_BLOCK_IDENTITY_ATTRS2, SYNTHETIC_PARA_ID_TYPES2, DOCX_ID_LENGTH2 = 8, MAX_DOCX_ID2 = 4294967295, BLOCK_IDENTITY_ATTRS2;
457346
457695
  var init_normalizeDuplicateBlockIdentitiesInContent = __esm(() => {
457347
- PARAGRAPH_IDENTITY_ATTRS2 = ["sdBlockId", "paraId"];
457348
- TABLE_IDENTITY_ATTRS2 = ["sdBlockId", "paraId", "blockId"];
457349
- DEFAULT_BLOCK_IDENTITY_ATTRS2 = ["sdBlockId", "blockId", "paraId"];
457350
- SYNTHETIC_PARA_ID_TYPES2 = new Set(["paragraph", "tableRow"]);
457351
- BLOCK_IDENTITY_ATTRS2 = {
457352
- paragraph: PARAGRAPH_IDENTITY_ATTRS2,
457353
- heading: DEFAULT_BLOCK_IDENTITY_ATTRS2,
457354
- listItem: DEFAULT_BLOCK_IDENTITY_ATTRS2,
457355
- table: TABLE_IDENTITY_ATTRS2,
457356
- tableRow: TABLE_IDENTITY_ATTRS2,
457357
- tableCell: TABLE_IDENTITY_ATTRS2,
457358
- tableHeader: TABLE_IDENTITY_ATTRS2,
457359
- sdt: DEFAULT_BLOCK_IDENTITY_ATTRS2,
457360
- structuredContentBlock: DEFAULT_BLOCK_IDENTITY_ATTRS2
457361
- };
457696
+ init_block_identity_renaming();
457362
457697
  });
457363
457698
 
457364
457699
  // ../../packages/super-editor/src/editors/v1/core/super-converter/v3/handlers/w/styles/index.js
@@ -471936,6 +472271,168 @@ var init_executor_registry = __esm(() => {
471936
472271
  registry3 = new Map;
471937
472272
  });
471938
472273
 
472274
+ // ../../packages/super-editor/src/editors/v1/document-api-adapters/plan-engine/repair-block-identities.ts
472275
+ function planRepairs2(doc6, identityMap) {
472276
+ if (identityMap) {
472277
+ return planRepairsFromIdentityMap2(identityMap);
472278
+ }
472279
+ return planRepairsByWalk2(doc6);
472280
+ }
472281
+ function planRepairsFromIdentityMap2(identityMap) {
472282
+ let hasDuplicates = false;
472283
+ for (const observations of identityMap.values()) {
472284
+ if (observations.length > 1) {
472285
+ hasDuplicates = true;
472286
+ break;
472287
+ }
472288
+ }
472289
+ if (!hasDuplicates) {
472290
+ return { plans: [], report: { repairedBlockCount: 0, duplicateBlockIds: [], renames: [] } };
472291
+ }
472292
+ const rewrites = [];
472293
+ for (const [value, observations] of identityMap) {
472294
+ if (observations.length <= 1)
472295
+ continue;
472296
+ for (let i5 = 1;i5 < observations.length; i5 += 1) {
472297
+ const { pos, attrs } = observations[i5];
472298
+ rewrites.push({ pos, value, attrs });
472299
+ }
472300
+ }
472301
+ rewrites.sort((a2, b2) => a2.pos - b2.pos);
472302
+ const reservedIds = new Set(identityMap.keys());
472303
+ const allocateDocxId = createDeterministicDocxIdAllocator2(reservedIds);
472304
+ const plansByPos = new Map;
472305
+ const duplicateBlockIds = [];
472306
+ const renames = [];
472307
+ for (const { pos, value, attrs } of rewrites) {
472308
+ const replacementValue = allocateDocxId();
472309
+ let plan = plansByPos.get(pos);
472310
+ if (!plan) {
472311
+ plan = { pos, rewrittenGroups: [] };
472312
+ plansByPos.set(pos, plan);
472313
+ }
472314
+ const attrsCopy = [...attrs];
472315
+ plan.rewrittenGroups.push({ originalValue: value, replacementValue, attrs: attrsCopy });
472316
+ duplicateBlockIds.push(value);
472317
+ renames.push({ originalValue: value, replacementValue, attrs: attrsCopy });
472318
+ }
472319
+ const plans = [...plansByPos.values()].sort((a2, b2) => a2.pos - b2.pos);
472320
+ return {
472321
+ plans,
472322
+ report: { repairedBlockCount: plans.length, duplicateBlockIds, renames }
472323
+ };
472324
+ }
472325
+ function planRepairsByWalk2(doc6) {
472326
+ const reservedIds = new Set;
472327
+ let hasDuplicates = false;
472328
+ doc6.descendants((node4) => {
472329
+ const entries = getExplicitIdentityEntries2(node4.attrs, node4.type?.name);
472330
+ for (const { value } of groupIdentityEntriesByValue2(entries)) {
472331
+ if (reservedIds.has(value)) {
472332
+ hasDuplicates = true;
472333
+ } else {
472334
+ reservedIds.add(value);
472335
+ }
472336
+ }
472337
+ });
472338
+ if (!hasDuplicates) {
472339
+ return { plans: [], report: { repairedBlockCount: 0, duplicateBlockIds: [], renames: [] } };
472340
+ }
472341
+ const allocateDocxId = createDeterministicDocxIdAllocator2(reservedIds);
472342
+ const seenIds = new Set;
472343
+ const plans = [];
472344
+ const duplicateBlockIds = [];
472345
+ const renames = [];
472346
+ doc6.descendants((node4, pos) => {
472347
+ const entries = getExplicitIdentityEntries2(node4.attrs, node4.type?.name);
472348
+ const groups = groupIdentityEntriesByValue2(entries);
472349
+ if (groups.length === 0)
472350
+ return;
472351
+ let plan = null;
472352
+ for (const group of groups) {
472353
+ if (seenIds.has(group.value)) {
472354
+ if (!plan)
472355
+ plan = { pos, rewrittenGroups: [] };
472356
+ const replacementValue = allocateDocxId();
472357
+ plan.rewrittenGroups.push({ originalValue: group.value, replacementValue, attrs: [...group.attrs] });
472358
+ duplicateBlockIds.push(group.value);
472359
+ renames.push({ originalValue: group.value, replacementValue, attrs: [...group.attrs] });
472360
+ seenIds.add(replacementValue);
472361
+ } else {
472362
+ seenIds.add(group.value);
472363
+ }
472364
+ }
472365
+ if (plan)
472366
+ plans.push(plan);
472367
+ });
472368
+ return {
472369
+ plans,
472370
+ report: { repairedBlockCount: plans.length, duplicateBlockIds, renames }
472371
+ };
472372
+ }
472373
+ function repairDuplicateBlockIdentities2(editor) {
472374
+ const doc6 = editor.state?.doc;
472375
+ if (!doc6 || typeof doc6.descendants !== "function")
472376
+ return null;
472377
+ if (typeof editor.state?.tr !== "object" || editor.state.tr === null)
472378
+ return null;
472379
+ if (typeof editor.dispatch !== "function")
472380
+ return null;
472381
+ let identityMap;
472382
+ try {
472383
+ identityMap = getBlockIndex2(editor).explicitIdentities;
472384
+ } catch {
472385
+ identityMap = undefined;
472386
+ }
472387
+ const { plans, report } = planRepairs2(doc6, identityMap);
472388
+ if (plans.length === 0)
472389
+ return null;
472390
+ const tr = editor.state.tr;
472391
+ tr.setMeta("addToHistory", false);
472392
+ tr.setMeta("superdoc/block-identity-repair", report);
472393
+ for (const plan of plans) {
472394
+ for (const group of plan.rewrittenGroups) {
472395
+ for (const attr of group.attrs) {
472396
+ tr.setNodeAttribute(plan.pos, attr, group.replacementValue);
472397
+ }
472398
+ }
472399
+ }
472400
+ editor.dispatch(tr);
472401
+ const blockedNodeIds = [];
472402
+ for (const plan of plans) {
472403
+ const node4 = editor.state.doc.nodeAt(plan.pos);
472404
+ if (!node4) {
472405
+ blockedNodeIds.push(`pos:${plan.pos}`);
472406
+ continue;
472407
+ }
472408
+ for (const group of plan.rewrittenGroups) {
472409
+ for (const attr of group.attrs) {
472410
+ if (node4.attrs?.[attr] !== group.replacementValue) {
472411
+ const observedId = typeof node4.attrs?.id === "string" && node4.attrs.id || typeof node4.attrs?.sdBlockId === "string" && node4.attrs.sdBlockId || `pos:${plan.pos}`;
472412
+ blockedNodeIds.push(observedId);
472413
+ }
472414
+ }
472415
+ }
472416
+ }
472417
+ if (blockedNodeIds.length > 0) {
472418
+ const unique2 = [...new Set(blockedNodeIds)];
472419
+ const MAX_ID_PREVIEW_LENGTH = 32;
472420
+ const truncate = (id2) => id2.length > MAX_ID_PREVIEW_LENGTH ? `${id2.slice(0, MAX_ID_PREVIEW_LENGTH - 1)}…` : id2;
472421
+ const preview = unique2.slice(0, 4).map(truncate).join(", ");
472422
+ const previewSuffix = unique2.length > 4 ? `, +${unique2.length - 4} more` : "";
472423
+ throw planError2("REPAIR_BLOCKED", `Runtime identity repair was rejected by a transaction filter ` + `(${unique2.length} node${unique2.length === 1 ? "" : "s"}: ${preview}${previewSuffix}). ` + `A structured-content lock or permission range likely covers one of the duplicate blocks. ` + `Re-import the document via doc.open to assign unique identities.`, undefined, {
472424
+ blockedNodeIds: unique2,
472425
+ remediation: "Re-import the document via doc.open to assign unique identities."
472426
+ });
472427
+ }
472428
+ return report;
472429
+ }
472430
+ var init_repair_block_identities = __esm(() => {
472431
+ init_block_identity_renaming();
472432
+ init_index_cache();
472433
+ init_errors6();
472434
+ });
472435
+
471939
472436
  // ../../packages/super-editor/src/editors/v1/document-api-adapters/helpers/selection-target-resolver.ts
471940
472437
  function resolveTextPoint3(editor, index3, point7) {
471941
472438
  const candidate = findTextBlockByNodeId2(index3, point7.blockId);
@@ -472899,10 +473396,12 @@ function assertNoDuplicateBlockIds2(index3) {
472899
473396
  duplicates.push(candidate.nodeId);
472900
473397
  }
472901
473398
  if (duplicates.length > 0) {
472902
- throw planError2("DOCUMENT_IDENTITY_CONFLICT", "Document contains blocks with duplicate identities. This must be resolved before mutations can be applied.", undefined, {
473399
+ const preview = duplicates.slice(0, 4).join(", ");
473400
+ const previewSuffix = duplicates.length > 4 ? `, +${duplicates.length - 4} more` : "";
473401
+ throw planError2("DOCUMENT_IDENTITY_CONFLICT", `Document contains ${duplicates.length} block identit${duplicates.length === 1 ? "y" : "ies"} shared by multiple blocks (${preview}${previewSuffix}). Re-import the document via doc.open to assign unique identities.`, undefined, {
472903
473402
  duplicateBlockIds: duplicates,
472904
473403
  blockCount: duplicates.length,
472905
- remediation: "Re-import the document or call document.repair() to assign unique identities."
473404
+ remediation: "Re-import the document via doc.open to assign unique identities."
472906
473405
  });
472907
473406
  }
472908
473407
  }
@@ -472933,12 +473432,76 @@ function assertSingleStoryKey2(steps) {
472933
473432
  }
472934
473433
  }
472935
473434
  }
473435
+ function collectReferencedBlockIds2(step3) {
473436
+ const where = step3.where;
473437
+ const ids = [];
473438
+ const withinNodeId = where.within?.nodeId;
473439
+ if (withinNodeId)
473440
+ ids.push(withinNodeId);
473441
+ if (isRefWhere2(where)) {
473442
+ const ref4 = where.ref;
473443
+ if (ref4.startsWith("text:")) {
473444
+ const decoded = decodeRef2(ref4);
473445
+ if (decoded) {
473446
+ for (const seg of decoded.segments ?? []) {
473447
+ if (seg?.blockId)
473448
+ ids.push(seg.blockId);
473449
+ }
473450
+ const nodeId = decoded.node?.nodeId;
473451
+ if (nodeId)
473452
+ ids.push(nodeId);
473453
+ }
473454
+ } else {
473455
+ ids.push(ref4);
473456
+ }
473457
+ return ids;
473458
+ }
473459
+ if (isBlockWhere2(where)) {
473460
+ ids.push(where.nodeId);
473461
+ return ids;
473462
+ }
473463
+ if (isTargetWhere2(where)) {
473464
+ for (const point7 of [where.target?.start, where.target?.end]) {
473465
+ const blockId = point7?.blockId;
473466
+ if (blockId)
473467
+ ids.push(blockId);
473468
+ const edgeNodeId = point7?.node?.nodeId;
473469
+ if (edgeNodeId)
473470
+ ids.push(edgeNodeId);
473471
+ }
473472
+ }
473473
+ return ids;
473474
+ }
473475
+ function assertNoStaleRefsAfterRepair2(steps, repairedIds) {
473476
+ if (repairedIds.size === 0)
473477
+ return;
473478
+ for (const step3 of steps) {
473479
+ for (const blockId of collectReferencedBlockIds2(step3)) {
473480
+ if (!repairedIds.has(blockId))
473481
+ continue;
473482
+ throw planError2("STALE_REF", `Step "${step3.id}" references block id "${blockId}", which was duplicated in this document and has just ` + `been repaired (the duplicate occurrence was renamed). The reference is ambiguous — it may have pointed ` + `at the renamed block. Re-run query.match / doc.find against the repaired document and retry with a fresh ref.`, step3.id, {
473483
+ blockId,
473484
+ repairedBlockIds: [...repairedIds],
473485
+ remediation: "Re-run query.match() or doc.find() to obtain fresh refs, then retry the mutation."
473486
+ });
473487
+ }
473488
+ }
473489
+ }
472936
473490
  function compilePlan2(editor, steps, options = {}) {
472937
473491
  if (steps.length > MAX_PLAN_STEPS2) {
472938
473492
  throw planError2("INVALID_INPUT", `plan contains ${steps.length} steps, maximum is ${MAX_PLAN_STEPS2}`);
472939
473493
  }
473494
+ let index3 = getBlockIndex2(editor);
473495
+ if (!options.skipIdentityRepair) {
473496
+ const repair = repairDuplicateBlockIdentities2(editor);
473497
+ if (repair) {
473498
+ clearIndexCache2(editor);
473499
+ index3 = getBlockIndex2(editor);
473500
+ console.warn(`[plan-engine] Repaired ${repair.repairedBlockCount} block(s) with duplicate identities ` + `before plan compilation. Original ids: ${repair.duplicateBlockIds.slice(0, 4).join(", ")}` + `${repair.duplicateBlockIds.length > 4 ? `, +${repair.duplicateBlockIds.length - 4} more` : ""}.`);
473501
+ assertNoStaleRefsAfterRepair2(steps, new Set(repair.duplicateBlockIds));
473502
+ }
473503
+ }
472940
473504
  const compiledRevision = getRevision2(editor);
472941
- const index3 = getBlockIndex2(editor);
472942
473505
  assertNoDuplicateBlockIds2(index3);
472943
473506
  const mutationSteps = [];
472944
473507
  const assertSteps = [];
@@ -472994,6 +473557,7 @@ var init_compiler = __esm(() => {
472994
473557
  init_style_resolver();
472995
473558
  init_index_cache();
472996
473559
  init_revision_tracker();
473560
+ init_repair_block_identities();
472997
473561
  init_text_strategy();
472998
473562
  init_block_strategy();
472999
473563
  init_node_address_resolver();
@@ -475201,6 +475765,7 @@ function executePlan2(editor, input2) {
475201
475765
  if (!input2.steps?.length) {
475202
475766
  throw planError2("INVALID_INPUT", "plan must contain at least one step");
475203
475767
  }
475768
+ checkRevision2(editor, input2.expectedRevision);
475204
475769
  const compiled = compilePlan2(editor, input2.steps, {
475205
475770
  selectTextModel: input2.changeMode === "tracked" ? "raw" : "visible"
475206
475771
  });
@@ -476706,7 +477271,8 @@ function selectionMutationWrapper2(editor, request, options) {
476706
477271
  const stepId = v4_default2();
476707
477272
  const where = buildSelectionWhere2(request);
476708
477273
  const step3 = buildSelectionStepDef2(stepId, request, where);
476709
- const compiled = compilePlan2(storyEditor, [step3]);
477274
+ checkRevision2(storyEditor, options?.expectedRevision);
477275
+ const compiled = compilePlan2(storyEditor, [step3], options?.dryRun ? { skipIdentityRepair: true } : undefined);
476710
477276
  if (request.kind === "insert" && request.target) {
476711
477277
  const hasNodeEdge = request.target.start.kind === "nodeEdge" || request.target.end.kind === "nodeEdge";
476712
477278
  if (hasNodeEdge) {
@@ -476741,7 +477307,6 @@ function selectionMutationWrapper2(editor, request, options) {
476741
477307
  }
476742
477308
  }
476743
477309
  }
476744
- checkRevision2(storyEditor, options?.expectedRevision);
476745
477310
  if (options?.dryRun) {
476746
477311
  const resolution2 = buildSelectionResolutionFromCompiled2(compiled, stepId);
476747
477312
  if (request.kind === "insert" && !request.text) {
@@ -476904,6 +477469,7 @@ function insertStructuredInner2(editor, input2, options) {
476904
477469
  }
476905
477470
  effectiveTarget = { kind: "text", blockId, range: { start: offset2, end: offset2 } };
476906
477471
  } else if (ref4) {
477472
+ checkRevision2(editor, options?.expectedRevision);
476907
477473
  const dummyStepId = v4_default2();
476908
477474
  const dummyStep = {
476909
477475
  id: dummyStepId,
@@ -476911,7 +477477,7 @@ function insertStructuredInner2(editor, input2, options) {
476911
477477
  where: { by: "ref", ref: ref4 },
476912
477478
  args: { position: "before", content: { text: "" } }
476913
477479
  };
476914
- const compiled = compilePlan2(editor, [dummyStep]);
477480
+ const compiled = compilePlan2(editor, [dummyStep], options?.dryRun ? { skipIdentityRepair: true } : undefined);
476915
477481
  const compiledStep = compiled.mutationSteps.find((s2) => s2.step.id === dummyStepId);
476916
477482
  const compiledTarget = compiledStep?.targets[0];
476917
477483
  if (!compiledTarget) {
@@ -490619,7 +491185,7 @@ function previewPlan2(editor, input2) {
490619
491185
  let currentPhase = "compile";
490620
491186
  let evaluatedRevision = getRevision2(editor);
490621
491187
  try {
490622
- const compiled = compilePlan2(editor, input2.steps);
491188
+ const compiled = compilePlan2(editor, input2.steps, { skipIdentityRepair: true });
490623
491189
  evaluatedRevision = compiled.compiledRevision;
490624
491190
  currentPhase = "execute";
490625
491191
  const tr = editor.state.tr;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superdoc-dev/mcp",
3
- "version": "0.12.0-next.26",
3
+ "version": "0.12.0-next.27",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=20"