cry-synced-db-client 0.1.199 → 0.1.201

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/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # Versions
2
2
 
3
+ ## 0.1.201 (2026-06-14)
4
+
5
+ ### `onBeforeDirtyClearAll` callback zdaj prejme `DirtyChange[]` (ne samo `DirtyMeta[]`)
6
+
7
+ `BeforeDirtyClearAllInfo.items` je nadgrajen iz `DirtyMeta[]` v `DirtyChange[]` —
8
+ callback dobi poleg metapodatkov (`id`, `collection`, `stuckSince`, ...) tudi
9
+ `changes` payload z dejanskimi field-level spremembami.
10
+
11
+ **Affected paths:**
12
+ - `clearDirty()` clear-all path: fetcha `DirtyChange[]` prek `getDirtyChangesBatch`
13
+ - `discardStuckItems()`: zamenja `getDirty` + `find` (ki je vračal
14
+ `Partial<LocalDbEntity>[]`) z `getDirtyChangesBatch` za pravilne `DirtyChange[]`
15
+
16
+ **Type change (backward-compatible):**
17
+ - `items` v `BeforeDirtyClearAllInfo`: `DirtyMeta[]` → `DirtyChange[]`
18
+ - `DirtyChange` je superset of `DirtyMeta`; vsa obstoječa polja (`id`,
19
+ `collection`, `createdAt`, `updatedAt`, `stuckSince`, ...) so še vedno na voljo
20
+
21
+ 876 pass, 0 fail.
22
+
23
+ ## 0.1.200 (2026-06-14)
24
+
25
+ ### `preprocessDirtyItem` skip/throw zdaj incrementa `numUploadAttempts`
26
+
27
+ `SyncEngine.uploadDirtyItems`: ko `preprocessDirtyItem` vrne `undefined` ali vrže
28
+ exception, se item ne samo preskoči — zdaj dobi tudi `incrementDirtyUploadAttempts`,
29
+ tako da po 2+ skipih postane stuck in viden prek `getStuckItems()` / `onDirtyItemStuck`.
30
+
31
+ Prej so skipani itemi tiho ostali v `_dirty_changes` brez metapodatkov in nikoli ne
32
+ bi postali stuck — zdaj se po 3 skipih (vsak sync da 2 incrementa = main + followUp)
33
+ dobijo `stuckSince`.
34
+
35
+ **Internal:**
36
+ - V `uploadDirtyItems` zbira `preprocessSkippedIds` v obeh poteh, batch-write v
37
+ `incrementDirtyUploadAttempts` takoj za `for` zanko (en DB write za vse skipane
38
+ iteme namesto N write-ov)
39
+
40
+ **Tests:** 5 novih testov v `test/preprocessDirtyItem.test.ts`:
41
+ - `undefined/throw: numUploadAttempts increments across sync cycles, eventually stuck`
42
+ - `undefined/throw: onDirtyItemStuck fires when item becomes stuck`
43
+ - `mixed: stuck item via getStuckItems while non-stuck dirty still active`
44
+
45
+ 876 pass, 0 fail.
46
+
3
47
  ## 0.1.198 (2026-06-13)
4
48
 
5
49
  ### Stuck-item tracking (`getStuckItems` / `discardStuckItems` / `onDirtyItemStuck`)
package/dist/index.js CHANGED
@@ -3245,7 +3245,10 @@ var _SyncEngine = class _SyncEngine {
3245
3245
  configMap.set(collectionName, config);
3246
3246
  }
3247
3247
  this.callOnFindNewerManyCall(syncSpecs, calledFrom);
3248
- this.callbackSafe(this.callbacks.onServerSyncStart, { calledFrom, collectionCount: syncSpecs.length });
3248
+ this.callbackSafe(this.callbacks.onServerSyncStart, {
3249
+ calledFrom,
3250
+ collectionCount: syncSpecs.length
3251
+ });
3249
3252
  const findNewerManyStartTime = Date.now();
3250
3253
  const collectionState = /* @__PURE__ */ new Map();
