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 +44 -0
- package/dist/index.js +456 -144
- package/dist/src/types/I_SyncedDb.d.ts +3 -3
- package/package.json +1 -1
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, {
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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)
|
|
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", {
|
|
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", {
|
|
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(
|
|
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({
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
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(
|
|
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, [
|
|
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)
|
|
3734
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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", {
|
|
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
|
|
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(
|
|
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
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
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)
|
|
3990
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
4047
|
-
|
|
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", {
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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)
|
|
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(
|
|
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(
|
|
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), {
|
|
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(
|
|
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, {
|
|
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(
|
|
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, {
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
5828
|
+
const toInMem = serverItems.filter(
|
|
5829
|
+
(s) => !s._deleted && !s._archived
|
|
5830
|
+
);
|
|
5667
5831
|
if (toInMem.length > 0) {
|
|
5668
|
-
this.inMemManager.writeBatch(
|
|
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())
|
|
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, {
|
|
5713
|
-
|
|
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())
|
|
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(
|
|
5781
|
-
|
|
5782
|
-
|
|
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(
|
|
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, {
|
|
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(
|
|
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(
|
|
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", {
|
|
6055
|
+
this.inMemManager.writeBatch(collection, toSaveInMem, "upsert", {
|
|
6056
|
+
source: "incremental"
|
|
6057
|
+
});
|
|
5863
6058
|
}
|
|
5864
6059
|
if (dirtyServerItems.length > 0) {
|
|
5865
|
-
await this.syncEngine.processCollectionServerData(
|
|
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(
|
|
6092
|
+
await this.syncEngine.processCollectionServerData(
|
|
6093
|
+
collection,
|
|
6094
|
+
serverItems,
|
|
6095
|
+
{ source: "incremental" }
|
|
6096
|
+
);
|
|
5894
6097
|
}).catch((err) => {
|
|
5895
|
-
networkError(
|
|
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", {
|
|
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
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
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(
|
|
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", {
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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", {
|
|
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(
|
|
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(
|
|
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(
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
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(
|
|
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(
|
|
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
|
|
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:
|
|
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(
|
|
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({
|
|
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(
|
|
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))
|
|
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, {
|
|
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 : {
|
|
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 {
|
|
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)
|
|
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(
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
|
|
7206
|
-
|
|
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(
|
|
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))
|
|
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
|
-
/**
|
|
125
|
-
items: import("./I_DexieDb").
|
|
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:
|
|
651
|
+
phase: "dexie" | "server";
|
|
652
652
|
collection: string;
|
|
653
653
|
loaded: number;
|
|
654
654
|
total: number;
|