@textbus/collaborate 4.1.0 → 4.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.
@@ -0,0 +1,6 @@
1
+ export * from './collab-history';
2
+ export * from './collaborate';
3
+ export * from './message-bus';
4
+ export * from './multiple-doc-collab-history';
5
+ export * from './sub-model-loader';
6
+ export * from './sync-connector';
@@ -0,0 +1,28 @@
1
+ import { Observable, Subject } from '@tanbo/stream';
2
+ import { Textbus } from '@textbus/core';
3
+ export interface Message<T> {
4
+ clientId: number;
5
+ message: T;
6
+ }
7
+ /**
8
+ * 协作消息总线,用于同步各终端消息
9
+ */
10
+ export declare abstract class MessageBus<T> {
11
+ onSync: Observable<void>;
12
+ protected syncEvent: Subject<void>;
13
+ constructor();
14
+ /**
15
+ * 立即同步消息
16
+ */
17
+ sync(): void;
18
+ /**
19
+ * 当需要同步协作消息是,Textbus 会自动调用,并把返回数据同步到其它终端
20
+ */
21
+ abstract get(textbus: Textbus): T;
22
+ /**
23
+ * 当远程消息更新时,Textbus 会自动调用
24
+ * @param message
25
+ * @param textbus
26
+ */
27
+ abstract consume(message: Message<T>[], textbus: Textbus): void;
28
+ }
@@ -1,8 +1,4 @@
1
1
  import { Observable, Subject } from '@tanbo/stream';
2
- export interface SyncState {
3
- clientId: number;
4
- state: Record<string, any>;
5
- }
6
2
  /**
7
3
  * 协作通信通用接口
8
4
  */
