cry-synced-db-client 0.1.207 → 0.1.209
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,23 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
+
## 0.1.209 (2026-06-25)
|
|
4
|
+
|
|
5
|
+
### Removed hardcoded `{ returnDeleted: true }` from sync specs
|
|
6
|
+
|
|
7
|
+
`CollectionSyncConfig.opts` now carries `returnDeleted`, `returnArchived`, and
|
|
8
|
+
`project` per-collection instead of being hardcoded in `SyncEngine`. Each
|
|
9
|
+
sync spec passes its own opts directly to `findNewer`.
|
|
10
|
+
|
|
11
|
+
### Added `onEviction` callback
|
|
12
|
+
|
|
13
|
+
New optional `onEviction` callback on `SyncEngineCallbacks` — fires with
|
|
14
|
+
`{ collection, totalEvicted, totalServerEvicted }` after each eviction pass.
|
|
15
|
+
|
|
16
|
+
### Test script fixes
|
|
17
|
+
|
|
18
|
+
- Added `test/preload-bun.cjs` — polyfill for Bun's missing `process.getBuiltinModule('v8')`
|
|
19
|
+
- Fixed `test:real-mongo` script to use `npx vitest run` (not `bun test`)
|
|
20
|
+
|
|
3
21
|
## 0.1.204 (2026-06-17)
|
|
4
22
|
|
|
5
23
|
### Per-collection error isolation in `uploadDirtyItems`
|
package/dist/index.js
CHANGED
|
@@ -3212,7 +3212,7 @@ var _SyncEngine = class _SyncEngine {
|
|
|
3212
3212
|
* never enter the positive-sync processing path.
|
|
3213
3213
|
*/
|
|
3214
3214
|
async sync(calledFrom, extras) {
|
|
3215
|
-
var _a, _b;
|
|
3215
|
+
var _a, _b, _c;
|
|
3216
3216
|
const startTime = Date.now();
|
|
3217
3217
|
let receivedCount = 0;
|
|
3218
3218
|
let sentCount = 0;
|
|
@@ -3239,7 +3239,7 @@ var _SyncEngine = class _SyncEngine {
|
|
|
3239
3239
|
collection: collectionName,
|
|
3240
3240
|
timestamp: (meta == null ? void 0 : meta.lastSyncTs) || 0,
|
|
3241
3241
|
query,
|
|
3242
|
-
opts:
|
|
3242
|
+
opts: (_c = config.syncConfig) == null ? void 0 : _c.opts
|
|
3243
3243
|
});
|
|
3244
3244
|
configMap.set(collectionName, config);
|
|
3245
3245
|
}
|
|
@@ -3271,7 +3271,26 @@ var _SyncEngine = class _SyncEngine {
|
|
|
3271
3271
|
allSpecs,
|
|
3272
3272
|
async (collection, items, specId) => {
|
|
3273
3273
|
if (specId !== void 0) {
|
|
3274
|
-
if (
|
|
3274
|
+
if (specId.endsWith(":exit")) {
|
|
3275
|
+
const exitItems = items.filter((it) => it._evictIds);
|
|
3276
|
+
if (exitItems.length > 0) {
|
|
3277
|
+
const exitIds = exitItems.map((it) => String(it._id));
|
|
3278
|
+
await this.dexieDb.deleteMany(collection, exitIds);
|
|
3279
|
+
this.deps.writeToInMemBatch(
|
|
3280
|
+
collection,
|
|
3281
|
+
exitIds.map((id) => ({ _id: id })),
|
|
3282
|
+
"delete",
|
|
3283
|
+
{ source: "incremental" }
|
|
3284
|
+
);
|
|
3285
|
+
this.callbackSafe(this.callbacks.onEviction, {
|
|
3286
|
+
collection,
|
|
3287
|
+
totalEvicted: exitIds.length,
|
|
3288
|
+
totalServerEvicted: exitIds.length
|
|
3289
|
+
});
|
|
3290
|
+
}
|
|
3291
|
+
} else if (extras) {
|
|
3292
|
+
extras.onChunk(specId, items);
|
|
3293
|
+
}
|
|
3275
3294
|
return;
|
|
3276
3295
|
}
|
|
3277
3296
|
const config = configMap.get(collection);
|
|
@@ -5391,7 +5410,7 @@ var _SyncedDb = class _SyncedDb {
|
|
|
5391
5410
|
}
|
|
5392
5411
|
// ==================== Lifecycle ====================
|
|
5393
5412
|
async init() {
|
|
5394
|
-
var _a, _b, _c
|
|
5413
|
+
var _a, _b, _c;
|
|
5395
5414
|
if (this.initialized) return;
|
|
5396
5415
|
if (typeof localStorage === "undefined") {
|
|
5397
5416
|
this.connectionManager.reportInfrastructureError(
|
|
@@ -5448,10 +5467,8 @@ var _SyncedDb = class _SyncedDb {
|
|
|
5448
5467
|
);
|
|
5449
5468
|
try {
|
|
5450
5469
|
await this.serverUpdateNotifier.connect();
|
|
5451
|
-
const ep = (_c = this.serverUpdateNotifier.endpoint) != null ? _c : "unknown";
|
|
5452
|
-
console.log(`[SyncedDb] SyncedDb: ebus-proxy connected to ${ep}`);
|
|
5453
5470
|
} catch (err) {
|
|
5454
|
-
const ep = (
|
|
5471
|
+
const ep = (_c = this.serverUpdateNotifier.endpoint) != null ? _c : "unknown";
|
|
5455
5472
|
console.warn(
|
|
5456
5473
|
`[SyncedDb] SyncedDb: ebus-proxy connection to ${ep} failed`
|
|
5457
5474
|
);
|
|
@@ -6714,9 +6731,7 @@ var _SyncedDb = class _SyncedDb {
|
|
|
6714
6731
|
const allDirty = await this.dexieDb.getDirty(collectionName);
|
|
6715
6732
|
const content = stuck.map((m) => {
|
|
6716
6733
|
const dirtyId = String(m.id);
|
|
6717
|
-
const found = allDirty.find(
|
|
6718
|
-
(d) => String(d._id) === dirtyId
|
|
6719
|
-
);
|
|
6734
|
+
const found = allDirty.find((d) => String(d._id) === dirtyId);
|
|
6720
6735
|
if (found) {
|
|
6721
6736
|
const _a = found, { _id, _ts, _rev } = _a, changedFields = __objRest(_a, ["_id", "_ts", "_rev"]);
|
|
6722
6737
|
return {
|
|
@@ -10866,7 +10881,8 @@ function preprocessForPack2(data) {
|
|
|
10866
10881
|
if (isTimestamp2(data)) return { t: data.high, i: data.low };
|
|
10867
10882
|
if (typeof data !== "object") return data;
|
|
10868
10883
|
if (data instanceof Date) return data;
|
|
10869
|
-
if (data instanceof Map || data instanceof Set || data instanceof RegExp)
|
|
10884
|
+
if (data instanceof Map || data instanceof Set || data instanceof RegExp)
|
|
10885
|
+
return data;
|
|
10870
10886
|
if (Array.isArray(data)) return data.map(preprocessForPack2);
|
|
10871
10887
|
const result = {};
|
|
10872
10888
|
for (const key of Object.keys(data)) {
|
|
@@ -10916,8 +10932,10 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
10916
10932
|
this.pongTimeoutMs = (_d = config.pongTimeoutMs) != null ? _d : DEFAULT_PONG_TIMEOUT_MS;
|
|
10917
10933
|
this.currentReconnectDelay = this.reconnectDelayMs;
|
|
10918
10934
|
if (config.onWsConnect) this.onWsConnectCallbacks.push(config.onWsConnect);
|
|
10919
|
-
if (config.onWsDisconnect)
|
|
10920
|
-
|
|
10935
|
+
if (config.onWsDisconnect)
|
|
10936
|
+
this.onWsDisconnectCallbacks.push(config.onWsDisconnect);
|
|
10937
|
+
if (config.onWsReconnect)
|
|
10938
|
+
this.onWsReconnectCallbacks.push(config.onWsReconnect);
|
|
10921
10939
|
this.onWsNotification = config.onWsNotification;
|
|
10922
10940
|
this.subscribeServices = (_e = config.subscribeServices) != null ? _e : false;
|
|
10923
10941
|
this.onServicesChange = config.onServicesChange;
|
|
@@ -10999,7 +11017,11 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
10999
11017
|
return new Promise((resolve, reject) => {
|
|
11000
11018
|
const timer = setTimeout(() => {
|
|
11001
11019
|
this._pendingRttPings.delete(id);
|
|
11002
|
-
reject(
|
|
11020
|
+
reject(
|
|
11021
|
+
new Error(
|
|
11022
|
+
`[Ebus2ProxyNotifier] measureWsRtt: timeout after ${timeoutMs}ms`
|
|
11023
|
+
)
|
|
11024
|
+
);
|
|
11003
11025
|
}, timeoutMs);
|
|
11004
11026
|
this._pendingRttPings.set(id, () => {
|
|
11005
11027
|
clearTimeout(timer);
|
|
@@ -11080,7 +11102,9 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
11080
11102
|
return new Promise((resolve, reject) => {
|
|
11081
11103
|
var _a2;
|
|
11082
11104
|
if ((_a2 = options == null ? void 0 : options.signal) == null ? void 0 : _a2.aborted) {
|
|
11083
|
-
reject(
|
|
11105
|
+
reject(
|
|
11106
|
+
new Error(`[Ebus2ProxyNotifier] callWorker(${service}): aborted`)
|
|
11107
|
+
);
|
|
11084
11108
|
return;
|
|
11085
11109
|
}
|
|
11086
11110
|
const timer = setTimeout(() => {
|
|
@@ -11106,7 +11130,9 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
11106
11130
|
);
|
|
11107
11131
|
} : void 0;
|
|
11108
11132
|
if (abortListener && options.signal) {
|
|
11109
|
-
options.signal.addEventListener("abort", abortListener, {
|
|
11133
|
+
options.signal.addEventListener("abort", abortListener, {
|
|
11134
|
+
once: true
|
|
11135
|
+
});
|
|
11110
11136
|
}
|
|
11111
11137
|
this._pendingRequests.set(id, {
|
|
11112
11138
|
resolve,
|
|
@@ -11164,11 +11190,15 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
11164
11190
|
if (idx !== -1) this.onWsConnectCallbacks.splice(idx, 1);
|
|
11165
11191
|
}
|
|
11166
11192
|
if (addedCallbacks.onDisconnect) {
|
|
11167
|
-
const idx = this.onWsDisconnectCallbacks.indexOf(
|
|
11193
|
+
const idx = this.onWsDisconnectCallbacks.indexOf(
|
|
11194
|
+
addedCallbacks.onDisconnect
|
|
11195
|
+
);
|
|
11168
11196
|
if (idx !== -1) this.onWsDisconnectCallbacks.splice(idx, 1);
|
|
11169
11197
|
}
|
|
11170
11198
|
if (addedCallbacks.onReconnect) {
|
|
11171
|
-
const idx = this.onWsReconnectCallbacks.indexOf(
|
|
11199
|
+
const idx = this.onWsReconnectCallbacks.indexOf(
|
|
11200
|
+
addedCallbacks.onReconnect
|
|
11201
|
+
);
|
|
11172
11202
|
if (idx !== -1) this.onWsReconnectCallbacks.splice(idx, 1);
|
|
11173
11203
|
}
|
|
11174
11204
|
};
|
|
@@ -11229,9 +11259,6 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
11229
11259
|
this.connected = true;
|
|
11230
11260
|
this.reconnectAttempt = 0;
|
|
11231
11261
|
this.currentReconnectDelay = this.reconnectDelayMs;
|
|
11232
|
-
console.log(
|
|
11233
|
-
`[Ebus2ProxyNotifier] Ebus2Proxy connected to ${this.wsUrl} (db: ${this.dbName})`
|
|
11234
|
-
);
|
|
11235
11262
|
this.sendSubscribe(`db/${this.dbName}`);
|
|
11236
11263
|
if (this.subscribeServices) {
|
|
11237
11264
|
this.sendSubscribe("ebus/services");
|
|
@@ -11241,7 +11268,10 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
11241
11268
|
try {
|
|
11242
11269
|
callback();
|
|
11243
11270
|
} catch (err) {
|
|
11244
|
-
console.error(
|
|
11271
|
+
console.error(
|
|
11272
|
+
`[Ebus2ProxyNotifier] onWsConnect callback failed: ${err}`,
|
|
11273
|
+
err
|
|
11274
|
+
);
|
|
11245
11275
|
}
|
|
11246
11276
|
}
|
|
11247
11277
|
}
|
|
@@ -11270,7 +11300,10 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
11270
11300
|
try {
|
|
11271
11301
|
callback(reason);
|
|
11272
11302
|
} catch (err) {
|
|
11273
|
-
console.error(
|
|
11303
|
+
console.error(
|
|
11304
|
+
`[Ebus2ProxyNotifier] onWsDisconnect callback failed: ${err}`,
|
|
11305
|
+
err
|
|
11306
|
+
);
|
|
11274
11307
|
}
|
|
11275
11308
|
}
|
|
11276
11309
|
}
|
|
@@ -11314,7 +11347,10 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
11314
11347
|
clearTimeout(pending.timer);
|
|
11315
11348
|
this._pendingRequests.delete(message.id);
|
|
11316
11349
|
if (pending.abortListener && pending.signal) {
|
|
11317
|
-
pending.signal.removeEventListener(
|
|
11350
|
+
pending.signal.removeEventListener(
|
|
11351
|
+
"abort",
|
|
11352
|
+
pending.abortListener
|
|
11353
|
+
);
|
|
11318
11354
|
}
|
|
11319
11355
|
pending.resolve(message.data);
|
|
11320
11356
|
}
|
|
@@ -11328,7 +11364,10 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
11328
11364
|
clearTimeout(pending.timer);
|
|
11329
11365
|
this._pendingRequests.delete(message.id);
|
|
11330
11366
|
if (pending.abortListener && pending.signal) {
|
|
11331
|
-
pending.signal.removeEventListener(
|
|
11367
|
+
pending.signal.removeEventListener(
|
|
11368
|
+
"abort",
|
|
11369
|
+
pending.abortListener
|
|
11370
|
+
);
|
|
11332
11371
|
}
|
|
11333
11372
|
pending.reject(
|
|
11334
11373
|
new Error(
|
|
@@ -11338,11 +11377,17 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
11338
11377
|
break;
|
|
11339
11378
|
}
|
|
11340
11379
|
}
|
|
11341
|
-
console.error(
|
|
11380
|
+
console.error(
|
|
11381
|
+
`[Ebus2ProxyNotifier] WebSocket server error: ${message.error}`,
|
|
11382
|
+
message.error
|
|
11383
|
+
);
|
|
11342
11384
|
break;
|
|
11343
11385
|
}
|
|
11344
11386
|
} catch (err) {
|
|
11345
|
-
console.error(
|
|
11387
|
+
console.error(
|
|
11388
|
+
`[Ebus2ProxyNotifier] Failed to parse WebSocket message: ${err}`,
|
|
11389
|
+
err
|
|
11390
|
+
);
|
|
11346
11391
|
}
|
|
11347
11392
|
}
|
|
11348
11393
|
handleChannelMessage(message) {
|
|
@@ -11350,7 +11395,10 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
11350
11395
|
try {
|
|
11351
11396
|
this.onServicesChange(message.data);
|
|
11352
11397
|
} catch (err) {
|
|
11353
|
-
console.error(
|
|
11398
|
+
console.error(
|
|
11399
|
+
`[Ebus2ProxyNotifier] onServicesChange callback failed: ${err}`,
|
|
11400
|
+
err
|
|
11401
|
+
);
|
|
11354
11402
|
}
|
|
11355
11403
|
return;
|
|
11356
11404
|
}
|
|
@@ -11367,14 +11415,20 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
11367
11415
|
try {
|
|
11368
11416
|
this.onWsNotification(payload);
|
|
11369
11417
|
} catch (err) {
|
|
11370
|
-
console.error(
|
|
11418
|
+
console.error(
|
|
11419
|
+
`[Ebus2ProxyNotifier] onWsNotification callback failed: ${err}`,
|
|
11420
|
+
err
|
|
11421
|
+
);
|
|
11371
11422
|
}
|
|
11372
11423
|
}
|
|
11373
11424
|
for (const callback of this.callbacks) {
|
|
11374
11425
|
try {
|
|
11375
11426
|
callback(payload);
|
|
11376
11427
|
} catch (err) {
|
|
11377
|
-
console.error(
|
|
11428
|
+
console.error(
|
|
11429
|
+
`[Ebus2ProxyNotifier] ServerUpdateCallback failed: ${err}`,
|
|
11430
|
+
err
|
|
11431
|
+
);
|
|
11378
11432
|
}
|
|
11379
11433
|
}
|
|
11380
11434
|
}
|
|
@@ -11393,7 +11447,10 @@ var Ebus2ProxyServerUpdateNotifier = class {
|
|
|
11393
11447
|
try {
|
|
11394
11448
|
callback(this.reconnectAttempt);
|
|
11395
11449
|
} catch (err) {
|
|
11396
|
-
console.error(
|
|
11450
|
+
console.error(
|
|
11451
|
+
`[Ebus2ProxyNotifier] onWsReconnect callback failed: ${err}`,
|
|
11452
|
+
err
|
|
11453
|
+
);
|
|
11397
11454
|
}
|
|
11398
11455
|
}
|
|
11399
11456
|
this.reconnectTimer = setTimeout(() => {
|
|
@@ -268,6 +268,11 @@ export interface SyncEngineCallbacks {
|
|
|
268
268
|
onFindNewerManyResult?: (info: FindNewerManyResultInfo) => void;
|
|
269
269
|
onUploadSkip?: (info: import("../../types/I_SyncedDb").UploadSkipInfo) => void;
|
|
270
270
|
onDirtyItemStuck?: (info: import("../../types/I_SyncedDb").DirtyItemStuckInfo) => void;
|
|
271
|
+
onEviction?: (info: {
|
|
272
|
+
collection: string;
|
|
273
|
+
totalEvicted: number;
|
|
274
|
+
totalServerEvicted: number;
|
|
275
|
+
}) => void;
|
|
271
276
|
}
|
|
272
277
|
export interface SyncEngineDeps {
|
|
273
278
|
getSyncMetaCache: () => Map<string, SyncMeta>;
|
|
@@ -10,6 +10,15 @@ export interface CollectionSyncConfig<T = any> {
|
|
|
10
10
|
enabled?: boolean | (() => boolean);
|
|
11
11
|
/** Query filter for sync. If a function, called at each sync to get the query. */
|
|
12
12
|
query?: QuerySpec<T> | (() => QuerySpec<T>);
|
|
13
|
+
/**
|
|
14
|
+
* Options passed to findNewerManyStream during sync.
|
|
15
|
+
* e.g. `{ returnDeleted: true }` to include soft-deleted records.
|
|
16
|
+
* When omitted, cry-db applies its own defaults.
|
|
17
|
+
*/
|
|
18
|
+
opts?: {
|
|
19
|
+
returnDeleted?: boolean;
|
|
20
|
+
returnArchived?: boolean;
|
|
21
|
+
};
|
|
13
22
|
}
|
|
14
23
|
export interface CollectionConfig<T = any> {
|
|
15
24
|
name: string;
|
|
@@ -531,6 +531,12 @@ export interface CollectionSyncConfig {
|
|
|
531
531
|
enabled?: boolean | (() => boolean);
|
|
532
532
|
/** Query filter for sync. If a function, called at each sync to get the query. */
|
|
533
533
|
query?: QuerySpec<any> | (() => QuerySpec<any>);
|
|
534
|
+
/** Options passed through to findNewer (returnDeleted, returnArchived, project, ...) */
|
|
535
|
+
opts?: {
|
|
536
|
+
returnDeleted?: boolean;
|
|
537
|
+
returnArchived?: boolean;
|
|
538
|
+
project?: Record<string, any>;
|
|
539
|
+
};
|
|
534
540
|
}
|
|
535
541
|
/**
|
|
536
542
|
* Konfiguracija za posamezno kolekcijo
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cry-synced-db-client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.209",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -20,25 +20,25 @@
|
|
|
20
20
|
"build": "bun run clean && bun run build:js && bun run build:types",
|
|
21
21
|
"build:js": "esbuild ./src/index.ts --bundle --outdir=./dist --target=es2017 --format=esm --platform=browser --external:dexie --external:bson --external:cry-helpers",
|
|
22
22
|
"build:types": "tsc --emitDeclarationOnly --outDir dist",
|
|
23
|
-
"test": "bun test test/*.test.ts test/restProxy/*.test.ts
|
|
23
|
+
"test": "bun test --preload ./test/preload-bun.cjs test/*.test.ts test/restProxy/*.test.ts; vitest run",
|
|
24
24
|
"test:bun": "bun test test/*.test.ts test/restProxy/*.test.ts",
|
|
25
25
|
"test:node-only": "vitest run",
|
|
26
|
-
"test:real-mongo": "USE_REAL_MONGO=1
|
|
26
|
+
"test:real-mongo": "USE_REAL_MONGO=1 npx vitest run test/node-only/",
|
|
27
27
|
"prepublishOnly": "bun run build"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/bun": "latest",
|
|
31
|
-
"bson": "^7.
|
|
31
|
+
"bson": "^7.3.1",
|
|
32
32
|
"cry-ebus-proxy": "^2.0.0",
|
|
33
|
-
"dexie": "^4.4.
|
|
33
|
+
"dexie": "^4.4.4",
|
|
34
34
|
"esbuild": "^0.28.1",
|
|
35
35
|
"fake-indexeddb": "^6.2.5",
|
|
36
36
|
"typescript": "^6",
|
|
37
|
-
"vitest": "^4.1.
|
|
37
|
+
"vitest": "^4.1.9"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"cry-db": "^2.5.
|
|
41
|
-
"cry-helpers": "^2.1.
|
|
40
|
+
"cry-db": "^2.5.6",
|
|
41
|
+
"cry-helpers": "^2.1.206",
|
|
42
42
|
"msgpackr": "^2.0.4",
|
|
43
43
|
"superjson": "^2.2.6"
|
|
44
44
|
},
|