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

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.
@@ -10,6 +10,9 @@ export interface DexieCloudOptions {
10
10
  periodicSync?: PeriodicSyncOptions;
11
11
  customLoginGui?: boolean;
12
12
  unsyncedTables?: string[];
13
+ unsyncedProperties?: {
14
+ [tableName: string]: string[];
15
+ };
13
16
  nameSuffix?: boolean;
14
17
  disableWebSocket?: boolean;
15
18
  disableEagerSync?: boolean;
@@ -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.14, Fri Oct 18 2024
12
12
  *
13
13
  * https://dexie.org
14
14
  *
@@ -6324,8 +6324,7 @@
6324
6324
  outstandingTransactions.next(outstandingTransactions.value);
6325
6325
  };
6326
6326
  const txComplete = () => {
6327
- if (tx.mutationsAdded &&
6328
- !isEagerSyncDisabled(db)) {
6327
+ if (tx.mutationsAdded && !isEagerSyncDisabled(db)) {
6329
6328
  triggerSync(db, 'push');
6330
6329
  }
6331
6330
  removeTransaction();
@@ -6407,26 +6406,107 @@
6407
6406
  : mutateAndLog(req);
6408
6407
  } }));
6409
6408
  function mutateAndLog(req) {
6409
+ var _a, _b;
6410
6410
  const trans = req.trans;
6411
- trans.mutationsAdded = true;
6411
+ const unsyncedProps = (_b = (_a = db.cloud.options) === null || _a === void 0 ? void 0 : _a.unsyncedProperties) === null || _b === void 0 ? void 0 : _b[tableName];
6412
6412
  const { txid, currentUser: { userId }, } = trans;
6413
6413
  const { type } = req;
6414
6414
  const opNo = ++trans.opCount;
6415
+ function stripChangeSpec(changeSpec) {
6416
+ if (!unsyncedProps)
6417
+ return changeSpec;
6418
+ let rv = changeSpec;
6419
+ for (const keyPath of Object.keys(changeSpec)) {
6420
+ if (unsyncedProps.some((p) => keyPath === p || keyPath.startsWith(p + '.'))) {
6421
+ if (rv === changeSpec)
6422
+ rv = Object.assign({}, changeSpec); // clone on demand
6423
+ delete rv[keyPath];
6424
+ }
6425
+ }
6426
+ return rv;
6427
+ }
6415
6428
  return table.mutate(req).then((res) => {
6429
+ var _a;
6416
6430
  const { numFailures: hasFailures, failures } = res;
6417
6431
  let keys = type === 'delete' ? req.keys : res.results;
6418
6432
  let values = 'values' in req ? req.values : [];
6419
- let updates = 'updates' in req && req.updates;
6433
+ let changeSpec = 'changeSpec' in req ? req.changeSpec : undefined;
6434
+ let updates = 'updates' in req ? req.updates : undefined;
6420
6435
  if (hasFailures) {
6421
6436
  keys = keys.filter((_, idx) => !failures[idx]);
6422
6437
  values = values.filter((_, idx) => !failures[idx]);
6423
6438
  }
6439
+ if (unsyncedProps) {
6440
+ // Filter out unsynced properties
6441
+ values = values.map((value) => {
6442
+ const newValue = Object.assign({}, value);
6443
+ for (const prop of unsyncedProps) {
6444
+ delete newValue[prop];
6445
+ }
6446
+ return newValue;
6447
+ });
6448
+ if (changeSpec) {
6449
+ // modify operation with criteria and changeSpec.
6450
+ // We must strip out unsynced properties from changeSpec.
6451
+ // We deal with criteria later.
6452
+ changeSpec = stripChangeSpec(changeSpec);
6453
+ if (Object.keys(changeSpec).length === 0) {
6454
+ // Nothing to change on server
6455
+ return res;
6456
+ }
6457
+ }
6458
+ if (updates) {
6459
+ let strippedChangeSpecs = updates.changeSpecs.map(stripChangeSpec);
6460
+ let newUpdates = {
6461
+ keys: [],
6462
+ changeSpecs: [],
6463
+ };
6464
+ const validKeys = new Dexie.RangeSet();
6465
+ let anyChangeSpecBecameEmpty = false;
6466
+ for (let i = 0, l = strippedChangeSpecs.length; i < l; ++i) {
6467
+ if (Object.keys(strippedChangeSpecs[i]).length > 0) {
6468
+ newUpdates.keys.push(updates.keys[i]);
6469
+ newUpdates.changeSpecs.push(strippedChangeSpecs[i]);
6470
+ validKeys.addKey(updates.keys[i]);
6471
+ }
6472
+ else {
6473
+ anyChangeSpecBecameEmpty = true;
6474
+ }
6475
+ }
6476
+ updates = newUpdates;
6477
+ if (anyChangeSpecBecameEmpty) {
6478
+ // Some keys were stripped. We must also strip them from keys and values
6479
+ let newKeys = [];
6480
+ let newValues = [];
6481
+ for (let i = 0, l = keys.length; i < l; ++i) {
6482
+ if (validKeys.hasKey(keys[i])) {
6483
+ newKeys.push(keys[i]);
6484
+ newValues.push(values[i]);
6485
+ }
6486
+ }
6487
+ keys = newKeys;
6488
+ values = newValues;
6489
+ }
6490
+ }
6491
+ }
6424
6492
  const ts = Date.now();
6425
6493
  // Canonicalize req.criteria.index to null if it's on the primary key.
6426
- const criteria = 'criteria' in req && req.criteria
6494
+ let criteria = 'criteria' in req && req.criteria
6427
6495
  ? Object.assign(Object.assign({}, req.criteria), { index: req.criteria.index === schema.primaryKey.keyPath // Use null to inform server that criteria is on primary key
6428
6496
  ? null // This will disable the server from trying to log consistent operations where it shouldnt.
6429
6497
  : req.criteria.index }) : undefined;
6498
+ if (unsyncedProps && (criteria === null || criteria === void 0 ? void 0 : criteria.index)) {
6499
+ const keyPaths = (_a = schema.indexes.find((idx) => idx.name === criteria.index)) === null || _a === void 0 ? void 0 : _a.keyPath;
6500
+ const involvedProps = keyPaths
6501
+ ? typeof keyPaths === 'string'
6502
+ ? [keyPaths]
6503
+ : keyPaths
6504
+ : [];
6505
+ if (involvedProps.some((p) => unsyncedProps === null || unsyncedProps === void 0 ? void 0 : unsyncedProps.includes(p))) {
6506
+ // Don't log criteria on unsynced properties as the server could not test them.
6507
+ criteria = undefined;
6508
+ }
6509
+ }
6430
6510
  const mut = req.type === 'delete'
6431
6511
  ? {
6432
6512
  type: 'delete',
@@ -6447,7 +6527,7 @@
6447
6527
  userId,
6448
6528
  values,
6449
6529
  }
6450
- : criteria && req.changeSpec
6530
+ : criteria && changeSpec
6451
6531
  ? {
6452
6532
  // Common changeSpec for all keys
6453
6533
  type: 'modify',
@@ -6455,30 +6535,41 @@
6455
6535
  opNo,
6456
6536
  keys,
6457
6537
  criteria,
6458
- changeSpec: req.changeSpec,
6538
+ changeSpec,
6459
6539
  txid,
6460
6540
  userId,
6461
6541
  }
6462
- : updates
6542
+ : changeSpec
6463
6543
  ? {
6464
- // One changeSpec per key
6544
+ // In case criteria involved an unsynced property, we go for keys instead.
6465
6545
  type: 'update',
6466
6546
  ts,
6467
6547
  opNo,
6468
- keys: updates.keys,
6469
- changeSpecs: updates.changeSpecs,
6470
- txid,
6471
- userId,
6472
- }
6473
- : {
6474
- type: 'upsert',
6475
- ts,
6476
- opNo,
6477
6548
  keys,
6478
- values,
6549
+ changeSpecs: keys.map(() => changeSpec),
6479
6550
  txid,
6480
6551
  userId,
6481
- };
6552
+ }
6553
+ : updates
6554
+ ? {
6555
+ // One changeSpec per key
6556
+ type: 'update',
6557
+ ts,
6558
+ opNo,
6559
+ keys: updates.keys,
6560
+ changeSpecs: updates.changeSpecs,
6561
+ txid,
6562
+ userId,
6563
+ }
6564
+ : {
6565
+ type: 'upsert',
6566
+ ts,
6567
+ opNo,
6568
+ keys,
6569
+ values,
6570
+ txid,
6571
+ userId,
6572
+ };
6482
6573
  if ('isAdditionalChunk' in req && req.isAdditionalChunk) {
6483
6574
  mut.isAdditionalChunk = true;
6484
6575
  }
@@ -8005,7 +8096,7 @@
8005
8096
  const syncComplete = new rxjs.Subject();
8006
8097
  dexie.cloud = {
8007
8098
  // @ts-ignore
8008
- version: "4.1.0-alpha.12",
8099
+ version: "4.1.0-alpha.14",
8009
8100
  options: Object.assign({}, DEFAULT_OPTIONS),
8010
8101
  schema: null,
8011
8102
  get currentUserId() {
@@ -8307,7 +8398,7 @@
8307
8398
  }
8308
8399
  }
8309
8400
  // @ts-ignore
8310
- dexieCloud.version = "4.1.0-alpha.12";
8401
+ dexieCloud.version = "4.1.0-alpha.14";
8311
8402
  Dexie.Cloud = dexieCloud;
8312
8403
 
8313
8404
  const ydocTriggers = {};
@@ -8331,8 +8422,8 @@
8331
8422
  return Object.assign(Object.assign({}, coreTable), { mutate(req) {
8332
8423
  switch (req.type) {
8333
8424
  case 'add': {
8334
- for (const obj of req.values) {
8335
- const primaryKey = coreTable.schema.primaryKey.extractKey(obj);
8425
+ for (const yUpdateRow of req.values) {
8426
+ const primaryKey = yUpdateRow.k;
8336
8427
  const doc = Dexie.DexieYProvider.getDocCache(db).find(parentTable, primaryKey, prop);
8337
8428
  if (doc) {
8338
8429
  if (!docIsAlreadyHooked.has(doc)) {
@@ -8341,7 +8432,7 @@
8341
8432
  }
8342
8433
  }
8343
8434
  else {
8344
- enqueueTrigger(tblName, primaryKey, trigger);
8435
+ enqueueTrigger(db, tblName, primaryKey, trigger);
8345
8436
  }
8346
8437
  }
8347
8438
  break;
@@ -8364,7 +8455,7 @@
8364
8455
  keySet.addKey(k);
8365
8456
  }
8366
8457
  for (const key of keySet) {
8367
- enqueueTrigger(tblName, key, trigger);
8458
+ enqueueTrigger(db, tblName, key, trigger);
8368
8459
  }
8369
8460
  });
8370
8461
  }
@@ -8406,11 +8497,12 @@
8406
8497
  }
8407
8498
  });
8408
8499
  }
8409
- function enqueueTrigger(updatesTable, parentId, trigger) {
8410
- var _a;
8411
- ((_a = scheduledTriggers[updatesTable]) !== null && _a !== void 0 ? _a : (scheduledTriggers[updatesTable] = [])).push({
8500
+ function enqueueTrigger(db, updatesTable, parentId, trigger) {
8501
+ scheduledTriggers.push({
8502
+ db,
8412
8503
  parentId,
8413
8504
  trigger,
8505
+ updatesTable
8414
8506
  });
8415
8507
  }
8416
8508
  function onTransactionCommitted() {