@@ -10,6 +10,7 @@ import type {
1010 ConnectDoc ,
1111 ConnectDocResult ,
1212 CRDTDoc ,
13+ EntityID ,
1314 ObjectID ,
1415 ObjectData ,
1516 ObjectType ,
@@ -22,18 +23,12 @@ interface EntityState {
2223}
2324
2425export class SyncProvider {
25- protected connectLocal : ConnectDoc | null ;
26- protected connectRemote : ConnectDoc | null ;
26+ private connectLocal : ConnectDoc | null ;
27+ private connectRemote : ConnectDoc | null ;
2728
28- protected configs : Map < ObjectType , SyncConfig > = new Map <
29- ObjectType ,
30- SyncConfig
31- > ( ) ;
32-
33- protected entityStates : Map < string , EntityState > = new Map <
34- string ,
35- EntityState
36- > ( ) ;
29+ protected configs : Map < ObjectType , SyncConfig > = new Map ( ) ;
30+ protected connections : Map < EntityID , ConnectDocResult [ ] > = new Map ( ) ;
31+ protected entityStates : Map < EntityID , EntityState > = new Map ( ) ;
3732
3833 /**
3934 * Constructor.
@@ -49,6 +44,26 @@ export class SyncProvider {
4944 this . connectRemote = connectRemote ;
5045 }
5146
47+ /**
48+ * Connect to a document.
49+ *
50+ * @param {ObjectID } objectId Object ID to connect.
51+ * @param {ObjectType } objectType Object type to connect.
52+ * @param {CRDTDoc } ydoc Yjs document for the object.
53+ */
54+ private async connect (
55+ objectId : ObjectID ,
56+ objectType : ObjectType ,
57+ ydoc : CRDTDoc
58+ ) : Promise < ConnectDocResult [ ] > {
59+ return (
60+ await Promise . all ( [
61+ this . connectLocal ?.( objectId , objectType , ydoc ) ,
62+ this . connectRemote ?.( objectId , objectType , ydoc ) ,
63+ ] )
64+ ) . filter ( ( result ) : result is ConnectDocResult => Boolean ( result ) ) ;
65+ }
66+
5267 /**
5368 * Fetch data from local database or remote source.
5469 *
@@ -64,41 +79,31 @@ export class SyncProvider {
6479 const ydoc = new Y . Doc ( { meta : new Map ( ) } ) ;
6580 const objectId = syncConfig . getObjectId ( initialData ) ;
6681 const objectType = syncConfig . objectType ;
82+ const connections = await this . connect ( objectId , objectType , ydoc ) ;
6783 const entityId = this . getEntityId ( objectType , objectId ) ;
6884
69- this . configs . set ( objectType , syncConfig ) ;
85+ const onDestroy = ( ) : void => {
86+ connections . forEach ( ( result ) => result . destroy ( ) ) ;
87+ ydoc . off ( 'update' , onUpdate ) ;
88+ ydoc . destroy ( ) ;
89+ this . entityStates . delete ( entityId ) ;
90+ } ;
7091
71- const updateHandler : ( _update : Uint8Array , origin : string ) => void = (
72- _update ,
73- origin
74- ) : void => {
92+ const onUpdate = ( _update : Uint8Array , origin : string ) : void => {
7593 if ( origin !== 'gutenberg' ) {
7694 const data = syncConfig . fromCRDTDoc ( ydoc ) ;
7795 handleChanges ( data ) ;
7896 }
7997 } ;
8098
81- ydoc . on ( 'update' , updateHandler ) ;
82-
83- const connectLocalResult : ConnectDocResult | null =
84- ( await this . connectLocal ?.( objectId , objectType , ydoc ) ) ?? null ;
85- const connectRemoteResult =
86- ( await this . connectRemote ?.( objectId , objectType , ydoc ) ) ??
87- null ;
88-
89- const entityState : EntityState = {
90- destroy : ( ) => {
91- connectLocalResult ?. destroy ?.( ) ;
92- connectRemoteResult ?. destroy ?.( ) ;
99+ ydoc . on ( 'update' , onUpdate ) ;
93100
94- ydoc . off ( 'update' , updateHandler ) ;
95- ydoc . destroy ( ) ;
96- this . entityStates . delete ( entityId ) ;
97- } ,
101+ this . configs . set ( objectType , syncConfig ) ;
102+ this . connections . set ( entityId , connections ) ;
103+ this . entityStates . set ( entityId , {
98104 ydoc,
99- } ;
100-
101- this . entityStates . set ( entityId , entityState ) ;
105+ destroy : onDestroy ,
106+ } ) ;
102107
103108 this . update ( objectType , initialData , initialData , 'gutenberg' ) ;
104109 }
@@ -112,7 +117,7 @@ export class SyncProvider {
112117 protected getEntityId (
113118 objectType : ObjectType ,
114119 objectId : ObjectID
115- ) : string {
120+ ) : EntityID {
116121 return `${ objectType } _${ objectId } ` ;
117122 }
118123
@@ -168,9 +173,6 @@ export class SyncProvider {
168173 * @param {ObjectID } objectId Object ID to discard.
169174 */
170175 public discard ( objectType : ObjectType , objectId : ObjectID ) : void {
171- const entityId = `${ objectType } _${ objectId } ` ;
172-
173176 this . getEntityState ( objectType , objectId ) ?. destroy ( ) ;
174- this . entityStates . delete ( entityId ) ;
175177 }
176178}
0 commit comments