@tiptap/y-tiptap 1.0.0 → 2.0.0-beta.1

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/y-tiptap.cjs CHANGED
@@ -3,21 +3,24 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var Y = require('yjs');
6
- var view = require('@tiptap/pm/view');
7
- var state = require('@tiptap/pm/state');
6
+ var prosemirrorView = require('prosemirror-view');
7
+ var prosemirrorState = require('prosemirror-state');
8
8
  require('y-protocols/awareness');
9
9
  var mutex = require('lib0/mutex');
10
- var PModel = require('@tiptap/pm/model');
10
+ var PModel = require('prosemirror-model');
11
11
  var math = require('lib0/math');
12
+ var object = require('lib0/object');
12
13
  var set = require('lib0/set');
13
14
  var diff = require('lib0/diff');
14
15
  var error = require('lib0/error');
16
+ var state = require('@tiptap/pm/state');
15
17
  var random = require('lib0/random');
16
18
  var environment = require('lib0/environment');
17
19
  var dom = require('lib0/dom');
18
20
  var eventloop = require('lib0/eventloop');
19
- var f = require('lib0/function');
20
21
  var map = require('lib0/map');
22
+ var sha256 = require('lib0/hash/sha256');
23
+ var buf = require('lib0/buffer');
21
24
 
22
25
  function _interopNamespace(e) {
23
26
  if (e && e.__esModule) return e;
@@ -40,14 +43,16 @@ function _interopNamespace(e) {
40
43
  var Y__namespace = /*#__PURE__*/_interopNamespace(Y);
41
44
  var PModel__namespace = /*#__PURE__*/_interopNamespace(PModel);
42
45
  var math__namespace = /*#__PURE__*/_interopNamespace(math);
46
+ var object__namespace = /*#__PURE__*/_interopNamespace(object);
43
47
  var set__namespace = /*#__PURE__*/_interopNamespace(set);
44
48
  var error__namespace = /*#__PURE__*/_interopNamespace(error);
45
49
  var random__namespace = /*#__PURE__*/_interopNamespace(random);
46
50
  var environment__namespace = /*#__PURE__*/_interopNamespace(environment);
47
51
  var dom__namespace = /*#__PURE__*/_interopNamespace(dom);
48
52
  var eventloop__namespace = /*#__PURE__*/_interopNamespace(eventloop);
49
- var f__namespace = /*#__PURE__*/_interopNamespace(f);
50
53
  var map__namespace = /*#__PURE__*/_interopNamespace(map);
54
+ var sha256__namespace = /*#__PURE__*/_interopNamespace(sha256);
55
+ var buf__namespace = /*#__PURE__*/_interopNamespace(buf);
51
56
 
52
57
  /**
53
58
  * The unique prosemirror plugin key for syncPlugin
@@ -70,11 +75,41 @@ const yUndoPluginKey = new state.PluginKey('y-undo');
70
75
  */
71
76
  const yCursorPluginKey = new state.PluginKey('yjs-cursor');
72
77
 
78
+ /**
79
+ * Custom function to transform sha256 hash to N byte
80
+ *
81
+ * @param {Uint8Array} digest
82
+ */
83
+ const _convolute = digest => {
84
+ const N = 6;
85
+ for (let i = N; i < digest.length; i++) {
86
+ digest[i % N] = digest[i % N] ^ digest[i];
87
+ }
88
+ return digest.slice(0, N)
89
+ };
90
+
91
+ /**
92
+ * @param {any} json
93
+ */
94
+ const hashOfJSON = (json) => buf__namespace.toBase64(_convolute(sha256__namespace.digest(buf__namespace.encodeAny(json))));
95
+
73
96
  /**
74
97
  * @module bindings/prosemirror
75
98
  */
76
99
 
77
- const MarkPrefix = '_mark_';
100
+ /**
101
+ * @typedef {Object} BindingMetadata
102
+ * @property {ProsemirrorMapping} BindingMetadata.mapping
103
+ * @property {Map<import('prosemirror-model').MarkType, boolean>} BindingMetadata.isOMark - is overlapping mark
104
+ */
105
+
106
+ /**
107
+ * @return BindingMetadata
108
+ */
109
+ const createEmptyMeta = () => ({
110
+ mapping: new Map(),
111
+ isOMark: new Map()
112
+ });
78
113
 
79
114
  /**
80
115
  * @param {Y.Item} item
@@ -148,7 +183,7 @@ const ySyncPlugin = (yXmlFragment, {
148
183
  } = {}) => {
149
184
  let initialContentChanged = false;
150
185
  const binding = new ProsemirrorBinding(yXmlFragment, mapping);
151
- const plugin = new state.Plugin({
186
+ const plugin = new prosemirrorState.Plugin({
152
187
  props: {
153
188
  editable: (state) => {
154
189
  const syncState = ySyncPluginKey.getState(state);
@@ -281,31 +316,48 @@ const ySyncPlugin = (yXmlFragment, {
281
316
  };
282
317
 
283
318
  /**
284
- * @param {any} tr
285
- * @param {any} relSel
319
+ * @param {import('prosemirror-state').Transaction} tr
320
+ * @param {ReturnType<typeof getRelativeSelection>} relSel
286
321
  * @param {ProsemirrorBinding} binding
287
322
  */
288
323
  const restoreRelativeSelection = (tr, relSel, binding) => {
289
324
  if (relSel !== null && relSel.anchor !== null && relSel.head !== null) {
290
- const anchor = relativePositionToAbsolutePosition(
291
- binding.doc,
292
- binding.type,
293
- relSel.anchor,
294
- binding.mapping
295
- );
296
- const head = relativePositionToAbsolutePosition(
297
- binding.doc,
298
- binding.type,
299
- relSel.head,
300
- binding.mapping
301
- );
302
- if (anchor !== null && head !== null) {
303
- tr = tr.setSelection(state.TextSelection.create(tr.doc, anchor, head));
325
+ if (relSel.type === 'all') {
326
+ tr.setSelection(new prosemirrorState.AllSelection(tr.doc));
327
+ } else if (relSel.type === 'node') {
328
+ const anchor = relativePositionToAbsolutePosition(
329
+ binding.doc,
330
+ binding.type,
331
+ relSel.anchor,
332
+ binding.mapping
333
+ );
334
+ tr.setSelection(prosemirrorState.NodeSelection.create(tr.doc, anchor));
335
+ } else {
336
+ const anchor = relativePositionToAbsolutePosition(
337
+ binding.doc,
338
+ binding.type,
339
+ relSel.anchor,
340
+ binding.mapping
341
+ );
342
+ const head = relativePositionToAbsolutePosition(
343
+ binding.doc,
344
+ binding.type,
345
+ relSel.head,
346
+ binding.mapping
347
+ );
348
+ if (anchor !== null && head !== null) {
349
+ tr.setSelection(prosemirrorState.TextSelection.between(tr.doc.resolve(anchor), tr.doc.resolve(head)));
350
+ }
304
351
  }
305
352
  }
306
353
  };
307
354
 
355
+ /**
356
+ * @param {ProsemirrorBinding} pmbinding
357
+ * @param {import('prosemirror-state').EditorState} state
358
+ */
308
359
  const getRelativeSelection = (pmbinding, state) => ({
360
+ type: /** @type {any} */ (state.selection).jsonID,
309
361
  anchor: absolutePositionToRelativePosition(
310
362
  state.selection.anchor,
311
363
  pmbinding.type,
@@ -337,6 +389,12 @@ class ProsemirrorBinding {
337
389
  this.prosemirrorView = null;
338
390
  this.mux = mutex.createMutex();
339
391
  this.mapping = mapping;
392
+ /**
393
+ * Is overlapping mark - i.e. mark does not exclude itself.
394
+ *
395
+ * @type {Map<import('prosemirror-model').MarkType, boolean>}
396
+ */
397
+ this.isOMark = new Map();
340
398
  this._observeFunction = this._typeChanged.bind(this);
341
399
  /**
342
400
  * @type {Y.Doc}
@@ -431,7 +489,7 @@ class ProsemirrorBinding {
431
489
  createNodeFromYElement(
432
490
  /** @type {Y.XmlElement} */ (t),
433
491
  this.prosemirrorView.state.schema,
434
- this.mapping
492
+ this
435
493
  )
436
494
  ).filter((n) => n !== null);
437
495
  // @ts-ignore
@@ -456,7 +514,7 @@ class ProsemirrorBinding {
456
514
  createNodeFromYElement(
457
515
  /** @type {Y.XmlElement} */ (t),
458
516
  this.prosemirrorView.state.schema,
459
- this.mapping
517
+ this
460
518
  )
461
519
  ).filter((n) => n !== null);
462
520
  // @ts-ignore
@@ -474,7 +532,7 @@ class ProsemirrorBinding {
474
532
  const clampedAnchor = math__namespace.min(math__namespace.max(sel.anchor, 0), tr.doc.content.size);
475
533
  const clampedHead = math__namespace.min(math__namespace.max(sel.head, 0), tr.doc.content.size);
476
534
 
477
- tr.setSelection(state.TextSelection.create(tr.doc, clampedAnchor, clampedHead));
535
+ tr.setSelection(prosemirrorState.TextSelection.create(tr.doc, clampedAnchor, clampedHead));
478
536
  }
479
537
  this.prosemirrorView.dispatch(
480
538
  tr.setMeta(ySyncPluginKey, { isChangeOrigin: true, binding: this })
@@ -493,6 +551,7 @@ class ProsemirrorBinding {
493
551
  * @type {Y.Doc}
494
552
  */
495
553
  let historyDoc = this.doc;
554
+ let historyType = this.type;
496
555
  if (!snapshot) {
497
556
  snapshot = Y__namespace.snapshot(this.doc);
498
557
  }
@@ -506,6 +565,29 @@ class ProsemirrorBinding {
506
565
  prevSnapshot = Y__namespace.snapshot(historyDoc);
507
566
  Y__namespace.applyUpdateV2(historyDoc, snapshot);
508
567
  snapshot = Y__namespace.snapshot(historyDoc);
568
+ if (historyType._item === null) {
569
+ /**
570
+ * If is a root type, we need to find the root key in the initial document
571
+ * and use it to get the history type.
572
+ */
573
+ const rootKey = Array.from(this.doc.share.keys()).find(
574
+ (key) => this.doc.share.get(key) === this.type
575
+ );
576
+ historyType = historyDoc.getXmlFragment(rootKey);
577
+ } else {
578
+ /**
579
+ * If it is a sub type, we use the item id to find the history type.
580
+ */
581
+ const historyStructs =
582
+ historyDoc.store.clients.get(historyType._item.id.client) ?? [];
583
+ const itemIndex = Y__namespace.findIndexSS(
584
+ historyStructs,
585
+ historyType._item.id.clock
586
+ );
587
+ const item = /** @type {Y.Item} */ (historyStructs[itemIndex]);
588
+ const content = /** @type {Y.ContentType} */ (item.content);
589
+ historyType = /** @type {Y.XmlFragment} */ (content.type);
590
+ }
509
591
  }
510
592
  // clear mapping because we are going to rerender
511
593
  this.mapping.clear();
@@ -513,6 +595,9 @@ class ProsemirrorBinding {
513
595
  historyDoc.transact((transaction) => {
514
596
  // before rendering, we are going to sanitize ops and split deleted ops
515
597
  // if they were deleted by seperate users.
598
+ /**
599
+ * @type {Y.PermanentUserData}
600
+ */
516
601
  const pud = pluginState.permanentUserData;
517
602
  if (pud) {
518
603
  pud.dss.forEach((ds) => {
@@ -539,7 +624,7 @@ class ProsemirrorBinding {
539
624
  };
540
625
  // Create document fragment and render
541
626
  const fragmentContent = Y__namespace.typeListToArraySnapshot(
542
- this.type,
627
+ historyType,
543
628
  new Y__namespace.Snapshot(prevSnapshot.ds, snapshot.sv)
544
629
  ).map((t) => {
545
630
  if (
@@ -549,7 +634,7 @@ class ProsemirrorBinding {
549
634
  return createNodeFromYElement(
550
635
  t,
551
636
  this.prosemirrorView.state.schema,
552
- new Map(),
637
+ { mapping: new Map(), isOMark: new Map() },
553
638
  snapshot,
554
639
  prevSnapshot,
555
640
  computeYChange
@@ -610,7 +695,7 @@ class ProsemirrorBinding {
610
695
  createNodeIfNotExists(
611
696
  /** @type {Y.XmlElement | Y.XmlHook} */ (t),
612
697
  this.prosemirrorView.state.schema,
613
- this.mapping
698
+ this
614
699
  )
615
700
  ).filter((n) => n !== null);
616
701
  // @ts-ignore
@@ -630,9 +715,12 @@ class ProsemirrorBinding {
630
715
  });
631
716
  }
632
717
 
718
+ /**
719
+ * @param {import('prosemirror-model').Node} doc
720
+ */
633
721
  _prosemirrorChanged (doc) {
634
722
  this.doc.transact(() => {
635
- updateYFragment(this.doc, this.type, doc, this.mapping);
723
+ updateYFragment(this.doc, this.type, doc, this);
636
724
  this.beforeTransactionSelection = getRelativeSelection(
637
725
  this,
638
726
  this.prosemirrorView.state
@@ -665,7 +753,7 @@ class ProsemirrorBinding {
665
753
  * @private
666
754
  * @param {Y.XmlElement | Y.XmlHook} el
667
755
  * @param {PModel.Schema} schema
668
- * @param {ProsemirrorMapping} mapping
756
+ * @param {BindingMetadata} meta
669
757
  * @param {Y.Snapshot} [snapshot]
670
758
  * @param {Y.Snapshot} [prevSnapshot]
671
759
  * @param {function('removed' | 'added', Y.ID):any} [computeYChange]
@@ -674,18 +762,18 @@ class ProsemirrorBinding {
674
762
  const createNodeIfNotExists = (
675
763
  el,
676
764
  schema,
677
- mapping,
765
+ meta,
678
766
  snapshot,
679
767
  prevSnapshot,
680
768
  computeYChange
681
769
  ) => {
682
- const node = /** @type {PModel.Node} */ (mapping.get(el));
770
+ const node = /** @type {PModel.Node} */ (meta.mapping.get(el));
683
771
  if (node === undefined) {
684
772
  if (el instanceof Y__namespace.XmlElement) {
685
773
  return createNodeFromYElement(
686
774
  el,
687
775
  schema,
688
- mapping,
776
+ meta,
689
777
  snapshot,
690
778
  prevSnapshot,
691
779
  computeYChange
@@ -701,7 +789,7 @@ const createNodeIfNotExists = (
701
789
  * @private
702
790
  * @param {Y.XmlElement} el
703
791
  * @param {any} schema
704
- * @param {ProsemirrorMapping} mapping
792
+ * @param {BindingMetadata} meta
705
793
  * @param {Y.Snapshot} [snapshot]
706
794
  * @param {Y.Snapshot} [prevSnapshot]
707
795
  * @param {function('removed' | 'added', Y.ID):any} [computeYChange]
@@ -710,18 +798,21 @@ const createNodeIfNotExists = (
710
798
  const createNodeFromYElement = (
711
799
  el,
712
800
  schema,
713
- mapping,
801
+ meta,
714
802
  snapshot,
715
803
  prevSnapshot,
716
804
  computeYChange
717
805
  ) => {
718
806
  const children = [];
807
+ /**
808
+ * @param {Y.XmlElement | Y.XmlText} type
809
+ */
719
810
  const createChildren = (type) => {
720
- if (type.constructor === Y__namespace.XmlElement) {
811
+ if (type instanceof Y__namespace.XmlElement) {
721
812
  const n = createNodeIfNotExists(
722
813
  type,
723
814
  schema,
724
- mapping,
815
+ meta,
725
816
  snapshot,
726
817
  prevSnapshot,
727
818
  computeYChange
@@ -733,7 +824,7 @@ const createNodeFromYElement = (
733
824
  // If the next ytext exists and was created by us, move the content to the current ytext.
734
825
  // This is a fix for #160 -- duplication of characters when two Y.Text exist next to each
735
826
  // other.
736
- const nextytext = type._item.right?.content.type;
827
+ const nextytext = /** @type {Y.ContentType} */ (type._item.right?.content)?.type;
737
828
  if (nextytext instanceof Y__namespace.Text && !nextytext._item.deleted && nextytext._item.id.client === nextytext.doc.clientID) {
738
829
  type.applyDelta([
739
830
  { retain: type.length },
@@ -747,7 +838,7 @@ const createNodeFromYElement = (
747
838
  const ns = createTextNodesFromYText(
748
839
  type,
749
840
  schema,
750
- mapping,
841
+ meta,
751
842
  snapshot,
752
843
  prevSnapshot,
753
844
  computeYChange
@@ -780,32 +871,15 @@ const createNodeFromYElement = (
780
871
  : { type: 'added' };
781
872
  }
782
873
  }
783
- const nodeAttrs = {};
784
- const nodeMarks = [];
785
-
786
- for (const key in attrs) {
787
- if (key.startsWith(MarkPrefix)) {
788
- const markName = key.replace(MarkPrefix, '');
789
- const markValue = attrs[key];
790
- if (isObject(markValue)) {
791
- nodeMarks.push(schema.mark(markName, /** @type {Object} */ (markValue).attrs));
792
- } else if (Array.isArray(markValue)) {
793
- nodeMarks.push(...markValue.map(attrs => schema.mark(markName, attrs)));
794
- }
795
- } else {
796
- nodeAttrs[key] = attrs[key];
797
- }
798
- }
799
-
800
- const node = schema.node(el.nodeName, nodeAttrs, children, nodeMarks);
801
- mapping.set(el, node);
874
+ const node = schema.node(el.nodeName, attrs, children);
875
+ meta.mapping.set(el, node);
802
876
  return node
803
877
  } catch (e) {
804
878
  // an error occured while creating the node. This is probably a result of a concurrent action.
805
879
  /** @type {Y.Doc} */ (el.doc).transact((transaction) => {
806
880
  /** @type {Y.Item} */ (el._item).delete(transaction);
807
881
  }, ySyncPluginKey);
808
- mapping.delete(el);
882
+ meta.mapping.delete(el);
809
883
  return null
810
884
  }
811
885
  };
@@ -813,8 +887,8 @@ const createNodeFromYElement = (
813
887
  /**
814
888
  * @private
815
889
  * @param {Y.XmlText} text
816
- * @param {any} schema
817
- * @param {ProsemirrorMapping} _mapping
890
+ * @param {import('prosemirror-model').Schema} schema
891
+ * @param {BindingMetadata} _meta
818
892
  * @param {Y.Snapshot} [snapshot]
819
893
  * @param {Y.Snapshot} [prevSnapshot]
820
894
  * @param {function('removed' | 'added', Y.ID):any} [computeYChange]
@@ -823,7 +897,7 @@ const createNodeFromYElement = (
823
897
  const createTextNodesFromYText = (
824
898
  text,
825
899
  schema,
826
- _mapping,
900
+ _meta,
827
901
  snapshot,
828
902
  prevSnapshot,
829
903
  computeYChange
@@ -833,19 +907,7 @@ const createTextNodesFromYText = (
833
907
  try {
834
908
  for (let i = 0; i < deltas.length; i++) {
835
909
  const delta = deltas[i];
836
- const marks = [];
837
- for (const markName in delta.attributes) {
838
- if (Array.isArray(delta.attributes[markName])) {
839
- // multiple marks of same type
840
- delta.attributes[markName].forEach(attrs => {
841
- marks.push(schema.mark(markName, attrs));
842
- });
843
- } else {
844
- // single mark
845
- marks.push(schema.mark(markName, delta.attributes[markName]));
846
- }
847
- }
848
- nodes.push(schema.text(delta.insert, marks));
910
+ nodes.push(schema.text(delta.insert, attributesToMarks(delta.attributes, schema)));
849
911
  }
850
912
  } catch (e) {
851
913
  // an error occured while creating the node. This is probably a result of a concurrent action.
@@ -861,67 +923,70 @@ const createTextNodesFromYText = (
861
923
  /**
862
924
  * @private
863
925
  * @param {Array<any>} nodes prosemirror node
864
- * @param {ProsemirrorMapping} mapping
926
+ * @param {BindingMetadata} meta
865
927
  * @return {Y.XmlText}
866
928
  */
867
- const createTypeFromTextNodes = (nodes, mapping) => {
929
+ const createTypeFromTextNodes = (nodes, meta) => {
868
930
  const type = new Y__namespace.XmlText();
869
931
  const delta = nodes.map((node) => ({
870
932
  // @ts-ignore
871
933
  insert: node.text,
872
- attributes: marksToAttributes(node.marks)
934
+ attributes: marksToAttributes(node.marks, meta)
873
935
  }));
874
936
  type.applyDelta(delta);
875
- mapping.set(type, nodes);
937
+ meta.mapping.set(type, nodes);
876
938
  return type
877
939
  };
878
940
 
879
941
  /**
880
942
  * @private
881
943
  * @param {any} node prosemirror node
882
- * @param {ProsemirrorMapping} mapping
944
+ * @param {BindingMetadata} meta
883
945
  * @return {Y.XmlElement}
884
946
  */
885
- const createTypeFromElementNode = (node, mapping) => {
947
+ const createTypeFromElementNode = (node, meta) => {
886
948
  const type = new Y__namespace.XmlElement(node.type.name);
887
- const nodeMarksAttr = nodeMarksToAttributes(node.marks);
888
949
  for (const key in node.attrs) {
889
950
  const val = node.attrs[key];
890
951
  if (val !== null && key !== 'ychange') {
891
952
  type.setAttribute(key, val);
892
953
  }
893
954
  }
894
- for (const key in nodeMarksAttr) {
895
- type.setAttribute(key, nodeMarksAttr[key]);
896
- }
897
955
  type.insert(
898
956
  0,
899
957
  normalizePNodeContent(node).map((n) =>
900
- createTypeFromTextOrElementNode(n, mapping)
958
+ createTypeFromTextOrElementNode(n, meta)
901
959
  )
902
960
  );
903
- mapping.set(type, node);
961
+ meta.mapping.set(type, node);
904
962
  return type
905
963
  };
906
964
 
907
965
  /**
908
966
  * @private
909
967
  * @param {PModel.Node|Array<PModel.Node>} node prosemirror text node
910
- * @param {ProsemirrorMapping} mapping
968
+ * @param {BindingMetadata} meta
911
969
  * @return {Y.XmlElement|Y.XmlText}
912
970
  */
913
- const createTypeFromTextOrElementNode = (node, mapping) =>
971
+ const createTypeFromTextOrElementNode = (node, meta) =>
914
972
  node instanceof Array
915
- ? createTypeFromTextNodes(node, mapping)
916
- : createTypeFromElementNode(node, mapping);
973
+ ? createTypeFromTextNodes(node, meta)
974
+ : createTypeFromElementNode(node, meta);
917
975
 
976
+ /**
977
+ * @param {any} val
978
+ */
918
979
  const isObject = (val) => typeof val === 'object' && val !== null;
919
980
 
981
+ /**
982
+ * @param {any} pattrs
983
+ * @param {any} yattrs
984
+ */
920
985
  const equalAttrs = (pattrs, yattrs) => {
921
986
  const keys = Object.keys(pattrs).filter((key) => pattrs[key] !== null);
922
987
  let eq =
923
988
  keys.length ===
924
- Object.keys(yattrs).filter((key) => yattrs[key] !== null && !key.startsWith(MarkPrefix)).length;
989
+ Object.keys(yattrs).filter((key) => yattrs[key] !== null).length;
925
990
  for (let i = 0; i < keys.length && eq; i++) {
926
991
  const key = keys[i];
927
992
  const l = pattrs[key];
@@ -932,20 +997,6 @@ const equalAttrs = (pattrs, yattrs) => {
932
997
  return eq
933
998
  };
934
999
 
935
- const equalMarks = (pmarks, yattrs) => {
936
- const keys = Object.keys(yattrs).filter((key) => key.startsWith(MarkPrefix));
937
- let eq =
938
- keys.length === pmarks.length;
939
- const pMarkAttr = nodeMarksToAttributes(pmarks);
940
- for (let i = 0; i < keys.length && eq; i++) {
941
- const key = keys[i];
942
- const l = pMarkAttr[key];
943
- const r = yattrs[key];
944
- eq = key === 'ychange' || f__namespace.equalityDeep(l, r);
945
- }
946
- return eq
947
- };
948
-
949
1000
  /**
950
1001
  * @typedef {Array<Array<PModel.Node>|PModel.Node>} NormalizedPNodeContent
951
1002
  */
@@ -980,17 +1031,14 @@ const normalizePNodeContent = (pnode) => {
980
1031
  const equalYTextPText = (ytext, ptexts) => {
981
1032
  const delta = ytext.toDelta();
982
1033
  return delta.length === ptexts.length &&
983
- delta.every((d, i) =>
1034
+ delta.every(/** @type {(d:any,i:number) => boolean} */ (d, i) =>
984
1035
  d.insert === /** @type {any} */ (ptexts[i]).text &&
985
- Object.keys(d.attributes || {}).reduce((sum, val) => sum + (Array.isArray(val) ? val.length : 1), 0) === ptexts[i].marks.length &&
986
- ptexts[i].marks.every((mark) => {
987
- const yattrs = d.attributes || {};
988
- if (Array.isArray(yattrs)) {
989
- return yattrs.some((yattr) => equalAttrs(mark.attrs, yattr))
990
- }
991
- return equalAttrs(mark.attrs, yattrs)
992
- }
993
- )
1036
+ object__namespace.keys(d.attributes || {}).length === ptexts[i].marks.length &&
1037
+ object__namespace.every(d.attributes, (attr, yattrname) => {
1038
+ const markname = yattr2markname(yattrname);
1039
+ const pmarks = ptexts[i].marks;
1040
+ return equalAttrs(attr, pmarks.find(/** @param {any} mark */ mark => mark.type.name === markname)?.attrs)
1041
+ })
994
1042
  )
995
1043
  };
996
1044
 
@@ -1005,8 +1053,7 @@ const equalYTypePNode = (ytype, pnode) => {
1005
1053
  ) {
1006
1054
  const normalizedContent = normalizePNodeContent(pnode);
1007
1055
  return ytype._length === normalizedContent.length &&
1008
- equalAttrs(pnode.attrs, ytype.getAttributes()) &&
1009
- equalMarks(pnode.marks, ytype.getAttributes()) &&
1056
+ equalAttrs(ytype.getAttributes(), pnode.attrs) &&
1010
1057
  ytype.toArray().every((ychild, i) =>
1011
1058
  equalYTypePNode(ychild, normalizedContent[i])
1012
1059
  )
@@ -1029,10 +1076,10 @@ const mappedIdentity = (mapped, pcontent) =>
1029
1076
  /**
1030
1077
  * @param {Y.XmlElement} ytype
1031
1078
  * @param {PModel.Node} pnode
1032
- * @param {ProsemirrorMapping} mapping
1079
+ * @param {BindingMetadata} meta
1033
1080
  * @return {{ foundMappedChild: boolean, equalityFactor: number }}
1034
1081
  */
1035
- const computeChildEqualityFactor = (ytype, pnode, mapping) => {
1082
+ const computeChildEqualityFactor = (ytype, pnode, meta) => {
1036
1083
  const yChildren = ytype.toArray();
1037
1084
  const pChildren = normalizePNodeContent(pnode);
1038
1085
  const pChildCnt = pChildren.length;
@@ -1044,7 +1091,7 @@ const computeChildEqualityFactor = (ytype, pnode, mapping) => {
1044
1091
  for (; left < minCnt; left++) {
1045
1092
  const leftY = yChildren[left];
1046
1093
  const leftP = pChildren[left];
1047
- if (mappedIdentity(mapping.get(leftY), leftP)) {
1094
+ if (mappedIdentity(meta.mapping.get(leftY), leftP)) {
1048
1095
  foundMappedChild = true; // definite (good) match!
1049
1096
  } else if (!equalYTypePNode(leftY, leftP)) {
1050
1097
  break
@@ -1053,7 +1100,7 @@ const computeChildEqualityFactor = (ytype, pnode, mapping) => {
1053
1100
  for (; left + right < minCnt; right++) {
1054
1101
  const rightY = yChildren[yChildCnt - right - 1];
1055
1102
  const rightP = pChildren[pChildCnt - right - 1];
1056
- if (mappedIdentity(mapping.get(rightY), rightP)) {
1103
+ if (mappedIdentity(meta.mapping.get(rightY), rightP)) {
1057
1104
  foundMappedChild = true;
1058
1105
  } else if (!equalYTypePNode(rightY, rightP)) {
1059
1106
  break
@@ -1065,6 +1112,9 @@ const computeChildEqualityFactor = (ytype, pnode, mapping) => {
1065
1112
  }
1066
1113
  };
1067
1114
 
1115
+ /**
1116
+ * @param {Y.Text} ytext
1117
+ */
1068
1118
  const ytextTrans = (ytext) => {
1069
1119
  let str = '';
1070
1120
  /**
@@ -1093,14 +1143,14 @@ const ytextTrans = (ytext) => {
1093
1143
  *
1094
1144
  * @param {Y.Text} ytext
1095
1145
  * @param {Array<any>} ptexts
1096
- * @param {ProsemirrorMapping} mapping
1146
+ * @param {BindingMetadata} meta
1097
1147
  */
1098
- const updateYText = (ytext, ptexts, mapping) => {
1099
- mapping.set(ytext, ptexts);
1148
+ const updateYText = (ytext, ptexts, meta) => {
1149
+ meta.mapping.set(ytext, ptexts);
1100
1150
  const { nAttrs, str } = ytextTrans(ytext);
1101
1151
  const content = ptexts.map((p) => ({
1102
1152
  insert: /** @type {any} */ (p).text,
1103
- attributes: Object.assign({}, nAttrs, marksToAttributes(p.marks))
1153
+ attributes: Object.assign({}, nAttrs, marksToAttributes(p.marks, meta))
1104
1154
  }));
1105
1155
  const { insert, remove, index } = diff.simpleDiff(
1106
1156
  str,
@@ -1113,30 +1163,40 @@ const updateYText = (ytext, ptexts, mapping) => {
1113
1163
  );
1114
1164
  };
1115
1165
 
1116
- const marksToAttributes = (marks) => {
1117
- const pattrs = {};
1118
- marks.forEach((mark) => {
1119
- if (mark.type.name !== 'ychange') {
1120
- if (pattrs[mark.type.name] && Array.isArray(pattrs[mark.type.name])) {
1121
- // already has multiple marks of same type
1122
- pattrs[mark.type.name].push(mark.attrs);
1123
- } else if (pattrs[mark.type.name]) {
1124
- // already has mark of same type, change to array
1125
- pattrs[mark.type.name] = [pattrs[mark.type.name], mark.attrs];
1126
- } else {
1127
- // first mark of this type
1128
- pattrs[mark.type.name] = mark.attrs;
1129
- }
1130
- }
1131
- });
1132
- return pattrs
1166
+ const hashedMarkNameRegex = /(.*)(--[a-zA-Z0-9+/=]{8})$/;
1167
+ /**
1168
+ * @param {string} attrName
1169
+ */
1170
+ const yattr2markname = attrName => hashedMarkNameRegex.exec(attrName)?.[1] ?? attrName;
1171
+
1172
+ /**
1173
+ * @todo move this to markstoattributes
1174
+ *
1175
+ * @param {Object<string, any>} attrs
1176
+ * @param {import('prosemirror-model').Schema} schema
1177
+ */
1178
+ const attributesToMarks = (attrs, schema) => {
1179
+ /**
1180
+ * @type {Array<import('prosemirror-model').Mark>}
1181
+ */
1182
+ const marks = [];
1183
+ for (const markName in attrs) {
1184
+ // remove hashes if necessary
1185
+ marks.push(schema.mark(yattr2markname(markName), attrs[markName]));
1186
+ }
1187
+ return marks
1133
1188
  };
1134
1189
 
1135
- const nodeMarksToAttributes = (marks) => {
1190
+ /**
1191
+ * @param {Array<import('prosemirror-model').Mark>} marks
1192
+ * @param {BindingMetadata} meta
1193
+ */
1194
+ const marksToAttributes = (marks, meta) => {
1136
1195
  const pattrs = {};
1137
1196
  marks.forEach((mark) => {
1138
1197
  if (mark.type.name !== 'ychange') {
1139
- pattrs[`${MarkPrefix}${mark.type.name}`] = mark.toJSON();
1198
+ const isOverlapping = map__namespace.setIfUndefined(meta.isOMark, mark.type, () => !mark.type.excludes(mark.type));
1199
+ pattrs[isOverlapping ? `${mark.type.name}--${hashOfJSON(mark.toJSON())}` : mark.type.name] = mark.attrs;
1140
1200
  }
1141
1201
  });
1142
1202
  return pattrs
@@ -1145,7 +1205,7 @@ const nodeMarksToAttributes = (marks) => {
1145
1205
  /**
1146
1206
  * Update a yDom node by syncing the current content of the prosemirror node.
1147
1207
  *
1148
- * This is a y-tiptap internal feature that you can use at your own risk.
1208
+ * This is a y-prosemirror internal feature that you can use at your own risk.
1149
1209
  *
1150
1210
  * @private
1151
1211
  * @unstable
@@ -1153,27 +1213,24 @@ const nodeMarksToAttributes = (marks) => {
1153
1213
  * @param {{transact: Function}} y
1154
1214
  * @param {Y.XmlFragment} yDomFragment
1155
1215
  * @param {any} pNode
1156
- * @param {ProsemirrorMapping} mapping
1216
+ * @param {BindingMetadata} meta
1157
1217
  */
1158
- const updateYFragment = (y, yDomFragment, pNode, mapping) => {
1218
+ const updateYFragment = (y, yDomFragment, pNode, meta) => {
1159
1219
  if (
1160
1220
  yDomFragment instanceof Y__namespace.XmlElement &&
1161
1221
  yDomFragment.nodeName !== pNode.type.name
1162
1222
  ) {
1163
1223
  throw new Error('node name mismatch!')
1164
1224
  }
1165
- mapping.set(yDomFragment, pNode);
1225
+ meta.mapping.set(yDomFragment, pNode);
1166
1226
  // update attributes
1167
1227
  if (yDomFragment instanceof Y__namespace.XmlElement) {
1168
1228
  const yDomAttrs = yDomFragment.getAttributes();
1169
1229
  const pAttrs = pNode.attrs;
1170
- const pNodeMarksAttr = nodeMarksToAttributes(pNode.marks);
1171
- const attrs = { ...pAttrs, ...pNodeMarksAttr };
1172
-
1173
- for (const key in attrs) {
1174
- if (attrs[key] !== null) {
1175
- if (yDomAttrs[key] !== attrs[key] && key !== 'ychange') {
1176
- yDomFragment.setAttribute(key, attrs[key]);
1230
+ for (const key in pAttrs) {
1231
+ if (pAttrs[key] !== null) {
1232
+ if (yDomAttrs[key] !== pAttrs[key] && key !== 'ychange') {
1233
+ yDomFragment.setAttribute(key, pAttrs[key]);
1177
1234
  }
1178
1235
  } else {
1179
1236
  yDomFragment.removeAttribute(key);
@@ -1181,7 +1238,7 @@ const updateYFragment = (y, yDomFragment, pNode, mapping) => {
1181
1238
  }
1182
1239
  // remove all keys that are no longer in pAttrs
1183
1240
  for (const key in yDomAttrs) {
1184
- if (attrs[key] === undefined) {
1241
+ if (pAttrs[key] === undefined) {
1185
1242
  yDomFragment.removeAttribute(key);
1186
1243
  }
1187
1244
  }
@@ -1198,10 +1255,10 @@ const updateYFragment = (y, yDomFragment, pNode, mapping) => {
1198
1255
  for (; left < minCnt; left++) {
1199
1256
  const leftY = yChildren[left];
1200
1257
  const leftP = pChildren[left];
1201
- if (!mappedIdentity(mapping.get(leftY), leftP)) {
1258
+ if (!mappedIdentity(meta.mapping.get(leftY), leftP)) {
1202
1259
  if (equalYTypePNode(leftY, leftP)) {
1203
1260
  // update mapping
1204
- mapping.set(leftY, leftP);
1261
+ meta.mapping.set(leftY, leftP);
1205
1262
  } else {
1206
1263
  break
1207
1264
  }
@@ -1211,10 +1268,10 @@ const updateYFragment = (y, yDomFragment, pNode, mapping) => {
1211
1268
  for (; right + left + 1 < minCnt; right++) {
1212
1269
  const rightY = yChildren[yChildCnt - right - 1];
1213
1270
  const rightP = pChildren[pChildCnt - right - 1];
1214
- if (!mappedIdentity(mapping.get(rightY), rightP)) {
1271
+ if (!mappedIdentity(meta.mapping.get(rightY), rightP)) {
1215
1272
  if (equalYTypePNode(rightY, rightP)) {
1216
1273
  // update mapping
1217
- mapping.set(rightY, rightP);
1274
+ meta.mapping.set(rightY, rightP);
1218
1275
  } else {
1219
1276
  break
1220
1277
  }
@@ -1229,7 +1286,7 @@ const updateYFragment = (y, yDomFragment, pNode, mapping) => {
1229
1286
  const rightP = pChildren[pChildCnt - right - 1];
1230
1287
  if (leftY instanceof Y__namespace.XmlText && leftP instanceof Array) {
1231
1288
  if (!equalYTextPText(leftY, leftP)) {
1232
- updateYText(leftY, leftP, mapping);
1289
+ updateYText(leftY, leftP, meta);
1233
1290
  }
1234
1291
  left += 1;
1235
1292
  } else {
@@ -1242,12 +1299,12 @@ const updateYFragment = (y, yDomFragment, pNode, mapping) => {
1242
1299
  const equalityLeft = computeChildEqualityFactor(
1243
1300
  /** @type {Y.XmlElement} */ (leftY),
1244
1301
  /** @type {PModel.Node} */ (leftP),
1245
- mapping
1302
+ meta
1246
1303
  );
1247
1304
  const equalityRight = computeChildEqualityFactor(
1248
1305
  /** @type {Y.XmlElement} */ (rightY),
1249
1306
  /** @type {PModel.Node} */ (rightP),
1250
- mapping
1307
+ meta
1251
1308
  );
1252
1309
  if (
1253
1310
  equalityLeft.foundMappedChild && !equalityRight.foundMappedChild
@@ -1270,7 +1327,7 @@ const updateYFragment = (y, yDomFragment, pNode, mapping) => {
1270
1327
  y,
1271
1328
  /** @type {Y.XmlFragment} */ (leftY),
1272
1329
  /** @type {PModel.Node} */ (leftP),
1273
- mapping
1330
+ meta
1274
1331
  );
1275
1332
  left += 1;
1276
1333
  } else if (updateRight) {
@@ -1278,14 +1335,14 @@ const updateYFragment = (y, yDomFragment, pNode, mapping) => {
1278
1335
  y,
1279
1336
  /** @type {Y.XmlFragment} */ (rightY),
1280
1337
  /** @type {PModel.Node} */ (rightP),
1281
- mapping
1338
+ meta
1282
1339
  );
1283
1340
  right += 1;
1284
1341
  } else {
1285
- mapping.delete(yDomFragment.get(left));
1342
+ meta.mapping.delete(yDomFragment.get(left));
1286
1343
  yDomFragment.delete(left, 1);
1287
1344
  yDomFragment.insert(left, [
1288
- createTypeFromTextOrElementNode(leftP, mapping)
1345
+ createTypeFromTextOrElementNode(leftP, meta)
1289
1346
  ]);
1290
1347
  left += 1;
1291
1348
  }
@@ -1295,18 +1352,18 @@ const updateYFragment = (y, yDomFragment, pNode, mapping) => {
1295
1352
  if (
1296
1353
  yChildCnt === 1 && pChildCnt === 0 && yChildren[0] instanceof Y__namespace.XmlText
1297
1354
  ) {
1298
- mapping.delete(yChildren[0]);
1299
- // Edge case handling https://github.com/yjs/y-tiptap/issues/108
1355
+ meta.mapping.delete(yChildren[0]);
1356
+ // Edge case handling https://github.com/yjs/y-prosemirror/issues/108
1300
1357
  // Only delete the content of the Y.Text to retain remote changes on the same Y.Text object
1301
1358
  yChildren[0].delete(0, yChildren[0].length);
1302
1359
  } else if (yDelLen > 0) {
1303
- yDomFragment.slice(left, left + yDelLen).forEach(type => mapping.delete(type));
1360
+ yDomFragment.slice(left, left + yDelLen).forEach(type => meta.mapping.delete(type));
1304
1361
  yDomFragment.delete(left, yDelLen);
1305
1362
  }
1306
1363
  if (left + right < pChildCnt) {
1307
1364
  const ins = [];
1308
1365
  for (let i = left; i < pChildCnt - right; i++) {
1309
- ins.push(createTypeFromTextOrElementNode(pChildren[i], mapping));
1366
+ ins.push(createTypeFromTextOrElementNode(pChildren[i], meta));
1310
1367
  }
1311
1368
  yDomFragment.insert(left, ins);
1312
1369
  }
@@ -1516,7 +1573,7 @@ const yXmlFragmentToProseMirrorFragment = (yXmlFragment, schema) => {
1516
1573
  createNodeFromYElement(
1517
1574
  /** @type {Y.XmlElement} */ (t),
1518
1575
  schema,
1519
- new Map()
1576
+ createEmptyMeta()
1520
1577
  )
1521
1578
  ).filter((n) => n !== null);
1522
1579
  return PModel.Fragment.fromArray(fragmentContent)
@@ -1537,21 +1594,20 @@ const yXmlFragmentToProseMirrorRootNode = (yXmlFragment, schema) =>
1537
1594
  *
1538
1595
  * @param {Y.XmlFragment} yXmlFragment
1539
1596
  * @param {Schema} schema
1597
+ *
1598
+ * @todo deprecate mapping property
1540
1599
  */
1541
1600
  const initProseMirrorDoc = (yXmlFragment, schema) => {
1542
- /**
1543
- * @type {ProsemirrorMapping}
1544
- */
1545
- const mapping = new Map();
1601
+ const meta = createEmptyMeta();
1546
1602
  const fragmentContent = yXmlFragment.toArray().map((t) =>
1547
1603
  createNodeFromYElement(
1548
1604
  /** @type {Y.XmlElement} */ (t),
1549
1605
  schema,
1550
- mapping
1606
+ meta
1551
1607
  )
1552
1608
  ).filter((n) => n !== null);
1553
1609
  const doc = schema.topNodeType.create(null, PModel.Fragment.fromArray(fragmentContent));
1554
- return { doc, mapping }
1610
+ return { doc, meta, mapping: meta.mapping }
1555
1611
  };
1556
1612
 
1557
1613
  /**
@@ -1594,7 +1650,7 @@ function prosemirrorToYDoc (doc, xmlFragment = 'prosemirror') {
1594
1650
  function prosemirrorToYXmlFragment (doc, xmlFragment) {
1595
1651
  const type = xmlFragment || new Y__namespace.XmlFragment();
1596
1652
  const ydoc = type.doc ? type.doc : { transact: (transaction) => transaction(undefined) };
1597
- updateYFragment(ydoc, type, doc, new Map());
1653
+ updateYFragment(ydoc, type, doc, { mapping: new Map(), isOMark: new Map() });
1598
1654
  return type
1599
1655
  }
1600
1656
 
@@ -1690,7 +1746,10 @@ function yDocToProsemirrorJSON (
1690
1746
  function yXmlFragmentToProsemirrorJSON (xmlFragment) {
1691
1747
  const items = xmlFragment.toArray();
1692
1748
 
1693
- function serialize (item) {
1749
+ /**
1750
+ * @param {Y.AbstractType} item
1751
+ */
1752
+ const serialize = item => {
1694
1753
  /**
1695
1754
  * @type {Object} NodeObject
1696
1755
  * @property {string} NodeObject.type
@@ -1700,79 +1759,49 @@ function yXmlFragmentToProsemirrorJSON (xmlFragment) {
1700
1759
  let response;
1701
1760
 
1702
1761
  // TODO: Must be a better way to detect text nodes than this
1703
- if (!item.nodeName) {
1762
+ if (item instanceof Y__namespace.XmlText) {
1704
1763
  const delta = item.toDelta();
1705
- response = delta.map((d) => {
1764
+ response = delta.map(/** @param {any} d */ (d) => {
1706
1765
  const text = {
1707
1766
  type: 'text',
1708
1767
  text: d.insert
1709
1768
  };
1710
-
1711
1769
  if (d.attributes) {
1712
- const marks = [];
1713
-
1714
- Object.keys(d.attributes).forEach((type) => {
1715
- const attrs = d.attributes[type];
1716
- if (Array.isArray(attrs)) {
1717
- // multiple marks of same type
1718
- attrs.forEach(singleAttrs => {
1719
- const mark = {
1720
- type
1721
- };
1722
-
1723
- if (Object.keys(singleAttrs)) {
1724
- mark.attrs = singleAttrs;
1725
- }
1726
-
1727
- marks.push(mark);
1728
- });
1729
- } else {
1730
- const mark = {
1731
- type
1732
- };
1733
-
1734
- if (Object.keys(attrs)) {
1735
- mark.attrs = attrs;
1736
- }
1737
-
1738
- marks.push(mark);
1770
+ text.marks = Object.keys(d.attributes).map((type_) => {
1771
+ const attrs = d.attributes[type_];
1772
+ const type = yattr2markname(type_);
1773
+ const mark = {
1774
+ type
1775
+ };
1776
+ if (Object.keys(attrs)) {
1777
+ mark.attrs = attrs;
1739
1778
  }
1779
+ return mark
1740
1780
  });
1741
-
1742
- text.marks = marks;
1743
1781
  }
1744
1782
  return text
1745
1783
  });
1746
- } else {
1784
+ } else if (item instanceof Y__namespace.XmlElement) {
1747
1785
  response = {
1748
1786
  type: item.nodeName
1749
1787
  };
1750
1788
 
1751
1789
  const attrs = item.getAttributes();
1752
-
1753
- // Add all non-mark attributes to the element
1754
- for (const key of Object.keys(attrs).filter((key) => !key.startsWith(MarkPrefix))) {
1755
- if (!response.attrs) response.attrs = {};
1756
- response.attrs[key] = attrs[key];
1757
- }
1758
-
1759
- // Check whether the attrs contains marks, if so, add them to the response
1760
- if (Object.keys(attrs).some((key) => key.startsWith(MarkPrefix))) {
1761
- response.marks = Object.keys(attrs)
1762
- .filter((key) => key.startsWith(MarkPrefix))
1763
- .map((key) => {
1764
- return attrs[key]
1765
- });
1790
+ if (Object.keys(attrs).length) {
1791
+ response.attrs = attrs;
1766
1792
  }
1767
1793
 
1768
1794
  const children = item.toArray();
1769
1795
  if (children.length) {
1770
1796
  response.content = children.map(serialize).flat();
1771
1797
  }
1798
+ } else {
1799
+ // expected either Y.XmlElement or Y.XmlText
1800
+ error__namespace.unexpectedCase();
1772
1801
  }
1773
1802
 
1774
1803
  return response
1775
- }
1804
+ };
1776
1805
 
1777
1806
  return {
1778
1807
  type: 'doc',
@@ -1815,7 +1844,7 @@ const defaultCursorBuilder = (user) => {
1815
1844
  * Default generator for the selection attributes
1816
1845
  *
1817
1846
  * @param {any} user user data
1818
- * @return {import('@tiptap/pm/view').DecorationAttrs}
1847
+ * @return {import('prosemirror-view').DecorationAttrs}
1819
1848
  */
1820
1849
  const defaultSelectionBuilder = (user) => {
1821
1850
  return {
@@ -1830,8 +1859,8 @@ const rxValidColor = /^#[0-9a-fA-F]{6}$/;
1830
1859
  * @param {any} state
1831
1860
  * @param {Awareness} awareness
1832
1861
  * @param {function(number, number, any):boolean} awarenessFilter
1833
- * @param {function({ name: string, color: string }):Element} createCursor
1834
- * @param {function({ name: string, color: string }):import('@tiptap/pm/view').DecorationAttrs} createSelection
1862
+ * @param {(user: { name: string, color: string }, clientId: number) => Element} createCursor
1863
+ * @param {(user: { name: string, color: string }, clientId: number) => import('prosemirror-view').DecorationAttrs} createSelection
1835
1864
  * @return {any} DecorationSet
1836
1865
  */
1837
1866
  const createDecorations = (
@@ -1849,7 +1878,7 @@ const createDecorations = (
1849
1878
  ystate.binding.mapping.size === 0
1850
1879
  ) {
1851
1880
  // do not render cursors while snapshot is active
1852
- return view.DecorationSet.create(state.doc, [])
1881
+ return prosemirrorView.DecorationSet.create(state.doc, [])
1853
1882
  }
1854
1883
  awareness.getStates().forEach((aw, clientId) => {
1855
1884
  if (!awarenessFilter(y.clientID, clientId, aw)) {
@@ -1861,7 +1890,7 @@ const createDecorations = (
1861
1890
  if (user.color == null) {
1862
1891
  user.color = '#ffa500';
1863
1892
  } else if (!rxValidColor.test(user.color)) {
1864
- // We only support 6-digit RGB colors in y-tiptap
1893
+ // We only support 6-digit RGB colors in y-prosemirror
1865
1894
  console.warn('A user uses an unsupported color format', user);
1866
1895
  }
1867
1896
  if (user.name == null) {
@@ -1884,7 +1913,7 @@ const createDecorations = (
1884
1913
  anchor = math__namespace.min(anchor, maxsize);
1885
1914
  head = math__namespace.min(head, maxsize);
1886
1915
  decorations.push(
1887
- view.Decoration.widget(head, () => createCursor(user), {
1916
+ prosemirrorView.Decoration.widget(head, () => createCursor(user, clientId), {
1888
1917
  key: clientId + '',
1889
1918
  side: 10
1890
1919
  })
@@ -1892,7 +1921,7 @@ const createDecorations = (
1892
1921
  const from = math__namespace.min(anchor, head);
1893
1922
  const to = math__namespace.max(anchor, head);
1894
1923
  decorations.push(
1895
- view.Decoration.inline(from, to, createSelection(user), {
1924
+ prosemirrorView.Decoration.inline(from, to, createSelection(user, clientId), {
1896
1925
  inclusiveEnd: true,
1897
1926
  inclusiveStart: false
1898
1927
  })
@@ -1900,7 +1929,7 @@ const createDecorations = (
1900
1929
  }
1901
1930
  }
1902
1931
  });
1903
- return view.DecorationSet.create(state.doc, decorations)
1932
+ return prosemirrorView.DecorationSet.create(state.doc, decorations)
1904
1933
  };
1905
1934
 
1906
1935
  /**
@@ -1911,8 +1940,8 @@ const createDecorations = (
1911
1940
  * @param {Awareness} awareness
1912
1941
  * @param {object} opts
1913
1942
  * @param {function(any, any, any):boolean} [opts.awarenessStateFilter]
1914
- * @param {function(any):HTMLElement} [opts.cursorBuilder]
1915
- * @param {function(any):import('@tiptap/pm/view').DecorationAttrs} [opts.selectionBuilder]
1943
+ * @param {(user: any, clientId: number) => HTMLElement} [opts.cursorBuilder]
1944
+ * @param {(user: any, clientId: number) => import('prosemirror-view').DecorationAttrs} [opts.selectionBuilder]
1916
1945
  * @param {function(any):any} [opts.getSelection]
1917
1946
  * @param {string} [cursorStateField] By default all editor bindings use the awareness 'cursor' field to propagate cursor information.
1918
1947
  * @return {any}
@@ -1927,7 +1956,7 @@ const yCursorPlugin = (
1927
1956
  } = {},
1928
1957
  cursorStateField = 'cursor'
1929
1958
  ) =>
1930
- new state.Plugin({
1959
+ new prosemirrorState.Plugin({
1931
1960
  key: yCursorPluginKey,
1932
1961
  state: {
1933
1962
  init (_, state) {