@superdoc-dev/cli 0.17.0-next.25 → 0.17.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 +407 -86
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -68327,7 +68327,7 @@ var init_remark_gfm_BhnWr3yf_es = __esm(() => {
68327
68327
  emptyOptions2 = {};
68328
68328
  });
68329
68329
 
68330
- // ../../packages/superdoc/dist/chunks/SuperConverter-CCgGAnXY.es.js
68330
+ // ../../packages/superdoc/dist/chunks/SuperConverter-DK5WIHuy.es.js
68331
68331
  function getExtensionConfigField(extension$1, field, context = { name: "" }) {
68332
68332
  const fieldValue = extension$1.config[field];
68333
68333
  if (typeof fieldValue === "function")
@@ -88534,6 +88534,22 @@ function fixTable(state, table, tablePos, tr) {
88534
88534
  }
88535
88535
  return tr.setMeta(fixTablesKey, { fixTables: true });
88536
88536
  }
88537
+ function findTable($pos) {
88538
+ return findParentNode$1((node3) => node3.type.spec.tableRole === "table", $pos);
88539
+ }
88540
+ function findParentNode$1(predicate, $pos) {
88541
+ for (let depth = $pos.depth;depth >= 0; depth -= 1) {
88542
+ const node3 = $pos.node(depth);
88543
+ if (predicate(node3))
88544
+ return {
88545
+ node: node3,
88546
+ pos: depth === 0 ? 0 : $pos.before(depth),
88547
+ start: $pos.start(depth),
88548
+ depth
88549
+ };
88550
+ }
88551
+ return null;
88552
+ }
88537
88553
  function selectedRect(state) {
88538
88554
  const sel = state.selection;
88539
88555
  const $pos = selectionCell(state);
@@ -90598,8 +90614,11 @@ function trackRevisions(editor) {
90598
90614
  return;
90599
90615
  subscribedEditors.add(editor);
90600
90616
  editor.on("transaction", ({ transaction }) => {
90601
- if (transaction.docChanged)
90602
- incrementRevision(editor);
90617
+ if (transaction.getMeta?.("superdoc/block-identity-repair"))
90618
+ return;
90619
+ if (!transaction.docChanged)
90620
+ return;
90621
+ incrementRevision(editor);
90603
90622
  });
90604
90623
  }
90605
90624
  function checkRevision(editor, expectedRevision) {
@@ -100535,19 +100554,22 @@ function toIdentityValue(value) {
100535
100554
  if (typeof value === "number" && Number.isFinite(value))
100536
100555
  return String(value);
100537
100556
  }
100538
- function getBlockIdentityAttrs(node3) {
100539
- if (!node3 || typeof node3 !== "object")
100557
+ function getBlockIdentityAttrsForType(typeName) {
100558
+ if (!typeName)
100540
100559
  return [];
100541
- return BLOCK_IDENTITY_ATTRS[node3.type] ?? [];
100560
+ return BLOCK_IDENTITY_ATTRS[typeName] ?? [];
100542
100561
  }
100543
- function getExplicitIdentityEntries(node3) {
100544
- const attrPriority = getBlockIdentityAttrs(node3);
100562
+ function shouldSynthesizeParaIdForType(typeName) {
100563
+ return Boolean(typeName && SYNTHETIC_PARA_ID_TYPES.has(typeName));
100564
+ }
100565
+ function getExplicitIdentityEntries(attrs, typeName) {
100566
+ const attrPriority = getBlockIdentityAttrsForType(typeName);
100545
100567
  if (attrPriority.length === 0)
100546
100568
  return [];
100547
- const attrs = typeof node3.attrs === "object" && node3.attrs ? node3.attrs : {};
100569
+ const safeAttrs = attrs && typeof attrs === "object" ? attrs : {};
100548
100570
  const identityEntries = [];
100549
100571
  for (const attr of attrPriority) {
100550
- const value = toIdentityValue(attrs[attr]);
100572
+ const value = toIdentityValue(safeAttrs[attr]);
100551
100573
  if (value)
100552
100574
  identityEntries.push({
100553
100575
  attr,
@@ -100571,18 +100593,6 @@ function groupIdentityEntriesByValue(identityEntries) {
100571
100593
  }
100572
100594
  return [...groupsByValue.values()];
100573
100595
  }
100574
- function shouldSynthesizeParaId(node3) {
100575
- return Boolean(node3 && typeof node3 === "object" && SYNTHETIC_PARA_ID_TYPES.has(node3.type));
100576
- }
100577
- function collectExplicitBlockIdentities(node3, reservedIds) {
100578
- if (!node3 || typeof node3 !== "object")
100579
- return;
100580
- const identityEntries = getExplicitIdentityEntries(node3);
100581
- for (const { value } of groupIdentityEntriesByValue(identityEntries))
100582
- reservedIds.add(value);
100583
- if (Array.isArray(node3.content))
100584
- node3.content.forEach((child) => collectExplicitBlockIdentities(child, reservedIds));
100585
- }
100586
100596
  function createDeterministicDocxIdAllocator(reservedIds) {
100587
100597
  let nextValue = 1;
100588
100598
  return () => {
@@ -100597,6 +100607,15 @@ function createDeterministicDocxIdAllocator(reservedIds) {
100597
100607
  throw new Error("Unable to allocate a unique synthetic DOCX block id.");
100598
100608
  };
100599
100609
  }
100610
+ function collectExplicitBlockIdentities(node3, reservedIds) {
100611
+ if (!node3 || typeof node3 !== "object")
100612
+ return;
100613
+ const identityEntries = getExplicitIdentityEntries(node3.attrs, node3?.type);
100614
+ for (const { value } of groupIdentityEntriesByValue(identityEntries))
100615
+ reservedIds.add(value);
100616
+ if (Array.isArray(node3.content))
100617
+ node3.content.forEach((child) => collectExplicitBlockIdentities(child, reservedIds));
100618
+ }
100600
100619
  function setBlockIdentity(node3, attrName, value) {
100601
100620
  node3.attrs = {
100602
100621
  ...node3.attrs ?? {},
@@ -100606,7 +100625,7 @@ function setBlockIdentity(node3, attrName, value) {
100606
100625
  function normalizeBlockIdentitiesInNode(node3, seenIds, allocateDocxId) {
100607
100626
  if (!node3 || typeof node3 !== "object")
100608
100627
  return;
100609
- const groupedIdentities = groupIdentityEntriesByValue(getExplicitIdentityEntries(node3));
100628
+ const groupedIdentities = groupIdentityEntriesByValue(getExplicitIdentityEntries(node3.attrs, node3?.type));
100610
100629
  if (groupedIdentities.length > 0)
100611
100630
  for (const identityGroup of groupedIdentities)
100612
100631
  if (seenIds.has(identityGroup.value)) {
@@ -100616,7 +100635,7 @@ function normalizeBlockIdentitiesInNode(node3, seenIds, allocateDocxId) {
100616
100635
  seenIds.add(replacementId);
100617
100636
  } else
100618
100637
  seenIds.add(identityGroup.value);
100619
- else if (shouldSynthesizeParaId(node3)) {
100638
+ else if (shouldSynthesizeParaIdForType(node3?.type)) {
100620
100639
  const syntheticParaId = allocateDocxId();
100621
100640
  setBlockIdentity(node3, "paraId", syntheticParaId);
100622
100641
  seenIds.add(syntheticParaId);
@@ -108234,6 +108253,7 @@ function buildBlockIndex(editor) {
108234
108253
  const byId = /* @__PURE__ */ new Map;
108235
108254
  const ambiguous = /* @__PURE__ */ new Set;
108236
108255
  const pathByNode = /* @__PURE__ */ new WeakMap;
108256
+ const explicitIdentities = /* @__PURE__ */ new Map;
108237
108257
  pathByNode.set(editor.state.doc, []);
108238
108258
  function registerKey(key, candidate) {
108239
108259
  if (byId.has(key)) {
@@ -108242,11 +108262,44 @@ function buildBlockIndex(editor) {
108242
108262
  } else if (!ambiguous.has(key))
108243
108263
  byId.set(key, candidate);
108244
108264
  }
108265
+ function recordExplicitIdentities(node3, pos) {
108266
+ const attrPriority = getBlockIdentityAttrsForType(node3.type?.name);
108267
+ if (attrPriority.length === 0)
108268
+ return;
108269
+ const attrs = node3.attrs ?? {};
108270
+ let nodeGroups;
108271
+ for (const attr of attrPriority) {
108272
+ const value = toIdentityValue(attrs[attr]);
108273
+ if (!value)
108274
+ continue;
108275
+ if (!nodeGroups)
108276
+ nodeGroups = /* @__PURE__ */ new Map;
108277
+ const existing = nodeGroups.get(value);
108278
+ if (existing)
108279
+ existing.push(attr);
108280
+ else
108281
+ nodeGroups.set(value, [attr]);
108282
+ }
108283
+ if (!nodeGroups)
108284
+ return;
108285
+ for (const [value, attrsForValue] of nodeGroups) {
108286
+ const observations = explicitIdentities.get(value);
108287
+ const observation = {
108288
+ pos,
108289
+ attrs: attrsForValue
108290
+ };
108291
+ if (observations)
108292
+ observations.push(observation);
108293
+ else
108294
+ explicitIdentities.set(value, [observation]);
108295
+ }
108296
+ }
108245
108297
  editor.state.doc.descendants((node3, pos, parent, index2) => {
108246
108298
  const parentPath = parent ? pathByNode.get(parent) ?? [] : [];
108247
108299
  const path2 = typeof index2 === "number" && Number.isInteger(index2) && index2 >= 0 ? [...parentPath, index2] : undefined;
108248
108300
  if (path2)
108249
108301
  pathByNode.set(node3, path2);
108302
+ recordExplicitIdentities(node3, pos);
108250
108303
  const nodeType = mapBlockNodeType(node3);
108251
108304
  if (!nodeType)
108252
108305
  return;
@@ -108269,7 +108322,8 @@ function buildBlockIndex(editor) {
108269
108322
  return {
108270
108323
  candidates,
108271
108324
  byId,
108272
- ambiguous
108325
+ ambiguous,
108326
+ explicitIdentities
108273
108327
  };
108274
108328
  }
108275
108329
  function findBlockById(index2, address2) {
@@ -111854,6 +111908,8 @@ function resolveStoryRuntime(hostEditor, locator, options = {}) {
111854
111908
  if (store && !hasHostStoreSyncListener(runtime.editor, storyKey)) {
111855
111909
  markHostStoreSyncListener(runtime.editor, storyKey);
111856
111910
  runtime.editor.on("transaction", ({ transaction }) => {
111911
+ if (transaction.getMeta?.("superdoc/block-identity-repair"))
111912
+ return;
111857
111913
  if (transaction.docChanged)
111858
111914
  incrementStoryRevision(store, storyKey);
111859
111915
  });
@@ -134913,7 +134969,7 @@ var isRegExp = (value) => {
134913
134969
  state.kern = kernNode.attributes["w:val"];
134914
134970
  }
134915
134971
  }, SuperConverter;
134916
- var init_SuperConverter_CCgGAnXY_es = __esm(() => {
134972
+ var init_SuperConverter_DK5WIHuy_es = __esm(() => {
134917
134973
  init_rolldown_runtime_Bg48TavK_es();
134918
134974
  init_jszip_C49i9kUs_es();
134919
134975
  init_xml_js_CqGKpaft_es();
@@ -175657,7 +175713,7 @@ var init_SuperConverter_CCgGAnXY_es = __esm(() => {
175657
175713
  };
175658
175714
  });
175659
175715
 
175660
- // ../../packages/superdoc/dist/chunks/create-headless-toolbar-BvrKiWf0.es.js
175716
+ // ../../packages/superdoc/dist/chunks/create-headless-toolbar-BLN1v7eO.es.js
175661
175717
  function parseSizeUnit(val = "0") {
175662
175718
  const length3 = val.toString() || "0";
175663
175719
  const value = Number.parseFloat(length3);
@@ -177140,6 +177196,194 @@ function applySetMarksToResolved(editor, existingMarks, setMarks) {
177140
177196
  }
177141
177197
  return marks;
177142
177198
  }
177199
+ function planRepairs(doc2, identityMap) {
177200
+ if (identityMap)
177201
+ return planRepairsFromIdentityMap(identityMap);
177202
+ return planRepairsByWalk(doc2);
177203
+ }
177204
+ function planRepairsFromIdentityMap(identityMap) {
177205
+ let hasDuplicates = false;
177206
+ for (const observations of identityMap.values())
177207
+ if (observations.length > 1) {
177208
+ hasDuplicates = true;
177209
+ break;
177210
+ }
177211
+ if (!hasDuplicates)
177212
+ return {
177213
+ plans: [],
177214
+ report: {
177215
+ repairedBlockCount: 0,
177216
+ duplicateBlockIds: [],
177217
+ renames: []
177218
+ }
177219
+ };
177220
+ const rewrites = [];
177221
+ for (const [value, observations] of identityMap) {
177222
+ if (observations.length <= 1)
177223
+ continue;
177224
+ for (let i4 = 1;i4 < observations.length; i4 += 1) {
177225
+ const { pos, attrs } = observations[i4];
177226
+ rewrites.push({
177227
+ pos,
177228
+ value,
177229
+ attrs
177230
+ });
177231
+ }
177232
+ }
177233
+ rewrites.sort((a, b) => a.pos - b.pos);
177234
+ const allocateDocxId = createDeterministicDocxIdAllocator(new Set(identityMap.keys()));
177235
+ const plansByPos = /* @__PURE__ */ new Map;
177236
+ const duplicateBlockIds = [];
177237
+ const renames = [];
177238
+ for (const { pos, value, attrs } of rewrites) {
177239
+ const replacementValue = allocateDocxId();
177240
+ let plan = plansByPos.get(pos);
177241
+ if (!plan) {
177242
+ plan = {
177243
+ pos,
177244
+ rewrittenGroups: []
177245
+ };
177246
+ plansByPos.set(pos, plan);
177247
+ }
177248
+ const attrsCopy = [...attrs];
177249
+ plan.rewrittenGroups.push({
177250
+ originalValue: value,
177251
+ replacementValue,
177252
+ attrs: attrsCopy
177253
+ });
177254
+ duplicateBlockIds.push(value);
177255
+ renames.push({
177256
+ originalValue: value,
177257
+ replacementValue,
177258
+ attrs: attrsCopy
177259
+ });
177260
+ }
177261
+ const plans = [...plansByPos.values()].sort((a, b) => a.pos - b.pos);
177262
+ return {
177263
+ plans,
177264
+ report: {
177265
+ repairedBlockCount: plans.length,
177266
+ duplicateBlockIds,
177267
+ renames
177268
+ }
177269
+ };
177270
+ }
177271
+ function planRepairsByWalk(doc2) {
177272
+ const reservedIds = /* @__PURE__ */ new Set;
177273
+ let hasDuplicates = false;
177274
+ doc2.descendants((node3) => {
177275
+ const entries2 = getExplicitIdentityEntries(node3.attrs, node3.type?.name);
177276
+ for (const { value } of groupIdentityEntriesByValue(entries2))
177277
+ if (reservedIds.has(value))
177278
+ hasDuplicates = true;
177279
+ else
177280
+ reservedIds.add(value);
177281
+ });
177282
+ if (!hasDuplicates)
177283
+ return {
177284
+ plans: [],
177285
+ report: {
177286
+ repairedBlockCount: 0,
177287
+ duplicateBlockIds: [],
177288
+ renames: []
177289
+ }
177290
+ };
177291
+ const allocateDocxId = createDeterministicDocxIdAllocator(reservedIds);
177292
+ const seenIds = /* @__PURE__ */ new Set;
177293
+ const plans = [];
177294
+ const duplicateBlockIds = [];
177295
+ const renames = [];
177296
+ doc2.descendants((node3, pos) => {
177297
+ const groups = groupIdentityEntriesByValue(getExplicitIdentityEntries(node3.attrs, node3.type?.name));
177298
+ if (groups.length === 0)
177299
+ return;
177300
+ let plan = null;
177301
+ for (const group of groups)
177302
+ if (seenIds.has(group.value)) {
177303
+ if (!plan)
177304
+ plan = {
177305
+ pos,
177306
+ rewrittenGroups: []
177307
+ };
177308
+ const replacementValue = allocateDocxId();
177309
+ plan.rewrittenGroups.push({
177310
+ originalValue: group.value,
177311
+ replacementValue,
177312
+ attrs: [...group.attrs]
177313
+ });
177314
+ duplicateBlockIds.push(group.value);
177315
+ renames.push({
177316
+ originalValue: group.value,
177317
+ replacementValue,
177318
+ attrs: [...group.attrs]
177319
+ });
177320
+ seenIds.add(replacementValue);
177321
+ } else
177322
+ seenIds.add(group.value);
177323
+ if (plan)
177324
+ plans.push(plan);
177325
+ });
177326
+ return {
177327
+ plans,
177328
+ report: {
177329
+ repairedBlockCount: plans.length,
177330
+ duplicateBlockIds,
177331
+ renames
177332
+ }
177333
+ };
177334
+ }
177335
+ function repairDuplicateBlockIdentities(editor) {
177336
+ const doc2 = editor.state?.doc;
177337
+ if (!doc2 || typeof doc2.descendants !== "function")
177338
+ return null;
177339
+ if (typeof editor.state?.tr !== "object" || editor.state.tr === null)
177340
+ return null;
177341
+ if (typeof editor.dispatch !== "function")
177342
+ return null;
177343
+ let identityMap;
177344
+ try {
177345
+ identityMap = getBlockIndex(editor).explicitIdentities;
177346
+ } catch {
177347
+ identityMap = undefined;
177348
+ }
177349
+ const { plans, report } = planRepairs(doc2, identityMap);
177350
+ if (plans.length === 0)
177351
+ return null;
177352
+ const tr = editor.state.tr;
177353
+ tr.setMeta("addToHistory", false);
177354
+ tr.setMeta("superdoc/block-identity-repair", report);
177355
+ for (const plan of plans)
177356
+ for (const group of plan.rewrittenGroups)
177357
+ for (const attr of group.attrs)
177358
+ tr.setNodeAttribute(plan.pos, attr, group.replacementValue);
177359
+ editor.dispatch(tr);
177360
+ const blockedNodeIds = [];
177361
+ for (const plan of plans) {
177362
+ const node3 = editor.state.doc.nodeAt(plan.pos);
177363
+ if (!node3) {
177364
+ blockedNodeIds.push(`pos:${plan.pos}`);
177365
+ continue;
177366
+ }
177367
+ for (const group of plan.rewrittenGroups)
177368
+ for (const attr of group.attrs)
177369
+ if (node3.attrs?.[attr] !== group.replacementValue) {
177370
+ const observedId = typeof node3.attrs?.id === "string" && node3.attrs.id || typeof node3.attrs?.sdBlockId === "string" && node3.attrs.sdBlockId || `pos:${plan.pos}`;
177371
+ blockedNodeIds.push(observedId);
177372
+ }
177373
+ }
177374
+ if (blockedNodeIds.length > 0) {
177375
+ const unique = [...new Set(blockedNodeIds)];
177376
+ const MAX_ID_PREVIEW_LENGTH = 32;
177377
+ const truncate = (id2) => id2.length > MAX_ID_PREVIEW_LENGTH ? `${id2.slice(0, MAX_ID_PREVIEW_LENGTH - 1)}…` : id2;
177378
+ const preview = unique.slice(0, 4).map(truncate).join(", ");
177379
+ const previewSuffix = unique.length > 4 ? `, +${unique.length - 4} more` : "";
177380
+ 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, {
177381
+ blockedNodeIds: unique,
177382
+ remediation: "Re-import the document via doc.open to assign unique identities."
177383
+ });
177384
+ }
177385
+ return report;
177386
+ }
177143
177387
  function getCandidateText(editor, candidate, options) {
177144
177388
  if (candidate.node.childCount > 0)
177145
177389
  return textContentInBlock(candidate.node, options);
@@ -178344,12 +178588,15 @@ function assertNoDuplicateBlockIds(index2) {
178344
178588
  if (count2 === 1)
178345
178589
  duplicates.push(candidate.nodeId);
178346
178590
  }
178347
- if (duplicates.length > 0)
178348
- throw planError("DOCUMENT_IDENTITY_CONFLICT", "Document contains blocks with duplicate identities. This must be resolved before mutations can be applied.", undefined, {
178591
+ if (duplicates.length > 0) {
178592
+ const preview = duplicates.slice(0, 4).join(", ");
178593
+ const previewSuffix = duplicates.length > 4 ? `, +${duplicates.length - 4} more` : "";
178594
+ 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, {
178349
178595
  duplicateBlockIds: duplicates,
178350
178596
  blockCount: duplicates.length,
178351
- remediation: "Re-import the document or call document.repair() to assign unique identities."
178597
+ remediation: "Re-import the document via doc.open to assign unique identities."
178352
178598
  });
178599
+ }
178353
178600
  }
178354
178601
  function assertSingleStoryKey(steps) {
178355
178602
  let seenStoryKey;
@@ -178377,11 +178624,71 @@ function assertSingleStoryKey(steps) {
178377
178624
  });
178378
178625
  }
178379
178626
  }
178627
+ function collectReferencedBlockIds(step3) {
178628
+ const where = step3.where;
178629
+ const ids = [];
178630
+ const withinNodeId = where.within?.nodeId;
178631
+ if (withinNodeId)
178632
+ ids.push(withinNodeId);
178633
+ if (isRefWhere(where)) {
178634
+ const ref3 = where.ref;
178635
+ if (ref3.startsWith("text:")) {
178636
+ const decoded = decodeRef(ref3);
178637
+ if (decoded) {
178638
+ for (const seg of decoded.segments ?? [])
178639
+ if (seg?.blockId)
178640
+ ids.push(seg.blockId);
178641
+ const nodeId = decoded.node?.nodeId;
178642
+ if (nodeId)
178643
+ ids.push(nodeId);
178644
+ }
178645
+ } else
178646
+ ids.push(ref3);
178647
+ return ids;
178648
+ }
178649
+ if (isBlockWhere(where)) {
178650
+ ids.push(where.nodeId);
178651
+ return ids;
178652
+ }
178653
+ if (isTargetWhere(where))
178654
+ for (const point3 of [where.target?.start, where.target?.end]) {
178655
+ const blockId = point3?.blockId;
178656
+ if (blockId)
178657
+ ids.push(blockId);
178658
+ const edgeNodeId = point3?.node?.nodeId;
178659
+ if (edgeNodeId)
178660
+ ids.push(edgeNodeId);
178661
+ }
178662
+ return ids;
178663
+ }
178664
+ function assertNoStaleRefsAfterRepair(steps, repairedIds) {
178665
+ if (repairedIds.size === 0)
178666
+ return;
178667
+ for (const step3 of steps)
178668
+ for (const blockId of collectReferencedBlockIds(step3)) {
178669
+ if (!repairedIds.has(blockId))
178670
+ continue;
178671
+ throw planError("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, {
178672
+ blockId,
178673
+ repairedBlockIds: [...repairedIds],
178674
+ remediation: "Re-run query.match() or doc.find() to obtain fresh refs, then retry the mutation."
178675
+ });
178676
+ }
178677
+ }
178380
178678
  function compilePlan(editor, steps, options = {}) {
178381
178679
  if (steps.length > 200)
178382
178680
  throw planError("INVALID_INPUT", `plan contains ${steps.length} steps, maximum is 200`);
178681
+ let index2 = getBlockIndex(editor);
178682
+ if (!options.skipIdentityRepair) {
178683
+ const repair = repairDuplicateBlockIdentities(editor);
178684
+ if (repair) {
178685
+ clearIndexCache(editor);
178686
+ index2 = getBlockIndex(editor);
178687
+ 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` : ""}.`);
178688
+ assertNoStaleRefsAfterRepair(steps, new Set(repair.duplicateBlockIds));
178689
+ }
178690
+ }
178383
178691
  const compiledRevision = getRevision(editor);
178384
- const index2 = getBlockIndex(editor);
178385
178692
  assertNoDuplicateBlockIds(index2);
178386
178693
  const mutationSteps = [];
178387
178694
  const assertSteps = [];
@@ -180474,6 +180781,7 @@ function executeCompiledPlan(editor, compiled, options = {}) {
180474
180781
  function executePlan(editor, input) {
180475
180782
  if (!input.steps?.length)
180476
180783
  throw planError("INVALID_INPUT", "plan must contain at least one step");
180784
+ checkRevision(editor, input.expectedRevision);
180477
180785
  return executeCompiledPlan(editor, compilePlan(editor, input.steps, { selectTextModel: input.changeMode === "tracked" ? "raw" : "visible" }), {
180478
180786
  changeMode: input.changeMode ?? "direct",
180479
180787
  expectedRevision: input.expectedRevision
@@ -181820,7 +182128,9 @@ function selectionMutationWrapper(editor, request, options) {
181820
182128
  ensureTrackedInlinePropertySupport(inlineKeys);
181821
182129
  }
181822
182130
  const stepId = v4_default();
181823
- const compiled = compilePlan(storyEditor, [buildSelectionStepDef(stepId, request, buildSelectionWhere(request))]);
182131
+ const step3 = buildSelectionStepDef(stepId, request, buildSelectionWhere(request));
182132
+ checkRevision(storyEditor, options?.expectedRevision);
182133
+ const compiled = compilePlan(storyEditor, [step3], options?.dryRun ? { skipIdentityRepair: true } : undefined);
181824
182134
  if (request.kind === "insert" && request.target) {
181825
182135
  if (request.target.start.kind === "nodeEdge" || request.target.end.kind === "nodeEdge")
181826
182136
  throw new DocumentApiAdapterError("INVALID_TARGET", "Text inserts do not support nodeEdge targets. Use a text-offset target inside a textblock.");
@@ -181850,7 +182160,6 @@ function selectionMutationWrapper(editor, request, options) {
181850
182160
  }
181851
182161
  }
181852
182162
  }
181853
- checkRevision(storyEditor, options?.expectedRevision);
181854
182163
  if (options?.dryRun) {
181855
182164
  const resolution$1 = buildSelectionResolutionFromCompiled(compiled, stepId);
181856
182165
  if (request.kind === "insert" && !request.text)
@@ -182068,6 +182377,7 @@ function insertStructuredInner(editor, input, options) {
182068
182377
  }
182069
182378
  };
182070
182379
  } else if (ref3) {
182380
+ checkRevision(editor, options?.expectedRevision);
182071
182381
  const dummyStepId = v4_default();
182072
182382
  const compiled = compilePlan(editor, [{
182073
182383
  id: dummyStepId,
@@ -182080,7 +182390,7 @@ function insertStructuredInner(editor, input, options) {
182080
182390
  position: "before",
182081
182391
  content: { text: "" }
182082
182392
  }
182083
- }]);
182393
+ }], options?.dryRun ? { skipIdentityRepair: true } : undefined);
182084
182394
  const compiledTarget = compiled.mutationSteps.find((s) => s.step.id === dummyStepId)?.targets[0];
182085
182395
  if (!compiledTarget)
182086
182396
  throw new DocumentApiAdapterError("TARGET_NOT_FOUND", "Structured insert ref could not be resolved.", { ref: ref3 });
@@ -186052,8 +186362,8 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, normalizeActorId = (value) => {
186052
186362
  }
186053
186363
  };
186054
186364
  };
186055
- var init_create_headless_toolbar_BvrKiWf0_es = __esm(() => {
186056
- init_SuperConverter_CCgGAnXY_es();
186365
+ var init_create_headless_toolbar_BLN1v7eO_es = __esm(() => {
186366
+ init_SuperConverter_DK5WIHuy_es();
186057
186367
  init_uuid_B2wVPhPi_es();
186058
186368
  init_constants_D9qj59G2_es();
186059
186369
  init_dist_B8HfvhaK_es();
@@ -235222,7 +235532,7 @@ var init_remark_gfm_eZN6yzWQ_es = __esm(() => {
235222
235532
  init_remark_gfm_BhnWr3yf_es();
235223
235533
  });
235224
235534
 
235225
- // ../../packages/superdoc/dist/chunks/src-BB0n1coY.es.js
235535
+ // ../../packages/superdoc/dist/chunks/src-PJVnllcq.es.js
235226
235536
  function deleteProps(obj, propOrProps) {
235227
235537
  const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
235228
235538
  const removeNested = (target, pathParts, index2 = 0) => {
@@ -258881,7 +259191,7 @@ function previewPlan(editor, input2) {
258881
259191
  let currentPhase = "compile";
258882
259192
  let evaluatedRevision = getRevision(editor);
258883
259193
  try {
258884
- const compiled = compilePlan(editor, input2.steps);
259194
+ const compiled = compilePlan(editor, input2.steps, { skipIdentityRepair: true });
258885
259195
  evaluatedRevision = compiled.compiledRevision;
258886
259196
  currentPhase = "execute";
258887
259197
  const tr = editor.state.tr;
@@ -286373,11 +286683,12 @@ function percentile(sortedValues, p$12) {
286373
286683
  return sortedValues[lower] * (1 - weight) + sortedValues[upper] * weight;
286374
286684
  }
286375
286685
  function pushEmptyLineSelectionBand(rects, opts) {
286686
+ const lineOffset = sumLineHeights(opts.measure, opts.startLineIndex, opts.lineIndex);
286376
286687
  rects.push({
286377
286688
  x: opts.x,
286378
- y: opts.y,
286689
+ y: opts.yBase + lineOffset,
286379
286690
  width: Math.max(1, opts.width),
286380
- height: opts.height,
286691
+ height: opts.lineHeight,
286381
286692
  pageIndex: opts.pageIndex
286382
286693
  });
286383
286694
  }
@@ -286408,13 +286719,15 @@ function selectionToRects(layout, blocks2, measures, from$1, to, geometryHelper)
286408
286719
  const sliceFrom = Math.max(range.pmStart, from$1);
286409
286720
  const sliceTo = Math.min(range.pmEnd, to);
286410
286721
  if (sliceFrom >= sliceTo) {
286411
- const emptyLineOffset = lineHeightBeforeIndex$1(measure, index2) - lineHeightBeforeIndex$1(measure, fragment2.fromLine);
286412
286722
  pushEmptyLineSelectionBand(rects, {
286413
286723
  x: fragment2.x,
286414
- y: fragment2.y + emptyLineOffset + pageTopY,
286724
+ yBase: fragment2.y + pageTopY,
286415
286725
  width: fragment2.width,
286416
- height: line.lineHeight,
286417
- pageIndex
286726
+ lineHeight: line.lineHeight,
286727
+ pageIndex,
286728
+ measure,
286729
+ lineIndex: index2,
286730
+ startLineIndex: fragment2.fromLine
286418
286731
  });
286419
286732
  return;
286420
286733
  }
@@ -286596,13 +286909,15 @@ function selectionToRects(layout, blocks2, measures, from$1, to, geometryHelper)
286596
286909
  const sliceFrom = Math.max(range.pmStart, from$1);
286597
286910
  const sliceTo = Math.min(range.pmEnd, to);
286598
286911
  if (sliceFrom >= sliceTo) {
286599
- const emptyLineOffset = lineHeightBeforeIndex$1(info.measure, index2) - lineHeightBeforeIndex$1(info.measure, info.startLine);
286600
286912
  pushEmptyLineSelectionBand(rects, {
286601
286913
  x: fragment2.x + contentOffsetX + cellX + padding.left,
286602
- y: fragment2.y + contentOffsetY + rowOffset + blockTopCursor + effectiveSpacingBeforePx + emptyLineOffset + pageTopY,
286914
+ yBase: fragment2.y + contentOffsetY + rowOffset + blockTopCursor + effectiveSpacingBeforePx + pageTopY,
286603
286915
  width: cellMeasure.width - padding.left - padding.right,
286604
- height: line.lineHeight,
286605
- pageIndex
286916
+ lineHeight: line.lineHeight,
286917
+ pageIndex,
286918
+ measure: info.measure,
286919
+ lineIndex: index2,
286920
+ startLineIndex: info.startLine
286606
286921
  });
286607
286922
  return;
286608
286923
  }
@@ -286943,15 +287258,7 @@ function selectionCollapsesAcrossTableCells(doc$12, anchor, head) {
286943
287258
  return false;
286944
287259
  const $from = doc$12.resolve(Math.min(anchor, head));
286945
287260
  const $to = doc$12.resolve(Math.max(anchor, head));
286946
- const cellAncestor = (pos) => {
286947
- for (let depth = pos.depth;depth > 0; depth--) {
286948
- const role = pos.node(depth).type.spec.tableRole;
286949
- if (role === "cell" || role === "header_cell")
286950
- return pos.node(depth);
286951
- }
286952
- return null;
286953
- };
286954
- return cellAncestor($from) !== cellAncestor($to) && $to.parentOffset === 0;
287261
+ return cellWrapping2($from) !== cellWrapping2($to) && $to.parentOffset === 0;
286955
287262
  } catch {
286956
287263
  return false;
286957
287264
  }
@@ -288939,6 +289246,19 @@ function getTopLevelTableBlockAtPos(doc$12, blocks2, tablePos) {
288939
289246
  return null;
288940
289247
  return getTableBlocks(blocks2)[tableIndex] ?? null;
288941
289248
  }
289249
+ function resolveCellContextAtResolvedPos($pos) {
289250
+ const $cell = cellAround($pos);
289251
+ if (!$cell)
289252
+ return null;
289253
+ const table2 = findTable($cell);
289254
+ if (!table2)
289255
+ return null;
289256
+ return {
289257
+ $cell,
289258
+ cellPos: $cell.pos,
289259
+ tablePos: table2.pos
289260
+ };
289261
+ }
288942
289262
  function resolveCellAnchorStateFromCellPos(doc$12, blocks2, cellPos) {
288943
289263
  if (!doc$12 || !Number.isFinite(cellPos) || cellPos < 0 || cellPos > doc$12.content.size)
288944
289264
  return null;
@@ -289043,30 +289363,30 @@ function resolveCellContext(doc$12, pos) {
289043
289363
  } catch {
289044
289364
  return null;
289045
289365
  }
289046
- let cellDepth = -1;
289047
- let tableDepth = -1;
289048
- for (let depth = $pos.depth;depth > 0; depth--) {
289049
- const role = $pos.node(depth).type.spec.tableRole;
289050
- if (cellDepth === -1 && (role === "cell" || role === "header_cell"))
289051
- cellDepth = depth;
289052
- if (cellDepth !== -1 && role === "table") {
289053
- tableDepth = depth;
289054
- break;
289055
- }
289056
- }
289057
- if (cellDepth === -1 || tableDepth === -1)
289366
+ const context = resolveCellContextAtResolvedPos($pos);
289367
+ if (!context)
289058
289368
  return null;
289059
289369
  return {
289060
- cellPos: $pos.before(cellDepth),
289061
- tablePos: $pos.before(tableDepth)
289370
+ cellPos: context.cellPos,
289371
+ tablePos: context.tablePos
289062
289372
  };
289063
289373
  }
289064
289374
  function resolveCrossCellSelection(doc$12, anchorPos, headPos) {
289065
- const anchor = resolveCellContext(doc$12, anchorPos);
289066
- const head = resolveCellContext(doc$12, headPos);
289375
+ if (!doc$12)
289376
+ return null;
289377
+ let $anchorPos;
289378
+ let $headPos;
289379
+ try {
289380
+ $anchorPos = doc$12.resolve(anchorPos);
289381
+ $headPos = doc$12.resolve(headPos);
289382
+ } catch {
289383
+ return null;
289384
+ }
289385
+ const anchor = resolveCellContextAtResolvedPos($anchorPos);
289386
+ const head = resolveCellContextAtResolvedPos($headPos);
289067
289387
  if (!anchor || !head)
289068
289388
  return null;
289069
- if (anchor.tablePos !== head.tablePos)
289389
+ if (!inSameTable(anchor.$cell, head.$cell))
289070
289390
  return null;
289071
289391
  if (anchor.cellPos === head.cellPos)
289072
289392
  return null;
@@ -307106,7 +307426,8 @@ var Node$13 = class Node$14 {
307106
307426
  const ySyncMeta = tr.getMeta(ySyncPluginKey);
307107
307427
  const pendingDeadKeyPlaceholder = TrackChangesBasePluginKey.getState(state)?.pendingDeadKeyPlaceholder ?? null;
307108
307428
  const hasDisallowedMeta = tr.meta && Object.keys(tr.meta).some((meta2) => !ALLOWED_META_KEYS.has(meta2));
307109
- if (ySyncMeta?.isChangeOrigin || !tr.steps.length || hasDisallowedMeta && !isProgrammaticInput || notAllowedMeta.includes(tr.getMeta("inputType")) || tr.getMeta(CommentsPluginKey)) {
307429
+ const isBlockIdentityRepair = Boolean(tr.getMeta("superdoc/block-identity-repair"));
307430
+ if (ySyncMeta?.isChangeOrigin || !tr.steps.length || isBlockIdentityRepair || hasDisallowedMeta && !isProgrammaticInput || notAllowedMeta.includes(tr.getMeta("inputType")) || tr.getMeta(CommentsPluginKey)) {
307110
307431
  if (pendingDeadKeyPlaceholder && !isCompositionTransaction(tr))
307111
307432
  mergeTrackChangesMeta(tr, { pendingDeadKeyPlaceholder: null });
307112
307433
  return tr;
@@ -333454,13 +333775,13 @@ menclose::after {
333454
333775
  return;
333455
333776
  console.log(...args$1);
333456
333777
  }, 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;
333457
- var init_src_BB0n1coY_es = __esm(() => {
333778
+ var init_src_PJVnllcq_es = __esm(() => {
333458
333779
  init_rolldown_runtime_Bg48TavK_es();
333459
- init_SuperConverter_CCgGAnXY_es();
333780
+ init_SuperConverter_DK5WIHuy_es();
333460
333781
  init_jszip_C49i9kUs_es();
333461
333782
  init_xml_js_CqGKpaft_es();
333462
333783
  init_uuid_B2wVPhPi_es();
333463
- init_create_headless_toolbar_BvrKiWf0_es();
333784
+ init_create_headless_toolbar_BLN1v7eO_es();
333464
333785
  init_constants_D9qj59G2_es();
333465
333786
  init_dist_B8HfvhaK_es();
333466
333787
  init_unified_Dsuw2be5_es();
@@ -369245,11 +369566,11 @@ function print() { __p += __j.call(arguments, '') }
369245
369566
  ]);
369246
369567
  });
369247
369568
 
369248
- // ../../packages/superdoc/dist/chunks/create-super-doc-ui-C_J_pCF0.es.js
369569
+ // ../../packages/superdoc/dist/chunks/create-super-doc-ui-CrjXK3s_.es.js
369249
369570
  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;
369250
- var init_create_super_doc_ui_C_J_pCF0_es = __esm(() => {
369251
- init_SuperConverter_CCgGAnXY_es();
369252
- init_create_headless_toolbar_BvrKiWf0_es();
369571
+ var init_create_super_doc_ui_CrjXK3s__es = __esm(() => {
369572
+ init_SuperConverter_DK5WIHuy_es();
369573
+ init_create_headless_toolbar_BLN1v7eO_es();
369253
369574
  DEFAULT_TEXT_ALIGN_OPTIONS = [
369254
369575
  {
369255
369576
  label: "Left",
@@ -369540,16 +369861,16 @@ var init_zipper_yaJVJ4z9_es = __esm(() => {
369540
369861
 
369541
369862
  // ../../packages/superdoc/dist/super-editor.es.js
369542
369863
  var init_super_editor_es = __esm(() => {
369543
- init_src_BB0n1coY_es();
369544
- init_SuperConverter_CCgGAnXY_es();
369864
+ init_src_PJVnllcq_es();
369865
+ init_SuperConverter_DK5WIHuy_es();
369545
369866
  init_jszip_C49i9kUs_es();
369546
369867
  init_xml_js_CqGKpaft_es();
369547
- init_create_headless_toolbar_BvrKiWf0_es();
369868
+ init_create_headless_toolbar_BLN1v7eO_es();
369548
369869
  init_constants_D9qj59G2_es();
369549
369870
  init_dist_B8HfvhaK_es();
369550
369871
  init_unified_Dsuw2be5_es();
369551
369872
  init_DocxZipper_FUsfThjV_es();
369552
- init_create_super_doc_ui_C_J_pCF0_es();
369873
+ init_create_super_doc_ui_CrjXK3s__es();
369553
369874
  init_ui_C5PAS9hY_es();
369554
369875
  init_eventemitter3_BnGqBE_Q_es();
369555
369876
  init_errors_CNaD6vcg_es();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superdoc-dev/cli",
3
- "version": "0.17.0-next.25",
3
+ "version": "0.17.0-next.27",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "superdoc": "./dist/index.js"
@@ -33,11 +33,11 @@
33
33
  "access": "public"
34
34
  },
35
35
  "optionalDependencies": {
36
- "@superdoc-dev/cli-darwin-arm64": "0.17.0-next.25",
37
- "@superdoc-dev/cli-darwin-x64": "0.17.0-next.25",
38
- "@superdoc-dev/cli-linux-arm64": "0.17.0-next.25",
39
- "@superdoc-dev/cli-windows-x64": "0.17.0-next.25",
40
- "@superdoc-dev/cli-linux-x64": "0.17.0-next.25"
36
+ "@superdoc-dev/cli-darwin-arm64": "0.17.0-next.27",
37
+ "@superdoc-dev/cli-darwin-x64": "0.17.0-next.27",
38
+ "@superdoc-dev/cli-linux-x64": "0.17.0-next.27",
39
+ "@superdoc-dev/cli-linux-arm64": "0.17.0-next.27",
40
+ "@superdoc-dev/cli-windows-x64": "0.17.0-next.27"
41
41
  },
42
42
  "scripts": {
43
43
  "predev": "node scripts/ensure-superdoc-build.js",