@verdant-web/store 2.0.5 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/DocumentManager.js +4 -4
- package/dist/cjs/DocumentManager.js.map +1 -1
- package/dist/cjs/openDocumentDatabase.js +5 -5
- package/dist/cjs/openDocumentDatabase.js.map +1 -1
- package/dist/cjs/queries2/GetQuery.js +1 -1
- package/dist/cjs/queries2/GetQuery.js.map +1 -1
- package/dist/cjs/reactives/Entity.d.ts +0 -1
- package/dist/cjs/reactives/Entity.js +4 -6
- package/dist/cjs/reactives/Entity.js.map +1 -1
- package/dist/cjs/sync/PresenceManager.d.ts +2 -0
- package/dist/cjs/sync/PresenceManager.js +9 -0
- package/dist/cjs/sync/PresenceManager.js.map +1 -1
- package/dist/cjs/sync/Sync.d.ts +12 -2
- package/dist/cjs/sync/Sync.js +24 -13
- package/dist/cjs/sync/Sync.js.map +1 -1
- package/dist/esm/DocumentManager.js +4 -4
- package/dist/esm/DocumentManager.js.map +1 -1
- package/dist/esm/openDocumentDatabase.js +5 -5
- package/dist/esm/openDocumentDatabase.js.map +1 -1
- package/dist/esm/queries2/GetQuery.js +1 -1
- package/dist/esm/queries2/GetQuery.js.map +1 -1
- package/dist/esm/reactives/Entity.d.ts +0 -1
- package/dist/esm/reactives/Entity.js +4 -6
- package/dist/esm/reactives/Entity.js.map +1 -1
- package/dist/esm/sync/PresenceManager.d.ts +2 -0
- package/dist/esm/sync/PresenceManager.js +9 -0
- package/dist/esm/sync/PresenceManager.js.map +1 -1
- package/dist/esm/sync/Sync.d.ts +12 -2
- package/dist/esm/sync/Sync.js +24 -13
- package/dist/esm/sync/Sync.js.map +1 -1
- package/dist/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/DocumentManager.ts +4 -6
- package/src/openDocumentDatabase.ts +4 -5
- package/src/queries2/GetQuery.ts +1 -1
- package/src/reactives/Entity.ts +2 -9
- package/src/sync/PresenceManager.ts +10 -0
- package/src/sync/Sync.ts +36 -15
package/src/sync/Sync.ts
CHANGED
|
@@ -120,13 +120,19 @@ export interface ServerSyncOptions<Profile = any, Presence = any>
|
|
|
120
120
|
* HTTP push/pull to sync changes. If another user joins, both users will
|
|
121
121
|
* be upgraded to websockets.
|
|
122
122
|
*
|
|
123
|
+
* Provide `peers-only` to only automatically use websockets if other
|
|
124
|
+
* users connect, but not if another device for the current user connects.
|
|
125
|
+
* By default, automatic transport selection will upgrade to websockets if
|
|
126
|
+
* another device from the current user connects, but if realtime sync is
|
|
127
|
+
* not necessary for such cases, you can save bandwidth by disabling this.
|
|
128
|
+
*
|
|
123
129
|
* Turning off this feature allows you more control over the transport
|
|
124
130
|
* which can be useful for low-power devices or to save server traffic.
|
|
125
131
|
* To modify transport modes manually, utilize `client.sync.setMode`.
|
|
126
132
|
* The built-in behavior is essentially switching modes based on
|
|
127
133
|
* the number of peers detected by client.sync.presence.
|
|
128
134
|
*/
|
|
129
|
-
automaticTransportSelection?: boolean;
|
|
135
|
+
automaticTransportSelection?: boolean | 'peers-only';
|
|
130
136
|
initialTransport?: SyncTransportMode;
|
|
131
137
|
autoStart?: boolean;
|
|
132
138
|
/**
|
|
@@ -148,7 +154,9 @@ export interface ServerSyncOptions<Profile = any, Presence = any>
|
|
|
148
154
|
}
|
|
149
155
|
|
|
150
156
|
export class ServerSync<Profile = any, Presence = any>
|
|
151
|
-
extends EventSubscriber<
|
|
157
|
+
extends EventSubscriber<
|
|
158
|
+
SyncEvents & { syncingChange: (syncing: boolean) => void }
|
|
159
|
+
>
|
|
152
160
|
implements Sync
|
|
153
161
|
{
|
|
154
162
|
private webSocketSync: WebSocketSync;
|
|
@@ -162,6 +170,7 @@ export class ServerSync<Profile = any, Presence = any>
|
|
|
162
170
|
reset?: boolean;
|
|
163
171
|
}) => Promise<void>;
|
|
164
172
|
private broadcastChannel: BroadcastChannel | null = null;
|
|
173
|
+
private _activelySyncing = false;
|
|
165
174
|
|
|
166
175
|
private meta: Metadata;
|
|
167
176
|
|
|
@@ -250,30 +259,34 @@ export class ServerSync<Profile = any, Presence = any>
|
|
|
250
259
|
this.pushPullSync.subscribe('message', this.handleMessage);
|
|
251
260
|
this.pushPullSync.subscribe('onlineChange', this.handleOnlineChange);
|
|
252
261
|
|
|
253
|
-
if (automaticTransportSelection) {
|
|
262
|
+
if (automaticTransportSelection && this.canDoRealtime) {
|
|
254
263
|
// automatically shift between transport modes depending
|
|
255
264
|
// on whether any peers are present
|
|
256
|
-
|
|
257
|
-
this.presence.subscribe('peersChanged', (peers) => {
|
|
265
|
+
const decideIfUpgrade = () => {
|
|
258
266
|
if (switchoverTimeout) {
|
|
259
267
|
clearTimeout(switchoverTimeout);
|
|
260
268
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
} else if (this.mode === 'realtime') {
|
|
269
|
-
// wait 1 second then switch to pull mode if still
|
|
269
|
+
const hasPeers = Object.keys(this.presence.peers).length > 0;
|
|
270
|
+
const shouldUpgrade =
|
|
271
|
+
hasPeers ||
|
|
272
|
+
(automaticTransportSelection !== 'peers-only' &&
|
|
273
|
+
this.presence.selfReplicaIds.size > 1);
|
|
274
|
+
if (shouldUpgrade && this.mode === 'pull') {
|
|
275
|
+
this.setMode('realtime');
|
|
276
|
+
} else if (!shouldUpgrade && this.mode === 'realtime') {
|
|
277
|
+
// wait 1 second then switch to pull mode if still empty
|
|
270
278
|
switchoverTimeout = setTimeout(() => {
|
|
271
279
|
if (Object.keys(this.presence.peers).length === 0) {
|
|
272
280
|
this.setMode('pull');
|
|
273
281
|
}
|
|
274
282
|
}, 1000);
|
|
275
283
|
}
|
|
276
|
-
}
|
|
284
|
+
};
|
|
285
|
+
let switchoverTimeout: NodeJS.Timer;
|
|
286
|
+
this.presence.subscribe('peersChanged', decideIfUpgrade);
|
|
287
|
+
if (automaticTransportSelection !== 'peers-only') {
|
|
288
|
+
this.presence.subscribe('selfChanged', decideIfUpgrade);
|
|
289
|
+
}
|
|
277
290
|
}
|
|
278
291
|
|
|
279
292
|
if (autoStart) {
|
|
@@ -289,6 +302,10 @@ export class ServerSync<Profile = any, Presence = any>
|
|
|
289
302
|
);
|
|
290
303
|
}
|
|
291
304
|
|
|
305
|
+
get syncing() {
|
|
306
|
+
return this._activelySyncing;
|
|
307
|
+
}
|
|
308
|
+
|
|
292
309
|
private handleBroadcastChannelMessage = (event: MessageEvent) => {
|
|
293
310
|
if (event.data.type === 'sync') {
|
|
294
311
|
this.handleMessage(event.data.message);
|
|
@@ -318,6 +335,8 @@ export class ServerSync<Profile = any, Presence = any>
|
|
|
318
335
|
await this.meta.setGlobalAck(message.timestamp);
|
|
319
336
|
break;
|
|
320
337
|
case 'sync-resp':
|
|
338
|
+
this._activelySyncing = true;
|
|
339
|
+
this.emit('syncingChange', true);
|
|
321
340
|
await this.onData({
|
|
322
341
|
operations: message.operations,
|
|
323
342
|
baselines: message.baselines,
|
|
@@ -329,6 +348,8 @@ export class ServerSync<Profile = any, Presence = any>
|
|
|
329
348
|
}
|
|
330
349
|
|
|
331
350
|
await this.meta.updateLastSynced(message.ackedTimestamp);
|
|
351
|
+
this._activelySyncing = false;
|
|
352
|
+
this.emit('syncingChange', false);
|
|
332
353
|
break;
|
|
333
354
|
case 'need-since':
|
|
334
355
|
this.activeSync.send(
|