cry-synced-db-client 0.1.138 → 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 +46 -2
- 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
|
@@ -3931,7 +3931,12 @@ var _SyncedDb = class _SyncedDb {
|
|
|
3931
3931
|
}
|
|
3932
3932
|
if (!(opts == null ? void 0 : opts.returnDeleted) && !(opts == null ? void 0 : opts.returnArchived)) {
|
|
3933
3933
|
const memItem = this.inMemDb.getById(collection, id);
|
|
3934
|
-
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
|
+
}
|
|
3935
3940
|
}
|
|
3936
3941
|
if ((opts == null ? void 0 : opts.referToServer) !== false && this.isOnline()) {
|
|
3937
3942
|
await this.ensureItemsAreLoaded(
|
|
@@ -3939,6 +3944,8 @@ var _SyncedDb = class _SyncedDb {
|
|
|
3939
3944
|
[id],
|
|
3940
3945
|
opts == null ? void 0 : opts.returnDeleted
|
|
3941
3946
|
);
|
|
3947
|
+
} else if ((opts == null ? void 0 : opts.refreshInBackground) && this.isOnline()) {
|
|
3948
|
+
this.refreshByIdsInBackground(collection, [id]);
|
|
3942
3949
|
}
|
|
3943
3950
|
if (((opts == null ? void 0 : opts.returnDeleted) || (opts == null ? void 0 : opts.returnArchived)) && this.isOnline()) {
|
|
3944
3951
|
try {
|
|
@@ -3975,12 +3982,28 @@ var _SyncedDb = class _SyncedDb {
|
|
|
3975
3982
|
return this.writeOnlyFindByIds(collection, ids);
|
|
3976
3983
|
}
|
|
3977
3984
|
if (ids.length === 0) return [];
|
|
3978
|
-
|
|
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) {
|
|
3979
3997
|
await this.ensureItemsAreLoaded(
|
|
3980
3998
|
collection,
|
|
3981
3999
|
ids,
|
|
3982
4000
|
opts == null ? void 0 : opts.returnDeleted
|
|
3983
4001
|
);
|
|
4002
|
+
if (wantsBgRefresh && hitIds && hitIds.length > 0) {
|
|
4003
|
+
this.refreshByIdsInBackground(collection, hitIds);
|
|
4004
|
+
}
|
|
4005
|
+
} else if (wantsBgRefresh) {
|
|
4006
|
+
this.refreshByIdsInBackground(collection, ids);
|
|
3984
4007
|
}
|
|
3985
4008
|
if (((opts == null ? void 0 : opts.returnDeleted) || (opts == null ? void 0 : opts.returnArchived)) && this.isOnline()) {
|
|
3986
4009
|
try {
|
|
@@ -4135,6 +4158,27 @@ var _SyncedDb = class _SyncedDb {
|
|
|
4135
4158
|
console.error(`referToServer failed for ${collection}:`, err);
|
|
4136
4159
|
});
|
|
4137
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
|
+
}
|
|
4138
4182
|
async ensureItemsAreLoaded(collection, ids, withDeleted) {
|
|
4139
4183
|
var _a;
|
|
4140
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
|
/**
|