cry-synced-db-client 0.1.209 → 0.1.212

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
+ ## 0.1.211 (2026-06-25)
4
+
5
+ ### Added `streamActivityTimeoutMs` to SyncedDbConfig
6
+
7
+ `findNewerManyStream` has two internal timeouts: `connectTimeout` (configurable via
8
+ `defaultTimeoutMs`) and `activityTimeout` (was hardcoded to 30s). The activity
9
+ timeout fires between stream chunk reads — if Dexie writes + Vuex reactivity for
10
+ a 2000-item chunk exceed 30s, the stream is aborted.
11
+
12
+ New fields:
13
+ - `RestProxy.defaultActivityTimeoutMs` — default for all streams (falls back to 30s)
14
+ - `SyncedDbConfig.streamActivityTimeoutMs` — threaded through SyncedDb → SyncEngine
15
+ → RestProxy.findNewerManyStream(options.activityTimeoutMs)
16
+
3
17
  ## 0.1.209 (2026-06-25)
4
18
 
5
19
  ### Removed hardcoded `{ returnDeleted: true }` from sync specs
package/dist/index.js CHANGED
@@ -3332,7 +3332,8 @@ var _SyncEngine = class _SyncEngine {
3332
3332
  },
3333
3333
  onResponseChunkBytes: (bytes) => {
3334
3334
  responseBytes = (responseBytes != null ? responseBytes : 0) + bytes;
3335
- }
3335
+ },
3336
+ activityTimeoutMs: this.deps.streamActivityTimeoutMs
3336
3337
  }
3337
3338
  ),
3338
3339
  "findNewerManyStream"
@@ -5087,6 +5088,7 @@ var _SyncedDb = class _SyncedDb {
5087
5088
  },
5088
5089
  getInMemById: (collection, id) => this.inMemDb.getById(collection, id),
5089
5090
  withSyncTimeout: (promise, operation) => this.connectionManager.withSyncTimeout(promise, operation),
5091
+ streamActivityTimeoutMs: config.streamActivityTimeoutMs,
5090
5092
  onSyncFailed: (reason) => this.connectionManager.callOnSyncFailed(reason),
5091
5093
  flushAllPendingChanges: () => this.pendingChanges.flushAll(),
5092
5094
  cancelRestUploadTimer: () => this.pendingChanges.cancelRestUploadTimer(),
@@ -6462,30 +6464,12 @@ var _SyncedDb = class _SyncedDb {
6462
6464
  }
6463
6465
  this.syncing = true;
6464
6466
  this.crossTabSync.startServerSync();
6465
- let evictionPlan;
6466
- let evictionServerFailed = false;
6467
- if (await this._isAutoEvictionDue(calledFrom)) {
6468
- try {
6469
- evictionPlan = await this._collectScopeExitPlan("auto");
6470
- } catch (err) {
6471
- console.error(
6472
- "[SyncedDb] [evict] phase 1 failed (skipping bundled eviction):",
6473
- err
6474
- );
6475
- }
6476
- }
6477
- const evictionExtras = evictionPlan && evictionPlan.specs.length > 0 ? {
6478
- specs: evictionPlan.specs,
6479
- onChunk: (specId, items) => {
6480
- this._applyScopeExitChunkToPlan(evictionPlan, specId, items);
6481
- }
6482
- } : void 0;
6483
6467
  const consumingPendingFullResync = this._pendingFullResync;
6484
6468
  if (consumingPendingFullResync) {
6485
6469
  await this._resetSyncCursors();
6486
6470
  }
