dexie-cloud-addon 4.2.0-rc.1 → 4.2.1

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.
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * ==========================================================================
10
10
  *
11
- * Version 4.2.0-rc.1, Wed Aug 06 2025
11
+ * Version 4.2.1, Wed Oct 01 2025
12
12
  *
13
13
  * https://dexie.org
14
14
  *
@@ -2472,17 +2472,14 @@
2472
2472
  : mutationTable;
2473
2473
  if (limit < Infinity)
2474
2474
  query = query.limit(limit);
2475
- const muts = yield query.toArray();
2476
- //const objTable = db.table(tableName);
2477
- /*for (const mut of muts) {
2478
- if (mut.type === "insert" || mut.type === "upsert") {
2479
- mut.values = await objTable.bulkGet(mut.keys);
2480
- }
2481
- }*/
2482
- return muts.map((mut) => ({
2475
+ let muts = yield query.toArray();
2476
+ muts = canonicalizeToUpdateOps(muts);
2477
+ muts = removeRedundantUpdateOps(muts);
2478
+ const rv = muts.map((mut) => ({
2483
2479
  table: tableName,
2484
2480
  mut,
2485
2481
  }));
2482
+ return rv;
2486
2483
  })));
2487
2484
  // Sort by time to get a true order of the operations (between tables)
2488
2485
  const sorted = flatten(allMutsOnTables).sort((a, b) => a.mut.txid === b.mut.txid
@@ -2511,6 +2508,69 @@
2511
2508
  return result;
2512
2509
  });
2513
2510
  }
2511
+ function removeRedundantUpdateOps(muts) {
2512
+ const updateCoverage = new Map();
2513
+ for (const mut of muts) {
2514
+ if (mut.type === 'update') {
2515
+ if (mut.keys.length !== 1 || mut.changeSpecs.length !== 1) {
2516
+ continue; // Don't optimize multi-key updates
2517
+ }
2518
+ const strKey = '' + mut.keys[0];
2519
+ const changeSpecs = mut.changeSpecs[0];
2520
+ if (Object.values(changeSpecs).some(v => typeof v === "object" && v && "@@propmod" in v)) {
2521
+ continue; // Cannot optimize if any PropModification is present
2522
+ }
2523
+ let keyCoverage = updateCoverage.get(strKey);
2524
+ if (keyCoverage) {
2525
+ keyCoverage.push({ txid: mut.txid, updateSpec: changeSpecs });
2526
+ }
2527
+ else {
2528
+ updateCoverage.set(strKey, [{ txid: mut.txid, updateSpec: changeSpecs }]);
2529
+ }
2530
+ }
2531
+ }
2532
+ muts = muts.filter(mut => {
2533
+ // Only apply optimization to update mutations that are single-key
2534
+ if (mut.type !== 'update')
2535
+ return true;
2536
+ if (mut.keys.length !== 1 || mut.changeSpecs.length !== 1)
2537
+ return true;
2538
+ // Keep track of properties that aren't overlapped by later transactions
2539
+ const unoverlappedProps = new Set(Object.keys(mut.changeSpecs[0]));
2540
+ const strKey = '' + mut.keys[0];
2541
+ const keyCoverage = updateCoverage.get(strKey);
2542
+ for (let i = keyCoverage.length - 1; i >= 0; --i) {
2543
+ const { txid, updateSpec } = keyCoverage[i];
2544
+ if (txid === mut.txid)
2545
+ break; // Stop when reaching own txid
2546
+ // If all changes in updateSpec are covered by all props on all mut.changeSpecs then
2547
+ // txid is redundant and can be removed.
2548
+ for (const keyPath of Object.keys(updateSpec)) {
2549
+ unoverlappedProps.delete(keyPath);
2550
+ }
2551
+ }
2552
+ if (unoverlappedProps.size === 0) {
2553
+ // This operation is completely overlapped by later operations. It can be removed.
2554
+ return false;
2555
+ }
2556
+ return true;
2557
+ });
2558
+ return muts;
2559
+ }
2560
+ function canonicalizeToUpdateOps(muts) {
2561
+ muts = muts.map(mut => {
2562
+ if (mut.type === 'modify' && mut.criteria.index === null) {
2563
+ // The criteria is on primary key. Convert to an update operation instead.
2564
+ // It is simpler for the server to handle and also more efficient.
2565
+ const updateMut = Object.assign(Object.assign({}, mut), { criteria: undefined, changeSpec: undefined, type: 'update', keys: mut.keys, changeSpecs: [mut.changeSpec] });
2566
+ delete updateMut.criteria;
2567
+ delete updateMut.changeSpec;
2568
+ return updateMut;
2569
+ }
2570
+ return mut;
2571
+ });
2572
+ return muts;
2573
+ }
2514
2574
 
2515
2575
  function randomString(bytes) {
2516
2576
  const buf = new Uint8Array(bytes);
@@ -14193,7 +14253,7 @@
14193
14253
  *
14194
14254
  * ==========================================================================
14195
14255
  *
14196
- * Version 4.2.0-rc.1, Wed Aug 06 2025
14256
+ * Version 4.2.1, Wed Oct 01 2025
14197
14257
  *
14198
14258
  * https://dexie.org
14199
14259
  *
@@ -18180,7 +18240,7 @@
18180
18240
  const syncComplete = new rxjs.Subject();
18181
18241
  dexie.cloud = {
18182
18242
  // @ts-ignore
18183
- version: "4.2.0-rc.1",
18243
+ version: "4.2.1",
18184
18244
  options: Object.assign({}, DEFAULT_OPTIONS),
18185
18245
  schema: null,
18186
18246
  get currentUserId() {
@@ -18497,7 +18557,7 @@
18497
18557
  }
18498
18558
  }
18499
18559
  // @ts-ignore
18500
- dexieCloud.version = "4.2.0-rc.1";
18560
+ dexieCloud.version = "4.2.1";
18501
18561
  Dexie.Cloud = dexieCloud;
18502
18562
 
18503
18563
  exports.default = dexieCloud;