cry-synced-db-client 0.1.167 → 0.1.168

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/dist/index.js CHANGED
@@ -329,6 +329,22 @@ function sameIdSequence(a, b) {
329
329
  }
330
330
  return true;
331
331
  }
332
+ function containsIdArrayDescendant(value) {
333
+ if (value === null || typeof value !== "object") return false;
334
+ if (value instanceof Date || isObjectIdLike(value)) return false;
335
+ if (Array.isArray(value)) {
336
+ if (value.length > 0 && allElementsHaveId(value)) return true;
337
+ for (const v of value) {
338
+ if (containsIdArrayDescendant(v)) return true;
339
+ }
340
+ return false;
341
+ }
342
+ if (!isPlainObject(value)) return false;
343
+ for (const key of Object.keys(value)) {
344
+ if (containsIdArrayDescendant(value[key])) return true;
345
+ }
346
+ return false;
347
+ }
332
348
  function computeArrayDiff(existingArr, updateArr, basePath, diff) {
333
349
  if (existingArr.length === 0 && updateArr.length === 0) return;
334
350
  if (!allElementsHaveId(updateArr) || existingArr.length > 0 && !allElementsHaveId(existingArr)) {
@@ -354,12 +370,14 @@ function computeArrayDiff(existingArr, updateArr, basePath, diff) {
354
370
  if (sameIdSequence(existingArr, updateArr)) {
355
371
  for (let i = 0; i < updateArr.length; i++) {
356
372
  const elementId = String(updateArr[i]._id);
357
- computeDiffInto(
358
- existingArr[i],
359
- updateArr[i],
360
- `${basePath}[${elementId}]`,
361
- diff
362
- );
373
+ const elementPath = `${basePath}[${elementId}]`;
374
+ if (containsIdArrayDescendant(updateArr[i])) {
375
+ if (!deepEquals(existingArr[i], updateArr[i])) {
376
+ diff[elementPath] = updateArr[i];
377
+ }
378
+ } else {
379
+ computeDiffInto(existingArr[i], updateArr[i], elementPath, diff);
380
+ }
363
381
  }
364
382
  } else {
365
383
  diff[basePath] = updateArr;
@@ -383,12 +401,19 @@ function computeArrayDiff(existingArr, updateArr, basePath, diff) {
383
401
  for (const updateEl of updateArr) {
384
402
  const id = String(updateEl._id);
385
403
  if (existingIds.has(id)) {
386
- computeDiffInto(
387
- existingById.get(id),
388
- updateEl,
389
- `${basePath}[${id}]`,
390
- diff
391
- );
404
+ const elementPath = `${basePath}[${id}]`;
405
+ if (containsIdArrayDescendant(updateEl)) {
406
+ if (!deepEquals(existingById.get(id), updateEl)) {
407
+ diff[elementPath] = updateEl;
408
+ }
409
+ } else {
410
+ computeDiffInto(
411
+ existingById.get(id),
412
+ updateEl,
413
+ elementPath,
414
+ diff
415
+ );
416
+ }
392
417
  }
393
418
  }
394
419
  }
@@ -3271,11 +3296,45 @@ var _SyncEngine = class _SyncEngine {
3271
3296
  let sentCount = 0;
3272
3297
  const collectionSentCounts = {};
3273
3298
  for (const result of results) {
3274
- const { collection, results: { inserted, updated, deleted, errors: errors2 } } = result;
3299
+ const {
3300
+ collection,
3301
+ results: { inserted, updated, deleted, errors: errors2, warnings }
3302
+ } = result;
3303
+ const erroredIds = /* @__PURE__ */ new Set();
3304
+ if (errors2 && errors2.length > 0) {
3305
+ for (const e of errors2) erroredIds.add(String(e._id));
3306
+ }
3275
3307
  const allSuccessIds = [];
3276
- for (const e of inserted) allSuccessIds.push(e._id);
3277
- for (const e of updated) allSuccessIds.push(e._id);
3278
- for (const e of deleted) allSuccessIds.push(e._id);
3308
+ const ambiguous = [];
3309
+ for (const e of inserted) {
3310
+ const sid = String(e._id);
3311
+ if (erroredIds.has(sid)) {
3312
+ ambiguous.push(sid);
3313
+ continue;
3314
+ }
3315
+ allSuccessIds.push(e._id);
3316
+ }
3317
+ for (const e of updated) {
3318
+ const sid = String(e._id);
3319
+ if (erroredIds.has(sid)) {
3320
+ ambiguous.push(sid);
3321
+ continue;
3322
+ }
3323
+ allSuccessIds.push(e._id);
3324
+ }
3325
+ for (const e of deleted) {
3326
+ const sid = String(e._id);
3327
+ if (erroredIds.has(sid)) {
3328
+ ambiguous.push(sid);
3329
+ continue;
3330
+ }
3331
+ allSuccessIds.push(e._id);
3332
+ }
3333
+ if (ambiguous.length > 0) {
3334
+ console.error(
3335
+ `Sync upload [${collection}]: ${ambiguous.length} id(s) appeared in BOTH inserted/updated/deleted AND errors[] \u2014 keeping dirty for safety. _ids: ${ambiguous.join(", ")}`
3336
+ );
3337
+ }
3279
3338
  if (allSuccessIds.length > 0) {
3280
3339
  await this.dexieDb.clearDirtyChangesBatch(collection, allSuccessIds);
3281
3340
  }
@@ -3368,12 +3427,19 @@ var _SyncEngine = class _SyncEngine {
3368
3427
  });
3369
3428
  }
3370
3429
  }
3371
- if (errors2) {
3372
- console.error(
3373
- `Sync upload errors for ${collection}:`,
3374
- errors2,
3375
- "\u2014 dirty entries for failed items will persist until retry"
3376
- );
3430
+ if (errors2 && errors2.length > 0) {
3431
+ for (const e of errors2) {
3432
+ console.error(
3433
+ `Sync upload error [${collection}] _id=${e._id}: ${e.error} \u2014 dirty entry will persist until retry`
3434
+ );
3435
+ }
3436
+ }
3437
+ if (warnings && warnings.length > 0) {
3438
+ for (const w of warnings) {
3439
+ console.warn(
3440
+ `Sync upload warning [${collection}] _id=${w._id}: ${w.error}`
3441
+ );
3442
+ }
3377
3443
  }
3378
3444
  const sentIds = /* @__PURE__ */ new Set([
3379
3445
  ...collectionBatches.flat().filter((b) => b.collection === collection).flatMap((b) => [
@@ -3433,15 +3499,60 @@ var _SyncEngine = class _SyncEngine {
3433
3499
  );
3434
3500
  let sentCount = 0;
3435
3501
  for (const result of results) {
3436
- const { results: { inserted, updated, deleted } } = result;
3502
+ const {
3503
+ results: { inserted, updated, deleted, errors: errors2, warnings }
3504
+ } = result;
3505
+ const erroredIds = /* @__PURE__ */ new Set();
3506
+ if (errors2 && errors2.length > 0) {
3507
+ for (const e of errors2) {
3508
+ erroredIds.add(String(e._id));
3509
+ console.error(
3510
+ `Sync upload error [${collection}] _id=${e._id}: ${e.error} \u2014 dirty entry will persist until retry`
3511
+ );
3512
+ }
3513
+ }
3514
+ if (warnings && warnings.length > 0) {
3515
+ for (const w of warnings) {
3516
+ console.warn(
3517
+ `Sync upload warning [${collection}] _id=${w._id}: ${w.error}`
3518
+ );
3519
+ }
3520
+ }
3437
3521
  const allSuccessIds = [];
3438
- for (const e of inserted) allSuccessIds.push(e._id);
3439
- for (const e of updated) allSuccessIds.push(e._id);
3440
- for (const e of deleted) allSuccessIds.push(e._id);
3522
+ const ambiguous = [];
3523
+ for (const e of inserted) {
3524
+ const sid = String(e._id);
3525
+ if (erroredIds.has(sid)) {
3526
+ ambiguous.push(sid);
3527
+ continue;
3528
+ }
3529
+ allSuccessIds.push(e._id);
3530
+ }
3531
+ for (const e of updated) {
3532
+ const sid = String(e._id);
3533
+ if (erroredIds.has(sid)) {
3534
+ ambiguous.push(sid);
3535
+ continue;
3536
+ }
3537
+ allSuccessIds.push(e._id);
3538
+ }
3539
+ for (const e of deleted) {
3540
+ const sid = String(e._id);
3541
+ if (erroredIds.has(sid)) {
3542
+ ambiguous.push(sid);
3543
+ continue;
3544
+ }
3545
+ allSuccessIds.push(e._id);
3546
+ }
3547
+ if (ambiguous.length > 0) {
3548
+ console.error(
3549
+ `Sync upload [${collection}]: ${ambiguous.length} id(s) appeared in BOTH inserted/updated/deleted AND errors[] \u2014 keeping dirty for safety. _ids: ${ambiguous.join(", ")}`
3550
+ );
3551
+ }
3441
3552
  if (allSuccessIds.length > 0) {
3442
3553
  await this.dexieDb.clearDirtyChangesBatch(collection, allSuccessIds);
3443
3554
  }
3444
- sentCount += inserted.length + updated.length + deleted.length;
3555
+ sentCount += allSuccessIds.length;
3445
3556
  }
3446
3557
  return { sentCount };
3447
3558
  }
@@ -43,7 +43,6 @@ export interface RestProxyConfig {
43
43
  * ## Performance
44
44
  *
45
45
  * Benchmarked at ~5ms per request (after warmup) on localhost.
46
- * Native fetch performs comparably to undici with connection pooling.
47
46
  *
48
47
  * ## Progress Callback Limitations
49
48
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cry-synced-db-client",
3
- "version": "0.1.167",
3
+ "version": "0.1.168",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -18,7 +18,7 @@
18
18
  "scripts": {
19
19
  "clean": "rm -rf dist",
20
20
  "build": "bun run clean && bun run build:js && bun run build:types",
21
- "build:js": "esbuild ./src/index.ts --bundle --outdir=./dist --target=es2017 --format=esm --platform=browser --external:dexie --external:bson --external:cry-helpers --external:notepack.io",
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
23
  "test": "bun test test/*.test.ts test/restProxy/*.test.ts && vitest run",
24
24
  "test:bun": "bun test test/*.test.ts test/restProxy/*.test.ts",
@@ -39,10 +39,7 @@
39
39
  "dependencies": {
40
40
  "cry-helpers": "^2.1.194",
41
41
  "msgpackr": "^2.0.1",
42
- "notepack": "^0.0.2",
43
- "notepack.io": "^3.0.1",
44
- "superjson": "^2.2.6",
45
- "undici": "^8.2.0"
42
+ "superjson": "^2.2.6"
46
43
  },
47
44
  "peerDependencies": {
48
45
  "bson": "^6.0.0 || ^7.0.0",