6487
6471
  try {
6488
- await this.syncEngine.sync(calledFrom, evictionExtras);
6472
+ await this.syncEngine.sync(calledFrom);
6489
6473
  if (!this.syncOnlyCollections) {
6490
6474
  const now = /* @__PURE__ */ new Date();
6491
6475
  if (!this._lastFullSyncDate) {
@@ -6505,24 +6489,11 @@ var _SyncedDb = class _SyncedDb {
6505
6489
  if (consumingPendingFullResync) this._pendingFullResync = false;
6506
6490
  }
6507
6491
  } catch (err) {
6508
- if (evictionExtras) evictionServerFailed = true;
6509
6492
  throw err;
6510
6493
  } finally {
6511
6494
  this.syncing = false;
6512
6495
  this.crossTabSync.endServerSync();
6513
6496
  await this.processQueuedWsUpdates();
6514
- if (evictionPlan) {
6515
- try {
6516
- await this._applyScopeExitPlan(
6517
- evictionPlan,
6518
- evictionServerFailed,
6519
- evictionExtras ? 1 : 0
6520
- );
6521
- await this._persistEvictionTimestamp();
6522
- } catch (err) {
6523
- console.error(`[SyncedDb] [evict] phase 3 failed: ${err}`, err);
6524
- }
6525
- }
6526
6497
  }
6527
6498
  } finally {
6528
6499
  this.syncLock = false;
@@ -10483,16 +10454,17 @@ var RestProxy = class {
10483
10454
  this._lastRequestMs = 0;
10484
10455
  this._totalRequestMs = 0;
10485
10456
  this._requestCount = 0;
10486
- var _a, _b, _c, _d, _e;
10457
+ var _a, _b, _c, _d, _e, _f;
10487
10458
  this.endpoint = config.endpoint;
10488
10459
  this.tenant = config.tenant;
10489
10460
  this.apiKey = config.apiKey;
10490
10461
  this.defaultTimeoutMs = (_a = config.defaultTimeoutMs) != null ? _a : DEFAULT_TIMEOUT;
10491
- this.audit = (_b = config.audit) != null ? _b : {};
10492
- this.timeRequestsPrint = (_c = config.timeRequestsPrint) != null ? _c : false;
10493
- this.timeRequests = (_d = config.timeRequests) != null ? _d : this.timeRequestsPrint;
10462
+ this.defaultActivityTimeoutMs = (_b = config.defaultActivityTimeoutMs) != null ? _b : 3e4;
10463
+ this.audit = (_c = config.audit) != null ? _c : {};
10464
+ this.timeRequestsPrint = (_d = config.timeRequestsPrint) != null ? _d : false;
10465
+ this.timeRequests = (_e = config.timeRequests) != null ? _e : this.timeRequestsPrint;
10494
10466
  this.onProgressCallback = config.onProgressCallback;
10495
- this.progressChunkSize = (_e = config.progressChunkSize) != null ? _e : DEFAULT_PROGRESS_CHUNK_SIZE;
10467
+ this.progressChunkSize = (_f = config.progressChunkSize) != null ? _f : DEFAULT_PROGRESS_CHUNK_SIZE;
10496
10468
  this.globalSignal = config.signal;
10497
10469
  }
10498
10470
  /** Set global abort signal */
@@ -10669,7 +10641,7 @@ var RestProxy = class {
10669
10641
  async findNewerManyStream(spec, onChunk, options) {
10670
10642
  var _a, _b, _c, _d, _e;
10671
10643
  const connectTimeout = (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : this.defaultTimeoutMs;
10672
- const activityTimeout = (_b = options == null ? void 0 : options.activityTimeoutMs) != null ? _b : 3e4;
10644
+ const activityTimeout = (_b = options == null ? void 0 : options.activityTimeoutMs) != null ? _b : this.defaultActivityTimeoutMs;
10673
10645
  const externalSignal = (_c = options == null ? void 0 : options.signal) != null ? _c : this.globalSignal;
10674
10646
  const startTime = this.timeRequests ? performance.now() : 0;
10675
10647
  const fetchStart = performance.now();
@@ -13,6 +13,17 @@ export interface RestProxyConfig {
13
13
  apiKey?: string;
14
14
  /** Default timeout in ms (default: 5000) */
15
15
  defaultTimeoutMs?: number;
16
+ /**
17
+ * Default activity timeout for streaming responses (default: 30000).
18
+ *
19
+ * Unlike `defaultTimeoutMs` which covers the initial fetch() connection,
20
+ * this timeout fires if the gap between individual chunk reads exceeds
21
+ * the limit. Streaming syncs with many large collections (e.g. initial
22
+ * sync on a new device with 60+ collections and 2000-item chunks) need
23
+ * a higher value because Dexie writes + Vuex reactivity between reads
24
+ * can delay the next read() past the default 30s.
25
+ */
26
+ defaultActivityTimeoutMs?: number;
16
27
  /** Audit info for requests */
17
28
  audit?: {
18
29
  user?: string;
@@ -64,6 +75,7 @@ export declare class RestProxy implements I_RestInterface {
64
75
  private tenant;
65
76
  private apiKey?;
66
77
  private defaultTimeoutMs;
78
+ private defaultActivityTimeoutMs;
67
79
  private audit;
68
80
  private timeRequests;
69
81
  private timeRequestsPrint;
@@ -282,6 +282,8 @@ export interface SyncEngineDeps {
282
282
  }) => void;
283
283
  getInMemById: <T extends DbEntity>(collection: string, id: Id) => T | undefined;
284
284
  withSyncTimeout: <T>(promise: Promise<T>, operation: string) => Promise<T>;
285
+ /** Activity timeout for streaming `findNewerManyStream` (ms). Default 30000. */
286
+ streamActivityTimeoutMs?: number;
285
287
  /** Notify consumers that a sync cycle failed. Does not mutate online state. */
286
288
  onSyncFailed: (reason: string) => void;
287
289
  flushAllPendingChanges: () => Promise<void>;
@@ -133,6 +133,7 @@ export interface I_RestInterface {
133
133
  findNewerManyStream<T>(spec: GetNewerSpec<T>[], onChunk: (collection: string, items: T[], specId?: string) => Promise<void>, options?: {
134
134
  timeoutMs?: number;
135
135
  signal?: AbortSignal;
136
+ activityTimeoutMs?: number;
136
137
  onRequestBytes?: (bytes: number) => void;
137
138
  onTtfbMs?: (ms: number) => void;
138
139
  onResponseChunkBytes?: (bytes: number) => void;
@@ -592,6 +592,16 @@ export interface SyncedDbConfig {
592
592
  restTimeoutMs?: number;
593
593
  /** Timeout za sync REST klice v ms (default: 120000) - daljši ker sync prenaša več podatkov */
594
594
  syncTimeoutMs?: number;
595
+ /**
596
+ * Activity timeout za streaming odgovore (default: 30000).
597
+ *
598
+ * Za razliko od `restTimeoutMs` (ki pokriva začetno fetch() povezavo),
599
+ * ta timeout sproži če je premor med posameznimi chunk read()-i daljši
600
+ * od meje. Initial sync na novi napravi (60+ kolekcij, 2000-item chunk-i)
601
+ * potrebuje višjo vrednost, ker Dexie writes + Vuex reactivity med read()-i
602
+ * lahko podaljšajo naslednji read() čez privzetih 30s.
603
+ */
604
+ streamActivityTimeoutMs?: number;
595
605
  /** Debounce čas za zapis v Dexie v ms (default: 200) */
596
606
  debounceDexieWritesMs?: number;
597
607
  /** Debounce čas za pošiljanje na REST v ms (default: 1000) - po uspešnem zapisu v Dexie */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cry-synced-db-client",
3
- "version": "0.1.209",
3
+ "version": "0.1.212",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",