@textbus/collaborate 5.1.6 → 5.2.1

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