cry-synced-db-client 0.1.113 → 0.1.115
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
|
@@ -3427,7 +3427,7 @@ var SyncedDb = class _SyncedDb {
|
|
|
3427
3427
|
this.syncOnlyCollections = null;
|
|
3428
3428
|
// Sync metadata cache
|
|
3429
3429
|
this.syncMetaCache = /* @__PURE__ */ new Map();
|
|
3430
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
3430
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
3431
3431
|
this.tenant = config.tenant;
|
|
3432
3432
|
this.dexieDb = config.dexieDb;
|
|
3433
3433
|
this.inMemDb = config.inMemDb;
|
|
@@ -3435,9 +3435,11 @@ var SyncedDb = class _SyncedDb {
|
|
|
3435
3435
|
this.serverUpdateNotifier = config.serverUpdateNotifier;
|
|
3436
3436
|
this.updaterId = Math.random().toString(36).substring(2, 15);
|
|
3437
3437
|
this.syncedDbInstanceId = `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
this.
|
|
3438
|
+
this.dexieLoadConcurrency = (_a = config.dexieLoadConcurrency) != null ? _a : 1;
|
|
3439
|
+
const windowId = (_b = config._testWindowId) != null ? _b : this.getOrCreateWindowId();
|
|
3440
|
+
this.defaultReturnDeleted = (_c = config.returnDeleted) != null ? _c : false;
|
|
3441
|
+
this.defaultReturnArchived = (_d = config.returnArchived) != null ? _d : false;
|
|
3442
|
+
this.onDatabaseCreated = config.onDatabaseCreated;
|
|
3441
3443
|
this.onSyncStart = config.onSyncStart;
|
|
3442
3444
|
this.onSyncEnd = config.onSyncEnd;
|
|
3443
3445
|
this.onDexieSyncStart = config.onDexieSyncStart;
|
|
@@ -3455,7 +3457,7 @@ var SyncedDb = class _SyncedDb {
|
|
|
3455
3457
|
this.inMemManager = new InMemManager({
|
|
3456
3458
|
inMemDb: this.inMemDb,
|
|
3457
3459
|
collections: this.collections,
|
|
3458
|
-
useObjectMetadata: (
|
|
3460
|
+
useObjectMetadata: (_e = config.useObjectMetadata) != null ? _e : false
|
|
3459
3461
|
});
|
|
3460
3462
|
this.leaderElection = new LeaderElectionManager({
|
|
3461
3463
|
tenant: this.tenant,
|
|
@@ -3477,7 +3479,7 @@ var SyncedDb = class _SyncedDb {
|
|
|
3477
3479
|
tenant: this.tenant,
|
|
3478
3480
|
instanceId: this.syncedDbInstanceId,
|
|
3479
3481
|
windowId,
|
|
3480
|
-
debounceMs: (
|
|
3482
|
+
debounceMs: (_f = config.crossTabSyncDebounceMs) != null ? _f : 100,
|
|
3481
3483
|
callbacks: {
|
|
3482
3484
|
onCrossTabSync: config.onCrossTabSync,
|
|
3483
3485
|
onInfrastructureError: config.onInfrastructureError ? (type, message, error) => {
|
|
@@ -3503,8 +3505,8 @@ var SyncedDb = class _SyncedDb {
|
|
|
3503
3505
|
});
|
|
3504
3506
|
this.connectionManager = new ConnectionManager({
|
|
3505
3507
|
restInterface: this.restInterface,
|
|
3506
|
-
restTimeoutMs: (
|
|
3507
|
-
syncTimeoutMs: (
|
|
3508
|
+
restTimeoutMs: (_g = config.restTimeoutMs) != null ? _g : 9e4,
|
|
3509
|
+
syncTimeoutMs: (_h = config.syncTimeoutMs) != null ? _h : 12e4,
|
|
3508
3510
|
autoSyncIntervalMs: config.autoSyncIntervalMs,
|
|
3509
3511
|
callbacks: {
|
|
3510
3512
|
onOnlineStatusChange: config.onOnlineStatusChange,
|
|
@@ -3530,8 +3532,8 @@ var SyncedDb = class _SyncedDb {
|
|
|
3530
3532
|
});
|
|
3531
3533
|
this.pendingChanges = new PendingChangesManager({
|
|
3532
3534
|
tenant: this.tenant,
|
|
3533
|
-
debounceDexieWritesMs: (
|
|
3534
|
-
debounceRestWritesMs: (
|
|
3535
|
+
debounceDexieWritesMs: (_i = config.debounceDexieWritesMs) != null ? _i : 500,
|
|
3536
|
+
debounceRestWritesMs: (_j = config.debounceRestWritesMs) != null ? _j : 100,
|
|
3535
3537
|
callbacks: {
|
|
3536
3538
|
onDexieWriteRequest: config.onDexieWriteRequest,
|
|
3537
3539
|
onDexieWriteResult: config.onDexieWriteResult,
|
|
@@ -3608,8 +3610,8 @@ var SyncedDb = class _SyncedDb {
|
|
|
3608
3610
|
});
|
|
3609
3611
|
if (config.wakeSyncEnabled) {
|
|
3610
3612
|
this.wakeSync = new WakeSyncManager({
|
|
3611
|
-
gapThresholdMs: (
|
|
3612
|
-
debounceMs: (
|
|
3613
|
+
gapThresholdMs: (_k = config.wakeSyncGapThresholdMs) != null ? _k : 1e4,
|
|
3614
|
+
debounceMs: (_l = config.wakeSyncDebounceMs) != null ? _l : 2e3,
|
|
3613
3615
|
callbacks: {
|
|
3614
3616
|
onWakeSync: config.onWakeSync
|
|
3615
3617
|
},
|
|
@@ -3624,7 +3626,7 @@ var SyncedDb = class _SyncedDb {
|
|
|
3624
3626
|
}
|
|
3625
3627
|
if (config.networkStatusEnabled) {
|
|
3626
3628
|
this.networkStatus = new NetworkStatusManager({
|
|
3627
|
-
debounceMs: (
|
|
3629
|
+
debounceMs: (_m = config.networkStatusDebounceMs) != null ? _m : 100,
|
|
3628
3630
|
callbacks: {
|
|
3629
3631
|
onBrowserNetworkChange: config.onBrowserNetworkChange,
|
|
3630
3632
|
onBrowserOnline: config.onBrowserOnline,
|
|
@@ -3667,16 +3669,7 @@ var SyncedDb = class _SyncedDb {
|
|
|
3667
3669
|
}
|
|
3668
3670
|
}
|
|
3669
3671
|
if (newlyAllowed.length > 0) {
|
|
3670
|
-
|
|
3671
|
-
let totalItems = 0;
|
|
3672
|
-
this.safeCallback(this.onDexieSyncStart, { calledFrom: "setSyncOnlyTheseCollections", collectionCount: newlyAllowed.length });
|
|
3673
|
-
for (let i = 0; i < newlyAllowed.length; i++) {
|
|
3674
|
-
const name = newlyAllowed[i];
|
|
3675
|
-
const items = await this.loadCollectionToInMem(name);
|
|
3676
|
-
totalItems += items;
|
|
3677
|
-
this.safeCallback(this.onSyncProgress, { collection: name, loaded: i + 1, total: newlyAllowed.length, items });
|
|
3678
|
-
}
|
|
3679
|
-
this.safeCallback(this.onDexieSyncEnd, { calledFrom: "setSyncOnlyTheseCollections", collectionCount: newlyAllowed.length, totalItems, durationMs: Date.now() - dexieStart });
|
|
3672
|
+
await this.loadCollectionsToInMem(newlyAllowed, "setSyncOnlyTheseCollections");
|
|
3680
3673
|
}
|
|
3681
3674
|
if (newlyAllowed.length > 0 && this.connectionManager.canSync()) {
|
|
3682
3675
|
this.sync("setSyncOnlyTheseCollections").catch(() => {
|
|
@@ -3714,18 +3707,16 @@ var SyncedDb = class _SyncedDb {
|
|
|
3714
3707
|
}
|
|
3715
3708
|
await this._loadLastFullSync();
|
|
3716
3709
|
await this._loadLastInitialSync();
|
|
3710
|
+
if (this.dexieDb.isNewDatabase() && this.onDatabaseCreated) {
|
|
3711
|
+
try {
|
|
3712
|
+
this.onDatabaseCreated();
|
|
3713
|
+
} catch (err) {
|
|
3714
|
+
console.error("onDatabaseCreated callback failed:", err);
|
|
3715
|
+
}
|
|
3716
|
+
}
|
|
3717
3717
|
await this.pendingChanges.recoverPendingWrites();
|
|
3718
3718
|
const allowedColls = [...this.collections.keys()].filter((n) => this.isSyncAllowed(n));
|
|
3719
|
-
|
|
3720
|
-
let totalItems = 0;
|
|
3721
|
-
this.safeCallback(this.onDexieSyncStart, { calledFrom: "init", collectionCount: allowedColls.length });
|
|
3722
|
-
for (let i = 0; i < allowedColls.length; i++) {
|
|
3723
|
-
const name = allowedColls[i];
|
|
3724
|
-
const items = await this.loadCollectionToInMem(name);
|
|
3725
|
-
totalItems += items;
|
|
3726
|
-
this.safeCallback(this.onSyncProgress, { collection: name, loaded: i + 1, total: allowedColls.length, items });
|
|
3727
|
-
}
|
|
3728
|
-
this.safeCallback(this.onDexieSyncEnd, { calledFrom: "init", collectionCount: allowedColls.length, totalItems, durationMs: Date.now() - dexieStart });
|
|
3719
|
+
await this.loadCollectionsToInMem(allowedColls, "init");
|
|
3729
3720
|
this.leaderElection.init();
|
|
3730
3721
|
this.crossTabSync.init();
|
|
3731
3722
|
(_a = this.wakeSync) == null ? void 0 : _a.init();
|
|
@@ -4558,6 +4549,47 @@ var SyncedDb = class _SyncedDb {
|
|
|
4558
4549
|
}
|
|
4559
4550
|
}
|
|
4560
4551
|
}
|
|
4552
|
+
/**
|
|
4553
|
+
* Load multiple collections from Dexie into in-mem with concurrency control.
|
|
4554
|
+
* @returns total items loaded
|
|
4555
|
+
*/
|
|
4556
|
+
async loadCollectionsToInMem(names, calledFrom) {
|
|
4557
|
+
if (names.length === 0) return 0;
|
|
4558
|
+
const dexieStart = Date.now();
|
|
4559
|
+
let totalItems = 0;
|
|
4560
|
+
let loaded = 0;
|
|
4561
|
+
this.safeCallback(this.onDexieSyncStart, {
|
|
4562
|
+
calledFrom,
|
|
4563
|
+
collectionCount: names.length
|
|
4564
|
+
});
|
|
4565
|
+
const concurrency = this.dexieLoadConcurrency;
|
|
4566
|
+
const queue = [...names];
|
|
4567
|
+
const workers = Array.from(
|
|
4568
|
+
{ length: Math.min(concurrency, queue.length) },
|
|
4569
|
+
async () => {
|
|
4570
|
+
while (queue.length > 0) {
|
|
4571
|
+
const name = queue.shift();
|
|
4572
|
+
const items = await this.loadCollectionToInMem(name);
|
|
4573
|
+
totalItems += items;
|
|
4574
|
+
loaded++;
|
|
4575
|
+
this.safeCallback(this.onSyncProgress, {
|
|
4576
|
+
collection: name,
|
|
4577
|
+
loaded,
|
|
4578
|
+
total: names.length,
|
|
4579
|
+
items
|
|
4580
|
+
});
|
|
4581
|
+
}
|
|
4582
|
+
}
|
|
4583
|
+
);
|
|
4584
|
+
await Promise.all(workers);
|
|
4585
|
+
this.safeCallback(this.onDexieSyncEnd, {
|
|
4586
|
+
calledFrom,
|
|
4587
|
+
collectionCount: names.length,
|
|
4588
|
+
totalItems,
|
|
4589
|
+
durationMs: Date.now() - dexieStart
|
|
4590
|
+
});
|
|
4591
|
+
return totalItems;
|
|
4592
|
+
}
|
|
4561
4593
|
async loadCollectionToInMem(name) {
|
|
4562
4594
|
const allItems = [];
|
|
4563
4595
|
await this.dexieDb.forEachBatch(name, 2e3, async (chunk) => {
|
|
@@ -4577,7 +4609,7 @@ var SyncedDb = class _SyncedDb {
|
|
|
4577
4609
|
}
|
|
4578
4610
|
assertCollection(name) {
|
|
4579
4611
|
if (!this.collections.has(name)) {
|
|
4580
|
-
throw new Error(`Collection "${name}" not configured`);
|
|
4612
|
+
throw new Error(`SyncedDb: Collection "${(name == null ? void 0 : name.toString()) || "?"}" not configured`);
|
|
4581
4613
|
}
|
|
4582
4614
|
}
|
|
4583
4615
|
/** Stringify an Id parameter (ObjectId → hex string). */
|
|
@@ -4658,6 +4690,7 @@ var DexieDb = class extends Dexie {
|
|
|
4658
4690
|
constructor(tenant, collectionConfigs) {
|
|
4659
4691
|
super(`synced-db-${tenant}`);
|
|
4660
4692
|
this.collections = /* @__PURE__ */ new Map();
|
|
4693
|
+
this._isNewDatabase = false;
|
|
4661
4694
|
this.tenant = tenant;
|
|
4662
4695
|
const schema = {};
|
|
4663
4696
|
schema[SYNC_META_TABLE] = "[tenant+collection]";
|
|
@@ -4666,6 +4699,9 @@ var DexieDb = class extends Dexie {
|
|
|
4666
4699
|
schema[config.name] = "_id";
|
|
4667
4700
|
}
|
|
4668
4701
|
this.version(1).stores(schema);
|
|
4702
|
+
this.on("populate", () => {
|
|
4703
|
+
this._isNewDatabase = true;
|
|
4704
|
+
});
|
|
4669
4705
|
this.syncMeta = this.table(SYNC_META_TABLE);
|
|
4670
4706
|
this.dirtyChanges = this.table(DIRTY_CHANGES_TABLE);
|
|
4671
4707
|
for (const config of collectionConfigs) {
|
|
@@ -4675,7 +4711,7 @@ var DexieDb = class extends Dexie {
|
|
|
4675
4711
|
getTable(collection) {
|
|
4676
4712
|
const table = this.collections.get(collection);
|
|
4677
4713
|
if (!table) {
|
|
4678
|
-
throw new Error(`Collection "${collection}" not configured`);
|
|
4714
|
+
throw new Error(`DexieDb: Collection "${(collection == null ? void 0 : collection.toString()) || "?"}" not configured`);
|
|
4679
4715
|
}
|
|
4680
4716
|
return table;
|
|
4681
4717
|
}
|
|
@@ -4874,6 +4910,9 @@ var DexieDb = class extends Dexie {
|
|
|
4874
4910
|
getTenant() {
|
|
4875
4911
|
return this.tenant;
|
|
4876
4912
|
}
|
|
4913
|
+
isNewDatabase() {
|
|
4914
|
+
return this._isNewDatabase;
|
|
4915
|
+
}
|
|
4877
4916
|
};
|
|
4878
4917
|
|
|
4879
4918
|
// node_modules/msgpackr/unpack.js
|
package/dist/src/db/DexieDb.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export declare class DexieDb extends Dexie implements I_DexieDb {
|
|
|
12
12
|
private collections;
|
|
13
13
|
private syncMeta;
|
|
14
14
|
private dirtyChanges;
|
|
15
|
+
private _isNewDatabase;
|
|
15
16
|
constructor(tenant: string, collectionConfigs: CollectionConfig<any>[]);
|
|
16
17
|
private getTable;
|
|
17
18
|
private idToString;
|
|
@@ -51,4 +52,5 @@ export declare class DexieDb extends Dexie implements I_DexieDb {
|
|
|
51
52
|
setSyncMeta(collection: string, lastSyncTs: any): Promise<void>;
|
|
52
53
|
deleteSyncMeta(collection: string): Promise<void>;
|
|
53
54
|
getTenant(): string;
|
|
55
|
+
isNewDatabase(): boolean;
|
|
54
56
|
}
|
|
@@ -31,12 +31,14 @@ export declare class SyncedDb implements I_SyncedDb {
|
|
|
31
31
|
private syncOnlyCollections;
|
|
32
32
|
private readonly updaterId;
|
|
33
33
|
private readonly syncedDbInstanceId;
|
|
34
|
+
private readonly dexieLoadConcurrency;
|
|
34
35
|
private syncMetaCache;
|
|
35
36
|
private unsubscribeServerUpdates?;
|
|
36
37
|
private cleanupNotifierCallbacks?;
|
|
37
38
|
private beforeUnloadHandler?;
|
|
38
39
|
private readonly defaultReturnDeleted;
|
|
39
40
|
private readonly defaultReturnArchived;
|
|
41
|
+
private readonly onDatabaseCreated?;
|
|
40
42
|
private readonly onSyncStart?;
|
|
41
43
|
private readonly onSyncEnd?;
|
|
42
44
|
private readonly onDexieSyncStart?;
|
|
@@ -181,6 +183,11 @@ export declare class SyncedDb implements I_SyncedDb {
|
|
|
181
183
|
*/
|
|
182
184
|
/** Safe callback invocation — swallows errors */
|
|
183
185
|
private safeCallback;
|
|
186
|
+
/**
|
|
187
|
+
* Load multiple collections from Dexie into in-mem with concurrency control.
|
|
188
|
+
* @returns total items loaded
|
|
189
|
+
*/
|
|
190
|
+
private loadCollectionsToInMem;
|
|
184
191
|
private loadCollectionToInMem;
|
|
185
192
|
private assertCollection;
|
|
186
193
|
/** Stringify an Id parameter (ObjectId → hex string). */
|
|
@@ -116,5 +116,7 @@ export interface I_DexieDb {
|
|
|
116
116
|
deleteSyncMeta(collection: string): Promise<void>;
|
|
117
117
|
/** Vrne tenant */
|
|
118
118
|
getTenant(): string;
|
|
119
|
+
/** Returns true if the IndexedDB database was created fresh during this session (first ever open). */
|
|
120
|
+
isNewDatabase(): boolean;
|
|
119
121
|
}
|
|
120
122
|
export {};
|
|
@@ -293,6 +293,8 @@ export interface SyncedDbConfig {
|
|
|
293
293
|
debounceRestWritesMs?: number;
|
|
294
294
|
/** Callback ki se pokliče, ko SyncedDb sam preide v offline stanje (npr. ob sync napaki) */
|
|
295
295
|
onForcedOffline?: (reason: string) => void;
|
|
296
|
+
/** Callback fired once during init() when the IndexedDB database was created fresh (first ever open). */
|
|
297
|
+
onDatabaseCreated?: () => void;
|
|
296
298
|
/** Callback at the start of each sync cycle. initialSync=true if no full sync has completed yet. */
|
|
297
299
|
onSyncStart?: (info: {
|
|
298
300
|
calledFrom?: string;
|
|
@@ -406,6 +408,12 @@ export interface SyncedDbConfig {
|
|
|
406
408
|
* Default: false
|
|
407
409
|
*/
|
|
408
410
|
returnArchived?: boolean;
|
|
411
|
+
/**
|
|
412
|
+
* Number of collections to load from Dexie concurrently during init
|
|
413
|
+
* and setSyncOnlyTheseCollections. Higher values speed up initial load
|
|
414
|
+
* by issuing parallel IndexedDB reads. Default: 1 (sequential).
|
|
415
|
+
*/
|
|
416
|
+
dexieLoadConcurrency?: number;
|
|
409
417
|
/**
|
|
410
418
|
* Enable sync on wake from sleep for leader tab.
|
|
411
419
|
* When enabled, detects wake via pageshow/focus/visibilitychange events
|