3251
3254
  for (const [name] of configMap) {
@@ -3276,7 +3279,12 @@ var _SyncEngine = class _SyncEngine {
3276
3279
  if (!config) return;
3277
3280
  const state = collectionState.get(collection);
3278
3281
  state.receivedCount += items.length;
3279
- const stats = await this.processIncomingServerData(collection, config, items, state.source);
3282
+ const stats = await this.processIncomingServerData(
3283
+ collection,
3284
+ config,
3285
+ items,
3286
+ state.source
3287
+ );
3280
3288
  state.conflicts += stats.conflictsResolved;
3281
3289
  if (stats.maxTs) {
3282
3290
  if (!state.maxTs || this.compareTimestamps(stats.maxTs, state.maxTs) > 0) {
@@ -3358,12 +3366,16 @@ var _SyncEngine = class _SyncEngine {
3358
3366
  try {
3359
3367
  uploadStats = await this.uploadDirtyItems(calledFrom);
3360
3368
  await this.deps.flushAllPendingChanges();
3361
- const followUp = await this.uploadDirtyItems(`${calledFrom != null ? calledFrom : "sync"}:followUp`);
3369
+ const followUp = await this.uploadDirtyItems(
3370
+ `${calledFrom != null ? calledFrom : "sync"}:followUp`
3371
+ );
3362
3372
  if (followUp.sentCount > 0) {
3363
3373
  uploadStats.sentCount += followUp.sentCount;
3364
3374
  if (followUp.collectionSentCounts) {
3365
3375
  uploadStats.collectionSentCounts = uploadStats.collectionSentCounts || {};
3366
- for (const [c, n] of Object.entries(followUp.collectionSentCounts)) {
3376
+ for (const [c, n] of Object.entries(
3377
+ followUp.collectionSentCounts
3378
+ )) {
3367
3379
  uploadStats.collectionSentCounts[c] = (uploadStats.collectionSentCounts[c] || 0) + n;
3368
3380
  }
3369
3381
  }
@@ -3375,7 +3387,9 @@ var _SyncEngine = class _SyncEngine {
3375
3387
  );
3376
3388
  }
3377
3389
  sentCount = uploadStats.sentCount;
3378
- for (const [collectionName, stats] of Object.entries(uploadStats.collectionSentCounts || {})) {
3390
+ for (const [collectionName, stats] of Object.entries(
3391
+ uploadStats.collectionSentCounts || {}
3392
+ )) {
3379
3393
  if (collectionStats[collectionName]) {
3380
3394
  collectionStats[collectionName].sentCount = stats;
3381
3395
  } else {
@@ -3473,15 +3487,20 @@ var _SyncEngine = class _SyncEngine {
3473
3487
  });
3474
3488
  }
3475
3489
  }
3476
- if (dexieSave.length > 0) await this.dexieDb.saveMany(collection, dexieSave);
3490
+ if (dexieSave.length > 0)
3491
+ await this.dexieDb.saveMany(collection, dexieSave);
3477
3492
  if (dexieDeleteIds.length > 0) {
3478
3493
  await this.dexieDb.deleteMany(collection, dexieDeleteIds);
3479
3494
  }
3480
3495
  if (memUpsert.length > 0) {
3481
- this.deps.writeToInMemBatch(collection, memUpsert, "upsert", { source: "incremental" });
3496
+ this.deps.writeToInMemBatch(collection, memUpsert, "upsert", {
3497
+ source: "incremental"
3498
+ });
3482
3499
  }
3483
3500
  if (memDelete.length > 0) {
3484
- this.deps.writeToInMemBatch(collection, memDelete, "delete", { source: "incremental" });
3501
+ this.deps.writeToInMemBatch(collection, memDelete, "delete", {
3502
+ source: "incremental"
3503
+ });
3485
3504
  }
3486
3505
  if (reAddDirty.length > 0) {
3487
3506
  await this.dexieDb.addDirtyChangesBatch(collection, reAddDirty);
@@ -3520,7 +3539,10 @@ var _SyncEngine = class _SyncEngine {
3520
3539
  const updates = [];
3521
3540
  const skipped = [];
3522
3541
  const ids = dirtyChanges.map((dc) => dc._id);
3523
- const fullItems = await this.dexieDb.getByIds(collectionName, ids);
3542
+ const fullItems = await this.dexieDb.getByIds(
3543
+ collectionName,
3544
+ ids
3545
+ );
3524
3546
  const orphanReconstructed = [];
3525
3547
  for (let i = 0; i < fullItems.length; i++) {
3526
3548
  const fullItem = fullItems[i];
@@ -3531,7 +3553,10 @@ var _SyncEngine = class _SyncEngine {
3531
3553
  const currentServerRev = typeof fullItem._rev === "number" ? fullItem._rev : void 0;
3532
3554
  updates.push({ _id: fullItem._id, delta, currentServerRev });
3533
3555
  } else {
3534
- skipped.push({ _id: String(fullItem._id), reason: "no-delta-for-fullitem" });
3556
+ skipped.push({
3557
+ _id: String(fullItem._id),
3558
+ reason: "no-delta-for-fullitem"
3559
+ });
3535
3560
  }
3536
3561
  } else if (id != null) {
3537
3562
  const delta = dirtyChangesMap.get(String(id));
@@ -3568,7 +3593,10 @@ var _SyncEngine = class _SyncEngine {
3568
3593
  timestamp: /* @__PURE__ */ new Date()
3569
3594
  });
3570
3595
  } catch (err) {
3571
- console.error(`[SyncEngine] onUploadSkip callback failed: ${err}`, err);
3596
+ console.error(
3597
+ `[SyncEngine] onUploadSkip callback failed: ${err}`,
3598
+ err
3599
+ );
3572
3600
  }
3573
3601
  }
3574
3602
  continue;
@@ -3585,10 +3613,14 @@ var _SyncEngine = class _SyncEngine {
3585
3613
  timestamp: /* @__PURE__ */ new Date()
3586
3614
  });
3587
3615
  } catch (err) {
3588
- console.error(`[SyncEngine] onUploadSkip callback failed: ${err}`, err);
3616
+ console.error(
3617
+ `[SyncEngine] onUploadSkip callback failed: ${err}`,
3618
+ err
3619
+ );
3589
3620
  }
3590
3621
  }
3591
3622
  const mappedUpdates = [];
3623
+ const preprocessSkippedIds = [];
3592
3624
  for (const item of updates) {
3593
3625
  const dirtyBaseRev = typeof item.delta._rev === "number" ? item.delta._rev : void 0;
3594
3626
  const stripped = stripServerManagedFromChanges(
@@ -3605,8 +3637,12 @@ var _SyncEngine = class _SyncEngine {
3605
3637
  };
3606
3638
  if (this.preprocessDirtyItem) {
3607
3639
  try {
3608
- const processed = this.preprocessDirtyItem(candidate, collectionName);
3640
+ const processed = this.preprocessDirtyItem(
3641
+ candidate,
3642
+ collectionName
3643
+ );
3609
3644
  if (processed === void 0) {
3645
+ preprocessSkippedIds.push(item._id);
3610
3646
  continue;
3611
3647
  }
3612
3648
  candidate = processed;
@@ -3615,6 +3651,7 @@ var _SyncEngine = class _SyncEngine {
3615
3651
  `[SyncEngine] preprocessDirtyItem(${collectionName}) failed for _id=${String(item._id)}; keeping dirty for retry:`,
3616
3652
  err
3617
3653
  );
3654
+ preprocessSkippedIds.push(item._id);
3618
3655
  continue;
3619
3656
  }
3620
3657
  }
@@ -3624,14 +3661,23 @@ var _SyncEngine = class _SyncEngine {
3624
3661
  update: candidate.update
3625
3662
  });
3626
3663
  }
3664
+ if (preprocessSkippedIds.length > 0) {
3665
+ const newlyStuck = await this.dexieDb.incrementDirtyUploadAttempts(
3666
+ collectionName,
3667
+ preprocessSkippedIds
3668
+ );
3669
+ this.callOnDirtyItemStuck(collectionName, newlyStuck, calledFrom);
3670
+ }
3627
3671
  if (mappedUpdates.length === 0) continue;
3628
- collectionBatches.push([{
3629
- collection: collectionName,
3630
- batch: {
3631
- updates: mappedUpdates,
3632
- deletes: []
3672
+ collectionBatches.push([
3673
+ {
3674
+ collection: collectionName,
3675
+ batch: {
3676
+ updates: mappedUpdates,
3677
+ deletes: []
3678
+ }
3633
3679
  }
3634
- }]);
3680
+ ]);
3635
3681
  }
3636
3682
  if (collectionBatches.length === 0) {
3637
3683
  return { sentCount: 0 };
@@ -3669,7 +3715,10 @@ var _SyncEngine = class _SyncEngine {
3669
3715
  const allIds = [];
3670
3716
  for (const u of b.batch.updates) allIds.push(u._id);
3671
3717
  for (const d of b.batch.deletes) allIds.push((_a = d._id) != null ? _a : d);
3672
- const newlyStuck = await this.dexieDb.incrementDirtyUploadAttempts(b.collection, allIds);
3718
+ const newlyStuck = await this.dexieDb.incrementDirtyUploadAttempts(
3719
+ b.collection,
3720
+ allIds
3721
+ );
3673
3722
  this.callOnDirtyItemStuck(b.collection, newlyStuck, calledFrom);
3674
3723
  }
3675
3724
  }
@@ -3721,7 +3770,9 @@ var _SyncEngine = class _SyncEngine {
3721
3770
  `[SyncEngine] Sync upload [${collection}]: ${ambiguous.length} id(s) appeared in BOTH inserted/updated/deleted AND errors[] \u2014 keeping dirty for safety. _ids: ${ambiguous.join(", ")}`
3722
3771
  );
3723
3772
  }
3724
- const dirtyBeforeRefresh = mustRefreshIds.size > 0 ? await this.dexieDb.getDirtyChangesBatch(collection, [...mustRefreshIds]) : /* @__PURE__ */ new Map();
3773
+ const dirtyBeforeRefresh = mustRefreshIds.size > 0 ? await this.dexieDb.getDirtyChangesBatch(collection, [
3774
+ ...mustRefreshIds
3775
+ ]) : /* @__PURE__ */ new Map();
3725
3776
  const uploadedByIdRefresh = mustRefreshIds.size > 0 ? this.uploadedSnapshotFor(collectionBatches, collection) : /* @__PURE__ */ new Map();
3726
3777
  if (allSuccessIds.length > 0) {
3727
3778
  await this.dexieDb.clearDirtyChangesBatch(collection, allSuccessIds);
@@ -3730,8 +3781,10 @@ var _SyncEngine = class _SyncEngine {
3730
3781
  for (const batch of collectionBatches) {
3731
3782
  for (const b of batch) {
3732
3783
  if (b.collection !== collection) continue;
3733
- for (const u of b.batch.updates) sentIdsForCollection.add(String(u._id));
3734
- for (const d of b.batch.deletes) sentIdsForCollection.add(String(d._id));
3784
+ for (const u of b.batch.updates)
3785
+ sentIdsForCollection.add(String(u._id));
3786
+ for (const d of b.batch.deletes)
3787
+ sentIdsForCollection.add(String(d._id));
3735
3788
  }
3736
3789
  }
3737
3790
  const retainedIds = [];
@@ -3741,7 +3794,10 @@ var _SyncEngine = class _SyncEngine {
3741
3794
  }
3742
3795
  }
3743
3796
  if (retainedIds.length > 0) {
3744
- const newlyStuck = await this.dexieDb.incrementDirtyUploadAttempts(collection, retainedIds);
3797
+ const newlyStuck = await this.dexieDb.incrementDirtyUploadAttempts(
3798
+ collection,
3799
+ retainedIds
3800
+ );
3745
3801
  this.callOnDirtyItemStuck(collection, newlyStuck, calledFrom);
3746
3802
  }
3747
3803
  let collectionSentCount = 0;
@@ -3753,7 +3809,10 @@ var _SyncEngine = class _SyncEngine {
3753
3809
  if (isWriteOnly) {
3754
3810
  await this.dexieDb.deleteMany(collection, idsToCheck);
3755
3811
  } else {
3756
- const dexieItems = await this.dexieDb.getByIds(collection, idsToCheck);
3812
+ const dexieItems = await this.dexieDb.getByIds(
3813
+ collection,
3814
+ idsToCheck
3815
+ );
3757
3816
  const dexieSaveBatch = [];
3758
3817
  const inMemUpdateBatch = [];
3759
3818
  const inMemDeleteIds = [];
@@ -3781,7 +3840,12 @@ var _SyncEngine = class _SyncEngine {
3781
3840
  await this.dexieDb.deleteMany(collection, dexieDeleteIds);
3782
3841
  }
3783
3842
  if (inMemUpdateBatch.length > 0) {
3784
- this.deps.writeToInMemBatch(collection, inMemUpdateBatch, "upsert", { source: "incremental" });
3843
+ this.deps.writeToInMemBatch(
3844
+ collection,
3845
+ inMemUpdateBatch,
3846
+ "upsert",
3847
+ { source: "incremental" }
3848
+ );
3785
3849
  }
3786
3850
  if (inMemDeleteIds.length > 0) {
3787
3851
  this.deps.writeToInMemBatch(
@@ -3804,7 +3868,9 @@ var _SyncEngine = class _SyncEngine {
3804
3868
  }
3805
3869
  await this.dexieDb.deleteMany(collection, deleteIds);
3806
3870
  if (!isWriteOnly) {
3807
- this.deps.writeToInMemBatch(collection, deleteDbEntities, "delete", { source: "incremental" });
3871
+ this.deps.writeToInMemBatch(collection, deleteDbEntities, "delete", {
3872
+ source: "incremental"
3873
+ });
3808
3874
  }
3809
3875
  sentCount += deleted.length;
3810
3876
  collectionSentCount += deleted.length;
@@ -3820,7 +3886,7 @@ var _SyncEngine = class _SyncEngine {
3820
3886
  if (collectionSentCount > 0) {
3821
3887
  collectionSentCounts[collection] = collectionSentCount;
3822
3888
  }
3823
- let maxTs = void 0;
3889
+ let maxTs;
3824
3890
  for (const arr of [inserted, updated, deleted]) {
3825
3891
  for (const item of arr) {
3826
3892
  if (item._ts) {
@@ -3890,7 +3956,10 @@ var _SyncEngine = class _SyncEngine {
3890
3956
  return { sentCount: 0 };
3891
3957
  }
3892
3958
  const ids = dirtyItems.map((item) => item._id);
3893
- const fullItems = await this.dexieDb.getByIds(collection, ids);
3959
+ const fullItems = await this.dexieDb.getByIds(
3960
+ collection,
3961
+ ids
3962
+ );
3894
3963
  const dirtyChangesMap = /* @__PURE__ */ new Map();
3895
3964
  for (const dirtyItem of dirtyItems) {
3896
3965
  dirtyChangesMap.set(String(dirtyItem._id), dirtyItem);
@@ -3906,20 +3975,24 @@ var _SyncEngine = class _SyncEngine {
3906
3975
  if (updates.length === 0) {
3907
3976
  return { sentCount: 0 };
3908
3977
  }
3909
- const collectionBatches = [[{
3910
- collection,
3911
- batch: {
3912
- updates: updates.map((item) => {
3913
- const _a = item.delta, { _ts, _rev } = _a, changes = __objRest(_a, ["_ts", "_rev"]);
3914
- return {
3915
- _id: item._id,
3916
- _rev: typeof _rev === "number" ? _rev : 0,
3917
- update: changes
3918
- };
3919
- }),
3920
- deletes: []
3921
- }
3922
- }]];
3978
+ const collectionBatches = [
3979
+ [
3980
+ {
3981
+ collection,
3982
+ batch: {
3983
+ updates: updates.map((item) => {
3984
+ const _a = item.delta, { _ts, _rev } = _a, changes = __objRest(_a, ["_ts", "_rev"]);
3985
+ return {
3986
+ _id: item._id,
3987
+ _rev: typeof _rev === "number" ? _rev : 0,
3988
+ update: changes
3989
+ };
3990
+ }),
3991
+ deletes: []
3992
+ }
3993
+ }
3994
+ ]
3995
+ ];
3923
3996
  const results = await this.deps.withSyncTimeout(
3924
3997
  this.restInterface.updateCollections(collectionBatches),
3925
3998
  "updateCollections"
@@ -3986,8 +4059,10 @@ var _SyncEngine = class _SyncEngine {
3986
4059
  for (const batch of collectionBatches) {
3987
4060
  for (const b of batch) {
3988
4061
  if (b.collection !== collection) continue;
3989
- for (const u of b.batch.updates) sentIdsForCollection.add(String(u._id));
3990
- for (const d of b.batch.deletes) sentIdsForCollection.add(String(d._id));
4062
+ for (const u of b.batch.updates)
4063
+ sentIdsForCollection.add(String(u._id));
4064
+ for (const d of b.batch.deletes)
4065
+ sentIdsForCollection.add(String(d._id));
3991
4066
  }
3992
4067
  }
3993
4068
  const retainedIds = [];
@@ -3997,7 +4072,10 @@ var _SyncEngine = class _SyncEngine {
3997
4072
  }
3998
4073
  }
3999
4074
  if (retainedIds.length > 0) {
4000
- const newlyStuck = await this.dexieDb.incrementDirtyUploadAttempts(collection, retainedIds);
4075
+ const newlyStuck = await this.dexieDb.incrementDirtyUploadAttempts(
4076
+ collection,
4077
+ retainedIds
4078
+ );
4001
4079
  this.callOnDirtyItemStuck(collection, newlyStuck, calledFrom);
4002
4080
  }
4003
4081
  if (mustRefresh && mustRefresh.length > 0) {
@@ -4025,7 +4103,12 @@ var _SyncEngine = class _SyncEngine {
4025
4103
  const config = this.collections.get(collectionName);
4026
4104
  if (!config) return { updatedIds: [] };
4027
4105
  const source = (_a = opts == null ? void 0 : opts.source) != null ? _a : "incremental";
4028
- const result = await this.processIncomingServerData(collectionName, config, serverData, source);
4106
+ const result = await this.processIncomingServerData(
4107
+ collectionName,
4108
+ config,
4109
+ serverData,
4110
+ source
4111
+ );
4029
4112
  if (result.updatedIds.length > 0) {
4030
4113
  this.deps.broadcastUpdates({ [collectionName]: result.updatedIds });
4031
4114
  }
@@ -4043,8 +4126,14 @@ var _SyncEngine = class _SyncEngine {
4043
4126
  const chunk = serverData.slice(offset, offset + BATCH);
4044
4127
  const chunkIds = [];
4045
4128
  for (const item of chunk) chunkIds.push(item._id);
4046
- const localItems = await this.dexieDb.getByIds(collectionName, chunkIds);
4047
- const dirtyChangesMap = await this.dexieDb.getDirtyChangesBatch(collectionName, chunkIds);
4129
+ const localItems = await this.dexieDb.getByIds(
4130
+ collectionName,
4131
+ chunkIds
4132
+ );
4133
+ const dirtyChangesMap = await this.dexieDb.getDirtyChangesBatch(
4134
+ collectionName,
4135
+ chunkIds
4136
+ );
4048
4137
  const dexieBatch = [];
4049
4138
  const inMemSaveBatch = [];
4050
4139
  const inMemDeleteIds = [];
@@ -4093,7 +4182,9 @@ var _SyncEngine = class _SyncEngine {
4093
4182
  await this.dexieDb.saveMany(collectionName, dexieBatch);
4094
4183
  }
4095
4184
  if (inMemSaveBatch.length > 0) {
4096
- this.deps.writeToInMemBatch(collectionName, inMemSaveBatch, "upsert", { source });
4185
+ this.deps.writeToInMemBatch(collectionName, inMemSaveBatch, "upsert", {
4186
+ source
4187
+ });
4097
4188
  }
4098
4189
  if (inMemDeleteIds.length > 0) {
4099
4190
  this.deps.writeToInMemBatch(
@@ -4141,7 +4232,10 @@ var _SyncEngine = class _SyncEngine {
4141
4232
  timestamp: /* @__PURE__ */ new Date()
4142
4233
  });
4143
4234
  } catch (err) {
4144
- console.error(`[SyncEngine] onConflictResolved callback failed: ${err}`, err);
4235
+ console.error(
4236
+ `[SyncEngine] onConflictResolved callback failed: ${err}`,
4237
+ err
4238
+ );
4145
4239
  }
4146
4240
  }
4147
4241
  return resolved;
@@ -4186,7 +4280,10 @@ var _SyncEngine = class _SyncEngine {
4186
4280
  calledFrom
4187
4281
  });
4188
4282
  } catch (err) {
4189
- console.error(`[SyncEngine] onFindNewerManyCall callback failed: ${err}`, err);
4283
+ console.error(
4284
+ `[SyncEngine] onFindNewerManyCall callback failed: ${err}`,
4285
+ err
4286
+ );
4190
4287
  }
4191
4288
  }
4192
4289
  }
@@ -4205,7 +4302,10 @@ var _SyncEngine = class _SyncEngine {
4205
4302
  ttfbMs: metrics == null ? void 0 : metrics.ttfbMs
4206
4303
  });
4207
4304
  } catch (err) {
4208
- console.error(`[SyncEngine] onFindNewerManyResult callback failed: ${err}`, err);
4305
+ console.error(
4306
+ `[SyncEngine] onFindNewerManyResult callback failed: ${err}`,
4307
+ err
4308
+ );
4209
4309
  }
4210
4310
  }
4211
4311
  }
@@ -4218,7 +4318,10 @@ var _SyncEngine = class _SyncEngine {
4218
4318
  calledFrom
4219
4319
  });
4220
4320
  } catch (err) {
4221
- console.error(`[SyncEngine] onServerWriteRequest callback failed: ${err}`, err);
4321
+ console.error(
4322
+ `[SyncEngine] onServerWriteRequest callback failed: ${err}`,
4323
+ err
4324
+ );
4222
4325
  }
4223
4326
  }
4224
4327
  }
@@ -4233,7 +4336,10 @@ var _SyncEngine = class _SyncEngine {
4233
4336
  calledFrom
4234
4337
  });
4235
4338
  } catch (err) {
4236
- console.error(`[SyncEngine] onServerWriteResult callback failed: ${err}`, err);
4339
+ console.error(
4340
+ `[SyncEngine] onServerWriteResult callback failed: ${err}`,
4341
+ err
4342
+ );
4237
4343
  }
4238
4344
  }
4239
4345
  }
@@ -4247,7 +4353,10 @@ var _SyncEngine = class _SyncEngine {
4247
4353
  timestamp: /* @__PURE__ */ new Date()
4248
4354
  });
4249
4355
  } catch (err) {
4250
- console.error(`[SyncEngine] onDirtyItemStuck callback failed: ${err}`, err);
4356
+ console.error(
4357
+ `[SyncEngine] onDirtyItemStuck callback failed: ${err}`,
4358
+ err
4359
+ );
4251
4360
  }
4252
4361
  }
4253
4362
  callOnServerSyncWrite(request, response, error, startTime, timestamp, calledFrom) {
@@ -4267,7 +4376,10 @@ var _SyncEngine = class _SyncEngine {
4267
4376
  timestamp
4268
4377
  });
4269
4378
  } catch (err) {
4270
- console.error(`[SyncEngine] onServerSyncWrite callback failed: ${err}`, err);
4379
+ console.error(
4380
+ `[SyncEngine] onServerSyncWrite callback failed: ${err}`,
4381
+ err
4382
+ );
4271
4383
  }
4272
4384
  }
4273
4385
  };
@@ -4790,7 +4902,8 @@ var _SyncedDb = class _SyncedDb {
4790
4902
  this.evictOnWake = (_g = config.evictOnWake) != null ? _g : false;
4791
4903
  for (const col of config.collections) {
4792
4904
  this.collections.set(col.name, col);
4793
- if (!col.writeOnly) this.preloadStatusMap.set(col.name, { state: "pending", itemCount: 0 });
4905
+ if (!col.writeOnly)
4906
+ this.preloadStatusMap.set(col.name, { state: "pending", itemCount: 0 });
4794
4907
  }
4795
4908
  this.inMemManager = new InMemManager({
4796
4909
  inMemDb: this.inMemDb,
@@ -4804,14 +4917,20 @@ var _SyncedDb = class _SyncedDb {
4804
4917
  onBecameLeader: () => {
4805
4918
  if (this.initialized && !this.connectionManager.isOnline() && !this.connectionManager.isForcedOffline()) {
4806
4919
  this.connectionManager.tryGoOnline().catch((err) => {
4807
- networkError(`[SyncedDb] tryGoOnline on becameLeader failed: ${err}`, err);
4920
+ networkError(
4921
+ `[SyncedDb] tryGoOnline on becameLeader failed: ${err}`,
4922
+ err
4923
+ );
4808
4924
  });
4809
4925
  }
4810
4926
  if (config.onBecameLeader) {
4811
4927
  try {
4812
4928
  config.onBecameLeader();
4813
4929
  } catch (err) {
4814
- console.error(`[SyncedDb] onBecameLeader callback failed: ${err}`, err);
4930
+ console.error(
4931
+ `[SyncedDb] onBecameLeader callback failed: ${err}`,
4932
+ err
4933
+ );
4815
4934
  }
4816
4935
  }
4817
4936
  },
@@ -4914,7 +5033,9 @@ var _SyncedDb = class _SyncedDb {
4914
5033
  restInterface: this.restInterface,
4915
5034
  preprocessDirtyItem: config.preprocessDirtyItem,
4916
5035
  callbacks: {
4917
- onSyncStart: config.onSyncStart ? (info) => config.onSyncStart(__spreadProps(__spreadValues({}, info), { initialSync: !this._lastFullSyncDate })) : void 0,
5036
+ onSyncStart: config.onSyncStart ? (info) => config.onSyncStart(__spreadProps(__spreadValues({}, info), {
5037
+ initialSync: !this._lastFullSyncDate
5038
+ })) : void 0,
4918
5039
  onSyncEnd: config.onSyncEnd,
4919
5040
  onSyncProgress: config.onSyncProgress,
4920
5041
  onServerSyncStart: config.onServerSyncStart,
@@ -5056,7 +5177,12 @@ var _SyncedDb = class _SyncedDb {
5056
5177
  "[SyncedDb] callWorker: no serverUpdateNotifier or notifier does not support callWorker"
5057
5178
  );
5058
5179
  }
5059
- return fn.call(this.serverUpdateNotifier, service, payload, options);
5180
+ return fn.call(
5181
+ this.serverUpdateNotifier,
5182
+ service,
5183
+ payload,
5184
+ options
5185
+ );
5060
5186
  }
5061
5187
  /**
5062
5188
  * Register a collection for sync at runtime. See `I_SyncedDb.addCollectionToSync`.
@@ -5093,7 +5219,10 @@ var _SyncedDb = class _SyncedDb {
5093
5219
  if (existing && !existing.temporaryConfig) continue;
5094
5220
  this.collections.set(spec.name, spec);
5095
5221
  if (!spec.writeOnly && !this.preloadStatusMap.has(spec.name)) {
5096
- this.preloadStatusMap.set(spec.name, { state: "pending", itemCount: 0 });
5222
+ this.preloadStatusMap.set(spec.name, {
5223
+ state: "pending",
5224
+ itemCount: 0
5225
+ });
5097
5226
  }
5098
5227
  if (this.syncOnlyCollections) {
5099
5228
  this.syncOnlyCollections.add(spec.name);
@@ -5155,7 +5284,11 @@ var _SyncedDb = class _SyncedDb {
5155
5284
  if (!data || data.length === 0) continue;
5156
5285
  const source = plan.wasFirstTime ? "initial" : "incremental";
5157
5286
  try {
5158
- await this.syncEngine.processCollectionServerData(plan.spec.name, data, { source });
5287
+ await this.syncEngine.processCollectionServerData(
5288
+ plan.spec.name,
5289
+ data,
5290
+ { source }
5291
+ );
5159
5292
  } catch (err) {
5160
5293
  console.error(
5161
5294
  `[SyncedDb] addCollectionsToSync: processCollectionServerData failed for "${plan.spec.name}":`,
@@ -5194,7 +5327,9 @@ var _SyncedDb = class _SyncedDb {
5194
5327
  if (!spec.writeOnly && this.connectionManager.canSync()) {
5195
5328
  const rawQuery = (_a = spec.syncConfig) == null ? void 0 : _a.query;
5196
5329
  const query = typeof rawQuery === "function" ? rawQuery() : rawQuery;
5197
- await this.syncCollectionForFind(spec.name, query, { returnDeleted: true });
5330
+ await this.syncCollectionForFind(spec.name, query, {
5331
+ returnDeleted: true
5332
+ });
5198
5333
  }
5199
5334
  }
5200
5335
  /**
@@ -5220,7 +5355,10 @@ var _SyncedDb = class _SyncedDb {
5220
5355
  }
5221
5356
  this.emitPreloadStatusChange();
5222
5357
  if (newlyAllowed.length > 0) {
5223
- await this.loadCollectionsToInMem(newlyAllowed, "setSyncOnlyTheseCollections");
5358
+ await this.loadCollectionsToInMem(
5359
+ newlyAllowed,
5360
+ "setSyncOnlyTheseCollections"
5361
+ );
5224
5362
  }
5225
5363
  if (newlyAllowed.length > 0 && this.connectionManager.canSync()) {
5226
5364
  this.sync("setSyncOnlyTheseCollections").catch(() => {
@@ -5262,12 +5400,17 @@ var _SyncedDb = class _SyncedDb {
5262
5400
  try {
5263
5401
  this.onDatabaseCreated();
5264
5402
  } catch (err) {
5265
- console.error(`[SyncedDb] onDatabaseCreated callback failed: ${err}`, err);
5403
+ console.error(
5404
+ `[SyncedDb] onDatabaseCreated callback failed: ${err}`,
5405
+ err
5406
+ );
5266
5407
  }
5267
5408
  }
5268
5409
  await this.pendingChanges.recoverPendingWrites();
5269
5410
  await this.preloadAllSyncMetas();
5270
- const allowedColls = [...this.collections.keys()].filter((n) => this.isSyncAllowed(n));
5411
+ const allowedColls = [...this.collections.keys()].filter(
5412
+ (n) => this.isSyncAllowed(n)
5413
+ );
5271
5414
  await this.loadCollectionsToInMem(allowedColls, "init");
5272
5415
  this.leaderElection.init();
5273
5416
  this.crossTabSync.init();
@@ -5298,7 +5441,9 @@ var _SyncedDb = class _SyncedDb {
5298
5441
  console.log(`[SyncedDb] SyncedDb: ebus-proxy connected to ${ep}`);
5299
5442
  } catch (err) {
5300
5443
  const ep = (_d = this.serverUpdateNotifier.endpoint) != null ? _d : "unknown";
5301
- console.warn(`[SyncedDb] SyncedDb: ebus-proxy connection to ${ep} failed`);
5444
+ console.warn(
5445
+ `[SyncedDb] SyncedDb: ebus-proxy connection to ${ep} failed`
5446
+ );
5302
5447
  this.connectionManager.reportInfrastructureError(
5303
5448
  "WEBSOCKET_CONNECTION_FAILED",
5304
5449
  `WebSocket connection to ${ep} failed during initialization`,
@@ -5320,10 +5465,16 @@ var _SyncedDb = class _SyncedDb {
5320
5465
  this.visibilityFlushHandler = () => {
5321
5466
  if (document.visibilityState !== "hidden") return;
5322
5467
  this.flushToServer("visibility-hidden").catch((err) => {
5323
- console.warn(`[SyncedDb] flushToServer on visibility-hidden failed: ${err == null ? void 0 : err.message}`, err);
5468
+ console.warn(
5469
+ `[SyncedDb] flushToServer on visibility-hidden failed: ${err == null ? void 0 : err.message}`,
5470
+ err
5471
+ );
5324
5472
  });
5325
5473
  };
5326
- document.addEventListener("visibilitychange", this.visibilityFlushHandler);
5474
+ document.addEventListener(
5475
+ "visibilitychange",
5476
+ this.visibilityFlushHandler
5477
+ );
5327
5478
  }
5328
5479
  this._checkForceFullResyncThreshold("init");
5329
5480
  this._startForceResyncCheckTimer();
@@ -5436,7 +5587,10 @@ var _SyncedDb = class _SyncedDb {
5436
5587
  });
5437
5588
  if (this.connectionManager.canSync()) {
5438
5589
  this.sync(`force-full-resync:${reason}`).catch((err) => {
5439
- console.error(`[SyncedDb] force full resync sync() failed: ${err}`, err);
5590
+ console.error(
5591
+ `[SyncedDb] force full resync sync() failed: ${err}`,
5592
+ err
5593
+ );
5440
5594
  });
5441
5595
  }
5442
5596
  }
@@ -5510,7 +5664,10 @@ var _SyncedDb = class _SyncedDb {
5510
5664
  this.beforeUnloadHandler = void 0;
5511
5665
  }
5512
5666
  if (typeof document !== "undefined" && this.visibilityFlushHandler) {
5513
- document.removeEventListener("visibilitychange", this.visibilityFlushHandler);
5667
+ document.removeEventListener(
5668
+ "visibilitychange",
5669
+ this.visibilityFlushHandler
5670
+ );
5514
5671
  this.visibilityFlushHandler = void 0;
5515
5672
  }
5516
5673
  this.syncMetaCache.clear();
@@ -5590,7 +5747,12 @@ var _SyncedDb = class _SyncedDb {
5590
5747
  if (serverItem) {
5591
5748
  await this.dexieDb.saveMany(collection, [serverItem]);
5592
5749
  if (!serverItem._deleted && !serverItem._archived) {
5593
- this.inMemManager.writeBatch(collection, [serverItem], "upsert", { source: "incremental" });
5750
+ this.inMemManager.writeBatch(
5751
+ collection,
5752
+ [serverItem],
5753
+ "upsert",
5754
+ { source: "incremental" }
5755
+ );
5594
5756
  }
5595
5757
  }
5596
5758
  } catch (e) {
@@ -5663,9 +5825,16 @@ var _SyncedDb = class _SyncedDb {
5663
5825
  );
5664
5826
  if (serverItems && serverItems.length > 0) {
5665
5827
  await this.dexieDb.saveMany(collection, serverItems);
5666
- const toInMem = serverItems.filter((s) => !s._deleted && !s._archived);
5828
+ const toInMem = serverItems.filter(
5829
+ (s) => !s._deleted && !s._archived
5830
+ );
5667
5831
  if (toInMem.length > 0) {
5668
- this.inMemManager.writeBatch(collection, toInMem, "upsert", { source: "incremental" });
5832
+ this.inMemManager.writeBatch(
5833
+ collection,
5834
+ toInMem,
5835
+ "upsert",
5836
+ { source: "incremental" }
5837
+ );
5669
5838
  }
5670
5839
  }
5671
5840
  } catch (e) {
@@ -5706,11 +5875,16 @@ var _SyncedDb = class _SyncedDb {
5706
5875
  filtered.push(item);
5707
5876
  }
5708
5877
  if (filtered.length === 0) {
5709
- if ((opts == null ? void 0 : opts.referToServer) && this.isOnline()) this.referToServerSync(collection, query);
5878
+ if ((opts == null ? void 0 : opts.referToServer) && this.isOnline())
5879
+ this.referToServerSync(collection, query);
5710
5880
  return null;
5711
5881
  }
5712
- const sorted = applyQueryOpts(filtered, { sort: opts.sort, project: opts == null ? void 0 : opts.project });
5713
- if ((opts == null ? void 0 : opts.referToServer) && this.isOnline()) this.referToServerSync(collection, query);
5882
+ const sorted = applyQueryOpts(filtered, {
5883
+ sort: opts.sort,
5884
+ project: opts == null ? void 0 : opts.project
5885
+ });
5886
+ if ((opts == null ? void 0 : opts.referToServer) && this.isOnline())
5887
+ this.referToServerSync(collection, query);
5714
5888
  return (_b = sorted[0]) != null ? _b : null;
5715
5889
  } else {
5716
5890
  let result = null;
@@ -5724,7 +5898,8 @@ var _SyncedDb = class _SyncedDb {
5724
5898
  if (result && (opts == null ? void 0 : opts.project)) {
5725
5899
  result = projectItem(result, opts.project);
5726
5900
  }
5727
- if ((opts == null ? void 0 : opts.referToServer) && this.isOnline()) this.referToServerSync(collection, query);
5901
+ if ((opts == null ? void 0 : opts.referToServer) && this.isOnline())
5902
+ this.referToServerSync(collection, query);
5728
5903
  return result;
5729
5904
  }
5730
5905
  }
@@ -5777,15 +5952,24 @@ var _SyncedDb = class _SyncedDb {
5777
5952
  const timestamp = (meta == null ? void 0 : meta.lastSyncTs) || 0;
5778
5953
  try {
5779
5954
  const serverData = await this.connectionManager.withRestTimeout(
5780
- this.restInterface.findNewer(collection, timestamp, query, {
5781
- returnDeleted: (opts == null ? void 0 : opts.returnDeleted) || false,
5782
- returnArchived: (opts == null ? void 0 : opts.returnArchived) || false
5783
- }),
5955
+ this.restInterface.findNewer(
5956
+ collection,
5957
+ timestamp,
5958
+ query,
5959
+ {
5960
+ returnDeleted: (opts == null ? void 0 : opts.returnDeleted) || false,
5961
+ returnArchived: (opts == null ? void 0 : opts.returnArchived) || false
5962
+ }
5963
+ ),
5784
5964
  "syncCollectionForFind"
5785
5965
  );
5786
5966
  if (serverData.length > 0) {
5787
5967
  const source = timestamp === 0 ? "initial" : "incremental";
5788
- await this.syncEngine.processCollectionServerData(collection, serverData, { source });
5968
+ await this.syncEngine.processCollectionServerData(
5969
+ collection,
5970
+ serverData,
5971
+ { source }
5972
+ );
5789
5973
  }
5790
5974
  } catch (e) {
5791
5975
  }
@@ -5799,11 +5983,17 @@ var _SyncedDb = class _SyncedDb {
5799
5983
  */
5800
5984
  referToServerSync(collection, query) {
5801
5985
  this.connectionManager.withRestTimeout(
5802
- this.restInterface.findNewer(collection, 0, query, { returnDeleted: true }),
5986
+ this.restInterface.findNewer(collection, 0, query, {
5987
+ returnDeleted: true
5988
+ }),
5803
5989
  "referToServer"
5804
5990
  ).then(async (serverData) => {
5805
5991
  if (serverData.length > 0) {
5806
- await this.syncEngine.processCollectionServerData(collection, serverData, { source: "refresh" });
5992
+ await this.syncEngine.processCollectionServerData(
5993
+ collection,
5994
+ serverData,
5995
+ { source: "refresh" }
5996
+ );
5807
5997
  }
5808
5998
  }).catch((err) => {
5809
5999
  networkError(`[SyncedDb] referToServer failed for ${collection}:`, err);
@@ -5831,7 +6021,10 @@ var _SyncedDb = class _SyncedDb {
5831
6021
  for (const item of serverItems) {
5832
6022
  serverById.set(String(item._id), item);
5833
6023
  }
5834
- const localItems = await this.dexieDb.getByIds(collection, ids);
6024
+ const localItems = await this.dexieDb.getByIds(
6025
+ collection,
6026
+ ids
6027
+ );
5835
6028
  const dirtyMap = await this.dexieDb.getDirtyChangesBatch(collection, ids);
5836
6029
  const toSaveDexie = [];
5837
6030
  const toSaveInMem = [];
@@ -5859,10 +6052,16 @@ var _SyncedDb = class _SyncedDb {
5859
6052
  await this.dexieDb.saveMany(collection, toSaveDexie);
5860
6053
  }
5861
6054
  if (toSaveInMem.length > 0) {
5862
- this.inMemManager.writeBatch(collection, toSaveInMem, "upsert", { source: "incremental" });
6055
+ this.inMemManager.writeBatch(collection, toSaveInMem, "upsert", {
6056
+ source: "incremental"
6057
+ });
5863
6058
  }
5864
6059
  if (dirtyServerItems.length > 0) {
5865
- await this.syncEngine.processCollectionServerData(collection, dirtyServerItems, { source: "incremental" });
6060
+ await this.syncEngine.processCollectionServerData(
6061
+ collection,
6062
+ dirtyServerItems,
6063
+ { source: "incremental" }
6064
+ );
5866
6065
  }
5867
6066
  }
5868
6067
  /**
@@ -5890,9 +6089,16 @@ var _SyncedDb = class _SyncedDb {
5890
6089
  "refreshInBackground"
5891
6090
  ).then(async (serverItems) => {
5892
6091
  if (!serverItems || serverItems.length === 0) return;
5893
- await this.syncEngine.processCollectionServerData(collection, serverItems, { source: "incremental" });
6092
+ await this.syncEngine.processCollectionServerData(
6093
+ collection,
6094
+ serverItems,
6095
+ { source: "incremental" }
6096
+ );
5894
6097
  }).catch((err) => {
5895
- networkError(`[SyncedDb] refreshInBackground failed for ${collection}:`, err);
6098
+ networkError(
6099
+ `[SyncedDb] refreshInBackground failed for ${collection}:`,
6100
+ err
6101
+ );
5896
6102
  });
5897
6103
  }
5898
6104
  async ensureItemsAreLoaded(collection, ids, withDeleted) {
@@ -5920,7 +6126,9 @@ var _SyncedDb = class _SyncedDb {
5920
6126
  await this.dexieDb.saveMany(collection, toSaveDexie);
5921
6127
  }
5922
6128
  if (toSaveInMem.length > 0) {
5923
- this.inMemManager.writeBatch(collection, toSaveInMem, "upsert", { source: "incremental" });
6129
+ this.inMemManager.writeBatch(collection, toSaveInMem, "upsert", {
6130
+ source: "incremental"
6131
+ });
5924
6132
  }
5925
6133
  }
5926
6134
  // ==================== Write Operations ====================
@@ -5965,12 +6173,10 @@ var _SyncedDb = class _SyncedDb {
5965
6173
  }
5966
6174
  const fullChanges = __spreadProps(__spreadValues({}, update), { _lastUpdaterId: this.updaterId });
5967
6175
  const diff = computeObjDiff(existing, fullChanges);
5968
- await this.dexieDb.addDirtyChange(
5969
- collection,
5970
- id,
5971
- diff,
5972
- { _ts: existing == null ? void 0 : existing._ts, _rev: existing == null ? void 0 : existing._rev }
5973
- );
6176
+ await this.dexieDb.addDirtyChange(collection, id, diff, {
6177
+ _ts: existing == null ? void 0 : existing._ts,
6178
+ _rev: existing == null ? void 0 : existing._rev
6179
+ });
5974
6180
  const isWriteOnly = (_b = this.collections.get(collection)) == null ? void 0 : _b.writeOnly;
5975
6181
  const currentMem = isWriteOnly ? null : this.inMemDb.getById(collection, id);
5976
6182
  const merged = applyObjDiff(
@@ -5979,9 +6185,17 @@ var _SyncedDb = class _SyncedDb {
5979
6185
  id,
5980
6186
  collection
5981
6187
  );
5982
- this.pendingChanges.schedule(collection, id, merged, 0, "save");
6188
+ this.pendingChanges.schedule(
6189
+ collection,
6190
+ id,
6191
+ merged,
6192
+ 0,
6193
+ "save"
6194
+ );
5983
6195
  if (!isWriteOnly && !(existing == null ? void 0 : existing._deleted) && !(existing == null ? void 0 : existing._archived)) {
5984
- this.inMemManager.writeBatch(collection, [merged], "upsert", { source: "incremental" });
6196
+ this.inMemManager.writeBatch(collection, [merged], "upsert", {
6197
+ source: "incremental"
6198
+ });
5985
6199
  }
5986
6200
  return merged;
5987
6201
  }
@@ -6026,7 +6240,12 @@ var _SyncedDb = class _SyncedDb {
6026
6240
  for (const path of unsetPaths) deleteByPath(newData, path);
6027
6241
  this.pendingChanges.schedule(collection, id, newData, 0, "insert");
6028
6242
  if (!((_a = this.collections.get(collection)) == null ? void 0 : _a.writeOnly)) {
6029
- this.inMemManager.writeBatch(collection, [newData], "upsert", { source: "incremental" });
6243
+ this.inMemManager.writeBatch(
6244
+ collection,
6245
+ [newData],
6246
+ "upsert",
6247
+ { source: "incremental" }
6248
+ );
6030
6249
  }
6031
6250
  return newData;
6032
6251
  }
@@ -6050,7 +6269,12 @@ var _SyncedDb = class _SyncedDb {
6050
6269
  };
6051
6270
  this.pendingChanges.schedule(collection, id, deleteUpdate, 0, "deleteOne");
6052
6271
  if (!((_a = this.collections.get(collection)) == null ? void 0 : _a.writeOnly)) {
6053
- this.inMemManager.writeBatch(collection, [{ _id: id }], "delete", { source: "incremental" });
6272
+ this.inMemManager.writeBatch(
6273
+ collection,
6274
+ [{ _id: id }],
6275
+ "delete",
6276
+ { source: "incremental" }
6277
+ );
6054
6278
  }
6055
6279
  return existing;
6056
6280
  }
@@ -6060,7 +6284,10 @@ var _SyncedDb = class _SyncedDb {
6060
6284
  const items = await this.find(collection, query);
6061
6285
  if (items.length === 0) return 0;
6062
6286
  const ids = items.map((item) => item._id);
6063
- const existingItems = await this.dexieDb.getByIds(collection, ids);
6287
+ const existingItems = await this.dexieDb.getByIds(
6288
+ collection,
6289
+ ids
6290
+ );
6064
6291
  const now = /* @__PURE__ */ new Date();
6065
6292
  const dirtyChangesBatch = [];
6066
6293
  const idsToDelete = [];
@@ -6077,7 +6304,13 @@ var _SyncedDb = class _SyncedDb {
6077
6304
  _deleted: now,
6078
6305
  _lastUpdaterId: this.updaterId
6079
6306
  };
6080
- this.pendingChanges.schedule(collection, item._id, deleteUpdate, 0, "deleteMany");
6307
+ this.pendingChanges.schedule(
6308
+ collection,
6309
+ item._id,
6310
+ deleteUpdate,
6311
+ 0,
6312
+ "deleteMany"
6313
+ );
6081
6314
  idsToDelete.push(item._id);
6082
6315
  }
6083
6316
  if (dirtyChangesBatch.length > 0) {
@@ -6105,11 +6338,19 @@ var _SyncedDb = class _SyncedDb {
6105
6338
  return null;
6106
6339
  }
6107
6340
  await this.connectionManager.withRestTimeout(
6108
- this.restInterface.call("hardDeleteOne", { collection, query: { _id: id } }),
6341
+ this.restInterface.call("hardDeleteOne", {
6342
+ collection,
6343
+ query: { _id: id }
6344
+ }),
6109
6345
  "hardDeleteOne"
6110
6346
  );
6111
6347
  await this.dexieDb.deleteOne(collection, id);
6112
- this.inMemManager.writeBatch(collection, [{ _id: id }], "delete", { source: "incremental" });
6348
+ this.inMemManager.writeBatch(
6349
+ collection,
6350
+ [{ _id: id }],
6351
+ "delete",
6352
+ { source: "incremental" }
6353
+ );
6113
6354
  return existing;
6114
6355
  }
6115
6356
  async hardDelete(collection, query) {
@@ -6121,7 +6362,9 @@ var _SyncedDb = class _SyncedDb {
6121
6362
  const items = await this.find(collection, query);
6122
6363
  if (items.length === 0) return 0;
6123
6364
  const existingItems = await Promise.all(
6124
- items.map((item) => this.dexieDb.getById(collection, item._id))
6365
+ items.map(
6366
+ (item) => this.dexieDb.getById(collection, item._id)
6367
+ )
6125
6368
  );
6126
6369
  const toDelete = [];
6127
6370
  for (let i = 0; i < items.length; i++) {
@@ -6136,24 +6379,38 @@ var _SyncedDb = class _SyncedDb {
6136
6379
  const queue = [...toDelete];
6137
6380
  const results = [];
6138
6381
  await Promise.all(
6139
- Array.from({ length: Math.min(maxConcurrency, queue.length) }, async () => {
6140
- while (queue.length > 0) {
6141
- const item = queue.pop();
6142
- if (!item) break;
6143
- try {
6144
- await this.connectionManager.withRestTimeout(
6145
- this.restInterface.call("hardDeleteOne", { collection, query: { _id: item.id } }),
6146
- "hardDelete"
6147
- );
6148
- await this.dexieDb.deleteOne(collection, item.id);
6149
- this.inMemManager.writeBatch(collection, [{ _id: item.id }], "delete", { source: "incremental" });
6150
- results.push(true);
6151
- } catch (err) {
6152
- networkError(`[SyncedDb] Failed to hard delete ${String(item.id)}:`, err);
6153
- results.push(false);
6382
+ Array.from(
6383
+ { length: Math.min(maxConcurrency, queue.length) },
6384
+ async () => {
6385
+ while (queue.length > 0) {
6386
+ const item = queue.pop();
6387
+ if (!item) break;
6388
+ try {
6389
+ await this.connectionManager.withRestTimeout(
6390
+ this.restInterface.call("hardDeleteOne", {
6391
+ collection,
6392
+ query: { _id: item.id }
6393
+ }),
6394
+ "hardDelete"
6395
+ );
6396
+ await this.dexieDb.deleteOne(collection, item.id);
6397
+ this.inMemManager.writeBatch(
6398
+ collection,
6399
+ [{ _id: item.id }],
6400
+ "delete",
6401
+ { source: "incremental" }
6402
+ );
6403
+ results.push(true);
6404
+ } catch (err) {
6405
+ networkError(
6406
+ `[SyncedDb] Failed to hard delete ${String(item.id)}:`,
6407
+ err
6408
+ );
6409
+ results.push(false);
6410
+ }
6154
6411
  }
6155
6412
  }
6156
- })
6413
+ )
6157
6414
  );
6158
6415
  return results.filter(Boolean).length;
6159
6416
  }
@@ -6205,11 +6462,17 @@ var _SyncedDb = class _SyncedDb {
6205
6462
  const now = /* @__PURE__ */ new Date();
6206
6463
  if (!this._lastFullSyncDate) {
6207
6464
  this._setLastInitialSync(now).catch((err) => {
6208
- console.error(`[SyncedDb] Failed to persist lastInitialSync: ${err}`, err);
6465
+ console.error(
6466
+ `[SyncedDb] Failed to persist lastInitialSync: ${err}`,
6467
+ err
6468
+ );
6209
6469
  });
6210
6470
  }
6211
6471
  this._setLastFullSync(now).catch((err) => {
6212
- console.error(`[SyncedDb] Failed to persist lastFullSync: ${err}`, err);
6472
+ console.error(
6473
+ `[SyncedDb] Failed to persist lastFullSync: ${err}`,
6474
+ err
6475
+ );
6213
6476
  });
6214
6477
  if (consumingPendingFullResync) this._pendingFullResync = false;
6215
6478
  }
@@ -6363,10 +6626,18 @@ var _SyncedDb = class _SyncedDb {
6363
6626
  for (const [name] of this.collections) {
6364
6627
  const metas2 = await this.dexieDb.getDirtyMeta(name);
6365
6628
  if (metas2.length === 0) continue;
6629
+ const ids2 = metas2.map((m) => m.id);
6630
+ const changesMap = await this.dexieDb.getDirtyChangesBatch(name, ids2);
6631
+ const items = metas2.map(
6632
+ (m) => {
6633
+ var _a;
6634
+ return (_a = changesMap.get(m.id)) != null ? _a : __spreadProps(__spreadValues({}, m), { changes: {} });
6635
+ }
6636
+ );
6366
6637
  this.safeCallback(this.onBeforeDirtyClearAll, {
6367
6638
  reason: calledFrom != null ? calledFrom : "manual",
6368
6639
  collection: name,
6369
- items: metas2,
6640
+ items,
6370
6641
  calledFrom,
6371
6642
  timestamp: /* @__PURE__ */ new Date()
6372
6643
  });
@@ -6429,10 +6700,19 @@ var _SyncedDb = class _SyncedDb {
6429
6700
  const metas = await this.dexieDb.getDirtyMeta(collectionName);
6430
6701
  const stuck = metas.filter((m) => m.stuckSince !== void 0);
6431
6702
  if (stuck.length === 0) continue;
6703
+ const stuckIds = stuck.map((m) => m.id);
6704
+ const changesMap = await this.dexieDb.getDirtyChangesBatch(
6705
+ collectionName,
6706
+ stuckIds
6707
+ );
6708
+ const content = stuck.map((m) => {
6709
+ const entry = changesMap.get(m.id);
6710
+ return entry != null ? entry : __spreadProps(__spreadValues({}, m), { changes: {} });
6711
+ });
6432
6712
  this.safeCallback(this.onBeforeDirtyClearAll, {
6433
6713
  reason: "discard-stuck",
6434
6714
  collection: collectionName,
6435
- items: stuck,
6715
+ items: content,
6436
6716
  calledFrom,
6437
6717
  timestamp: /* @__PURE__ */ new Date()
6438
6718
  });
@@ -6478,7 +6758,9 @@ var _SyncedDb = class _SyncedDb {
6478
6758
  }
6479
6759
  async dropDatabase(force = false) {
6480
6760
  if (!force && (this.connectionManager.isForcedOffline() || !this.connectionManager.isOnline())) {
6481
- throw new Error("Cannot drop database: database is offline. Use force=true to drop anyway.");
6761
+ throw new Error(
6762
+ "Cannot drop database: database is offline. Use force=true to drop anyway."
6763
+ );
6482
6764
  }
6483
6765
  await this.pendingChanges.flushAll();
6484
6766
  const collectionNames = Array.from(this.collections.keys());
@@ -6486,7 +6768,10 @@ var _SyncedDb = class _SyncedDb {
6486
6768
  for (const collectionName of collectionNames) {
6487
6769
  const dirtyItems = await this.dexieDb.getDirty(collectionName);
6488
6770
  if (dirtyItems.length > 0) {
6489
- dirtyCollections.push({ name: collectionName, count: dirtyItems.length });
6771
+ dirtyCollections.push({
6772
+ name: collectionName,
6773
+ count: dirtyItems.length
6774
+ });
6490
6775
  }
6491
6776
  }
6492
6777
  if (dirtyCollections.length > 0) {
@@ -6764,7 +7049,11 @@ var _SyncedDb = class _SyncedDb {
6764
7049
  );
6765
7050
  serverRounds = 1;
6766
7051
  for (const [specId, items] of Object.entries(results)) {
6767
- this._applyScopeExitChunkToPlan(plan, specId, items);
7052
+ this._applyScopeExitChunkToPlan(
7053
+ plan,
7054
+ specId,
7055
+ items
7056
+ );
6768
7057
  }
6769
7058
  } catch (err) {
6770
7059
  serverFailed = true;
@@ -7067,7 +7356,8 @@ var _SyncedDb = class _SyncedDb {
7067
7356
  const config = this.collections.get(collection);
7068
7357
  if (!config) return false;
7069
7358
  if (config.writeOnly) return false;
7070
- if (this.syncOnlyCollections && !this.syncOnlyCollections.has(collection)) return false;
7359
+ if (this.syncOnlyCollections && !this.syncOnlyCollections.has(collection))
7360
+ return false;
7071
7361
  return true;
7072
7362
  }
7073
7363
  /**
@@ -7142,7 +7432,11 @@ var _SyncedDb = class _SyncedDb {
7142
7432
  var _a;
7143
7433
  try {
7144
7434
  const count = await this._hydrateCollectionFromDexie(name);
7145
- this.preloadStatusMap.set(name, { state: "hydrated", itemCount: count, hydratedAt: /* @__PURE__ */ new Date() });
7435
+ this.preloadStatusMap.set(name, {
7436
+ state: "hydrated",
7437
+ itemCount: count,
7438
+ hydratedAt: /* @__PURE__ */ new Date()
7439
+ });
7146
7440
  this.emitPreloadStatusChange();
7147
7441
  return count;
7148
7442
  } catch (err) {
@@ -7169,7 +7463,10 @@ var _SyncedDb = class _SyncedDb {
7169
7463
  let pendingCount = 0;
7170
7464
  for (const name of this.collections.keys()) {
7171
7465
  if (!this.isSyncAllowed(name)) continue;
7172
- const rec = (_a = this.preloadStatusMap.get(name)) != null ? _a : { state: "pending", itemCount: 0 };
7466
+ const rec = (_a = this.preloadStatusMap.get(name)) != null ? _a : {
7467
+ state: "pending",
7468
+ itemCount: 0
7469
+ };
7173
7470
  const everDownloaded = !!((_b = this.syncMetaCache.get(name)) == null ? void 0 : _b.lastSyncTs);
7174
7471
  const ready = rec.state === "hydrated";
7175
7472
  if (rec.state === "failed") failedCount++;
@@ -7191,22 +7488,34 @@ var _SyncedDb = class _SyncedDb {
7191
7488
  else if (readyCount === expectedCount) aggregate = "full";
7192
7489
  else if (failedCount === expectedCount) aggregate = "failed";
7193
7490
  else aggregate = "partial";
7194
- return { aggregate, collections, expectedCount, readyCount, failedCount, pendingCount };
7491
+ return {
7492
+ aggregate,
7493
+ collections,
7494
+ expectedCount,
7495
+ readyCount,
7496
+ failedCount,
7497
+ pendingCount
7498
+ };
7195
7499
  }
7196
7500
  /** Emit onPreloadStatusChange with a fresh snapshot (skips computation when no listener). */
7197
7501
  emitPreloadStatusChange() {
7198
- if (this.onPreloadStatusChange) this.safeCallback(this.onPreloadStatusChange, this.getPreloadStatus());
7502
+ if (this.onPreloadStatusChange)
7503
+ this.safeCallback(this.onPreloadStatusChange, this.getPreloadStatus());
7199
7504
  }
7200
7505
  async _hydrateCollectionFromDexie(name) {
7201
7506
  const allItems = [];
7202
- await this.dexieDb.forEachBatch(name, 2e3, async (chunk) => {
7203
- for (let i = 0; i < chunk.length; i++) {
7204
- const item = chunk[i];
7205
- if (!item._deleted && !item._archived) {
7206
- allItems.push(item);
7507
+ await this.dexieDb.forEachBatch(
7508
+ name,
7509
+ 2e3,
7510
+ async (chunk) => {
7511
+ for (let i = 0; i < chunk.length; i++) {
7512
+ const item = chunk[i];
7513
+ if (!item._deleted && !item._archived) {
7514
+ allItems.push(item);
7515
+ }
7207
7516
  }
7208
7517
  }
7209
- });
7518
+ );
7210
7519
  const dirty = await this.dexieDb.getDirty(name);
7211
7520
  if (dirty.length > 0) {
7212
7521
  const itemById = /* @__PURE__ */ new Map();
@@ -7275,7 +7584,9 @@ var _SyncedDb = class _SyncedDb {
7275
7584
  }
7276
7585
  assertCollection(name) {
7277
7586
  if (!this.collections.has(name)) {
7278
- throw new Error(`SyncedDb: Collection "${(name == null ? void 0 : name.toString()) || "?"}" not configured`);
7587
+ throw new Error(
7588
+ `SyncedDb: Collection "${(name == null ? void 0 : name.toString()) || "?"}" not configured`
7589
+ );
7279
7590
  }
7280
7591
  }
7281
7592
  /**
@@ -7405,7 +7716,8 @@ var _SyncedDb = class _SyncedDb {
7405
7716
  if (_SyncedDb.isObjectIdLike(data)) return String(data);
7406
7717
  if (typeof data !== "object") return data;
7407
7718
  if (data instanceof Date) return data;
7408
- if (Array.isArray(data)) return data.map((v) => _SyncedDb.stringifyObjectIds(v));
7719
+ if (Array.isArray(data))
7720
+ return data.map((v) => _SyncedDb.stringifyObjectIds(v));
7409
7721
  const result = {};
7410
7722
  for (const key of Object.keys(data)) {
7411
7723
  result[key] = _SyncedDb.stringifyObjectIds(data[key]);
@@ -121,8 +121,8 @@ export interface BeforeDirtyClearAllInfo {
121
121
  reason: string;
122
122
  /** Collection whose dirty entries are about to be deleted. */
123
123
  collection: string;
124
- /** Meta of every dirty entry in this collection (no `changes` payload). */
125
- items: import("./I_DexieDb").DirtyMeta[];
124
+ /** Every dirty entry in this collection includes both metadata and the `changes` payload. */
125
+ items: import("./I_DexieDb").DirtyChange[];
126
126
  /** Optional caller tag passed through `clearDirty(undefined, undefined, calledFrom)`. */
127
127
  calledFrom?: string;
128
128
  /** Timestamp when the callback fires. */
@@ -648,7 +648,7 @@ export interface SyncedDbConfig {
648
648
  * `loaded`/`total` are scoped to the phase that emitted the event.
649
649
  */
650
650
  onSyncProgress?: (info: {
651
- phase: 'dexie' | 'server';
651
+ phase: "dexie" | "server";
652
652
  collection: string;
653
653
  loaded: number;
654
654
  total: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cry-synced-db-client",
3
- "version": "0.1.199",
3
+ "version": "0.1.201",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",