44library ;
55
66import 'dart:async' ;
7+ import 'dart:convert' ;
78import 'dart:js_interop' ;
89
910import 'package:async/async.dart' ;
@@ -41,12 +42,15 @@ class _SyncWorker {
4142 });
4243 }
4344
44- _SyncRunner referenceSyncTask (String databaseIdentifier,
45- int crudThrottleTimeMs, _ConnectedClient client) {
45+ _SyncRunner referenceSyncTask (
46+ String databaseIdentifier,
47+ int crudThrottleTimeMs,
48+ String ? syncParamsEncoded,
49+ _ConnectedClient client) {
4650 return _requestedSyncTasks.putIfAbsent (databaseIdentifier, () {
47- return _SyncRunner (databaseIdentifier, crudThrottleTimeMs );
51+ return _SyncRunner (databaseIdentifier);
4852 })
49- ..registerClient (client);
53+ ..registerClient (client, crudThrottleTimeMs, syncParamsEncoded );
5054 }
5155}
5256
@@ -64,11 +68,11 @@ class _ConnectedClient {
6468 switch (type) {
6569 case SyncWorkerMessageType .startSynchronization:
6670 final request = payload as StartSynchronization ;
67- _runner = _worker.referenceSyncTask (
68- request.databaseName , request.crudThrottleTimeMs , this );
71+ _runner = _worker.referenceSyncTask (request.databaseName,
72+ request.crudThrottleTimeMs , request.syncParamsEncoded , this );
6973 return (JSObject (), null );
7074 case SyncWorkerMessageType .abortSynchronization:
71- _runner? .unregisterClient (this );
75+ _runner? .disconnectClient (this );
7276 _runner = null ;
7377 return (JSObject (), null );
7478 default :
@@ -105,7 +109,8 @@ class _ConnectedClient {
105109
106110class _SyncRunner {
107111 final String identifier;
108- final int crudThrottleTimeMs;
112+ int crudThrottleTimeMs = 1 ;
113+ String ? syncParamsEncoded;
109114
110115 final StreamGroup <_RunnerEvent > _group = StreamGroup ();
111116 final StreamController <_RunnerEvent > _mainEvents = StreamController ();
@@ -114,24 +119,46 @@ class _SyncRunner {
114119 _ConnectedClient ? databaseHost;
115120 final connections = < _ConnectedClient > [];
116121
117- _SyncRunner (this .identifier, this .crudThrottleTimeMs ) {
122+ _SyncRunner (this .identifier) {
118123 _group.add (_mainEvents.stream);
119124
120125 Future (() async {
121126 await for (final event in _group.stream) {
122127 try {
123128 switch (event) {
124- case _AddConnection (: final client):
129+ case _AddConnection (
130+ : final client,
131+ : final crudThrottleTimeMs,
132+ : final syncParamsEncoded
133+ ):
125134 connections.add (client);
135+ var reconnect = false ;
136+ if (this .crudThrottleTimeMs != crudThrottleTimeMs) {
137+ this .crudThrottleTimeMs = crudThrottleTimeMs;
138+ reconnect = true ;
139+ }
140+ if (this .syncParamsEncoded != syncParamsEncoded) {
141+ this .syncParamsEncoded = syncParamsEncoded;
142+ reconnect = true ;
143+ }
126144 if (sync == null ) {
127145 await _requestDatabase (client);
146+ } else if (reconnect) {
147+ // Parameters changed - reconnect.
148+ sync ? .abort ();
149+ sync = null ;
150+ await _requestDatabase (client);
128151 }
129152 case _RemoveConnection (: final client):
130153 connections.remove (client);
131154 if (connections.isEmpty) {
132155 await sync ? .abort ();
133156 sync = null ;
134157 }
158+ case _DisconnectClient (: final client):
159+ connections.remove (client);
160+ await sync ? .abort ();
161+ sync = null ;
135162 case _ActiveDatabaseClosed ():
136163 _logger.info ('Remote database closed, finding a new client' );
137164 sync ? .abort ();
@@ -226,16 +253,20 @@ class _SyncRunner {
226253 );
227254 }
228255
256+ final syncParams = syncParamsEncoded == null
257+ ? null
258+ : jsonDecode (syncParamsEncoded! ) as Map <String , dynamic >;
259+
229260 sync = StreamingSyncImplementation (
230- adapter: BucketStorage (database),
231- credentialsCallback: client.channel.credentialsCallback,
232- invalidCredentialsCallback: client.channel.invalidCredentialsCallback,
233- uploadCrud: client.channel.uploadCrud,
234- crudUpdateTriggerStream: crudStream,
235- retryDelay: Duration (seconds: 3 ),
236- client: FetchClient (mode: RequestMode .cors),
237- identifier: identifier,
238- );
261+ adapter: BucketStorage (database),
262+ credentialsCallback: client.channel.credentialsCallback,
263+ invalidCredentialsCallback: client.channel.invalidCredentialsCallback,
264+ uploadCrud: client.channel.uploadCrud,
265+ crudUpdateTriggerStream: crudStream,
266+ retryDelay: Duration (seconds: 3 ),
267+ client: FetchClient (mode: RequestMode .cors),
268+ identifier: identifier,
269+ syncParameters : syncParams );
239270 sync ! .statusStream.listen ((event) {
240271 _logger.fine ('Broadcasting sync event: $event ' );
241272 for (final client in connections) {
@@ -246,21 +277,31 @@ class _SyncRunner {
246277 sync ! .streamingSync ();
247278 }
248279
249- void registerClient (_ConnectedClient client) {
250- _mainEvents.add (_AddConnection (client));
280+ void registerClient (_ConnectedClient client, int currentCrudThrottleTimeMs,
281+ String ? currentSyncParamsEncoded) {
282+ _mainEvents.add (_AddConnection (
283+ client, currentCrudThrottleTimeMs, currentSyncParamsEncoded));
251284 }
252285
286+ /// Remove a client, disconnecting if no clients remain..
253287 void unregisterClient (_ConnectedClient client) {
254288 _mainEvents.add (_RemoveConnection (client));
255289 }
290+
291+ /// Remove a client, and immediately disconnect.
292+ void disconnectClient (_ConnectedClient client) {
293+ _mainEvents.add (_DisconnectClient (client));
294+ }
256295}
257296
258297sealed class _RunnerEvent {}
259298
260299final class _AddConnection implements _RunnerEvent {
261300 final _ConnectedClient client;
301+ final int crudThrottleTimeMs;
302+ final String ? syncParamsEncoded;
262303
263- _AddConnection (this .client);
304+ _AddConnection (this .client, this .crudThrottleTimeMs, this .syncParamsEncoded );
264305}
265306
266307final class _RemoveConnection implements _RunnerEvent {
@@ -269,6 +310,12 @@ final class _RemoveConnection implements _RunnerEvent {
269310 _RemoveConnection (this .client);
270311}
271312
313+ final class _DisconnectClient implements _RunnerEvent {
314+ final _ConnectedClient client;
315+
316+ _DisconnectClient (this .client);
317+ }
318+
272319final class _ActiveDatabaseClosed implements _RunnerEvent {
273320 const _ActiveDatabaseClosed ();
274321}
0 commit comments