@arbidocs/coedit 0.5.21 → 0.5.23

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/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var Y3 = require('yjs');
3
+ var Y = require('yjs');
4
4
  var store = require('@docx-editor.dev/core/store');
5
5
  var collaboration = require('@docx-editor.dev/core/collaboration');
6
6
  var replication = require('@docx-editor.dev/core/collaboration/replication');
@@ -23,7 +23,7 @@ function _interopNamespace(e) {
23
23
  return Object.freeze(n);
24
24
  }
25
25
 
26
- var Y3__namespace = /*#__PURE__*/_interopNamespace(Y3);
26
+ var Y__namespace = /*#__PURE__*/_interopNamespace(Y);
27
27
 
28
28
  // src/encoding.ts
29
29
 
@@ -336,6 +336,92 @@ function writeUnits(text, units) {
336
336
  function isRichParagraph(map) {
337
337
  return map.has("inline");
338
338
  }
339
+ var PACKED = "xml";
340
+ function isPackedElement(map) {
341
+ return map.has(PACKED);
342
+ }
343
+ function isCompact(map) {
344
+ return isRichParagraph(map) || isPackedElement(map);
345
+ }
346
+ var TEXT_BEARING = /* @__PURE__ */ new Set(["p", "t", "delText", "instrText", "delInstrText"]);
347
+ function packable(xml) {
348
+ if (xml.ns === WML && TEXT_BEARING.has(xml.local)) return false;
349
+ return xml.children.every((c) => typeof c === "string" || packable(c));
350
+ }
351
+ function createPacked(xml, scope) {
352
+ const map = new Y__namespace.Map();
353
+ map.set(PACKED, serializeXml(xml, scope));
354
+ return map;
355
+ }
356
+ function repack(map, xml) {
357
+ const next = serializeXml(xml, scopeOf(map));
358
+ if (map.get(PACKED) !== next) map.set(PACKED, next);
359
+ }
360
+ function scopeOf(node) {
361
+ const chain = [];
362
+ let parent = node.parent;
363
+ while (parent instanceof Y__namespace.Array) {
364
+ const owner = parent.parent;
365
+ if (!(owner instanceof Y__namespace.Map)) break;
366
+ chain.push(owner);
367
+ parent = owner.parent;
368
+ }
369
+ const scope = /* @__PURE__ */ new Map();
370
+ for (const el of chain.reverse()) {
371
+ for (const b of el.get("bindings").toArray()) scope.set(b.prefix, b.ns);
372
+ }
373
+ return scope;
374
+ }
375
+ function scopeWithin(el) {
376
+ const scope = scopeOf(el);
377
+ if (!isPackedElement(el)) {
378
+ for (const b of el.get("bindings").toArray()) scope.set(b.prefix, b.ns);
379
+ }
380
+ return scope;
381
+ }
382
+ var unpackLimits = { maxBytes: 64 * 1024 * 1024, maxElements: 2e6 };
383
+ function unpack(text, scope) {
384
+ const read = store.readXml(text, unpackLimits);
385
+ if (!read.ok) throw new Error(`collab: a packed element is not readable XML (${read.reason})`);
386
+ const convert = (node, outer) => {
387
+ const bindings = [];
388
+ const named = [];
389
+ for (const [name, value] of Object.entries(node.attributes)) {
390
+ if (name === "xmlns") bindings.push({ prefix: "", ns: value });
391
+ else if (name.startsWith("xmlns:")) bindings.push({ prefix: name.slice(6), ns: value });
392
+ else named.push([name, value]);
393
+ }
394
+ const inner = new Map(outer);
395
+ for (const b of bindings) inner.set(b.prefix, b.ns);
396
+ const resolve = (prefix) => {
397
+ if (prefix === "xml") return store.XML_NAMESPACE_URI;
398
+ const ns = inner.get(prefix);
399
+ if (ns === void 0)
400
+ throw new Error(`collab: prefix ${prefix} is not bound in a packed element`);
401
+ return ns;
402
+ };
403
+ const colon = node.name.indexOf(":");
404
+ const xml = {
405
+ ns: colon < 0 ? inner.get("") ?? "" : resolve(node.name.slice(0, colon)),
406
+ local: colon < 0 ? node.name : node.name.slice(colon + 1),
407
+ attrs: named.map(([name, value]) => {
408
+ const at = name.indexOf(":");
409
+ if (at < 0) return { ns: "", local: name, value };
410
+ const prefix = name.slice(0, at);
411
+ return { ns: resolve(prefix), local: name.slice(at + 1), prefix, value };
412
+ }),
413
+ bindings,
414
+ children: node.children.map(
415
+ (child) => child.type === "text" ? child.value : convert(child, inner)
416
+ )
417
+ };
418
+ if (colon >= 0) xml.prefix = node.name.slice(0, colon);
419
+ return xml;
420
+ };
421
+ const root = read.nodes.find((n) => n.type === "element");
422
+ if (!root || root.type !== "element") throw new Error("collab: a packed element is empty");
423
+ return convert(root, scope);
424
+ }
339
425
  function isParagraphEl(el) {
340
426
  return el.ns === WML && el.local === "p";
341
427
  }
@@ -343,47 +429,53 @@ function fieldsOf(map, xml) {
343
429
  map.set("ns", xml.ns);
344
430
  map.set("local", xml.local);
345
431
  if (xml.prefix !== void 0) map.set("prefix", xml.prefix);
346
- const attrs = new Y3__namespace.Array();
432
+ const attrs = new Y__namespace.Array();
347
433
  attrs.push(xml.attrs.map((a) => ({ ...a })));
348
434
  map.set("attrs", attrs);
349
- const bindings = new Y3__namespace.Array();
435
+ const bindings = new Y__namespace.Array();
350
436
  bindings.push(xml.bindings.map((b) => ({ ...b })));
351
437
  map.set("bindings", bindings);
352
438
  }
353
439
  function newText(value) {
354
- const text = new Y3__namespace.Text();
440
+ const text = new Y__namespace.Text();
355
441
  text.insert(0, value);
356
442
  return text;
357
443
  }
358
- function createRichParagraph(xml, encoded) {
359
- const map = new Y3__namespace.Map();
444
+ function createRichParagraph(xml, encoded, scope = /* @__PURE__ */ new Map()) {
445
+ const map = new Y__namespace.Map();
360
446
  fieldsOf(map, xml);
361
- const children = new Y3__namespace.Array();
362
- children.push(encoded.head.map((el) => xmlToLive(el)));
447
+ const inner = withBindings(scope, xml.bindings);
448
+ const children = new Y__namespace.Array();
449
+ children.push(encoded.head.map((el) => xmlToLive(el, inner)));
363
450
  map.set("children", children);
364
- const inline = new Y3__namespace.Text();
451
+ const inline = new Y__namespace.Text();
365
452
  writeUnits(inline, encoded.units);
366
453
  map.set("inline", inline);
367
454
  return map;
368
455
  }
369
- function xmlToLive(xml) {
456
+ function withBindings(scope, bindings) {
457
+ const inner = new Map(scope);
458
+ for (const b of bindings) inner.set(b.prefix, b.ns);
459
+ return inner;
460
+ }
461
+ function xmlToLive(xml, scope = /* @__PURE__ */ new Map(), root = false) {
370
462
  if (isParagraphEl(xml)) {
371
463
  const encoded = encodeParagraph(xml.children);
372
- if (encoded) return createRichParagraph(xml, encoded);
464
+ if (encoded) return createRichParagraph(xml, encoded, scope);
373
465
  }
374
- return xmlToGenericLive(xml);
375
- }
376
- function xmlToGenericLive(xml) {
377
- const map = new Y3__namespace.Map();
466
+ if (!root && packable(xml)) return createPacked(xml, scope);
467
+ const map = new Y__namespace.Map();
378
468
  fieldsOf(map, xml);
379
- const children = new Y3__namespace.Array();
380
- children.push(xml.children.map((c) => typeof c === "string" ? newText(c) : xmlToLive(c)));
469
+ const inner = withBindings(scope, xml.bindings);
470
+ const children = new Y__namespace.Array();
471
+ children.push(xml.children.map((c) => typeof c === "string" ? newText(c) : xmlToLive(c, inner)));
381
472
  map.set("children", children);
382
473
  return map;
383
474
  }
384
475
  function liveToXml(map) {
476
+ if (isPackedElement(map)) return unpack(map.get(PACKED), scopeOf(map));
385
477
  const prefix = map.get("prefix");
386
- const stored = map.get("children").toArray().map((child) => child instanceof Y3__namespace.Text ? child.toString() : liveToXml(child));
478
+ const stored = map.get("children").toArray().map((child) => child instanceof Y__namespace.Text ? child.toString() : liveToXml(child));
387
479
  const children = isRichParagraph(map) ? [...stored, ...decodeInline(readUnits(map.get("inline")))] : stored;
388
480
  const xml = {
389
481
  ns: map.get("ns"),
@@ -398,14 +490,13 @@ function liveToXml(map) {
398
490
  var escapeText = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
399
491
  var escapeAttr = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/\t/g, "&#9;").replace(/\n/g, "&#10;").replace(/\r/g, "&#13;");
400
492
  var qualified = (prefix, local) => prefix ? `${prefix}:${local}` : local;
401
- function serializeXml(el, scope) {
402
- const inScope = new Map(scope);
403
- for (const b of el.bindings) inScope.set(b.prefix, b.ns);
404
- let out = `<${qualified(el.prefix, el.local)}`;
405
- for (const b of el.bindings) {
493
+ function startTag(prefix, local, bindings, attrs, scope) {
494
+ const inScope = withBindings(scope, bindings);
495
+ let out = `<${qualified(prefix, local)}`;
496
+ for (const b of bindings) {
406
497
  out += b.prefix === "" ? ` xmlns="${escapeAttr(b.ns)}"` : ` xmlns:${b.prefix}="${escapeAttr(b.ns)}"`;
407
498
  }
408
- for (const a of el.attrs) {
499
+ for (const a of attrs) {
409
500
  let p = a.prefix;
410
501
  if (a.ns !== "" && !p) {
411
502
  for (const [candidate, uri] of inScope) {
@@ -417,48 +508,41 @@ function serializeXml(el, scope) {
417
508
  }
418
509
  out += ` ${qualified(p, a.local)}="${escapeAttr(a.value)}"`;
419
510
  }
511
+ return [out, inScope];
512
+ }
513
+ function serializeXml(el, scope) {
514
+ const [out, inScope] = startTag(el.prefix, el.local, el.bindings, el.attrs, scope);
420
515
  if (el.children.length === 0) return `${out}/>`;
421
- out += ">";
516
+ let body = "";
422
517
  for (const child of el.children) {
423
- out += typeof child === "string" ? escapeText(child) : serializeXml(child, inScope);
518
+ body += typeof child === "string" ? escapeText(child) : serializeXml(child, inScope);
424
519
  }
425
- return `${out}</${qualified(el.prefix, el.local)}>`;
520
+ return `${out}>${body}</${qualified(el.prefix, el.local)}>`;
426
521
  }
427
522
  function serializeLive(el, scope) {
428
- if (isRichParagraph(el)) return serializeXml(liveToXml(el), scope);
523
+ if (isPackedElement(el)) return el.get(PACKED);
429
524
  const prefix = el.get("prefix");
430
525
  const local = el.get("local");
431
526
  const bindings = el.get("bindings").toArray();
432
527
  const attrs = el.get("attrs").toArray();
433
528
  const children = el.get("children").toArray();
434
- const inScope = new Map(scope);
435
- for (const b of bindings) inScope.set(b.prefix, b.ns);
436
- let out = `<${qualified(prefix, local)}`;
437
- for (const b of bindings) {
438
- out += b.prefix === "" ? ` xmlns="${escapeAttr(b.ns)}"` : ` xmlns:${b.prefix}="${escapeAttr(b.ns)}"`;
439
- }
440
- for (const a of attrs) {
441
- let p = a.prefix;
442
- if (a.ns !== "" && !p) {
443
- for (const [candidate, uri] of inScope) {
444
- if (candidate !== "" && uri === a.ns) {
445
- p = candidate;
446
- break;
447
- }
448
- }
449
- }
450
- out += ` ${qualified(p, a.local)}="${escapeAttr(a.value)}"`;
451
- }
452
- if (children.length === 0) return `${out}/>`;
453
- out += ">";
529
+ const [out, inScope] = startTag(prefix, local, bindings, attrs, scope);
530
+ const inline = isRichParagraph(el) ? decodeInline(readUnits(el.get("inline"))) : [];
531
+ if (children.length === 0 && inline.length === 0) return `${out}/>`;
532
+ let body = "";
454
533
  for (const child of children) {
455
- out += child instanceof Y3__namespace.Text ? escapeText(child.toString()) : serializeLive(child, inScope);
534
+ body += child instanceof Y__namespace.Text ? escapeText(child.toString()) : serializeLive(child, inScope);
456
535
  }
457
- return `${out}</${qualified(prefix, local)}>`;
536
+ for (const child of inline) body += serializeXml(child, inScope);
537
+ return `${out}>${body}</${qualified(prefix, local)}>`;
458
538
  }
459
539
 
460
540
  // src/encoding.ts
461
- var COLLAB_FORMAT = "arbi-docx/1";
541
+ var COLLAB_FORMAT = "arbi-docx/2";
542
+ var READABLE_FORMATS = /* @__PURE__ */ new Set(["arbi-docx/1", COLLAB_FORMAT]);
543
+ function isReadableFormat(format) {
544
+ return format !== void 0 && READABLE_FORMATS.has(format);
545
+ }
462
546
  function isBootstrapped(doc) {
463
547
  return doc.getMap("meta").get("format") !== void 0;
464
548
  }
@@ -752,7 +836,7 @@ var NodeRegistry = class {
752
836
  require(id) {
753
837
  let entry = this.entries.get(id) ?? this.resolveInsideParagraph(id);
754
838
  if (!entry) throw new RegistryError(`journal names unknown node ${id}`);
755
- if ("live" in entry && entry.live instanceof Y3__namespace.Map && isRichParagraph(entry.live)) {
839
+ if ("live" in entry && entry.live instanceof Y__namespace.Map && isCompact(entry.live)) {
756
840
  this.openParagraph(entry.live);
757
841
  entry = this.entries.get(id);
758
842
  }
@@ -770,7 +854,7 @@ var NodeRegistry = class {
770
854
  for (let length = path.length - 1; length >= 1; length--) {
771
855
  const ancestor = this.entries.get(id.slice(0, hash + 1) + path.slice(0, length).join("."));
772
856
  if (!ancestor) continue;
773
- if ("live" in ancestor && ancestor.live instanceof Y3__namespace.Map && isRichParagraph(ancestor.live)) {
857
+ if ("live" in ancestor && ancestor.live instanceof Y__namespace.Map && isCompact(ancestor.live)) {
774
858
  this.openParagraph(ancestor.live);
775
859
  return this.entries.get(id);
776
860
  }
@@ -802,13 +886,13 @@ var NodeRegistry = class {
802
886
  /**
803
887
  * Walk a mirror root and register every node under its positional id, `${part}#0` for the root and
804
888
  * `${parent}.${index}` below it. This is the id scheme core assigns when it reads a part. A rich
805
- * paragraph is registered as one node; its inner nodes appear when it is opened.
889
+ * paragraph or a packed element is registered as one node; its inner nodes appear when it is opened.
806
890
  */
807
891
  registerTree(partName, root) {
808
892
  const walk = (node, id) => {
809
893
  this.registerLive(id, node);
810
- if (node instanceof Y3__namespace.Text) return;
811
- if (isRichParagraph(node)) return;
894
+ if (node instanceof Y__namespace.Text) return;
895
+ if (isCompact(node)) return;
812
896
  childrenOf(node).forEach((child, index) => walk(child, `${id}.${index}`));
813
897
  };
814
898
  walk(root, `${partName}#0`);
@@ -865,7 +949,7 @@ var NodeRegistry = class {
865
949
  for (const child of children) this.own(child, owner);
866
950
  if (owner) this.dirty.add(owner);
867
951
  }
868
- /** Write every changed open paragraph back into the mirror. Call at the end of a journal. */
952
+ /** Write every changed open paragraph or packed element back into the mirror. Call at the end of a journal. */
869
953
  flushRich() {
870
954
  for (const live of [...this.dirty]) {
871
955
  this.dirty.delete(live);
@@ -876,6 +960,11 @@ var NodeRegistry = class {
876
960
  writeBack(record) {
877
961
  const { live, root } = record;
878
962
  const xml = plainToXml(root);
963
+ if (isPackedElement(live)) {
964
+ if (packable(xml)) repack(live, xml);
965
+ else this.degrade(record);
966
+ return;
967
+ }
879
968
  const encoded = encodeParagraph(xml.children);
880
969
  if (!encoded) {
881
970
  this.degrade(record);
@@ -892,21 +981,22 @@ var NodeRegistry = class {
892
981
  bindings.push(xml.bindings.map((b) => ({ ...b })));
893
982
  }
894
983
  const head = childrenOf(live);
895
- const stored = head.toArray().map((child) => liveToXml(child));
896
- if (JSON.stringify(stored) !== JSON.stringify(encoded.head)) {
984
+ const scope = scopeWithin(live);
985
+ const stored = head.toArray().map((child) => serializeLive(child, scope)).join("");
986
+ if (stored !== encoded.head.map((el) => serializeXml(el, scope)).join("")) {
897
987
  head.delete(0, head.length);
898
- head.push(encoded.head.map((el) => xmlToLive(el)));
988
+ head.push(encoded.head.map((el) => xmlToLive(el, scope)));
899
989
  }
900
990
  const inline = live.get("inline");
901
991
  applyUnits(inline, readUnits(inline), encoded.units);
902
992
  }
903
- /** The paragraph can no longer be held as rich text: store it as plain elements instead. */
993
+ /** The paragraph can no longer be held as rich text, or the element packed: store it as a tree. */
904
994
  degrade(record) {
905
995
  const parent = record.live.parent;
906
- if (!(parent instanceof Y3__namespace.Array))
996
+ if (!(parent instanceof Y__namespace.Array))
907
997
  throw new RegistryError("a paragraph outside a parent cannot change form");
908
998
  const index = parent.toArray().indexOf(record.live);
909
- const generic = this.toGenericLive(record.root);
999
+ const generic = this.toGenericLive(record.root, scopeOf(record.live));
910
1000
  this.open.delete(record.live);
911
1001
  parent.delete(index, 1);
912
1002
  parent.insert(index, [generic]);
@@ -921,8 +1011,8 @@ var NodeRegistry = class {
921
1011
  snapshotLive(node) {
922
1012
  const id = this.liveIds.get(node);
923
1013
  if (id === void 0) throw new RegistryError("live node has no registered id");
924
- if (node instanceof Y3__namespace.Text) return { type: "text", id, value: node.toString() };
925
- if (isRichParagraph(node)) {
1014
+ if (node instanceof Y__namespace.Text) return { type: "text", id, value: node.toString() };
1015
+ if (isCompact(node)) {
926
1016
  return this.open.get(node)?.root ?? xmlToPlain(liveToXml(node), id);
927
1017
  }
928
1018
  const prefix = node.get("prefix");
@@ -950,8 +1040,8 @@ var NodeRegistry = class {
950
1040
  if (id !== void 0 && this.isCurrentLive(id, node)) {
951
1041
  this.entries.set(id, { plain });
952
1042
  }
953
- if (node instanceof Y3__namespace.Text || plain.type === "text") return;
954
- if (isRichParagraph(node)) {
1043
+ if (node instanceof Y__namespace.Text || plain.type === "text") return;
1044
+ if (isCompact(node)) {
955
1045
  this.open.delete(node);
956
1046
  this.dirty.delete(node);
957
1047
  return;
@@ -959,53 +1049,61 @@ var NodeRegistry = class {
959
1049
  const liveChildren = childrenOf(node).toArray();
960
1050
  liveChildren.forEach((child, index) => this.detachInto(child, plain.children[index]));
961
1051
  }
962
- /** Build Yjs types for a plain subtree and register every node as live. */
963
- toLive(plain) {
1052
+ /**
1053
+ * Build Yjs types for a plain subtree placed where `scope` is in force, and register every node as
1054
+ * live. A rich paragraph or packed element stays open on the plain tree, which is already current.
1055
+ * A part's `root` is never packed.
1056
+ */
1057
+ toLive(plain, scope = /* @__PURE__ */ new Map(), root = false) {
964
1058
  if (plain.type === "text") {
965
- const text = new Y3__namespace.Text();
1059
+ const text = new Y__namespace.Text();
966
1060
  text.insert(0, plain.value);
967
1061
  this.registerLive(plain.id, text);
968
1062
  return text;
969
1063
  }
1064
+ const xml = plainToXml(plain);
1065
+ let map;
970
1066
  if (isParagraphEl(plain)) {
971
- const xml = plainToXml(plain);
972
1067
  const encoded = encodeParagraph(xml.children);
973
- if (encoded) {
974
- const map = createRichParagraph(xml, encoded);
975
- this.liveIds.set(map, plain.id);
976
- this.registerPlain(plain);
977
- this.own(plain, map);
978
- this.open.set(map, { live: map, root: plain, id: plain.id });
979
- return map;
980
- }
1068
+ if (encoded) map = createRichParagraph(xml, encoded, scope);
1069
+ }
1070
+ if (!map && !root && packable(xml)) map = xmlToLive(xml, scope);
1071
+ if (map) {
1072
+ this.liveIds.set(map, plain.id);
1073
+ this.registerPlain(plain);
1074
+ this.own(plain, map);
1075
+ this.open.set(map, { live: map, root: plain, id: plain.id });
1076
+ return map;
981
1077
  }
982
- return this.toGenericLive(plain);
1078
+ return this.toGenericLive(plain, scope);
983
1079
  }
984
- toGenericLive(plain) {
1080
+ toGenericLive(plain, scope) {
985
1081
  const map = xmlToGenericShell(plain);
986
- const children = new Y3__namespace.Array();
987
- children.push(plain.children.map((child) => this.toLive(child)));
1082
+ const inner = withBindings(scope, plain.bindings);
1083
+ const children = new Y__namespace.Array();
1084
+ children.push(plain.children.map((child) => this.toLive(child, inner)));
988
1085
  map.set("children", children);
989
1086
  this.registerLive(plain.id, map);
990
1087
  return map;
991
1088
  }
992
1089
  /**
993
- * A live node that can be inserted into a parent. Anything not yet attached is built fresh; an
994
- * attached node is copied, because a Yjs type cannot have two parents.
1090
+ * A live node that can be inserted into a parent (`scope` is in force there), or a part's `root`.
1091
+ * Anything not yet attached is built fresh; an attached node is copied, because a Yjs type cannot
1092
+ * have two parents.
995
1093
  */
996
- attachable(id) {
997
- return this.toLive(this.snapshot(id));
1094
+ attachable(id, scope = /* @__PURE__ */ new Map(), root = false) {
1095
+ return this.toLive(this.snapshot(id), scope, root);
998
1096
  }
999
1097
  };
1000
1098
  function xmlToGenericShell(plain) {
1001
- const map = new Y3__namespace.Map();
1099
+ const map = new Y__namespace.Map();
1002
1100
  map.set("ns", plain.ns);
1003
1101
  map.set("local", plain.local);
1004
1102
  if (plain.prefix !== void 0) map.set("prefix", plain.prefix);
1005
- const attrs = new Y3__namespace.Array();
1103
+ const attrs = new Y__namespace.Array();
1006
1104
  attrs.push(plain.attrs.map((a) => ({ ...a })));
1007
1105
  map.set("attrs", attrs);
1008
- const bindings = new Y3__namespace.Array();
1106
+ const bindings = new Y__namespace.Array();
1009
1107
  bindings.push(plain.bindings.map((b) => ({ ...b })));
1010
1108
  map.set("bindings", bindings);
1011
1109
  return map;
@@ -1070,7 +1168,7 @@ function setNamespaceBinding(registry, id, prefix, uri) {
1070
1168
  }
1071
1169
  }
1072
1170
  function asLiveElement(node, id) {
1073
- if (node instanceof Y3__namespace.Text) throw new JournalError(`${id} is a text node, not an element`);
1171
+ if (node instanceof Y__namespace.Text) throw new JournalError(`${id} is a text node, not an element`);
1074
1172
  return node;
1075
1173
  }
1076
1174
  function asPlainElement(node, id) {
@@ -1086,7 +1184,7 @@ function spliceText(registry, id, start, deleteCount, insert) {
1086
1184
  return;
1087
1185
  }
1088
1186
  const text = entry.live;
1089
- if (!(text instanceof Y3__namespace.Text)) throw new JournalError(`${id} is not a text node`);
1187
+ if (!(text instanceof Y__namespace.Text)) throw new JournalError(`${id} is not a text node`);
1090
1188
  if (start < 0 || start + deleteCount > text.length) {
1091
1189
  throw new JournalError(`text splice out of range on ${id}`);
1092
1190
  }
@@ -1099,27 +1197,29 @@ function detachRemoved(registry, parent, start, count) {
1099
1197
  function spliceChildren(registry, parentId, start, deleteCount, childIds) {
1100
1198
  const parentEntry = registry.require(parentId);
1101
1199
  if ("plain" in parentEntry) {
1102
- const parent = asPlainElement(parentEntry.plain, parentId);
1103
- if (start < 0 || start + deleteCount > parent.children.length) {
1200
+ const parent2 = asPlainElement(parentEntry.plain, parentId);
1201
+ if (start < 0 || start + deleteCount > parent2.children.length) {
1104
1202
  throw new JournalError(`child splice out of range on ${parentId}`);
1105
1203
  }
1106
1204
  const inserted2 = childIds.map((id) => registry.snapshot(id));
1107
- parent.children.splice(start, deleteCount, ...inserted2);
1108
- registry.adopt(parent, inserted2);
1205
+ parent2.children.splice(start, deleteCount, ...inserted2);
1206
+ registry.adopt(parent2, inserted2);
1109
1207
  return;
1110
1208
  }
1111
- const children = childrenOf(asLiveElement(parentEntry.live, parentId));
1209
+ const parent = asLiveElement(parentEntry.live, parentId);
1210
+ const children = childrenOf(parent);
1112
1211
  if (start < 0 || start + deleteCount > children.length) {
1113
1212
  throw new JournalError(`child splice out of range on ${parentId}`);
1114
1213
  }
1115
1214
  detachRemoved(registry, children, start, deleteCount);
1116
- const inserted = childIds.map((id) => registry.attachable(id));
1215
+ const scope = scopeWithin(parent);
1216
+ const inserted = childIds.map((id) => registry.attachable(id, scope));
1117
1217
  if (deleteCount > 0) children.delete(start, deleteCount);
1118
1218
  if (inserted.length > 0) children.insert(start, inserted);
1119
1219
  }
1120
1220
  function locate(registry, id, node) {
1121
1221
  const children = node.parent;
1122
- if (!(children instanceof Y3__namespace.Array)) throw new JournalError(`${id} is not attached`);
1222
+ if (!(children instanceof Y__namespace.Array)) throw new JournalError(`${id} is not attached`);
1123
1223
  const index = children.toArray().indexOf(node);
1124
1224
  if (index < 0) throw new JournalError(`${id} is not in its parent`);
1125
1225
  return { children, index };
@@ -1146,8 +1246,10 @@ function moveNode(registry, id, destinationId, destinationIndex) {
1146
1246
  registry.adopt(destination2, [copy]);
1147
1247
  return;
1148
1248
  }
1149
- const destination = childrenOf(asLiveElement(destinationEntry.live, destinationId));
1150
- destination.insert(destinationIndex, [registry.toLive(copy)]);
1249
+ const destination = asLiveElement(destinationEntry.live, destinationId);
1250
+ childrenOf(destination).insert(destinationIndex, [
1251
+ registry.toLive(copy, scopeWithin(destination))
1252
+ ]);
1151
1253
  }
1152
1254
  function renameNode(registry, id, qname) {
1153
1255
  const entry = registry.require(id);
@@ -1162,7 +1264,7 @@ function renameNode(registry, id, qname) {
1162
1264
  return true;
1163
1265
  }
1164
1266
  const live = entry.live;
1165
- if (live instanceof Y3__namespace.Text || isRichParagraph(live)) return false;
1267
+ if (live instanceof Y__namespace.Text || isCompact(live)) return false;
1166
1268
  if (live.get("ns") !== qname.namespaceUri) live.set("ns", qname.namespaceUri);
1167
1269
  if (live.get("local") !== qname.localName) live.set("local", qname.localName);
1168
1270
  if (qname.prefix === void 0) {
@@ -1192,7 +1294,7 @@ function putNode(registry, effect) {
1192
1294
  }
1193
1295
  function rootFor(registry, id) {
1194
1296
  const entry = registry.require(id);
1195
- const live = "live" in entry && entry.live.parent === null ? entry.live : registry.attachable(id);
1297
+ const live = "live" in entry && entry.live.parent === null ? entry.live : registry.attachable(id, /* @__PURE__ */ new Map(), true);
1196
1298
  return asLiveElement(live, id);
1197
1299
  }
1198
1300
  function applyEffect(doc, registry, effect, context) {
@@ -1236,7 +1338,7 @@ function applyEffect(doc, registry, effect, context) {
1236
1338
  const rels = doc.getMap("rels");
1237
1339
  let byId = rels.get(effect.owner);
1238
1340
  if (!byId) {
1239
- byId = new Y3__namespace.Map();
1341
+ byId = new Y__namespace.Map();
1240
1342
  rels.set(effect.owner, byId);
1241
1343
  }
1242
1344
  byId.set(effect.record.id, { ...effect.record });
@@ -1441,7 +1543,7 @@ var DocxCollaborationSession = class {
1441
1543
  this.doc = options.doc;
1442
1544
  this.awareness = options.awareness;
1443
1545
  this.offlineEditing = options.offlineEditing ?? false;
1444
- this.undoManager = new Y3__namespace.UndoManager(
1546
+ this.undoManager = new Y__namespace.UndoManager(
1445
1547
  [
1446
1548
  this.doc.getMap("parts"),
1447
1549
  this.doc.getMap("rels"),
@@ -1481,7 +1583,7 @@ var DocxCollaborationSession = class {
1481
1583
  this.setStatus("error", "not-initialized");
1482
1584
  return;
1483
1585
  }
1484
- if (readFormat(this.doc) !== COLLAB_FORMAT) {
1586
+ if (!isReadableFormat(readFormat(this.doc))) {
1485
1587
  this.setStatus("error", "collaboration-format-mismatch", readFormat(this.doc));
1486
1588
  return;
1487
1589
  }
@@ -1755,7 +1857,7 @@ function resolveAddress(port, address) {
1755
1857
  };
1756
1858
  }
1757
1859
  function vectorKey(doc) {
1758
- return Array.from(Y3__namespace.encodeStateVector(doc)).join(",");
1860
+ return Array.from(Y__namespace.encodeStateVector(doc)).join(",");
1759
1861
  }
1760
1862
  function randomToken() {
1761
1863
  if (typeof crypto.randomUUID === "function") return crypto.randomUUID();