cry-synced-db-client 0.1.195 → 0.1.197

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,28 @@
1
1
  # Versions
2
2
 
3
+ ## 0.1.196 (2026-06-10)
4
+
5
+ ### `refreshImmediately` — blokirni server-fetch z verzijsko primerjavo
6
+
7
+ Nova opcija `refreshImmediately` na `QueryOpts` za `findById` in `findByIds`.
8
+ Ko je `true` in smo online, vedno najprej blokirno pridobi podatke s serverja.
9
+ Če je `_rev` na serverju višji od lokalnega v Dexie, posodobi Dexie + in-mem.
10
+ Vrne novejši podatek (server če je bil novejši, sicer lokalni). Ob napaki
11
+ serverja pade nazaj na lokalne podatke.
12
+
13
+ Razlika od `referToServer`: `refreshImmediately` vedno kliče server (tudi če
14
+ zapis obstaja lokalno), ne samo ob cache miss-u.
15
+ Razlika od `refreshInBackground`: `refreshImmediately` je blokiren — počaka
16
+ na odgovor serverja in vrne ažuriran podatek.
17
+
18
+ Internal:
19
+ - `_refreshImmediately()` — nova zasebna metoda: fetča s serverja, primerja
20
+ `_rev`, posodobi Dexie samo če server novejši; za iteme z dirty spremembami
21
+ delegira `processCollectionServerData`
22
+ - `_isServerNewer()` — primerjava `_rev` vrednosti
23
+ - `findById` / `findByIds` — zgodnja `refreshImmediately` pot pred in-mem
24
+ hitre poti
25
+
3
26
  ## 0.1.195 (2026-06-09)
4
27
 
5
28
  ### `ensureItemsAreLoaded` always fetches all IDs from server
