Skip to content

Commit 323eaab

Browse files
committed
Update SyncProvider for better extensibility
1 parent 76b6288 commit 323eaab

File tree

2 files changed

+42
-39
lines changed

2 files changed

+42
-39
lines changed

packages/sync/src/provider.ts

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -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

2425
export 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
}

packages/sync/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type * as Y from 'yjs';
55
import type { Awareness } from 'y-protocols/awareness';
66

77
export type * as Y from 'yjs';
8+
export type EntityID = string;
89
export type ObjectID = string;
910
export type ObjectType = string;
1011
export type ObjectData = object;

0 commit comments

Comments
 (0)