dexie-cloud-addon 4.1.0-alpha.12 → 4.1.0-alpha.13

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.1.0-alpha.12, Wed Oct 16 2024
11
+ * Version 4.1.0-alpha.13, Thu Oct 17 2024
12
12
  *
13
13
  * https://dexie.org
14
14
  *
@@ -16,7 +16,7 @@
16
16
  *
17
17
  */
18
18
 
19
- import Dexie, { PropModification, cmp, DexieYProvider, liveQuery } from 'dexie';
19
+ import Dexie, { PropModification, cmp, DexieYProvider, RangeSet, liveQuery } from 'dexie';
20
20
  import { Observable as Observable$1, BehaviorSubject, firstValueFrom, Subject, from as from$1, filter as filter$1, fromEvent, of, merge, switchMap as switchMap$1, tap as tap$1, mergeMap as mergeMap$1, Subscription as Subscription$1, throwError, combineLatest, map as map$1, share, timer as timer$1 } from 'rxjs';
21
21
 
22
22
  /******************************************************************************
@@ -6321,8 +6321,7 @@ function createMutationTrackingMiddleware({ currentUserObservable, db, }) {
6321
6321
  outstandingTransactions.next(outstandingTransactions.value);
6322
6322
  };
6323
6323
  const txComplete = () => {
6324
- if (tx.mutationsAdded &&
6325
- !isEagerSyncDisabled(db)) {
6324
+ if (tx.mutationsAdded && !isEagerSyncDisabled(db)) {
6326
6325
  triggerSync(db, 'push');
6327
6326
  }
6328
6327
  removeTransaction();
@@ -6404,26 +6403,107 @@ function createMutationTrackingMiddleware({ currentUserObservable, db, }) {
6404
6403
  : mutateAndLog(req);
6405
6404
  } }));
6406
6405
  function mutateAndLog(req) {
6406
+ var _a, _b;
6407
6407
  const trans = req.trans;
6408
- trans.mutationsAdded = true;
6408
+ const unsyncedProps = (_b = (_a = db.cloud.options) === null || _a === void 0 ? void 0 : _a.unsyncedProperties) === null || _b === void 0 ? void 0 : _b[tableName];
6409
6409
  const { txid, currentUser: { userId }, } = trans;
6410
6410
  const { type } = req;
6411
6411
  const opNo = ++trans.opCount;
6412
+ function stripChangeSpec(changeSpec) {
6413
+ if (!unsyncedProps)
6414
+ return changeSpec;
6415
+ let rv = changeSpec;
6416
+ for (const keyPath of Object.keys(changeSpec)) {
6417
+ if (unsyncedProps.some((p) => keyPath === p || keyPath.startsWith(p + '.'))) {
6418
+ if (rv === changeSpec)
6419
+ rv = Object.assign({}, changeSpec); // clone on demand
6420
+ delete rv[keyPath];
6421
+ }
6422
+ }
6423
+ return rv;
6424
+ }
6412
6425
  return table.mutate(req).then((res) => {
6426
+ var _a;
6413
6427
  const { numFailures: hasFailures, failures } = res;
6414
6428
  let keys = type === 'delete' ? req.keys : res.results;
6415
6429
  let values = 'values' in req ? req.values : [];
6416
- let updates = 'updates' in req && req.updates;
6430
+ let changeSpec = 'changeSpec' in req ? req.changeSpec : undefined;
6431
+ let updates = 'updates' in req ? req.updates : undefined;
6417
6432
  if (hasFailures) {
6418
6433
  keys = keys.filter((_, idx) => !failures[idx]);
6419
6434
  values = values.filter((_, idx) => !failures[idx]);
6420
6435
  }
6436
+ if (unsyncedProps) {
6437
+ // Filter out unsynced properties
6438
+ values = values.map((value) => {
6439
+ const newValue = Object.assign({}, value);
6440
+ for (const prop of unsyncedProps) {
6441
+ delete newValue[prop];
6442
+ }
6443
+ return newValue;
6444
+ });
6445
+ if (changeSpec) {
6446
+ // modify operation with criteria and changeSpec.
6447
+ // We must strip out unsynced properties from changeSpec.
6448
+ // We deal with criteria later.
6449
+ changeSpec = stripChangeSpec(changeSpec);
6450
+ if (Object.keys(changeSpec).length === 0) {
6451
+ // Nothing to change on server
6452
+ return res;
6453
+ }
6454
+ }
6455
+ if (updates) {
6456
+ let strippedChangeSpecs = updates.changeSpecs.map(stripChangeSpec);
6457
+ let newUpdates = {
6458
+ keys: [],
6459
+ changeSpecs: [],
6460
+ };
6461
+ const validKeys = new RangeSet();
6462
+ let anyChangeSpecBecameEmpty = false;
6463
+ for (let i = 0, l = strippedChangeSpecs.length; i < l; ++i) {
6464
+ if (Object.keys(strippedChangeSpecs[i]).length > 0) {
6465
+ newUpdates.keys.push(updates.keys[i]);
6466
+ newUpdates.changeSpecs.push(strippedChangeSpecs[i]);
6467
+ validKeys.addKey(updates.keys[i]);
6468
+ }
6469
+ else {
6470
+ anyChangeSpecBecameEmpty = true;
6471
+ }
6472
+ }
6473
+ updates = newUpdates;
6474
+ if (anyChangeSpecBecameEmpty) {
6475
+ // Some keys were stripped. We must also strip them from keys and values
6476
+ let newKeys = [];
6477
+ let newValues = [];
6478
+ for (let i = 0, l = keys.length; i < l; ++i) {
6479
+ if (validKeys.hasKey(keys[i])) {
6480
+ newKeys.push(keys[i]);
6481
+ newValues.push(values[i]);
6482
+ }
6483
+ }
6484
+ keys = newKeys;
6485
+ values = newValues;
6486
+ }
6487
+ }
6488
+ }
6421
6489
  const ts = Date.now();
6422
6490
  // Canonicalize req.criteria.index to null if it's on the primary key.
6423
- const criteria = 'criteria' in req && req.criteria
6491
+ let criteria = 'criteria' in req && req.criteria
6424
6492
  ? Object.assign(Object.assign({}, req.criteria), { index: req.criteria.index === schema.primaryKey.keyPath // Use null to inform server that criteria is on primary key
6425
6493
  ? null // This will disable the server from trying to log consistent operations where it shouldnt.
6426
6494
  : req.criteria.index }) : undefined;
6495
+ if (unsyncedProps && (criteria === null || criteria === void 0 ? void 0 : criteria.index)) {
6496
+ const keyPaths = (_a = schema.indexes.find((idx) => idx.name === criteria.index)) === null || _a === void 0 ? void 0 : _a.keyPath;
6497
+ const involvedProps = keyPaths
6498
+ ? typeof keyPaths === 'string'
6499
+ ? [keyPaths]
6500
+ : keyPaths
6501
+ : [];
6502
+ if (involvedProps.some((p) => unsyncedProps === null || unsyncedProps === void 0 ? void 0 : unsyncedProps.includes(p))) {
6503
+ // Don't log criteria on unsynced properties as the server could not test them.
6504
+ criteria = undefined;
6505
+ }
6506
+ }
6427
6507
  const mut = req.type === 'delete'
6428
6508
  ? {
6429
6509
  type: 'delete',
@@ -6444,7 +6524,7 @@ function createMutationTrackingMiddleware({ currentUserObservable, db, }) {
6444
6524
  userId,
6445
6525
  values,
6446
6526
  }
6447
- : criteria && req.changeSpec
6527
+ : criteria && changeSpec
6448
6528
  ? {
6449
6529
  // Common changeSpec for all keys
6450
6530
  type: 'modify',
@@ -6452,30 +6532,41 @@ function createMutationTrackingMiddleware({ currentUserObservable, db, }) {
6452
6532
  opNo,
6453
6533
  keys,
6454
6534
  criteria,
6455
- changeSpec: req.changeSpec,
6535
+ changeSpec,
6456
6536
  txid,
6457
6537
  userId,
6458
6538
  }
6459
- : updates
6539
+ : changeSpec
6460
6540
  ? {
6461
- // One changeSpec per key
6541
+ // In case criteria involved an unsynced property, we go for keys instead.
6462
6542
  type: 'update',
6463
6543
  ts,
6464
6544
  opNo,
6465
- keys: updates.keys,
6466
- changeSpecs: updates.changeSpecs,
6467
- txid,
6468
- userId,
6469
- }
6470
- : {
6471
- type: 'upsert',
6472
- ts,
6473
- opNo,
6474
6545
  keys,
6475
- values,
6546
+ changeSpecs: keys.map(() => changeSpec),
6476
6547
  txid,
6477
6548
  userId,
6478
- };
6549
+ }
6550
+ : updates
6551
+ ? {
6552
+ // One changeSpec per key
6553
+ type: 'update',
6554
+ ts,
6555
+ opNo,
6556
+ keys: updates.keys,
6557
+ changeSpecs: updates.changeSpecs,
6558
+ txid,
6559
+ userId,
6560
+ }
6561
+ : {
6562
+ type: 'upsert',
6563
+ ts,
6564
+ opNo,
6565
+ keys,
6566
+ values,
6567
+ txid,
6568
+ userId,
6569
+ };
6479
6570
  if ('isAdditionalChunk' in req && req.isAdditionalChunk) {
6480
6571
  mut.isAdditionalChunk = true;
6481
6572
  }
@@ -7995,7 +8086,7 @@ function dexieCloud(dexie) {
7995
8086
  const syncComplete = new Subject();
7996
8087
  dexie.cloud = {
7997
8088
  // @ts-ignore
7998
- version: "4.1.0-alpha.12",
8089
+ version: "4.1.0-alpha.13",
7999
8090
  options: Object.assign({}, DEFAULT_OPTIONS),
8000
8091
  schema: null,
8001
8092
  get currentUserId() {
@@ -8297,7 +8388,7 @@ function dexieCloud(dexie) {
8297
8388
  }
8298
8389
  }
8299
8390
  // @ts-ignore
8300
- dexieCloud.version = "4.1.0-alpha.12";
8391
+ dexieCloud.version = "4.1.0-alpha.13";
8301
8392
  Dexie.Cloud = dexieCloud;
8302
8393
 
8303
8394
  // In case the SW lives for a while, let it reuse already opened connections: