@textbus/collaborate 4.0.0-alpha.74 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,14 +1,16 @@
1
1
  import { Module, Textbus } from '@textbus/core';
2
2
  import { Provider } from '@viewfly/core';
3
+ import { Doc as YDoc } from 'yjs';
3
4
  import { UserInfo } from './user-activity';
5
+ import { SyncConnector } from './sync-connector';
4
6
  export interface CollaborateConfig {
5
- url: string;
6
- roomName: string;
7
7
  userinfo: UserInfo;
8
+ createConnector(yDoc: YDoc): SyncConnector;
8
9
  }
9
10
  export declare class CollaborateModule implements Module {
10
11
  config: CollaborateConfig;
11
12
  providers: Provider[];
12
13
  constructor(config: CollaborateConfig);
13
14
  setup(textbus: Textbus): Promise<(() => void) | void> | (() => void) | void;
15
+ onDestroy(textbus: Textbus): void;
14
16
  }
@@ -0,0 +1,2 @@
1
+ export * from './hocuspocus-connector';
2
+ export * from './y-websocket-connector';
@@ -0,0 +1,13 @@
1
+ import { Observable } from '@tanbo/stream';
2
+ import { HocuspocusProviderConfiguration } from '@hocuspocus/provider';
3
+ import { SyncConnector } from '../sync-connector';
4
+ export declare class HocuspocusConnector extends SyncConnector {
5
+ onLoad: Observable<void>;
6
+ onStateChange: Observable<any>;
7
+ private loadEvent;
8
+ private stateChangeEvent;
9
+ private provide;
10
+ constructor(config: HocuspocusProviderConfiguration);
11
+ setLocalStateField(key: string, data: Record<string, any>): void;
12
+ onDestroy(): void;
13
+ }
@@ -0,0 +1,13 @@
1
+ import { Doc as YDoc } from 'yjs';
2
+ import { Observable } from '@tanbo/stream';
3
+ import { SyncConnector } from '../sync-connector';
4
+ export declare class YWebsocketConnector extends SyncConnector {
5
+ onLoad: Observable<void>;
6
+ onStateChange: Observable<any>;
7
+ private provide;
8
+ private loadEvent;
9
+ private stateChangeEvent;
10
+ constructor(url: string, roomName: string, yDoc: YDoc);
11
+ setLocalStateField(key: string, data: Record<string, any>): void;
12
+ onDestroy(): void;
13
+ }
@@ -1,8 +1,70 @@
1
- import { Injectable, Inject, Optional } from '@viewfly/core';
2
1
  import { Subject, map, filter, Subscription } from '@tanbo/stream';
2
+ import { HocuspocusProvider } from '@hocuspocus/provider';
3
+ import { WebsocketProvider } from 'y-websocket';
4
+ import { Injectable, Inject, Optional } from '@viewfly/core';
3
5
  import { makeError, HISTORY_STACK_SIZE, ChangeOrigin, createObjectProxy, createArrayProxy, Slot, RootComponentRef, Scheduler, Registry, Selection, History } from '@textbus/core';
4
6
  import { Doc, UndoManager, Map, Array as Array$1, Text, createAbsolutePositionFromRelativePosition, createRelativePositionFromTypeIndex } from 'yjs';
5
- import { WebsocketProvider } from 'y-websocket';
7
+
8
+ /**
9
+ * 协作通信通用接口
10
+ */
11
+ class SyncConnector {
12
+ }
13
+
14
+ class HocuspocusConnector extends SyncConnector {
15
+ constructor(config) {
16
+ super();
17
+ this.loadEvent = new Subject();
18
+ this.stateChangeEvent = new Subject();
19
+ this.onLoad = this.loadEvent.asObservable();
20
+ this.onStateChange = this.stateChangeEvent.asObservable();
21
+ this.provide = new HocuspocusProvider(Object.assign(Object.assign({}, config), { onSynced: (data) => {
22
+ var _a;
23
+ (_a = config.onSynced) === null || _a === void 0 ? void 0 : _a.call(config, data);
24
+ this.loadEvent.next();
25
+ }, onAwarenessUpdate: (data) => {
26
+ var _a;
27
+ (_a = config.onAwarenessUpdate) === null || _a === void 0 ? void 0 : _a.call(config, data);
28
+ data.states.forEach(state => {
29
+ this.stateChangeEvent.next(state);
30
+ });
31
+ } }));
32
+ }
33
+ setLocalStateField(key, data) {
34
+ this.provide.setAwarenessField(key, data);
35
+ }
36
+ onDestroy() {
37
+ this.provide.disconnect();
38
+ this.provide.destroy();
39
+ }
40
+ }
41
+
42
+ class YWebsocketConnector extends SyncConnector {
43
+ constructor(url, roomName, yDoc) {
44
+ super();
45
+ this.loadEvent = new Subject();
46
+ this.stateChangeEvent = new Subject();
47
+ this.onLoad = this.loadEvent.asObservable();
48
+ this.onStateChange = this.stateChangeEvent.asObservable();
49
+ this.provide = new WebsocketProvider(url, roomName, yDoc);
50
+ this.provide.on('sync', (is) => {
51
+ if (is) {
52
+ this.loadEvent.next();
53
+ }
54
+ });
55
+ this.provide.awareness.on('update', () => {
56
+ this.provide.awareness.getStates().forEach(state => {
57
+ this.stateChangeEvent.next(state);
58
+ });
59
+ });
60
+ }
61
+ setLocalStateField(key, data) {
62
+ this.provide.awareness.setLocalStateField(key, data);
63
+ }
64
+ onDestroy() {
65
+ this.provide.disconnect();
66
+ }
67
+ }
6
68
 