package/dist/index.js CHANGED
@@ -5488,6 +5488,22 @@ var _SyncedDb = class _SyncedDb {
5488
5488
  if ((_a = this.collections.get(collection)) == null ? void 0 : _a.writeOnly) {
5489
5489
  return this.writeOnlyFindById(collection, id);
5490
5490
  }
5491
+ if ((opts == null ? void 0 : opts.refreshImmediately) && this.isOnline()) {
5492
+ try {
5493
+ await this._refreshImmediately(collection, [id]);
5494
+ } catch (e) {
5495
+ }
5496
+ const item2 = await this.dexieDb.getById(collection, id);
5497
+ if (!item2) return null;
5498
+ if (!(opts == null ? void 0 : opts.returnDeleted) && item2._deleted) return null;
5499
+ if (!(opts == null ? void 0 : opts.returnArchived) && item2._archived) return null;
5500
+ let result2 = item2;
5501
+ if (opts == null ? void 0 : opts.project) {
5502
+ const [projected] = applyQueryOpts([result2], { project: opts.project });
5503
+ result2 = projected;
5504
+ }
5505
+ return result2;
5506
+ }
5491
5507
  if (!(opts == null ? void 0 : opts.returnDeleted) && !(opts == null ? void 0 : opts.returnArchived)) {
5492
5508
  const memItem = this.inMemDb.getById(collection, id);
5493
5509
  if (memItem) {
@@ -5542,6 +5558,21 @@ var _SyncedDb = class _SyncedDb {
5542
5558
  return this.writeOnlyFindByIds(collection, ids);
5543
5559
  }
5544
5560
  if (ids.length === 0) return [];
5561
+ if ((opts == null ? void 0 : opts.refreshImmediately) && this.isOnline()) {
5562
+ try {
5563
+ await this._refreshImmediately(collection, ids);
5564
+ } catch (e) {
5565
+ }
5566
+ const items2 = await this.dexieDb.getByIds(collection, ids);
5567
+ const results2 = [];
5568
+ for (const item of items2) {
5569
+ if (!item) continue;
5570
+ if (!(opts == null ? void 0 : opts.returnDeleted) && item._deleted) continue;
5571
+ if (!(opts == null ? void 0 : opts.returnArchived) && item._archived) continue;
5572
+ results2.push(item);
5573
+ }
5574
+ return applyQueryOpts(results2, opts);
5575
+ }
5545
5576
  const wantsBgRefresh = (opts == null ? void 0 : opts.refreshInBackground) === true && this.isOnline();
5546
5577
  const referToServerEnabled = (opts == null ? void 0 : opts.referToServer) !== false && this.isOnline();
5547
5578
  let hitIds = null;
@@ -5719,6 +5750,71 @@ var _SyncedDb = class _SyncedDb {
5719
5750
  networkError(`[SyncedDb] referToServer failed for ${collection}:`, err);
5720
5751
  });
5721
5752
  }
5753
+ /**
5754
+ * Blocking fetch of specific IDs from the server with version comparison.
5755
+ * Used by findById/findByIds when `refreshImmediately: true`.
5756
+ *
5757
+ * Always fetches from server (never skips). For items WITHOUT pending
5758
+ * dirty changes: compares `_rev` — only updates Dexie + inMem when the
5759
+ * server `_rev` is strictly higher than the local `_rev`. For items WITH
5760
+ * pending dirty changes: delegates to `processCollectionServerData` which
5761
+ * runs full conflict resolution (server-wins on higher `_rev`, local fields
5762
+ * not present on server are preserved).
5763
+ */
5764
+ async _refreshImmediately(collection, ids) {
5765
+ if (ids.length === 0) return;
5766
+ const serverItems = await this.connectionManager.withRestTimeout(
5767
+ this.restInterface.findByIds(collection, ids),
5768
+ "refreshImmediately"
5769
+ );
5770
+ if (!serverItems || serverItems.length === 0) return;
5771
+ const serverById = /* @__PURE__ */ new Map();
5772
+ for (const item of serverItems) {
5773
+ serverById.set(String(item._id), item);
5774
+ }
5775
+ const localItems = await this.dexieDb.getByIds(collection, ids);
5776
+ const dirtyMap = await this.dexieDb.getDirtyChangesBatch(collection, ids);
5777
+ const toSaveDexie = [];
5778
+ const toSaveInMem = [];
5779
+ const dirtyServerItems = [];
5780
+ for (let i = 0; i < ids.length; i++) {
5781
+ const id = ids[i];
5782
+ const serverItem = serverById.get(id);
5783
+ if (!serverItem) continue;
5784
+ const localItem = localItems[i];
5785
+ if (dirtyMap.has(id)) {
5786
+ dirtyServerItems.push(serverItem);
5787
+ } else if (!localItem) {
5788
+ toSaveDexie.push(serverItem);
5789
+ if (!serverItem._deleted && !serverItem._archived) {
5790
+ toSaveInMem.push(serverItem);
5791
+ }
5792
+ } else if (this._isServerNewer(serverItem, localItem)) {
5793
+ toSaveDexie.push(serverItem);
5794
+ if (!serverItem._deleted && !serverItem._archived) {
5795
+ toSaveInMem.push(serverItem);
5796
+ }
5797
+ }
5798
+ }
5799
+ if (toSaveDexie.length > 0) {
5800
+ await this.dexieDb.saveMany(collection, toSaveDexie);
5801
+ }
5802
+ if (toSaveInMem.length > 0) {
5803
+ this.inMemManager.writeBatch(collection, toSaveInMem, "upsert", { source: "incremental" });
5804
+ }
5805
+ if (dirtyServerItems.length > 0) {
5806
+ await this.syncEngine.processCollectionServerData(collection, dirtyServerItems, { source: "incremental" });
5807
+ }
5808
+ }
5809
+ /**
5810
+ * Compare two items by `_rev` — returns true if `serverItem` has a
5811
+ * strictly higher revision than `localItem`.
5812
+ */
5813
+ _isServerNewer(serverItem, localItem) {
5814
+ const serverRev = typeof serverItem._rev === "number" ? serverItem._rev : 0;
5815
+ const localRev = typeof localItem._rev === "number" ? localItem._rev : 0;
5816
+ return serverRev > localRev;
5817
+ }
5722
5818
  /**
5723
5819
  * Fire-and-forget background fetch of specific IDs from the server.
5724
5820
  * Used by findById/findByIds when `refreshInBackground: true`.
@@ -9980,7 +10076,7 @@ var RestProxy = class {
9980
10076
  this._requestCount++;
9981
10077
  if (this.timeRequestsPrint) {
9982
10078
  console.log(
9983
- `[RestProxy] ${operation}:`,
10079
+ `[RestProxy] ${operation} ${(payload == null ? void 0 : payload.collection) || ""}:`,
9984
10080
  elapsed.toFixed(2),
9985
10081
  "ms (total:",
9986
10082
  this._totalRequestMs.toFixed(2),
@@ -242,6 +242,23 @@ export declare class SyncedDb implements I_SyncedDb {
242
242
  * Dexie + in-mem.
243
243
  */
244
244
  private referToServerSync;
245
+ /**
246
+ * Blocking fetch of specific IDs from the server with version comparison.
247
+ * Used by findById/findByIds when `refreshImmediately: true`.
248
+ *
249
+ * Always fetches from server (never skips). For items WITHOUT pending
250
+ * dirty changes: compares `_rev` — only updates Dexie + inMem when the
251
+ * server `_rev` is strictly higher than the local `_rev`. For items WITH
252
+ * pending dirty changes: delegates to `processCollectionServerData` which
253
+ * runs full conflict resolution (server-wins on higher `_rev`, local fields
254
+ * not present on server are preserved).
255
+ */
256
+ private _refreshImmediately;
257
+ /**
258
+ * Compare two items by `_rev` — returns true if `serverItem` has a
259
+ * strictly higher revision than `localItem`.
260
+ */
261
+ private _isServerNewer;
245
262
  /**
246
263
  * Fire-and-forget background fetch of specific IDs from the server.
247
264
  * Used by findById/findByIds when `refreshInBackground: true`.
@@ -41,6 +41,22 @@ export type QueryOpts = Partial<{
41
41
  * Ignorirano na find/findOne (tam uporabi `referToServer`).
42
42
  */
43
43
  refreshInBackground: boolean;
44
+ /**
45
+ * findById/findByIds (privzeto false): če je true in smo online, vedno
46
+ * najprej blokirno pridobi podatek s serverja. Če je verzija na serverju
47
+ * novejša od verzije v Dexie (višji `_ts`), posodobi Dexie + in-mem
48
+ * skozi konflikt resolucijo. Vrne novejši podatek (server če je bil
49
+ * novejši, sicer lokalni). Ob napaki pri klicu na server pade nazaj
50
+ * na lokalne podatke.
51
+ *
52
+ * Razlika od `referToServer`: ta vedno pokliče server (tudi če zapis
53
+ * obstaja lokalno), ne samo ob cache miss-u.
54
+ * Razlika od `refreshInBackground`: ta je blokiren — počaka na odgovor
55
+ * serverja in vrne ažuriran podatek.
56
+ *
57
+ * Ignorirano na find/findOne.
58
+ */
59
+ refreshImmediately: boolean;
44
60
  }>;
