@remirror/extension-yjs 1.0.17 → 1.0.21

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.
@@ -1,5 +1,5 @@
1
1
  import type { Doc } from 'yjs';
2
- import { AcceptUndefined, EditorState, KeyBindingProps, NonChainableCommandFunction, OnSetOptionsProps, PlainExtension, ProsemirrorPlugin, Selection, Shape } from '@remirror/core';
2
+ import { AcceptUndefined, Dispose, EditorState, KeyBindingProps, NonChainableCommandFunction, OnSetOptionsProps, PlainExtension, ProsemirrorPlugin, Selection, Shape } from '@remirror/core';
3
3
  export interface ColorDef {
4
4
  light: string;
5
5
  dark: string;
@@ -73,7 +73,10 @@ export declare class YjsExtension extends PlainExtension<YjsOptions> {
73
73
  * The provider that is being used for the editor.
74
74
  */
75
75
  get provider(): YjsRealtimeProvider;
76
- onView(): void;
76
+ getBinding(): {
77
+ mapping: Map<any, any>;
78
+ } | undefined;
79
+ onView(): Dispose | void;
77
80
  /**
78
81
  * Create the yjs plugins.
79
82
  */
@@ -110,8 +113,6 @@ export declare class YjsExtension extends PlainExtension<YjsOptions> {
110
113
  * Handle the redo keybinding for the editor.
111
114
  */
112
115
  redoShortcut(props: KeyBindingProps): boolean;
113
- private absolutePositionToRelativePosition;
114
- private relativePositionToAbsolutePosition;
115
116
  }
116
117
  /**
117
118
  * The default destroy provider method.
@@ -3,12 +3,103 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _applyDecoratedDescriptor = require('@babel/runtime/helpers/applyDecoratedDescriptor');
6
+ var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
7
+ var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
6
8
  var yProsemirror = require('y-prosemirror');
9
+ var yjs = require('yjs');
7
10
  var core = require('@remirror/core');
8
11
  var extensionAnnotation = require('@remirror/extension-annotation');
9
12
  var messages = require('@remirror/messages');
10
13
 
11
14
  var _dec, _dec2, _dec3, _dec4, _dec5, _class, _class2;
15
+
16
+ var _excluded = ["from", "to"],
17
+ _excluded2 = ["from", "to"];
18
+
19
+ class YjsAnnotationStore {
20
+ constructor(doc, pmName, mapName, getMapping) {
21
+ this.doc = doc;
22
+ this.getMapping = getMapping;
23
+ this.type = doc.getXmlFragment(pmName);
24
+ this.map = doc.getMap(mapName);
25
+ }
26
+
27
+ addAnnotation(_ref) {
28
+ var from = _ref.from,
29
+ to = _ref.to,
30
+ data = _objectWithoutProperties(_ref, _excluded);
31
+
32
+ // XXX: Why is this cast needed?
33
+ var storedData = _objectSpread(_objectSpread({}, data), {}, {
34
+ from: this.absolutePositionToRelativePosition(from),
35
+ to: this.absolutePositionToRelativePosition(to)
36
+ });
37
+
38
+ this.map.set(data.id, storedData);
39
+ }
40
+
41
+ updateAnnotation(id, updateData) {
42
+ var existing = this.map.get(id);
43
+ core.assert(existing);
44
+ this.map.set(id, _objectSpread(_objectSpread({}, updateData), {}, {
45
+ from: existing.from,
46
+ to: existing.to
47
+ }));
48
+ }
49
+
50
+ removeAnnotations(ids) {
51
+ yjs.transact(this.doc, () => {
52
+ ids.forEach(id => this.map.delete(id));
53
+ });
54
+ }
55
+
56
+ setAnnotations(annotations) {
57
+ yjs.transact(this.doc, () => {
58
+ this.map.clear();
59
+ annotations.forEach(annotation => this.addAnnotation(annotation));
60
+ });
61
+ }
62
+
63
+ formatAnnotations() {
64
+ var result = [];
65
+ this.map.forEach(_ref2 => {
66
+ var relFrom = _ref2.from,
67
+ relTo = _ref2.to,
68
+ data = _objectWithoutProperties(_ref2, _excluded2);
69
+
70
+ var from = this.relativePositionToAbsolutePosition(relFrom);
71
+ var to = this.relativePositionToAbsolutePosition(relTo);
72
+
73
+ if (!from || !to) {
74
+ return;
75
+ } // XXX: Why is this cast needed?
76
+
77
+
78
+ result.push(_objectSpread(_objectSpread({}, data), {}, {
79
+ from,
80
+ to
81
+ }));
82
+ });
83
+ return result;
84
+ }
85
+
86
+ absolutePositionToRelativePosition(pos) {
87
+ var mapping = this.getMapping();
88
+ return yProsemirror.absolutePositionToRelativePosition(pos, this.type, mapping);
89
+ }
90
+
91
+ relativePositionToAbsolutePosition(relPos) {
92
+ var mapping = this.getMapping();
93
+ return yProsemirror.relativePositionToAbsolutePosition(this.doc, this.type, relPos, mapping);
94
+ }
95
+
96
+ }
97
+ /**
98
+ * The YJS extension is the recommended extension for creating a collaborative
99
+ * editor.
100
+ */
101
+
102
+
12
103
  var YjsExtension = (_dec = core.extension({
13
104
  defaultOptions: {
14
105
  getProvider: () => {
@@ -28,23 +119,23 @@ var YjsExtension = (_dec = core.extension({
28
119
  defaultPriority: core.ExtensionPriority.High
29
120
  }), _dec2 = core.command({
30
121
  disableChaining: true,
31
- description: _ref => {
32
- var t = _ref.t;
122
+ description: _ref3 => {
123
+ var t = _ref3.t;
33
124
  return t(messages.ExtensionHistoryMessages.UNDO_DESCRIPTION);
34
125
  },
35
- label: _ref2 => {
36
- var t = _ref2.t;
126
+ label: _ref4 => {
127
+ var t = _ref4.t;
37
128
  return t(messages.ExtensionHistoryMessages.UNDO_LABEL);
38
129
  },
39
130
  icon: 'arrowGoBackFill'
40
131
  }), _dec3 = core.command({
41
132
  disableChaining: true,
42
- description: _ref3 => {
43
- var t = _ref3.t;
133
+ description: _ref5 => {
134
+ var t = _ref5.t;
44
135
  return t(messages.ExtensionHistoryMessages.REDO_DESCRIPTION);
45
136
  },
46
- label: _ref4 => {
47
- var t = _ref4.t;
137
+ label: _ref6 => {
138
+ var t = _ref6.t;
48
139
  return t(messages.ExtensionHistoryMessages.REDO_LABEL);
49
140
  },
50
141
  icon: 'arrowGoForwardFill'
@@ -69,14 +160,27 @@ var YjsExtension = (_dec = core.extension({
69
160
  return (_this$_provider = this._provider) !== null && _this$_provider !== void 0 ? _this$_provider : this._provider = getLazyValue(getProvider);
70
161
  }
71
162
 
163
+ getBinding() {
164
+ var state = this.store.getState();
165
+
166
+ var _ySyncPluginKey$getSt = yProsemirror.ySyncPluginKey.getState(state),
167
+ binding = _ySyncPluginKey$getSt.binding;
168
+
169
+ return binding;
170
+ }
171
+
72
172
  onView() {
73
173
  try {
174
+ var annotationStore = new YjsAnnotationStore(this.provider.doc, 'prosemirror', 'annotations', () => {
175
+ var _this$getBinding;
176
+
177
+ return (_this$getBinding = this.getBinding()) === null || _this$getBinding === void 0 ? void 0 : _this$getBinding.mapping;
178
+ });
74
179
  this.store.manager.getExtension(extensionAnnotation.AnnotationExtension).setOptions({
75
- getMap: () => this.provider.doc.getMap('annotations'),
76
- transformPosition: this.absolutePositionToRelativePosition.bind(this),
77
- transformPositionBeforeRender: this.relativePositionToAbsolutePosition.bind(this)
180
+ getStore: () => annotationStore
78
181
  });
79
- this.provider.doc.on('update', (_update, _origin, _doc, yjsTr) => {
182
+
183
+ var handler = (_update, _origin, _doc, yjsTr) => {
80
184
  var _this$store$commands$, _this$store$commands;
81
185
 
82
186
  // Ignore own changes
@@ -85,7 +189,12 @@ var YjsExtension = (_dec = core.extension({
85
189
  }
86
190
 
87
191
  (_this$store$commands$ = (_this$store$commands = this.store.commands).redrawAnnotations) === null || _this$store$commands$ === void 0 ? void 0 : _this$store$commands$.call(_this$store$commands);
88
- });
192
+ };
193
+
194
+ this.provider.doc.on('update', handler);
195
+ return () => {
196
+ this.provider.doc.off('update', handler);
197
+ };
89
198
  } catch (_unused) {// AnnotationExtension isn't present in editor
90
199
  }
91
200
  }
@@ -104,13 +213,16 @@ var YjsExtension = (_dec = core.extension({
104
213
  trackedOrigins = _this$options.trackedOrigins;
105
214
  var yDoc = this.provider.doc;
106
215
  var type = yDoc.getXmlFragment('prosemirror');
216
+ var undoManager = new yjs.UndoManager(type, {
217
+ trackedOrigins: new Set([yProsemirror.ySyncPluginKey, ...trackedOrigins]),
218
+ deleteFilter: item => yProsemirror.defaultDeleteFilter(item, protectedNodes)
219
+ });
107
220
  return [yProsemirror.ySyncPlugin(type, syncPluginOptions), yProsemirror.yCursorPlugin(this.provider.awareness, {
108
221
  cursorBuilder,
109
222
  cursorStateField,
110
223
  getSelection
111
224
  }, cursorStateField), yProsemirror.yUndoPlugin({
112
- protectedNodes,
113
- trackedOrigins
225
+ undoManager
114
226
  })];
115
227
  }
116
228
  /**
@@ -123,6 +235,13 @@ var YjsExtension = (_dec = core.extension({
123
235
  pickChanged = props.pickChanged;
124
236
  var changedPluginOptions = pickChanged(['cursorBuilder', 'cursorStateField', 'getProvider', 'getSelection', 'syncPluginOptions', 'protectedNodes', 'trackedOrigins']);
125
237
 
238
+ if (changes.protectedNodes.changed || changes.trackedOrigins.changed) {
239
+ // Cannot change these, as we would need a new undo manager instance, and for that
240
+ // we would need to unregister the previous instance from the document to avoid
241
+ // memory leaks.
242
+ throw new Error("Cannot change \"protectedNodes\" or \"trackedOrigins\" options");
243
+ }
244
+
126
245
  if (changes.getProvider.changed) {
127
246
  this._provider = undefined;
128
247
  var previousProvider = getLazyValue(changes.getProvider.previousValue); // Check whether the values have changed.
@@ -222,26 +341,6 @@ var YjsExtension = (_dec = core.extension({
222
341
  return this.yRedo()(props);
223
342
  }
224
343
 
225
- absolutePositionToRelativePosition(pos) {
226
- var state = this.store.getState();
227
-
228
- var _ySyncPluginKey$getSt = yProsemirror.ySyncPluginKey.getState(state),
229
- type = _ySyncPluginKey$getSt.type,
230
- binding = _ySyncPluginKey$getSt.binding;
231
-
232
- return yProsemirror.absolutePositionToRelativePosition(pos, type, binding.mapping);
233
- }
234
-
235
- relativePositionToAbsolutePosition(relPos) {
236
- var state = this.store.getState();
237
-
238
- var _ySyncPluginKey$getSt2 = yProsemirror.ySyncPluginKey.getState(state),
239
- type = _ySyncPluginKey$getSt2.type,
240
- binding = _ySyncPluginKey$getSt2.binding;
241
-
242
- return yProsemirror.relativePositionToAbsolutePosition(this.provider.doc, type, relPos, binding.mapping);
243
- }
244
-
245
344
  }, (_applyDecoratedDescriptor(_class2.prototype, "yUndo", [_dec2], Object.getOwnPropertyDescriptor(_class2.prototype, "yUndo"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "yRedo", [_dec3], Object.getOwnPropertyDescriptor(_class2.prototype, "yRedo"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "undoShortcut", [_dec4], Object.getOwnPropertyDescriptor(_class2.prototype, "undoShortcut"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "redoShortcut", [_dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "redoShortcut"), _class2.prototype)), _class2)) || _class);
246
345
  /**
247
346
  * The default destroy provider method.
@@ -1,10 +1,101 @@
1
1
  import _applyDecoratedDescriptor from '@babel/runtime/helpers/esm/applyDecoratedDescriptor';
2
- import { defaultCursorBuilder, ySyncPlugin, yCursorPlugin, yUndoPlugin, yUndoPluginKey, undo, redo, ySyncPluginKey, absolutePositionToRelativePosition, relativePositionToAbsolutePosition } from 'y-prosemirror';
3
- import { extension, invariant, ErrorConstant, ExtensionPriority, command, keyBinding, NamedShortcut, PlainExtension, isFunction, isEmptyObject, nonChainable, convertCommand } from '@remirror/core';
2
+ import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';
3
+ import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
4
+ import { defaultCursorBuilder, ySyncPluginKey, defaultDeleteFilter, ySyncPlugin, yCursorPlugin, yUndoPlugin, yUndoPluginKey, undo, redo, absolutePositionToRelativePosition, relativePositionToAbsolutePosition } from 'y-prosemirror';
5
+ import { UndoManager, transact } from 'yjs';
6
+ import { extension, invariant, ErrorConstant, ExtensionPriority, command, keyBinding, NamedShortcut, PlainExtension, isFunction, isEmptyObject, nonChainable, convertCommand, assert } from '@remirror/core';
4
7
  import { AnnotationExtension } from '@remirror/extension-annotation';
5
8
  import { ExtensionHistoryMessages } from '@remirror/messages';
6
9
 
7
10
  var _dec, _dec2, _dec3, _dec4, _dec5, _class, _class2;
11
+
12
+ var _excluded = ["from", "to"],
13
+ _excluded2 = ["from", "to"];
14
+
15
+ class YjsAnnotationStore {
16
+ constructor(doc, pmName, mapName, getMapping) {
17
+ this.doc = doc;
18
+ this.getMapping = getMapping;
19
+ this.type = doc.getXmlFragment(pmName);
20
+ this.map = doc.getMap(mapName);
21
+ }
22
+
23
+ addAnnotation(_ref) {
24
+ var from = _ref.from,
25
+ to = _ref.to,
26
+ data = _objectWithoutProperties(_ref, _excluded);
27
+
28
+ // XXX: Why is this cast needed?
29
+ var storedData = _objectSpread(_objectSpread({}, data), {}, {
30
+ from: this.absolutePositionToRelativePosition(from),
31
+ to: this.absolutePositionToRelativePosition(to)
32
+ });
33
+
34
+ this.map.set(data.id, storedData);
35
+ }
36
+
37
+ updateAnnotation(id, updateData) {
38
+ var existing = this.map.get(id);
39
+ assert(existing);
40
+ this.map.set(id, _objectSpread(_objectSpread({}, updateData), {}, {
41
+ from: existing.from,
42
+ to: existing.to
43
+ }));
44
+ }
45
+
46
+ removeAnnotations(ids) {
47
+ transact(this.doc, () => {
48
+ ids.forEach(id => this.map.delete(id));
49
+ });
50
+ }
51
+
52
+ setAnnotations(annotations) {
53
+ transact(this.doc, () => {
54
+ this.map.clear();
55
+ annotations.forEach(annotation => this.addAnnotation(annotation));
56
+ });
57
+ }
58
+
59
+ formatAnnotations() {
60
+ var result = [];
61
+ this.map.forEach(_ref2 => {
62
+ var relFrom = _ref2.from,
63
+ relTo = _ref2.to,
64
+ data = _objectWithoutProperties(_ref2, _excluded2);
65
+
66
+ var from = this.relativePositionToAbsolutePosition(relFrom);
67
+ var to = this.relativePositionToAbsolutePosition(relTo);
68
+
69
+ if (!from || !to) {
70
+ return;
71
+ } // XXX: Why is this cast needed?
72
+
73
+
74
+ result.push(_objectSpread(_objectSpread({}, data), {}, {
75
+ from,
76
+ to
77
+ }));
78
+ });
79
+ return result;
80
+ }
81
+
82
+ absolutePositionToRelativePosition(pos) {
83
+ var mapping = this.getMapping();
84
+ return absolutePositionToRelativePosition(pos, this.type, mapping);
85
+ }
86
+
87
+ relativePositionToAbsolutePosition(relPos) {
88
+ var mapping = this.getMapping();
89
+ return relativePositionToAbsolutePosition(this.doc, this.type, relPos, mapping);
90
+ }
91
+
92
+ }
93
+ /**
94
+ * The YJS extension is the recommended extension for creating a collaborative
95
+ * editor.
96
+ */
97
+
98
+
8
99
  var YjsExtension = (_dec = extension({
9
100
  defaultOptions: {
10
101
  getProvider: () => {
@@ -24,23 +115,23 @@ var YjsExtension = (_dec = extension({
24
115
  defaultPriority: ExtensionPriority.High
25
116
  }), _dec2 = command({
26
117
  disableChaining: true,
27
- description: _ref => {
28
- var t = _ref.t;
118
+ description: _ref3 => {
119
+ var t = _ref3.t;
29
120
  return t(ExtensionHistoryMessages.UNDO_DESCRIPTION);
30
121
  },
31
- label: _ref2 => {
32
- var t = _ref2.t;
122
+ label: _ref4 => {
123
+ var t = _ref4.t;
33
124
  return t(ExtensionHistoryMessages.UNDO_LABEL);
34
125
  },
35
126
  icon: 'arrowGoBackFill'
36
127
  }), _dec3 = command({
37
128
  disableChaining: true,
38
- description: _ref3 => {
39
- var t = _ref3.t;
129
+ description: _ref5 => {
130
+ var t = _ref5.t;
40
131
  return t(ExtensionHistoryMessages.REDO_DESCRIPTION);
41
132
  },
42
- label: _ref4 => {
43
- var t = _ref4.t;
133
+ label: _ref6 => {
134
+ var t = _ref6.t;
44
135
  return t(ExtensionHistoryMessages.REDO_LABEL);
45
136
  },
46
137
  icon: 'arrowGoForwardFill'
@@ -65,14 +156,27 @@ var YjsExtension = (_dec = extension({
65
156
  return (_this$_provider = this._provider) !== null && _this$_provider !== void 0 ? _this$_provider : this._provider = getLazyValue(getProvider);
66
157
  }
67
158
 
159
+ getBinding() {
160
+ var state = this.store.getState();
161
+
162
+ var _ySyncPluginKey$getSt = ySyncPluginKey.getState(state),
163
+ binding = _ySyncPluginKey$getSt.binding;
164
+
165
+ return binding;
166
+ }
167
+
68
168
  onView() {
69
169
  try {
170
+ var annotationStore = new YjsAnnotationStore(this.provider.doc, 'prosemirror', 'annotations', () => {
171
+ var _this$getBinding;
172
+
173
+ return (_this$getBinding = this.getBinding()) === null || _this$getBinding === void 0 ? void 0 : _this$getBinding.mapping;
174
+ });
70
175
  this.store.manager.getExtension(AnnotationExtension).setOptions({
71
- getMap: () => this.provider.doc.getMap('annotations'),
72
- transformPosition: this.absolutePositionToRelativePosition.bind(this),
73
- transformPositionBeforeRender: this.relativePositionToAbsolutePosition.bind(this)
176
+ getStore: () => annotationStore
74
177
  });
75
- this.provider.doc.on('update', (_update, _origin, _doc, yjsTr) => {
178
+
179
+ var handler = (_update, _origin, _doc, yjsTr) => {
76
180
  var _this$store$commands$, _this$store$commands;
77
181
 
78
182
  // Ignore own changes
@@ -81,7 +185,12 @@ var YjsExtension = (_dec = extension({
81
185
  }
82
186
 
83
187
  (_this$store$commands$ = (_this$store$commands = this.store.commands).redrawAnnotations) === null || _this$store$commands$ === void 0 ? void 0 : _this$store$commands$.call(_this$store$commands);
84
- });
188
+ };
189
+
190
+ this.provider.doc.on('update', handler);
191
+ return () => {
192
+ this.provider.doc.off('update', handler);
193
+ };
85
194
  } catch (_unused) {// AnnotationExtension isn't present in editor
86
195
  }
87
196
  }
@@ -100,13 +209,16 @@ var YjsExtension = (_dec = extension({
100
209
  trackedOrigins = _this$options.trackedOrigins;
101
210
  var yDoc = this.provider.doc;
102
211
  var type = yDoc.getXmlFragment('prosemirror');
212
+ var undoManager = new UndoManager(type, {
213
+ trackedOrigins: new Set([ySyncPluginKey, ...trackedOrigins]),
214
+ deleteFilter: item => defaultDeleteFilter(item, protectedNodes)
215
+ });
103
216
  return [ySyncPlugin(type, syncPluginOptions), yCursorPlugin(this.provider.awareness, {
104
217
  cursorBuilder,
105
218
  cursorStateField,
106
219
  getSelection
107
220
  }, cursorStateField), yUndoPlugin({
108
- protectedNodes,
109
- trackedOrigins
221
+ undoManager
110
222
  })];
111
223
  }
112
224
  /**
@@ -119,6 +231,13 @@ var YjsExtension = (_dec = extension({
119
231
  pickChanged = props.pickChanged;
120
232
  var changedPluginOptions = pickChanged(['cursorBuilder', 'cursorStateField', 'getProvider', 'getSelection', 'syncPluginOptions', 'protectedNodes', 'trackedOrigins']);
121
233
 
234
+ if (changes.protectedNodes.changed || changes.trackedOrigins.changed) {
235
+ // Cannot change these, as we would need a new undo manager instance, and for that
236
+ // we would need to unregister the previous instance from the document to avoid
237
+ // memory leaks.
238
+ throw new Error("Cannot change \"protectedNodes\" or \"trackedOrigins\" options");
239
+ }
240
+
122
241
  if (changes.getProvider.changed) {
123
242
  this._provider = undefined;
124
243
  var previousProvider = getLazyValue(changes.getProvider.previousValue); // Check whether the values have changed.
@@ -218,26 +337,6 @@ var YjsExtension = (_dec = extension({
218
337
  return this.yRedo()(props);
219
338
  }
220
339
 
221
- absolutePositionToRelativePosition(pos) {
222
- var state = this.store.getState();
223
-
224
- var _ySyncPluginKey$getSt = ySyncPluginKey.getState(state),
225
- type = _ySyncPluginKey$getSt.type,
226
- binding = _ySyncPluginKey$getSt.binding;
227
-
228
- return absolutePositionToRelativePosition(pos, type, binding.mapping);
229
- }
230
-
231
- relativePositionToAbsolutePosition(relPos) {
232
- var state = this.store.getState();
233
-
234
- var _ySyncPluginKey$getSt2 = ySyncPluginKey.getState(state),
235
- type = _ySyncPluginKey$getSt2.type,
236
- binding = _ySyncPluginKey$getSt2.binding;
237
-
238
- return relativePositionToAbsolutePosition(this.provider.doc, type, relPos, binding.mapping);
239
- }
240
-
241
340
  }, (_applyDecoratedDescriptor(_class2.prototype, "yUndo", [_dec2], Object.getOwnPropertyDescriptor(_class2.prototype, "yUndo"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "yRedo", [_dec3], Object.getOwnPropertyDescriptor(_class2.prototype, "yRedo"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "undoShortcut", [_dec4], Object.getOwnPropertyDescriptor(_class2.prototype, "undoShortcut"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "redoShortcut", [_dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "redoShortcut"), _class2.prototype)), _class2)) || _class);
242
341
  /**
243
342
  * The default destroy provider method.
@@ -3,12 +3,103 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _applyDecoratedDescriptor = require('@babel/runtime/helpers/applyDecoratedDescriptor');
6
+ var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
7
+ var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
6
8
  var yProsemirror = require('y-prosemirror');
9
+ var yjs = require('yjs');
7
10
  var core = require('@remirror/core');
8
11
  var extensionAnnotation = require('@remirror/extension-annotation');
9
12
  var messages = require('@remirror/messages');
10
13
 
11
14
  var _dec, _dec2, _dec3, _dec4, _dec5, _class, _class2;
15
+
16
+ var _excluded = ["from", "to"],
17
+ _excluded2 = ["from", "to"];
18
+
19
+ class YjsAnnotationStore {
20
+ constructor(doc, pmName, mapName, getMapping) {
21
+ this.doc = doc;
22
+ this.getMapping = getMapping;
23
+ this.type = doc.getXmlFragment(pmName);
24
+ this.map = doc.getMap(mapName);
25
+ }
26
+
27
+ addAnnotation(_ref) {
28
+ var from = _ref.from,
29
+ to = _ref.to,
30
+ data = _objectWithoutProperties(_ref, _excluded);
31
+
32
+ // XXX: Why is this cast needed?
33
+ var storedData = _objectSpread(_objectSpread({}, data), {}, {
34
+ from: this.absolutePositionToRelativePosition(from),
35
+ to: this.absolutePositionToRelativePosition(to)
36
+ });
37
+
38
+ this.map.set(data.id, storedData);
39
+ }
40
+
41
+ updateAnnotation(id, updateData) {
42
+ var existing = this.map.get(id);
43
+ core.assert(existing);
44
+ this.map.set(id, _objectSpread(_objectSpread({}, updateData), {}, {
45
+ from: existing.from,
46
+ to: existing.to
47
+ }));
48
+ }
49
+
50
+ removeAnnotations(ids) {
51
+ yjs.transact(this.doc, () => {
52
+ ids.forEach(id => this.map.delete(id));
53
+ });
54
+ }
55
+
56
+ setAnnotations(annotations) {
57
+ yjs.transact(this.doc, () => {
58
+ this.map.clear();
59
+ annotations.forEach(annotation => this.addAnnotation(annotation));
60
+ });
61
+ }
62
+
63
+ formatAnnotations() {
64
+ var result = [];
65
+ this.map.forEach(_ref2 => {
66
+ var relFrom = _ref2.from,
67
+ relTo = _ref2.to,
68
+ data = _objectWithoutProperties(_ref2, _excluded2);
69
+
70
+ var from = this.relativePositionToAbsolutePosition(relFrom);
71
+ var to = this.relativePositionToAbsolutePosition(relTo);
72
+
73
+ if (!from || !to) {
74
+ return;
75
+ } // XXX: Why is this cast needed?
76
+
77
+
78
+ result.push(_objectSpread(_objectSpread({}, data), {}, {
79
+ from,
80
+ to
81
+ }));
82
+ });
83
+ return result;
84
+ }
85
+
86
+ absolutePositionToRelativePosition(pos) {
87
+ var mapping = this.getMapping();
88
+ return yProsemirror.absolutePositionToRelativePosition(pos, this.type, mapping);
89
+ }
90
+
91
+ relativePositionToAbsolutePosition(relPos) {
92
+ var mapping = this.getMapping();
93
+ return yProsemirror.relativePositionToAbsolutePosition(this.doc, this.type, relPos, mapping);
94
+ }
95
+
96
+ }
97
+ /**
98
+ * The YJS extension is the recommended extension for creating a collaborative
99
+ * editor.
100
+ */
101
+
102
+
12
103
  var YjsExtension = (_dec = core.extension({
13
104
  defaultOptions: {
14
105
  getProvider: () => {
@@ -28,23 +119,23 @@ var YjsExtension = (_dec = core.extension({
28
119
  defaultPriority: core.ExtensionPriority.High
29
120
  }), _dec2 = core.command({
30
121
  disableChaining: true,
31
- description: _ref => {
32
- var t = _ref.t;
122
+ description: _ref3 => {
123
+ var t = _ref3.t;
33
124
  return t(messages.ExtensionHistoryMessages.UNDO_DESCRIPTION);
34
125
  },
35
- label: _ref2 => {
36
- var t = _ref2.t;
126
+ label: _ref4 => {
127
+ var t = _ref4.t;
37
128
  return t(messages.ExtensionHistoryMessages.UNDO_LABEL);
38
129
  },
39
130
  icon: 'arrowGoBackFill'
40
131
  }), _dec3 = core.command({
41
132
  disableChaining: true,
42
- description: _ref3 => {
43
- var t = _ref3.t;
133
+ description: _ref5 => {
134
+ var t = _ref5.t;
44
135
  return t(messages.ExtensionHistoryMessages.REDO_DESCRIPTION);
45
136
  },
46
- label: _ref4 => {
47
- var t = _ref4.t;
137
+ label: _ref6 => {
138
+ var t = _ref6.t;
48
139
  return t(messages.ExtensionHistoryMessages.REDO_LABEL);
49
140
  },
50
141
  icon: 'arrowGoForwardFill'
@@ -69,14 +160,27 @@ var YjsExtension = (_dec = core.extension({
69
160
  return (_this$_provider = this._provider) !== null && _this$_provider !== void 0 ? _this$_provider : this._provider = getLazyValue(getProvider);
70
161
  }
71
162
 
163
+ getBinding() {
164
+ var state = this.store.getState();
165
+
166
+ var _ySyncPluginKey$getSt = yProsemirror.ySyncPluginKey.getState(state),
167
+ binding = _ySyncPluginKey$getSt.binding;
168
+
169
+ return binding;
170
+ }
171
+
72
172
  onView() {
73
173
  try {
174
+ var annotationStore = new YjsAnnotationStore(this.provider.doc, 'prosemirror', 'annotations', () => {
175
+ var _this$getBinding;
176
+
177
+ return (_this$getBinding = this.getBinding()) === null || _this$getBinding === void 0 ? void 0 : _this$getBinding.mapping;
178
+ });
74
179
  this.store.manager.getExtension(extensionAnnotation.AnnotationExtension).setOptions({
75
- getMap: () => this.provider.doc.getMap('annotations'),
76
- transformPosition: this.absolutePositionToRelativePosition.bind(this),
77
- transformPositionBeforeRender: this.relativePositionToAbsolutePosition.bind(this)
180
+ getStore: () => annotationStore
78
181
  });
79
- this.provider.doc.on('update', (_update, _origin, _doc, yjsTr) => {
182
+
183
+ var handler = (_update, _origin, _doc, yjsTr) => {
80
184
  var _this$store$commands$, _this$store$commands;
81
185
 
82
186
  // Ignore own changes
@@ -85,7 +189,12 @@ var YjsExtension = (_dec = core.extension({
85
189
  }
86
190
 
87
191
  (_this$store$commands$ = (_this$store$commands = this.store.commands).redrawAnnotations) === null || _this$store$commands$ === void 0 ? void 0 : _this$store$commands$.call(_this$store$commands);
88
- });
192
+ };
193
+
194
+ this.provider.doc.on('update', handler);
195
+ return () => {
196
+ this.provider.doc.off('update', handler);
197
+ };
89
198
  } catch (_unused) {// AnnotationExtension isn't present in editor
90
199
  }
91
200
  }
@@ -104,13 +213,16 @@ var YjsExtension = (_dec = core.extension({
104
213
  trackedOrigins = _this$options.trackedOrigins;
105
214
  var yDoc = this.provider.doc;
106
215
  var type = yDoc.getXmlFragment('prosemirror');
216
+ var undoManager = new yjs.UndoManager(type, {
217
+ trackedOrigins: new Set([yProsemirror.ySyncPluginKey, ...trackedOrigins]),
218
+ deleteFilter: item => yProsemirror.defaultDeleteFilter(item, protectedNodes)
219
+ });
107
220
  return [yProsemirror.ySyncPlugin(type, syncPluginOptions), yProsemirror.yCursorPlugin(this.provider.awareness, {
108
221
  cursorBuilder,
109
222
  cursorStateField,
110
223
  getSelection
111
224
  }, cursorStateField), yProsemirror.yUndoPlugin({
112
- protectedNodes,
113
- trackedOrigins
225
+ undoManager
114
226
  })];
115
227
  }
116
228
  /**
@@ -123,6 +235,13 @@ var YjsExtension = (_dec = core.extension({
123
235
  pickChanged = props.pickChanged;
124
236
  var changedPluginOptions = pickChanged(['cursorBuilder', 'cursorStateField', 'getProvider', 'getSelection', 'syncPluginOptions', 'protectedNodes', 'trackedOrigins']);
125
237
 
238
+ if (changes.protectedNodes.changed || changes.trackedOrigins.changed) {
239
+ // Cannot change these, as we would need a new undo manager instance, and for that
240
+ // we would need to unregister the previous instance from the document to avoid
241
+ // memory leaks.
242
+ throw new Error("Cannot change \"protectedNodes\" or \"trackedOrigins\" options");
243
+ }
244
+
126
245
  if (changes.getProvider.changed) {
127
246
  this._provider = undefined;
128
247
  var previousProvider = getLazyValue(changes.getProvider.previousValue); // Check whether the values have changed.
@@ -222,26 +341,6 @@ var YjsExtension = (_dec = core.extension({
222
341
  return this.yRedo()(props);
223
342
  }
224
343
 
225
- absolutePositionToRelativePosition(pos) {
226
- var state = this.store.getState();
227
-
228
- var _ySyncPluginKey$getSt = yProsemirror.ySyncPluginKey.getState(state),
229
- type = _ySyncPluginKey$getSt.type,
230
- binding = _ySyncPluginKey$getSt.binding;
231
-
232
- return yProsemirror.absolutePositionToRelativePosition(pos, type, binding.mapping);
233
- }
234
-
235
- relativePositionToAbsolutePosition(relPos) {
236
- var state = this.store.getState();
237
-
238
- var _ySyncPluginKey$getSt2 = yProsemirror.ySyncPluginKey.getState(state),
239
- type = _ySyncPluginKey$getSt2.type,
240
- binding = _ySyncPluginKey$getSt2.binding;
241
-
242
- return yProsemirror.relativePositionToAbsolutePosition(this.provider.doc, type, relPos, binding.mapping);
243
- }
244
-
245
344
  }, (_applyDecoratedDescriptor(_class2.prototype, "yUndo", [_dec2], Object.getOwnPropertyDescriptor(_class2.prototype, "yUndo"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "yRedo", [_dec3], Object.getOwnPropertyDescriptor(_class2.prototype, "yRedo"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "undoShortcut", [_dec4], Object.getOwnPropertyDescriptor(_class2.prototype, "undoShortcut"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "redoShortcut", [_dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "redoShortcut"), _class2.prototype)), _class2)) || _class);
246
345
  /**
247
346
  * The default destroy provider method.
@@ -3,12 +3,103 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _applyDecoratedDescriptor = require('@babel/runtime/helpers/applyDecoratedDescriptor');
6
+ var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
7
+ var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
6
8
  var yProsemirror = require('y-prosemirror');
9
+ var yjs = require('yjs');
7
10
  var core = require('@remirror/core');
8
11
  var extensionAnnotation = require('@remirror/extension-annotation');
9
12
  var messages = require('@remirror/messages');
10
13
 
11
14
  var _dec, _dec2, _dec3, _dec4, _dec5, _class, _class2;
15
+
16
+ var _excluded = ["from", "to"],
17
+ _excluded2 = ["from", "to"];
18
+
19
+ class YjsAnnotationStore {
20
+ constructor(doc, pmName, mapName, getMapping) {
21
+ this.doc = doc;
22
+ this.getMapping = getMapping;
23
+ this.type = doc.getXmlFragment(pmName);
24
+ this.map = doc.getMap(mapName);
25
+ }
26
+
27
+ addAnnotation(_ref) {
28
+ var from = _ref.from,
29
+ to = _ref.to,
30
+ data = _objectWithoutProperties(_ref, _excluded);
31
+
32
+ // XXX: Why is this cast needed?
33
+ var storedData = _objectSpread(_objectSpread({}, data), {}, {
34
+ from: this.absolutePositionToRelativePosition(from),
35
+ to: this.absolutePositionToRelativePosition(to)
36
+ });
37
+
38
+ this.map.set(data.id, storedData);
39
+ }
40
+
41
+ updateAnnotation(id, updateData) {
42
+ var existing = this.map.get(id);
43
+ core.assert(existing);
44
+ this.map.set(id, _objectSpread(_objectSpread({}, updateData), {}, {
45
+ from: existing.from,
46
+ to: existing.to
47
+ }));
48
+ }
49
+
50
+ removeAnnotations(ids) {
51
+ yjs.transact(this.doc, () => {
52
+ ids.forEach(id => this.map.delete(id));
53
+ });
54
+ }
55
+
56
+ setAnnotations(annotations) {
57
+ yjs.transact(this.doc, () => {
58
+ this.map.clear();
59
+ annotations.forEach(annotation => this.addAnnotation(annotation));
60
+ });
61
+ }
62
+
63
+ formatAnnotations() {
64
+ var result = [];
65
+ this.map.forEach(_ref2 => {
66
+ var relFrom = _ref2.from,
67
+ relTo = _ref2.to,
68
+ data = _objectWithoutProperties(_ref2, _excluded2);
69
+
70
+ var from = this.relativePositionToAbsolutePosition(relFrom);
71
+ var to = this.relativePositionToAbsolutePosition(relTo);
72
+
73
+ if (!from || !to) {
74
+ return;
75
+ } // XXX: Why is this cast needed?
76
+
77
+
78
+ result.push(_objectSpread(_objectSpread({}, data), {}, {
79
+ from,
80
+ to
81
+ }));
82
+ });
83
+ return result;
84
+ }
85
+
86
+ absolutePositionToRelativePosition(pos) {
87
+ var mapping = this.getMapping();
88
+ return yProsemirror.absolutePositionToRelativePosition(pos, this.type, mapping);
89
+ }
90
+
91
+ relativePositionToAbsolutePosition(relPos) {
92
+ var mapping = this.getMapping();
93
+ return yProsemirror.relativePositionToAbsolutePosition(this.doc, this.type, relPos, mapping);
94
+ }
95
+
96
+ }
97
+ /**
98
+ * The YJS extension is the recommended extension for creating a collaborative
99
+ * editor.
100
+ */
101
+
102
+
12
103
  var YjsExtension = (_dec = core.extension({
13
104
  defaultOptions: {
14
105
  getProvider: () => {
@@ -25,23 +116,23 @@ var YjsExtension = (_dec = core.extension({
25
116
  defaultPriority: core.ExtensionPriority.High
26
117
  }), _dec2 = core.command({
27
118
  disableChaining: true,
28
- description: _ref => {
29
- var t = _ref.t;
119
+ description: _ref3 => {
120
+ var t = _ref3.t;
30
121
  return t(messages.ExtensionHistoryMessages.UNDO_DESCRIPTION);
31
122
  },
32
- label: _ref2 => {
33
- var t = _ref2.t;
123
+ label: _ref4 => {
124
+ var t = _ref4.t;
34
125
  return t(messages.ExtensionHistoryMessages.UNDO_LABEL);
35
126
  },
36
127
  icon: 'arrowGoBackFill'
37
128
  }), _dec3 = core.command({
38
129
  disableChaining: true,
39
- description: _ref3 => {
40
- var t = _ref3.t;
130
+ description: _ref5 => {
131
+ var t = _ref5.t;
41
132
  return t(messages.ExtensionHistoryMessages.REDO_DESCRIPTION);
42
133
  },
43
- label: _ref4 => {
44
- var t = _ref4.t;
134
+ label: _ref6 => {
135
+ var t = _ref6.t;
45
136
  return t(messages.ExtensionHistoryMessages.REDO_LABEL);
46
137
  },
47
138
  icon: 'arrowGoForwardFill'
@@ -66,14 +157,27 @@ var YjsExtension = (_dec = core.extension({
66
157
  return (_this$_provider = this._provider) !== null && _this$_provider !== void 0 ? _this$_provider : this._provider = getLazyValue(getProvider);
67
158
  }
68
159
 
160
+ getBinding() {
161
+ var state = this.store.getState();
162
+
163
+ var _ySyncPluginKey$getSt = yProsemirror.ySyncPluginKey.getState(state),
164
+ binding = _ySyncPluginKey$getSt.binding;
165
+
166
+ return binding;
167
+ }
168
+
69
169
  onView() {
70
170
  try {
171
+ var annotationStore = new YjsAnnotationStore(this.provider.doc, 'prosemirror', 'annotations', () => {
172
+ var _this$getBinding;
173
+
174
+ return (_this$getBinding = this.getBinding()) === null || _this$getBinding === void 0 ? void 0 : _this$getBinding.mapping;
175
+ });
71
176
  this.store.manager.getExtension(extensionAnnotation.AnnotationExtension).setOptions({
72
- getMap: () => this.provider.doc.getMap('annotations'),
73
- transformPosition: this.absolutePositionToRelativePosition.bind(this),
74
- transformPositionBeforeRender: this.relativePositionToAbsolutePosition.bind(this)
177
+ getStore: () => annotationStore
75
178
  });
76
- this.provider.doc.on('update', (_update, _origin, _doc, yjsTr) => {
179
+
180
+ var handler = (_update, _origin, _doc, yjsTr) => {
77
181
  var _this$store$commands$, _this$store$commands;
78
182
 
79
183
  // Ignore own changes
@@ -82,7 +186,12 @@ var YjsExtension = (_dec = core.extension({
82
186
  }
83
187
 
84
188
  (_this$store$commands$ = (_this$store$commands = this.store.commands).redrawAnnotations) === null || _this$store$commands$ === void 0 ? void 0 : _this$store$commands$.call(_this$store$commands);
85
- });
189
+ };
190
+
191
+ this.provider.doc.on('update', handler);
192
+ return () => {
193
+ this.provider.doc.off('update', handler);
194
+ };
86
195
  } catch (_unused) {// AnnotationExtension isn't present in editor
87
196
  }
88
197
  }
@@ -101,13 +210,16 @@ var YjsExtension = (_dec = core.extension({
101
210
  trackedOrigins = _this$options.trackedOrigins;
102
211
  var yDoc = this.provider.doc;
103
212
  var type = yDoc.getXmlFragment('prosemirror');
213
+ var undoManager = new yjs.UndoManager(type, {
214
+ trackedOrigins: new Set([yProsemirror.ySyncPluginKey, ...trackedOrigins]),
215
+ deleteFilter: item => yProsemirror.defaultDeleteFilter(item, protectedNodes)
216
+ });
104
217
  return [yProsemirror.ySyncPlugin(type, syncPluginOptions), yProsemirror.yCursorPlugin(this.provider.awareness, {
105
218
  cursorBuilder,
106
219
  cursorStateField,
107
220
  getSelection
108
221
  }, cursorStateField), yProsemirror.yUndoPlugin({
109
- protectedNodes,
110
- trackedOrigins
222
+ undoManager
111
223
  })];
112
224
  }
113
225
  /**
@@ -120,6 +232,13 @@ var YjsExtension = (_dec = core.extension({
120
232
  pickChanged = props.pickChanged;
121
233
  var changedPluginOptions = pickChanged(['cursorBuilder', 'cursorStateField', 'getProvider', 'getSelection', 'syncPluginOptions', 'protectedNodes', 'trackedOrigins']);
122
234
 
235
+ if (changes.protectedNodes.changed || changes.trackedOrigins.changed) {
236
+ // Cannot change these, as we would need a new undo manager instance, and for that
237
+ // we would need to unregister the previous instance from the document to avoid
238
+ // memory leaks.
239
+ throw new Error("Cannot change \"protectedNodes\" or \"trackedOrigins\" options");
240
+ }
241
+
123
242
  if (changes.getProvider.changed) {
124
243
  this._provider = undefined;
125
244
  var previousProvider = getLazyValue(changes.getProvider.previousValue); // Check whether the values have changed.
@@ -219,26 +338,6 @@ var YjsExtension = (_dec = core.extension({
219
338
  return this.yRedo()(props);
220
339
  }
221
340
 
222
- absolutePositionToRelativePosition(pos) {
223
- var state = this.store.getState();
224
-
225
- var _ySyncPluginKey$getSt = yProsemirror.ySyncPluginKey.getState(state),
226
- type = _ySyncPluginKey$getSt.type,
227
- binding = _ySyncPluginKey$getSt.binding;
228
-
229
- return yProsemirror.absolutePositionToRelativePosition(pos, type, binding.mapping);
230
- }
231
-
232
- relativePositionToAbsolutePosition(relPos) {
233
- var state = this.store.getState();
234
-
235
- var _ySyncPluginKey$getSt2 = yProsemirror.ySyncPluginKey.getState(state),
236
- type = _ySyncPluginKey$getSt2.type,
237
- binding = _ySyncPluginKey$getSt2.binding;
238
-
239
- return yProsemirror.relativePositionToAbsolutePosition(this.provider.doc, type, relPos, binding.mapping);
240
- }
241
-
242
341
  }, (_applyDecoratedDescriptor(_class2.prototype, "yUndo", [_dec2], Object.getOwnPropertyDescriptor(_class2.prototype, "yUndo"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "yRedo", [_dec3], Object.getOwnPropertyDescriptor(_class2.prototype, "yRedo"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "undoShortcut", [_dec4], Object.getOwnPropertyDescriptor(_class2.prototype, "undoShortcut"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "redoShortcut", [_dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "redoShortcut"), _class2.prototype)), _class2)) || _class);
243
342
  /**
244
343
  * The default destroy provider method.
@@ -1,10 +1,101 @@
1
1
  import _applyDecoratedDescriptor from '@babel/runtime/helpers/esm/applyDecoratedDescriptor';
2
- import { defaultCursorBuilder, ySyncPlugin, yCursorPlugin, yUndoPlugin, yUndoPluginKey, undo, redo, ySyncPluginKey, absolutePositionToRelativePosition, relativePositionToAbsolutePosition } from 'y-prosemirror';
3
- import { extension, invariant, ErrorConstant, ExtensionPriority, command, keyBinding, NamedShortcut, PlainExtension, isFunction, isEmptyObject, nonChainable, convertCommand } from '@remirror/core';
2
+ import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';
3
+ import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
4
+ import { defaultCursorBuilder, ySyncPluginKey, defaultDeleteFilter, ySyncPlugin, yCursorPlugin, yUndoPlugin, yUndoPluginKey, undo, redo, absolutePositionToRelativePosition, relativePositionToAbsolutePosition } from 'y-prosemirror';
5
+ import { UndoManager, transact } from 'yjs';
6
+ import { extension, invariant, ErrorConstant, ExtensionPriority, command, keyBinding, NamedShortcut, PlainExtension, isFunction, isEmptyObject, nonChainable, convertCommand, assert } from '@remirror/core';
4
7
  import { AnnotationExtension } from '@remirror/extension-annotation';
5
8
  import { ExtensionHistoryMessages } from '@remirror/messages';
6
9
 
7
10
  var _dec, _dec2, _dec3, _dec4, _dec5, _class, _class2;
11
+
12
+ var _excluded = ["from", "to"],
13
+ _excluded2 = ["from", "to"];
14
+
15
+ class YjsAnnotationStore {
16
+ constructor(doc, pmName, mapName, getMapping) {
17
+ this.doc = doc;
18
+ this.getMapping = getMapping;
19
+ this.type = doc.getXmlFragment(pmName);
20
+ this.map = doc.getMap(mapName);
21
+ }
22
+
23
+ addAnnotation(_ref) {
24
+ var from = _ref.from,
25
+ to = _ref.to,
26
+ data = _objectWithoutProperties(_ref, _excluded);
27
+
28
+ // XXX: Why is this cast needed?
29
+ var storedData = _objectSpread(_objectSpread({}, data), {}, {
30
+ from: this.absolutePositionToRelativePosition(from),
31
+ to: this.absolutePositionToRelativePosition(to)
32
+ });
33
+
34
+ this.map.set(data.id, storedData);
35
+ }
36
+
37
+ updateAnnotation(id, updateData) {
38
+ var existing = this.map.get(id);
39
+ assert(existing);
40
+ this.map.set(id, _objectSpread(_objectSpread({}, updateData), {}, {
41
+ from: existing.from,
42
+ to: existing.to
43
+ }));
44
+ }
45
+
46
+ removeAnnotations(ids) {
47
+ transact(this.doc, () => {
48
+ ids.forEach(id => this.map.delete(id));
49
+ });
50
+ }
51
+
52
+ setAnnotations(annotations) {
53
+ transact(this.doc, () => {
54
+ this.map.clear();
55
+ annotations.forEach(annotation => this.addAnnotation(annotation));
56
+ });
57
+ }
58
+
59
+ formatAnnotations() {
60
+ var result = [];
61
+ this.map.forEach(_ref2 => {
62
+ var relFrom = _ref2.from,
63
+ relTo = _ref2.to,
64
+ data = _objectWithoutProperties(_ref2, _excluded2);
65
+
66
+ var from = this.relativePositionToAbsolutePosition(relFrom);
67
+ var to = this.relativePositionToAbsolutePosition(relTo);
68
+
69
+ if (!from || !to) {
70
+ return;
71
+ } // XXX: Why is this cast needed?
72
+
73
+
74
+ result.push(_objectSpread(_objectSpread({}, data), {}, {
75
+ from,
76
+ to
77
+ }));
78
+ });
79
+ return result;
80
+ }
81
+
82
+ absolutePositionToRelativePosition(pos) {
83
+ var mapping = this.getMapping();
84
+ return absolutePositionToRelativePosition(pos, this.type, mapping);
85
+ }
86
+
87
+ relativePositionToAbsolutePosition(relPos) {
88
+ var mapping = this.getMapping();
89
+ return relativePositionToAbsolutePosition(this.doc, this.type, relPos, mapping);
90
+ }
91
+
92
+ }
93
+ /**
94
+ * The YJS extension is the recommended extension for creating a collaborative
95
+ * editor.
96
+ */
97
+
98
+
8
99
  var YjsExtension = (_dec = extension({
9
100
  defaultOptions: {
10
101
  getProvider: () => {
@@ -24,23 +115,23 @@ var YjsExtension = (_dec = extension({
24
115
  defaultPriority: ExtensionPriority.High
25
116
  }), _dec2 = command({
26
117
  disableChaining: true,
27
- description: _ref => {
28
- var t = _ref.t;
118
+ description: _ref3 => {
119
+ var t = _ref3.t;
29
120
  return t(ExtensionHistoryMessages.UNDO_DESCRIPTION);
30
121
  },
31
- label: _ref2 => {
32
- var t = _ref2.t;
122
+ label: _ref4 => {
123
+ var t = _ref4.t;
33
124
  return t(ExtensionHistoryMessages.UNDO_LABEL);
34
125
  },
35
126
  icon: 'arrowGoBackFill'
36
127
  }), _dec3 = command({
37
128
  disableChaining: true,
38
- description: _ref3 => {
39
- var t = _ref3.t;
129
+ description: _ref5 => {
130
+ var t = _ref5.t;
40
131
  return t(ExtensionHistoryMessages.REDO_DESCRIPTION);
41
132
  },
42
- label: _ref4 => {
43
- var t = _ref4.t;
133
+ label: _ref6 => {
134
+ var t = _ref6.t;
44
135
  return t(ExtensionHistoryMessages.REDO_LABEL);
45
136
  },
46
137
  icon: 'arrowGoForwardFill'
@@ -65,14 +156,27 @@ var YjsExtension = (_dec = extension({
65
156
  return (_this$_provider = this._provider) !== null && _this$_provider !== void 0 ? _this$_provider : this._provider = getLazyValue(getProvider);
66
157
  }
67
158
 
159
+ getBinding() {
160
+ var state = this.store.getState();
161
+
162
+ var _ySyncPluginKey$getSt = ySyncPluginKey.getState(state),
163
+ binding = _ySyncPluginKey$getSt.binding;
164
+
165
+ return binding;
166
+ }
167
+
68
168
  onView() {
69
169
  try {
170
+ var annotationStore = new YjsAnnotationStore(this.provider.doc, 'prosemirror', 'annotations', () => {
171
+ var _this$getBinding;
172
+
173
+ return (_this$getBinding = this.getBinding()) === null || _this$getBinding === void 0 ? void 0 : _this$getBinding.mapping;
174
+ });
70
175
  this.store.manager.getExtension(AnnotationExtension).setOptions({
71
- getMap: () => this.provider.doc.getMap('annotations'),
72
- transformPosition: this.absolutePositionToRelativePosition.bind(this),
73
- transformPositionBeforeRender: this.relativePositionToAbsolutePosition.bind(this)
176
+ getStore: () => annotationStore
74
177
  });
75
- this.provider.doc.on('update', (_update, _origin, _doc, yjsTr) => {
178
+
179
+ var handler = (_update, _origin, _doc, yjsTr) => {
76
180
  var _this$store$commands$, _this$store$commands;
77
181
 
78
182
  // Ignore own changes
@@ -81,7 +185,12 @@ var YjsExtension = (_dec = extension({
81
185
  }
82
186
 
83
187
  (_this$store$commands$ = (_this$store$commands = this.store.commands).redrawAnnotations) === null || _this$store$commands$ === void 0 ? void 0 : _this$store$commands$.call(_this$store$commands);
84
- });
188
+ };
189
+
190
+ this.provider.doc.on('update', handler);
191
+ return () => {
192
+ this.provider.doc.off('update', handler);
193
+ };
85
194
  } catch (_unused) {// AnnotationExtension isn't present in editor
86
195
  }
87
196
  }
@@ -100,13 +209,16 @@ var YjsExtension = (_dec = extension({
100
209
  trackedOrigins = _this$options.trackedOrigins;
101
210
  var yDoc = this.provider.doc;
102
211
  var type = yDoc.getXmlFragment('prosemirror');
212
+ var undoManager = new UndoManager(type, {
213
+ trackedOrigins: new Set([ySyncPluginKey, ...trackedOrigins]),
214
+ deleteFilter: item => defaultDeleteFilter(item, protectedNodes)
215
+ });
103
216
  return [ySyncPlugin(type, syncPluginOptions), yCursorPlugin(this.provider.awareness, {
104
217
  cursorBuilder,
105
218
  cursorStateField,
106
219
  getSelection
107
220
  }, cursorStateField), yUndoPlugin({
108
- protectedNodes,
109
- trackedOrigins
221
+ undoManager
110
222
  })];
111
223
  }
112
224
  /**
@@ -119,6 +231,13 @@ var YjsExtension = (_dec = extension({
119
231
  pickChanged = props.pickChanged;
120
232
  var changedPluginOptions = pickChanged(['cursorBuilder', 'cursorStateField', 'getProvider', 'getSelection', 'syncPluginOptions', 'protectedNodes', 'trackedOrigins']);
121
233
 
234
+ if (changes.protectedNodes.changed || changes.trackedOrigins.changed) {
235
+ // Cannot change these, as we would need a new undo manager instance, and for that
236
+ // we would need to unregister the previous instance from the document to avoid
237
+ // memory leaks.
238
+ throw new Error("Cannot change \"protectedNodes\" or \"trackedOrigins\" options");
239
+ }
240
+
122
241
  if (changes.getProvider.changed) {
123
242
  this._provider = undefined;
124
243
  var previousProvider = getLazyValue(changes.getProvider.previousValue); // Check whether the values have changed.
@@ -218,26 +337,6 @@ var YjsExtension = (_dec = extension({
218
337
  return this.yRedo()(props);
219
338
  }
220
339
 
221
- absolutePositionToRelativePosition(pos) {
222
- var state = this.store.getState();
223
-
224
- var _ySyncPluginKey$getSt = ySyncPluginKey.getState(state),
225
- type = _ySyncPluginKey$getSt.type,
226
- binding = _ySyncPluginKey$getSt.binding;
227
-
228
- return absolutePositionToRelativePosition(pos, type, binding.mapping);
229
- }
230
-
231
- relativePositionToAbsolutePosition(relPos) {
232
- var state = this.store.getState();
233
-
234
- var _ySyncPluginKey$getSt2 = ySyncPluginKey.getState(state),
235
- type = _ySyncPluginKey$getSt2.type,
236
- binding = _ySyncPluginKey$getSt2.binding;
237
-
238
- return relativePositionToAbsolutePosition(this.provider.doc, type, relPos, binding.mapping);
239
- }
240
-
241
340
  }, (_applyDecoratedDescriptor(_class2.prototype, "yUndo", [_dec2], Object.getOwnPropertyDescriptor(_class2.prototype, "yUndo"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "yRedo", [_dec3], Object.getOwnPropertyDescriptor(_class2.prototype, "yRedo"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "undoShortcut", [_dec4], Object.getOwnPropertyDescriptor(_class2.prototype, "undoShortcut"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "redoShortcut", [_dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "redoShortcut"), _class2.prototype)), _class2)) || _class);
242
341
  /**
243
342
  * The default destroy provider method.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remirror/extension-yjs",
3
- "version": "1.0.17",
3
+ "version": "1.0.21",
4
4
  "description": "Realtime collaboration with yjs",
5
5
  "keywords": [
6
6
  "remirror",
@@ -45,15 +45,15 @@
45
45
  "dependencies": {
46
46
  "@babel/runtime": "^7.13.10",
47
47
  "@remirror/core": "^1.3.3",
48
- "@remirror/extension-annotation": "^1.1.9",
48
+ "@remirror/extension-annotation": "^1.1.12",
49
49
  "@remirror/messages": "^1.0.6",
50
- "y-prosemirror": "^1.0.9",
50
+ "y-prosemirror": "^1.0.14",
51
51
  "y-protocols": "^1.0.5"
52
52
  },
53
53
  "devDependencies": {
54
- "@remirror/pm": "^1.0.10",
55
- "y-webrtc": "^10.2.0",
56
- "yjs": "^13.5.11"
54
+ "@remirror/pm": "^1.0.11",
55
+ "y-webrtc": "^10.2.2",
56
+ "yjs": "^13.5.23"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "@remirror/pm": "^1.0.10",