@superdoc-dev/mcp 0.12.0-next.25 → 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 +766 -174
  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-CCgGAnXY.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")
@@ -72379,6 +72379,22 @@ function fixTable(state, table, tablePos, tr) {
72379
72379
  }
72380
72380
  return tr.setMeta(fixTablesKey, { fixTables: true });
72381
72381
  }
72382
+ function findTable($pos) {
72383
+ return findParentNode$1((node2) => node2.type.spec.tableRole === "table", $pos);
72384
+ }
72385
+ function findParentNode$1(predicate, $pos) {
72386
+ for (let depth = $pos.depth;depth >= 0; depth -= 1) {
72387
+ const node2 = $pos.node(depth);
72388
+ if (predicate(node2))
72389
+ return {
72390
+ node: node2,
72391
+ pos: depth === 0 ? 0 : $pos.before(depth),
72392
+ start: $pos.start(depth),
72393
+ depth
72394
+ };
72395
+ }
72396
+ return null;
72397
+ }
72382
72398
  function selectedRect(state) {
72383
72399
  const sel = state.selection;
72384
72400
  const $pos = selectionCell(state);
@@ -74443,8 +74459,11 @@ function trackRevisions(editor) {
74443
74459
  return;
74444
74460
  subscribedEditors.add(editor);
74445
74461
  editor.on("transaction", ({ transaction }) => {
74446
- if (transaction.docChanged)
74447
- incrementRevision(editor);
74462
+ if (transaction.getMeta?.("superdoc/block-identity-repair"))
74463
+ return;
74464
+ if (!transaction.docChanged)
74465
+ return;
74466
+ incrementRevision(editor);
74448
74467
  });
74449
74468
  }
74450
74469
  function checkRevision(editor, expectedRevision) {
@@ -84380,19 +84399,22 @@ function toIdentityValue(value) {
84380
84399
  if (typeof value === "number" && Number.isFinite(value))
84381
84400
  return String(value);
84382
84401
  }
84383
- function getBlockIdentityAttrs(node2) {
84384
- if (!node2 || typeof node2 !== "object")
84402
+ function getBlockIdentityAttrsForType(typeName) {
84403
+ if (!typeName)
84385
84404
  return [];
84386
- 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));
84387
84409
  }
84388
- function getExplicitIdentityEntries(node2) {
84389
- const attrPriority = getBlockIdentityAttrs(node2);
84410
+ function getExplicitIdentityEntries(attrs, typeName) {
84411
+ const attrPriority = getBlockIdentityAttrsForType(typeName);
84390
84412
  if (attrPriority.length === 0)
84391
84413
  return [];
84392
- const attrs = typeof node2.attrs === "object" && node2.attrs ? node2.attrs : {};
84414
+ const safeAttrs = attrs && typeof attrs === "object" ? attrs : {};
84393
84415
  const identityEntries = [];
84394
84416
  for (const attr of attrPriority) {
84395
- const value = toIdentityValue(attrs[attr]);
84417
+ const value = toIdentityValue(safeAttrs[attr]);
84396
84418
  if (value)
84397
84419
  identityEntries.push({
84398
84420
  attr,
@@ -84416,18 +84438,6 @@ function groupIdentityEntriesByValue(identityEntries) {
84416
84438
  }
84417
84439
  return [...groupsByValue.values()];
84418
84440
  }
84419
- function shouldSynthesizeParaId(node2) {
84420
- return Boolean(node2 && typeof node2 === "object" && SYNTHETIC_PARA_ID_TYPES.has(node2.type));
84421
- }
84422
- function collectExplicitBlockIdentities(node2, reservedIds) {
84423
- if (!node2 || typeof node2 !== "object")
84424
- return;
84425
- const identityEntries = getExplicitIdentityEntries(node2);
84426
- for (const { value } of groupIdentityEntriesByValue(identityEntries))
84427
- reservedIds.add(value);
84428
- if (Array.isArray(node2.content))
84429
- node2.content.forEach((child) => collectExplicitBlockIdentities(child, reservedIds));
84430
- }
84431
84441
  function createDeterministicDocxIdAllocator(reservedIds) {
84432
84442
  let nextValue = 1;
84433
84443
  return () => {
@@ -84442,6 +84452,15 @@ function createDeterministicDocxIdAllocator(reservedIds) {
84442
84452
  throw new Error("Unable to allocate a unique synthetic DOCX block id.");
84443
84453
  };
84444
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
+ }
84445
84464
  function setBlockIdentity(node2, attrName, value) {
84446
84465
  node2.attrs = {
84447
84466
  ...node2.attrs ?? {},
@@ -84451,7 +84470,7 @@ function setBlockIdentity(node2, attrName, value) {
84451
84470
  function normalizeBlockIdentitiesInNode(node2, seenIds, allocateDocxId) {
84452
84471
  if (!node2 || typeof node2 !== "object")
84453
84472
  return;
84454
- const groupedIdentities = groupIdentityEntriesByValue(getExplicitIdentityEntries(node2));
84473
+ const groupedIdentities = groupIdentityEntriesByValue(getExplicitIdentityEntries(node2.attrs, node2?.type));
84455
84474
  if (groupedIdentities.length > 0)
84456
84475
  for (const identityGroup of groupedIdentities)
84457
84476
  if (seenIds.has(identityGroup.value)) {
@@ -84461,7 +84480,7 @@ function normalizeBlockIdentitiesInNode(node2, seenIds, allocateDocxId) {
84461
84480
  seenIds.add(replacementId);
84462
84481
  } else
84463
84482
  seenIds.add(identityGroup.value);
84464
- else if (shouldSynthesizeParaId(node2)) {
84483
+ else if (shouldSynthesizeParaIdForType(node2?.type)) {
84465
84484
  const syntheticParaId = allocateDocxId();
84466
84485
  setBlockIdentity(node2, "paraId", syntheticParaId);
84467
84486
  seenIds.add(syntheticParaId);
@@ -92079,6 +92098,7 @@ function buildBlockIndex(editor) {
92079
92098
  const byId = /* @__PURE__ */ new Map;
92080
92099
  const ambiguous = /* @__PURE__ */ new Set;
92081
92100
  const pathByNode = /* @__PURE__ */ new WeakMap;
92101
+ const explicitIdentities = /* @__PURE__ */ new Map;
92082
92102
  pathByNode.set(editor.state.doc, []);
92083
92103
  function registerKey(key, candidate) {
92084
92104
  if (byId.has(key)) {
@@ -92087,11 +92107,44 @@ function buildBlockIndex(editor) {
92087
92107
  } else if (!ambiguous.has(key))
92088
92108
  byId.set(key, candidate);
92089
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
+ }
92090
92142
  editor.state.doc.descendants((node2, pos, parent, index2) => {
92091
92143
  const parentPath = parent ? pathByNode.get(parent) ?? [] : [];
92092
92144
  const path2 = typeof index2 === "number" && Number.isInteger(index2) && index2 >= 0 ? [...parentPath, index2] : undefined;
92093
92145
  if (path2)
92094
92146
  pathByNode.set(node2, path2);
92147
+ recordExplicitIdentities(node2, pos);
92095
92148
  const nodeType = mapBlockNodeType(node2);
92096
92149
  if (!nodeType)
92097
92150
  return;
@@ -92114,7 +92167,8 @@ function buildBlockIndex(editor) {
92114
92167
  return {
92115
92168
  candidates,
92116
92169
  byId,
92117
- ambiguous
92170
+ ambiguous,
92171
+ explicitIdentities
92118
92172
  };
92119
92173
  }
92120
92174
  function findBlockById(index2, address) {
@@ -95699,6 +95753,8 @@ function resolveStoryRuntime(hostEditor, locator, options = {}) {
95699
95753
  if (store && !hasHostStoreSyncListener(runtime.editor, storyKey)) {
95700
95754
  markHostStoreSyncListener(runtime.editor, storyKey);
95701
95755
  runtime.editor.on("transaction", ({ transaction }) => {
95756
+ if (transaction.getMeta?.("superdoc/block-identity-repair"))
95757
+ return;
95702
95758
  if (transaction.docChanged)
95703
95759
  incrementStoryRevision(store, storyKey);
95704
95760
  });
@@ -118758,7 +118814,7 @@ var isRegExp = (value) => {
118758
118814
  state.kern = kernNode.attributes["w:val"];
118759
118815
  }
118760
118816
  }, SuperConverter;
118761
- var init_SuperConverter_CCgGAnXY_es = __esm(() => {
118817
+ var init_SuperConverter_DK5WIHuy_es = __esm(() => {
118762
118818
  init_rolldown_runtime_Bg48TavK_es();
118763
118819
  init_jszip_C49i9kUs_es();
118764
118820
  init_xml_js_CqGKpaft_es();
@@ -159502,7 +159558,7 @@ var init_SuperConverter_CCgGAnXY_es = __esm(() => {
159502
159558
  };
159503
159559
  });
159504
159560
 
159505
- // ../../packages/superdoc/dist/chunks/create-headless-toolbar-BvrKiWf0.es.js
159561
+ // ../../packages/superdoc/dist/chunks/create-headless-toolbar-BLN1v7eO.es.js
159506
159562
  function parseSizeUnit(val = "0") {
159507
159563
  const length = val.toString() || "0";
159508
159564
  const value = Number.parseFloat(length);
@@ -160985,6 +161041,194 @@ function applySetMarksToResolved(editor, existingMarks, setMarks) {
160985
161041
  }
160986
161042
  return marks;
160987
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
+ }
160988
161232
  function getCandidateText(editor, candidate, options) {
160989
161233
  if (candidate.node.childCount > 0)
160990
161234
  return textContentInBlock(candidate.node, options);
@@ -162189,12 +162433,15 @@ function assertNoDuplicateBlockIds(index2) {
162189
162433
  if (count === 1)
162190
162434
  duplicates.push(candidate.nodeId);
162191
162435
  }
162192
- if (duplicates.length > 0)
162193
- 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, {
162194
162440
  duplicateBlockIds: duplicates,
162195
162441
  blockCount: duplicates.length,
162196
- 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."
162197
162443
  });
162444
+ }
162198
162445
  }
162199
162446
  function assertSingleStoryKey(steps) {
162200
162447
  let seenStoryKey;
@@ -162222,11 +162469,71 @@ function assertSingleStoryKey(steps) {
162222
162469
  });
162223
162470
  }
162224
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
+ }
162225
162523
  function compilePlan(editor, steps, options = {}) {
162226
162524
  if (steps.length > 200)
162227
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
+ }
162228
162536
  const compiledRevision = getRevision(editor);
162229
- const index2 = getBlockIndex(editor);
162230
162537
  assertNoDuplicateBlockIds(index2);
162231
162538
  const mutationSteps = [];
162232
162539
  const assertSteps = [];
@@ -164319,6 +164626,7 @@ function executeCompiledPlan(editor, compiled, options = {}) {
164319
164626
  function executePlan(editor, input) {
164320
164627
  if (!input.steps?.length)
164321
164628
  throw planError("INVALID_INPUT", "plan must contain at least one step");
164629
+ checkRevision(editor, input.expectedRevision);
164322
164630
  return executeCompiledPlan(editor, compilePlan(editor, input.steps, { selectTextModel: input.changeMode === "tracked" ? "raw" : "visible" }), {
164323
164631
  changeMode: input.changeMode ?? "direct",
164324
164632
  expectedRevision: input.expectedRevision
@@ -165665,7 +165973,9 @@ function selectionMutationWrapper(editor, request, options) {
165665
165973
  ensureTrackedInlinePropertySupport(inlineKeys);
165666
165974
  }
165667
165975
  const stepId = v4_default();
165668
- 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);
165669
165979
  if (request.kind === "insert" && request.target) {
165670
165980
  if (request.target.start.kind === "nodeEdge" || request.target.end.kind === "nodeEdge")
165671
165981
  throw new DocumentApiAdapterError("INVALID_TARGET", "Text inserts do not support nodeEdge targets. Use a text-offset target inside a textblock.");
@@ -165695,7 +166005,6 @@ function selectionMutationWrapper(editor, request, options) {
165695
166005
  }
165696
166006
  }
165697
166007
  }
165698
- checkRevision(storyEditor, options?.expectedRevision);
165699
166008
  if (options?.dryRun) {
165700
166009
  const resolution$1 = buildSelectionResolutionFromCompiled(compiled, stepId);
165701
166010
  if (request.kind === "insert" && !request.text)
@@ -165913,6 +166222,7 @@ function insertStructuredInner(editor, input, options) {
165913
166222
  }
165914
166223
  };
165915
166224
  } else if (ref2) {
166225
+ checkRevision(editor, options?.expectedRevision);
165916
166226
  const dummyStepId = v4_default();
165917
166227
  const compiled = compilePlan(editor, [{
165918
166228
  id: dummyStepId,
@@ -165925,7 +166235,7 @@ function insertStructuredInner(editor, input, options) {
165925
166235
  position: "before",
165926
166236
  content: { text: "" }
165927
166237
  }
165928
- }]);
166238
+ }], options?.dryRun ? { skipIdentityRepair: true } : undefined);
165929
166239
  const compiledTarget = compiled.mutationSteps.find((s) => s.step.id === dummyStepId)?.targets[0];
165930
166240
  if (!compiledTarget)
165931
166241
  throw new DocumentApiAdapterError("TARGET_NOT_FOUND", "Structured insert ref could not be resolved.", { ref: ref2 });
@@ -169897,8 +170207,8 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, normalizeActorId = (value) => {
169897
170207
  }
169898
170208
  };
169899
170209
  };
169900
- var init_create_headless_toolbar_BvrKiWf0_es = __esm(() => {
169901
- init_SuperConverter_CCgGAnXY_es();
170210
+ var init_create_headless_toolbar_BLN1v7eO_es = __esm(() => {
170211
+ init_SuperConverter_DK5WIHuy_es();
169902
170212
  init_uuid_B2wVPhPi_es();
169903
170213
  init_constants_D9qj59G2_es();
169904
170214
  init_dist_B8HfvhaK_es();
@@ -224588,7 +224898,7 @@ var init_remark_gfm_eZN6yzWQ_es = __esm(() => {
224588
224898
  init_remark_gfm_BhnWr3yf_es();
224589
224899
  });
224590
224900
 
224591
- // ../../packages/superdoc/dist/chunks/src-BB0n1coY.es.js
224901
+ // ../../packages/superdoc/dist/chunks/src-PJVnllcq.es.js
224592
224902
  function deleteProps(obj, propOrProps) {
224593
224903
  const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
224594
224904
  const removeNested = (target, pathParts, index2 = 0) => {
@@ -248114,7 +248424,7 @@ function previewPlan(editor, input2) {
248114
248424
  let currentPhase = "compile";
248115
248425
  let evaluatedRevision = getRevision(editor);
248116
248426
  try {
248117
- const compiled = compilePlan(editor, input2.steps);
248427
+ const compiled = compilePlan(editor, input2.steps, { skipIdentityRepair: true });
248118
248428
  evaluatedRevision = compiled.compiledRevision;
248119
248429
  currentPhase = "execute";
248120
248430
  const tr = editor.state.tr;
@@ -275606,11 +275916,12 @@ function percentile(sortedValues, p$12) {
275606
275916
  return sortedValues[lower] * (1 - weight) + sortedValues[upper] * weight;
275607
275917
  }
275608
275918
  function pushEmptyLineSelectionBand(rects, opts) {
275919
+ const lineOffset = sumLineHeights(opts.measure, opts.startLineIndex, opts.lineIndex);
275609
275920
  rects.push({
275610
275921
  x: opts.x,
275611
- y: opts.y,
275922
+ y: opts.yBase + lineOffset,
275612
275923
  width: Math.max(1, opts.width),
275613
- height: opts.height,
275924
+ height: opts.lineHeight,
275614
275925
  pageIndex: opts.pageIndex
275615
275926
  });
275616
275927
  }
@@ -275641,13 +275952,15 @@ function selectionToRects(layout, blocks2, measures, from$1, to, geometryHelper)
275641
275952
  const sliceFrom = Math.max(range.pmStart, from$1);
275642
275953
  const sliceTo = Math.min(range.pmEnd, to);
275643
275954
  if (sliceFrom >= sliceTo) {
275644
- const emptyLineOffset = lineHeightBeforeIndex$1(measure, index2) - lineHeightBeforeIndex$1(measure, fragment.fromLine);
275645
275955
  pushEmptyLineSelectionBand(rects, {
275646
275956
  x: fragment.x,
275647
- y: fragment.y + emptyLineOffset + pageTopY,
275957
+ yBase: fragment.y + pageTopY,
275648
275958
  width: fragment.width,
275649
- height: line.lineHeight,
275650
- pageIndex
275959
+ lineHeight: line.lineHeight,
275960
+ pageIndex,
275961
+ measure,
275962
+ lineIndex: index2,
275963
+ startLineIndex: fragment.fromLine
275651
275964
  });
275652
275965
  return;
275653
275966
  }
@@ -275829,13 +276142,15 @@ function selectionToRects(layout, blocks2, measures, from$1, to, geometryHelper)
275829
276142
  const sliceFrom = Math.max(range.pmStart, from$1);
275830
276143
  const sliceTo = Math.min(range.pmEnd, to);
275831
276144
  if (sliceFrom >= sliceTo) {
275832
- const emptyLineOffset = lineHeightBeforeIndex$1(info.measure, index2) - lineHeightBeforeIndex$1(info.measure, info.startLine);
275833
276145
  pushEmptyLineSelectionBand(rects, {
275834
276146
  x: fragment.x + contentOffsetX + cellX + padding.left,
275835
- y: fragment.y + contentOffsetY + rowOffset + blockTopCursor + effectiveSpacingBeforePx + emptyLineOffset + pageTopY,
276147
+ yBase: fragment.y + contentOffsetY + rowOffset + blockTopCursor + effectiveSpacingBeforePx + pageTopY,
275836
276148
  width: cellMeasure.width - padding.left - padding.right,
275837
- height: line.lineHeight,
275838
- pageIndex
276149
+ lineHeight: line.lineHeight,
276150
+ pageIndex,
276151
+ measure: info.measure,
276152
+ lineIndex: index2,
276153
+ startLineIndex: info.startLine
275839
276154
  });
275840
276155
  return;
275841
276156
  }
@@ -276176,15 +276491,7 @@ function selectionCollapsesAcrossTableCells(doc$12, anchor, head) {
276176
276491
  return false;
276177
276492
  const $from = doc$12.resolve(Math.min(anchor, head));
276178
276493
  const $to = doc$12.resolve(Math.max(anchor, head));
276179
- const cellAncestor = (pos) => {
276180
- for (let depth = pos.depth;depth > 0; depth--) {
276181
- const role = pos.node(depth).type.spec.tableRole;
276182
- if (role === "cell" || role === "header_cell")
276183
- return pos.node(depth);
276184
- }
276185
- return null;
276186
- };
276187
- return cellAncestor($from) !== cellAncestor($to) && $to.parentOffset === 0;
276494
+ return cellWrapping2($from) !== cellWrapping2($to) && $to.parentOffset === 0;
276188
276495
  } catch {
276189
276496
  return false;
276190
276497
  }
@@ -278172,6 +278479,19 @@ function getTopLevelTableBlockAtPos(doc$12, blocks2, tablePos) {
278172
278479
  return null;
278173
278480
  return getTableBlocks(blocks2)[tableIndex] ?? null;
278174
278481
  }
278482
+ function resolveCellContextAtResolvedPos($pos) {
278483
+ const $cell = cellAround($pos);
278484
+ if (!$cell)
278485
+ return null;
278486
+ const table2 = findTable($cell);
278487
+ if (!table2)
278488
+ return null;
278489
+ return {
278490
+ $cell,
278491
+ cellPos: $cell.pos,
278492
+ tablePos: table2.pos
278493
+ };
278494
+ }
278175
278495
  function resolveCellAnchorStateFromCellPos(doc$12, blocks2, cellPos) {
278176
278496
  if (!doc$12 || !Number.isFinite(cellPos) || cellPos < 0 || cellPos > doc$12.content.size)
278177
278497
  return null;
@@ -278276,30 +278596,30 @@ function resolveCellContext(doc$12, pos) {
278276
278596
  } catch {
278277
278597
  return null;
278278
278598
  }
278279
- let cellDepth = -1;
278280
- let tableDepth = -1;
278281
- for (let depth = $pos.depth;depth > 0; depth--) {
278282
- const role = $pos.node(depth).type.spec.tableRole;
278283
- if (cellDepth === -1 && (role === "cell" || role === "header_cell"))
278284
- cellDepth = depth;
278285
- if (cellDepth !== -1 && role === "table") {
278286
- tableDepth = depth;
278287
- break;
278288
- }
278289
- }
278290
- if (cellDepth === -1 || tableDepth === -1)
278599
+ const context = resolveCellContextAtResolvedPos($pos);
278600
+ if (!context)
278291
278601
  return null;
278292
278602
  return {
278293
- cellPos: $pos.before(cellDepth),
278294
- tablePos: $pos.before(tableDepth)
278603
+ cellPos: context.cellPos,
278604
+ tablePos: context.tablePos
278295
278605
  };
278296
278606
  }
278297
278607
  function resolveCrossCellSelection(doc$12, anchorPos, headPos) {
278298
- const anchor = resolveCellContext(doc$12, anchorPos);
278299
- const head = resolveCellContext(doc$12, headPos);
278608
+ if (!doc$12)
278609
+ return null;
278610
+ let $anchorPos;
278611
+ let $headPos;
278612
+ try {
278613
+ $anchorPos = doc$12.resolve(anchorPos);
278614
+ $headPos = doc$12.resolve(headPos);
278615
+ } catch {
278616
+ return null;
278617
+ }
278618
+ const anchor = resolveCellContextAtResolvedPos($anchorPos);
278619
+ const head = resolveCellContextAtResolvedPos($headPos);
278300
278620
  if (!anchor || !head)
278301
278621
  return null;
278302
- if (anchor.tablePos !== head.tablePos)
278622
+ if (!inSameTable(anchor.$cell, head.$cell))
278303
278623
  return null;
278304
278624
  if (anchor.cellPos === head.cellPos)
278305
278625
  return null;
@@ -296339,7 +296659,8 @@ var Node$13 = class Node$14 {
296339
296659
  const ySyncMeta = tr.getMeta(ySyncPluginKey);
296340
296660
  const pendingDeadKeyPlaceholder = TrackChangesBasePluginKey.getState(state)?.pendingDeadKeyPlaceholder ?? null;
296341
296661
  const hasDisallowedMeta = tr.meta && Object.keys(tr.meta).some((meta4) => !ALLOWED_META_KEYS.has(meta4));
296342
- 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)) {
296343
296664
  if (pendingDeadKeyPlaceholder && !isCompositionTransaction(tr))
296344
296665
  mergeTrackChangesMeta(tr, { pendingDeadKeyPlaceholder: null });
296345
296666
  return tr;
@@ -322687,13 +323008,13 @@ menclose::after {
322687
323008
  return;
322688
323009
  console.log(...args$1);
322689
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;
322690
- var init_src_BB0n1coY_es = __esm(() => {
323011
+ var init_src_PJVnllcq_es = __esm(() => {
322691
323012
  init_rolldown_runtime_Bg48TavK_es();
322692
- init_SuperConverter_CCgGAnXY_es();
323013
+ init_SuperConverter_DK5WIHuy_es();
322693
323014
  init_jszip_C49i9kUs_es();
322694
323015
  init_xml_js_CqGKpaft_es();
322695
323016
  init_uuid_B2wVPhPi_es();
322696
- init_create_headless_toolbar_BvrKiWf0_es();
323017
+ init_create_headless_toolbar_BLN1v7eO_es();
322697
323018
  init_constants_D9qj59G2_es();
322698
323019
  init_dist_B8HfvhaK_es();
322699
323020
  init_unified_Dsuw2be5_es();
@@ -358478,11 +358799,11 @@ function print() { __p += __j.call(arguments, '') }
358478
358799
  ]);
358479
358800
  });
358480
358801
 
358481
- // ../../packages/superdoc/dist/chunks/create-super-doc-ui-C_J_pCF0.es.js
358802
+ // ../../packages/superdoc/dist/chunks/create-super-doc-ui-CrjXK3s_.es.js
358482
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;
358483
- var init_create_super_doc_ui_C_J_pCF0_es = __esm(() => {
358484
- init_SuperConverter_CCgGAnXY_es();
358485
- init_create_headless_toolbar_BvrKiWf0_es();
358804
+ var init_create_super_doc_ui_CrjXK3s__es = __esm(() => {
358805
+ init_SuperConverter_DK5WIHuy_es();
358806
+ init_create_headless_toolbar_BLN1v7eO_es();
358486
358807
  DEFAULT_TEXT_ALIGN_OPTIONS = [
358487
358808
  {
358488
358809
  label: "Left",
@@ -358773,16 +359094,16 @@ var init_zipper_yaJVJ4z9_es = __esm(() => {
358773
359094
 
358774
359095
  // ../../packages/superdoc/dist/super-editor.es.js
358775
359096
  var init_super_editor_es = __esm(() => {
358776
- init_src_BB0n1coY_es();
358777
- init_SuperConverter_CCgGAnXY_es();
359097
+ init_src_PJVnllcq_es();
359098
+ init_SuperConverter_DK5WIHuy_es();
358778
359099
  init_jszip_C49i9kUs_es();
358779
359100
  init_xml_js_CqGKpaft_es();
358780
- init_create_headless_toolbar_BvrKiWf0_es();
359101
+ init_create_headless_toolbar_BLN1v7eO_es();
358781
359102
  init_constants_D9qj59G2_es();
358782
359103
  init_dist_B8HfvhaK_es();
358783
359104
  init_unified_Dsuw2be5_es();
358784
359105
  init_DocxZipper_FUsfThjV_es();
358785
- init_create_super_doc_ui_C_J_pCF0_es();
359106
+ init_create_super_doc_ui_CrjXK3s__es();
358786
359107
  init_ui_C5PAS9hY_es();
358787
359108
  init_eventemitter3_BnGqBE_Q_es();
358788
359109
  init_errors_CNaD6vcg_es();
@@ -358902,6 +359223,81 @@ var init_errors4 = __esm(() => {
358902
359223
  };
358903
359224
  });
358904
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
+
358905
359301
  // ../../packages/super-editor/src/editors/v1/document-api-adapters/helpers/node-address-resolver.ts
358906
359302
  function isListItem3(attrs) {
358907
359303
  const numbering = attrs?.paragraphProperties?.numberingProperties;
@@ -359005,6 +359401,7 @@ function buildBlockIndex2(editor) {
359005
359401
  const byId = new Map;
359006
359402
  const ambiguous = new Set;
359007
359403
  const pathByNode = new WeakMap;
359404
+ const explicitIdentities = new Map;
359008
359405
  pathByNode.set(editor.state.doc, []);
359009
359406
  function registerKey(key2, candidate) {
359010
359407
  if (byId.has(key2)) {
@@ -359014,12 +359411,44 @@ function buildBlockIndex2(editor) {
359014
359411
  byId.set(key2, candidate);
359015
359412
  }
359016
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
+ }
359017
359445
  editor.state.doc.descendants((node2, pos, parent, index2) => {
359018
359446
  const parentPath = parent ? pathByNode.get(parent) ?? [] : [];
359019
359447
  const path2 = typeof index2 === "number" && Number.isInteger(index2) && index2 >= 0 ? [...parentPath, index2] : undefined;
359020
359448
  if (path2) {
359021
359449
  pathByNode.set(node2, path2);
359022
359450
  }
359451
+ recordExplicitIdentities(node2, pos);
359023
359452
  const nodeType = mapBlockNodeType2(node2);
359024
359453
  if (!nodeType)
359025
359454
  return;
@@ -359040,7 +359469,7 @@ function buildBlockIndex2(editor) {
359040
359469
  registerKey(`${nodeType}:${aliasId}`, candidate);
359041
359470
  }
359042
359471
  });
359043
- return { candidates, byId, ambiguous };
359472
+ return { candidates, byId, ambiguous, explicitIdentities };
359044
359473
  }
359045
359474
  function findBlockById2(index2, address) {
359046
359475
  if (address.kind !== "block")
@@ -359125,6 +359554,7 @@ var SUPPORTED_BLOCK_NODE_TYPES, ALIAS_ELIGIBLE_TYPES2;
359125
359554
  var init_node_address_resolver = __esm(() => {
359126
359555
  init_deterministic_node_id();
359127
359556
  init_errors4();
359557
+ init_block_identity_renaming();
359128
359558
  SUPPORTED_BLOCK_NODE_TYPES = new Set([
359129
359559
  "paragraph",
359130
359560
  "heading",
@@ -391939,9 +392369,11 @@ function trackRevisions2(editor) {
391939
392369
  return;
391940
392370
  subscribedEditors2.add(editor);
391941
392371
  editor.on("transaction", ({ transaction }) => {
391942
- if (transaction.docChanged) {
391943
- incrementRevision2(editor);
391944
- }
392372
+ if (transaction.getMeta?.("superdoc/block-identity-repair"))
392373
+ return;
392374
+ if (!transaction.docChanged)
392375
+ return;
392376
+ incrementRevision2(editor);
391945
392377
  });
391946
392378
  }
391947
392379
  function checkRevision2(editor, expectedRevision) {
@@ -405261,6 +405693,8 @@ function resolveStoryRuntime2(hostEditor, locator, options = {}) {
405261
405693
  if (store && !hasHostStoreSyncListener2(runtime.editor, storyKey)) {
405262
405694
  markHostStoreSyncListener2(runtime.editor, storyKey);
405263
405695
  runtime.editor.on("transaction", ({ transaction }) => {
405696
+ if (transaction.getMeta?.("superdoc/block-identity-repair"))
405697
+ return;
405264
405698
  if (transaction.docChanged) {
405265
405699
  incrementStoryRevision2(store, storyKey);
405266
405700
  }
@@ -457208,54 +457642,10 @@ var init_math3 = __esm(() => {
457208
457642
  });
457209
457643
 
457210
457644
  // ../../packages/super-editor/src/editors/v1/core/super-converter/v2/importer/normalizeDuplicateBlockIdentitiesInContent.js
457211
- function toIdentityValue2(value) {
457212
- if (typeof value === "string" && value.length > 0)
457213
- return value;
457214
- if (typeof value === "number" && Number.isFinite(value))
457215
- return String(value);
457216
- return;
457217
- }
457218
- function getBlockIdentityAttrs2(node4) {
457219
- if (!node4 || typeof node4 !== "object")
457220
- return [];
457221
- return BLOCK_IDENTITY_ATTRS2[node4.type] ?? [];
457222
- }
457223
- function getExplicitIdentityEntries2(node4) {
457224
- const attrPriority = getBlockIdentityAttrs2(node4);
457225
- if (attrPriority.length === 0)
457226
- return [];
457227
- const attrs = typeof node4.attrs === "object" && node4.attrs ? node4.attrs : {};
457228
- const identityEntries = [];
457229
- for (const attr of attrPriority) {
457230
- const value = toIdentityValue2(attrs[attr]);
457231
- if (value) {
457232
- identityEntries.push({ attr, value });
457233
- }
457234
- }
457235
- return identityEntries;
457236
- }
457237
- function groupIdentityEntriesByValue2(identityEntries) {
457238
- const groupsByValue = new Map;
457239
- for (const entry of identityEntries) {
457240
- const existingGroup = groupsByValue.get(entry.value);
457241
- if (existingGroup) {
457242
- existingGroup.attrs.push(entry.attr);
457243
- continue;
457244
- }
457245
- groupsByValue.set(entry.value, {
457246
- value: entry.value,
457247
- attrs: [entry.attr]
457248
- });
457249
- }
457250
- return [...groupsByValue.values()];
457251
- }
457252
- function shouldSynthesizeParaId2(node4) {
457253
- return Boolean(node4 && typeof node4 === "object" && SYNTHETIC_PARA_ID_TYPES2.has(node4.type));
457254
- }
457255
457645
  function collectExplicitBlockIdentities2(node4, reservedIds) {
457256
457646
  if (!node4 || typeof node4 !== "object")
457257
457647
  return;
457258
- const identityEntries = getExplicitIdentityEntries2(node4);
457648
+ const identityEntries = getExplicitIdentityEntries2(node4.attrs, node4?.type);
457259
457649
  for (const { value } of groupIdentityEntriesByValue2(identityEntries)) {
457260
457650
  reservedIds.add(value);
457261
457651
  }
@@ -457263,27 +457653,13 @@ function collectExplicitBlockIdentities2(node4, reservedIds) {
457263
457653
  node4.content.forEach((child) => collectExplicitBlockIdentities2(child, reservedIds));
457264
457654
  }
457265
457655
  }
457266
- function createDeterministicDocxIdAllocator2(reservedIds) {
457267
- let nextValue = 1;
457268
- return () => {
457269
- while (nextValue <= MAX_DOCX_ID2) {
457270
- const id2 = nextValue.toString(16).toUpperCase().padStart(DOCX_ID_LENGTH2, "0");
457271
- nextValue += 1;
457272
- if (reservedIds.has(id2))
457273
- continue;
457274
- reservedIds.add(id2);
457275
- return id2;
457276
- }
457277
- throw new Error("Unable to allocate a unique synthetic DOCX block id.");
457278
- };
457279
- }
457280
457656
  function setBlockIdentity2(node4, attrName, value) {
457281
457657
  node4.attrs = { ...node4.attrs ?? {}, [attrName]: value };
457282
457658
  }
457283
457659
  function normalizeBlockIdentitiesInNode2(node4, seenIds, allocateDocxId) {
457284
457660
  if (!node4 || typeof node4 !== "object")
457285
457661
  return;
457286
- const identityEntries = getExplicitIdentityEntries2(node4);
457662
+ const identityEntries = getExplicitIdentityEntries2(node4.attrs, node4?.type);
457287
457663
  const groupedIdentities = groupIdentityEntriesByValue2(identityEntries);
457288
457664
  if (groupedIdentities.length > 0) {
457289
457665
  for (const identityGroup of groupedIdentities) {
@@ -457297,7 +457673,7 @@ function normalizeBlockIdentitiesInNode2(node4, seenIds, allocateDocxId) {
457297
457673
  seenIds.add(identityGroup.value);
457298
457674
  }
457299
457675
  }
457300
- } else if (shouldSynthesizeParaId2(node4)) {
457676
+ } else if (shouldSynthesizeParaIdForType2(node4?.type)) {
457301
457677
  const syntheticParaId = allocateDocxId();
457302
457678
  setBlockIdentity2(node4, "paraId", syntheticParaId);
457303
457679
  seenIds.add(syntheticParaId);
@@ -457316,23 +457692,8 @@ function normalizeDuplicateBlockIdentitiesInContent2(content4 = []) {
457316
457692
  content4.forEach((node4) => normalizeBlockIdentitiesInNode2(node4, seenIds, allocateDocxId));
457317
457693
  return content4;
457318
457694
  }
457319
- 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;
457320
457695
  var init_normalizeDuplicateBlockIdentitiesInContent = __esm(() => {
457321
- PARAGRAPH_IDENTITY_ATTRS2 = ["sdBlockId", "paraId"];
457322
- TABLE_IDENTITY_ATTRS2 = ["sdBlockId", "paraId", "blockId"];
457323
- DEFAULT_BLOCK_IDENTITY_ATTRS2 = ["sdBlockId", "blockId", "paraId"];
457324
- SYNTHETIC_PARA_ID_TYPES2 = new Set(["paragraph", "tableRow"]);
457325
- BLOCK_IDENTITY_ATTRS2 = {
457326
- paragraph: PARAGRAPH_IDENTITY_ATTRS2,
457327
- heading: DEFAULT_BLOCK_IDENTITY_ATTRS2,
457328
- listItem: DEFAULT_BLOCK_IDENTITY_ATTRS2,
457329
- table: TABLE_IDENTITY_ATTRS2,
457330
- tableRow: TABLE_IDENTITY_ATTRS2,
457331
- tableCell: TABLE_IDENTITY_ATTRS2,
457332
- tableHeader: TABLE_IDENTITY_ATTRS2,
457333
- sdt: DEFAULT_BLOCK_IDENTITY_ATTRS2,
457334
- structuredContentBlock: DEFAULT_BLOCK_IDENTITY_ATTRS2
457335
- };
457696
+ init_block_identity_renaming();
457336
457697
  });
457337
457698
 
457338
457699
  // ../../packages/super-editor/src/editors/v1/core/super-converter/v3/handlers/w/styles/index.js
@@ -471910,6 +472271,168 @@ var init_executor_registry = __esm(() => {
471910
472271
  registry3 = new Map;
471911
472272
  });
471912
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
+
471913
472436
  // ../../packages/super-editor/src/editors/v1/document-api-adapters/helpers/selection-target-resolver.ts
471914
472437
  function resolveTextPoint3(editor, index3, point7) {
471915
472438
  const candidate = findTextBlockByNodeId2(index3, point7.blockId);
@@ -472873,10 +473396,12 @@ function assertNoDuplicateBlockIds2(index3) {
472873
473396
  duplicates.push(candidate.nodeId);
472874
473397
  }
472875
473398
  if (duplicates.length > 0) {
472876
- 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, {
472877
473402
  duplicateBlockIds: duplicates,
472878
473403
  blockCount: duplicates.length,
472879
- 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."
472880
473405
  });
472881
473406
  }
472882
473407
  }
@@ -472907,12 +473432,76 @@ function assertSingleStoryKey2(steps) {
472907
473432
  }
472908
473433
  }
472909
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
+ }
472910
473490
  function compilePlan2(editor, steps, options = {}) {
472911
473491
  if (steps.length > MAX_PLAN_STEPS2) {
472912
473492
  throw planError2("INVALID_INPUT", `plan contains ${steps.length} steps, maximum is ${MAX_PLAN_STEPS2}`);
472913
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
+ }
472914
473504
  const compiledRevision = getRevision2(editor);
472915
- const index3 = getBlockIndex2(editor);
472916
473505
  assertNoDuplicateBlockIds2(index3);
472917
473506
  const mutationSteps = [];
472918
473507
  const assertSteps = [];
@@ -472968,6 +473557,7 @@ var init_compiler = __esm(() => {
472968
473557
  init_style_resolver();
472969
473558
  init_index_cache();
472970
473559
  init_revision_tracker();
473560
+ init_repair_block_identities();
472971
473561
  init_text_strategy();
472972
473562
  init_block_strategy();
472973
473563
  init_node_address_resolver();
@@ -475175,6 +475765,7 @@ function executePlan2(editor, input2) {
475175
475765
  if (!input2.steps?.length) {
475176
475766
  throw planError2("INVALID_INPUT", "plan must contain at least one step");
475177
475767
  }
475768
+ checkRevision2(editor, input2.expectedRevision);
475178
475769
  const compiled = compilePlan2(editor, input2.steps, {
475179
475770
  selectTextModel: input2.changeMode === "tracked" ? "raw" : "visible"
475180
475771
  });
@@ -476680,7 +477271,8 @@ function selectionMutationWrapper2(editor, request, options) {
476680
477271
  const stepId = v4_default2();
476681
477272
  const where = buildSelectionWhere2(request);
476682
477273
  const step3 = buildSelectionStepDef2(stepId, request, where);
476683
- const compiled = compilePlan2(storyEditor, [step3]);
477274
+ checkRevision2(storyEditor, options?.expectedRevision);
477275
+ const compiled = compilePlan2(storyEditor, [step3], options?.dryRun ? { skipIdentityRepair: true } : undefined);
476684
477276
  if (request.kind === "insert" && request.target) {
476685
477277
  const hasNodeEdge = request.target.start.kind === "nodeEdge" || request.target.end.kind === "nodeEdge";
476686
477278
  if (hasNodeEdge) {
@@ -476715,7 +477307,6 @@ function selectionMutationWrapper2(editor, request, options) {
476715
477307
  }
476716
477308
  }
476717
477309
  }
476718
- checkRevision2(storyEditor, options?.expectedRevision);
476719
477310
  if (options?.dryRun) {
476720
477311
  const resolution2 = buildSelectionResolutionFromCompiled2(compiled, stepId);
476721
477312
  if (request.kind === "insert" && !request.text) {
@@ -476878,6 +477469,7 @@ function insertStructuredInner2(editor, input2, options) {
476878
477469
  }
476879
477470
  effectiveTarget = { kind: "text", blockId, range: { start: offset2, end: offset2 } };
476880
477471
  } else if (ref4) {
477472
+ checkRevision2(editor, options?.expectedRevision);
476881
477473
  const dummyStepId = v4_default2();
476882
477474
  const dummyStep = {
476883
477475
  id: dummyStepId,
@@ -476885,7 +477477,7 @@ function insertStructuredInner2(editor, input2, options) {
476885
477477
  where: { by: "ref", ref: ref4 },
476886
477478
  args: { position: "before", content: { text: "" } }
476887
477479
  };
476888
- const compiled = compilePlan2(editor, [dummyStep]);
477480
+ const compiled = compilePlan2(editor, [dummyStep], options?.dryRun ? { skipIdentityRepair: true } : undefined);
476889
477481
  const compiledStep = compiled.mutationSteps.find((s2) => s2.step.id === dummyStepId);
476890
477482
  const compiledTarget = compiledStep?.targets[0];
476891
477483
  if (!compiledTarget) {
@@ -490593,7 +491185,7 @@ function previewPlan2(editor, input2) {
490593
491185
  let currentPhase = "compile";
490594
491186
  let evaluatedRevision = getRevision2(editor);
490595
491187
  try {
490596
- const compiled = compilePlan2(editor, input2.steps);
491188
+ const compiled = compilePlan2(editor, input2.steps, { skipIdentityRepair: true });
490597
491189
  evaluatedRevision = compiled.compiledRevision;
490598
491190
  currentPhase = "execute";
490599
491191
  const tr = editor.state.tr;