@textbus/collaborate 5.1.6 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,1790 +0,0 @@
1
- import { Injectable, Inject, Optional } from '@viewfly/core';
2
- import { makeError, ChangeOrigin, Slot, observe, AsyncSlot, AsyncComponent, Component, Scheduler, Registry, Selection, HISTORY_STACK_SIZE, RootComponentRef, History } from '@textbus/core';
3
- import { Subject, map, filter, Subscription } from '@tanbo/stream';
4
- import { Doc, createAbsolutePositionFromRelativePosition, createRelativePositionFromTypeIndex, Map, Array as Array$1, Text, UndoManager } from 'yjs';
5
- import { HocuspocusProvider } from '@hocuspocus/provider';
6
- import { WebsocketProvider } from 'y-websocket';
7
-
8
- /******************************************************************************
9
- Copyright (c) Microsoft Corporation.
10
-
11
- Permission to use, copy, modify, and/or distribute this software for any
12
- purpose with or without fee is hereby granted.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
15
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
16
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
17
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
18
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
19
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20
- PERFORMANCE OF THIS SOFTWARE.
21
- ***************************************************************************** */
22
- /* global Reflect, Promise, SuppressedError, Symbol */
23
-
24
-
25
- function __decorate(decorators, target, key, desc) {
26
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
27
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
28
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
29
- return c > 3 && r && Object.defineProperty(target, key, r), r;
30
- }
31
-
32
- function __param(paramIndex, decorator) {
33
- return function (target, key) { decorator(target, key, paramIndex); }
34
- }
35
-
36
- function __metadata(metadataKey, metadataValue) {
37
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
38
- }
39
-
40
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
41
- var e = new Error(message);
42
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
43
- };
44
-
45
- const subModelLoaderErrorFn = makeError('subModelLoaderError');
46
- /**
47
- * 子文档加载器
48
- */
49
- class SubModelLoader {
50
- }
51
- let NonSubModelLoader = class NonSubModelLoader extends SubModelLoader {
52
- createSubModelBySlot() {
53
- throw subModelLoaderErrorFn('single document does not support async slot.');
54
- }
55
- createSubModelByComponent() {
56
- throw subModelLoaderErrorFn('single document does not support async component.');
57
- }
58
- loadSubModelByComponent() {
59
- throw subModelLoaderErrorFn('single document does not support async component.');
60
- }
61
- loadSubModelBySlot() {
62
- throw subModelLoaderErrorFn('single document does not support async slot.');
63
- }
64
- getLoadedModelBySlot() {
65
- throw subModelLoaderErrorFn('single document does not support async slot.');
66
- }
67
- getLoadedModelByComponent() {
68
- throw subModelLoaderErrorFn('single document does not support async component.');
69
- }
70
- };
71
- NonSubModelLoader = __decorate([
72
- Injectable()
73
- ], NonSubModelLoader);
74
-
75
- const collaborateErrorFn = makeError('Collaborate');
76
- class SlotMap {
77
- constructor() {
78
- Object.defineProperty(this, "slotAndYTextMap", {
79
- enumerable: true,
80
- configurable: true,
81
- writable: true,
82
- value: new WeakMap()
83
- });
84
- Object.defineProperty(this, "yTextAndSlotMap", {
85
- enumerable: true,
86
- configurable: true,
87
- writable: true,
88
- value: new WeakMap()
89
- });
90
- }
91
- set(key, value) {
92
- if (key instanceof Slot) {
93
- this.slotAndYTextMap.set(key, value);
94
- this.yTextAndSlotMap.set(value, key);
95
- }
96
- else {
97
- this.slotAndYTextMap.set(value, key);
98
- this.yTextAndSlotMap.set(key, value);
99
- }
100
- }
101
- get(key) {
102
- if (key instanceof Slot) {
103
- return this.slotAndYTextMap.get(key) || null;
104
- }
105
- return this.yTextAndSlotMap.get(key) || null;
106
- }
107
- delete(key) {
108
- if (key instanceof Slot) {
109
- const v = this.slotAndYTextMap.get(key);
110
- this.slotAndYTextMap.delete(key);
111
- if (v) {
112
- this.yTextAndSlotMap.delete(v);
113
- }
114
- }
115
- else {
116
- const v = this.yTextAndSlotMap.get(key);
117
- this.yTextAndSlotMap.delete(key);
118
- if (v) {
119
- this.slotAndYTextMap.delete(v);
120
- }
121
- }
122
- }
123
- }
124
- let Collaborate = class Collaborate {
125
- constructor(scheduler, registry, selection, subModelLoader) {
126
- Object.defineProperty(this, "scheduler", {
127
- enumerable: true,
128
- configurable: true,
129
- writable: true,
130
- value: scheduler
131
- });
132
- Object.defineProperty(this, "registry", {
133
- enumerable: true,
134
- configurable: true,
135
- writable: true,
136
- value: registry
137
- });
138
- Object.defineProperty(this, "selection", {
139
- enumerable: true,
140
- configurable: true,
141
- writable: true,
142
- value: selection
143
- });
144
- Object.defineProperty(this, "subModelLoader", {
145
- enumerable: true,
146
- configurable: true,
147
- writable: true,
148
- value: subModelLoader
149
- });
150
- Object.defineProperty(this, "yDoc", {
151
- enumerable: true,
152
- configurable: true,
153
- writable: true,
154
- value: new Doc()
155
- });
156
- Object.defineProperty(this, "slotMap", {
157
- enumerable: true,
158
- configurable: true,
159
- writable: true,
160
- value: new SlotMap()
161
- });
162
- Object.defineProperty(this, "onAddSubModel", {
163
- enumerable: true,
164
- configurable: true,
165
- writable: true,
166
- value: void 0
167
- });
168
- Object.defineProperty(this, "subscriptions", {
169
- enumerable: true,
170
- configurable: true,
171
- writable: true,
172
- value: []
173
- });
174
- Object.defineProperty(this, "updateFromRemote", {
175
- enumerable: true,
176
- configurable: true,
177
- writable: true,
178
- value: false
179
- });
180
- Object.defineProperty(this, "addSubModelEvent", {
181
- enumerable: true,
182
- configurable: true,
183
- writable: true,
184
- value: new Subject()
185
- });
186
- Object.defineProperty(this, "updateRemoteActions", {
187
- enumerable: true,
188
- configurable: true,
189
- writable: true,
190
- value: new WeakMap()
191
- });
192
- Object.defineProperty(this, "noRecord", {
193
- enumerable: true,
194
- configurable: true,
195
- writable: true,
196
- value: {}
197
- });
198
- this.onAddSubModel = this.addSubModelEvent.asObservable();
199
- }
200
- syncRootComponent(yDoc, sharedComponent, localComponent) {
201
- this.initSyncEvent(yDoc);
202
- this.syncComponent(yDoc, sharedComponent, localComponent);
203
- }
204
- syncRootSlot(yDoc, sharedSlot, localSlot) {
205
- if (sharedSlot.length) {
206
- localSlot.retain(0);
207
- localSlot.delete(localSlot.length);
208
- localSlot.cleanAttributes();
209
- localSlot.cleanFormats();
210
- this.initLocalSlotBySharedSlot(sharedSlot, localSlot);
211
- }
212
- else {
213
- yDoc.transact(() => {
214
- this.initSharedSlotByLocalSlot(sharedSlot, localSlot);
215
- });
216
- }
217
- this.initSyncEvent(yDoc);
218
- this.syncSlot(sharedSlot, localSlot);
219
- }
220
- getAbstractSelection(position) {
221
- const anchorPosition = createAbsolutePositionFromRelativePosition(position.anchor.position, position.anchor.doc);
222
- const focusPosition = createAbsolutePositionFromRelativePosition(position.focus.position, position.focus.doc);
223
- if (anchorPosition && focusPosition) {
224
- const focusSlot = this.slotMap.get(focusPosition.type);
225
- const anchorSlot = this.slotMap.get(anchorPosition.type);
226
- if (focusSlot && anchorSlot) {
227
- return {
228
- anchorSlot,
229
- anchorOffset: anchorPosition.index,
230
- focusSlot,
231
- focusOffset: focusPosition.index
232
- };
233
- }
234
- }
235
- return null;
236
- }
237
- getRelativeCursorLocation() {
238
- const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
239
- if (anchorSlot) {
240
- const anchorYText = this.slotMap.get(anchorSlot);
241
- if (anchorYText) {
242
- const anchorPosition = createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
243
- if (focusSlot) {
244
- const focusYText = this.slotMap.get(focusSlot);
245
- if (focusYText) {
246
- const focusPosition = createRelativePositionFromTypeIndex(focusYText, focusOffset);
247
- return {
248
- focus: {
249
- doc: focusYText.doc,
250
- position: focusPosition
251
- },
252
- anchor: {
253
- doc: anchorYText.doc,
254
- position: anchorPosition
255
- }
256
- };
257
- }
258
- }
259
- }
260
- }
261
- return null;
262
- }
263
- restoreCursorPosition(position) {
264
- if (!position) {
265
- this.selection.unSelect();
266
- return;
267
- }
268
- const selection = this.getAbstractSelection(position);
269
- if (selection) {
270
- this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
271
- }
272
- }
273
- initSyncEvent(yDoc) {
274
- this.subscriptions.push(this.scheduler.onDocChanged.pipe(map(item => {
275
- return item.filter(i => {
276
- return i.from !== ChangeOrigin.Remote;
277
- });
278
- }), filter(item => {
279
- return item.length;
280
- })).subscribe(() => {
281
- const updates = [];
282
- let update = null;
283
- const updateRemoteActions = this.updateRemoteActions.get(yDoc) || [];
284
- for (const item of updateRemoteActions) {
285
- if (!update) {
286
- update = {
287
- record: item.record,
288
- actions: []
289
- };
290
- updates.push(update);
291
- }
292
- if (update.record === item.record) {
293
- update.actions.push(item.action);
294
- }
295
- else {
296
- update = {
297
- record: item.record,
298
- actions: [item.action]
299
- };
300
- updates.push(update);
301
- }
302
- }
303
- this.updateRemoteActions.delete(yDoc);
304
- for (const item of updates) {
305
- yDoc.transact(() => {
306
- item.actions.forEach(fn => {
307
- fn();
308
- });
309
- }, item.record ? yDoc : this.noRecord);
310
- }
311
- }));
312
- }
313
- syncComponent(yDoc, sharedComponent, localComponent) {
314
- let state = sharedComponent.get('state');
315
- if (!state) {
316
- state = new Map();
317
- this.syncLocalMapToSharedMap(localComponent.state, state);
318
- yDoc.transact(() => {
319
- sharedComponent.set('state', state);
320
- });
321
- }
322
- else {
323
- Object.keys(localComponent.state).forEach(key => {
324
- Reflect.deleteProperty(localComponent.state, key);
325
- });
326
- this.syncSharedMapToLocalMap(state, localComponent.state);
327
- }
328
- }
329
- syncSlot(sharedSlot, localSlot) {
330
- const syncRemote = (ev, tr) => {
331
- this.runRemoteUpdate(tr, () => {
332
- localSlot.retain(0);
333
- ev.keysChanged.forEach(key => {
334
- const change = ev.keys.get(key);
335
- if (!change) {
336
- return;
337
- }
338
- const updateType = change.action;
339
- if (updateType === 'update' || updateType === 'add') {
340
- const attribute = this.registry.getAttribute(key);
341
- if (attribute) {
342
- localSlot.setAttribute(attribute, sharedSlot.getAttribute(key));
343
- }
344
- }
345
- else if (updateType === 'delete') {
346
- const attribute = this.registry.getAttribute(key);
347
- if (attribute) {
348
- localSlot.removeAttribute(attribute);
349
- }
350
- }
351
- });
352
- ev.delta.forEach(action => {
353
- if (Reflect.has(action, 'retain')) {
354
- if (action.attributes) {
355
- const formats = remoteFormatsToLocal(this.registry, action.attributes);
356
- if (formats.length) {
357
- localSlot.retain(action.retain, formats);
358
- }
359
- }
360
- localSlot.retain(localSlot.index + action.retain);
361
- }
362
- else if (action.insert) {
363
- const index = localSlot.index;
364
- let length = 1;
365
- if (typeof action.insert === 'string') {
366
- length = action.insert.length;
367
- localSlot.insert(action.insert, remoteFormatsToLocal(this.registry, action.attributes));
368
- }
369
- else {
370
- const sharedComponent = action.insert;
371
- const component = this.createLocalComponentBySharedComponent(sharedComponent);
372
- localSlot.insert(component);
373
- }
374
- if (this.selection.isSelected && !(tr.origin instanceof UndoManager)) {
375
- if (localSlot === this.selection.anchorSlot && this.selection.anchorOffset > index) {
376
- this.selection.setAnchor(localSlot, this.selection.anchorOffset + length);
377
- }
378
- if (localSlot === this.selection.focusSlot && this.selection.focusOffset > index) {
379
- this.selection.setFocus(localSlot, this.selection.focusOffset + length);
380
- }
381
- }
382
- }
383
- else if (action.delete) {
384
- const index = localSlot.index;
385
- localSlot.delete(action.delete);
386
- if (this.selection.isSelected && !(tr.origin instanceof UndoManager)) {
387
- if (localSlot === this.selection.anchorSlot && this.selection.anchorOffset >= index) {
388
- this.selection.setAnchor(localSlot, this.selection.startOffset - action.delete);
389
- }
390
- if (localSlot === this.selection.focusSlot && this.selection.focusOffset >= index) {
391
- this.selection.setFocus(localSlot, this.selection.focusOffset - action.delete);
392
- }
393
- }
394
- }
395
- });
396
- });
397
- };
398
- sharedSlot.observe(syncRemote);
399
- const sub = localSlot.onContentChange.subscribe(actions => {
400
- this.runLocalUpdate(sharedSlot.doc, true, () => {
401
- var _a;
402
- let offset = 0;
403
- let length = 0;
404
- for (const action of actions) {
405
- if (action.type === 'retain') {
406
- const formats = action.formats;
407
- if (formats) {
408
- const keys = Object.keys(formats);
409
- let length = keys.length;
410
- keys.forEach(key => {
411
- const formatter = this.registry.getFormatter(key);
412
- if (!formatter) {
413
- length--;
414
- Reflect.deleteProperty(formats, key);
415
- }
416
- });
417
- if (length) {
418
- sharedSlot.format(offset, action.offset, formats);
419
- }
420
- }
421
- else {
422
- offset = action.offset;
423
- }
424
- }
425
- else if (action.type === 'contentInsert') {
426
- const delta = sharedSlot.toDelta();
427
- const isEmpty = delta.length === 1 && delta[0].insert === Slot.emptyPlaceholder;
428
- if (typeof action.content === 'string') {
429
- length = action.content.length;
430
- sharedSlot.insert(offset, action.content, action.formats || {});
431
- }
432
- else {
433
- length = 1;
434
- const sharedComponent = this.createSharedComponentByLocalComponent(action.ref);
435
- sharedSlot.insertEmbed(offset, sharedComponent, action.formats || {});
436
- }
437
- if (isEmpty && offset === 0) {
438
- sharedSlot.delete(sharedSlot.length - 1, 1);
439
- }
440
- offset += length;
441
- }
442
- else if (action.type === 'delete') {
443
- const delta = sharedSlot.toDelta();
444
- if (sharedSlot.length) {
445
- sharedSlot.delete(offset, action.count);
446
- }
447
- if (sharedSlot.length === 0) {
448
- sharedSlot.insert(0, '\n', (_a = delta[0]) === null || _a === void 0 ? void 0 : _a.attributes);
449
- }
450
- }
451
- else if (action.type === 'attrSet') {
452
- sharedSlot.setAttribute(action.name, action.value);
453
- }
454
- else if (action.type === 'attrDelete') {
455
- sharedSlot.removeAttribute(action.name);
456
- }
457
- }
458
- });
459
- });
460
- this.slotMap.set(localSlot, sharedSlot);
461
- localSlot.__changeMarker__.addDetachCallback(() => {
462
- this.slotMap.delete(localSlot);
463
- sharedSlot.unobserve(syncRemote);
464
- sub.unsubscribe();
465
- });
466
- }
467
- destroy() {
468
- this.subscriptions.forEach(i => i.unsubscribe());
469
- this.subscriptions = [];
470
- }
471
- syncSharedMapToLocalMap(sharedMap, localMap) {
472
- sharedMap.forEach((value, key) => {
473
- localMap[key] = this.createLocalModelBySharedByModel(value);
474
- });
475
- this.syncObject(sharedMap, localMap);
476
- }
477
- createLocalMapBySharedMap(sharedMap) {
478
- const localMap = observe({});
479
- this.syncSharedMapToLocalMap(sharedMap, localMap);
480
- return localMap;
481
- }
482
- createLocalArrayBySharedArray(sharedArray) {
483
- const localArray = observe([]);
484
- localArray.push(...sharedArray.map(item => this.createLocalModelBySharedByModel(item)));
485
- this.syncArray(sharedArray, localArray);
486
- return localArray;
487
- }
488
- syncLocalMapToSharedMap(localMap, sharedMap) {
489
- Object.entries(localMap).forEach(([key, value]) => {
490
- sharedMap.set(key, this.createSharedModelByLocalModel(value));
491
- });
492
- this.syncObject(sharedMap, localMap);
493
- }
494
- createSharedMapByLocalMap(localMap) {
495
- const sharedMap = new Map();
496
- this.syncLocalMapToSharedMap(localMap, sharedMap);
497
- return sharedMap;
498
- }
499
- createSharedArrayByLocalArray(localArray) {
500
- const sharedArray = new Array$1();
501
- localArray.forEach(value => {
502
- sharedArray.push([this.createSharedModelByLocalModel(value)]);
503
- });
504
- this.syncArray(sharedArray, localArray);
505
- return sharedArray;
506
- }
507
- createSharedSlotByLocalSlot(localSlot) {
508
- const sharedSlot = new Text();
509
- const isAsyncSlot = localSlot instanceof AsyncSlot;
510
- sharedSlot.setAttribute('schema', [...localSlot.schema]);
511
- sharedSlot.setAttribute('type', isAsyncSlot ? 'async' : 'sync');
512
- if (isAsyncSlot) {
513
- let isDestroyed = false;
514
- const sharedMetadata = this.createSharedMapByLocalMap(localSlot.metadata);
515
- sharedSlot.setAttribute('metadata', sharedMetadata);
516
- this.subModelLoader.createSubModelBySlot(localSlot).then(subDocument => {
517
- if (isDestroyed) {
518
- return;
519
- }
520
- const content = subDocument.getText('content');
521
- const state = subDocument.getMap('state');
522
- this.syncLocalMapToSharedMap(localSlot.state, state);
523
- this.initSharedSlotByLocalSlot(content, localSlot);
524
- this.syncSlot(content, localSlot);
525
- this.addSubModelEvent.next({
526
- yDoc: subDocument,
527
- yType: content
528
- });
529
- this.initSyncEvent(subDocument);
530
- localSlot.loader.markAsLoaded();
531
- });
532
- localSlot.__changeMarker__.addDetachCallback(() => {
533
- isDestroyed = true;
534
- });
535
- return sharedSlot;
536
- }
537
- const sharedSlotState = new Map();
538
- this.syncLocalMapToSharedMap(localSlot.state, sharedSlotState);
539
- sharedSlot.setAttribute('state', sharedSlotState);
540
- const sharedContent = new Text();
541
- this.initSharedSlotByLocalSlot(sharedContent, localSlot);
542
- sharedSlot.insertEmbed(0, sharedContent);
543
- this.syncSlot(sharedContent, localSlot);
544
- return sharedSlot;
545
- }
546
- initSharedSlotByLocalSlot(sharedContent, localSlot) {
547
- let offset = 0;
548
- localSlot.toDelta().forEach(i => {
549
- let formats = {};
550
- if (i.formats) {
551
- i.formats.forEach(item => {
552
- formats[item[0].name] = item[1];
553
- });
554
- }
555
- else {
556
- formats = null;
557
- }
558
- if (typeof i.insert === 'string') {
559
- sharedContent.insert(offset, i.insert, formats);
560
- }
561
- else {
562
- const sharedComponent = this.createSharedComponentByLocalComponent(i.insert);
563
- sharedContent.insertEmbed(offset, sharedComponent, formats);
564
- }
565
- offset += i.insert.length;
566
- });
567
- localSlot.getAttributes().forEach(item => {
568
- sharedContent.setAttribute(item[0].name, item[1]);
569
- });
570
- }
571
- createLocalSlotBySharedSlot(sharedSlot) {
572
- var _a;
573
- const type = sharedSlot.getAttribute('type');
574
- const schema = sharedSlot.getAttribute('schema');
575
- if (type === 'async') {
576
- const metadata = sharedSlot.getAttribute('metadata');
577
- const slot = new AsyncSlot(schema || [], {}, {});
578
- this.syncSharedMapToLocalMap(metadata, slot.metadata);
579
- const loadedSubDocument = this.subModelLoader.getLoadedModelBySlot(slot);
580
- if (loadedSubDocument) {
581
- const subContent = loadedSubDocument.getText('content');
582
- const data = loadedSubDocument.getMap('state');
583
- this.syncSharedMapToLocalMap(data, slot.state);
584
- this.syncRootSlot(loadedSubDocument, subContent, slot);
585
- this.addSubModelEvent.next({
586
- yDoc: loadedSubDocument,
587
- yType: subContent
588
- });
589
- slot.loader.markAsLoaded();
590
- return slot;
591
- }
592
- let isDestroyed = false;
593
- slot.loader.onRequestLoad.toPromise().then(() => {
594
- return this.subModelLoader.loadSubModelBySlot(slot);
595
- }).then(subDocument => {
596
- if (isDestroyed) {
597
- return;
598
- }
599
- const subContent = subDocument.getText('content');
600
- const state = subDocument.getMap('state');
601
- this.syncSharedMapToLocalMap(state, slot.state);
602
- this.syncRootSlot(subDocument, subContent, slot);
603
- this.addSubModelEvent.next({
604
- yDoc: subDocument,
605
- yType: subContent
606
- });
607
- slot.loader.markAsLoaded();
608
- });
609
- slot.__changeMarker__.addDetachCallback(() => {
610
- isDestroyed = true;
611
- });
612
- return slot;
613
- }
614
- const contentDelta = sharedSlot.toDelta();
615
- const content = (_a = contentDelta[0]) === null || _a === void 0 ? void 0 : _a.insert;
616
- if (!(content instanceof Text)) {
617
- throw collaborateErrorFn('shared slot content type is not `YText`.');
618
- }
619
- const localSlot = new Slot(schema || [], {});
620
- const sharedSlotState = sharedSlot.getAttribute('state');
621
- this.syncSharedMapToLocalMap(sharedSlotState, localSlot.state);
622
- this.initLocalSlotBySharedSlot(content, localSlot);
623
- this.syncSlot(content, localSlot);
624
- return localSlot;
625
- }
626
- initLocalSlotBySharedSlot(content, localSlot) {
627
- const delta = content.toDelta();
628
- const attrs = content.getAttributes();
629
- Object.keys(attrs).forEach(key => {
630
- const attribute = this.registry.getAttribute(key);
631
- if (attribute) {
632
- localSlot.setAttribute(attribute, attrs[key]);
633
- }
634
- });
635
- for (const action of delta) {
636
- if (action.insert) {
637
- if (typeof action.insert === 'string') {
638
- const formats = remoteFormatsToLocal(this.registry, action.attributes);
639
- localSlot.insert(action.insert, formats);
640
- }
641
- else {
642
- const sharedComponent = action.insert;
643
- const component = this.createLocalComponentBySharedComponent(sharedComponent);
644
- localSlot.insert(component, remoteFormatsToLocal(this.registry, action.attributes));
645
- }
646
- }
647
- else {
648
- throw collaborateErrorFn('unexpected delta action.');
649
- }
650
- }
651
- }
652
- createSharedModelByLocalModel(localModel) {
653
- if (localModel instanceof Slot) {
654
- return this.createSharedSlotByLocalSlot(localModel);
655
- }
656
- if (Array.isArray(localModel)) {
657
- return this.createSharedArrayByLocalArray(localModel);
658
- }
659
- if (typeof localModel === 'object' && localModel !== null) {
660
- return this.createSharedMapByLocalMap(localModel);
661
- }
662
- return localModel;
663
- }
664
- createLocalModelBySharedByModel(sharedModel) {
665
- if (sharedModel instanceof Map) {
666
- return this.createLocalMapBySharedMap(sharedModel);
667
- }
668
- if (sharedModel instanceof Array$1) {
669
- return this.createLocalArrayBySharedArray(sharedModel);
670
- }
671
- if (sharedModel instanceof Text) {
672
- return this.createLocalSlotBySharedSlot(sharedModel);
673
- }
674
- return sharedModel;
675
- }
676
- createSharedComponentByLocalComponent(component) {
677
- const sharedComponent = new Map();
678
- sharedComponent.set('name', component.name);
679
- if (component instanceof AsyncComponent) {
680
- sharedComponent.set('type', 'async');
681
- const sharedMetadata = this.createSharedMapByLocalMap(component.metadata);
682
- sharedComponent.set('metadata', sharedMetadata);
683
- const state = component.state;
684
- let isDestroyed = false;
685
- state.__changeMarker__.addDetachCallback(() => {
686
- isDestroyed = true;
687
- });
688
- this.subModelLoader.createSubModelByComponent(component).then(subDocument => {
689
- if (isDestroyed) {
690
- return;
691
- }
692
- const state = subDocument.getMap('state');
693
- this.syncComponent(subDocument, state, component);
694
- this.addSubModelEvent.next({
695
- yType: state,
696
- yDoc: subDocument
697
- });
698
- this.initSyncEvent(subDocument);
699
- component.loader.markAsLoaded();
700
- });
701
- return sharedComponent;
702
- }
703
- const sharedState = this.createSharedMapByLocalMap(component.state);
704
- sharedComponent.set('state', sharedState);
705
- sharedComponent.set('type', 'sync');
706
- return sharedComponent;
707
- }
708
- createLocalComponentBySharedComponent(yMap) {
709
- const componentName = yMap.get('name');
710
- const type = yMap.get('type');
711
- let instance;
712
- if (type === 'async') {
713
- instance = this.registry.createComponentByData(componentName, {}, {});
714
- if (instance instanceof AsyncComponent) {
715
- const sharedMetadata = yMap.get('metadata');
716
- this.syncSharedMapToLocalMap(sharedMetadata, instance.metadata);
717
- const loadedSubDocument = this.subModelLoader.getLoadedModelByComponent(instance);
718
- if (loadedSubDocument) {
719
- const state = loadedSubDocument.getMap('state');
720
- this.syncComponent(loadedSubDocument, state, instance);
721
- this.addSubModelEvent.next({
722
- yType: state,
723
- yDoc: loadedSubDocument
724
- });
725
- instance.loader.markAsLoaded();
726
- return instance;
727
- }
728
- const state = instance.state;
729
- let isDestroyed = false;
730
- instance.loader.onRequestLoad.toPromise().then(() => {
731
- return this.subModelLoader.loadSubModelByComponent(instance);
732
- })
733
- .then(subDocument => {
734
- if (isDestroyed) {
735
- return;
736
- }
737
- const state = subDocument.getMap('state');
738
- this.syncComponent(subDocument, state, instance);
739
- this.addSubModelEvent.next({
740
- yType: state,
741
- yDoc: subDocument
742
- });
743
- instance.loader.markAsLoaded();
744
- });
745
- state.__changeMarker__.addDetachCallback(() => {
746
- isDestroyed = true;
747
- });
748
- }
749
- else if (instance instanceof Component) {
750
- throw collaborateErrorFn(`component name \`${componentName}\` is not a async component.`);
751
- }
752
- }
753
- else {
754
- const sharedState = yMap.get('state');
755
- const state = this.createLocalMapBySharedMap(sharedState);
756
- instance = this.registry.createComponentByData(componentName, state);
757
- }
758
- if (instance) {
759
- return instance;
760
- }
761
- throw collaborateErrorFn(`cannot find component factory \`${componentName}\`.`);
762
- }
763
- /**
764
- * 双向同步数组
765
- * @param sharedArray
766
- * @param localArray
767
- * @private
768
- */
769
- syncArray(sharedArray, localArray) {
770
- function logError(type) {
771
- console.error(collaborateErrorFn(`${type} error, length exceeded, path in ${localArray.__changeMarker__.getPaths().join('/')}`));
772
- }
773
- const sub = localArray.__changeMarker__.onSelfChange.subscribe((actions) => {
774
- this.runLocalUpdate(sharedArray.doc, !localArray.__changeMarker__.irrevocableUpdate, () => {
775
- let index = 0;
776
- for (const action of actions) {
777
- switch (action.type) {
778
- case 'retain':
779
- index = action.offset;
780
- break;
781
- case 'insert':
782
- {
783
- const ref = action.ref;
784
- if (!Array.isArray(ref)) {
785
- throw collaborateErrorFn('The insertion action must have a reference value.');
786
- }
787
- const data = ref.map(item => {
788
- return this.createSharedModelByLocalModel(item);
789
- });
790
- if (index <= sharedArray.length) {
791
- sharedArray.insert(index, data);
792
- }
793
- else {
794
- sharedArray.insert(sharedArray.length, data);
795
- logError('insert');
796
- }
797
- }
798
- break;
799
- case 'delete':
800
- if (action.count <= 0) {
801
- break;
802
- }
803
- if (index < sharedArray.length) {
804
- sharedArray.delete(index, action.count);
805
- }
806
- else {
807
- logError('delete');
808
- }
809
- break;
810
- case 'setIndex':
811
- if (action.index < sharedArray.length) {
812
- sharedArray.delete(action.index, 1);
813
- sharedArray.insert(action.index, [this.createSharedModelByLocalModel(action.ref)]);
814
- }
815
- else {
816
- sharedArray.insert(sharedArray.length, [this.createSharedModelByLocalModel(action.ref)]);
817
- logError('setIndex');
818
- }
819
- break;
820
- }
821
- }
822
- });
823
- });
824
- const syncRemote = (ev, tr) => {
825
- this.runRemoteUpdate(tr, () => {
826
- let index = 0;
827
- ev.delta.forEach((action) => {
828
- if (Reflect.has(action, 'retain')) {
829
- index += action.retain;
830
- }
831
- else if (action.insert) {
832
- const data = action.insert.map((item) => {
833
- return this.createLocalModelBySharedByModel(item);
834
- });
835
- localArray.splice(index, 0, ...data);
836
- index += data.length;
837
- }
838
- else if (action.delete) {
839
- localArray.splice(index, action.delete);
840
- }
841
- });
842
- });
843
- };
844
- sharedArray.observe(syncRemote);
845
- localArray.__changeMarker__.addDetachCallback(() => {
846
- sub.unsubscribe();
847
- sharedArray.unobserve(syncRemote);
848
- });
849
- }
850
- /**
851
- * 双向同步对象
852
- * @param sharedObject
853
- * @param localObject
854
- * @private
855
- */
856
- syncObject(sharedObject, localObject) {
857
- const syncRemote = (ev, tr) => {
858
- this.runRemoteUpdate(tr, () => {
859
- ev.changes.keys.forEach((item, key) => {
860
- if (item.action === 'add' || item.action === 'update') {
861
- const value = sharedObject.get(key);
862
- localObject[key] = this.createLocalModelBySharedByModel(value);
863
- }
864
- else {
865
- Reflect.deleteProperty(localObject, key);
866
- }
867
- });
868
- });
869
- };
870
- sharedObject.observe(syncRemote);
871
- const sub = localObject.__changeMarker__.onSelfChange.subscribe((actions) => {
872
- this.runLocalUpdate(sharedObject.doc, !localObject.__changeMarker__.irrevocableUpdate, () => {
873
- for (const action of actions) {
874
- switch (action.type) {
875
- case 'propSet':
876
- {
877
- const subModel = this.createSharedModelByLocalModel(action.ref);
878
- sharedObject.set(action.key, subModel);
879
- if (sharedObject.size === 0) {
880
- // 奇怪的 bug,设置了子模型,但子模型会标记为 deleted,导致设置后无效
881
- console.error(collaborateErrorFn(`prop set error, key is ${action.key}`));
882
- }
883
- }
884
- break;
885
- case 'propDelete':
886
- sharedObject.delete(action.key);
887
- break;
888
- }
889
- }
890
- });
891
- });
892
- localObject.__changeMarker__.addDetachCallback(function () {
893
- sharedObject.unobserve(syncRemote);
894
- sub.unsubscribe();
895
- });
896
- }
897
- runLocalUpdate(yDoc, record, fn) {
898
- if (this.updateFromRemote || !yDoc) {
899
- return;
900
- }
901
- let changeList = this.updateRemoteActions.get(yDoc);
902
- if (!changeList) {
903
- changeList = [];
904
- this.updateRemoteActions.set(yDoc, changeList);
905
- }
906
- changeList.push({
907
- record,
908
- action: fn
909
- });
910
- }
911
- runRemoteUpdate(tr, fn) {
912
- if (tr.origin === tr.doc) {
913
- return;
914
- }
915
- this.updateFromRemote = true;
916
- if (tr.origin instanceof UndoManager) {
917
- this.scheduler.historyApplyTransact(fn);
918
- }
919
- else {
920
- this.scheduler.remoteUpdateTransact(fn);
921
- }
922
- this.updateFromRemote = false;
923
- }
924
- };
925
- Collaborate = __decorate([
926
- Injectable(),
927
- __metadata("design:paramtypes", [Scheduler,
928
- Registry,
929
- Selection,
930
- SubModelLoader])
931
- ], Collaborate);
932
- function remoteFormatsToLocal(registry, attrs) {
933
- const formats = [];
934
- if (attrs) {
935
- Object.keys(attrs).forEach(key => {
936
- const formatter = registry.getFormatter(key);
937
- if (formatter) {
938
- formats.push([formatter, attrs[key]]);
939
- }
940
- });
941
- }
942
- return formats;
943
- }
944
-
945
- class CustomUndoManagerConfig {
946
- }
947
- const collabHistoryErrorFn = makeError('CollabHistory');
948
- let CollabHistory = class CollabHistory {
949
- get canBack() {
950
- var _a;
951
- return ((_a = this.manager) === null || _a === void 0 ? void 0 : _a.canUndo()) || false;
952
- }
953
- get canForward() {
954
- var _a;
955
- return ((_a = this.manager) === null || _a === void 0 ? void 0 : _a.canRedo()) || false;
956
- }
957
- constructor(rootComponentRef, collaborate, scheduler, stackSize, undoManagerConfig) {
958
- Object.defineProperty(this, "rootComponentRef", {
959
- enumerable: true,
960
- configurable: true,
961
- writable: true,
962
- value: rootComponentRef
963
- });
964
- Object.defineProperty(this, "collaborate", {
965
- enumerable: true,
966
- configurable: true,
967
- writable: true,
968
- value: collaborate
969
- });
970
- Object.defineProperty(this, "scheduler", {
971
- enumerable: true,
972
- configurable: true,
973
- writable: true,
974
- value: scheduler
975
- });
976
- Object.defineProperty(this, "stackSize", {
977
- enumerable: true,
978
- configurable: true,
979
- writable: true,
980
- value: stackSize
981
- });
982
- Object.defineProperty(this, "undoManagerConfig", {
983
- enumerable: true,
984
- configurable: true,
985
- writable: true,
986
- value: undoManagerConfig
987
- });
988
- Object.defineProperty(this, "onBack", {
989
- enumerable: true,
990
- configurable: true,
991
- writable: true,
992
- value: void 0
993
- });
994
- Object.defineProperty(this, "onForward", {
995
- enumerable: true,
996
- configurable: true,
997
- writable: true,
998
- value: void 0
999
- });
1000
- Object.defineProperty(this, "onChange", {
1001
- enumerable: true,
1002
- configurable: true,
1003
- writable: true,
1004
- value: void 0
1005
- });
1006
- Object.defineProperty(this, "onPush", {
1007
- enumerable: true,
1008
- configurable: true,
1009
- writable: true,
1010
- value: void 0
1011
- });
1012
- Object.defineProperty(this, "manager", {
1013
- enumerable: true,
1014
- configurable: true,
1015
- writable: true,
1016
- value: null
1017
- });
1018
- Object.defineProperty(this, "historyItems", {
1019
- enumerable: true,
1020
- configurable: true,
1021
- writable: true,
1022
- value: []
1023
- });
1024
- Object.defineProperty(this, "index", {
1025
- enumerable: true,
1026
- configurable: true,
1027
- writable: true,
1028
- value: 0
1029
- });
1030
- Object.defineProperty(this, "subscriptions", {
1031
- enumerable: true,
1032
- configurable: true,
1033
- writable: true,
1034
- value: []
1035
- });
1036
- Object.defineProperty(this, "backEvent", {
1037
- enumerable: true,
1038
- configurable: true,
1039
- writable: true,
1040
- value: new Subject()
1041
- });
1042
- Object.defineProperty(this, "forwardEvent", {
1043
- enumerable: true,
1044
- configurable: true,
1045
- writable: true,
1046
- value: new Subject()
1047
- });
1048
- Object.defineProperty(this, "changeEvent", {
1049
- enumerable: true,
1050
- configurable: true,
1051
- writable: true,
1052
- value: new Subject()
1053
- });
1054
- Object.defineProperty(this, "pushEvent", {
1055
- enumerable: true,
1056
- configurable: true,
1057
- writable: true,
1058
- value: new Subject()
1059
- });
1060
- this.onBack = this.backEvent.asObservable();
1061
- this.onForward = this.forwardEvent.asObservable();
1062
- this.onChange = this.changeEvent.asObservable();
1063
- this.onPush = this.pushEvent.asObservable();
1064
- }
1065
- listen() {
1066
- const root = this.collaborate.yDoc.getMap('RootComponent');
1067
- const rootComponent = this.rootComponentRef.component;
1068
- this.collaborate.syncRootComponent(this.collaborate.yDoc, root, rootComponent);
1069
- const undoManagerConfig = this.undoManagerConfig || {};
1070
- const manager = new UndoManager(root, {
1071
- trackedOrigins: new Set([this.collaborate.yDoc]),
1072
- captureTransaction(arg) {
1073
- if (undoManagerConfig.captureTransaction) {
1074
- return undoManagerConfig.captureTransaction(arg);
1075
- }
1076
- return true;
1077
- },
1078
- deleteFilter(item) {
1079
- if (undoManagerConfig.deleteFilter) {
1080
- return undoManagerConfig.deleteFilter(item);
1081
- }
1082
- return true;
1083
- }
1084
- });
1085
- this.manager = manager;
1086
- let beforePosition = null;
1087
- this.subscriptions.push(this.scheduler.onLocalChangeBefore.subscribe(() => {
1088
- beforePosition = this.collaborate.getRelativeCursorLocation();
1089
- }), this.collaborate.onAddSubModel.subscribe(() => {
1090
- throw collabHistoryErrorFn('single document does not support submodels.');
1091
- }));
1092
- manager.on('stack-item-added', (event) => {
1093
- if (event.type === 'undo') {
1094
- if (event.origin === manager) {
1095
- this.index++;
1096
- }
1097
- else {
1098
- this.historyItems.length = this.index;
1099
- this.historyItems.push({
1100
- before: beforePosition,
1101
- after: this.collaborate.getRelativeCursorLocation()
1102
- });
1103
- this.index++;
1104
- }
1105
- }
1106
- else {
1107
- this.index--;
1108
- }
1109
- if (manager.undoStack.length > this.stackSize) {
1110
- this.historyItems.shift();
1111
- manager.undoStack.shift();
1112
- }
1113
- if (event.origin === this.collaborate.yDoc) {
1114
- this.pushEvent.next();
1115
- }
1116
- this.changeEvent.next();
1117
- });
1118
- manager.on('stack-item-popped', (ev) => {
1119
- const index = ev.type === 'undo' ? this.index : this.index - 1;
1120
- const position = this.historyItems[index] || null;
1121
- const p = ev.type === 'undo' ? position === null || position === void 0 ? void 0 : position.before : position === null || position === void 0 ? void 0 : position.after;
1122
- this.collaborate.restoreCursorPosition(p);
1123
- });
1124
- }
1125
- back() {
1126
- var _a;
1127
- if (this.canBack) {
1128
- (_a = this.manager) === null || _a === void 0 ? void 0 : _a.undo();
1129
- this.backEvent.next();
1130
- }
1131
- }
1132
- forward() {
1133
- var _a;
1134
- if (this.canForward) {
1135
- (_a = this.manager) === null || _a === void 0 ? void 0 : _a.redo();
1136
- this.forwardEvent.next();
1137
- }
1138
- }
1139
- clear() {
1140
- var _a;
1141
- const last = this.historyItems.pop();
1142
- this.historyItems = last ? [last] : [];
1143
- this.index = last ? 1 : 0;
1144
- (_a = this.manager) === null || _a === void 0 ? void 0 : _a.clear();
1145
- this.changeEvent.next();
1146
- }
1147
- destroy() {
1148
- this.index = 0;
1149
- this.historyItems = [];
1150
- this.subscriptions.forEach(i => i.unsubscribe());
1151
- if (this.manager) {
1152
- this.manager.destroy();
1153
- this.manager.captureTransaction = () => true;
1154
- this.manager.deleteFilter = () => true;
1155
- this.manager.trackedOrigins = new Set([null]);
1156
- }
1157
- this.manager = null;
1158
- }
1159
- };
1160
- CollabHistory = __decorate([
1161
- Injectable(),
1162
- __param(3, Inject(HISTORY_STACK_SIZE)),
1163
- __param(4, Optional()),
1164
- __metadata("design:paramtypes", [RootComponentRef,
1165
- Collaborate,
1166
- Scheduler, Number, CustomUndoManagerConfig])
1167
- ], CollabHistory);
1168
-
1169
- /**
1170
- * 协作消息总线,用于同步各终端消息
1171
- */
1172
- class MessageBus {
1173
- constructor() {
1174
- Object.defineProperty(this, "onSync", {
1175
- enumerable: true,
1176
- configurable: true,
1177
- writable: true,
1178
- value: void 0
1179
- });
1180
- Object.defineProperty(this, "syncEvent", {
1181
- enumerable: true,
1182
- configurable: true,
1183
- writable: true,
1184
- value: new Subject()
1185
- });
1186
- this.onSync = this.syncEvent.asObservable();
1187
- }
1188
- /**
1189
- * 立即同步消息
1190
- */
1191
- sync() {
1192
- this.syncEvent.next();
1193
- }
1194
- }
1195
-
1196
- let MultipleDocCollabHistory = class MultipleDocCollabHistory {
1197
- get canBack() {
1198
- return this.actionStack.length > 0 && this.index > 0;
1199
- }
1200
- get canForward() {
1201
- return this.actionStack.length > 0 && this.index < this.actionStack.length;
1202
- }
1203
- constructor(collaborate, scheduler, rootComponentRef, stackSize, undoManagerConfig) {
1204
- Object.defineProperty(this, "collaborate", {
1205
- enumerable: true,
1206
- configurable: true,
1207
- writable: true,
1208
- value: collaborate
1209
- });
1210
- Object.defineProperty(this, "scheduler", {
1211
- enumerable: true,
1212
- configurable: true,
1213
- writable: true,
1214
- value: scheduler
1215
- });
1216
- Object.defineProperty(this, "rootComponentRef", {
1217
- enumerable: true,
1218
- configurable: true,
1219
- writable: true,
1220
- value: rootComponentRef
1221
- });
1222
- Object.defineProperty(this, "stackSize", {
1223
- enumerable: true,
1224
- configurable: true,
1225
- writable: true,
1226
- value: stackSize
1227
- });
1228
- Object.defineProperty(this, "undoManagerConfig", {
1229
- enumerable: true,
1230
- configurable: true,
1231
- writable: true,
1232
- value: undoManagerConfig
1233
- });
1234
- Object.defineProperty(this, "onChange", {
1235
- enumerable: true,
1236
- configurable: true,
1237
- writable: true,
1238
- value: void 0
1239
- });
1240
- Object.defineProperty(this, "onBack", {
1241
- enumerable: true,
1242
- configurable: true,
1243
- writable: true,
1244
- value: void 0
1245
- });
1246
- Object.defineProperty(this, "onForward", {
1247
- enumerable: true,
1248
- configurable: true,
1249
- writable: true,
1250
- value: void 0
1251
- });
1252
- Object.defineProperty(this, "onPush", {
1253
- enumerable: true,
1254
- configurable: true,
1255
- writable: true,
1256
- value: void 0
1257
- });
1258
- Object.defineProperty(this, "isListen", {
1259
- enumerable: true,
1260
- configurable: true,
1261
- writable: true,
1262
- value: false
1263
- });
1264
- Object.defineProperty(this, "changeEvent", {
1265
- enumerable: true,
1266
- configurable: true,
1267
- writable: true,
1268
- value: new Subject()
1269
- });
1270
- Object.defineProperty(this, "backEvent", {
1271
- enumerable: true,
1272
- configurable: true,
1273
- writable: true,
1274
- value: new Subject()
1275
- });
1276
- Object.defineProperty(this, "forwardEvent", {
1277
- enumerable: true,
1278
- configurable: true,
1279
- writable: true,
1280
- value: new Subject()
1281
- });
1282
- Object.defineProperty(this, "pushEvent", {
1283
- enumerable: true,
1284
- configurable: true,
1285
- writable: true,
1286
- value: new Subject()
1287
- });
1288
- Object.defineProperty(this, "actionStack", {
1289
- enumerable: true,
1290
- configurable: true,
1291
- writable: true,
1292
- value: []
1293
- });
1294
- Object.defineProperty(this, "index", {
1295
- enumerable: true,
1296
- configurable: true,
1297
- writable: true,
1298
- value: 0
1299
- });
1300
- Object.defineProperty(this, "stackItem", {
1301
- enumerable: true,
1302
- configurable: true,
1303
- writable: true,
1304
- value: null
1305
- });
1306
- Object.defineProperty(this, "timer", {
1307
- enumerable: true,
1308
- configurable: true,
1309
- writable: true,
1310
- value: null
1311
- });
1312
- Object.defineProperty(this, "beforePosition", {
1313
- enumerable: true,
1314
- configurable: true,
1315
- writable: true,
1316
- value: null
1317
- });
1318
- Object.defineProperty(this, "subscription", {
1319
- enumerable: true,
1320
- configurable: true,
1321
- writable: true,
1322
- value: new Subscription()
1323
- });
1324
- Object.defineProperty(this, "subDocs", {
1325
- enumerable: true,
1326
- configurable: true,
1327
- writable: true,
1328
- value: new Set()
1329
- });
1330
- Object.defineProperty(this, "listenerCaches", {
1331
- enumerable: true,
1332
- configurable: true,
1333
- writable: true,
1334
- value: new Set()
1335
- });
1336
- this.onChange = this.changeEvent.asObservable();
1337
- this.onBack = this.backEvent.asObservable();
1338
- this.onForward = this.forwardEvent.asObservable();
1339
- this.onPush = this.pushEvent.asObservable();
1340
- }
1341
- listen() {
1342
- this.isListen = true;
1343
- const root = this.collaborate.yDoc.getMap('RootComponent');
1344
- const rootComponent = this.rootComponentRef.component;
1345
- this.collaborate.syncRootComponent(this.collaborate.yDoc, root, rootComponent);
1346
- this.listenItem(root, this.collaborate.yDoc);
1347
- this.subscription.add(this.collaborate.onAddSubModel.subscribe(({ yType, yDoc }) => {
1348
- if (this.subDocs.has(yType)) {
1349
- return;
1350
- }
1351
- this.subDocs.add(yType);
1352
- if (this.isListen) {
1353
- this.listenItem(yType, yDoc);
1354
- }
1355
- }), this.scheduler.onLocalChangeBefore.subscribe(() => {
1356
- this.beforePosition = this.collaborate.getRelativeCursorLocation();
1357
- }));
1358
- }
1359
- forward() {
1360
- if (!this.canForward) {
1361
- return;
1362
- }
1363
- clearTimeout(this.timer);
1364
- const item = this.actionStack[this.index];
1365
- if (item) {
1366
- for (const i of item.undoManagers) {
1367
- i.redo();
1368
- }
1369
- this.collaborate.restoreCursorPosition(item.after);
1370
- }
1371
- this.index++;
1372
- this.forwardEvent.next();
1373
- this.changeEvent.next();
1374
- }
1375
- back() {
1376
- if (!this.canBack) {
1377
- return;
1378
- }
1379
- clearTimeout(this.timer);
1380
- let historyStackItem;
1381
- if (this.stackItem) {
1382
- historyStackItem = this.stackItem;
1383
- this.stackItem = null;
1384
- }
1385
- else {
1386
- this.index--;
1387
- historyStackItem = this.actionStack[this.index];
1388
- }
1389
- let len = historyStackItem.undoManagers.length;
1390
- while (len > 0) {
1391
- len--;
1392
- historyStackItem.undoManagers[len].undo();
1393
- }
1394
- if (historyStackItem) {
1395
- const beforePosition = historyStackItem.before;
1396
- this.collaborate.restoreCursorPosition(beforePosition);
1397
- this.backEvent.next();
1398
- this.changeEvent.next();
1399
- }
1400
- }
1401
- clear() {
1402
- this.actionStack = [];
1403
- this.stackItem = null;
1404
- this.index = 0;
1405
- this.beforePosition = null;
1406
- clearTimeout(this.timer);
1407
- this.listenerCaches.forEach((undoManager) => {
1408
- undoManager.clear();
1409
- });
1410
- this.changeEvent.next();
1411
- }
1412
- destroy() {
1413
- this.clear();
1414
- this.beforePosition = this.stackItem = null;
1415
- this.subscription.unsubscribe();
1416
- this.listenerCaches.forEach((undoManager) => {
1417
- undoManager.destroy();
1418
- });
1419
- this.subDocs.clear();
1420
- this.listenerCaches.clear();
1421
- }
1422
- listenItem(yType, yDoc) {
1423
- const undoManagerConfig = this.undoManagerConfig || {};
1424
- const undoManager = new UndoManager(yType, {
1425
- trackedOrigins: new Set([yDoc]),
1426
- captureTimeout: 0,
1427
- captureTransaction(arg) {
1428
- if (undoManagerConfig.captureTransaction) {
1429
- return undoManagerConfig.captureTransaction(arg);
1430
- }
1431
- return true;
1432
- },
1433
- deleteFilter(item) {
1434
- if (undoManagerConfig.deleteFilter) {
1435
- return undoManagerConfig.deleteFilter(item);
1436
- }
1437
- return true;
1438
- }
1439
- });
1440
- undoManager.on('stack-item-added', (event) => {
1441
- if (event.type === 'undo' && !(event.origin instanceof UndoManager)) {
1442
- if (this.index != this.actionStack.length) {
1443
- const redoStack = this.actionStack.slice(this.index);
1444
- redoStack.forEach(item => {
1445
- item.undoManagers.forEach(i => {
1446
- i.clear(false, true);
1447
- });
1448
- });
1449
- this.actionStack.length = this.index;
1450
- this.changeEvent.next();
1451
- }
1452
- if (this.stackItem === null) {
1453
- this.stackItem = {
1454
- before: this.beforePosition,
1455
- after: null,
1456
- undoManagers: []
1457
- };
1458
- this.timer = setTimeout(() => {
1459
- if (this.actionStack.length >= this.stackSize) {
1460
- this.actionStack.shift();
1461
- }
1462
- else {
1463
- this.index++;
1464
- }
1465
- // this.beforePosition = this.collaborate.getRelativeCursorLocation()
1466
- this.stackItem.after = this.beforePosition;
1467
- this.actionStack.push(this.stackItem);
1468
- this.stackItem = null;
1469
- this.pushEvent.next();
1470
- this.changeEvent.next();
1471
- }, 500);
1472
- }
1473
- this.stackItem.undoManagers.push(undoManager);
1474
- }
1475
- });
1476
- this.listenerCaches.add(undoManager);
1477
- }
1478
- };
1479
- MultipleDocCollabHistory = __decorate([
1480
- Injectable(),
1481
- __param(3, Inject(HISTORY_STACK_SIZE)),
1482
- __param(4, Optional()),
1483
- __metadata("design:paramtypes", [Collaborate,
1484
- Scheduler,
1485
- RootComponentRef, Number, CustomUndoManagerConfig])
1486
- ], MultipleDocCollabHistory);
1487
-
1488
- /**
1489
- * 协作通信通用接口
1490
- */
1491
- class SyncConnector {
1492
- constructor() {
1493
- /**
1494
- * 当文档加载完成时触发的观察者
1495
- */
1496
- Object.defineProperty(this, "onLoad", {
1497
- enumerable: true,
1498
- configurable: true,
1499
- writable: true,
1500
- value: void 0
1501
- });
1502
- /**
1503
- * 当文档 awareness 状态变更时触发的观察者
1504
- */
1505
- Object.defineProperty(this, "onStateChange", {
1506
- enumerable: true,
1507
- configurable: true,
1508
- writable: true,
1509
- value: void 0
1510
- });
1511
- Object.defineProperty(this, "loadEvent", {
1512
- enumerable: true,
1513
- configurable: true,
1514
- writable: true,
1515
- value: new Subject()
1516
- });
1517
- Object.defineProperty(this, "stateChangeEvent", {
1518
- enumerable: true,
1519
- configurable: true,
1520
- writable: true,
1521
- value: new Subject()
1522
- });
1523
- this.onLoad = this.loadEvent.asObservable();
1524
- this.onStateChange = this.stateChangeEvent.asObservable();
1525
- }
1526
- }
1527
-
1528
- class HocuspocusConnector extends SyncConnector {
1529
- constructor(config) {
1530
- super();
1531
- Object.defineProperty(this, "provide", {
1532
- enumerable: true,
1533
- configurable: true,
1534
- writable: true,
1535
- value: void 0
1536
- });
1537
- this.provide = new HocuspocusProvider(Object.assign(Object.assign({}, config), { onSynced: (data) => {
1538
- var _a;
1539
- (_a = config.onSynced) === null || _a === void 0 ? void 0 : _a.call(config, data);
1540
- this.loadEvent.next();
1541
- }, onAwarenessUpdate: (data) => {
1542
- var _a;
1543
- (_a = config.onAwarenessUpdate) === null || _a === void 0 ? void 0 : _a.call(config, data);
1544
- const states = data.states.map(state => {
1545
- return {
1546
- clientId: state.clientId,
1547
- message: state.message
1548
- };
1549
- });
1550
- this.stateChangeEvent.next(states);
1551
- } }));
1552
- }
1553
- setLocalStateField(key, data) {
1554
- this.provide.setAwarenessField(key, data);
1555
- }
1556
- onDestroy() {
1557
- this.provide.disconnect();
1558
- this.provide.destroy();
1559
- }
1560
- }
1561
-
1562
- class YWebsocketConnector extends SyncConnector {
1563
- constructor(url, roomName, yDoc) {
1564
- super();
1565
- Object.defineProperty(this, "provide", {
1566
- enumerable: true,
1567
- configurable: true,
1568
- writable: true,
1569
- value: void 0
1570
- });
1571
- Object.defineProperty(this, "onSync", {
1572
- enumerable: true,
1573
- configurable: true,
1574
- writable: true,
1575
- value: (is) => {
1576
- if (is) {
1577
- this.loadEvent.next();
1578
- }
1579
- }
1580
- });
1581
- Object.defineProperty(this, "onUpdate", {
1582
- enumerable: true,
1583
- configurable: true,
1584
- writable: true,
1585
- value: () => {
1586
- const syncStates = [];
1587
- this.provide.awareness.getStates().forEach((state, id) => {
1588
- syncStates.push({
1589
- clientId: id,
1590
- message: state.message,
1591
- });
1592
- });
1593
- this.stateChangeEvent.next(syncStates);
1594
- }
1595
- });
1596
- this.onLoad = this.loadEvent.asObservable();
1597
- this.onStateChange = this.stateChangeEvent.asObservable();
1598
- this.provide = new WebsocketProvider(url, roomName, yDoc);
1599
- this.provide.once('sync', this.onSync);
1600
- this.provide.awareness.on('update', this.onUpdate);
1601
- }
1602
- setLocalStateField(key, data) {
1603
- this.provide.awareness.setLocalStateField(key, data);
1604
- }
1605
- onDestroy() {
1606
- this.provide.awareness.off('update', this.onUpdate);
1607
- this.provide.disconnect();
1608
- this.provide.destroy();
1609
- }
1610
- }
1611
-
1612
- class CollaborateModule {
1613
- constructor(config) {
1614
- Object.defineProperty(this, "config", {
1615
- enumerable: true,
1616
- configurable: true,
1617
- writable: true,
1618
- value: config
1619
- });
1620
- Object.defineProperty(this, "subscription", {
1621
- enumerable: true,
1622
- configurable: true,
1623
- writable: true,
1624
- value: new Subscription()
1625
- });
1626
- Object.defineProperty(this, "providers", {
1627
- enumerable: true,
1628
- configurable: true,
1629
- writable: true,
1630
- value: [
1631
- Collaborate,
1632
- CollabHistory,
1633
- {
1634
- provide: History,
1635
- useExisting: CollabHistory
1636
- }, {
1637
- provide: SyncConnector,
1638
- useFactory: (collab) => {
1639
- return this.config.createConnector(collab.yDoc);
1640
- },
1641
- deps: [Collaborate]
1642
- }, {
1643
- provide: SubModelLoader,
1644
- useClass: NonSubModelLoader
1645
- }
1646
- ]
1647
- });
1648
- Object.defineProperty(this, "timer", {
1649
- enumerable: true,
1650
- configurable: true,
1651
- writable: true,
1652
- value: null
1653
- });
1654
- }
1655
- setup(textbus) {
1656
- const messageBus = textbus.get(MessageBus, null);
1657
- const connector = textbus.get(SyncConnector);
1658
- const collab = textbus.get(Collaborate);
1659
- if (messageBus) {
1660
- const selection = textbus.get(Selection);
1661
- connector.setLocalStateField('message', messageBus.get(textbus));
1662
- this.subscription.add(messageBus.onSync.subscribe(() => {
1663
- connector.setLocalStateField('message', messageBus.get(textbus));
1664
- }), selection.onChange.subscribe(() => {
1665
- connector.setLocalStateField('message', messageBus.get(textbus));
1666
- }), connector.onStateChange.subscribe((states) => {
1667
- messageBus.consume(states, textbus);
1668
- }));
1669
- }
1670
- return connector.onLoad.toPromise().then(() => {
1671
- if (!this.config.onlyLoad) {
1672
- return;
1673
- }
1674
- const root = collab.yDoc.getMap('RootComponent');
1675
- if (root.has('state')) {
1676
- return;
1677
- }
1678
- return new Promise(resolve => {
1679
- const testing = () => {
1680
- if (root.has('state')) {
1681
- resolve();
1682
- }
1683
- else {
1684
- this.timer = setTimeout(testing, 1000);
1685
- }
1686
- };
1687
- this.timer = setTimeout(testing, 1000);
1688
- });
1689
- });
1690
- }
1691
- onDestroy(textbus) {
1692
- this.subscription.unsubscribe();
1693
- textbus.get(Collaborate).destroy();
1694
- textbus.get(History).destroy();
1695
- textbus.get(SyncConnector).onDestroy();
1696
- clearTimeout(this.timer);
1697
- }
1698
- }
1699
-
1700
- class MultipleDocumentCollaborateModule {
1701
- constructor(config) {
1702
- Object.defineProperty(this, "config", {
1703
- enumerable: true,
1704
- configurable: true,
1705
- writable: true,
1706
- value: config
1707
- });
1708
- Object.defineProperty(this, "subscription", {
1709
- enumerable: true,
1710
- configurable: true,
1711
- writable: true,
1712
- value: new Subscription()
1713
- });
1714
- Object.defineProperty(this, "providers", {
1715
- enumerable: true,
1716
- configurable: true,
1717
- writable: true,
1718
- value: [
1719
- Collaborate,
1720
- MultipleDocCollabHistory,
1721
- {
1722
- provide: History,
1723
- useExisting: MultipleDocCollabHistory
1724
- }, {
1725
- provide: SyncConnector,
1726
- useFactory: (collab) => {
1727
- return this.config.createConnector(collab.yDoc);
1728
- },
1729
- deps: [Collaborate]
1730
- }, {
1731
- provide: SubModelLoader,
1732
- useFactory: () => {
1733
- return this.config.subModelLoader;
1734
- }
1735
- }
1736
- ]
1737
- });
1738
- Object.defineProperty(this, "timer", {
1739
- enumerable: true,
1740
- configurable: true,
1741
- writable: true,
1742
- value: null
1743
- });
1744
- }
1745
- setup(textbus) {
1746
- const messageBus = textbus.get(MessageBus, null);
1747
- const connector = textbus.get(SyncConnector);
1748
- const collab = textbus.get(Collaborate);
1749
- if (messageBus) {
1750
- const selection = textbus.get(Selection);
1751
- connector.setLocalStateField('message', messageBus.get(textbus));
1752
- this.subscription.add(messageBus.onSync.subscribe(() => {
1753
- connector.setLocalStateField('message', messageBus.get(textbus));
1754
- }), selection.onChange.subscribe(() => {
1755
- connector.setLocalStateField('message', messageBus.get(textbus));
1756
- }), connector.onStateChange.subscribe((states) => {
1757
- messageBus.consume(states, textbus);
1758
- }));
1759
- }
1760
- return connector.onLoad.toPromise().then(() => {
1761
- if (!this.config.onlyLoad) {
1762
- return;
1763
- }
1764
- const root = collab.yDoc.getMap('RootComponent');
1765
- if (root.has('state')) {
1766
- return;
1767
- }
1768
- return new Promise(resolve => {
1769
- const testing = () => {
1770
- if (root.has('state')) {
1771
- resolve();
1772
- }
1773
- else {
1774
- this.timer = setTimeout(testing, 1000);
1775
- }
1776
- };
1777
- this.timer = setTimeout(testing, 1000);
1778
- });
1779
- });
1780
- }
1781
- onDestroy(textbus) {
1782
- this.subscription.unsubscribe();
1783
- textbus.get(Collaborate).destroy();
1784
- textbus.get(History).destroy();
1785
- textbus.get(SyncConnector).onDestroy();
1786
- clearTimeout(this.timer);
1787
- }
1788
- }
1789
-
1790
- export { CollabHistory, Collaborate, CollaborateModule, CustomUndoManagerConfig, HocuspocusConnector, MessageBus, MultipleDocCollabHistory, MultipleDocumentCollaborateModule, NonSubModelLoader, SubModelLoader, SyncConnector, YWebsocketConnector };