@ai-matrx/office 0.8.29 → 0.8.30

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.
package/CHANGELOG.md CHANGED
@@ -1,10 +1,20 @@
1
1
  # Changelog
2
2
 
3
- ## 0.8.29
3
+ ## 0.8.30
4
4
 
5
5
  UNVERIFIED: this release has no Unreleased entry and the source comparison could not be made (the caller supplied no source comparison). Whether source changed is unknown; consumer action is unknown.
6
6
  Check the package's gitHead on npm against this version's gitHead: `git diff <previous gitHead> <this gitHead> -- apps/shared/office/src`.
7
7
 
8
+ ## 0.8.29
9
+
10
+ SOURCE CHANGED WITH NO RELEASE NOTE. This release shipped source changes that nobody described in an Unreleased entry,
11
+ so they may include breaking API changes. Consumer action is UNKNOWN: read the diff before upgrading.
12
+ Diff: `git diff 01daf620b4 acce3dd470 -- apps/shared/office/src`
13
+
14
+ Changed shipped source files (2):
15
+ - `apps/shared/office/src/collab/sheets/transform/fuzz/seats.ts`
16
+ - `apps/shared/office/src/univer/collab/sheets-ot/univer-port.ts`
17
+
8
18
  ## 0.8.28
9
19
 
10
20
  Automatic changed-only republish (docs/metadata drift since the last published version; verified: `git diff 0c69bc7f5b 01daf620b4 -- apps/shared/office/src`
package/dist/docs.cjs CHANGED
@@ -50,11 +50,111 @@ function takeCovered(snapshot) {
50
50
  };
51
51
  }
52
52
 
