@difizen/libro-shared-model 0.0.0-snapshot-20241017072317

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/es/ymodels.js ADDED
@@ -0,0 +1,1789 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
3
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
7
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
9
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
10
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
11
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
12
+ function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get.bind(); } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } return _get.apply(this, arguments); }
13
+ function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
14
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
15
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
16
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
17
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
18
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
19
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
20
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
21
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
22
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
23
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
24
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
25
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
26
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
27
+ /* eslint-disable @typescript-eslint/no-explicit-any */
28
+
29
+ import { deepCopy, deepEqual } from '@difizen/libro-common';
30
+ import { Emitter } from '@difizen/mana-app';
31
+ import { v4 } from 'uuid';
32
+ import { Awareness } from 'y-protocols/awareness';
33
+ import * as Y from 'yjs';
34
+
35
+ /**
36
+ * Abstract interface to define Shared Models that can be bound to a text editor using any existing
37
+ * Yjs-based editor binding.
38
+ */
39
+
40
+ /**
41
+ * Generic shareable document.
42
+ */
43
+ export var YDocument = /*#__PURE__*/function () {
44
+ function YDocument() {
45
+ var _this = this;
46
+ _classCallCheck(this, YDocument);
47
+ /**
48
+ * YJS document
49
+ */
50
+ this.ydoc = new Y.Doc();
51
+ /**
52
+ * Shared state
53
+ */
54
+ this.ystate = this.ydoc.getMap('state');
55
+ /**
56
+ * YJS document undo manager
57
+ */
58
+ this.undoManager = new Y.UndoManager([], {
59
+ trackedOrigins: new Set([this]),
60
+ doc: this.ydoc
61
+ });
62
+ /**
63
+ * Shared awareness
64
+ */
65
+ this.awareness = new Awareness(this.ydoc);
66
+ /**
67
+ * Handle a change to the ystate.
68
+ */
69
+ this.onStateChanged = function (event) {
70
+ var stateChange = new Array();
71
+ event.keysChanged.forEach(function (key) {
72
+ var change = event.changes.keys.get(key);
73
+ if (change) {
74
+ stateChange.push({
75
+ name: key,
76
+ oldValue: change.oldValue,
77
+ newValue: _this.ystate.get(key)
78
+ });
79
+ }
80
+ });
81
+ _this._changedEmitter.fire({
82
+ stateChange: stateChange
83
+ });
84
+ };
85
+ this._changedEmitter = new Emitter();
86
+ this._changed = this._changedEmitter.event;
87
+ this._isDisposed = false;
88
+ this.ystate.observe(this.onStateChanged);
89
+ }
90
+ _createClass(YDocument, [{
91
+ key: "changed",
92
+ get:
93
+ /**
94
+ * The changed signal.
95
+ */
96
+ function get() {
97
+ return this._changed;
98
+ }
99
+
100
+ /**
101
+ * Whether the document is disposed or not.
102
+ */
103
+ }, {
104
+ key: "isDisposed",
105
+ get: function get() {
106
+ return this._isDisposed;
107
+ }
108
+
109
+ /**
110
+ * Whether the object can undo changes.
111
+ */
112
+ }, {
113
+ key: "canUndo",
114
+ value: function canUndo() {
115
+ return this.undoManager.undoStack.length > 0;
116
+ }
117
+
118
+ /**
119
+ * Whether the object can redo changes.
120
+ */
121
+ }, {
122
+ key: "canRedo",
123
+ value: function canRedo() {
124
+ return this.undoManager.redoStack.length > 0;
125
+ }
126
+
127
+ /**
128
+ * Dispose of the resources.
129
+ */
130
+ }, {
131
+ key: "dispose",
132
+ value: function dispose() {
133
+ if (this._isDisposed) {
134
+ return;
135
+ }
136
+ this._isDisposed = true;
137
+ this.ystate.unobserve(this.onStateChanged);
138
+ this.awareness.destroy();
139
+ this.undoManager.destroy();
140
+ this.ydoc.destroy();
141
+ }
142
+
143
+ /**
144
+ * Undo an operation.
145
+ */
146
+ }, {
147
+ key: "undo",
148
+ value: function undo() {
149
+ this.undoManager.undo();
150
+ }
151
+
152
+ /**
153
+ * Redo an operation.
154
+ */
155
+ }, {
156
+ key: "redo",
157
+ value: function redo() {
158
+ this.undoManager.redo();
159
+ }
160
+
161
+ /**
162
+ * Clear the change stack.
163
+ */
164
+ }, {
165
+ key: "clearUndoHistory",
166
+ value: function clearUndoHistory() {
167
+ this.undoManager.clear();
168
+ }
169
+
170
+ /**
171
+ * Perform a transaction. While the function f is called, all changes to the shared
172
+ * document are bundled into a single event.
173
+ */
174
+ }, {
175
+ key: "transact",
176
+ value: function transact(f) {
177
+ var undoable = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
178
+ this.ydoc.transact(f, undoable ? this : null);
179
+ }
180
+ }]);
181
+ return YDocument;
182
+ }();
183
+
184
+ /**
185
+ * Shareable text file.
186
+ */
187
+ export var YFile = /*#__PURE__*/function (_ref) {
188
+ _inherits(YFile, _ref);
189
+ var _super = _createSuper(YFile);
190
+ function YFile() {
191
+ var _this2;
192
+ _classCallCheck(this, YFile);
193
+ _this2 = _super.call(this);
194
+ /**
195
+ * YJS file text.
196
+ */
197
+ _this2.ysource = _this2.ydoc.getText('source');
198
+ /**
199
+ * Handle a change to the ymodel.
200
+ */
201
+ _this2._modelObserver = function (event) {
202
+ _this2._changedEmitter.fire({
203
+ sourceChange: event.changes.delta
204
+ });
205
+ };
206
+ _this2.undoManager.addToScope(_this2.ysource);
207
+ _this2.ysource.observe(_this2._modelObserver);
208
+ return _this2;
209
+ }
210
+ _createClass(YFile, [{
211
+ key: "source",
212
+ get:
213
+ /**
214
+ * File text
215
+ */
216
+ function get() {
217
+ return this.getSource();
218
+ },
219
+ set: function set(v) {
220
+ this.setSource(v);
221
+ }
222
+
223
+ /**
224
+ * Dispose of the resources.
225
+ */
226
+ }, {
227
+ key: "dispose",
228
+ value: function dispose() {
229
+ if (this.isDisposed) {
230
+ return;
231
+ }
232
+ this.ysource.unobserve(this._modelObserver);
233
+ _get(_getPrototypeOf(YFile.prototype), "dispose", this).call(this);
234
+ }
235
+
236
+ /**
237
+ * Get the file text.
238
+ *
239
+ * @returns File text.
240
+ */
241
+ }, {
242
+ key: "getSource",
243
+ value: function getSource() {
244
+ return this.ysource.toString();
245
+ }
246
+
247
+ /**
248
+ * Set the file text.
249
+ *
250
+ * @param value New text
251
+ */
252
+ }, {
253
+ key: "setSource",
254
+ value: function setSource(value) {
255
+ var _this3 = this;
256
+ this.transact(function () {
257
+ var ytext = _this3.ysource;
258
+ ytext.delete(0, ytext.length);
259
+ ytext.insert(0, value);
260
+ });
261
+ }
262
+
263
+ /**
264
+ * Replace content from `start' to `end` with `value`.
265
+ *
266
+ * @param start: The start index of the range to replace (inclusive).
267
+ * @param end: The end index of the range to replace (exclusive).
268
+ * @param value: New source (optional).
269
+ */
270
+ }, {
271
+ key: "updateSource",
272
+ value: function updateSource(start, end) {
273
+ var _this4 = this;
274
+ var value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
275
+ this.transact(function () {
276
+ var ysource = _this4.ysource;
277
+ // insert and then delete.
278
+ // This ensures that the cursor position is adjusted after the replaced content.
279
+ ysource.insert(start, value);
280
+ ysource.delete(start + value.length, end - start);
281
+ });
282
+ }
283
+ }], [{
284
+ key: "create",
285
+ value:
286
+ /**
287
+ * Instantiate a new shareable file.
288
+ *
289
+ * @param source The initial file content
290
+ *
291
+ * @returns The file model
292
+ */
293
+ function create(source) {
294
+ var model = new YFile();
295
+ if (source) {
296
+ model.source = source;
297
+ }
298
+ return model;
299
+ }
300
+ }]);
301
+ return YFile;
302
+ }(YDocument);
303
+ export var defaultCellTypeAdaptor = function defaultCellTypeAdaptor(cell_Type) {
304
+ return cell_Type;
305
+ };
306
+
307
+ /**
308
+ * Create a new shared cell model given the YJS shared type.
309
+ */
310
+ var createCellModelFromSharedType = function createCellModelFromSharedType(type) {
311
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
312
+ var cellTypeAdaptor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultCellTypeAdaptor;
313
+ switch (cellTypeAdaptor(type.get('cell_type'))) {
314
+ case 'code':
315
+ return new YCodeCell(type, type.get('source'), type.get('outputs'), options);
316
+ case 'markdown':
317
+ return new YMarkdownCell(type, type.get('source'), options);
318
+ case 'raw':
319
+ return new YRawCell(type, type.get('source'), options);
320
+ default:
321
+ throw new Error('Found unknown cell type');
322
+ }
323
+ };
324
+
325
+ /**
326
+ * Create a new cell that can be inserted in an existing shared model.
327
+ *
328
+ * If no notebook is specified the cell will be standalone.
329
+ *
330
+ * @param cell Cell JSON representation
331
+ * @param notebook Notebook to which the cell will be added
332
+ */
333
+ var createCell = function createCell(cell, notebook) {
334
+ var _cell$id;
335
+ var cellTypeAdaptor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultCellTypeAdaptor;
336
+ var ymodel = new Y.Map();
337
+ var ysource = new Y.Text();
338
+ ymodel.set('source', ysource);
339
+ ymodel.set('metadata', {});
340
+ ymodel.set('cell_type', cell.cell_type);
341
+ ymodel.set('id', (_cell$id = cell.id) !== null && _cell$id !== void 0 ? _cell$id : v4());
342
+ var ycell;
343
+ switch (cellTypeAdaptor(cell.cell_type)) {
344
+ case 'markdown':
345
+ {
346
+ ycell = new YMarkdownCell(ymodel, ysource, {
347
+ notebook: notebook
348
+ });
349
+ if (cell.attachments !== null) {
350
+ ycell.setAttachments(cell.attachments);
351
+ }
352
+ break;
353
+ }
354
+ case 'code':
355
+ {
356
+ var _cCell$execution_coun;
357
+ var youtputs = new Y.Array();
358
+ ymodel.set('outputs', youtputs);
359
+ ycell = new YCodeCell(ymodel, ysource, youtputs, {
360
+ notebook: notebook
361
+ });
362
+ var cCell = cell;
363
+ ycell.execution_count = (_cCell$execution_coun = cCell.execution_count) !== null && _cCell$execution_coun !== void 0 ? _cCell$execution_coun : null;
364
+ if (cCell.outputs) {
365
+ ycell.setOutputs(cCell.outputs);
366
+ }
367
+ break;
368
+ }
369
+ default:
370
+ {
371
+ // raw
372
+ ycell = new YRawCell(ymodel, ysource, {
373
+ notebook: notebook
374
+ });
375
+ if (cell.attachments) {
376
+ ycell.setAttachments(cell.attachments);
377
+ }
378
+ break;
379
+ }
380
+ }
381
+ if (cell.metadata !== null) {
382
+ ycell.setMetadata(cell.metadata);
383
+ }
384
+ if (cell.source !== null) {
385
+ ycell.setSource(typeof cell.source === 'string' ? cell.source : cell.source.join('\n'));
386
+ }
387
+ return ycell;
388
+ };
389
+
390
+ /**
391
+ * Create a new cell that cannot be inserted in an existing shared model.
392
+ *
393
+ * @param cell Cell JSON representation
394
+ */
395
+ export var createStandaloneCell = function createStandaloneCell(cell, cellTypeAdaptor) {
396
+ return createCell(cell, undefined, cellTypeAdaptor);
397
+ };
398
+ export var YBaseCell = /*#__PURE__*/function () {
399
+ /**
400
+ * Base cell constructor
401
+ *
402
+ * ### Notes
403
+ * Don't use the constructor directly - prefer using ``YNotebook.insertCell``
404
+ *
405
+ * The ``ysource`` is needed because ``ymodel.get('source')`` will
406
+ * not return the real source if the model is not yet attached to
407
+ * a document. Requesting it explicitly allows to introspect a non-empty
408
+ * source before the cell is attached to the document.
409
+ *
410
+ * @param ymodel Cell map
411
+ * @param ysource Cell source
412
+ * @param options { notebook?: The notebook the cell is attached to }
413
+ */
414
+ function YBaseCell(ymodel, ysource) {
415
+ var _this5 = this;
416
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
417
+ _classCallCheck(this, YBaseCell);
418
+ /**
419
+ * Handle a change to the ymodel.
420
+ */
421
+ this._modelObserver = function (events) {
422
+ _this5._changedEmitter.fire(_this5.getChanges(events));
423
+ };
424
+ this._metadataChangedEmitter = new Emitter();
425
+ this._metadataChanged = this._metadataChangedEmitter.event;
426
+ /**
427
+ * The notebook that this cell belongs to.
428
+ */
429
+ this._notebook = null;
430
+ this._changedEmitter = new Emitter();
431
+ this._changed = this._changedEmitter.event;
432
+ this._isDisposed = false;
433
+ this._undoManager = null;
434
+ this.ymodel = ymodel;
435
+ this._ysource = ysource;
436
+ this._prevSourceLength = ysource ? ysource.length : 0;
437
+ this._notebook = null;
438
+ this._awareness = null;
439
+ this._undoManager = null;
440
+ if (options.notebook) {
441
+ this._notebook = options.notebook;
442
+ // We cannot create a undo manager with the cell not yet attached in the notebook
443
+ // so we defer that to the notebook insertCell method
444
+ } else {
445
+ // Standalone cell
446
+ var doc = new Y.Doc();
447
+ doc.getArray().insert(0, [this.ymodel]);
448
+ this._awareness = new Awareness(doc);
449
+ this._undoManager = new Y.UndoManager([this.ymodel], {
450
+ trackedOrigins: new Set([this])
451
+ });
452
+ }
453
+ this.ymodel.observeDeep(this._modelObserver);
454
+ }
455
+
456
+ /**
457
+ * Cell notebook awareness or null if the cell is standalone.
458
+ */
459
+ _createClass(YBaseCell, [{
460
+ key: "awareness",
461
+ get: function get() {
462
+ var _ref2, _this$_awareness, _this$notebook;
463
+ return (_ref2 = (_this$_awareness = this._awareness) !== null && _this$_awareness !== void 0 ? _this$_awareness : (_this$notebook = this.notebook) === null || _this$notebook === void 0 ? void 0 : _this$notebook.awareness) !== null && _ref2 !== void 0 ? _ref2 : null;
464
+ }
465
+
466
+ /**
467
+ * The type of the cell.
468
+ */
469
+ }, {
470
+ key: "cell_type",
471
+ get: function get() {
472
+ throw new Error('A YBaseCell must not be constructed');
473
+ }
474
+
475
+ /**
476
+ * The changed signal.
477
+ */
478
+ }, {
479
+ key: "changed",
480
+ get: function get() {
481
+ return this._changed;
482
+ }
483
+
484
+ /**
485
+ * Cell id
486
+ */
487
+ }, {
488
+ key: "id",
489
+ get: function get() {
490
+ return this.getId();
491
+ }
492
+
493
+ /**
494
+ * Whether the model has been disposed or not.
495
+ */
496
+ }, {
497
+ key: "isDisposed",
498
+ get: function get() {
499
+ return this._isDisposed;
500
+ }
501
+
502
+ /**
503
+ * Whether the cell is standalone or not.
504
+ *
505
+ * If the cell is standalone. It cannot be
506
+ * inserted into a YNotebook because the Yjs model is already
507
+ * attached to an anonymous Y.Doc instance.
508
+ */
509
+ }, {
510
+ key: "isStandalone",
511
+ get: function get() {
512
+ return this._notebook !== null;
513
+ }
514
+
515
+ /**
516
+ * Cell metadata.
517
+ */
518
+ }, {
519
+ key: "metadata",
520
+ get: function get() {
521
+ return this.getMetadata();
522
+ },
523
+ set: function set(v) {
524
+ this.setMetadata(v);
525
+ }
526
+
527
+ /**
528
+ * Signal triggered when the cell metadata changes.
529
+ */
530
+ }, {
531
+ key: "metadataChanged",
532
+ get: function get() {
533
+ return this._metadataChanged;
534
+ }
535
+
536
+ /**
537
+ * The notebook that this cell belongs to.
538
+ */
539
+ }, {
540
+ key: "notebook",
541
+ get: function get() {
542
+ return this._notebook;
543
+ }
544
+
545
+ /**
546
+ * Cell input content.
547
+ */
548
+ }, {
549
+ key: "source",
550
+ get: function get() {
551
+ return this.getSource();
552
+ },
553
+ set: function set(v) {
554
+ this.setSource(v);
555
+ }
556
+
557
+ /**
558
+ * The cell undo manager.
559
+ */
560
+ }, {
561
+ key: "undoManager",
562
+ get: function get() {
563
+ var _this$notebook2;
564
+ if (!this.notebook) {
565
+ return this._undoManager;
566
+ }
567
+ return (_this$notebook2 = this.notebook) !== null && _this$notebook2 !== void 0 && _this$notebook2.disableDocumentWideUndoRedo ? this._undoManager : this.notebook.undoManager;
568
+ }
569
+
570
+ /**
571
+ * Defer setting the undo manager as it requires the
572
+ * cell to be attached to the notebook Y document.
573
+ */
574
+ }, {
575
+ key: "setUndoManager",
576
+ value: function setUndoManager() {
577
+ if (this._undoManager) {
578
+ throw new Error('The cell undo manager is already set.');
579
+ }
580
+ if (this._notebook && this._notebook.disableDocumentWideUndoRedo) {
581
+ this._undoManager = new Y.UndoManager([this.ymodel], {
582
+ trackedOrigins: new Set([this])
583
+ });
584
+ }
585
+ }
586
+ }, {
587
+ key: "ysource",
588
+ get: function get() {
589
+ return this._ysource;
590
+ }
591
+
592
+ /**
593
+ * Whether the object can undo changes.
594
+ */
595
+ }, {
596
+ key: "canUndo",
597
+ value: function canUndo() {
598
+ return !!this.undoManager && this.undoManager.undoStack.length > 0;
599
+ }
600
+
601
+ /**
602
+ * Whether the object can redo changes.
603
+ */
604
+ }, {
605
+ key: "canRedo",
606
+ value: function canRedo() {
607
+ return !!this.undoManager && this.undoManager.redoStack.length > 0;
608
+ }
609
+
610
+ /**
611
+ * Clear the change stack.
612
+ */
613
+ }, {
614
+ key: "clearUndoHistory",
615
+ value: function clearUndoHistory() {
616
+ var _this$undoManager;
617
+ (_this$undoManager = this.undoManager) === null || _this$undoManager === void 0 || _this$undoManager.clear();
618
+ }
619
+
620
+ /**
621
+ * Undo an operation.
622
+ */
623
+ }, {
624
+ key: "undo",
625
+ value: function undo() {
626
+ var _this$undoManager2;
627
+ (_this$undoManager2 = this.undoManager) === null || _this$undoManager2 === void 0 || _this$undoManager2.undo();
628
+ }
629
+
630
+ /**
631
+ * Redo an operation.
632
+ */
633
+ }, {
634
+ key: "redo",
635
+ value: function redo() {
636
+ var _this$undoManager3;
637
+ (_this$undoManager3 = this.undoManager) === null || _this$undoManager3 === void 0 || _this$undoManager3.redo();
638
+ }
639
+
640
+ /**
641
+ * Dispose of the resources.
642
+ */
643
+ }, {
644
+ key: "dispose",
645
+ value: function dispose() {
646
+ if (this._isDisposed) {
647
+ return;
648
+ }
649
+ this._isDisposed = true;
650
+ this.ymodel.unobserveDeep(this._modelObserver);
651
+ if (this._awareness) {
652
+ // A new document is created for standalone cell.
653
+ var doc = this._awareness.doc;
654
+ this._awareness.destroy();
655
+ doc.destroy();
656
+ }
657
+ if (this._undoManager) {
658
+ var _this$notebook3;
659
+ // Be sure to not destroy the document undo manager.
660
+ if (this._undoManager === ((_this$notebook3 = this.notebook) === null || _this$notebook3 === void 0 ? void 0 : _this$notebook3.undoManager)) {
661
+ this._undoManager = null;
662
+ } else {
663
+ this._undoManager.destroy();
664
+ }
665
+ }
666
+ }
667
+
668
+ /**
669
+ * Get cell id.
670
+ *
671
+ * @returns Cell id
672
+ */
673
+ }, {
674
+ key: "getId",
675
+ value: function getId() {
676
+ return this.ymodel.get('id');
677
+ }
678
+
679
+ /**
680
+ * Gets cell's source.
681
+ *
682
+ * @returns Cell's source.
683
+ */
684
+ }, {
685
+ key: "getSource",
686
+ value: function getSource() {
687
+ return this.ysource.toString();
688
+ }
689
+
690
+ /**
691
+ * Sets cell's source.
692
+ *
693
+ * @param value: New source.
694
+ */
695
+ }, {
696
+ key: "setSource",
697
+ value: function setSource(value) {
698
+ var _this6 = this;
699
+ this.transact(function () {
700
+ _this6.ysource.delete(0, _this6.ysource.length);
701
+ _this6.ysource.insert(0, value);
702
+ });
703
+ // @todo Do we need proper replace semantic? This leads to issues in editor bindings because they don't switch source.
704
+ // this.ymodel.set('source', new Y.Text(value));
705
+ }
706
+
707
+ /**
708
+ * Replace content from `start' to `end` with `value`.
709
+ *
710
+ * @param start: The start index of the range to replace (inclusive).
711
+ *
712
+ * @param end: The end index of the range to replace (exclusive).
713
+ *
714
+ * @param value: New source (optional).
715
+ */
716
+ }, {
717
+ key: "updateSource",
718
+ value: function updateSource(start, end) {
719
+ var _this7 = this;
720
+ var value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
721
+ this.transact(function () {
722
+ var ysource = _this7.ysource;
723
+ // insert and then delete.
724
+ // This ensures that the cursor position is adjusted after the replaced content.
725
+ ysource.insert(start, value);
726
+ ysource.delete(start + value.length, end - start);
727
+ });
728
+ }
729
+
730
+ /**
731
+ * Delete a metadata cell.
732
+ *
733
+ * @param key The key to delete
734
+ */
735
+ }, {
736
+ key: "deleteMetadata",
737
+ value: function deleteMetadata(key) {
738
+ var allMetadata = deepCopy(this.ymodel.get('metadata'));
739
+ delete allMetadata[key];
740
+ this.setMetadata(allMetadata);
741
+ }
742
+
743
+ /**
744
+ * Returns the metadata associated with the cell.
745
+ *
746
+ * @param key
747
+ * @returns Cell metadata.
748
+ */
749
+ }, {
750
+ key: "getMetadata",
751
+ value: function getMetadata(key) {
752
+ var metadata = this.ymodel.get('metadata');
753
+ if (typeof key === 'string') {
754
+ return deepCopy(metadata[key]);
755
+ } else {
756
+ return deepCopy(metadata);
757
+ }
758
+ }
759
+
760
+ /**
761
+ * Sets some cell metadata.
762
+ *
763
+ * If only one argument is provided, it will override all cell metadata.
764
+ * Otherwise a single key will be set to a new value.
765
+ *
766
+ * @param metadata Cell's metadata or key.
767
+ * @param value Metadata value
768
+ */
769
+ }, {
770
+ key: "setMetadata",
771
+ value: function setMetadata(metadata, value) {
772
+ var _clone$jupyter,
773
+ _this8 = this;
774
+ if (typeof metadata === 'string') {
775
+ if (typeof value === 'undefined') {
776
+ throw new TypeError("Metadata value for ".concat(metadata, " cannot be 'undefined'; use deleteMetadata."));
777
+ }
778
+ var key = metadata;
779
+ // eslint-disable-next-line no-param-reassign
780
+ metadata = this.getMetadata();
781
+ // @ts-expect-error metadata type is changed at runtime.
782
+ metadata[key] = value;
783
+ }
784
+ var clone = deepCopy(metadata);
785
+ if (clone.collapsed !== null) {
786
+ clone.jupyter = clone.jupyter || {};
787
+ clone.jupyter.outputs_hidden = clone.collapsed;
788
+ } else if ((clone === null || clone === void 0 || (_clone$jupyter = clone.jupyter) === null || _clone$jupyter === void 0 ? void 0 : _clone$jupyter.outputs_hidden) !== null) {
789
+ clone.collapsed = clone.jupyter.outputs_hidden;
790
+ }
791
+ if (this.ymodel.doc === null || !deepEqual(clone, this.getMetadata())) {
792
+ this.transact(function () {
793
+ _this8.ymodel.set('metadata', clone);
794
+ });
795
+ }
796
+ }
797
+
798
+ /**
799
+ * Serialize the model to JSON.
800
+ */
801
+ }, {
802
+ key: "toJSON",
803
+ value: function toJSON() {
804
+ return {
805
+ id: this.getId(),
806
+ cell_type: this.cell_type,
807
+ source: this.getSource(),
808
+ metadata: this.getMetadata()
809
+ };
810
+ }
811
+
812
+ /**
813
+ * Perform a transaction. While the function f is called, all changes to the shared
814
+ * document are bundled into a single event.
815
+ */
816
+ }, {
817
+ key: "transact",
818
+ value: function transact(f) {
819
+ var undoable = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
820
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
821
+ if (this.notebook && undoable) {
822
+ this.notebook.transact(f);
823
+ } else {
824
+ if (this.ymodel.doc === null) {
825
+ f();
826
+ } else {
827
+ this.ymodel.doc.transact(f, this);
828
+ }
829
+ }
830
+ }
831
+
832
+ /**
833
+ * Extract changes from YJS events
834
+ *
835
+ * @param events YJS events
836
+ * @returns Cell changes
837
+ */
838
+ }, {
839
+ key: "getChanges",
840
+ value: function getChanges(events) {
841
+ var _this9 = this;
842
+ var changes = {};
843
+ var sourceEvent = events.find(function (event) {
844
+ return event.target === _this9.ymodel.get('source');
845
+ });
846
+ if (sourceEvent) {
847
+ changes.sourceChange = sourceEvent.changes.delta;
848
+ }
849
+ var modelEvent = events.find(function (event) {
850
+ return event.target === _this9.ymodel;
851
+ });
852
+ if (modelEvent && modelEvent.keysChanged.has('metadata')) {
853
+ var _metadataChange$oldVa;
854
+ var change = modelEvent.changes.keys.get('metadata');
855
+ var metadataChange = changes.metadataChange = {
856
+ oldValue: change !== null && change !== void 0 && change.oldValue ? change.oldValue : undefined,
857
+ newValue: this.getMetadata()
858
+ };
859
+ var oldValue = (_metadataChange$oldVa = metadataChange.oldValue) !== null && _metadataChange$oldVa !== void 0 ? _metadataChange$oldVa : {};
860
+ var oldKeys = Object.keys(oldValue);
861
+ var newKeys = Object.keys(metadataChange.newValue);
862
+ var _iterator = _createForOfIteratorHelper(new Set(oldKeys.concat(newKeys))),
863
+ _step;
864
+ try {
865
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
866
+ var key = _step.value;
867
+ if (!oldKeys.includes(key)) {
868
+ this._metadataChangedEmitter.fire({
869
+ key: key,
870
+ newValue: metadataChange.newValue[key],
871
+ type: 'add'
872
+ });
873
+ } else if (!newKeys.includes(key)) {
874
+ this._metadataChangedEmitter.fire({
875
+ key: key,
876
+ oldValue: metadataChange.oldValue[key],
877
+ type: 'remove'
878
+ });
879
+ } else if (!deepEqual(oldValue[key], metadataChange.newValue[key])) {
880
+ this._metadataChangedEmitter.fire({
881
+ key: key,
882
+ newValue: metadataChange.newValue[key],
883
+ oldValue: metadataChange.oldValue[key],
884
+ type: 'change'
885
+ });
886
+ }
887
+ }
888
+ } catch (err) {
889
+ _iterator.e(err);
890
+ } finally {
891
+ _iterator.f();
892
+ }
893
+ }
894
+
895
+ // The model allows us to replace the complete source with a new string. We express this in the Delta format
896
+ // as a replace of the complete string.
897
+ var ysource = this.ymodel.get('source');
898
+ if (modelEvent && modelEvent.keysChanged.has('source')) {
899
+ changes.sourceChange = [{
900
+ delete: this._prevSourceLength
901
+ }, {
902
+ insert: ysource.toString()
903
+ }];
904
+ }
905
+ this._prevSourceLength = ysource.length;
906
+ return changes;
907
+ }
908
+ }], [{
909
+ key: "createStandalone",
910
+ value:
911
+ /**
912
+ * Create a new YCell that works standalone. It cannot be
913
+ * inserted into a YNotebook because the Yjs model is already
914
+ * attached to an anonymous Y.Doc instance.
915
+ */
916
+ function createStandalone(id) {
917
+ var cell = createCell({
918
+ id: id,
919
+ cell_type: this.prototype.cell_type,
920
+ source: '',
921
+ metadata: {}
922
+ });
923
+ return cell;
924
+ }
925
+ }]);
926
+ return YBaseCell;
927
+ }();
928
+
929
+ /**
930
+ * Shareable code cell.
931
+ */
932
+ export var YCodeCell = /*#__PURE__*/function (_YBaseCell2) {
933
+ _inherits(YCodeCell, _YBaseCell2);
934
+ var _super2 = _createSuper(YCodeCell);
935
+ /**
936
+ * Code cell constructor
937
+ *
938
+ * ### Notes
939
+ * Don't use the constructor directly - prefer using ``YNotebook.insertCell``
940
+ *
941
+ * The ``ysource`` is needed because ``ymodel.get('source')`` will
942
+ * not return the real source if the model is not yet attached to
943
+ * a document. Requesting it explicitly allows to introspect a non-empty
944
+ * source before the cell is attached to the document.
945
+ *
946
+ * @param ymodel Cell map
947
+ * @param ysource Cell source
948
+ * @param youtputs Code cell outputs
949
+ * @param options { notebook?: The notebook the cell is attached to }
950
+ */
951
+ function YCodeCell(ymodel, ysource, youtputs) {
952
+ var _this10;
953
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
954
+ _classCallCheck(this, YCodeCell);
955
+ _this10 = _super2.call(this, ymodel, ysource, options);
956
+ _this10._youtputs = youtputs;
957
+ return _this10;
958
+ }
959
+
960
+ /**
961
+ * The type of the cell.
962
+ */
963
+ _createClass(YCodeCell, [{
964
+ key: "cell_type",
965
+ get: function get() {
966
+ return this.ymodel.get('cell_type');
967
+ }
968
+
969
+ /**
970
+ * The code cell's prompt number. Will be null if the cell has not been run.
971
+ */
972
+ }, {
973
+ key: "execution_count",
974
+ get: function get() {
975
+ return this.ymodel.get('execution_count') || null;
976
+ },
977
+ set: function set(count) {
978
+ var _this11 = this;
979
+ // Do not use `this.execution_count`. When initializing the
980
+ // cell, we need to set execution_count to `null` if we compare
981
+ // using `this.execution_count` it will return `null` and we will
982
+ // never initialize it
983
+ if (this.ymodel.get('execution_count') !== count) {
984
+ this.transact(function () {
985
+ _this11.ymodel.set('execution_count', count);
986
+ });
987
+ }
988
+ }
989
+
990
+ /**
991
+ * Cell outputs.
992
+ */
993
+ }, {
994
+ key: "outputs",
995
+ get: function get() {
996
+ return this.getOutputs();
997
+ },
998
+ set: function set(v) {
999
+ this.setOutputs(v);
1000
+ }
1001
+
1002
+ /**
1003
+ * Execution, display, or stream outputs.
1004
+ */
1005
+ }, {
1006
+ key: "getOutputs",
1007
+ value: function getOutputs() {
1008
+ return deepCopy(this._youtputs.toArray());
1009
+ }
1010
+
1011
+ /**
1012
+ * Replace all outputs.
1013
+ */
1014
+ }, {
1015
+ key: "setOutputs",
1016
+ value: function setOutputs(outputs) {
1017
+ var _this12 = this;
1018
+ this.transact(function () {
1019
+ _this12._youtputs.delete(0, _this12._youtputs.length);
1020
+ _this12._youtputs.insert(0, outputs);
1021
+ }, false);
1022
+ }
1023
+
1024
+ /**
1025
+ * Replace content from `start' to `end` with `outputs`.
1026
+ *
1027
+ * @param start: The start index of the range to replace (inclusive).
1028
+ *
1029
+ * @param end: The end index of the range to replace (exclusive).
1030
+ *
1031
+ * @param outputs: New outputs (optional).
1032
+ */
1033
+ }, {
1034
+ key: "updateOutputs",
1035
+ value: function updateOutputs(start, end) {
1036
+ var _this13 = this;
1037
+ var outputs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
1038
+ var fin = end < this._youtputs.length ? end - start : this._youtputs.length - start;
1039
+ this.transact(function () {
1040
+ _this13._youtputs.delete(start, fin);
1041
+ _this13._youtputs.insert(start, outputs);
1042
+ }, false);
1043
+ }
1044
+
1045
+ /**
1046
+ * Serialize the model to JSON.
1047
+ */
1048
+ }, {
1049
+ key: "toJSON",
1050
+ value: function toJSON() {
1051
+ return _objectSpread(_objectSpread({}, _get(_getPrototypeOf(YCodeCell.prototype), "toJSON", this).call(this)), {}, {
1052
+ outputs: this.getOutputs(),
1053
+ execution_count: this.execution_count
1054
+ });
1055
+ }
1056
+
1057
+ /**
1058
+ * Extract changes from YJS events
1059
+ *
1060
+ * @param events YJS events
1061
+ * @returns Cell changes
1062
+ */
1063
+ }, {
1064
+ key: "getChanges",
1065
+ value: function getChanges(events) {
1066
+ var _this14 = this;
1067
+ var changes = _get(_getPrototypeOf(YCodeCell.prototype), "getChanges", this).call(this, events);
1068
+ var outputEvent = events.find(function (event) {
1069
+ return event.target === _this14.ymodel.get('outputs');
1070
+ });
1071
+ if (outputEvent) {
1072
+ changes.outputsChange = outputEvent.changes.delta;
1073
+ }
1074
+ var modelEvent = events.find(function (event) {
1075
+ return event.target === _this14.ymodel;
1076
+ });
1077
+ if (modelEvent && modelEvent.keysChanged.has('execution_count')) {
1078
+ var change = modelEvent.changes.keys.get('execution_count');
1079
+ changes.executionCountChange = {
1080
+ oldValue: change.oldValue,
1081
+ newValue: this.ymodel.get('execution_count')
1082
+ };
1083
+ }
1084
+ return changes;
1085
+ }
1086
+ }], [{
1087
+ key: "createStandalone",
1088
+ value:
1089
+ /**
1090
+ * Create a new YCodeCell that works standalone. It cannot be
1091
+ * inserted into a YNotebook because the Yjs model is already
1092
+ * attached to an anonymous Y.Doc instance.
1093
+ */
1094
+ function createStandalone(id) {
1095
+ return _get(_getPrototypeOf(YCodeCell), "createStandalone", this).call(this, id);
1096
+ }
1097
+ }]);
1098
+ return YCodeCell;
1099
+ }(YBaseCell);
1100
+ var YAttachmentCell = /*#__PURE__*/function (_ref3) {
1101
+ _inherits(YAttachmentCell, _ref3);
1102
+ var _super3 = _createSuper(YAttachmentCell);
1103
+ function YAttachmentCell() {
1104
+ _classCallCheck(this, YAttachmentCell);
1105
+ return _super3.apply(this, arguments);
1106
+ }
1107
+ _createClass(YAttachmentCell, [{
1108
+ key: "attachments",
1109
+ get:
1110
+ /**
1111
+ * Cell attachments
1112
+ */
1113
+ function get() {
1114
+ return this.getAttachments();
1115
+ },
1116
+ set: function set(v) {
1117
+ this.setAttachments(v);
1118
+ }
1119
+
1120
+ /**
1121
+ * Gets the cell attachments.
1122
+ *
1123
+ * @returns The cell attachments.
1124
+ */
1125
+ }, {
1126
+ key: "getAttachments",
1127
+ value: function getAttachments() {
1128
+ return this.ymodel.get('attachments');
1129
+ }
1130
+
1131
+ /**
1132
+ * Sets the cell attachments
1133
+ *
1134
+ * @param attachments: The cell attachments.
1135
+ */
1136
+ }, {
1137
+ key: "setAttachments",
1138
+ value: function setAttachments(attachments) {
1139
+ var _this15 = this;
1140
+ this.transact(function () {
1141
+ if (attachments === null) {
1142
+ _this15.ymodel.delete('attachments');
1143
+ } else {
1144
+ _this15.ymodel.set('attachments', attachments);
1145
+ }
1146
+ });
1147
+ }
1148
+
1149
+ /**
1150
+ * Extract changes from YJS events
1151
+ *
1152
+ * @param events YJS events
1153
+ * @returns Cell changes
1154
+ */
1155
+ }, {
1156
+ key: "getChanges",
1157
+ value: function getChanges(events) {
1158
+ var _this16 = this;
1159
+ var changes = _get(_getPrototypeOf(YAttachmentCell.prototype), "getChanges", this).call(this, events);
1160
+ var modelEvent = events.find(function (event) {
1161
+ return event.target === _this16.ymodel;
1162
+ });
1163
+ if (modelEvent && modelEvent.keysChanged.has('attachments')) {
1164
+ var change = modelEvent.changes.keys.get('attachments');
1165
+ changes.executionCountChange = {
1166
+ oldValue: change.oldValue,
1167
+ newValue: this.ymodel.get('attachments')
1168
+ };
1169
+ }
1170
+ return changes;
1171
+ }
1172
+ }]);
1173
+ return YAttachmentCell;
1174
+ }(YBaseCell);
1175
+ /**
1176
+ * Shareable raw cell.
1177
+ */
1178
+ export var YRawCell = /*#__PURE__*/function (_YAttachmentCell) {
1179
+ _inherits(YRawCell, _YAttachmentCell);
1180
+ var _super4 = _createSuper(YRawCell);
1181
+ function YRawCell() {
1182
+ _classCallCheck(this, YRawCell);
1183
+ return _super4.apply(this, arguments);
1184
+ }
1185
+ _createClass(YRawCell, [{
1186
+ key: "cell_type",
1187
+ get:
1188
+ /**
1189
+ * String identifying the type of cell.
1190
+ */
1191
+ function get() {
1192
+ return 'raw';
1193
+ }
1194
+
1195
+ /**
1196
+ * Serialize the model to JSON.
1197
+ */
1198
+ }, {
1199
+ key: "toJSON",
1200
+ value: function toJSON() {
1201
+ return {
1202
+ id: this.getId(),
1203
+ cell_type: 'raw',
1204
+ source: this.getSource(),
1205
+ metadata: this.getMetadata(),
1206
+ attachments: this.getAttachments()
1207
+ };
1208
+ }
1209
+ }], [{
1210
+ key: "createStandalone",
1211
+ value:
1212
+ /**
1213
+ * Create a new YRawCell that works standalone. It cannot be
1214
+ * inserted into a YNotebook because the Yjs model is already
1215
+ * attached to an anonymous Y.Doc instance.
1216
+ */
1217
+ function createStandalone(id) {
1218
+ return _get(_getPrototypeOf(YRawCell), "createStandalone", this).call(this, id);
1219
+ }
1220
+ }]);
1221
+ return YRawCell;
1222
+ }(YAttachmentCell);
1223
+
1224
+ /**
1225
+ * Shareable markdown cell.
1226
+ */
1227
+ export var YMarkdownCell = /*#__PURE__*/function (_YAttachmentCell2) {
1228
+ _inherits(YMarkdownCell, _YAttachmentCell2);
1229
+ var _super5 = _createSuper(YMarkdownCell);
1230
+ function YMarkdownCell() {
1231
+ _classCallCheck(this, YMarkdownCell);
1232
+ return _super5.apply(this, arguments);
1233
+ }
1234
+ _createClass(YMarkdownCell, [{
1235
+ key: "cell_type",
1236
+ get:
1237
+ /**
1238
+ * String identifying the type of cell.
1239
+ */
1240
+ function get() {
1241
+ return 'markdown';
1242
+ }
1243
+
1244
+ /**
1245
+ * Serialize the model to JSON.
1246
+ */
1247
+ }, {
1248
+ key: "toJSON",
1249
+ value: function toJSON() {
1250
+ return {
1251
+ id: this.getId(),
1252
+ cell_type: 'markdown',
1253
+ source: this.getSource(),
1254
+ metadata: this.getMetadata(),
1255
+ attachments: this.getAttachments()
1256
+ };
1257
+ }
1258
+ }], [{
1259
+ key: "createStandalone",
1260
+ value:
1261
+ /**
1262
+ * Create a new YMarkdownCell that works standalone. It cannot be
1263
+ * inserted into a YNotebook because the Yjs model is already
1264
+ * attached to an anonymous Y.Doc instance.
1265
+ */
1266
+ function createStandalone(id) {
1267
+ return _get(_getPrototypeOf(YMarkdownCell), "createStandalone", this).call(this, id);
1268
+ }
1269
+ }]);
1270
+ return YMarkdownCell;
1271
+ }(YAttachmentCell);
1272
+
1273
+ /**
1274
+ * Cell type.
1275
+ */
1276
+
1277
+ /**
1278
+ * Shared implementation of the Shared Document types.
1279
+ *
1280
+ * Shared cells can be inserted into a SharedNotebook.
1281
+ * Shared cells only start emitting events when they are connected to a SharedNotebook.
1282
+ *
1283
+ * "Standalone" cells must not be inserted into a (Shared)Notebook.
1284
+ * Standalone cells emit events immediately after they have been created, but they must not
1285
+ * be included into a (Shared)Notebook.
1286
+ */
1287
+ export var YNotebook = /*#__PURE__*/function (_YDocument2) {
1288
+ _inherits(YNotebook, _YDocument2);
1289
+ var _super6 = _createSuper(YNotebook);
1290
+ function YNotebook() {
1291
+ var _options$disableDocum, _options$cellTypeAdap;
1292
+ var _this17;
1293
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1294
+ _classCallCheck(this, YNotebook);
1295
+ _this17 = _super6.call(this);
1296
+ _this17._undoChangedEmitter = new Emitter();
1297
+ _this17._redoChangedEmitter = new Emitter();
1298
+ _this17._canRedo = false;
1299
+ _this17._canUndo = false;
1300
+ _this17.handleUndoChanged = function () {
1301
+ var canRedo = _this17.undoManager.canRedo();
1302
+ if (_this17._canRedo !== canRedo) {
1303
+ _this17._canRedo = canRedo;
1304
+ _this17._redoChangedEmitter.fire(canRedo);
1305
+ }
1306
+ var canUndo = _this17.undoManager.canUndo();
1307
+ if (_this17._canUndo !== canUndo) {
1308
+ _this17._canUndo = canUndo;
1309
+ _this17._undoChangedEmitter.fire(canUndo);
1310
+ }
1311
+ };
1312
+ _this17.cellTypeAdaptor = defaultCellTypeAdaptor;
1313
+ /**
1314
+ * YJS map for the notebook metadata
1315
+ */
1316
+ _this17.ymeta = _this17.ydoc.getMap('meta');
1317
+ /**
1318
+ * Handle a change to the ystate.
1319
+ */
1320
+ _this17._onMetaChanged = function (event) {
1321
+ if (event.keysChanged.has('metadata')) {
1322
+ var _metadataChange$oldVa2;
1323
+ var change = event.changes.keys.get('metadata');
1324
+ var metadataChange = {
1325
+ oldValue: change !== null && change !== void 0 && change.oldValue ? change.oldValue : undefined,
1326
+ newValue: _this17.getMetadata()
1327
+ };
1328
+ var oldValue = (_metadataChange$oldVa2 = metadataChange.oldValue) !== null && _metadataChange$oldVa2 !== void 0 ? _metadataChange$oldVa2 : {};
1329
+ var oldKeys = Object.keys(oldValue);
1330
+ var newKeys = Object.keys(metadataChange.newValue);
1331
+ var _iterator2 = _createForOfIteratorHelper(new Set(oldKeys.concat(newKeys))),
1332
+ _step2;
1333
+ try {
1334
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
1335
+ var key = _step2.value;
1336
+ if (!oldKeys.includes(key)) {
1337
+ _this17._metadataChangedEmitter.fire({
1338
+ key: key,
1339
+ newValue: metadataChange.newValue[key],
1340
+ type: 'add'
1341
+ });
1342
+ } else if (!newKeys.includes(key)) {
1343
+ _this17._metadataChangedEmitter.fire({
1344
+ key: key,
1345
+ oldValue: metadataChange.oldValue[key],
1346
+ type: 'remove'
1347
+ });
1348
+ } else if (!deepEqual(oldValue[key], metadataChange.newValue[key])) {
1349
+ _this17._metadataChangedEmitter.fire({
1350
+ key: key,
1351
+ newValue: metadataChange.newValue[key],
1352
+ oldValue: metadataChange.oldValue[key],
1353
+ type: 'change'
1354
+ });
1355
+ }
1356
+ }
1357
+ } catch (err) {
1358
+ _iterator2.e(err);
1359
+ } finally {
1360
+ _iterator2.f();
1361
+ }
1362
+ _this17._changedEmitter.fire({
1363
+ metadataChange: metadataChange
1364
+ });
1365
+ }
1366
+ if (event.keysChanged.has('nbformat')) {
1367
+ var _change = event.changes.keys.get('nbformat');
1368
+ var nbformatChanged = {
1369
+ key: 'nbformat',
1370
+ oldValue: _change !== null && _change !== void 0 && _change.oldValue ? _change.oldValue : undefined,
1371
+ newValue: _this17.nbformat
1372
+ };
1373
+ _this17._changedEmitter.fire({
1374
+ nbformatChanged: nbformatChanged
1375
+ });
1376
+ }
1377
+ if (event.keysChanged.has('nbformat_minor')) {
1378
+ var _change2 = event.changes.keys.get('nbformat_minor');
1379
+ var _nbformatChanged = {
1380
+ key: 'nbformat_minor',
1381
+ oldValue: _change2 !== null && _change2 !== void 0 && _change2.oldValue ? _change2.oldValue : undefined,
1382
+ newValue: _this17.nbformat_minor
1383
+ };
1384
+ _this17._changedEmitter.fire({
1385
+ nbformatChanged: _nbformatChanged
1386
+ });
1387
+ }
1388
+ };
1389
+ /**
1390
+ * Handle a change to the list of cells.
1391
+ */
1392
+ _this17._onYCellsChanged = function (event) {
1393
+ // update the type cell mapping by iterating through the added/removed types
1394
+ event.changes.added.forEach(function (item) {
1395
+ var type = item.content.type;
1396
+ if (!_this17._ycellMapping.has(type)) {
1397
+ var c = createCellModelFromSharedType(type, {
1398
+ notebook: _assertThisInitialized(_this17)
1399
+ }, _this17.cellTypeAdaptor);
1400
+ c.setUndoManager();
1401
+ _this17._ycellMapping.set(type, c);
1402
+ }
1403
+ });
1404
+ event.changes.deleted.forEach(function (item) {
1405
+ var type = item.content.type;
1406
+ var model = _this17._ycellMapping.get(type);
1407
+ if (model) {
1408
+ model.dispose();
1409
+ _this17._ycellMapping.delete(type);
1410
+ }
1411
+ });
1412
+ var index = 0;
1413
+
1414
+ // this reflects the event.changes.delta, but replaces the content of delta.insert with ycells
1415
+ var cellsChange = [];
1416
+ event.changes.delta.forEach(function (d) {
1417
+ if (d.insert) {
1418
+ var _this17$cells;
1419
+ var insertedCells = d.insert.map(function (ycell) {
1420
+ return _this17._ycellMapping.get(ycell);
1421
+ });
1422
+ cellsChange.push({
1423
+ insert: insertedCells
1424
+ });
1425
+ (_this17$cells = _this17.cells).splice.apply(_this17$cells, [index, 0].concat(_toConsumableArray(insertedCells)));
1426
+ _this17._cellsChangedEmitter.fire({
1427
+ type: 'add',
1428
+ newIndex: index,
1429
+ newValues: insertedCells,
1430
+ oldIndex: -2,
1431
+ oldValues: []
1432
+ });
1433
+ index += d.insert.length;
1434
+ } else if (d.delete) {
1435
+ cellsChange.push(d);
1436
+ var oldValues = _this17.cells.splice(index, d.delete);
1437
+ _this17._cellsChangedEmitter.fire({
1438
+ type: 'remove',
1439
+ newIndex: -1,
1440
+ newValues: [],
1441
+ oldIndex: index,
1442
+ oldValues: oldValues
1443
+ });
1444
+ } else if (d.retain) {
1445
+ cellsChange.push(d);
1446
+ index += d.retain;
1447
+ }
1448
+ });
1449
+ _this17._changedEmitter.fire({
1450
+ cellsChange: cellsChange
1451
+ });
1452
+ };
1453
+ _this17._cellsChangedEmitter = new Emitter();
1454
+ _this17._cellsChanged = _this17._cellsChangedEmitter.event;
1455
+ _this17._metadataChangedEmitter = new Emitter();
1456
+ _this17._metadataChanged = _this17._metadataChangedEmitter.event;
1457
+ /**
1458
+ * Internal Yjs cells list
1459
+ */
1460
+ _this17._ycells = _this17.ydoc.getArray('cells');
1461
+ _this17._ycellMapping = new WeakMap();
1462
+ _this17._disableDocumentWideUndoRedo = (_options$disableDocum = options.disableDocumentWideUndoRedo) !== null && _options$disableDocum !== void 0 ? _options$disableDocum : false;
1463
+ _this17.cellTypeAdaptor = (_options$cellTypeAdap = options.cellTypeAdaptor) !== null && _options$cellTypeAdap !== void 0 ? _options$cellTypeAdap : defaultCellTypeAdaptor;
1464
+ _this17.cells = _this17._ycells.toArray().map(function (ycell) {
1465
+ if (!_this17._ycellMapping.has(ycell)) {
1466
+ _this17._ycellMapping.set(ycell, createCellModelFromSharedType(ycell, {
1467
+ notebook: _assertThisInitialized(_this17)
1468
+ }, _this17.cellTypeAdaptor));
1469
+ }
1470
+ return _this17._ycellMapping.get(ycell);
1471
+ });
1472
+ _this17.undoManager.addToScope(_this17._ycells);
1473
+ _this17._ycells.observe(_this17._onYCellsChanged);
1474
+ _this17.ymeta.observe(_this17._onMetaChanged);
1475
+ _this17.undoManager.on('stack-item-updated', _this17.handleUndoChanged);
1476
+ _this17.undoManager.on('stack-item-added', _this17.handleUndoChanged);
1477
+ _this17.undoManager.on('stack-item-popped', _this17.handleUndoChanged);
1478
+ _this17.undoManager.on('stack-cleared', _this17.handleUndoChanged);
1479
+ _this17._canRedo = _this17.undoManager.canRedo();
1480
+ _this17._canUndo = _this17.undoManager.canUndo();
1481
+ return _this17;
1482
+ }
1483
+ _createClass(YNotebook, [{
1484
+ key: "undoChanged",
1485
+ get:
1486
+ /**
1487
+ * Signal triggered when a undo stack changed.
1488
+ */
1489
+ function get() {
1490
+ return this._undoChangedEmitter.event;
1491
+ }
1492
+ }, {
1493
+ key: "redoChanged",
1494
+ get:
1495
+ /**
1496
+ * Signal triggered when a undo stack changed.
1497
+ */
1498
+ function get() {
1499
+ return this._redoChangedEmitter.event;
1500
+ }
1501
+
1502
+ /**
1503
+ * Create a new YNotebook.
1504
+ */
1505
+ }, {
1506
+ key: "cellsChanged",
1507
+ get:
1508
+ /**
1509
+ * Cells list
1510
+ */
1511
+
1512
+ /**
1513
+ * Signal triggered when the cells list changes.
1514
+ */
1515
+ function get() {
1516
+ return this._cellsChanged;
1517
+ }
1518
+
1519
+ /**
1520
+ * Wether the undo/redo logic should be
1521
+ * considered on the full document across all cells.
1522
+ *
1523
+ * Default: false
1524
+ */
1525
+ }, {
1526
+ key: "disableDocumentWideUndoRedo",
1527
+ get: function get() {
1528
+ return this._disableDocumentWideUndoRedo;
1529
+ }
1530
+
1531
+ /**
1532
+ * Notebook metadata
1533
+ */
1534
+ }, {
1535
+ key: "metadata",
1536
+ get: function get() {
1537
+ return this.getMetadata();
1538
+ },
1539
+ set: function set(v) {
1540
+ this.setMetadata(v);
1541
+ }
1542
+
1543
+ /**
1544
+ * Signal triggered when a metadata changes.
1545
+ */
1546
+ }, {
1547
+ key: "metadataChanged",
1548
+ get: function get() {
1549
+ return this._metadataChanged;
1550
+ }
1551
+
1552
+ /**
1553
+ * nbformat major version
1554
+ */
1555
+ }, {
1556
+ key: "nbformat",
1557
+ get: function get() {
1558
+ return this.ymeta.get('nbformat');
1559
+ },
1560
+ set: function set(value) {
1561
+ var _this18 = this;
1562
+ this.transact(function () {
1563
+ _this18.ymeta.set('nbformat', value);
1564
+ }, false);
1565
+ }
1566
+
1567
+ /**
1568
+ * nbformat minor version
1569
+ */
1570
+ }, {
1571
+ key: "nbformat_minor",
1572
+ get: function get() {
1573
+ return this.ymeta.get('nbformat_minor');
1574
+ },
1575
+ set: function set(value) {
1576
+ var _this19 = this;
1577
+ this.transact(function () {
1578
+ _this19.ymeta.set('nbformat_minor', value);
1579
+ }, false);
1580
+ }
1581
+
1582
+ /**
1583
+ * Dispose of the resources.
1584
+ */
1585
+ }, {
1586
+ key: "dispose",
1587
+ value: function dispose() {
1588
+ if (this.isDisposed) {
1589
+ return;
1590
+ }
1591
+ this._ycells.unobserve(this._onYCellsChanged);
1592
+ this.ymeta.unobserve(this._onMetaChanged);
1593
+ this.undoManager.off('stack-item-updated', this.handleUndoChanged);
1594
+ this.undoManager.off('stack-item-added', this.handleUndoChanged);
1595
+ this.undoManager.off('stack-item-popped', this.handleUndoChanged);
1596
+ this.undoManager.off('stack-cleared', this.handleUndoChanged);
1597
+ _get(_getPrototypeOf(YNotebook.prototype), "dispose", this).call(this);
1598
+ }
1599
+
1600
+ /**
1601
+ * Get a shared cell by index.
1602
+ *
1603
+ * @param index: Cell's position.
1604
+ *
1605
+ * @returns The requested shared cell.
1606
+ */
1607
+ }, {
1608
+ key: "getCell",
1609
+ value: function getCell(index) {
1610
+ return this.cells[index];
1611
+ }
1612
+
1613
+ /**
1614
+ * Add a shared cell at the notebook bottom.
1615
+ *
1616
+ * @param cell Cell to add.
1617
+ *
1618
+ * @returns The added cell.
1619
+ */
1620
+ }, {
1621
+ key: "addCell",
1622
+ value: function addCell(cell) {
1623
+ return this.insertCell(this._ycells.length, cell);
1624
+ }
1625
+
1626
+ /**
1627
+ * Insert a shared cell into a specific position.
1628
+ *
1629
+ * @param index: Cell's position.
1630
+ * @param cell: Cell to insert.
1631
+ *
1632
+ * @returns The inserted cell.
1633
+ */
1634
+ }, {
1635
+ key: "insertCell",
1636
+ value: function insertCell(index, cell) {
1637
+ return this.insertCells(index, [cell])[0];
1638
+ }
1639
+
1640
+ /**
1641
+ * Insert a list of shared cells into a specific position.
1642
+ *
1643
+ * @param index: Position to insert the cells.
1644
+ * @param cells: Array of shared cells to insert.
1645
+ *
1646
+ * @returns The inserted cells.
1647
+ */
1648
+ }, {
1649
+ key: "insertCells",
1650
+ value: function insertCells(index, cells) {
1651
+ var _this20 = this;
1652
+ var yCells = cells.map(function (c) {
1653
+ var cell = createCell(c, _this20);
1654
+ _this20._ycellMapping.set(cell.ymodel, cell);
1655
+ return cell;
1656
+ });
1657
+ this.transact(function () {
1658
+ _this20._ycells.insert(index, yCells.map(function (cell) {
1659
+ return cell.ymodel;
1660
+ }));
1661
+ });
1662
+ yCells.forEach(function (c) {
1663
+ c.setUndoManager();
1664
+ });
1665
+ return yCells;
1666
+ }
1667
+
1668
+ /**
1669
+ * Move a cell.
1670
+ *
1671
+ * @param fromIndex: Index of the cell to move.
1672
+ * @param toIndex: New position of the cell.
1673
+ */
1674
+ }, {
1675
+ key: "moveCell",
1676
+ value: function moveCell(fromIndex, toIndex) {
1677
+ var _this21 = this;
1678
+ this.transact(function () {
1679
+ // FIXME we need to use yjs move feature to preserve undo history
1680
+ var clone = createCell(_this21.getCell(fromIndex).toJSON(), _this21);
1681
+ _this21._ycells.delete(fromIndex, 1);
1682
+ _this21._ycells.insert(toIndex, [clone.ymodel]);
1683
+ });
1684
+ }
1685
+
1686
+ /**
1687
+ * Remove a cell.
1688
+ *
1689
+ * @param index: Index of the cell to remove.
1690
+ */
1691
+ }, {
1692
+ key: "deleteCell",
1693
+ value: function deleteCell(index) {
1694
+ this.deleteCellRange(index, index + 1);
1695
+ }
1696
+
1697
+ /**
1698
+ * Remove a range of cells.
1699
+ *
1700
+ * @param from: The start index of the range to remove (inclusive).
1701
+ * @param to: The end index of the range to remove (exclusive).
1702
+ */
1703
+ }, {
1704
+ key: "deleteCellRange",
1705
+ value: function deleteCellRange(from, to) {
1706
+ var _this22 = this;
1707
+ // Cells will be removed from the mapping in the model event listener.
1708
+ this.transact(function () {
1709
+ _this22._ycells.delete(from, to - from);
1710
+ });
1711
+ }
1712
+
1713
+ /**
1714
+ * Delete a metadata notebook.
1715
+ *
1716
+ * @param key The key to delete
1717
+ */
1718
+ }, {
1719
+ key: "deleteMetadata",
1720
+ value: function deleteMetadata(key) {
1721
+ var allMetadata = deepCopy(this.ymeta.get('metadata'));
1722
+ delete allMetadata[key];
1723
+ this.setMetadata(allMetadata);
1724
+ }
1725
+
1726
+ /**
1727
+ * Returns some metadata associated with the notebook.
1728
+ *
1729
+ * If no `key` is provided, it will return all metadata.
1730
+ * Else it will return the value for that key.
1731
+ *
1732
+ * @param key Key to get from the metadata
1733
+ * @returns Notebook's metadata.
1734
+ */
1735
+ }, {
1736
+ key: "getMetadata",
1737
+ value: function getMetadata(key) {
1738
+ var meta = this.ymeta.get('metadata');
1739
+ if (typeof key === 'string') {
1740
+ return deepCopy(meta[key]);
1741
+ } else {
1742
+ return deepCopy(meta !== null && meta !== void 0 ? meta : {});
1743
+ }
1744
+ }
1745
+
1746
+ /**
1747
+ * Sets some metadata associated with the notebook.
1748
+ *
1749
+ * If only one argument is provided, it will override all notebook metadata.
1750
+ * Otherwise a single key will be set to a new value.
1751
+ *
1752
+ * @param metadata All Notebook's metadata or the key to set.
1753
+ * @param value New metadata value
1754
+ */
1755
+ }, {
1756
+ key: "setMetadata",
1757
+ value: function setMetadata(metadata, value) {
1758
+ if (typeof metadata === 'string') {
1759
+ if (typeof value === 'undefined') {
1760
+ throw new TypeError("Metadata value for ".concat(metadata, " cannot be 'undefined'; use deleteMetadata."));
1761
+ }
1762
+ var update = {};
1763
+ update[metadata] = value;
1764
+ this.updateMetadata(update);
1765
+ } else {
1766
+ this.ymeta.set('metadata', deepCopy(metadata));
1767
+ }
1768
+ }
1769
+
1770
+ /**
1771
+ * Updates the metadata associated with the notebook.
1772
+ *
1773
+ * @param value: Metadata's attribute to update.
1774
+ */
1775
+ }, {
1776
+ key: "updateMetadata",
1777
+ value: function updateMetadata(value) {
1778
+ // TODO: Maybe modify only attributes instead of replacing the whole metadata?
1779
+ this.ymeta.set('metadata', _objectSpread(_objectSpread({}, this.getMetadata()), value));
1780
+ }
1781
+ }], [{
1782
+ key: "create",
1783
+ value: function create() {
1784
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1785
+ return new YNotebook(options);
1786
+ }
1787
+ }]);
1788
+ return YNotebook;
1789
+ }(YDocument);