7
69
  /******************************************************************************
8
70
  Copyright (c) Microsoft Corporation.
@@ -737,8 +799,8 @@ function remoteFormatsToLocal(registry, attrs) {
737
799
  }
738
800
 
739
801
  let UserActivity = class UserActivity {
740
- constructor(websocketProvider, selection) {
741
- this.websocketProvider = websocketProvider;
802
+ constructor(syncConnector, selection) {
803
+ this.syncConnector = syncConnector;
742
804
  this.selection = selection;
743
805
  this.stateChangeEvent = new Subject();
744
806
  this.userChangeEvent = new Subject();
@@ -747,27 +809,23 @@ let UserActivity = class UserActivity {
747
809
  this.onUserChange = this.userChangeEvent.asObservable();
748
810
  }
749
811
  init(userinfo) {
750
- const provide = this.websocketProvider;
751
- provide.awareness.setLocalStateField('user', userinfo);
812
+ this.syncConnector.setLocalStateField('user', userinfo);
752
813
  this.subscription.add(this.selection.onChange.subscribe(() => {
753
814
  const selection = this.selection.getPaths();
754
- provide.awareness.setLocalStateField('selection', Object.assign(Object.assign({}, userinfo), { selection }));
755
- }));
756
- provide.awareness.on('update', () => {
815
+ this.syncConnector.setLocalStateField('selection', Object.assign(Object.assign({}, userinfo), { selection }));
816
+ }), this.syncConnector.onStateChange.subscribe((state) => {
757
817
  const users = [];
758
818
  const remoteSelections = [];
759
- provide.awareness.getStates().forEach(state => {
760
- if (state.user) {
761
- users.push(state.user);
762
- }
763
- if (state.selection) {
764
- remoteSelections.push(state.selection);
765
- }
766
- });
819
+ if (state.user) {
820
+ users.push(state.user);
821
+ }
822
+ if (state.selection) {
823
+ remoteSelections.push(state.selection);
824
+ }
767
825
  const selections = remoteSelections.filter(i => i.id !== userinfo.id);
768
826
  this.userChangeEvent.next(users);
769
827
  this.stateChangeEvent.next(selections);
770
- });
828
+ }));
771
829
  }
772
830
  destroy() {
773
831
  this.subscription.unsubscribe();
@@ -775,7 +833,7 @@ let UserActivity = class UserActivity {
775
833
  };
776
834
  UserActivity = __decorate([
777
835
  Injectable(),
778
- __metadata("design:paramtypes", [WebsocketProvider,
836
+ __metadata("design:paramtypes", [SyncConnector,
779
837
  Selection])
780
838
  ], UserActivity);
781
839
 
@@ -789,29 +847,24 @@ class CollaborateModule {
789
847
  provide: History,
790
848
  useExisting: Collaborate
791
849
  }, {
792
- provide: WebsocketProvider,
850
+ provide: SyncConnector,
793
851
  useFactory: (collab) => {
794
- return new WebsocketProvider(this.config.url, this.config.roomName, collab.yDoc);
852
+ return this.config.createConnector(collab.yDoc);
795
853
  },
796
854
  deps: [Collaborate]
797
855
  }
798
856
  ];
799
857
  }
800
858
  setup(textbus) {
801
- const provide = textbus.get(WebsocketProvider);
859
+ const connector = textbus.get(SyncConnector);
802
860
  const userActivity = textbus.get(UserActivity);
803
861
  userActivity.init(this.config.userinfo);
804
- return new Promise((resolve) => {
805
- provide.on('sync', (is) => {
806
- if (is) {
807
- resolve(() => {
808
- provide.disconnect();
809
- userActivity.destroy();
810
- });
811
- }
812
- });
813
- });
862
+ return connector.onLoad.toPromise();
863
+ }
864
+ onDestroy(textbus) {
865
+ textbus.get(UserActivity).destroy();
866
+ textbus.get(SyncConnector).onDestroy();
814
867
  }
815
868
  }
816
869
 
817
- export { Collaborate, CollaborateModule, CustomUndoManagerConfig, UserActivity };
870
+ export { Collaborate, CollaborateModule, CustomUndoManagerConfig, HocuspocusConnector, SyncConnector, UserActivity, YWebsocketConnector };
package/bundles/index.js CHANGED
@@ -1,10 +1,72 @@
1
1
  'use strict';
2
2
 
3
- var core$1 = require('@viewfly/core');
4
3
  var stream = require('@tanbo/stream');
4
+ var provider = require('@hocuspocus/provider');
5
+ var yWebsocket = require('y-websocket');
6
+ var core$1 = require('@viewfly/core');
5
7
  var core = require('@textbus/core');
6
8
  var yjs = require('yjs');
7
- var yWebsocket = require('y-websocket');
9
+
10
+ /**
11
+ * 协作通信通用接口
12
+ */
13
+ class SyncConnector {
14
+ }
15
+
16
+ class HocuspocusConnector extends SyncConnector {
17
+ constructor(config) {
18
+ super();
19
+ this.loadEvent = new stream.Subject();
20
+ this.stateChangeEvent = new stream.Subject();
21
+ this.onLoad = this.loadEvent.asObservable();
22
+ this.onStateChange = this.stateChangeEvent.asObservable();
23
+ this.provide = new provider.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
+ data.states.forEach(state => {
31
+ this.stateChangeEvent.next(state);
32
+ });
33
+ } }));
34
+ }
35
+ setLocalStateField(key, data) {
36
+ this.provide.setAwarenessField(key, data);
37
+ }
38
+ onDestroy() {
39
+ this.provide.disconnect();
40
+ this.provide.destroy();
41
+ }
42
+ }
43
+
44
+ class YWebsocketConnector extends SyncConnector {
45
+ constructor(url, roomName, yDoc) {
46
+ super();
47
+ this.loadEvent = new stream.Subject();
48
+ this.stateChangeEvent = new stream.Subject();
49
+ this.onLoad = this.loadEvent.asObservable();
50
+ this.onStateChange = this.stateChangeEvent.asObservable();
51
+ this.provide = new yWebsocket.WebsocketProvider(url, roomName, yDoc);
52
+ this.provide.on('sync', (is) => {
53
+ if (is) {
54
+ this.loadEvent.next();
55
+ }
56
+ });
57
+ this.provide.awareness.on('update', () => {
58
+ this.provide.awareness.getStates().forEach(state => {
59
+ this.stateChangeEvent.next(state);
60
+ });
61
+ });
62
+ }
63
+ setLocalStateField(key, data) {
64
+ this.provide.awareness.setLocalStateField(key, data);
65
+ }
66
+ onDestroy() {
67
+ this.provide.disconnect();
68
+ }
69
+ }
8
70
 
