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;
@@ -16,6 +16,7 @@ export interface LeaderElectionCallbacks {
16
16
  }
17
17
  export interface LeaderElectionConfig {
18
18
  tenant: string;
19
+ windowId: string;
19
20
  callbacks: LeaderElectionCallbacks;
20
21
  }
21
22
  export interface I_LeaderElectionManager {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cry-synced-db-client",
3
- "version": "0.1.53",
3
+ "version": "0.1.54",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",