@@ -14,9 +10,9 @@ export declare abstract class SyncConnector {
14
10
  /**
15
11
  * 当文档 awareness 状态变更时触发的观察者
16
12
  */
17
- onStateChange: Observable<SyncState[]>;
13
+ onStateChange: Observable<any[]>;
18
14
  protected loadEvent: Subject<void>;
19
- protected stateChangeEvent: Subject<SyncState[]>;
15
+ protected stateChangeEvent: Subject<any[]>;
20
16
  protected constructor();
21
17
  /**
22
18
  * 设置 awareness 状态
@@ -1,14 +1,13 @@
1
1
  import { Module, Textbus } from '@textbus/core';
2
2
  import { Provider } from '@viewfly/core';
3
3
  import { Doc as YDoc } from 'yjs';
4
- import { UserInfo } from './user-activity';
5
- import { SyncConnector } from './sync-connector';
4
+ import { SyncConnector } from './base/_api';
6
5
  export interface CollaborateConfig {
7
- userinfo: UserInfo;
8
6
  createConnector(yDoc: YDoc): SyncConnector;
9
7
  }
10
8
  export declare class CollaborateModule implements Module {
11
9
  config: CollaborateConfig;
10
+ private subscription;
12
11
  providers: Provider[];
13
12
  constructor(config: CollaborateConfig);
14
13
  setup(textbus: Textbus): Promise<(() => void) | void> | (() => void) | void;
@@ -1,6 +1,6 @@
1
1
  import { HocuspocusProvider } from '@hocuspocus/provider';
2
2
  import { HocuspocusProviderConfiguration } from '@hocuspocus/provider';
3
- import { SyncConnector } from '../sync-connector';
3
+ import { SyncConnector } from '../base/sync-connector';
4
4
  export declare class HocuspocusConnector extends SyncConnector {
5
5
  provide: HocuspocusProvider;
6
6
  constructor(config: HocuspocusProviderConfiguration);
@@ -1,6 +1,6 @@
1
1
  import { Doc as YDoc } from 'yjs';
2
2
  import { WebsocketProvider } from 'y-websocket';
3
- import { SyncConnector } from '../sync-connector';
3
+ import { SyncConnector } from '../base/sync-connector';
4
4
  export declare class YWebsocketConnector extends SyncConnector {
5
5
  provide: WebsocketProvider;
6
6
  constructor(url: string, roomName: string, yDoc: YDoc);
@@ -1,79 +1,9 @@
1
- import { HocuspocusProvider } from '@hocuspocus/provider';
2
- import { Subject, map, filter, Subscription } from '@tanbo/stream';
3
- import { WebsocketProvider } from 'y-websocket';
4
1
  import { Injectable, Inject, Optional } from '@viewfly/core';
5
2
  import { makeError, ChangeOrigin, Slot, createObjectProxy, createArrayProxy, AsyncSlot, AsyncComponent, Component, Scheduler, Registry, Selection, HISTORY_STACK_SIZE, RootComponentRef, History } from '@textbus/core';
3
+ import { Subject, map, filter, Subscription } from '@tanbo/stream';
6
4
  import { Doc, createAbsolutePositionFromRelativePosition, createRelativePositionFromTypeIndex, Map, Array as Array$1, Text, UndoManager } from 'yjs';
7
-
8
- /**
9
- * 协作通信通用接口
10
- */
11
- class SyncConnector {
12
- constructor() {
13
- this.loadEvent = new Subject();
14
- this.stateChangeEvent = new Subject();
15
- this.onLoad = this.loadEvent.asObservable();
16
- this.onStateChange = this.stateChangeEvent.asObservable();
17
- }
18
- }
19
-
20
- class HocuspocusConnector extends SyncConnector {
21
- constructor(config) {
22
- super();
23
- this.provide = new HocuspocusProvider(Object.assign(Object.assign({}, config), { onSynced: (data) => {
24
- var _a;
25
- (_a = config.onSynced) === null || _a === void 0 ? void 0 : _a.call(config, data);
26
- this.loadEvent.next();
27
- }, onAwarenessUpdate: (data) => {
28
- var _a;
29
- (_a = config.onAwarenessUpdate) === null || _a === void 0 ? void 0 : _a.call(config, data);
30
- const states = data.states.map(state => {
31
- return {
32
- clientId: state.clientId,
33
- state: Object.assign({}, state)
34
- };
35
- });
36
- this.stateChangeEvent.next(states);
37
- } }));
38
- }
39
- setLocalStateField(key, data) {
40
- this.provide.setAwarenessField(key, data);
41
- }
42
- onDestroy() {
43
- this.provide.disconnect();
44
- this.provide.destroy();
45
- }
46
- }
47
-
48
- class YWebsocketConnector extends SyncConnector {
49
- constructor(url, roomName, yDoc) {
50
- super();
51
- this.onLoad = this.loadEvent.asObservable();
52
- this.onStateChange = this.stateChangeEvent.asObservable();
53
- this.provide = new WebsocketProvider(url, roomName, yDoc);
54
- this.provide.on('sync', (is) => {
55
- if (is) {
56
- this.loadEvent.next();
57
- }
58
- });
59
- this.provide.awareness.on('update', () => {
60
- const syncStates = [];
61
- this.provide.awareness.getStates().forEach((state, id) => {
62
- syncStates.push({
63
- clientId: id,
64
- state: state,
65
- });
66
- });
67
- this.stateChangeEvent.next(syncStates);
68
- });
69
- }
70
- setLocalStateField(key, data) {
71
- this.provide.awareness.setLocalStateField(key, data);
72
- }
73
- onDestroy() {
74
- this.provide.disconnect();
75
- }
76
- }
5
+ import { HocuspocusProvider } from '@hocuspocus/provider';
6
+ import { WebsocketProvider } from 'y-websocket';
77
7
 
78
8
  /******************************************************************************
79
9
  Copyright (c) Microsoft Corporation.
@@ -1033,81 +963,19 @@ CollabHistory = __decorate([
1033
963
  Selection, Number, CustomUndoManagerConfig])
1034
964
  ], CollabHistory);
1035
965
 
1036
- let UserActivity = class UserActivity {
1037
- constructor(syncConnector, selection) {
1038
- this.syncConnector = syncConnector;
1039
- this.selection = selection;
1040
- this.stateChangeEvent = new Subject();
1041
- this.userChangeEvent = new Subject();
1042
- this.subscription = new Subscription();
1043
- this.onStateChange = this.stateChangeEvent.asObservable();
1044
- this.onUserChange = this.userChangeEvent.asObservable();
1045
- }
1046
- init(userinfo) {
1047
- this.syncConnector.setLocalStateField('user', userinfo);
1048
- this.subscription.add(this.selection.onChange.subscribe(() => {
1049
- const selection = this.selection.getPaths();
1050
- this.syncConnector.setLocalStateField('selection', Object.assign(Object.assign({}, userinfo), { selection }));
1051
- }), this.syncConnector.onStateChange.subscribe((states) => {
1052
- const users = [];
1053
- const remoteSelections = [];
1054
- states.forEach(item => {
1055
- const state = item.state;
1056
- if (state.user) {
1057
- users.push(state.user);
1058
- }
1059
- if (state.selection) {
1060
- remoteSelections.push(state.selection);
1061
- }
1062
- });
1063
- const selections = remoteSelections.filter(i => i.id !== userinfo.id);
1064
- this.userChangeEvent.next(users);
1065
- this.stateChangeEvent.next(selections);
1066
- }));
1067
- }
1068
- destroy() {
1069
- this.subscription.unsubscribe();
1070
- }
1071
- };
1072
- UserActivity = __decorate([
1073
- Injectable(),
1074
- __metadata("design:paramtypes", [SyncConnector,
1075
- Selection])
1076
- ], UserActivity);
1077
-
1078
- class CollaborateModule {
1079
- constructor(config) {
1080
- this.config = config;
1081
- this.providers = [
1082
- Collaborate,
1083
- UserActivity,
1084
- CollabHistory,
1085
- {
1086
- provide: History,
1087
- useExisting: CollabHistory
1088
- }, {
1089
- provide: SyncConnector,
1090
- useFactory: (collab) => {
1091
- return this.config.createConnector(collab.yDoc);
1092
- },
1093
- deps: [Collaborate]
1094
- }, {
1095
- provide: SubModelLoader,
1096
- useClass: NonSubModelLoader
1097
- }
1098
- ];
1099
- }
1100
- setup(textbus) {
1101
- const connector = textbus.get(SyncConnector);
1102
- const userActivity = textbus.get(UserActivity);
1103
- userActivity.init(this.config.userinfo);
1104
- return connector.onLoad.toPromise();
966
+ /**
967
+ * 协作消息总线,用于同步各终端消息
968
+ */
969
+ class MessageBus {
970
+ constructor() {
971
+ this.syncEvent = new Subject();
972
+ this.onSync = this.syncEvent.asObservable();
1105
973
  }
1106
- onDestroy(textbus) {
1107
- textbus.get(Collaborate).destroy();
1108
- textbus.get(History).destroy();
1109
- textbus.get(UserActivity).destroy();
1110
- textbus.get(SyncConnector).onDestroy();
974
+ /**
975
+ * 立即同步消息
976
+ */
977
+ sync() {
978
+ this.syncEvent.next();
1111
979
  }
1112
980
  }
1113
981
 
@@ -1289,12 +1157,128 @@ MultipleDocCollabHistory = __decorate([
1289
1157
  RootComponentRef, Number, CustomUndoManagerConfig])
1290
1158
  ], MultipleDocCollabHistory);