45
61
  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";
46
62
  export type InsertKeyOf<T> = keyof T | "_rev" | "_ts" | "_csq" | "_deleted";
@@ -1091,6 +1091,10 @@ export interface I_SyncedDb {
1091
1091
  * jih v ozadju revalidira s serverja (Dexie + in-mem skozi konflikt
1092
1092
  * resolucijo). Ortogonalno do referToServer; ne povzroči duplikata
1093
1093
  * server klicev za missing ID-je.
1094
+ * refreshImmediately (privzeto false): če je true in smo online, vedno
1095
+ * najprej blokirno pridobi podatek s serverja. Če je server verzija
1096
+ * novejša (višji `_ts`), posodobi Dexie + in-mem. Vrne novejši podatek.
1097
+ * Ob napaki serverja pade nazaj na lokalne podatke.
1094
1098
  *
1095
1099
  * Auto-registracija: če `collection` ni registrirana v runtime sync
1096
1100
  * configu, se avtomatsko doda kot **temporary** s queryjem
@@ -1107,6 +1111,10 @@ export interface I_SyncedDb {
1107
1111
  * jih v ozadju revalidira s serverja (Dexie + in-mem skozi konflikt
1108
1112
  * resolucijo). Ortogonalno do referToServer; ne povzroči duplikata
1109
1113
  * server klicev za missing ID-je.
1114
+ * refreshImmediately (privzeto false): če je true in smo online, vedno
1115
+ * najprej blokirno pridobi podatke s serverja. Če je server verzija
1116
+ * novejša (višji `_ts`), posodobi Dexie + in-mem. Vrne novejše podatke.
1117
+ * Ob napaki serverja pade nazaj na lokalne podatke.
1110
1118
  *
1111
1119
  * Auto-registracija: enako kot `findById` — če `collection` ni v
1112
1120
  * runtime sync configu, se doda kot temporary s queryjem
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cry-synced-db-client",
3
- "version": "0.1.195",
3
+ "version": "0.1.197",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",