9
71
  /******************************************************************************
10
72
  Copyright (c) Microsoft Corporation.
@@ -739,8 +801,8 @@ function remoteFormatsToLocal(registry, attrs) {
739
801
  }
740
802
 
741
803
  exports.UserActivity = class UserActivity {
742
- constructor(websocketProvider, selection) {
743
- this.websocketProvider = websocketProvider;
804
+ constructor(syncConnector, selection) {
805
+ this.syncConnector = syncConnector;
744
806
  this.selection = selection;
745
807
  this.stateChangeEvent = new stream.Subject();
746
808
  this.userChangeEvent = new stream.Subject();
@@ -749,27 +811,23 @@ exports.UserActivity = class UserActivity {
749
811
  this.onUserChange = this.userChangeEvent.asObservable();
750
812
  }
751
813
  init(userinfo) {
752
- const provide = this.websocketProvider;
753
- provide.awareness.setLocalStateField('user', userinfo);
814
+ this.syncConnector.setLocalStateField('user', userinfo);
754
815
  this.subscription.add(this.selection.onChange.subscribe(() => {
755
816
  const selection = this.selection.getPaths();
756
- provide.awareness.setLocalStateField('selection', Object.assign(Object.assign({}, userinfo), { selection }));
757
- }));
758
- provide.awareness.on('update', () => {
817
+ this.syncConnector.setLocalStateField('selection', Object.assign(Object.assign({}, userinfo), { selection }));
818
+ }), this.syncConnector.onStateChange.subscribe((state) => {
759
819
  const users = [];
760
820
  const remoteSelections = [];
761
- provide.awareness.getStates().forEach(state => {
762
- if (state.user) {
763
- users.push(state.user);
764
- }
765
- if (state.selection) {
766
- remoteSelections.push(state.selection);
767
- }
768
- });
821
+ if (state.user) {
822
+ users.push(state.user);
823
+ }
824
+ if (state.selection) {
825
+ remoteSelections.push(state.selection);
826
+ }
769
827
  const selections = remoteSelections.filter(i => i.id !== userinfo.id);
770
828
  this.userChangeEvent.next(users);
771
829
  this.stateChangeEvent.next(selections);
772
- });
830
+ }));
773
831
  }
774
832
  destroy() {
775
833
  this.subscription.unsubscribe();
@@ -777,7 +835,7 @@ exports.UserActivity = class UserActivity {
777
835
  };
778
836
  exports.UserActivity = __decorate([
779
837
  core$1.Injectable(),
780
- __metadata("design:paramtypes", [yWebsocket.WebsocketProvider,
838
+ __metadata("design:paramtypes", [SyncConnector,
781
839
  core.Selection])
782
840
  ], exports.UserActivity);
783
841
 
@@ -791,30 +849,28 @@ class CollaborateModule {
791
849
  provide: core.History,
792
850
  useExisting: exports.Collaborate
793
851
  }, {
794
- provide: yWebsocket.WebsocketProvider,
852
+ provide: SyncConnector,
795
853
  useFactory: (collab) => {
796
- return new yWebsocket.WebsocketProvider(this.config.url, this.config.roomName, collab.yDoc);
854
+ return this.config.createConnector(collab.yDoc);
797
855
  },
798
856
  deps: [exports.Collaborate]
799
857
  }
800
858
  ];
801
859
  }
802
860
  setup(textbus) {
803
- const provide = textbus.get(yWebsocket.WebsocketProvider);
861
+ const connector = textbus.get(SyncConnector);
804
862
  const userActivity = textbus.get(exports.UserActivity);
805
863
  userActivity.init(this.config.userinfo);
806
- return new Promise((resolve) => {
807
- provide.on('sync', (is) => {
808
- if (is) {
809
- resolve(() => {
810
- provide.disconnect();
811
- userActivity.destroy();
812
- });
813
- }
814
- });
815
- });
864
+ return connector.onLoad.toPromise();
865
+ }
866
+ onDestroy(textbus) {
867
+ textbus.get(exports.UserActivity).destroy();
868
+ textbus.get(SyncConnector).onDestroy();
816
869
  }
817
870
  }
818
871
 
819
872
  exports.CollaborateModule = CollaborateModule;
820
873
  exports.CustomUndoManagerConfig = CustomUndoManagerConfig;
874
+ exports.HocuspocusConnector = HocuspocusConnector;
875
+ exports.SyncConnector = SyncConnector;
876
+ exports.YWebsocketConnector = YWebsocketConnector;
@@ -1,3 +1,5 @@
1
+ export * from './connectors/_api';
1
2
  export * from './collaborate';
2
3
  export * from './collaborate-module';
4
+ export * from './sync-connector';
3
5
  export * from './user-activity';
@@ -0,0 +1,10 @@
1
+ import { Observable } from '@tanbo/stream';
2
+ /**
3
+ * 协作通信通用接口
4
+ */
5
+ export declare abstract class SyncConnector {
6
+ abstract onLoad: Observable<void>;
7
+ abstract onStateChange: Observable<any>;
8
+ abstract setLocalStateField(key: string, data: Record<string, any>): void;
9
+ abstract onDestroy(): void;
10
+ }
@@ -1,6 +1,6 @@
1
1
  import { Observable } from '@tanbo/stream';
