cry-synced-db-client 0.1.33 → 0.1.34

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
@@ -1583,7 +1583,7 @@ class SyncedDb {
1583
1583
  case "insert": {
1584
1584
  const serverItem = payload.data;
1585
1585
  if (serverItem) {
1586
- await this.handleServerItemUpdate(collectionName, serverItem);
1586
+ await this.handleServerItemInsert(collectionName, serverItem);
1587
1587
  if (serverItem._ts) {
1588
1588
  await this.broadcastMetaUpdate(collectionName, serverItem._ts);
1589
1589
  }
@@ -1595,7 +1595,7 @@ class SyncedDb {
1595
1595
  if (deltaData && deltaData._id) {
1596
1596
  const localItem = await this.dexieDb.getById(collectionName, deltaData._id);
1597
1597
  if (localItem) {
1598
- await this.handleServerItemUpdate(collectionName, deltaData);
1598
+ await this.handleServerItemUpdate(collectionName, localItem, deltaData);
1599
1599
  if (deltaData._ts) {
1600
1600
  await this.broadcastMetaUpdate(collectionName, deltaData._ts);
1601
1601
  }
@@ -1603,7 +1603,7 @@ class SyncedDb {
1603
1603
  const items = await this.restInterface.findNewer(collectionName, 0, { _id: deltaData._id });
1604
1604
  const fullItem = items[0];
1605
1605
  if (fullItem) {
1606
- await this.handleServerItemUpdate(collectionName, fullItem);
1606
+ await this.handleServerItemInsert(collectionName, fullItem);
1607
1607
  if (fullItem._ts) {
1608
1608
  await this.broadcastMetaUpdate(collectionName, fullItem._ts);
1609
1609
  }
@@ -1623,19 +1623,19 @@ class SyncedDb {
1623
1623
  if (item.operation === "insert") {
1624
1624
  const serverItem = item.data;
1625
1625
  if (serverItem) {
1626
- await this.handleServerItemUpdate(collectionName, serverItem);
1626
+ await this.handleServerItemInsert(collectionName, serverItem);
1627
1627
  }
1628
1628
  } else if (item.operation === "update") {
1629
1629
  const deltaData = item.data;
1630
1630
  if (deltaData && deltaData._id) {
1631
1631
  const localItem = await this.dexieDb.getById(collectionName, deltaData._id);
1632
1632
  if (localItem) {
1633
- await this.handleServerItemUpdate(collectionName, deltaData);
1633
+ await this.handleServerItemUpdate(collectionName, localItem, deltaData);
1634
1634
  } else {
1635
1635
  const items = await this.restInterface.findNewer(collectionName, 0, { _id: deltaData._id });
1636
1636
  const fullItem = items[0];
1637
1637
  if (fullItem) {
1638
- await this.handleServerItemUpdate(collectionName, fullItem);
1638
+ await this.handleServerItemInsert(collectionName, fullItem);
1639
1639
  }
1640
1640
  }
1641
1641
  }
@@ -1651,61 +1651,69 @@ class SyncedDb {
1651
1651
  }
1652
1652
  }
1653
1653
  }
1654
- async handleServerItemUpdate(collectionName, serverItem) {
1654
+ async handleServerItemInsert(collectionName, serverItem) {
1655
1655
  const localItem = await this.dexieDb.getById(collectionName, serverItem._id);
1656
- const pendingKey = this.getPendingKey(collectionName, serverItem._id);
1656
+ if (localItem) {
1657
+ await this.dexieDb.save(collectionName, serverItem._id, {
1658
+ _rev: serverItem._rev,
1659
+ _ts: serverItem._ts,
1660
+ _dirty: false
1661
+ });
1662
+ } else {
1663
+ await this.dexieDb.insert(collectionName, {
1664
+ ...serverItem,
1665
+ _dirty: false
1666
+ });
1667
+ if (!serverItem._deleted) {
1668
+ this.inMemDb.insert(collectionName, this.stripLocalFields(serverItem));
1669
+ }
1670
+ }
1671
+ }
1672
+ async handleServerItemUpdate(collectionName, localItem, serverDelta) {
1673
+ const isLoopback = serverDelta._lastUpdaterId === this.updaterId && serverDelta._rev !== undefined && localItem._rev !== undefined && serverDelta._rev === localItem._rev + 1;
1674
+ if (isLoopback) {
1675
+ await this.dexieDb.save(collectionName, serverDelta._id, {
1676
+ _rev: serverDelta._rev,
1677
+ _ts: serverDelta._ts,
1678
+ _dirty: false
1679
+ });
1680
+ return;
1681
+ }
1682
+ const pendingKey = this.getPendingKey(collectionName, serverDelta._id);
1657
1683
  const pendingChange = this.pendingChanges.get(pendingKey);
1658
- const hasPendingChanges = !!pendingChange;
1659
- if (hasPendingChanges) {
1660
- const currentMemItem = this.inMemDb.getById(collectionName, serverItem._id);
1684
+ if (pendingChange) {
1685
+ const currentMemItem = this.inMemDb.getById(collectionName, serverDelta._id);
1661
1686
  if (currentMemItem) {
1662
- const merged = this.mergeLocalWithDelta(currentMemItem, serverItem);
1687
+ const merged = this.mergeLocalWithDelta(currentMemItem, serverDelta);
1663
1688
  if (!merged._deleted) {
1664
- this.inMemDb.save(collectionName, serverItem._id, this.stripLocalFields(merged));
1689
+ this.inMemDb.save(collectionName, serverDelta._id, this.stripLocalFields(merged));
1665
1690
  }
1666
1691
  pendingChange.data = {
1667
1692
  ...pendingChange.data,
1668
- ...this.getNewFieldsFromServer(currentMemItem, serverItem)
1693
+ ...this.getNewFieldsFromServer(currentMemItem, serverDelta)
1669
1694
  };
1670
1695
  }
1671
1696
  return;
1672
1697
  }
1673
- if (localItem) {
1674
- if (serverItem._lastUpdaterId === this.updaterId && serverItem._rev !== undefined && localItem._rev !== undefined && serverItem._rev === localItem._rev + 1) {
1675
- await this.dexieDb.save(collectionName, serverItem._id, {
1676
- _rev: serverItem._rev,
1677
- _ts: serverItem._ts,
1678
- _dirty: false
1679
- });
1680
- return;
1681
- }
1682
- if (localItem._dirty) {
1683
- const merged = this.mergeLocalWithDelta(localItem, serverItem);
1684
- await this.dexieDb.save(collectionName, serverItem._id, {
1685
- ...merged,
1686
- _dirty: true
1687
- });
1688
- if (!merged._deleted) {
1689
- this.inMemDb.save(collectionName, serverItem._id, this.stripLocalFields(merged));
1690
- }
1691
- } else {
1692
- await this.dexieDb.save(collectionName, serverItem._id, {
1693
- ...serverItem,
1694
- _dirty: false
1695
- });
1696
- if (!serverItem._deleted) {
1697
- this.inMemDb.save(collectionName, serverItem._id, this.stripLocalFields(serverItem));
1698
- } else {
1699
- this.inMemDb.deleteOne(collectionName, serverItem._id);
1700
- }
1698
+ if (localItem._dirty) {
1699
+ const merged = this.mergeLocalWithDelta(localItem, serverDelta);
1700
+ await this.dexieDb.save(collectionName, serverDelta._id, {
1701
+ ...merged,
1702
+ _dirty: true
1703
+ });
1704
+ if (!merged._deleted) {
1705
+ this.inMemDb.save(collectionName, serverDelta._id, this.stripLocalFields(merged));
1701
1706
  }
1702
1707
  } else {
1703
- await this.dexieDb.insert(collectionName, {
1704
- ...serverItem,
1708
+ const merged = this.mergeLocalWithDelta(localItem, serverDelta);
1709
+ await this.dexieDb.save(collectionName, serverDelta._id, {
1710
+ ...merged,
1705
1711
  _dirty: false
1706
1712
  });
1707
- if (!serverItem._deleted) {
1708
- this.inMemDb.insert(collectionName, this.stripLocalFields(serverItem));
1713
+ if (!merged._deleted) {
1714
+ this.inMemDb.save(collectionName, serverDelta._id, this.stripLocalFields(merged));
1715
+ } else {
1716
+ this.inMemDb.deleteOne(collectionName, serverDelta._id);
1709
1717
  }
1710
1718
  }
1711
1719
  }
@@ -199,6 +199,16 @@ export declare class SyncedDb implements I_SyncedDb {
199
199
  */
200
200
  private handleCrossTabMetaUpdate;
201
201
  private handleServerUpdate;
202
+ /**
203
+ * Handle server insert notification.
204
+ * Insert notifications contain full object data.
205
+ */
206
+ private handleServerItemInsert;
207
+ /**
208
+ * Handle server update notification (delta).
209
+ * Update notifications contain only changed fields.
210
+ * Caller must provide the existing local item.
211
+ */
202
212
  private handleServerItemUpdate;
203
213
  private getNewFieldsFromServer;
204
214
  /**
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Test constants for faster test execution
3
+ */
4
+ /** Debounce time for tests (ms) - much shorter than production default of 1000ms */
5
+ export declare const TEST_DEBOUNCE_MS = 5;
6
+ /** Helper to get wait time for debounce (1.2x debounce time) */
7
+ export declare const getDebounceWaitMs: (debounceMs?: number) => number;
8
+ /** REST endpoint for real-life proxy tests */
9
+ export declare const REST_ENDPOINT = "http://localhost:3002";
10
+ /** Test tenant name for RestProxy tests */
11
+ export declare const TEST_TENANT = "test";
12
+ /** API key for RestProxy tests */
13
+ export declare const API_KEY = "1234";
14
+ /** WebSocket URL for ebus-proxy tests */
15
+ export declare const EBUS_PROXY_WS_URL = "ws://localhost:3033";
16
+ /** API key for ebus-proxy tests */
17
+ export declare const EBUS_PROXY_API_KEY = "123";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cry-synced-db-client",
3
- "version": "0.1.33",
3
+ "version": "0.1.34",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes