cry-synced-db-client 0.1.137 → 0.1.139
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 +14 -0
- package/dist/index.js +59 -10
- package/dist/src/db/SyncedDb.d.ts +8 -0
- package/dist/src/types/I_RestInterface.d.ts +15 -0
- package/dist/src/types/I_SyncedDb.d.ts +8 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- Add `refreshInBackground` `QueryOpts` option for `findById` / `findByIds`
|
|
6
|
+
- Stale-while-revalidate: cache-hit returns local result immediately and
|
|
7
|
+
triggers a background fetch that updates Dexie + in-mem through conflict
|
|
8
|
+
resolution (`processCollectionServerData`).
|
|
9
|
+
- Orthogonal to `referToServer` — does not change miss behaviour. With
|
|
10
|
+
defaults (`referToServer: true`) misses are still awaited; with
|
|
11
|
+
`referToServer: false` misses return `null` and bg fetch loads them async.
|
|
12
|
+
- Dedupes against `referToServer`: IDs fetched blockingly are NOT re-fetched
|
|
13
|
+
in the background (no double-round-trip).
|
|
14
|
+
- Noop when offline or on writeOnly collections.
|
|
15
|
+
- Ignored on `find` / `findOne` (use `referToServer` there).
|
|
16
|
+
|
|
3
17
|
## 0.1.136 (2026-04-20)
|
|
4
18
|
|
|
5
19
|
- `DexieDb.saveMany` is now fail-safe:
|
package/dist/index.js
CHANGED
|
@@ -3110,6 +3110,7 @@ var ServerUpdateHandler = class {
|
|
|
3110
3110
|
if (updates.length > 0) {
|
|
3111
3111
|
const updateIds = updates.map((u) => u._id);
|
|
3112
3112
|
const localItems = await this.dexieDb.getByIds(collectionName, updateIds);
|
|
3113
|
+
const missingIds = [];
|
|
3113
3114
|
for (let i = 0; i < updates.length; i++) {
|
|
3114
3115
|
const deltaData = updates[i];
|
|
3115
3116
|
const localItem = localItems[i];
|
|
@@ -3117,14 +3118,18 @@ var ServerUpdateHandler = class {
|
|
|
3117
3118
|
await this.handleServerItemUpdate(collectionName, localItem, deltaData);
|
|
3118
3119
|
updatedIds.push(String(deltaData._id));
|
|
3119
3120
|
} else {
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3121
|
+
missingIds.push(deltaData._id);
|
|
3122
|
+
}
|
|
3123
|
+
}
|
|
3124
|
+
if (missingIds.length > 0) {
|
|
3125
|
+
const fullItems = await this.restInterface.findByIds(
|
|
3126
|
+
collectionName,
|
|
3127
|
+
missingIds
|
|
3128
|
+
);
|
|
3129
|
+
for (const fullItem of fullItems) {
|
|
3130
|
+
if (!fullItem) continue;
|
|
3131
|
+
await this.handleServerItemInsert(collectionName, fullItem);
|
|
3132
|
+
updatedIds.push(String(fullItem._id));
|
|
3128
3133
|
}
|
|
3129
3134
|
}
|
|
3130
3135
|
}
|
|
@@ -3926,7 +3931,12 @@ var _SyncedDb = class _SyncedDb {
|
|
|
3926
3931
|
}
|
|
3927
3932
|
if (!(opts == null ? void 0 : opts.returnDeleted) && !(opts == null ? void 0 : opts.returnArchived)) {
|
|
3928
3933
|
const memItem = this.inMemDb.getById(collection, id);
|
|
3929
|
-
if (memItem)
|
|
3934
|
+
if (memItem) {
|
|
3935
|
+
if ((opts == null ? void 0 : opts.refreshInBackground) && this.isOnline()) {
|
|
3936
|
+
this.refreshByIdsInBackground(collection, [id]);
|
|
3937
|
+
}
|
|
3938
|
+
return memItem;
|
|
3939
|
+
}
|
|
3930
3940
|
}
|
|
3931
3941
|
if ((opts == null ? void 0 : opts.referToServer) !== false && this.isOnline()) {
|
|
3932
3942
|
await this.ensureItemsAreLoaded(
|
|
@@ -3934,6 +3944,8 @@ var _SyncedDb = class _SyncedDb {
|
|
|
3934
3944
|
[id],
|
|
3935
3945
|
opts == null ? void 0 : opts.returnDeleted
|
|
3936
3946
|
);
|
|
3947
|
+
} else if ((opts == null ? void 0 : opts.refreshInBackground) && this.isOnline()) {
|
|
3948
|
+
this.refreshByIdsInBackground(collection, [id]);
|
|
3937
3949
|
}
|
|
3938
3950
|
if (((opts == null ? void 0 : opts.returnDeleted) || (opts == null ? void 0 : opts.returnArchived)) && this.isOnline()) {
|
|
3939
3951
|
try {
|
|
@@ -3970,12 +3982,28 @@ var _SyncedDb = class _SyncedDb {
|
|
|
3970
3982
|
return this.writeOnlyFindByIds(collection, ids);
|
|
3971
3983
|
}
|
|
3972
3984
|
if (ids.length === 0) return [];
|
|
3973
|
-
|
|
3985
|
+
const wantsBgRefresh = (opts == null ? void 0 : opts.refreshInBackground) === true && this.isOnline();
|
|
3986
|
+
const referToServerEnabled = (opts == null ? void 0 : opts.referToServer) !== false && this.isOnline();
|
|
3987
|
+
let hitIds = null;
|
|
3988
|
+
if (wantsBgRefresh && referToServerEnabled && !(opts == null ? void 0 : opts.returnDeleted) && !(opts == null ? void 0 : opts.returnArchived)) {
|
|
3989
|
+
hitIds = [];
|
|
3990
|
+
for (const id of ids) {
|
|
3991
|
+
if (this.inMemDb.getById(collection, id)) {
|
|
3992
|
+
hitIds.push(id);
|
|
3993
|
+
}
|
|
3994
|
+
}
|
|
3995
|
+
}
|
|
3996
|
+
if (referToServerEnabled) {
|
|
3974
3997
|
await this.ensureItemsAreLoaded(
|
|
3975
3998
|
collection,
|
|
3976
3999
|
ids,
|
|
3977
4000
|
opts == null ? void 0 : opts.returnDeleted
|
|
3978
4001
|
);
|
|
4002
|
+
if (wantsBgRefresh && hitIds && hitIds.length > 0) {
|
|
4003
|
+
this.refreshByIdsInBackground(collection, hitIds);
|
|
4004
|
+
}
|
|
4005
|
+
} else if (wantsBgRefresh) {
|
|
4006
|
+
this.refreshByIdsInBackground(collection, ids);
|
|
3979
4007
|
}
|
|
3980
4008
|
if (((opts == null ? void 0 : opts.returnDeleted) || (opts == null ? void 0 : opts.returnArchived)) && this.isOnline()) {
|
|
3981
4009
|
try {
|
|
@@ -4130,6 +4158,27 @@ var _SyncedDb = class _SyncedDb {
|
|
|
4130
4158
|
console.error(`referToServer failed for ${collection}:`, err);
|
|
4131
4159
|
});
|
|
4132
4160
|
}
|
|
4161
|
+
/**
|
|
4162
|
+
* Fire-and-forget background fetch of specific IDs from the server.
|
|
4163
|
+
* Used by findById/findByIds when `refreshInBackground: true`.
|
|
4164
|
+
* Always fetches from server (does not skip when items exist locally),
|
|
4165
|
+
* and routes results through conflict resolution so local dirty changes
|
|
4166
|
+
* are preserved.
|
|
4167
|
+
*/
|
|
4168
|
+
refreshByIdsInBackground(collection, ids) {
|
|
4169
|
+
var _a;
|
|
4170
|
+
if (ids.length === 0) return;
|
|
4171
|
+
if ((_a = this.collections.get(collection)) == null ? void 0 : _a.writeOnly) return;
|
|
4172
|
+
this.connectionManager.withRestTimeout(
|
|
4173
|
+
this.restInterface.findByIds(collection, ids),
|
|
4174
|
+
"refreshInBackground"
|
|
4175
|
+
).then(async (serverItems) => {
|
|
4176
|
+
if (!serverItems || serverItems.length === 0) return;
|
|
4177
|
+
await this.syncEngine.processCollectionServerData(collection, serverItems);
|
|
4178
|
+
}).catch((err) => {
|
|
4179
|
+
console.error(`refreshInBackground failed for ${collection}:`, err);
|
|
4180
|
+
});
|
|
4181
|
+
}
|
|
4133
4182
|
async ensureItemsAreLoaded(collection, ids, withDeleted) {
|
|
4134
4183
|
var _a;
|
|
4135
4184
|
this.assertCollection(collection);
|
|
@@ -131,6 +131,14 @@ export declare class SyncedDb implements I_SyncedDb {
|
|
|
131
131
|
* Dexie + in-mem.
|
|
132
132
|
*/
|
|
133
133
|
private referToServerSync;
|
|
134
|
+
/**
|
|
135
|
+
* Fire-and-forget background fetch of specific IDs from the server.
|
|
136
|
+
* Used by findById/findByIds when `refreshInBackground: true`.
|
|
137
|
+
* Always fetches from server (does not skip when items exist locally),
|
|
138
|
+
* and routes results through conflict resolution so local dirty changes
|
|
139
|
+
* are preserved.
|
|
140
|
+
*/
|
|
141
|
+
private refreshByIdsInBackground;
|
|
134
142
|
ensureItemsAreLoaded(collection: string, ids: string[], withDeleted?: boolean): Promise<void>;
|
|
135
143
|
save<T extends DbEntity>(collection: string, id: Id, update: Partial<T>): Promise<T>;
|
|
136
144
|
upsert<T extends DbEntity>(collection: string, query: QuerySpec<T>, update: UpdateSpec<T>): Promise<T>;
|
|
@@ -26,6 +26,21 @@ export type QueryOpts = Partial<{
|
|
|
26
26
|
* pošlje query na server in posodobi in-mem z rezultati.
|
|
27
27
|
*/
|
|
28
28
|
referToServer: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* findById/findByIds (privzeto false): če je zapis lokalno prisoten,
|
|
31
|
+
* ga vrne takoj, nato pa v ozadju ponovno pridobi iste ID-je s serverja
|
|
32
|
+
* in jih posodobi v Dexie + in-mem (skozi konflikt resolucijo).
|
|
33
|
+
*
|
|
34
|
+
* Ortogonalno do `referToServer`:
|
|
35
|
+
* - hit + refreshInBackground: vrne lokalno + bg revalidacija
|
|
36
|
+
* - miss + referToServer:true: await fetch (privzeto); bg refresh NE sprozi
|
|
37
|
+
* (misses so ravno bili pobrani — izognemo se duplikatu)
|
|
38
|
+
* - miss + referToServer:false + refreshInBackground:true: vrne null,
|
|
39
|
+
* bg fetch prinese zapis asinhrono
|
|
40
|
+
*
|
|
41
|
+
* Ignorirano na find/findOne (tam uporabi `referToServer`).
|
|
42
|
+
*/
|
|
43
|
+
refreshInBackground: boolean;
|
|
29
44
|
}>;
|
|
30
45
|
export type KeyOf<T> = keyof T | "$bit" | "$set" | "$inc" | "$currentDate" | "$min" | "$max" | "$mul" | "$rename" | "$setOnInsert" | "$unset" | "$pull" | "$push" | "$pop" | "$addToSet" | "$pushAll" | "_rev" | "_ts" | "_csq" | "_deleted";
|
|
31
46
|
export type InsertKeyOf<T> = keyof T | "_rev" | "_ts" | "_csq" | "_deleted";
|
|
@@ -556,11 +556,19 @@ export interface I_SyncedDb {
|
|
|
556
556
|
/**
|
|
557
557
|
* Poišče objekt po ID-ju.
|
|
558
558
|
* referToServer (privzeto true): če ne obstaja lokalno, prebere s serverja.
|
|
559
|
+
* refreshInBackground (privzeto false): lokalne zadetke vrne takoj, nato
|
|
560
|
+
* jih v ozadju revalidira s serverja (Dexie + in-mem skozi konflikt
|
|
561
|
+
* resolucijo). Ortogonalno do referToServer; ne povzroči duplikata
|
|
562
|
+
* server klicev za missing ID-je.
|
|
559
563
|
*/
|
|
560
564
|
findById<T extends DbEntity>(collection: string, id: Id, opts?: QueryOpts): Promise<T | null>;
|
|
561
565
|
/**
|
|
562
566
|
* Poišče objekte po ID-jih.
|
|
563
567
|
* referToServer (privzeto true): manjkajoče prebere s serverja.
|
|
568
|
+
* refreshInBackground (privzeto false): lokalne zadetke vrne takoj, nato
|
|
569
|
+
* jih v ozadju revalidira s serverja (Dexie + in-mem skozi konflikt
|
|
570
|
+
* resolucijo). Ortogonalno do referToServer; ne povzroči duplikata
|
|
571
|
+
* server klicev za missing ID-je.
|
|
564
572
|
*/
|
|
565
573
|
findByIds<T extends DbEntity>(collection: string, ids: Id[], opts?: QueryOpts): Promise<T[]>;
|
|
566
574
|
/**
|