2
2
  import { Selection, SelectionPaths } from '@textbus/core';
3
- import { WebsocketProvider } from 'y-websocket';
3
+ import { SyncConnector } from './sync-connector';
4
4
  export interface UserInfo {
5
5
  username: string;
6
6
  color: string;
@@ -10,14 +10,14 @@ export interface ActivityInfo extends UserInfo {
10
10
  selection: SelectionPaths;
11
11
  }
12
12
  export declare class UserActivity {
13
- private websocketProvider;
13
+ private syncConnector;
14
14
  private selection;
15
15
  onStateChange: Observable<ActivityInfo[]>;
16
16
  onUserChange: Observable<UserInfo[]>;
17
17
  private stateChangeEvent;
18
18
  private userChangeEvent;
19
19
  private subscription;
20
- constructor(websocketProvider: WebsocketProvider, selection: Selection);
20
+ constructor(syncConnector: SyncConnector, selection: Selection);
21
21
  init(userinfo: UserInfo): void;
22
22
  destroy(): void;
23
23
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@textbus/collaborate",
3
- "version": "4.0.0-alpha.74",
3
+ "version": "4.0.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",
@@ -25,8 +25,9 @@
25
25
  "typescript editor"
26
26
  ],
27
27
  "dependencies": {
28
+ "@hocuspocus/provider": "^2.13.6",
28
29
  "@tanbo/stream": "^1.2.5",
29
- "@textbus/core": "^4.0.0-alpha.74",
30
+ "@textbus/core": "^4.0.0",
30
31
  "@viewfly/core": "^1.0.0-alpha.22",
31
32
  "y-websocket": "^1.4.3",
32
33
  "yjs": "^13.6.14"
@@ -49,5 +50,5 @@
49
50
  "bugs": {
50
51
  "url": "https://github.com/textbus/textbus.git/issues"
51
52
  },
52
- "gitHead": "fcd0c2f0e5111a1019cdd92144cde932fb4f5acd"
53
+ "gitHead": "cf4fd289b73bc777124a32fe42bb58eba05a34f1"
53
54
  }