cry-synced-db-client 0.1.53 → 0.1.54
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/index.js
CHANGED
|
@@ -274,6 +274,7 @@ class InMemManager {
|
|
|
274
274
|
// src/db/managers/LeaderElectionManager.ts
|
|
275
275
|
class LeaderElectionManager {
|
|
276
276
|
tenant;
|
|
277
|
+
windowId;
|
|
277
278
|
callbacks;
|
|
278
279
|
isLeaderFlag = false;
|
|
279
280
|
closing = false;
|
|
@@ -285,11 +286,12 @@ class LeaderElectionManager {
|
|
|
285
286
|
visibilityChangeHandler;
|
|
286
287
|
constructor(config) {
|
|
287
288
|
this.tenant = config.tenant;
|
|
289
|
+
this.windowId = config.windowId;
|
|
288
290
|
this.callbacks = config.callbacks;
|
|
289
291
|
}
|
|
290
292
|
init() {
|
|
291
293
|
if (typeof BroadcastChannel !== "undefined") {
|
|
292
|
-
this.leaderReelectionChannel = new BroadcastChannel(`synced-db-leader-reelection-${this.tenant}`);
|
|
294
|
+
this.leaderReelectionChannel = new BroadcastChannel(`synced-db-leader-reelection-${this.tenant}-${this.windowId}`);
|
|
293
295
|
this.leaderReelectionChannel.onmessage = (event) => {
|
|
294
296
|
if (event.data?.type === "reelect-leader") {
|
|
295
297
|
this.handleLeaderReelection();
|
|
@@ -328,7 +330,7 @@ class LeaderElectionManager {
|
|
|
328
330
|
this.becameLeaderPromise = new Promise((resolve) => {
|
|
329
331
|
this.becameLeaderResolve = resolve;
|
|
330
332
|
});
|
|
331
|
-
const lockName = `synced-db-leader-${this.tenant}`;
|
|
333
|
+
const lockName = `synced-db-leader-${this.tenant}-${this.windowId}`;
|
|
332
334
|
navigator.locks.request(lockName, { mode: "exclusive" }, () => {
|
|
333
335
|
this.isLeaderFlag = true;
|
|
334
336
|
this.callOnBecameLeader();
|
|
@@ -2695,6 +2697,7 @@ class SyncedDb {
|
|
|
2695
2697
|
this.serverUpdateNotifier = config.serverUpdateNotifier;
|
|
2696
2698
|
this.updaterId = Math.random().toString(36).substring(2, 15);
|
|
2697
2699
|
this.syncedDbInstanceId = `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
2700
|
+
const windowId = this.getOrCreateWindowId();
|
|
2698
2701
|
this.onSync = config.onSync;
|
|
2699
2702
|
this.onConflictResolved = config.onConflictResolved;
|
|
2700
2703
|
this.onWsNotification = config.onWsNotification;
|
|
@@ -2709,6 +2712,7 @@ class SyncedDb {
|
|
|
2709
2712
|
});
|
|
2710
2713
|
this.leaderElection = new LeaderElectionManager({
|
|
2711
2714
|
tenant: this.tenant,
|
|
2715
|
+
windowId,
|
|
2712
2716
|
callbacks: {
|
|
2713
2717
|
onBecameLeader: config.onBecameLeader,
|
|
2714
2718
|
onLostLeadership: config.onLostLeadership,
|
|
@@ -3277,6 +3281,18 @@ class SyncedDb {
|
|
|
3277
3281
|
deleteObjectsMetadata(collection, _ids) {
|
|
3278
3282
|
this.inMemManager.deleteObjectsMetadata(collection, _ids);
|
|
3279
3283
|
}
|
|
3284
|
+
getOrCreateWindowId() {
|
|
3285
|
+
const storageKey = `synced-db-window-id-${this.tenant}`;
|
|
3286
|
+
if (typeof sessionStorage !== "undefined") {
|
|
3287
|
+
let windowId = sessionStorage.getItem(storageKey);
|
|
3288
|
+
if (!windowId) {
|
|
3289
|
+
windowId = `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
3290
|
+
sessionStorage.setItem(storageKey, windowId);
|
|
3291
|
+
}
|
|
3292
|
+
return windowId;
|
|
3293
|
+
}
|
|
3294
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
3295
|
+
}
|
|
3280
3296
|
assertCollection(name) {
|
|
3281
3297
|
if (!this.collections.has(name)) {
|
|
3282
3298
|
throw new Error(`Collection "${name}" not configured`);
|
|
@@ -79,5 +79,11 @@ export declare class SyncedDb implements I_SyncedDb {
|
|
|
79
79
|
setObjectsMetadata<M>(collection: string, _ids: Id[], metadatas: M[]): void;
|
|
80
80
|
deleteObjectMetadata(collection: string, _id: Id): void;
|
|
81
81
|
deleteObjectsMetadata(collection: string, _ids: Id[]): void;
|
|
82
|
+
/**
|
|
83
|
+
* Get or create a window-scoped ID.
|
|
84
|
+
* Persists across page reloads but unique per browser window.
|
|
85
|
+
* Used for window-scoped leader election.
|
|
86
|
+
*/
|
|
87
|
+
private getOrCreateWindowId;
|
|
82
88
|
private assertCollection;
|
|
83
89
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import type { I_LeaderElectionManager, LeaderElectionConfig } from "../types/managers";
|
|
8
8
|
export declare class LeaderElectionManager implements I_LeaderElectionManager {
|
|
9
9
|
private readonly tenant;
|
|
10
|
+
private readonly windowId;
|
|
10
11
|
private readonly callbacks;
|
|
11
12
|
private isLeaderFlag;
|
|
12
13
|
private closing;
|