53
+ // src/docs/comment-anchors.ts
54
+
55
+ var COMMENT_ANCHOR_RANGE_TYPE = _core.CustomRangeType.COMMENT;
56
+ var COMMENT_ANCHOR_PART_PREFIX = "anchor:";
57
+ var COMMENT_ANCHOR_LABEL_MAX = 200;
58
+ var ID_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789";
59
+ function newCommentAnchorId() {
60
+ const bytes = new Uint8Array(16);
61
+ globalThis.crypto.getRandomValues(bytes);
62
+ let out = "c";
63
+ for (const b of bytes) out += ID_ALPHABET[b % ID_ALPHABET.length];
64
+ return out;
65
+ }
66
+ function commentAnchorPartKey(anchorId) {
67
+ return `${COMMENT_ANCHOR_PART_PREFIX}${anchorId}`;
68
+ }
69
+ function anchorIdOfPartAnchor(anchor) {
70
+ if (!anchor || typeof anchor !== "object") return null;
71
+ const a = anchor;
72
+ if ((a.__kind === "part_anchor" || a.__kind === "text_anchor") && typeof a.anchor_id === "string" && a.anchor_id.length > 0) return a.anchor_id;
73
+ if (a.__kind !== "part_anchor" || typeof a.part_key !== "string") return null;
74
+ if (!a.part_key.startsWith(COMMENT_ANCHOR_PART_PREFIX)) return null;
75
+ const id = a.part_key.slice(COMMENT_ANCHOR_PART_PREFIX.length);
76
+ return id.length > 0 ? id : null;
77
+ }
78
+ function quoteOfCommentAnchor(anchor) {
79
+ if (!anchor || typeof anchor !== "object") return "";
80
+ const a = anchor;
81
+ return typeof a.label === "string" ? a.label : typeof a.exact === "string" ? a.exact : "";
82
+ }
83
+ function commentPartAnchor(anchorId, quote) {
84
+ const label = quote.replace(/\s+/g, " ").trim().slice(0, COMMENT_ANCHOR_LABEL_MAX);
85
+ return { __kind: "part_anchor", part_key: commentAnchorPartKey(anchorId), ...label ? { label } : {} };
86
+ }
87
+ var CONTROL = /[\u0000-\u001f\u007f]/g;
88
+ function commentAnchorsOf(body) {
89
+ const out = /* @__PURE__ */ new Map();
90
+ const b = _nullishCoalesce(body, () => ( {}));
91
+ const stream = typeof b.dataStream === "string" ? b.dataStream : "";
92
+ for (const r of _nullishCoalesce(b.customRanges, () => ( []))) {
93
+ if (!r || r.rangeType !== COMMENT_ANCHOR_RANGE_TYPE || typeof r.rangeId !== "string") continue;
94
+ const start = r.startIndex;
95
+ const end = r.endIndex + 1;
96
+ if (!(end > start)) continue;
97
+ const had = out.get(r.rangeId);
98
+ const s2 = had ? Math.min(had.start, start) : start;
99
+ const e2 = had ? Math.max(had.end, end) : end;
100
+ out.set(r.rangeId, { id: r.rangeId, start: s2, end: e2, text: "" });
101
+ }
102
+ for (const span of out.values()) span.text = stream.slice(span.start, span.end).replace(CONTROL, " ");
103
+ return out;
104
+ }
105
+ function addCommentAnchorActions(body, start, end, anchorId) {
106
+ if (!(end > start) || start < 0) return null;
107
+ const textX = _core.BuildTextUtils.customRange.add({
108
+ body,
109
+ ranges: [{ startOffset: start, endOffset: end, collapsed: false }],
110
+ rangeId: anchorId,
111
+ rangeType: COMMENT_ANCHOR_RANGE_TYPE
112
+ });
113
+ if (!textX) return null;
114
+ return _core.JSONX.getInstance().editOp(textX.serialize(), ["body"]);
115
+ }
116
+ function removeCommentAnchorActions(documentDataModel, anchorId) {
117
+ const textX = _core.BuildTextUtils.customRange.delete({ documentDataModel, rangeId: anchorId });
118
+ if (!textX) return null;
119
+ return _core.JSONX.getInstance().editOp(textX.serialize(), ["body"]);
120
+ }
121
+ var RETAIN_KEYS = /* @__PURE__ */ new Set(["t", "len", "body", "coverType"]);
122
+ var RANGE_KEYS = /* @__PURE__ */ new Set(["rangeId", "rangeType", "startIndex", "endIndex", "properties"]);
123
+ var isObj = (v) => !!v && typeof v === "object" && !Array.isArray(v);
124
+ var keysOf = (o) => Object.keys(o).filter((k) => o[k] !== void 0);
125
+ function isDocsAnchorOnlyOp(op) {
126
+ if (!Array.isArray(op) || op.length !== 2 || op[0] !== "body") return false;
127
+ const x = op[1];
128
+ if (!isObj(x) || x.et !== "text-x" || !Array.isArray(x.e) || x.e.length === 0) return false;
129
+ if (keysOf(x).some((k) => k !== "et" && k !== "e")) return false;
130
+ for (const c of x.e) {
131
+ if (!isObj(c) || c.t !== "r" || typeof c.len !== "number") return false;
132
+ if (keysOf(c).some((k) => !RETAIN_KEYS.has(k))) return false;
133
+ if ("coverType" in c && typeof c.coverType !== "number") return false;
134
+ if ("body" in c) {
135
+ const b = c.body;
136
+ if (!isObj(b) || keysOf(b).some((k) => k !== "dataStream" && k !== "customRanges")) return false;
137
+ if (b.dataStream !== void 0 && b.dataStream !== "") return false;
138
+ if (!Array.isArray(b.customRanges) || b.customRanges.length === 0) return false;
139
+ for (const r of b.customRanges) {
140
+ if (!isObj(r) || r.rangeType !== COMMENT_ANCHOR_RANGE_TYPE) return false;
141
+ if (keysOf(r).some((k) => !RANGE_KEYS.has(k))) return false;
142
+ }
143
+ }
144
+ }
145
+ return true;
146
+ }
147
+
53
148
  // src/docs/document-model.ts
54
149
  var RICH_TEXT_EDITING_ID = "doc.mutation.rich-text-editing";
