cry-synced-db-client 0.1.76 → 0.1.77
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 +85 -28
- package/dist/src/db/SyncedDb.d.ts +27 -0
- package/dist/src/db/types/managers.d.ts +6 -0
- package/dist/src/types/I_SyncedDb.d.ts +12 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -705,7 +705,6 @@ var CrossTabSyncManager = class {
|
|
|
705
705
|
// Private Methods
|
|
706
706
|
// ============================================================
|
|
707
707
|
async handleCrossTabMetaUpdate(payload) {
|
|
708
|
-
var _a;
|
|
709
708
|
if (!this.deps.isInitialized()) {
|
|
710
709
|
return;
|
|
711
710
|
}
|
|
@@ -717,7 +716,7 @@ var CrossTabSyncManager = class {
|
|
|
717
716
|
if (!collections.has(collection)) {
|
|
718
717
|
continue;
|
|
719
718
|
}
|
|
720
|
-
if (
|
|
719
|
+
if (!this.deps.isSyncAllowed(collection)) {
|
|
721
720
|
continue;
|
|
722
721
|
}
|
|
723
722
|
if (ids.length === 0) {
|
|
@@ -2344,7 +2343,7 @@ var _SyncEngine = class _SyncEngine {
|
|
|
2344
2343
|
const syncSpecs = [];
|
|
2345
2344
|
const configMap = /* @__PURE__ */ new Map();
|
|
2346
2345
|
for (const [collectionName, config] of this.collections) {
|
|
2347
|
-
if (
|
|
2346
|
+
if (!this.deps.isSyncAllowed(collectionName)) continue;
|
|
2348
2347
|
const syncEnabled = (_a = config.syncConfig) == null ? void 0 : _a.enabled;
|
|
2349
2348
|
const shouldSync = typeof syncEnabled === "function" ? syncEnabled() : syncEnabled;
|
|
2350
2349
|
if (shouldSync === false) {
|
|
@@ -2873,13 +2872,12 @@ var ServerUpdateHandler = class {
|
|
|
2873
2872
|
* Handle incoming server update (WebSocket notification).
|
|
2874
2873
|
*/
|
|
2875
2874
|
async handleServerUpdate(payload) {
|
|
2876
|
-
var _a;
|
|
2877
2875
|
this.callOnWsNotification(payload);
|
|
2878
2876
|
if (!this.deps.isLeader()) return;
|
|
2879
2877
|
if (!this.deps.canReceiveServerUpdates()) return;
|
|
2880
2878
|
const collectionName = payload.collection;
|
|
2881
2879
|
if (!this.collections.has(collectionName)) return;
|
|
2882
|
-
if (
|
|
2880
|
+
if (!this.deps.isSyncAllowed(collectionName)) return;
|
|
2883
2881
|
const updatedIds = [];
|
|
2884
2882
|
switch (payload.operation) {
|
|
2885
2883
|
case "insert": {
|
|
@@ -3293,6 +3291,8 @@ var SyncedDb = class {
|
|
|
3293
3291
|
this.syncing = false;
|
|
3294
3292
|
this.syncLock = false;
|
|
3295
3293
|
this.wsUpdateQueue = [];
|
|
3294
|
+
/** When non-null, only these collections participate in sync/in-mem loading. */
|
|
3295
|
+
this.syncOnlyCollections = null;
|
|
3296
3296
|
// Sync metadata cache
|
|
3297
3297
|
this.syncMetaCache = /* @__PURE__ */ new Map();
|
|
3298
3298
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
@@ -3358,7 +3358,8 @@ var SyncedDb = class {
|
|
|
3358
3358
|
dexieDb: this.dexieDb,
|
|
3359
3359
|
writeToInMemBatch: (collection, items, operation) => {
|
|
3360
3360
|
this.inMemManager.writeBatch(collection, items, operation);
|
|
3361
|
-
}
|
|
3361
|
+
},
|
|
3362
|
+
isSyncAllowed: (collection) => this.isSyncAllowed(collection)
|
|
3362
3363
|
}
|
|
3363
3364
|
});
|
|
3364
3365
|
this.connectionManager = new ConnectionManager({
|
|
@@ -3438,7 +3439,8 @@ var SyncedDb = class {
|
|
|
3438
3439
|
flushAllPendingChanges: () => this.pendingChanges.flushAll(),
|
|
3439
3440
|
cancelRestUploadTimer: () => this.pendingChanges.cancelRestUploadTimer(),
|
|
3440
3441
|
awaitRestUpload: () => this.pendingChanges.awaitRestUpload(),
|
|
3441
|
-
broadcastUpdates: (updates) => this.crossTabSync.broadcastMetaUpdate(updates)
|
|
3442
|
+
broadcastUpdates: (updates) => this.crossTabSync.broadcastMetaUpdate(updates),
|
|
3443
|
+
isSyncAllowed: (collection) => this.isSyncAllowed(collection)
|
|
3442
3444
|
}
|
|
3443
3445
|
});
|
|
3444
3446
|
this.serverUpdateHandler = new ServerUpdateHandler({
|
|
@@ -3457,7 +3459,8 @@ var SyncedDb = class {
|
|
|
3457
3459
|
this.inMemManager.writeBatch(collection, items, operation);
|
|
3458
3460
|
},
|
|
3459
3461
|
broadcastUpdates: (updates) => this.crossTabSync.broadcastMetaUpdate(updates),
|
|
3460
|
-
getPendingChange: (collection, id) => this.pendingChanges.getPendingChange(collection, id)
|
|
3462
|
+
getPendingChange: (collection, id) => this.pendingChanges.getPendingChange(collection, id),
|
|
3463
|
+
isSyncAllowed: (collection) => this.isSyncAllowed(collection)
|
|
3461
3464
|
}
|
|
3462
3465
|
});
|
|
3463
3466
|
if (config.wakeSyncEnabled) {
|
|
@@ -3500,6 +3503,41 @@ var SyncedDb = class {
|
|
|
3500
3503
|
isLeaderTab() {
|
|
3501
3504
|
return this.leaderElection.isLeader();
|
|
3502
3505
|
}
|
|
3506
|
+
/**
|
|
3507
|
+
* Restrict sync to only these collections. When non-empty, only the listed
|
|
3508
|
+
* collections load from Dexie→in-mem and download from server. Pass an empty
|
|
3509
|
+
* array to sync all collections again.
|
|
3510
|
+
*
|
|
3511
|
+
* Newly-allowed collections are loaded from Dexie immediately and a sync is
|
|
3512
|
+
* triggered if online.
|
|
3513
|
+
*/
|
|
3514
|
+
async setSyncOnlyTheseCollections(collections) {
|
|
3515
|
+
const prevAllowed = /* @__PURE__ */ new Set();
|
|
3516
|
+
for (const [name] of this.collections) {
|
|
3517
|
+
if (this.isSyncAllowed(name)) prevAllowed.add(name);
|
|
3518
|
+
}
|
|
3519
|
+
this.syncOnlyCollections = collections.length > 0 ? new Set(collections) : null;
|
|
3520
|
+
const newlyAllowed = [];
|
|
3521
|
+
for (const [name] of this.collections) {
|
|
3522
|
+
if (this.isSyncAllowed(name) && !prevAllowed.has(name)) {
|
|
3523
|
+
newlyAllowed.push(name);
|
|
3524
|
+
}
|
|
3525
|
+
}
|
|
3526
|
+
for (const name of newlyAllowed) {
|
|
3527
|
+
await this.loadCollectionToInMem(name);
|
|
3528
|
+
}
|
|
3529
|
+
if (newlyAllowed.length > 0 && this.connectionManager.canSync()) {
|
|
3530
|
+
this.sync("setSyncOnlyTheseCollections").catch(() => {
|
|
3531
|
+
});
|
|
3532
|
+
}
|
|
3533
|
+
}
|
|
3534
|
+
/**
|
|
3535
|
+
* Get the current syncOnlyTheseCollections filter.
|
|
3536
|
+
* Returns null when all collections are synced.
|
|
3537
|
+
*/
|
|
3538
|
+
getSyncOnlyTheseCollections() {
|
|
3539
|
+
return this.syncOnlyCollections;
|
|
3540
|
+
}
|
|
3503
3541
|
/**
|
|
3504
3542
|
* Test helper: simulate receiving a cross-tab broadcast from another instance.
|
|
3505
3543
|
*/
|
|
@@ -3523,26 +3561,9 @@ var SyncedDb = class {
|
|
|
3523
3561
|
);
|
|
3524
3562
|
}
|
|
3525
3563
|
await this.pendingChanges.recoverPendingWrites();
|
|
3526
|
-
for (const [name
|
|
3527
|
-
if (
|
|
3528
|
-
this.
|
|
3529
|
-
await this.dexieDb.forEachBatch(name, 2e3, async (chunk) => {
|
|
3530
|
-
let writeIdx = 0;
|
|
3531
|
-
for (let i = 0; i < chunk.length; i++) {
|
|
3532
|
-
const item = chunk[i];
|
|
3533
|
-
if (!item._deleted && !item._archived) {
|
|
3534
|
-
chunk[writeIdx++] = item;
|
|
3535
|
-
}
|
|
3536
|
-
}
|
|
3537
|
-
chunk.length = writeIdx;
|
|
3538
|
-
if (chunk.length > 0) {
|
|
3539
|
-
this.inMemManager.writeBatch(name, chunk, "upsert");
|
|
3540
|
-
}
|
|
3541
|
-
});
|
|
3542
|
-
const meta = await this.dexieDb.getSyncMeta(name);
|
|
3543
|
-
if (meta) {
|
|
3544
|
-
this.syncMetaCache.set(name, meta);
|
|
3545
|
-
}
|
|
3564
|
+
for (const [name] of this.collections) {
|
|
3565
|
+
if (!this.isSyncAllowed(name)) continue;
|
|
3566
|
+
await this.loadCollectionToInMem(name);
|
|
3546
3567
|
}
|
|
3547
3568
|
this.leaderElection.init();
|
|
3548
3569
|
this.crossTabSync.init();
|
|
@@ -4263,6 +4284,42 @@ var SyncedDb = class {
|
|
|
4263
4284
|
returnArchived: (_b = opts == null ? void 0 : opts.returnArchived) != null ? _b : this.defaultReturnArchived
|
|
4264
4285
|
});
|
|
4265
4286
|
}
|
|
4287
|
+
/**
|
|
4288
|
+
* Whether a collection participates in sync (server download,
|
|
4289
|
+
* WS notifications, cross-tab sync, Dexie→in-mem loading).
|
|
4290
|
+
* False for writeOnly collections and collections excluded by syncOnlyCollections.
|
|
4291
|
+
*/
|
|
4292
|
+
isSyncAllowed(collection) {
|
|
4293
|
+
const config = this.collections.get(collection);
|
|
4294
|
+
if (!config) return false;
|
|
4295
|
+
if (config.writeOnly) return false;
|
|
4296
|
+
if (this.syncOnlyCollections && !this.syncOnlyCollections.has(collection)) return false;
|
|
4297
|
+
return true;
|
|
4298
|
+
}
|
|
4299
|
+
/**
|
|
4300
|
+
* Load a single collection from Dexie into in-memory cache.
|
|
4301
|
+
* Filters out deleted and archived items.
|
|
4302
|
+
*/
|
|
4303
|
+
async loadCollectionToInMem(name) {
|
|
4304
|
+
this.inMemManager.clearCollection(name);
|
|
4305
|
+
await this.dexieDb.forEachBatch(name, 2e3, async (chunk) => {
|
|
4306
|
+
let writeIdx = 0;
|
|
4307
|
+
for (let i = 0; i < chunk.length; i++) {
|
|
4308
|
+
const item = chunk[i];
|
|
4309
|
+
if (!item._deleted && !item._archived) {
|
|
4310
|
+
chunk[writeIdx++] = item;
|
|
4311
|
+
}
|
|
4312
|
+
}
|
|
4313
|
+
chunk.length = writeIdx;
|
|
4314
|
+
if (chunk.length > 0) {
|
|
4315
|
+
this.inMemManager.writeBatch(name, chunk, "upsert");
|
|
4316
|
+
}
|
|
4317
|
+
});
|
|
4318
|
+
const meta = await this.dexieDb.getSyncMeta(name);
|
|
4319
|
+
if (meta) {
|
|
4320
|
+
this.syncMetaCache.set(name, meta);
|
|
4321
|
+
}
|
|
4322
|
+
}
|
|
4266
4323
|
assertCollection(name) {
|
|
4267
4324
|
if (!this.collections.has(name)) {
|
|
4268
4325
|
throw new Error(`Collection "${name}" not configured`);
|
|
@@ -27,6 +27,8 @@ export declare class SyncedDb implements I_SyncedDb {
|
|
|
27
27
|
private syncing;
|
|
28
28
|
private syncLock;
|
|
29
29
|
private wsUpdateQueue;
|
|
30
|
+
/** When non-null, only these collections participate in sync/in-mem loading. */
|
|
31
|
+
private syncOnlyCollections;
|
|
30
32
|
private readonly updaterId;
|
|
31
33
|
private readonly syncedDbInstanceId;
|
|
32
34
|
private syncMetaCache;
|
|
@@ -44,6 +46,20 @@ export declare class SyncedDb implements I_SyncedDb {
|
|
|
44
46
|
getInstanceId(): string;
|
|
45
47
|
getCrossTabSyncDebounceMs(): number;
|
|
46
48
|
isLeaderTab(): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Restrict sync to only these collections. When non-empty, only the listed
|
|
51
|
+
* collections load from Dexie→in-mem and download from server. Pass an empty
|
|
52
|
+
* array to sync all collections again.
|
|
53
|
+
*
|
|
54
|
+
* Newly-allowed collections are loaded from Dexie immediately and a sync is
|
|
55
|
+
* triggered if online.
|
|
56
|
+
*/
|
|
57
|
+
setSyncOnlyTheseCollections(collections: string[]): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Get the current syncOnlyTheseCollections filter.
|
|
60
|
+
* Returns null when all collections are synced.
|
|
61
|
+
*/
|
|
62
|
+
getSyncOnlyTheseCollections(): ReadonlySet<string> | null;
|
|
47
63
|
/**
|
|
48
64
|
* Test helper: simulate receiving a cross-tab broadcast from another instance.
|
|
49
65
|
*/
|
|
@@ -114,6 +130,17 @@ export declare class SyncedDb implements I_SyncedDb {
|
|
|
114
130
|
* Per-call values take precedence over global defaults.
|
|
115
131
|
*/
|
|
116
132
|
private resolveOpts;
|
|
133
|
+
/**
|
|
134
|
+
* Whether a collection participates in sync (server download,
|
|
135
|
+
* WS notifications, cross-tab sync, Dexie→in-mem loading).
|
|
136
|
+
* False for writeOnly collections and collections excluded by syncOnlyCollections.
|
|
137
|
+
*/
|
|
138
|
+
private isSyncAllowed;
|
|
139
|
+
/**
|
|
140
|
+
* Load a single collection from Dexie into in-memory cache.
|
|
141
|
+
* Filters out deleted and archived items.
|
|
142
|
+
*/
|
|
143
|
+
private loadCollectionToInMem;
|
|
117
144
|
private assertCollection;
|
|
118
145
|
/**
|
|
119
146
|
* Asserts write-only collection has online connectivity for reads.
|
|
@@ -50,6 +50,8 @@ export interface CrossTabSyncDeps {
|
|
|
50
50
|
dexieDb: I_DexieDb;
|
|
51
51
|
/** Write to in-mem batch. */
|
|
52
52
|
writeToInMemBatch: <T extends DbEntity>(collection: string, items: T[], operation: "upsert" | "delete") => void;
|
|
53
|
+
/** Whether a collection participates in sync (not writeOnly, not filtered out). */
|
|
54
|
+
isSyncAllowed: (collection: string) => boolean;
|
|
53
55
|
}
|
|
54
56
|
export interface CrossTabSyncConfig {
|
|
55
57
|
tenant: string;
|
|
@@ -225,6 +227,8 @@ export interface SyncEngineDeps {
|
|
|
225
227
|
awaitRestUpload: () => Promise<void>;
|
|
226
228
|
/** Broadcast updated IDs to other tabs */
|
|
227
229
|
broadcastUpdates: (updates: Record<string, string[]>) => void;
|
|
230
|
+
/** Whether a collection participates in sync (not writeOnly, not filtered out). */
|
|
231
|
+
isSyncAllowed: (collection: string) => boolean;
|
|
228
232
|
}
|
|
229
233
|
export interface SyncEngineConfig {
|
|
230
234
|
tenant: string;
|
|
@@ -256,6 +260,8 @@ export interface ServerUpdateHandlerDeps {
|
|
|
256
260
|
getPendingChange: (collection: string, id: Id) => PendingChange | undefined;
|
|
257
261
|
broadcastUpdates: (updates: Record<string, string[]>) => void;
|
|
258
262
|
writeToInMemBatch: <T extends DbEntity>(collection: string, items: T[], operation: "upsert" | "delete") => void;
|
|
263
|
+
/** Whether a collection participates in sync (not writeOnly, not filtered out). */
|
|
264
|
+
isSyncAllowed: (collection: string) => boolean;
|
|
259
265
|
}
|
|
260
266
|
export interface ServerUpdateHandlerConfig {
|
|
261
267
|
tenant: string;
|
|
@@ -518,6 +518,18 @@ export interface I_SyncedDb {
|
|
|
518
518
|
sync(calledFrom?: string): Promise<void>;
|
|
519
519
|
/** Ali je sinhronizacija v teku */
|
|
520
520
|
isSyncing(): boolean;
|
|
521
|
+
/**
|
|
522
|
+
* Restrict sync to only these collections. When non-empty, only listed
|
|
523
|
+
* collections load Dexie→in-mem and download from server. Pass empty
|
|
524
|
+
* array to sync all collections. Newly-allowed collections are loaded
|
|
525
|
+
* immediately and a sync is triggered if online.
|
|
526
|
+
*/
|
|
527
|
+
setSyncOnlyTheseCollections(collections: string[]): Promise<void>;
|
|
528
|
+
/**
|
|
529
|
+
* Get the current syncOnlyTheseCollections filter.
|
|
530
|
+
* Returns null when all collections are synced.
|
|
531
|
+
*/
|
|
532
|
+
getSyncOnlyTheseCollections(): ReadonlySet<string> | null;
|
|
521
533
|
/**
|
|
522
534
|
* Izvede batch upsert na serverju
|
|
523
535
|
*
|