@textbus/collaborate 4.0.4 → 4.1.0-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
package/bundles/index.js CHANGED
@@ -114,6 +114,36 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
114
114
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
115
115
  };
116
116
 
117
+ const subModelLoaderErrorFn = core.makeError('subModelLoaderError');
118
+ /**
119
+ * 子文档加载器
120
+ */
121
+ class SubModelLoader {
122
+ }
123
+ exports.NonSubModelLoader = class NonSubModelLoader extends SubModelLoader {
124
+ createSubModelBySlot() {
125
+ throw subModelLoaderErrorFn('single document does not support async slot.');
126
+ }
127
+ createSubModelByComponent() {
128
+ throw subModelLoaderErrorFn('single document does not support async component.');
129
+ }
130
+ loadSubModelByComponent() {
131
+ throw subModelLoaderErrorFn('single document does not support async component.');
132
+ }
133
+ loadSubModelBySlot() {
134
+ throw subModelLoaderErrorFn('single document does not support async slot.');
135
+ }
136
+ getLoadedModelBySlot() {
137
+ throw subModelLoaderErrorFn('single document does not support async slot.');
138
+ }
139
+ getLoadedModelByComponent() {
140
+ throw subModelLoaderErrorFn('single document does not support async component.');
141
+ }
142
+ };
143
+ exports.NonSubModelLoader = __decorate([
144
+ core$1.Injectable()
145
+ ], exports.NonSubModelLoader);
146
+
117
147
  const collaborateErrorFn = core.makeError('Collaborate');
118
148
  class SlotMap {
119
149
  constructor() {
@@ -153,112 +183,41 @@ class SlotMap {
153
183
  }
154
184
  }
155
185
  }
