cry-synced-db-client 0.1.66 → 0.1.69

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
@@ -640,6 +640,7 @@ class ConnectionManager {
640
640
  } else {
641
641
  this.online = online;
642
642
  this.stopAutoSync();
643
+ this.callbacks.onOnlineStatusChange?.(false);
643
644
  }
644
645
  }
645
646
  forceOffline(forced) {
@@ -2031,6 +2032,7 @@ class SyncEngine {
2031
2032
  let receivedCount = 0;
2032
2033
  let sentCount = 0;
2033
2034
  let conflictsResolved = 0;
2035
+ const collectionStats = {};
2034
2036
  try {
2035
2037
  this.deps.cancelRestUploadTimer();
2036
2038
  await this.deps.awaitRestUpload();
@@ -2068,6 +2070,11 @@ class SyncEngine {
2068
2070
  for (const [collectionName, config] of configMap) {
2069
2071
  const serverData = allServerData[collectionName] || [];
2070
2072
  receivedCount += serverData.length;
2073
+ collectionStats[collectionName] = {
2074
+ receivedCount: serverData.length,
2075
+ sentCount: 0,
2076
+ receivedItems: serverData
2077
+ };
2071
2078
  const stats = await this.processIncomingServerData(collectionName, config, serverData);
2072
2079
  conflictsResolved += stats.conflictsResolved;
2073
2080
  if (stats.updatedIds.length > 0) {
@@ -2079,13 +2086,25 @@ class SyncEngine {
2079
2086
  }
2080
2087
  const uploadStats = await this.uploadDirtyItems(calledFrom);
2081
2088
  sentCount = uploadStats.sentCount;
2089
+ for (const [collectionName, stats] of Object.entries(uploadStats.collectionSentCounts || {})) {
2090
+ if (collectionStats[collectionName]) {
2091
+ collectionStats[collectionName].sentCount = stats;
2092
+ } else {
2093
+ collectionStats[collectionName] = {
2094
+ receivedCount: 0,
2095
+ sentCount: stats,
2096
+ receivedItems: []
2097
+ };
2098
+ }
2099
+ }
2082
2100
  this.callOnSync({
2083
2101
  durationMs: Date.now() - startTime,
2084
2102
  receivedCount,
2085
2103
  sentCount,
2086
2104
  conflictsResolved,
2087
2105
  success: true,
2088
- calledFrom
2106
+ calledFrom,
2107
+ collections: collectionStats
2089
2108
  });
2090
2109
  } catch (err) {
2091
2110
  const reason = err instanceof Error ? err.message : String(err);
@@ -2098,7 +2117,8 @@ class SyncEngine {
2098
2117
  conflictsResolved,
2099
2118
  success: false,
2100
2119
  error: err instanceof Error ? err : new Error(String(err)),
2101
- calledFrom
2120
+ calledFrom,
2121
+ collections: collectionStats
2102
2122
  });
2103
2123
  throw err;
2104
2124
  }
@@ -2157,6 +2177,7 @@ class SyncEngine {
2157
2177
  throw err;
2158
2178
  }
2159
2179
  let sentCount = 0;
2180
+ const collectionSentCounts = {};
2160
2181
  for (const result of results) {
2161
2182
  const { collection, results: { inserted, updated, deleted, errors } } = result;
2162
2183
  const allSuccessIds = [
@@ -2167,6 +2188,7 @@ class SyncEngine {
2167
2188
  if (allSuccessIds.length > 0) {
2168
2189
  await this.dexieDb.clearDirtyChangesBatch(collection, allSuccessIds);
2169
2190
  }
2191
+ let collectionSentCount = 0;
2170
2192
  const insertedAndUpdated = [...inserted, ...updated];
2171
2193
  if (insertedAndUpdated.length > 0) {
2172
2194
  const idsToCheck = insertedAndUpdated.map((e) => e._id);
@@ -2201,12 +2223,17 @@ class SyncEngine {
2201
2223
  this.deps.writeToInMemBatch(collection, inMemUpdateBatch, "upsert");
2202
2224
  }
2203
2225
  sentCount += insertedAndUpdated.length;
2226
+ collectionSentCount += insertedAndUpdated.length;
2204
2227
  }
2205
2228
  if (deleted.length > 0) {
2206
2229
  const deleteIds = deleted.map((e) => e._id);
2207
2230
  await this.dexieDb.deleteMany(collection, deleteIds);
2208
2231
  this.deps.writeToInMemBatch(collection, deleteIds.map((id) => ({ _id: id })), "delete");
2209
2232
  sentCount += deleted.length;
2233
+ collectionSentCount += deleted.length;
2234
+ }
2235
+ if (collectionSentCount > 0) {
2236
+ collectionSentCounts[collection] = collectionSentCount;
2210
2237
  }
2211
2238
  const allItems = [...inserted, ...updated, ...deleted];
2212
2239
  let maxTs = undefined;
@@ -2233,7 +2260,7 @@ class SyncEngine {
2233
2260
  console.error(`Sync errors for ${collection}:`, errors);
2234
2261
  }
2235
2262
  }
2236
- return { sentCount };
2263
+ return { sentCount, collectionSentCounts };
2237
2264
  }
2238
2265
  async uploadDirtyItemsForCollection(collection) {
2239
2266
  const dirtyItems = await this.dexieDb.getDirty(collection);
@@ -2884,6 +2911,7 @@ class SyncedDb {
2884
2911
  initialized = false;
2885
2912
  syncing = false;
2886
2913
  syncLock = false;
2914
+ wsUpdateQueue = [];
2887
2915
  updaterId;
2888
2916
  syncedDbInstanceId;
2889
2917
  syncMetaCache = new Map;
@@ -3133,7 +3161,13 @@ class SyncedDb {
3133
3161
  if (cleanup)
3134
3162
  this.cleanupNotifierCallbacks = cleanup;
3135
3163
  }
3136
- this.unsubscribeServerUpdates = this.serverUpdateNotifier.subscribe((payload) => this.serverUpdateHandler.handleServerUpdate(payload));
3164
+ this.unsubscribeServerUpdates = this.serverUpdateNotifier.subscribe((payload) => {
3165
+ if (this.syncing) {
3166
+ this.wsUpdateQueue.push(payload);
3167
+ return;
3168
+ }
3169
+ return this.serverUpdateHandler.handleServerUpdate(payload);
3170
+ });
3137
3171
  try {
3138
3172
  await this.serverUpdateNotifier.connect();
3139
3173
  } catch (err) {
@@ -3415,6 +3449,16 @@ class SyncedDb {
3415
3449
  } finally {
3416
3450
  this.syncing = false;
3417
3451
  this.syncLock = false;
3452
+ await this.processQueuedWsUpdates();
3453
+ }
3454
+ }
3455
+ async processQueuedWsUpdates() {
3456
+ if (this.wsUpdateQueue.length === 0)
3457
+ return;
3458
+ const queue = this.wsUpdateQueue;
3459
+ this.wsUpdateQueue = [];
3460
+ for (const payload of queue) {
3461
+ await this.serverUpdateHandler.handleServerUpdate(payload);
3418
3462
  }
3419
3463
  }
3420
3464
  isSyncing() {
@@ -26,6 +26,7 @@ export declare class SyncedDb implements I_SyncedDb {
26
26
  private initialized;
27
27
  private syncing;
28
28
  private syncLock;
29
+ private wsUpdateQueue;
29
30
  private readonly updaterId;
30
31
  private readonly syncedDbInstanceId;
31
32
  private syncMetaCache;
@@ -65,6 +66,7 @@ export declare class SyncedDb implements I_SyncedDb {
65
66
  hardDelete<T extends DbEntity>(collection: string, query: QuerySpec<T>): Promise<number>;
66
67
  ping(timeoutMs?: number): Promise<boolean>;
67
68
  sync(calledFrom?: string): Promise<void>;
69
+ private processQueuedWsUpdates;
68
70
  isSyncing(): boolean;
69
71
  upsertBatch<T extends DbEntity>(collection: string, batch: BatchSpec<T>): Promise<T[]>;
70
72
  getMemoryCollection<T extends DbEntity>(collection: string): T[];
@@ -27,6 +27,8 @@ export interface SyncResult {
27
27
  */
28
28
  export interface UploadResult {
29
29
  sentCount: number;
30
+ /** Per-collection sent counts (collection name -> count) */
31
+ collectionSentCounts?: Record<string, number>;
30
32
  }
31
33
  /**
32
34
  * Result from processing incoming server data.
@@ -198,6 +198,17 @@ export interface ConflictResolutionReport {
198
198
  /** Timestamp when conflict was resolved */
199
199
  timestamp: Date;
200
200
  }
201
+ /**
202
+ * Per-collection sync statistics
203
+ */
204
+ export interface CollectionSyncStats {
205
+ /** Number of items received from server for this collection */
206
+ receivedCount: number;
207
+ /** Number of dirty items sent to server for this collection */
208
+ sentCount: number;
209
+ /** The actual items received from server (for debugging/logging) */
210
+ receivedItems: LocalDbEntity[];
211
+ }
201
212
  /**
202
213
  * Informacije o sinhronizaciji za debugging/logging
203
214
  */
@@ -216,6 +227,8 @@ export interface SyncInfo {
216
227
  error?: Error;
217
228
  /** Where sync was called from (for debugging) */
218
229
  calledFrom?: string;
230
+ /** Per-collection sync statistics (collection name -> stats) */
231
+ collections?: Record<string, CollectionSyncStats>;
219
232
  }
220
233
  /**
221
234
  * Configuration for collection sync behavior (used in sync() method only, not uploadDirtyItems)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cry-synced-db-client",
3
- "version": "0.1.66",
3
+ "version": "0.1.69",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",