@textbus/collaborate 4.1.0 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.0",
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.0",
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
- }