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 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) return 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
- if ((opts == null ? void 0 : opts.referToServer) !== false && this.isOnline()) {
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
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cry-synced-db-client",
3
- "version": "0.1.138",
3
+ "version": "0.1.139",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",