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
  *
@@ -16,7 +16,7 @@
16
16
  *
17
17
  */
18
18
 
19
- import Dexie, { PropModification, cmp, DexieYProvider, liveQuery, RangeSet } from 'dexie';
19
+ import Dexie, { PropModification, cmp, DexieYProvider, RangeSet, liveQuery } from 'dexie';
20
20
  import { firstValueFrom, from as from$1, filter as filter$1, Observable as Observable$1, BehaviorSubject, Subject, 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
  }
@@ -8002,7 +8093,7 @@ function dexieCloud(dexie) {
8002
8093
  const syncComplete = new Subject();
8003
8094
  dexie.cloud = {
8004
8095
  // @ts-ignore
8005
- version: "4.1.0-alpha.12",
8096
+ version: "4.1.0-alpha.14",
8006
8097
  options: Object.assign({}, DEFAULT_OPTIONS),
8007
8098
  schema: null,
8008
8099
  get currentUserId() {
@@ -8304,7 +8395,7 @@ function dexieCloud(dexie) {
8304
8395
  }
8305
8396
  }
8306
8397
  // @ts-ignore
8307
- dexieCloud.version = "4.1.0-alpha.12";
8398
+ dexieCloud.version = "4.1.0-alpha.14";
8308
8399
  Dexie.Cloud = dexieCloud;
8309
8400
 
8310
8401
  const ydocTriggers = {};
@@ -8328,8 +8419,8 @@ const createMiddleware = (db) => ({
8328
8419
  return Object.assign(Object.assign({}, coreTable), { mutate(req) {
8329
8420
  switch (req.type) {
8330
8421
  case 'add': {
8331
- for (const obj of req.values) {
8332
- const primaryKey = coreTable.schema.primaryKey.extractKey(obj);
8422
+ for (const yUpdateRow of req.values) {
8423
+ const primaryKey = yUpdateRow.k;
8333
8424
  const doc = DexieYProvider.getDocCache(db).find(parentTable, primaryKey, prop);
8334
8425
  if (doc) {
8335
8426
  if (!docIsAlreadyHooked.has(doc)) {
@@ -8338,7 +8429,7 @@ const createMiddleware = (db) => ({
8338
8429
  }
8339
8430
  }
8340
8431
  else {
8341
- enqueueTrigger(tblName, primaryKey, trigger);
8432
+ enqueueTrigger(db, tblName, primaryKey, trigger);
8342
8433
  }
8343
8434
  }
8344
8435
  break;
@@ -8361,7 +8452,7 @@ const createMiddleware = (db) => ({
8361
8452
  keySet.addKey(k);
8362
8453
  }
8363
8454
  for (const key of keySet) {
8364
- enqueueTrigger(tblName, key, trigger);
8455
+ enqueueTrigger(db, tblName, key, trigger);
8365
8456
  }
8366
8457
  });
8367
8458
  }
@@ -8403,11 +8494,12 @@ function executeTriggers(triggersToRun) {
8403
8494
  }
8404
8495
  });
8405
8496
  }
8406
- function enqueueTrigger(updatesTable, parentId, trigger) {
8407
- var _a;
8408
- ((_a = scheduledTriggers[updatesTable]) !== null && _a !== void 0 ? _a : (scheduledTriggers[updatesTable] = [])).push({
8497
+ function enqueueTrigger(db, updatesTable, parentId, trigger) {
8498
+ scheduledTriggers.push({
8499
+ db,
8409
8500
  parentId,
8410
8501
  trigger,
8502
+ updatesTable
8411
8503
  });
8412
8504
  }
8413
8505
  function onTransactionCommitted() {