1291
1159
 
1160
+ /**
1161
+ * 协作通信通用接口
1162
+ */
1163
+ class SyncConnector {
1164
+ constructor() {
1165
+ this.loadEvent = new Subject();
1166
+ this.stateChangeEvent = new Subject();
1167
+ this.onLoad = this.loadEvent.asObservable();
1168
+ this.onStateChange = this.stateChangeEvent.asObservable();
1169
+ }
1170
+ }
1171
+
1172
+ class HocuspocusConnector extends SyncConnector {
1173
+ constructor(config) {
1174
+ super();
1175
+ this.provide = new HocuspocusProvider(Object.assign(Object.assign({}, config), { onSynced: (data) => {
1176
+ var _a;
1177
+ (_a = config.onSynced) === null || _a === void 0 ? void 0 : _a.call(config, data);
1178
+ this.loadEvent.next();
1179
+ }, onAwarenessUpdate: (data) => {
1180
+ var _a;
1181
+ (_a = config.onAwarenessUpdate) === null || _a === void 0 ? void 0 : _a.call(config, data);
1182
+ const states = data.states.map(state => {
1183
+ return {
1184
+ clientId: state.clientId,
1185
+ message: state.message
1186
+ };
1187
+ });
1188
+ this.stateChangeEvent.next(states);
1189
+ } }));
1190
+ }
1191
+ setLocalStateField(key, data) {
1192
+ this.provide.setAwarenessField(key, data);
1193
+ }
1194
+ onDestroy() {
1195
+ this.provide.disconnect();
1196
+ this.provide.destroy();
1197
+ }
1198
+ }
1199
+
1200
+ class YWebsocketConnector extends SyncConnector {
1201
+ constructor(url, roomName, yDoc) {
1202
+ super();
1203
+ this.onLoad = this.loadEvent.asObservable();
1204
+ this.onStateChange = this.stateChangeEvent.asObservable();
1205
+ this.provide = new WebsocketProvider(url, roomName, yDoc);
1206
+ this.provide.on('sync', (is) => {
1207
+ if (is) {
1208
+ this.loadEvent.next();
1209
+ }
1210
+ });
1211
+ this.provide.awareness.on('update', () => {
1212
+ const syncStates = [];
1213
+ this.provide.awareness.getStates().forEach((state, id) => {
1214
+ syncStates.push({
1215
+ clientId: id,
1216
+ message: state.message,
1217
+ });
1218
+ });
1219
+ this.stateChangeEvent.next(syncStates);
1220
+ });
1221
+ }
1222
+ setLocalStateField(key, data) {
1223
+ this.provide.awareness.setLocalStateField(key, data);
1224
+ }
1225
+ onDestroy() {
1226
+ this.provide.disconnect();
1227
+ }
1228
+ }
1229
+
1230
+ class CollaborateModule {
1231
+ constructor(config) {
1232
+ this.config = config;
1233
+ this.subscription = new Subscription();
1234
+ this.providers = [
1235
+ Collaborate,
1236
+ CollabHistory,
1237
+ {
1238
+ provide: History,
1239
+ useExisting: CollabHistory
1240
+ }, {
1241
+ provide: SyncConnector,
1242
+ useFactory: (collab) => {
1243
+ return this.config.createConnector(collab.yDoc);
1244
+ },
1245
+ deps: [Collaborate]
1246
+ }, {
1247
+ provide: SubModelLoader,
1248
+ useClass: NonSubModelLoader
1249
+ }
1250
+ ];
1251
+ }
1252
+ setup(textbus) {
1253
+ const messageBus = textbus.get(MessageBus, null);
1254
+ const connector = textbus.get(SyncConnector);
1255
+ if (messageBus) {
1256
+ const selection = textbus.get(Selection);
1257
+ connector.setLocalStateField('message', messageBus.get(textbus));
1258
+ this.subscription.add(messageBus.onSync.subscribe(() => {
1259
+ connector.setLocalStateField('message', messageBus.get(textbus));
1260
+ }), selection.onChange.subscribe(() => {
1261
+ connector.setLocalStateField('message', messageBus.get(textbus));
1262
+ }), connector.onStateChange.subscribe((states) => {
1263
+ messageBus.consume(states, textbus);
1264
+ }));
1265
+ }
1266
+ return connector.onLoad.toPromise();
1267
+ }
1268
+ onDestroy(textbus) {
1269
+ this.subscription.unsubscribe();
1270
+ textbus.get(Collaborate).destroy();
1271
+ textbus.get(History).destroy();
1272
+ textbus.get(SyncConnector).onDestroy();
1273
+ }
1274
+ }
1275
+
1292
1276
  class MultipleDocumentCollaborateModule {
1293
1277
  constructor(config) {
1294
1278
  this.config = config;
1279
+ this.subscription = new Subscription();
1295
1280
  this.providers = [
1296
1281
  Collaborate,
1297
- UserActivity,
1298
1282
  MultipleDocCollabHistory,
1299
1283
  {
1300
1284
  provide: History,
@@ -1314,17 +1298,27 @@ class MultipleDocumentCollaborateModule {
1314
1298
  ];
1315
1299
  }
1316
1300
  setup(textbus) {
1301
+ const messageBus = textbus.get(MessageBus, null);
1317
1302
  const connector = textbus.get(SyncConnector);
1318
- const userActivity = textbus.get(UserActivity);
1319
- userActivity.init(this.config.userinfo);
1303
+ if (messageBus) {
1304
+ const selection = textbus.get(Selection);
1305
+ connector.setLocalStateField('message', messageBus.get(textbus));
1306
+ this.subscription.add(messageBus.onSync.subscribe(() => {
1307
+ connector.setLocalStateField('message', messageBus.get(textbus));
1308
+ }), selection.onChange.subscribe(() => {
1309
+ connector.setLocalStateField('message', messageBus.get(textbus));
1310
+ }), connector.onStateChange.subscribe((states) => {
1311
+ messageBus.consume(states, textbus);
1312
+ }));
1313
+ }
1320
1314
  return connector.onLoad.toPromise();
1321
1315
  }
1322
1316
  onDestroy(textbus) {
1317
+ this.subscription.unsubscribe();
1323
1318
  textbus.get(Collaborate).destroy();
1324
1319
  textbus.get(History).destroy();
1325
- textbus.get(UserActivity).destroy();
1326
1320
  textbus.get(SyncConnector).onDestroy();
1327
1321
  }
1328
1322
  }
1329
1323
 
1330
- export { CollabHistory, Collaborate, CollaborateModule, CustomUndoManagerConfig, HocuspocusConnector, MultipleDocCollabHistory, MultipleDocumentCollaborateModule, NonSubModelLoader, SubModelLoader, SyncConnector, UserActivity, YWebsocketConnector };
1324
+ export { CollabHistory, Collaborate, CollaborateModule, CustomUndoManagerConfig, HocuspocusConnector, MessageBus, MultipleDocCollabHistory, MultipleDocumentCollaborateModule, NonSubModelLoader, SubModelLoader, SyncConnector, YWebsocketConnector };
package/bundles/index.js CHANGED
@@ -1,81 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var provider = require('@hocuspocus/provider');
4
- var stream = require('@tanbo/stream');
5
- var yWebsocket = require('y-websocket');
6
3
  var core$1 = require('@viewfly/core');
7
4
  var core = require('@textbus/core');
5
+ var stream = require('@tanbo/stream');
8
6
  var yjs = require('yjs');
9
-
10
- /**
11
- * 协作通信通用接口
12
- */
13
- class SyncConnector {
14
- constructor() {
15
- this.loadEvent = new stream.Subject();
16
- this.stateChangeEvent = new stream.Subject();
17
- this.onLoad = this.loadEvent.asObservable();
18
- this.onStateChange = this.stateChangeEvent.asObservable();
19
- }
20
- }
21
-
22
- class HocuspocusConnector extends SyncConnector {
23
- constructor(config) {
24
- super();
25
- this.provide = new provider.HocuspocusProvider(Object.assign(Object.assign({}, config), { onSynced: (data) => {
26
- var _a;
27
- (_a = config.onSynced) === null || _a === void 0 ? void 0 : _a.call(config, data);
28
- this.loadEvent.next();
29
- }, onAwarenessUpdate: (data) => {
30
- var _a;
31
- (_a = config.onAwarenessUpdate) === null || _a === void 0 ? void 0 : _a.call(config, data);
32
- const states = data.states.map(state => {
33
- return {
34
- clientId: state.clientId,
35
- state: Object.assign({}, state)
36
- };
37
- });
38
- this.stateChangeEvent.next(states);
39
- } }));
40
- }
41
- setLocalStateField(key, data) {
42
- this.provide.setAwarenessField(key, data);
43
- }
44
- onDestroy() {
45
- this.provide.disconnect();
46
- this.provide.destroy();
47
- }
48
- }
49
-
50
- class YWebsocketConnector extends SyncConnector {
51
- constructor(url, roomName, yDoc) {
52
- super();
53
- this.onLoad = this.loadEvent.asObservable();
54
- this.onStateChange = this.stateChangeEvent.asObservable();
55
- this.provide = new yWebsocket.WebsocketProvider(url, roomName, yDoc);
56
- this.provide.on('sync', (is) => {
57
- if (is) {
58
- this.loadEvent.next();
59
- }
60
- });
61
- this.provide.awareness.on('update', () => {
62
- const syncStates = [];
63
- this.provide.awareness.getStates().forEach((state, id) => {
64
- syncStates.push({
65
- clientId: id,
66
- state: state,
67
- });
68
- });
69
- this.stateChangeEvent.next(syncStates);
70
- });
71
- }
72
- setLocalStateField(key, data) {
73
- this.provide.awareness.setLocalStateField(key, data);
74
- }
75
- onDestroy() {
76
- this.provide.disconnect();
77
- }
78
- }
7
+ var provider = require('@hocuspocus/provider');
8
+ var yWebsocket = require('y-websocket');
79
9
 
80
10
  /******************************************************************************
81
11
  Copyright (c) Microsoft Corporation.
@@ -1035,81 +965,19 @@ exports.CollabHistory = __decorate([
1035
965
  core.Selection, Number, CustomUndoManagerConfig])
1036
966
  ], exports.CollabHistory);
1037
967
 
1038
- exports.UserActivity = class UserActivity {
1039
- constructor(syncConnector, selection) {
1040
- this.syncConnector = syncConnector;
1041
- this.selection = selection;
1042
- this.stateChangeEvent = new stream.Subject();
1043
- this.userChangeEvent = new stream.Subject();
1044
- this.subscription = new stream.Subscription();
1045
- this.onStateChange = this.stateChangeEvent.asObservable();
1046
- this.onUserChange = this.userChangeEvent.asObservable();
1047
- }
1048
- init(userinfo) {
1049
- this.syncConnector.setLocalStateField('user', userinfo);
1050
- this.subscription.add(this.selection.onChange.subscribe(() => {
1051
- const selection = this.selection.getPaths();
1052
- this.syncConnector.setLocalStateField('selection', Object.assign(Object.assign({}, userinfo), { selection }));
1053
- }), this.syncConnector.onStateChange.subscribe((states) => {
1054
- const users = [];
1055
- const remoteSelections = [];
1056
- states.forEach(item => {
1057
- const state = item.state;
1058
- if (state.user) {
1059
- users.push(state.user);
1060
- }
1061
- if (state.selection) {
1062
- remoteSelections.push(state.selection);
1063
- }
1064
- });
1065
- const selections = remoteSelections.filter(i => i.id !== userinfo.id);
1066
- this.userChangeEvent.next(users);
1067
- this.stateChangeEvent.next(selections);
1068
- }));
1069
- }
1070
- destroy() {
1071
- this.subscription.unsubscribe();
1072
- }
1073
- };
1074
- exports.UserActivity = __decorate([
1075
- core$1.Injectable(),
1076
- __metadata("design:paramtypes", [SyncConnector,
1077
- core.Selection])
1078
- ], exports.UserActivity);
1079
-
1080
- class CollaborateModule {
1081
- constructor(config) {
1082
- this.config = config;
1083
- this.providers = [
1084
- exports.Collaborate,
1085
- exports.UserActivity,
1086
- exports.CollabHistory,
1087
- {
1088
- provide: core.History,
1089
- useExisting: exports.CollabHistory
1090
- }, {
1091
- provide: SyncConnector,
1092
- useFactory: (collab) => {
1093
- return this.config.createConnector(collab.yDoc);
1094
- },
1095
- deps: [exports.Collaborate]
1096
- }, {
1097
- provide: SubModelLoader,
1098
- useClass: exports.NonSubModelLoader
1099
- }
1100
- ];
1101
- }
1102
- setup(textbus) {
1103
- const connector = textbus.get(SyncConnector);
1104
- const userActivity = textbus.get(exports.UserActivity);
1105
- userActivity.init(this.config.userinfo);
1106
- return connector.onLoad.toPromise();
968
+ /**
969
+ * 协作消息总线,用于同步各终端消息
970
+ */
971
+ class MessageBus {
972
+ constructor() {
973
+ this.syncEvent = new stream.Subject();
974
+ this.onSync = this.syncEvent.asObservable();
1107
975
  }
1108
- onDestroy(textbus) {
1109
- textbus.get(exports.Collaborate).destroy();
1110
- textbus.get(core.History).destroy();
1111
- textbus.get(exports.UserActivity).destroy();
1112
- textbus.get(SyncConnector).onDestroy();
976
+ /**
977
+ * 立即同步消息
978
+ */
979
+ sync() {
980
+ this.syncEvent.next();
1113
981
  }
1114
982
  }
1115
983
 
@@ -1291,12 +1159,128 @@ exports.MultipleDocCollabHistory = __decorate([
1291
1159
  core.RootComponentRef, Number, CustomUndoManagerConfig])
1292
1160
  ], exports.MultipleDocCollabHistory);
1293
1161
 
1162
+ /**
1163
+ * 协作通信通用接口
1164
+ */
1165
+ class SyncConnector {
1166
+ constructor() {
1167
+ this.loadEvent = new stream.Subject();
1168
+ this.stateChangeEvent = new stream.Subject();
1169
+ this.onLoad = this.loadEvent.asObservable();
1170
+ this.onStateChange = this.stateChangeEvent.asObservable();
1171
+ }
1172
+ }
1173
+
1174
+ class HocuspocusConnector extends SyncConnector {
1175
+ constructor(config) {
1176
+ super();
1177
+ this.provide = new provider.HocuspocusProvider(Object.assign(Object.assign({}, config), { onSynced: (data) => {
1178
+ var _a;
1179
+ (_a = config.onSynced) === null || _a === void 0 ? void 0 : _a.call(config, data);
1180
+ this.loadEvent.next();
1181
+ }, onAwarenessUpdate: (data) => {
1182
+ var _a;
1183
+ (_a = config.onAwarenessUpdate) === null || _a === void 0 ? void 0 : _a.call(config, data);
1184
+ const states = data.states.map(state => {
1185
+ return {
1186
+ clientId: state.clientId,
1187
+ message: state.message
1188
+ };
1189
+ });
1190
+ this.stateChangeEvent.next(states);
1191
+ } }));
1192
+ }
1193
+ setLocalStateField(key, data) {
1194
+ this.provide.setAwarenessField(key, data);
1195
+ }
1196
+ onDestroy() {
1197
+ this.provide.disconnect();
1198
+ this.provide.destroy();
1199
+ }
1200
+ }
1201
+
1202
+ class YWebsocketConnector extends SyncConnector {
1203
+ constructor(url, roomName, yDoc) {
1204
+ super();
1205
+ this.onLoad = this.loadEvent.asObservable();
1206
+ this.onStateChange = this.stateChangeEvent.asObservable();
1207
+ this.provide = new yWebsocket.WebsocketProvider(url, roomName, yDoc);
1208
+ this.provide.on('sync', (is) => {
1209
+ if (is) {
1210
+ this.loadEvent.next();
1211
+ }
1212
+ });
1213
+ this.provide.awareness.on('update', () => {
1214
+ const syncStates = [];
1215
+ this.provide.awareness.getStates().forEach((state, id) => {
1216
+ syncStates.push({
1217
+ clientId: id,
1218
+ message: state.message,
1219
+ });
1220
+ });
1221
+ this.stateChangeEvent.next(syncStates);
1222
+ });
1223
+ }
1224
+ setLocalStateField(key, data) {
1225
+ this.provide.awareness.setLocalStateField(key, data);
1226
+ }
1227
+ onDestroy() {
1228
+ this.provide.disconnect();
1229
+ }
1230
+ }
1231
+
1232
+ class CollaborateModule {
1233
+ constructor(config) {
1234
+ this.config = config;
1235
+ this.subscription = new stream.Subscription();
1236
+ this.providers = [
1237
+ exports.Collaborate,
1238
+ exports.CollabHistory,
1239
+ {
1240
+ provide: core.History,
1241
+ useExisting: exports.CollabHistory
1242
+ }, {
1243
+ provide: SyncConnector,
1244
+ useFactory: (collab) => {
1245
+ return this.config.createConnector(collab.yDoc);
1246
+ },
1247
+ deps: [exports.Collaborate]
1248
+ }, {
1249
+ provide: SubModelLoader,
1250
+ useClass: exports.NonSubModelLoader
1251
+ }
1252
+ ];
1253
+ }
1254
+ setup(textbus) {
1255
+ const messageBus = textbus.get(MessageBus, null);
1256
+ const connector = textbus.get(SyncConnector);
1257
+ if (messageBus) {
1258
+ const selection = textbus.get(core.Selection);
1259
+ connector.setLocalStateField('message', messageBus.get(textbus));
1260
+ this.subscription.add(messageBus.onSync.subscribe(() => {
1261
+ connector.setLocalStateField('message', messageBus.get(textbus));
1262
+ }), selection.onChange.subscribe(() => {
1263
+ connector.setLocalStateField('message', messageBus.get(textbus));
1264
+ }), connector.onStateChange.subscribe((states) => {
1265
+ messageBus.consume(states, textbus);
1266
+ }));
1267
+ }
1268
+ return connector.onLoad.toPromise();
1269
+ }
1270
+ onDestroy(textbus) {
1271
+ this.subscription.unsubscribe();
1272
+ textbus.get(exports.Collaborate).destroy();
1273
+ textbus.get(core.History).destroy();
1274
+ textbus.get(SyncConnector).onDestroy();
1275
+ }
1276
+ }
1277
+
1294
1278
  class MultipleDocumentCollaborateModule {
1295
1279
  constructor(config) {
1296
1280
  this.config = config;
1281
+ this.subscription = new stream.Subscription();
1297
1282
  this.providers = [
1298
1283
  exports.Collaborate,
1299
- exports.UserActivity,
1300
1284
  exports.MultipleDocCollabHistory,
1301
1285
  {
1302
1286
  provide: core.History,
@@ -1316,15 +1300,25 @@ class MultipleDocumentCollaborateModule {
1316
1300
  ];
1317
1301
  }
1318
1302
  setup(textbus) {
1303
+ const messageBus = textbus.get(MessageBus, null);
1319
1304
  const connector = textbus.get(SyncConnector);
1320
- const userActivity = textbus.get(exports.UserActivity);
1321
- userActivity.init(this.config.userinfo);
1305
+ if (messageBus) {
1306
+ const selection = textbus.get(core.Selection);
1307
+ connector.setLocalStateField('message', messageBus.get(textbus));
1308
+ this.subscription.add(messageBus.onSync.subscribe(() => {
1309
+ connector.setLocalStateField('message', messageBus.get(textbus));
1310
+ }), selection.onChange.subscribe(() => {
1311
+ connector.setLocalStateField('message', messageBus.get(textbus));
1312
+ }), connector.onStateChange.subscribe((states) => {
1313
+ messageBus.consume(states, textbus);
1314
+ }));
1315
+ }
1322
1316
  return connector.onLoad.toPromise();
1323
1317
  }
1324
1318
  onDestroy(textbus) {
1319
+ this.subscription.unsubscribe();
1325
1320
  textbus.get(exports.Collaborate).destroy();
1326
1321
  textbus.get(core.History).destroy();
1327
- textbus.get(exports.UserActivity).destroy();
1328
1322
  textbus.get(SyncConnector).onDestroy();
1329
1323
  }
1330
1324
  }
@@ -1332,6 +1326,7 @@ class MultipleDocumentCollaborateModule {
1332
1326
  exports.CollaborateModule = CollaborateModule;
1333
1327
  exports.CustomUndoManagerConfig = CustomUndoManagerConfig;
1334
1328
  exports.HocuspocusConnector = HocuspocusConnector;
1329
+ exports.MessageBus = MessageBus;
1335
1330
  exports.MultipleDocumentCollaborateModule = MultipleDocumentCollaborateModule;
1336
1331
  exports.SubModelLoader = SubModelLoader;
1337
1332
  exports.SyncConnector = SyncConnector;
@@ -1,12 +1,13 @@
1
1
  import { Module, Textbus } from '@textbus/core';
2
2
  import { Provider } from '@viewfly/core';
3
+ import { SubModelLoader } from './base/_api';
3
4
  import { CollaborateConfig } from './collaborate-module';
4
- import { SubModelLoader } from './sub-model-loader';
5
5
  export interface MultipleDocCollaborateConfig extends CollaborateConfig {
6
6
  subModelLoader: SubModelLoader;
7
7
  }
8
8
  export declare class MultipleDocumentCollaborateModule implements Module {
9
9
  config: MultipleDocCollaborateConfig;
10
+ private subscription;
10
11
  providers: Provider[];
11
12
  constructor(config: MultipleDocCollaborateConfig);
12
13
  setup(textbus: Textbus): Promise<(() => void) | void> | (() => void) | void;
@@ -1,9 +1,4 @@
1
+ export * from './base/_api';
1
2
  export * from './connectors/_api';
2
- export * from './collab-history';
3
- export * from './collaborate';
4
3
  export * from './collaborate-module';
5
- export * from './multiple-doc-collab-history';
6
4
  export * from './multiple-document-collaborate-module';
7
- export * from './sub-model-loader';
8
- export * from './sync-connector';
9
- export * from './user-activity';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@textbus/collaborate",
3
- "version": "4.1.0",
3
+ "version": "4.2.1",
4
4
  "description": "Textbus is a rich text editor and framework that is highly customizable and extensible to achieve rich wysiwyg effects.",
5
5
  "main": "./bundles/index.js",
6
6
  "module": "./bundles/index.esm.js",
@@ -27,7 +27,7 @@
27
27
  "dependencies": {
28
28
  "@hocuspocus/provider": "^2.13.6",
29
29
  "@tanbo/stream": "^1.2.5",
30
- "@textbus/core": "^4.1.0",
30
+ "@textbus/core": "^4.2.1",
31
31
  "@viewfly/core": "^1.0.5",
32
32
  "y-websocket": "^1.4.3",
33
33
  "yjs": "^13.6.14"
@@ -1,23 +0,0 @@
1
- import { Observable } from '@tanbo/stream';
2
- import { Selection, SelectionPaths } from '@textbus/core';
3
- import { SyncConnector } from './sync-connector';
4
- export interface UserInfo {
5
- username: string;
6
- color: string;
7
- id: string;
8
- }
9
- export interface ActivityInfo extends UserInfo {
10
- selection: SelectionPaths;
11
- }
12
- export declare class UserActivity {
13
- private syncConnector;
14
- private selection;
15
- onStateChange: Observable<ActivityInfo[]>;
16
- onUserChange: Observable<UserInfo[]>;
17
- private stateChangeEvent;
18
- private userChangeEvent;
19
- private subscription;
20
- constructor(syncConnector: SyncConnector, selection: Selection);
21
- init(userinfo: UserInfo): void;
22
- destroy(): void;
23
- }