55
150
  var COMMAND_TYPE = 0;
56
151
  var DEPTH_GUARDED = /* @__PURE__ */ Symbol.for("ai-matrx.office.docs.command-depth-guard");
57
152
  var DOCUMENT_SAVE_DELAY_MS = 2500;
153
+ function isCommentAnchorMutation(info) {
154
+ if (info.id !== RICH_TEXT_EDITING_ID) return false;
155
+ const params = info.params;
156
+ return !!params && !params.segmentId && isDocsAnchorOnlyOp(params.actions);
157
+ }
58
158
  var viewIds = 0;
59
159
  var DocumentModel = (_class = class {
60
160
 
@@ -193,11 +293,13 @@ var DocumentModel = (_class = class {
193
293
  onViewMutation(viewId, info, options) {
194
294
  if (this.relaying || _optionalChain([options, 'optionalAccess', _19 => _19.fromCollab]) || _optionalChain([options, 'optionalAccess', _20 => _20.fromChangeset])) return;
195
295
  const view = this.views.get(viewId);
196
- if (!view || !view.port.editable()) return;
296
+ if (!view) return;
297
+ const editable = view.port.editable();
298
+ if (!editable && !(_optionalChain([view, 'access', _21 => _21.port, 'access', _22 => _22.commentOnly, 'optionalCall', _23 => _23()]) === true && isCommentAnchorMutation(info))) return;
197
299
  this.lastEditedView = viewId;
198
300
  this.relay(info, viewId);
199
301
  for (const listener of this.collabListeners) listener(info, options);
200
- if (this.otListeners.size && !_optionalChain([options, 'optionalAccess', _21 => _21.onlyLocal])) {
302
+ if (this.otListeners.size && !_optionalChain([options, 'optionalAccess', _24 => _24.onlyLocal])) {
201
303
  const m = {
202
304
  id: info.id,
203
305
  params: info.params,
@@ -208,7 +310,7 @@ var DocumentModel = (_class = class {
208
310
  view.pre = null;
209
311
  for (const listener of Array.from(this.otListeners)) listener(m);
210
312
  }
211
- if (isContentMutation(info)) this.markDirty();
313
+ if (editable && isContentMutation(info)) this.markDirty();
212
314
  }
213
315
  /**
214
316
  * Per view: the outermost command running (a mutation's group label) and, while a room listens, the document
@@ -257,7 +359,7 @@ var DocumentModel = (_class = class {
257
359
  /** The unit id a view's document has (what a replayed mutation must be addressed to). */
258
360
  unitIdOf(view) {
259
361
  try {
260
- return _nullishCoalesce(_nullishCoalesce(_optionalChain([view, 'access', _22 => _22.port, 'access', _23 => _23.unitId, 'optionalCall', _24 => _24()]), () => ( _optionalChain([view, 'access', _25 => _25.port, 'access', _26 => _26.snapshot, 'call', _27 => _27(), 'optionalAccess', _28 => _28.id]))), () => ( null));
362
+ return _nullishCoalesce(_nullishCoalesce(_optionalChain([view, 'access', _25 => _25.port, 'access', _26 => _26.unitId, 'optionalCall', _27 => _27()]), () => ( _optionalChain([view, 'access', _28 => _28.port, 'access', _29 => _29.snapshot, 'call', _30 => _30(), 'optionalAccess', _31 => _31.id]))), () => ( null));
261
363
  } catch (e6) {
262
364
  return null;
263
365
  }
@@ -291,7 +393,7 @@ var DocumentModel = (_class = class {
291
393
  /** A view could not follow an edit: say so, then show the saved version (unless this tab has unsaved edits of its own). */
292
394
  applyFailed(mutationId, error) {
293
395
  try {
294
- _optionalChain([this, 'access', _29 => _29.deps, 'access', _30 => _30.onApplyFailed, 'optionalCall', _31 => _31(this.documentId, mutationId, error)]);
396
+ _optionalChain([this, 'access', _32 => _32.deps, 'access', _33 => _33.onApplyFailed, 'optionalCall', _34 => _34(this.documentId, mutationId, error)]);
295
397
  } catch (notifyError) {
296
398
  console.warn(`[document-model] the notice for ${this.documentId}'s failed apply also failed`, notifyError);
297
399
  }
@@ -319,7 +421,7 @@ var DocumentModel = (_class = class {
319
421
  async write(reason) {
320
422
  if (this.ot) {
321
423
  const wrote = await this.ot.write(reason);
322
- if (wrote) _optionalChain([this, 'access', _32 => _32.deps, 'access', _33 => _33.onSaved, 'optionalCall', _34 => _34(this.documentId, reason === "manual" ? "manual" : "autosave")]);
424
+ if (wrote) _optionalChain([this, 'access', _35 => _35.deps, 'access', _36 => _36.onSaved, 'optionalCall', _37 => _37(this.documentId, reason === "manual" ? "manual" : "autosave")]);
323
425
  return wrote;
324
426
  }
325
427
  const snapshot = this.latest();
@@ -344,7 +446,7 @@ var DocumentModel = (_class = class {
344
446
  this.saving = false;
345
447
  }
346
448
  if (this.views.size === 0) this.stored = snapshot;
347
- _optionalChain([this, 'access', _35 => _35.deps, 'access', _36 => _36.onSaved, 'optionalCall', _37 => _37(this.documentId, origin)]);
449
+ _optionalChain([this, 'access', _38 => _38.deps, 'access', _39 => _39.onSaved, 'optionalCall', _40 => _40(this.documentId, origin)]);
348
450
  return true;
349
451
  }
350
452
  hasUnsaved() {
@@ -387,7 +489,7 @@ var DocumentModel = (_class = class {
387
489
  replaceContent(row) {
388
490
  if (this.ot) return this.ot.replace(row.snapshot);
389
491
  this.show(row);
390
- _optionalChain([this, 'access', _38 => _38.collab, 'optionalAccess', _39 => _39.announceReplaced, 'call', _40 => _40(row.id)]);
492
+ _optionalChain([this, 'access', _41 => _41.collab, 'optionalAccess', _42 => _42.announceReplaced, 'call', _43 => _43(row.id)]);
391
493
  }
392
494
  /** A peer replaced the document: show the newest save (once). */
393
495
  async onPeerReplaced() {
@@ -410,7 +512,7 @@ var DocumentModel = (_class = class {
410
512
  this.relaying = true;
411
513
  try {
412
514
  for (const view of this.views.values()) view.port.remount(snapshot);
413
- _optionalChain([this, 'access', _41 => _41.parked, 'optionalAccess', _42 => _42.remount, 'call', _43 => _43(snapshot)]);
515
+ _optionalChain([this, 'access', _44 => _44.parked, 'optionalAccess', _45 => _45.remount, 'call', _46 => _46(snapshot)]);
414
516
  } finally {
415
517
  this.relaying = false;
416
518
  }
@@ -484,7 +586,7 @@ var DocumentModel = (_class = class {
484
586
  const input = Array.isArray(params.actions) ? params.actions.length : 0;
485
587
  let sel = null;
486
588
  try {
487
- sel = _nullishCoalesce(_optionalChain([view, 'access', _44 => _44.port, 'access', _45 => _45.selection, 'optionalAccess', _46 => _46.get, 'call', _47 => _47()]), () => ( null));
589
+ sel = _nullishCoalesce(_optionalChain([view, 'access', _47 => _47.port, 'access', _48 => _48.selection, 'optionalAccess', _49 => _49.get, 'call', _50 => _50()]), () => ( null));
488
590
  } catch (e7) {
489
591
  sel = null;
490
592
  }
@@ -495,7 +597,7 @@ var DocumentModel = (_class = class {
495
597
  const moved = sel && sel.length && sel.every((r) => !r.segmentId) ? moveRangesThroughBodyEdit(sel, params.actions) : null;
496
598
  if (moved) {
497
599
  try {
498
- _optionalChain([view, 'access', _48 => _48.port, 'access', _49 => _49.selection, 'optionalAccess', _50 => _50.set, 'call', _51 => _51(moved)]);
600
+ _optionalChain([view, 'access', _51 => _51.port, 'access', _52 => _52.selection, 'optionalAccess', _53 => _53.set, 'call', _54 => _54(moved)]);
499
601
  } catch (error) {
500
602
  console.warn(`[document-model] could not move this view's caret past a collaborator's edit`, error);
501
603
  }
@@ -514,7 +616,7 @@ var DocumentModel = (_class = class {
514
616
  this.relaying = true;
515
617
  try {
516
618
  for (const view of this.views.values()) view.port.remount(s2);
517
- _optionalChain([this, 'access', _52 => _52.parked, 'optionalAccess', _53 => _53.remount, 'call', _54 => _54(s2)]);
619
+ _optionalChain([this, 'access', _55 => _55.parked, 'optionalAccess', _56 => _56.remount, 'call', _57 => _57(s2)]);
518
620
  } finally {
519
621
  this.relaying = false;
520
622
  }
@@ -523,7 +625,7 @@ var DocumentModel = (_class = class {
523
625
  const out = [];
524
626
  for (const view of this.views.values()) {
525
627
  const unitId = this.unitIdOf(view);
526
- const service = _optionalChain([view, 'access', _55 => _55.port, 'access', _56 => _56.undoRedo, 'optionalCall', _57 => _57()]);
628
+ const service = _optionalChain([view, 'access', _58 => _58.port, 'access', _59 => _59.undoRedo, 'optionalCall', _60 => _60()]);
527
629
  if (unitId && service) out.push({ service, unitId });
528
630
  }
529
631
  return out;
@@ -532,7 +634,7 @@ var DocumentModel = (_class = class {
532
634
  selection: () => {
533
635
  for (const view of this.views.values()) {
534
636
  try {
535
- const sel = _optionalChain([view, 'access', _58 => _58.port, 'access', _59 => _59.selection, 'optionalAccess', _60 => _60.get, 'call', _61 => _61()]);
637
+ const sel = _optionalChain([view, 'access', _61 => _61.port, 'access', _62 => _62.selection, 'optionalAccess', _63 => _63.get, 'call', _64 => _64()]);
536
638
  if (sel) return sel;
537
639
  } catch (e8) {
538
640
  }
@@ -591,9 +693,9 @@ var DocumentModel = (_class = class {
591
693
  * so a collaborator's save still reaches the body a returning view boots from.
592
694
  */
593
695
  rest() {
594
- _optionalChain([this, 'access', _62 => _62.collab, 'optionalAccess', _63 => _63.stop, 'call', _64 => _64()]);
696
+ _optionalChain([this, 'access', _65 => _65.collab, 'optionalAccess', _66 => _66.stop, 'call', _67 => _67()]);
595
697
  this.collab = null;
596
- _optionalChain([this, 'access', _65 => _65.ot, 'optionalAccess', _66 => _66.stop, 'call', _67 => _67()]);
698
+ _optionalChain([this, 'access', _68 => _68.ot, 'optionalAccess', _69 => _69.stop, 'call', _70 => _70()]);
597
699
  this.ot = null;
598
700
  this.awareness = null;
599
701
  }
@@ -609,9 +711,9 @@ var DocumentModel = (_class = class {
609
711
  console.warn(`[document-model] could not dispose ${this.documentId}'s kept editor`, error);
610
712
  }
611
713
  }
612
- _optionalChain([this, 'access', _68 => _68.realtimeClose, 'optionalCall', _69 => _69()]);
714
+ _optionalChain([this, 'access', _71 => _71.realtimeClose, 'optionalCall', _72 => _72()]);
613
715
  this.realtimeClose = null;
614
- _optionalChain([this, 'access', _70 => _70.pageClose, 'optionalCall', _71 => _71()]);
716
+ _optionalChain([this, 'access', _73 => _73.pageClose, 'optionalCall', _74 => _74()]);
615
717
  this.pageClose = null;
616
718
  }
617
719
  }, _class);
@@ -889,12 +991,12 @@ function movePeerRangesThroughBodyEdit(ranges, actions) {
889
991
  }
890
992
  var sameRanges = (a, b) => a.length === b.length && a.every((r, i) => r.start === b[i].start && r.end === b[i].end);
891
993
  function readCaret(raw) {
892
- const c = _optionalChain([raw, 'optionalAccess', _72 => _72.caret]);
994
+ const c = _optionalChain([raw, 'optionalAccess', _75 => _75.caret]);
893
995
  if (!c || !Array.isArray(c.ranges) || typeof c.at !== "number") return null;
894
996
  const ranges = [];
895
997
  for (const r of c.ranges.slice(0, CARET_MAX_RANGES)) {
896
- const s2 = _optionalChain([r, 'optionalAccess', _73 => _73.start]);
897
- const e2 = _optionalChain([r, 'optionalAccess', _74 => _74.end]);
998
+ const s2 = _optionalChain([r, 'optionalAccess', _76 => _76.start]);
999
+ const e2 = _optionalChain([r, 'optionalAccess', _77 => _77.end]);
898
1000
  if (typeof s2 !== "number" || typeof e2 !== "number" || !Number.isFinite(s2) || !Number.isFinite(e2) || s2 < 0 || e2 < 0) return null;
899
1001
  ranges.push({ start: s2, end: e2 });
900
1002
  }
@@ -960,101 +1062,6 @@ var RemoteCaretBook = (_class2 = class {
960
1062
  }
961
1063
  }, _class2);
962
1064
 
963
- // src/docs/comment-anchors.ts
964
-
965
- var COMMENT_ANCHOR_RANGE_TYPE = _core.CustomRangeType.COMMENT;
966
- var COMMENT_ANCHOR_PART_PREFIX = "anchor:";
967
- var COMMENT_ANCHOR_LABEL_MAX = 200;
968
- var ID_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789";
969
- function newCommentAnchorId() {
970
- const bytes = new Uint8Array(16);
971
- globalThis.crypto.getRandomValues(bytes);
972
- let out = "c";
973
- for (const b of bytes) out += ID_ALPHABET[b % ID_ALPHABET.length];
974
- return out;
975
- }
976
- function commentAnchorPartKey(anchorId) {
977
- return `${COMMENT_ANCHOR_PART_PREFIX}${anchorId}`;
978
- }
979
- function anchorIdOfPartAnchor(anchor) {
980
- if (!anchor || typeof anchor !== "object") return null;
981
- const a = anchor;
982
- if ((a.__kind === "part_anchor" || a.__kind === "text_anchor") && typeof a.anchor_id === "string" && a.anchor_id.length > 0) return a.anchor_id;
983
- if (a.__kind !== "part_anchor" || typeof a.part_key !== "string") return null;
984
- if (!a.part_key.startsWith(COMMENT_ANCHOR_PART_PREFIX)) return null;
985
- const id = a.part_key.slice(COMMENT_ANCHOR_PART_PREFIX.length);
986
- return id.length > 0 ? id : null;
987
- }
988
- function quoteOfCommentAnchor(anchor) {
989
- if (!anchor || typeof anchor !== "object") return "";
990
- const a = anchor;
991
- return typeof a.label === "string" ? a.label : typeof a.exact === "string" ? a.exact : "";
992
- }
993
- function commentPartAnchor(anchorId, quote) {
994
- const label = quote.replace(/\s+/g, " ").trim().slice(0, COMMENT_ANCHOR_LABEL_MAX);
995
- return { __kind: "part_anchor", part_key: commentAnchorPartKey(anchorId), ...label ? { label } : {} };
996
- }
997
- var CONTROL = /[\u0000-\u001f\u007f]/g;
998
- function commentAnchorsOf(body) {
999
- const out = /* @__PURE__ */ new Map();
1000
- const b = _nullishCoalesce(body, () => ( {}));
1001
- const stream = typeof b.dataStream === "string" ? b.dataStream : "";
1002
- for (const r of _nullishCoalesce(b.customRanges, () => ( []))) {
1003
- if (!r || r.rangeType !== COMMENT_ANCHOR_RANGE_TYPE || typeof r.rangeId !== "string") continue;
1004
- const start = r.startIndex;
1005
- const end = r.endIndex + 1;
1006
- if (!(end > start)) continue;
1007
- const had = out.get(r.rangeId);
1008
- const s2 = had ? Math.min(had.start, start) : start;
1009
- const e2 = had ? Math.max(had.end, end) : end;
1010
- out.set(r.rangeId, { id: r.rangeId, start: s2, end: e2, text: "" });
1011
- }
1012
- for (const span of out.values()) span.text = stream.slice(span.start, span.end).replace(CONTROL, " ");
1013
- return out;
1014
- }
1015
- function addCommentAnchorActions(body, start, end, anchorId) {
1016
- if (!(end > start) || start < 0) return null;
1017
- const textX = _core.BuildTextUtils.customRange.add({
1018
- body,
1019
- ranges: [{ startOffset: start, endOffset: end, collapsed: false }],
1020
- rangeId: anchorId,
1021
- rangeType: COMMENT_ANCHOR_RANGE_TYPE
1022
- });
1023
- if (!textX) return null;
1024
- return _core.JSONX.getInstance().editOp(textX.serialize(), ["body"]);
1025
- }
1026
- function removeCommentAnchorActions(documentDataModel, anchorId) {
1027
- const textX = _core.BuildTextUtils.customRange.delete({ documentDataModel, rangeId: anchorId });
1028
- if (!textX) return null;
1029
- return _core.JSONX.getInstance().editOp(textX.serialize(), ["body"]);
1030
- }
1031
- var RETAIN_KEYS = /* @__PURE__ */ new Set(["t", "len", "body", "coverType"]);
1032
- var RANGE_KEYS = /* @__PURE__ */ new Set(["rangeId", "rangeType", "startIndex", "endIndex", "properties"]);
1033
- var isObj = (v) => !!v && typeof v === "object" && !Array.isArray(v);
1034
- var keysOf = (o) => Object.keys(o).filter((k) => o[k] !== void 0);
1035
- function isDocsAnchorOnlyOp(op) {
1036
- if (!Array.isArray(op) || op.length !== 2 || op[0] !== "body") return false;
1037
- const x = op[1];
1038
- if (!isObj(x) || x.et !== "text-x" || !Array.isArray(x.e) || x.e.length === 0) return false;
1039
- if (keysOf(x).some((k) => k !== "et" && k !== "e")) return false;
1040
- for (const c of x.e) {
1041
- if (!isObj(c) || c.t !== "r" || typeof c.len !== "number") return false;
1042
- if (keysOf(c).some((k) => !RETAIN_KEYS.has(k))) return false;
1043
- if ("coverType" in c && typeof c.coverType !== "number") return false;
1044
- if ("body" in c) {
1045
- const b = c.body;
1046
- if (!isObj(b) || keysOf(b).some((k) => k !== "dataStream" && k !== "customRanges")) return false;
1047
- if (b.dataStream !== void 0 && b.dataStream !== "") return false;
1048
- if (!Array.isArray(b.customRanges) || b.customRanges.length === 0) return false;
1049
- for (const r of b.customRanges) {
1050
- if (!isObj(r) || r.rangeType !== COMMENT_ANCHOR_RANGE_TYPE) return false;
1051
- if (keysOf(r).some((k) => !RANGE_KEYS.has(k))) return false;
1052
- }
1053
- }
1054
- }
1055
- return true;
1056
- }
1057
-
1058
1065
 
1059
1066
 
1060
1067