cry-synced-db-client 0.1.67 → 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
@@ -2032,6 +2032,7 @@ class SyncEngine {
2032
2032
  let receivedCount = 0;
2033
2033
  let sentCount = 0;
2034
2034
  let conflictsResolved = 0;
2035
+ const collectionStats = {};
2035
2036
  try {
2036
2037
  this.deps.cancelRestUploadTimer();
2037
2038
  await this.deps.awaitRestUpload();
@@ -2069,6 +2070,11 @@ class SyncEngine {
2069
2070
  for (const [collectionName, config] of configMap) {
2070
2071
  const serverData = allServerData[collectionName] || [];
2071
2072
  receivedCount += serverData.length;
2073
+ collectionStats[collectionName] = {
2074
+ receivedCount: serverData.length,
2075
+ sentCount: 0,
2076
+ receivedItems: serverData
2077
+ };
2072
2078
  const stats = await this.processIncomingServerData(collectionName, config, serverData);
2073
2079
  conflictsResolved += stats.conflictsResolved;
2074
2080
  if (stats.updatedIds.length > 0) {
@@ -2080,13 +2086,25 @@ class SyncEngine {
2080
2086
  }
2081
2087
  const uploadStats = await this.uploadDirtyItems(calledFrom);
2082
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
+ }
2083
2100
  this.callOnSync({
2084
2101
  durationMs: Date.now() - startTime,
2085
2102
  receivedCount,
2086
2103
  sentCount,
2087
2104
  conflictsResolved,
2088
2105
  success: true,
2089
- calledFrom
2106
+ calledFrom,
2107
+ collections: collectionStats
2090
2108
  });
2091
2109
  } catch (err) {
2092
2110
  const reason = err instanceof Error ? err.message : String(err);
@@ -2099,7 +2117,8 @@ class SyncEngine {
2099
2117
  conflictsResolved,
2100
2118
  success: false,
2101
2119
  error: err instanceof Error ? err : new Error(String(err)),
2102
- calledFrom
2120
+ calledFrom,
2121
+ collections: collectionStats
2103
2122
  });
2104
2123
  throw err;
2105
2124
  }
@@ -2158,6 +2177,7 @@ class SyncEngine {
2158
2177
  throw err;
2159
2178
  }
2160
2179
  let sentCount = 0;
2180
+ const collectionSentCounts = {};
2161
2181
  for (const result of results) {
2162
2182
  const { collection, results: { inserted, updated, deleted, errors } } = result;
2163
2183
  const allSuccessIds = [
@@ -2168,6 +2188,7 @@ class SyncEngine {
2168
2188
  if (allSuccessIds.length > 0) {
2169
2189
  await this.dexieDb.clearDirtyChangesBatch(collection, allSuccessIds);
2170
2190
  }
2191
+ let collectionSentCount = 0;
2171
2192
  const insertedAndUpdated = [...inserted, ...updated];
2172
2193
  if (insertedAndUpdated.length > 0) {
2173
2194
  const idsToCheck = insertedAndUpdated.map((e) => e._id);
@@ -2202,12 +2223,17 @@ class SyncEngine {
2202
2223
  this.deps.writeToInMemBatch(collection, inMemUpdateBatch, "upsert");
2203
2224
  }
2204
2225
  sentCount += insertedAndUpdated.length;
2226
+ collectionSentCount += insertedAndUpdated.length;
2205
2227
  }
2206
2228
  if (deleted.length > 0) {
2207
2229
  const deleteIds = deleted.map((e) => e._id);
2208
2230
  await this.dexieDb.deleteMany(collection, deleteIds);
2209
2231
  this.deps.writeToInMemBatch(collection, deleteIds.map((id) => ({ _id: id })), "delete");
2210
2232
  sentCount += deleted.length;
2233
+ collectionSentCount += deleted.length;
2234
+ }
2235
+ if (collectionSentCount > 0) {
2236
+ collectionSentCounts[collection] = collectionSentCount;
2211
2237
  }
2212
2238
  const allItems = [...inserted, ...updated, ...deleted];
2213
2239
  let maxTs = undefined;
@@ -2234,7 +2260,7 @@ class SyncEngine {
2234
2260
  console.error(`Sync errors for ${collection}:`, errors);
2235
2261
  }
2236
2262
  }
2237
- return { sentCount };
2263
+ return { sentCount, collectionSentCounts };
2238
2264
  }
2239
2265
  async uploadDirtyItemsForCollection(collection) {
2240
2266
  const dirtyItems = await this.dexieDb.getDirty(collection);
@@ -2885,6 +2911,7 @@ class SyncedDb {
2885
2911
  initialized = false;
2886
2912
  syncing = false;
2887
2913
  syncLock = false;
2914
+ wsUpdateQueue = [];
2888
2915
  updaterId;
2889
2916
  syncedDbInstanceId;
2890
2917
  syncMetaCache = new Map;
@@ -3134,7 +3161,13 @@ class SyncedDb {
3134
3161
  if (cleanup)
3135
3162
  this.cleanupNotifierCallbacks = cleanup;
3136
3163
  }
3137
- 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
+ });
3138
3171
  try {
3139
3172
  await this.serverUpdateNotifier.connect();
3140
3173
  } catch (err) {
@@ -3416,6 +3449,16 @@ class SyncedDb {
3416
3449
  } finally {
3417
3450
  this.syncing = false;
3418
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);
3419
3462
  }
3420
3463
  }
3421
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.67",
3
+ "version": "0.1.69",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",