156
- class CustomUndoManagerConfig {
157
- }
158
186
  exports.Collaborate = class Collaborate {
159
- get canBack() {
160
- var _a;
161
- return ((_a = this.manager) === null || _a === void 0 ? void 0 : _a.canUndo()) || false;
162
- }
163
- get canForward() {
164
- var _a;
165
- return ((_a = this.manager) === null || _a === void 0 ? void 0 : _a.canRedo()) || false;
166
- }
167
- constructor(stackSize, rootComponentRef, scheduler, registry, selection, undoManagerConfig) {
168
- this.stackSize = stackSize;
169
- this.rootComponentRef = rootComponentRef;
187
+ constructor(scheduler, registry, selection, subModelLoader) {
170
188
  this.scheduler = scheduler;
171
189
  this.registry = registry;
172
190
  this.selection = selection;
173
- this.undoManagerConfig = undoManagerConfig;
191
+ this.subModelLoader = subModelLoader;
174
192
  this.yDoc = new yjs.Doc();
175
- this.backEvent = new stream.Subject();
176
- this.forwardEvent = new stream.Subject();
177
- this.changeEvent = new stream.Subject();
178
- this.pushEvent = new stream.Subject();
179
- this.manager = null;
193
+ this.slotMap = new SlotMap();
180
194
  this.subscriptions = [];
181
195
  this.updateFromRemote = false;
182
- this.localChangesAppliedEvent = new stream.Subject();
183
- this.selectionChangeEvent = new stream.Subject();
184
- this.slotMap = new SlotMap();
185
- this.updateRemoteActions = [];
196
+ this.addSubModelEvent = new stream.Subject();
197
+ this.updateRemoteActions = new WeakMap();
186
198
  this.noRecord = {};
187
- this.historyItems = [];
188
- this.index = 0;
189
- this.onBack = this.backEvent.asObservable();
190
- this.onForward = this.forwardEvent.asObservable();
191
- this.onChange = this.changeEvent.asObservable();
192
- this.onPush = this.pushEvent.asObservable();
193
- this.onLocalChangesApplied = this.localChangesAppliedEvent.asObservable();
199
+ this.onAddSubModel = this.addSubModelEvent.asObservable();
194
200
  }
195
- listen() {
196
- const root = this.yDoc.getMap('RootComponent');
197
- const rootComponent = this.rootComponentRef.component;
198
- const undoManagerConfig = this.undoManagerConfig || {};
199
- const manager = new yjs.UndoManager(root, {
200
- trackedOrigins: new Set([this.yDoc]),
201
- captureTransaction(arg) {
202
- if (undoManagerConfig.captureTransaction) {
203
- return undoManagerConfig.captureTransaction(arg);
204
- }
205
- return true;
206
- },
207
- deleteFilter(item) {
208
- if (undoManagerConfig.deleteFilter) {
209
- return undoManagerConfig.deleteFilter(item);
210
- }
211
- return true;
212
- }
213
- });
214
- this.manager = manager;
215
- let beforePosition = null;
216
- this.subscriptions.push(this.scheduler.onLocalChangeBefore.subscribe(() => {
217
- beforePosition = this.getRelativeCursorLocation();
218
- }));
219
- manager.on('stack-item-added', (event) => {
220
- if (event.type === 'undo') {
221
- if (event.origin === manager) {
222
- this.index++;
223
- }
224
- else {
225
- this.historyItems.length = this.index;
226
- this.historyItems.push({
227
- before: beforePosition,
228
- after: this.getRelativeCursorLocation()
229
- });
230
- this.index++;
231
- }
232
- }
233
- else {
234
- this.index--;
235
- }
236
- if (manager.undoStack.length > this.stackSize) {
237
- this.historyItems.shift();
238
- manager.undoStack.shift();
239
- }
240
- if (event.origin === this.yDoc) {
241
- this.pushEvent.next();
242
- }
243
- this.changeEvent.next();
244
- });
245
- manager.on('stack-item-popped', (ev) => {
246
- const index = ev.type === 'undo' ? this.index : this.index - 1;
247
- const position = this.historyItems[index] || null;
248
- const p = ev.type === 'undo' ? position === null || position === void 0 ? void 0 : position.before : position === null || position === void 0 ? void 0 : position.after;
249
- if (p) {
250
- const selection = this.getAbstractSelection(p);
251
- if (selection) {
252
- this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
253
- return;
254
- }
255
- }
256
- this.selection.unSelect();
257
- });
258
- this.subscriptions.push(this.selection.onChange.subscribe(() => {
259
- const paths = this.selection.getPaths();
260
- this.selectionChangeEvent.next(paths);
261
- }), this.scheduler.onDocChanged.pipe(stream.map(item => {
201
+ syncRootComponent(yDoc, sharedComponent, localComponent) {
202
+ this.initSyncEvent(yDoc);
203
+ this.syncComponent(yDoc, sharedComponent, localComponent);
204
+ }
205
+ syncRootSlot(yDoc, sharedSlot, localSlot) {
206
+ if (sharedSlot.length) {
207
+ localSlot.retain(0);
208
+ localSlot.delete(localSlot.length);
209
+ localSlot.cleanAttributes();
210
+ localSlot.cleanFormats();
211
+ this.initLocalSlotBySharedSlot(sharedSlot, localSlot);
212
+ }
213
+ else {
214
+ this.initSharedSlotByLocalSlot(sharedSlot, localSlot);
215
+ }
216
+ this.initSyncEvent(yDoc);
217
+ this.syncSlot(sharedSlot, localSlot);
218
+ }
219
+ initSyncEvent(yDoc) {
220
+ this.subscriptions.push(this.scheduler.onDocChanged.pipe(stream.map(item => {
262
221
  return item.filter(i => {
263
222
  return i.from !== core.ChangeOrigin.Remote;
264
223
  });
@@ -267,7 +226,8 @@ exports.Collaborate = class Collaborate {
267
226
  })).subscribe(() => {
268
227
  const updates = [];
269
228
  let update = null;
270
- for (const item of this.updateRemoteActions) {
229
+ const updateRemoteActions = this.updateRemoteActions.get(yDoc) || [];
230
+ for (const item of updateRemoteActions) {
271
231
  if (!update) {
272
232
  update = {
273
233
  record: item.record,
@@ -286,240 +246,54 @@ exports.Collaborate = class Collaborate {
286
246
  updates.push(update);
287
247
  }
288
248
  }
289
- this.updateRemoteActions = [];
249
+ this.updateRemoteActions.delete(yDoc);
290
250
  for (const item of updates) {
291
- this.yDoc.transact(() => {
251
+ yDoc.transact(() => {
292
252
  item.actions.forEach(fn => {
293
253
  fn();
294
254
  });
295
- }, item.record ? this.yDoc : this.noRecord);
255
+ }, item.record ? yDoc : this.noRecord);
296
256
  }
297
- this.localChangesAppliedEvent.next();
298
257
  }));
299
- this.syncRootComponent(root, rootComponent);
300
- }
301
- back() {
302
- var _a;
303
- if (this.canBack) {
304
- (_a = this.manager) === null || _a === void 0 ? void 0 : _a.undo();
305
- this.backEvent.next();
306
- }
307
- }
308
- forward() {
309
- var _a;
310
- if (this.canForward) {
311
- (_a = this.manager) === null || _a === void 0 ? void 0 : _a.redo();
312
- this.forwardEvent.next();
313
- }
314
- }
315
- clear() {
316
- var _a;
317
- const last = this.historyItems.pop();
318
- this.historyItems = last ? [last] : [];
319
- this.index = last ? 1 : 0;
320
- (_a = this.manager) === null || _a === void 0 ? void 0 : _a.clear();
321
- this.changeEvent.next();
322
- }
323
- destroy() {
324
- var _a;
325
- this.index = 0;
326
- this.historyItems = [];
327
- this.subscriptions.forEach(i => i.unsubscribe());
328
- (_a = this.manager) === null || _a === void 0 ? void 0 : _a.destroy();
329
258
  }
330
- syncRootComponent(root, rootComponent) {
331
- let state = root.get('state');
259
+ syncComponent(yDoc, sharedComponent, localComponent) {
260
+ let state = sharedComponent.get('state');
332
261
  if (!state) {
333
262
  state = new yjs.Map();
334
- this.syncLocalMapToSharedMap(rootComponent.state, state);
335
- this.yDoc.transact(() => {
336
- root.set('state', state);
263
+ this.syncLocalMapToSharedMap(localComponent.state, state);
264
+ yDoc.transact(() => {
265
+ sharedComponent.set('state', state);
337
266
  });
338
267
  }
339
268
  else {
340
- Object.keys(rootComponent.state).forEach(key => {
341
- Reflect.deleteProperty(rootComponent.state, key);
269
+ Object.keys(localComponent.state).forEach(key => {
270
+ Reflect.deleteProperty(localComponent.state, key);
342
271
  });
343
- this.syncSharedMapToLocalMap(state, rootComponent.state);
272
+ this.syncSharedMapToLocalMap(state, localComponent.state);
344
273
  }
345
274
  }
346
- syncSharedMapToLocalMap(sharedMap, localMap) {
347
- sharedMap.forEach((value, key) => {
348
- localMap[key] = this.createLocalModelBySharedByModel(value);
349
- });
350
- this.syncObject(sharedMap, localMap);
351
- }
352
- createLocalMapBySharedMap(sharedMap) {
353
- const localMap = core.createObjectProxy({});
354
- this.syncSharedMapToLocalMap(sharedMap, localMap);
355
- return localMap;
356
- }
357
- createLocalArrayBySharedArray(sharedArray) {
358
- const localArray = core.createArrayProxy([]);
359
- localArray.push(...sharedArray.map(item => this.createLocalModelBySharedByModel(item)));
360
- this.syncArray(sharedArray, localArray);
361
- return localArray;
362
- }
363
- syncLocalMapToSharedMap(localMap, sharedMap) {
364
- Object.entries(localMap).forEach(([key, value]) => {
365
- sharedMap.set(key, this.createSharedModelByLocalModel(value));
366
- });
367
- this.syncObject(sharedMap, localMap);
368
- }
369
- createSharedMapByLocalMap(localMap) {
370
- const sharedMap = new yjs.Map();
371
- this.syncLocalMapToSharedMap(localMap, sharedMap);
372
- return sharedMap;
373
- }
374
- createSharedArrayByLocalArray(localArray) {
375
- const sharedArray = new yjs.Array();
376
- localArray.forEach(value => {
377
- sharedArray.push([this.createSharedModelByLocalModel(value)]);
378
- });
379
- this.syncArray(sharedArray, localArray);
380
- return sharedArray;
381
- }
382
- createSharedSlotByLocalSlot(localSlot) {
383
- const sharedSlot = new yjs.Text();
384
- sharedSlot.setAttribute('__schema__', [...localSlot.schema]);
385
- let offset = 0;
386
- localSlot.toDelta().forEach(i => {
387
- let formats = {};
388
- if (i.formats) {
389
- i.formats.forEach(item => {
390
- formats[item[0].name] = item[1];
391
- });
392
- }
393
- else {
394
- formats = null;
395
- }
396
- if (typeof i.insert === 'string') {
397
- sharedSlot.insert(offset, i.insert, formats);
398
- }
399
- else {
400
- const sharedComponent = this.createSharedComponentByLocalComponent(i.insert);
401
- sharedSlot.insertEmbed(offset, sharedComponent, formats);
402
- }
403
- offset += i.insert.length;
404
- });
405
- localSlot.getAttributes().forEach(item => {
406
- sharedSlot.setAttribute(item[0].name, item[1]);
407
- });
408
- this.syncSlot(sharedSlot, localSlot);
409
- return sharedSlot;
410
- }
411
- createLocalSlotBySharedSlot(sharedSlot) {
412
- const delta = sharedSlot.toDelta();
413
- const localSlot = new core.Slot(sharedSlot.getAttribute('__schema__') || []); // TODO 这里有潜在的问题
414
- const attrs = sharedSlot.getAttributes();
415
- Object.keys(attrs).forEach(key => {
416
- const attribute = this.registry.getAttribute(key);
417
- if (attribute) {
418
- localSlot.setAttribute(attribute, attrs[key]);
419
- }
420
- });
421
- for (const action of delta) {
422
- if (action.insert) {
423
- if (typeof action.insert === 'string') {
424
- const formats = remoteFormatsToLocal(this.registry, action.attributes);
425
- localSlot.insert(action.insert, formats);
426
- }
427
- else {
428
- const sharedComponent = action.insert;
429
- const component = this.createLocalComponentBySharedComponent(sharedComponent);
430
- localSlot.insert(component, remoteFormatsToLocal(this.registry, action.attributes));
431
- }
432
- }
433
- else {
434
- throw collaborateErrorFn('unexpected delta action.');
435
- }
436
- }
437
- this.syncSlot(sharedSlot, localSlot);
438
- return localSlot;
439
- }
440
- createSharedModelByLocalModel(localModel) {
441
- if (localModel instanceof core.Slot) {
442
- return this.createSharedSlotByLocalSlot(localModel);
443
- }
444
- if (Array.isArray(localModel)) {
445
- return this.createSharedArrayByLocalArray(localModel);
446
- }
447
- if (typeof localModel === 'object' && localModel !== null) {
448
- return this.createSharedMapByLocalMap(localModel);
449
- }
450
- return localModel;
451
- }
452
- createLocalModelBySharedByModel(sharedModel) {
453
- if (sharedModel instanceof yjs.Map) {
454
- return this.createLocalMapBySharedMap(sharedModel);
455
- }
456
- if (sharedModel instanceof yjs.Array) {
457
- return this.createLocalArrayBySharedArray(sharedModel);
458
- }
459
- if (sharedModel instanceof yjs.Text) {
460
- return this.createLocalSlotBySharedSlot(sharedModel);
461
- }
462
- return sharedModel;
463
- }
464
- getAbstractSelection(position) {
465
- const anchorPosition = yjs.createAbsolutePositionFromRelativePosition(position.anchor, this.yDoc);
466
- const focusPosition = yjs.createAbsolutePositionFromRelativePosition(position.focus, this.yDoc);
467
- if (anchorPosition && focusPosition) {
468
- const focusSlot = this.slotMap.get(focusPosition.type);
469
- const anchorSlot = this.slotMap.get(anchorPosition.type);
470
- if (focusSlot && anchorSlot) {
471
- return {
472
- anchorSlot,
473
- anchorOffset: anchorPosition.index,
474
- focusSlot,
475
- focusOffset: focusPosition.index
476
- };
477
- }
478
- }
479
- return null;
480
- }
481
- getRelativeCursorLocation() {
482
- const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
483
- if (anchorSlot) {
484
- const anchorYText = this.slotMap.get(anchorSlot);
485
- if (anchorYText) {
486
- const anchorPosition = yjs.createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
487
- if (focusSlot) {
488
- const focusYText = this.slotMap.get(focusSlot);
489
- if (focusYText) {
490
- const focusPosition = yjs.createRelativePositionFromTypeIndex(focusYText, focusOffset);
491
- return {
492
- focus: focusPosition,
493
- anchor: anchorPosition
494
- };
495
- }
496
- }
497
- }
498
- }
499
- return null;
500
- }
501
- syncSlot(sharedSlot, localSlot) {
502
- const syncRemote = (ev, tr) => {
503
- this.runRemoteUpdate(tr, () => {
504
- localSlot.retain(0);
505
- ev.keysChanged.forEach(key => {
506
- const change = ev.keys.get(key);
507
- if (!change) {
508
- return;
509
- }
510
- const updateType = change.action;
511
- if (updateType === 'update' || updateType === 'add') {
512
- const attribute = this.registry.getAttribute(key);
513
- if (attribute) {
514
- localSlot.setAttribute(attribute, sharedSlot.getAttribute(key));
515
- }
516
- }
517
- else if (updateType === 'delete') {
518
- const attribute = this.registry.getAttribute(key);
519
- if (attribute) {
520
- localSlot.removeAttribute(attribute);
521
- }
522
- }
275
+ syncSlot(sharedSlot, localSlot) {
276
+ const syncRemote = (ev, tr) => {
277
+ this.runRemoteUpdate(tr, () => {
278
+ localSlot.retain(0);
279
+ ev.keysChanged.forEach(key => {
280
+ const change = ev.keys.get(key);
281
+ if (!change) {
282
+ return;
283
+ }
284
+ const updateType = change.action;
285
+ if (updateType === 'update' || updateType === 'add') {
286
+ const attribute = this.registry.getAttribute(key);
287
+ if (attribute) {
288
+ localSlot.setAttribute(attribute, sharedSlot.getAttribute(key));
289
+ }
290
+ }
291
+ else if (updateType === 'delete') {
292
+ const attribute = this.registry.getAttribute(key);
293
+ if (attribute) {
294
+ localSlot.removeAttribute(attribute);
295
+ }
296
+ }
523
297
  });
524
298
  ev.delta.forEach(action => {
525
299
  if (Reflect.has(action, 'retain')) {
@@ -546,7 +320,7 @@ exports.Collaborate = class Collaborate {
546
320
  const component = this.createLocalComponentBySharedComponent(sharedComponent);
547
321
  localSlot.insert(component);
548
322
  }
549
- if (this.selection.isSelected && tr.origin !== this.manager) {
323
+ if (this.selection.isSelected && !(tr.origin instanceof yjs.UndoManager)) {
550
324
  if (localSlot === this.selection.anchorSlot && this.selection.anchorOffset > index) {
551
325
  this.selection.setAnchor(localSlot, this.selection.anchorOffset + length);
552
326
  }
@@ -558,7 +332,7 @@ exports.Collaborate = class Collaborate {
558
332
  else if (action.delete) {
559
333
  const index = localSlot.index;
560
334
  localSlot.delete(action.delete);
561
- if (this.selection.isSelected && tr.origin !== this.manager) {
335
+ if (this.selection.isSelected && !(tr.origin instanceof yjs.UndoManager)) {
562
336
  if (localSlot === this.selection.anchorSlot && this.selection.anchorOffset >= index) {
563
337
  this.selection.setAnchor(localSlot, this.selection.startOffset - action.delete);
564
338
  }
@@ -572,7 +346,7 @@ exports.Collaborate = class Collaborate {
572
346
  };
573
347
  sharedSlot.observe(syncRemote);
574
348
  const sub = localSlot.onContentChange.subscribe(actions => {
575
- this.runLocalUpdate(() => {
349
+ this.runLocalUpdate(sharedSlot.doc, true, () => {
576
350
  var _a;
577
351
  let offset = 0;
578
352
  let length = 0;
@@ -630,7 +404,7 @@ exports.Collaborate = class Collaborate {
630
404
  sharedSlot.removeAttribute(action.name);
631
405
  }
632
406
  }
633
- }, true);
407
+ });
634
408
  });
635
409
  this.slotMap.set(localSlot, sharedSlot);
636
410
  localSlot.__changeMarker__.destroyCallbacks.push(() => {
@@ -639,18 +413,279 @@ exports.Collaborate = class Collaborate {
639
413
  sub.unsubscribe();
640
414
  });
641
415
  }
416
+ destroy() {
417
+ this.subscriptions.forEach(i => i.unsubscribe());
418
+ }
419
+ syncSharedMapToLocalMap(sharedMap, localMap) {
420
+ sharedMap.forEach((value, key) => {
421
+ localMap[key] = this.createLocalModelBySharedByModel(value);
422
+ });
423
+ this.syncObject(sharedMap, localMap);
424
+ }
425
+ createLocalMapBySharedMap(sharedMap) {
426
+ const localMap = core.createObjectProxy({});
427
+ this.syncSharedMapToLocalMap(sharedMap, localMap);
428
+ return localMap;
429
+ }
430
+ createLocalArrayBySharedArray(sharedArray) {
431
+ const localArray = core.createArrayProxy([]);
432
+ localArray.push(...sharedArray.map(item => this.createLocalModelBySharedByModel(item)));
433
+ this.syncArray(sharedArray, localArray);
434
+ return localArray;
435
+ }
436
+ syncLocalMapToSharedMap(localMap, sharedMap) {
437
+ Object.entries(localMap).forEach(([key, value]) => {
438
+ sharedMap.set(key, this.createSharedModelByLocalModel(value));
439
+ });
440
+ this.syncObject(sharedMap, localMap);
441
+ }
442
+ createSharedMapByLocalMap(localMap) {
443
+ const sharedMap = new yjs.Map();
444
+ this.syncLocalMapToSharedMap(localMap, sharedMap);
445
+ return sharedMap;
446
+ }
447
+ createSharedArrayByLocalArray(localArray) {
448
+ const sharedArray = new yjs.Array();
449
+ localArray.forEach(value => {
450
+ sharedArray.push([this.createSharedModelByLocalModel(value)]);
451
+ });
452
+ this.syncArray(sharedArray, localArray);
453
+ return sharedArray;
454
+ }
455
+ createSharedSlotByLocalSlot(localSlot) {
456
+ const sharedSlot = new yjs.Text();
457
+ const isAsyncSlot = localSlot instanceof core.AsyncSlot;
458
+ sharedSlot.setAttribute('schema', [...localSlot.schema]);
459
+ sharedSlot.setAttribute('type', isAsyncSlot ? 'async' : 'sync');
460
+ if (isAsyncSlot) {
461
+ let isDestroyed = false;
462
+ sharedSlot.setAttribute('metadata', localSlot.metadata);
463
+ this.subModelLoader.createSubModelBySlot(localSlot).then(subDocument => {
464
+ if (isDestroyed) {
465
+ return;
466
+ }
467
+ const content = subDocument.getText('content');
468
+ this.initSharedSlotByLocalSlot(content, localSlot);
469
+ this.syncSlot(content, localSlot);
470
+ this.addSubModelEvent.next({
471
+ yDoc: subDocument,
472
+ yType: content
473
+ });
474
+ localSlot.loader.markAsLoaded();
475
+ });
476
+ localSlot.__changeMarker__.destroyCallbacks.push(() => {
477
+ isDestroyed = true;
478
+ });
479
+ return sharedSlot;
480
+ }
481
+ const sharedContent = new yjs.Text();
482
+ this.initSharedSlotByLocalSlot(sharedContent, localSlot);
483
+ sharedSlot.insertEmbed(0, sharedContent);
484
+ this.syncSlot(sharedContent, localSlot);
485
+ return sharedSlot;
486
+ }
487
+ initSharedSlotByLocalSlot(sharedContent, localSlot) {
488
+ let offset = 0;
489
+ localSlot.toDelta().forEach(i => {
490
+ let formats = {};
491
+ if (i.formats) {
492
+ i.formats.forEach(item => {
493
+ formats[item[0].name] = item[1];
494
+ });
495
+ }
496
+ else {
497
+ formats = null;
498
+ }
499
+ if (typeof i.insert === 'string') {
500
+ sharedContent.insert(offset, i.insert, formats);
501
+ }
502
+ else {
503
+ const sharedComponent = this.createSharedComponentByLocalComponent(i.insert);
504
+ sharedContent.insertEmbed(offset, sharedComponent, formats);
505
+ }
506
+ offset += i.insert.length;
507
+ });
508
+ localSlot.getAttributes().forEach(item => {
509
+ sharedContent.setAttribute(item[0].name, item[1]);
510
+ });
511
+ }
512
+ createLocalSlotBySharedSlot(sharedSlot) {
513
+ var _a;
514
+ const type = sharedSlot.getAttribute('type');
515
+ const schema = sharedSlot.getAttribute('schema');
516
+ if (type === 'async') {
517
+ const metadata = sharedSlot.getAttribute('metadata');
518
+ const slot = new core.AsyncSlot(schema || [], metadata);
519
+ const loadedSubDocument = this.subModelLoader.getLoadedModelBySlot(slot);
520
+ if (loadedSubDocument) {
521
+ const subContent = loadedSubDocument.getText('content');
522
+ this.syncRootSlot(loadedSubDocument, subContent, slot);
523
+ this.addSubModelEvent.next({
524
+ yDoc: loadedSubDocument,
525
+ yType: subContent
526
+ });
527
+ slot.loader.markAsLoaded();
528
+ return slot;
529
+ }
530
+ let isDestroyed = false;
531
+ slot.loader.onRequestLoad.toPromise().then(() => {
532
+ return this.subModelLoader.loadSubModelBySlot(slot);
533
+ }).then(subDocument => {
534
+ if (isDestroyed) {
535
+ return;
536
+ }
537
+ slot.loader.markAsLoaded();
538
+ const subContent = subDocument.getText('content');
539
+ this.syncRootSlot(subDocument, subContent, slot);
540
+ this.addSubModelEvent.next({
541
+ yDoc: subDocument,
542
+ yType: subContent
543
+ });
544
+ });
545
+ slot.__changeMarker__.destroyCallbacks.push(() => {
546
+ isDestroyed = true;
547
+ });
548
+ return slot;
549
+ }
550
+ const contentDelta = sharedSlot.toDelta();
551
+ const content = (_a = contentDelta[0]) === null || _a === void 0 ? void 0 : _a.insert;
552
+ if (!(content instanceof yjs.Text)) {
553
+ throw collaborateErrorFn('shared slot content type is not `YText`.');
554
+ }
555
+ const localSlot = new core.Slot(schema || []);
556
+ this.initLocalSlotBySharedSlot(content, localSlot);
557
+ this.syncSlot(content, localSlot);
558
+ return localSlot;
559
+ }
560
+ initLocalSlotBySharedSlot(content, localSlot) {
561
+ const delta = content.toDelta();
562
+ const attrs = content.getAttributes();
563
+ Object.keys(attrs).forEach(key => {
564
+ const attribute = this.registry.getAttribute(key);
565
+ if (attribute) {
566
+ localSlot.setAttribute(attribute, attrs[key]);
567
+ }
568
+ });
569
+ for (const action of delta) {
570
+ if (action.insert) {
571
+ if (typeof action.insert === 'string') {
572
+ const formats = remoteFormatsToLocal(this.registry, action.attributes);
573
+ localSlot.insert(action.insert, formats);
574
+ }
575
+ else {
576
+ const sharedComponent = action.insert;
577
+ const component = this.createLocalComponentBySharedComponent(sharedComponent);
578
+ localSlot.insert(component, remoteFormatsToLocal(this.registry, action.attributes));
579
+ }
580
+ }
581
+ else {
582
+ throw collaborateErrorFn('unexpected delta action.');
583
+ }
584
+ }
585
+ }
586
+ createSharedModelByLocalModel(localModel) {
587
+ if (localModel instanceof core.Slot) {
588
+ return this.createSharedSlotByLocalSlot(localModel);
589
+ }
590
+ if (Array.isArray(localModel)) {
591
+ return this.createSharedArrayByLocalArray(localModel);
592
+ }
593
+ if (typeof localModel === 'object' && localModel !== null) {
594
+ return this.createSharedMapByLocalMap(localModel);
595
+ }
596
+ return localModel;
597
+ }
598
+ createLocalModelBySharedByModel(sharedModel) {
599
+ if (sharedModel instanceof yjs.Map) {
600
+ return this.createLocalMapBySharedMap(sharedModel);
601
+ }
602
+ if (sharedModel instanceof yjs.Array) {
603
+ return this.createLocalArrayBySharedArray(sharedModel);
604
+ }
605
+ if (sharedModel instanceof yjs.Text) {
606
+ return this.createLocalSlotBySharedSlot(sharedModel);
607
+ }
608
+ return sharedModel;
609
+ }
642
610
  createSharedComponentByLocalComponent(component) {
643
611
  const sharedComponent = new yjs.Map();
644
- const sharedState = this.createSharedMapByLocalMap(component.state);
645
612
  sharedComponent.set('name', component.name);
613
+ if (component instanceof core.AsyncComponent) {
614
+ sharedComponent.set('type', 'async');
615
+ sharedComponent.set('metadata', component.getMetadata());
616
+ const state = component.state;
617
+ let isDestroyed = false;
618
+ state.__changeMarker__.destroyCallbacks.push(() => {
619
+ isDestroyed = true;
620
+ });
621
+ this.subModelLoader.createSubModelByComponent(component).then(subDocument => {
622
+ if (isDestroyed) {
623
+ return;
624
+ }
625
+ const state = subDocument.getMap('state');
626
+ this.syncComponent(subDocument, state, component);
627
+ this.addSubModelEvent.next({
628
+ yType: state,
629
+ yDoc: subDocument
630
+ });
631
+ component.loader.markAsLoaded();
632
+ });
633
+ return sharedComponent;
634
+ }
635
+ const sharedState = this.createSharedMapByLocalMap(component.state);
646
636
  sharedComponent.set('state', sharedState);
637
+ sharedComponent.set('type', 'sync');
647
638
  return sharedComponent;
648
639
  }
649
640
  createLocalComponentBySharedComponent(yMap) {
650
641
  const componentName = yMap.get('name');
651
- const sharedState = yMap.get('state');
652
- const state = this.createLocalMapBySharedMap(sharedState);
653
- const instance = this.registry.createComponentByData(componentName, state);
642
+ const type = yMap.get('type');
643
+ let instance;
644
+ if (type === 'async') {
645
+ instance = this.registry.createComponentByData(componentName, {});
646
+ if (instance instanceof core.AsyncComponent) {
647
+ instance.setMetadata(yMap.get('metadata'));
648
+ const loadedSubDocument = this.subModelLoader.getLoadedModelByComponent(instance);
649
+ if (loadedSubDocument) {
650
+ const state = loadedSubDocument.getMap('state');
651
+ this.syncComponent(loadedSubDocument, state, instance);
652
+ this.addSubModelEvent.next({
653
+ yType: state,
654
+ yDoc: loadedSubDocument
655
+ });
656
+ instance.loader.markAsLoaded();
657
+ return instance;
658
+ }
659
+ const state = instance.state;
660
+ let isDestroyed = false;
661
+ instance.loader.onRequestLoad.toPromise().then(() => {
662
+ return this.subModelLoader.loadSubModelByComponent(instance);
663
+ })
664
+ .then(subDocument => {
665
+ if (isDestroyed) {
666
+ return;
667
+ }
668
+ instance.loader.markAsLoaded();
669
+ const state = subDocument.getMap('state');
670
+ this.syncComponent(subDocument, state, instance);
671
+ this.addSubModelEvent.next({
672
+ yType: state,
673
+ yDoc: subDocument
674
+ });
675
+ });
676
+ state.__changeMarker__.destroyCallbacks.push(() => {
677
+ isDestroyed = true;
678
+ });
679
+ }
680
+ else if (instance instanceof core.Component) {
681
+ throw collaborateErrorFn(`component name \`${componentName}\` is not a async component.`);
682
+ }
683
+ }
684
+ else {
685
+ const sharedState = yMap.get('state');
686
+ const state = this.createLocalMapBySharedMap(sharedState);
687
+ instance = this.registry.createComponentByData(componentName, state);
688
+ }
654
689
  if (instance) {
655
690
  return instance;
656
691
  }
@@ -664,7 +699,7 @@ exports.Collaborate = class Collaborate {
664
699
  */
665
700
  syncArray(sharedArray, localArray) {
666
701
  const sub = localArray.__changeMarker__.onSelfChange.subscribe((actions) => {
667
- this.runLocalUpdate(() => {
702
+ this.runLocalUpdate(sharedArray.doc, !localArray.__changeMarker__.irrevocableUpdate, () => {
668
703
  let index = 0;
669
704
  for (const action of actions) {
670
705
  switch (action.type) {
@@ -695,7 +730,7 @@ exports.Collaborate = class Collaborate {
695
730
  break;
696
731
  }
697
732
  }
698
- }, !localArray.__changeMarker__.irrevocableUpdate);
733
+ });
699
734
  });
700
735
  const syncRemote = (ev, tr) => {
701
736
  this.runRemoteUpdate(tr, () => {
@@ -745,7 +780,7 @@ exports.Collaborate = class Collaborate {
745
780
  };
746
781
  sharedObject.observe(syncRemote);
747
782
  const sub = localObject.__changeMarker__.onSelfChange.subscribe((actions) => {
748
- this.runLocalUpdate(() => {
783
+ this.runLocalUpdate(sharedObject.doc, !localObject.__changeMarker__.irrevocableUpdate, () => {
749
784
  for (const action of actions) {
750
785
  switch (action.type) {
751
786
  case 'propSet':
@@ -756,28 +791,33 @@ exports.Collaborate = class Collaborate {
756
791
  break;
757
792
  }
758
793
  }
759
- }, !localObject.__changeMarker__.irrevocableUpdate);
794
+ });
760
795
  });
761
796
  localObject.__changeMarker__.destroyCallbacks.push(function () {
762
797
  sharedObject.unobserve(syncRemote);
763
798
  sub.unsubscribe();
764
799
  });
765
800
  }
766
- runLocalUpdate(fn, record) {
767
- if (this.updateFromRemote) {
801
+ runLocalUpdate(yDoc, record, fn) {
802
+ if (this.updateFromRemote || !yDoc) {
768
803
  return;
769
804
  }
770
- this.updateRemoteActions.push({
805
+ let changeList = this.updateRemoteActions.get(yDoc);
806
+ if (!changeList) {
807
+ changeList = [];
808
+ this.updateRemoteActions.set(yDoc, changeList);
809
+ }
810
+ changeList.push({
771
811
  record,
772
812
  action: fn
773
813
  });
774
814
  }
775
815
  runRemoteUpdate(tr, fn) {
776
- if (tr.origin === this.yDoc) {
816
+ if (tr.origin === tr.doc) {
777
817
  return;
778
818
  }
779
819
  this.updateFromRemote = true;
780
- if (tr.origin === this.manager) {
820
+ if (tr.origin instanceof yjs.UndoManager) {
781
821
  this.scheduler.historyApplyTransact(fn);
782
822
  }
783
823
  else {
@@ -788,13 +828,10 @@ exports.Collaborate = class Collaborate {
788
828
  };
789
829
  exports.Collaborate = __decorate([
790
830
  core$1.Injectable(),
791
- __param(0, core$1.Inject(core.HISTORY_STACK_SIZE)),
792
- __param(5, core$1.Optional()),
793
- __metadata("design:paramtypes", [Number, core.RootComponentRef,
794
- core.Scheduler,
831
+ __metadata("design:paramtypes", [core.Scheduler,
795
832
  core.Registry,
796
833
  core.Selection,
797
- CustomUndoManagerConfig])
834
+ SubModelLoader])
798
835
  ], exports.Collaborate);
799
836
  function remoteFormatsToLocal(registry, attrs) {
800
837
  const formats = [];
@@ -809,6 +846,182 @@ function remoteFormatsToLocal(registry, attrs) {
809
846
  return formats;
810
847
  }
811
848
 
849
+ class CustomUndoManagerConfig {
850
+ }
851
+ const collabHistoryErrorFn = core.makeError('CollabHistory');
852
+ exports.CollabHistory = class CollabHistory {
853
+ get canBack() {
854
+ var _a;
855
+ return ((_a = this.manager) === null || _a === void 0 ? void 0 : _a.canUndo()) || false;
856
+ }
857
+ get canForward() {
858
+ var _a;
859
+ return ((_a = this.manager) === null || _a === void 0 ? void 0 : _a.canRedo()) || false;
860
+ }
861
+ constructor(rootComponentRef, collaborate, scheduler, selection, stackSize, undoManagerConfig) {
862
+ this.rootComponentRef = rootComponentRef;
863
+ this.collaborate = collaborate;
864
+ this.scheduler = scheduler;
865
+ this.selection = selection;
866
+ this.stackSize = stackSize;
867
+ this.undoManagerConfig = undoManagerConfig;
868
+ this.manager = null;
869
+ this.historyItems = [];
870
+ this.index = 0;
871
+ this.subscriptions = [];
872
+ this.backEvent = new stream.Subject();
873
+ this.forwardEvent = new stream.Subject();
874
+ this.changeEvent = new stream.Subject();
875
+ this.pushEvent = new stream.Subject();
876
+ this.onBack = this.backEvent.asObservable();
877
+ this.onForward = this.forwardEvent.asObservable();
878
+ this.onChange = this.changeEvent.asObservable();
879
+ this.onPush = this.pushEvent.asObservable();
880
+ }
881
+ listen() {
882
+ const root = this.collaborate.yDoc.getMap('RootComponent');
883
+ const rootComponent = this.rootComponentRef.component;
884
+ this.collaborate.syncRootComponent(this.collaborate.yDoc, root, rootComponent);
885
+ const undoManagerConfig = this.undoManagerConfig || {};
886
+ const manager = new yjs.UndoManager(root, {
887
+ trackedOrigins: new Set([this.collaborate.yDoc]),
888
+ captureTransaction(arg) {
889
+ if (undoManagerConfig.captureTransaction) {
890
+ return undoManagerConfig.captureTransaction(arg);
891
+ }
892
+ return true;
893
+ },
894
+ deleteFilter(item) {
895
+ if (undoManagerConfig.deleteFilter) {
896
+ return undoManagerConfig.deleteFilter(item);
897
+ }
898
+ return true;
899
+ }
900
+ });
901
+ this.manager = manager;
902
+ let beforePosition = null;
903
+ this.subscriptions.push(this.scheduler.onLocalChangeBefore.subscribe(() => {
904
+ beforePosition = this.getRelativeCursorLocation();
905
+ }), this.collaborate.onAddSubModel.subscribe(() => {
906
+ throw collabHistoryErrorFn('single document does not support submodels.');
907
+ }));
908
+ manager.on('stack-item-added', (event) => {
909
+ if (event.type === 'undo') {
910
+ if (event.origin === manager) {
911
+ this.index++;
912
+ }
913
+ else {
914
+ this.historyItems.length = this.index;
915
+ this.historyItems.push({
916
+ before: beforePosition,
917
+ after: this.getRelativeCursorLocation()
918
+ });
919
+ this.index++;
920
+ }
921
+ }
922
+ else {
923
+ this.index--;
924
+ }
925
+ if (manager.undoStack.length > this.stackSize) {
926
+ this.historyItems.shift();
927
+ manager.undoStack.shift();
928
+ }
929
+ if (event.origin === this.collaborate.yDoc) {
930
+ this.pushEvent.next();
931
+ }
932
+ this.changeEvent.next();
933
+ });
934
+ manager.on('stack-item-popped', (ev) => {
935
+ const index = ev.type === 'undo' ? this.index : this.index - 1;
936
+ const position = this.historyItems[index] || null;
937
+ const p = ev.type === 'undo' ? position === null || position === void 0 ? void 0 : position.before : position === null || position === void 0 ? void 0 : position.after;
938
+ if (p) {
939
+ const selection = this.getAbstractSelection(p);
940
+ if (selection) {
941
+ this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
942
+ return;
943
+ }
944
+ }
945
+ this.selection.unSelect();
946
+ });
947
+ }
948
+ back() {
949
+ var _a;
950
+ if (this.canBack) {
951
+ (_a = this.manager) === null || _a === void 0 ? void 0 : _a.undo();
952
+ this.backEvent.next();
953
+ }
954
+ }
955
+ forward() {
956
+ var _a;
957
+ if (this.canForward) {
958
+ (_a = this.manager) === null || _a === void 0 ? void 0 : _a.redo();
959
+ this.forwardEvent.next();
960
+ }
961
+ }
962
+ clear() {
963
+ var _a;
964
+ const last = this.historyItems.pop();
965
+ this.historyItems = last ? [last] : [];
966
+ this.index = last ? 1 : 0;
967
+ (_a = this.manager) === null || _a === void 0 ? void 0 : _a.clear();
968
+ this.changeEvent.next();
969
+ }
970
+ destroy() {
971
+ var _a;
972
+ this.index = 0;
973
+ this.historyItems = [];
974
+ this.subscriptions.forEach(i => i.unsubscribe());
975
+ (_a = this.manager) === null || _a === void 0 ? void 0 : _a.destroy();
976
+ }
977
+ getAbstractSelection(position) {
978
+ const anchorPosition = yjs.createAbsolutePositionFromRelativePosition(position.anchor, this.collaborate.yDoc);
979
+ const focusPosition = yjs.createAbsolutePositionFromRelativePosition(position.focus, this.collaborate.yDoc);
980
+ if (anchorPosition && focusPosition) {
981
+ const focusSlot = this.collaborate.slotMap.get(focusPosition.type);
982
+ const anchorSlot = this.collaborate.slotMap.get(anchorPosition.type);
983
+ if (focusSlot && anchorSlot) {
984
+ return {
985
+ anchorSlot,
986
+ anchorOffset: anchorPosition.index,
987
+ focusSlot,
988
+ focusOffset: focusPosition.index
989
+ };
990
+ }
991
+ }
992
+ return null;
993
+ }
994
+ getRelativeCursorLocation() {
995
+ const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
996
+ if (anchorSlot) {
997
+ const anchorYText = this.collaborate.slotMap.get(anchorSlot);
998
+ if (anchorYText) {
999
+ const anchorPosition = yjs.createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
1000
+ if (focusSlot) {
1001
+ const focusYText = this.collaborate.slotMap.get(focusSlot);
1002
+ if (focusYText) {
1003
+ const focusPosition = yjs.createRelativePositionFromTypeIndex(focusYText, focusOffset);
1004
+ return {
1005
+ focus: focusPosition,
1006
+ anchor: anchorPosition
1007
+ };
1008
+ }
1009
+ }
1010
+ }
1011
+ }
1012
+ return null;
1013
+ }
1014
+ };
1015
+ exports.CollabHistory = __decorate([
1016
+ core$1.Injectable(),
1017
+ __param(4, core$1.Inject(core.HISTORY_STACK_SIZE)),
1018
+ __param(5, core$1.Optional()),
1019
+ __metadata("design:paramtypes", [core.RootComponentRef,
1020
+ exports.Collaborate,
1021
+ core.Scheduler,
1022
+ core.Selection, Number, CustomUndoManagerConfig])
1023
+ ], exports.CollabHistory);
1024
+
812
1025
  exports.UserActivity = class UserActivity {
813
1026
  constructor(syncConnector, selection) {
814
1027
  this.syncConnector = syncConnector;
@@ -857,15 +1070,219 @@ class CollaborateModule {
857
1070
  this.providers = [
858
1071
  exports.Collaborate,
859
1072
  exports.UserActivity,
1073
+ exports.CollabHistory,
1074
+ {
1075
+ provide: core.History,
1076
+ useExisting: exports.CollabHistory
1077
+ }, {
1078
+ provide: SyncConnector,
1079
+ useFactory: (collab) => {
1080
+ return this.config.createConnector(collab.yDoc);
1081
+ },
1082
+ deps: [exports.Collaborate]
1083
+ }, {
1084
+ provide: SubModelLoader,
1085
+ useClass: exports.NonSubModelLoader
1086
+ }
1087
+ ];
1088
+ }
1089
+ setup(textbus) {
1090
+ const connector = textbus.get(SyncConnector);
1091
+ const userActivity = textbus.get(exports.UserActivity);
1092
+ userActivity.init(this.config.userinfo);
1093
+ return connector.onLoad.toPromise();
1094
+ }
1095
+ onDestroy(textbus) {
1096
+ textbus.get(exports.Collaborate).destroy();
1097
+ textbus.get(core.History).destroy();
1098
+ textbus.get(exports.UserActivity).destroy();
1099
+ textbus.get(SyncConnector).onDestroy();
1100
+ }
1101
+ }
1102
+
1103
+ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
1104
+ get canBack() {
1105
+ return this.actionStack.length > 0 && this.index > 0;
1106
+ }
1107
+ get canForward() {
1108
+ return this.actionStack.length > 0 && this.index < this.actionStack.length;
1109
+ }
1110
+ constructor(collaborate, rootComponentRef, stackSize, undoManagerConfig) {
1111
+ this.collaborate = collaborate;
1112
+ this.rootComponentRef = rootComponentRef;
1113
+ this.stackSize = stackSize;
1114
+ this.undoManagerConfig = undoManagerConfig;
1115
+ this.isListen = false;
1116
+ this.changeEvent = new stream.Subject();
1117
+ this.backEvent = new stream.Subject();
1118
+ this.forwardEvent = new stream.Subject();
1119
+ this.pushEvent = new stream.Subject();
1120
+ this.actionStack = [];
1121
+ this.index = 0;
1122
+ this.stackItem = null;
1123
+ this.timer = null;
1124
+ this.subscription = new stream.Subscription();
1125
+ this.subDocs = new Set();
1126
+ this.listenerCaches = new Set();
1127
+ this.onChange = this.changeEvent.asObservable();
1128
+ this.onBack = this.backEvent.asObservable();
1129
+ this.onForward = this.forwardEvent.asObservable();
1130
+ this.onPush = this.pushEvent.asObservable();
1131
+ }
1132
+ listen() {
1133
+ this.isListen = true;
1134
+ const root = this.collaborate.yDoc.getMap('RootComponent');
1135
+ const rootComponent = this.rootComponentRef.component;
1136
+ this.collaborate.syncRootComponent(this.collaborate.yDoc, root, rootComponent);
1137
+ this.listenItem(root, this.collaborate.yDoc);
1138
+ this.subscription.add(this.collaborate.onAddSubModel.subscribe(({ yType, yDoc }) => {
1139
+ if (this.subDocs.has(yType)) {
1140
+ return;
1141
+ }
1142
+ this.subDocs.add(yType);
1143
+ if (this.isListen) {
1144
+ this.listenItem(yType, yDoc);
1145
+ }
1146
+ }));
1147
+ }
1148
+ forward() {
1149
+ if (!this.canForward) {
1150
+ return;
1151
+ }
1152
+ clearTimeout(this.timer);
1153
+ const item = this.actionStack[this.index];
1154
+ if (item) {
1155
+ for (const i of item) {
1156
+ i.redo();
1157
+ }
1158
+ }
1159
+ this.index++;
1160
+ this.forwardEvent.next();
1161
+ this.changeEvent.next();
1162
+ }
1163
+ back() {
1164
+ if (!this.canBack) {
1165
+ return;
1166
+ }
1167
+ clearTimeout(this.timer);
1168
+ let actions;
1169
+ if (this.stackItem) {
1170
+ actions = this.stackItem;
1171
+ this.stackItem = null;
1172
+ }
1173
+ else {
1174
+ this.index--;
1175
+ actions = this.actionStack[this.index];
1176
+ }
1177
+ let len = actions.length;
1178
+ while (len > 0) {
1179
+ len--;
1180
+ actions[len].undo();
1181
+ }
1182
+ if (actions) {
1183
+ this.backEvent.next();
1184
+ this.changeEvent.next();
1185
+ }
1186
+ }
1187
+ clear() {
1188
+ this.actionStack = [];
1189
+ this.stackItem = [];
1190
+ this.index = 0;
1191
+ clearTimeout(this.timer);
1192
+ this.listenerCaches.forEach((undoManager) => {
1193
+ undoManager.clear();
1194
+ });
1195
+ this.changeEvent.next();
1196
+ }
1197
+ destroy() {
1198
+ this.clear();
1199
+ this.subscription.unsubscribe();
1200
+ this.listenerCaches.forEach((undoManager) => {
1201
+ undoManager.destroy();
1202
+ });
1203
+ this.subDocs.clear();
1204
+ this.listenerCaches.clear();
1205
+ }
1206
+ listenItem(yType, yDoc) {
1207
+ const undoManagerConfig = this.undoManagerConfig || {};
1208
+ const undoManager = new yjs.UndoManager(yType, {
1209
+ trackedOrigins: new Set([yDoc]),
1210
+ captureTimeout: 0,
1211
+ captureTransaction(arg) {
1212
+ if (undoManagerConfig.captureTransaction) {
1213
+ return undoManagerConfig.captureTransaction(arg);
1214
+ }
1215
+ return true;
1216
+ },
1217
+ deleteFilter(item) {
1218
+ if (undoManagerConfig.deleteFilter) {
1219
+ return undoManagerConfig.deleteFilter(item);
1220
+ }
1221
+ return true;
1222
+ }
1223
+ });
1224
+ undoManager.on('stack-item-added', (event) => {
1225
+ if (event.type === 'undo' && !(event.origin instanceof yjs.UndoManager)) {
1226
+ if (this.index != this.actionStack.length) {
1227
+ const redoStack = this.actionStack.slice(this.index);
1228
+ redoStack.forEach(item => {
1229
+ item.forEach(i => {
1230
+ i.clear(false, true);
1231
+ });
1232
+ });
1233
+ this.actionStack.length = this.index;
1234
+ this.changeEvent.next();
1235
+ }
1236
+ if (this.stackItem === null) {
1237
+ this.stackItem = [];
1238
+ this.timer = setTimeout(() => {
1239
+ if (this.actionStack.length >= this.stackSize) {
1240
+ this.actionStack.shift();
1241
+ }
1242
+ else {
1243
+ this.index++;
1244
+ }
1245
+ this.actionStack.push(this.stackItem);
1246
+ this.stackItem = null;
1247
+ this.pushEvent.next();
1248
+ this.changeEvent.next();
1249
+ }, 500);
1250
+ }
1251
+ this.stackItem.push(undoManager);
1252
+ }
1253
+ });
1254
+ this.listenerCaches.add(undoManager);
1255
+ }
1256
+ };
1257
+ exports.MultipleDocCollabHistory = __decorate([
1258
+ core$1.Injectable(),
1259
+ __param(2, core$1.Inject(core.HISTORY_STACK_SIZE)),
1260
+ __param(3, core$1.Optional()),
1261
+ __metadata("design:paramtypes", [exports.Collaborate,
1262
+ core.RootComponentRef, Number, CustomUndoManagerConfig])
1263
+ ], exports.MultipleDocCollabHistory);
1264
+
1265
+ class MultipleDocumentCollaborateModule {
1266
+ constructor(config) {
1267
+ this.config = config;
1268
+ this.providers = [
1269
+ exports.Collaborate,
1270
+ exports.UserActivity,
1271
+ exports.MultipleDocCollabHistory,
860
1272
  {
861
1273
  provide: core.History,
862
- useExisting: exports.Collaborate
1274
+ useExisting: exports.MultipleDocCollabHistory
863
1275
  }, {
864
1276
  provide: SyncConnector,
865
1277
  useFactory: (collab) => {
866
1278
  return this.config.createConnector(collab.yDoc);
867
1279
  },
868
1280
  deps: [exports.Collaborate]
1281
+ }, {
1282
+ provide: SubModelLoader,
1283
+ useFactory: () => {
1284
+ return this.config.subModelLoader;
1285
+ }
869
1286
  }
870
1287
  ];
871
1288
  }
@@ -876,6 +1293,8 @@ class CollaborateModule {
876
1293
  return connector.onLoad.toPromise();
877
1294
  }
878
1295
  onDestroy(textbus) {
1296
+ textbus.get(exports.Collaborate).destroy();
1297
+ textbus.get(core.History).destroy();
879
1298
  textbus.get(exports.UserActivity).destroy();
880
1299
  textbus.get(SyncConnector).onDestroy();
881
1300
  }
@@ -884,5 +1303,7 @@ class CollaborateModule {
884
1303
  exports.CollaborateModule = CollaborateModule;
885
1304
  exports.CustomUndoManagerConfig = CustomUndoManagerConfig;
886
1305
  exports.HocuspocusConnector = HocuspocusConnector;
1306
+ exports.MultipleDocumentCollaborateModule = MultipleDocumentCollaborateModule;
1307
+ exports.SubModelLoader = SubModelLoader;
887
1308
  exports.SyncConnector = SyncConnector;
888
1309
  exports.YWebsocketConnector = YWebsocketConnector;