@powerhousedao/connect 1.0.8 → 1.0.10-dev.0

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.
Files changed (40) hide show
  1. package/LICENSE +661 -0
  2. package/dist/.env +0 -5
  3. package/dist/assets/{app-D3TxLTK-.css → app-BIIVKAZr.css} +241 -60
  4. package/dist/assets/{app-Bw1Ba-jV.js → app-CsiwsM42.js} +2262 -1224
  5. package/dist/assets/{app-loader-KTD3Q6e9.js → app-loader-C7A2YjX4.js} +876 -577
  6. package/dist/assets/{app-loader-CjrEwupY.css → app-loader-pcztQTL4.css} +189 -26
  7. package/dist/assets/{ccip-D3HujWHr.js → ccip-BG1d6viz.js} +3 -3
  8. package/dist/assets/{content-D3TuBhK9.js → content-0UFgs2d1.js} +37 -7
  9. package/dist/assets/{index-DpasqVlD.js → index-BMDqhr-9.js} +3 -3
  10. package/dist/assets/{index-DsNVpRhT.js → index-CTEGX1We.js} +670 -519
  11. package/dist/assets/{index-yFk8X8m1.js → index-yr0-SqYf.js} +4 -4
  12. package/dist/assets/{main.CzEw2R-H.js → main.BmcV9296.js} +1 -1
  13. package/dist/assets/{style-D4JhTt_m.css → style-Ce3V83BE.css} +31 -36
  14. package/dist/external-packages.js +5 -0
  15. package/dist/hmr.js +4 -1
  16. package/dist/index.html +1 -4
  17. package/dist/modules/@powerhousedao/reactor-browser/{chunk-G6LMXRY5.js → chunk-2ONJ2PX4.js} +1 -1
  18. package/dist/modules/@powerhousedao/reactor-browser/{chunk-P46ZMPJ3.js → chunk-3C54663M.js} +1 -1
  19. package/dist/modules/@powerhousedao/reactor-browser/{chunk-6AXML2S3.js → chunk-5QJXNK35.js} +1 -1
  20. package/dist/modules/@powerhousedao/reactor-browser/{chunk-FW7N6EJH.js → chunk-C7QRY43M.js} +3 -3
  21. package/dist/modules/@powerhousedao/reactor-browser/{chunk-45DCPCA7.js → chunk-CO2RVWYY.js} +1 -1
  22. package/dist/modules/@powerhousedao/reactor-browser/{chunk-POMUCSTC.js → chunk-ISDEPHKP.js} +74 -20
  23. package/dist/modules/@powerhousedao/reactor-browser/{chunk-F3RCGUF6.js → chunk-NHD6VUCD.js} +2 -2
  24. package/dist/modules/@powerhousedao/reactor-browser/{chunk-YOX3ZAET.js → chunk-SQ5HIKYV.js} +581 -334
  25. package/dist/modules/@powerhousedao/reactor-browser/{chunk-M2UUQ5LH.js → chunk-U34SEKEB.js} +2 -2
  26. package/dist/modules/@powerhousedao/reactor-browser/{chunk-4LZZ55AN.js → chunk-XV42KZK3.js} +1 -1
  27. package/dist/modules/@powerhousedao/reactor-browser/context/index.js +2 -2
  28. package/dist/modules/@powerhousedao/reactor-browser/context/read-mode.js +2 -2
  29. package/dist/modules/@powerhousedao/reactor-browser/hooks/index.js +8 -8
  30. package/dist/modules/@powerhousedao/reactor-browser/hooks/useAddDebouncedOperations.js +3 -3
  31. package/dist/modules/@powerhousedao/reactor-browser/hooks/useConnectCrypto.js +2 -2
  32. package/dist/modules/@powerhousedao/reactor-browser/hooks/useDocumentDrives.js +2 -2
  33. package/dist/modules/@powerhousedao/reactor-browser/hooks/useDocumentEditor.js +5 -5
  34. package/dist/modules/@powerhousedao/reactor-browser/hooks/useDriveActions.js +2 -2
  35. package/dist/modules/@powerhousedao/reactor-browser/hooks/useDriveActionsWithUiNodes.js +3 -3
  36. package/dist/modules/@powerhousedao/reactor-browser/index.js +10 -10
  37. package/dist/modules/@powerhousedao/reactor-browser/reactor.js +2 -2
  38. package/dist/swEnv.js +0 -3
  39. package/dist/vite-envs.sh +1 -28
  40. package/package.json +9 -9
@@ -688,30 +688,79 @@ var require_lib = __commonJS({
688
688
  }
689
689
  });
690
690
 
691
+ // ../../packages/document-drive/dist/src/cache/util.js
692
+ var trimResultingState = (document) => {
693
+ const global2 = document.operations.global.map((e) => {
694
+ delete e.resultingState;
695
+ return e;
696
+ });
697
+ const local = document.operations.local.map((e) => {
698
+ delete e.resultingState;
699
+ return e;
700
+ });
701
+ return { ...document, operations: { global: global2, local } };
702
+ };
703
+
691
704
  // ../../packages/document-drive/dist/src/cache/memory.js
692
705
  var InMemoryCache = class {
693
- cache = /* @__PURE__ */ new Map();
694
- async setDocument(drive, id, document) {
695
- const global2 = document.operations.global.map((e) => {
696
- delete e.resultingState;
697
- return e;
698
- });
699
- const local = document.operations.local.map((e) => {
700
- delete e.resultingState;
701
- return e;
702
- });
703
- const doc = { ...document, operations: { global: global2, local } };
704
- if (!this.cache.has(drive)) {
705
- this.cache.set(drive, /* @__PURE__ */ new Map());
706
+ idTodocument = /* @__PURE__ */ new Map();
707
+ idToDrive = /* @__PURE__ */ new Map();
708
+ slugToDriveId = /* @__PURE__ */ new Map();
709
+ clear() {
710
+ this.idTodocument.clear();
711
+ this.idToDrive.clear();
712
+ this.slugToDriveId.clear();
713
+ }
714
+ /////////////////////////////////////////////////////////////////////////////
715
+ // ICache
716
+ /////////////////////////////////////////////////////////////////////////////
717
+ async setDocument(documentId, document) {
718
+ const doc = trimResultingState(document);
719
+ this.idTodocument.set(documentId, doc);
720
+ }
721
+ async getDocument(documentId) {
722
+ return this.idTodocument.get(documentId);
723
+ }
724
+ async deleteDocument(documentId) {
725
+ return this.idTodocument.delete(documentId);
726
+ }
727
+ async setDrive(driveId, drive) {
728
+ const doc = trimResultingState(drive);
729
+ this.idToDrive.set(driveId, doc);
730
+ }
731
+ async getDrive(driveId) {
732
+ return this.idToDrive.get(driveId);
733
+ }
734
+ async deleteDrive(driveId) {
735
+ const drive = this.idToDrive.get(driveId);
736
+ if (!drive) {
737
+ return false;
706
738
  }
707
- this.cache.get(drive)?.set(id, doc);
708
- return true;
739
+ const slug = drive.state.global.slug;
740
+ if (slug) {
741
+ this.slugToDriveId.delete(slug);
742
+ }
743
+ return this.idToDrive.delete(driveId);
709
744
  }
710
- async deleteDocument(drive, id) {
711
- return this.cache.get(drive)?.delete(id) ?? false;
745
+ async setDriveBySlug(slug, drive) {
746
+ const driveId = drive.state.global.id;
747
+ this.slugToDriveId.set(slug, driveId);
748
+ this.setDrive(driveId, drive);
712
749
  }
713
- async getDocument(drive, id) {
714
- return this.cache.get(drive)?.get(id);
750
+ async getDriveBySlug(slug) {
751
+ const driveId = this.slugToDriveId.get(slug);
752
+ if (!driveId) {
753
+ return void 0;
754
+ }
755
+ return this.getDrive(driveId);
756
+ }
757
+ async deleteDriveBySlug(slug) {
758
+ const driveId = this.slugToDriveId.get(slug);
759
+ if (!driveId) {
760
+ return false;
761
+ }
762
+ this.slugToDriveId.delete(slug);
763
+ return this.deleteDrive(driveId);
715
764
  }
716
765
  };
717
766
  var memory_default = InMemoryCache;
@@ -1652,19 +1701,16 @@ var ReadDocumentNotFoundError = class extends ReadDriveError {
1652
1701
  // ../../packages/document-drive/dist/src/storage/memory.js
1653
1702
  var MemoryStorage = class {
1654
1703
  documents;
1655
- drives;
1656
1704
  driveManifests;
1657
- slugToDriveId = {};
1658
1705
  constructor() {
1659
1706
  this.documents = {};
1660
- this.drives = {};
1661
1707
  this.driveManifests = {};
1662
1708
  }
1663
1709
  ////////////////////////////////
1664
1710
  // IDocumentStorage
1665
1711
  ////////////////////////////////
1666
1712
  exists(documentId) {
1667
- return Promise.resolve(!!this.documents[documentId]);
1713
+ return Promise.resolve(!!this.documents[documentId] || !!this.documents[`drive/${documentId}`]);
1668
1714
  }
1669
1715
  create(documentId, document) {
1670
1716
  this.documents[documentId] = document;
@@ -1673,10 +1719,52 @@ var MemoryStorage = class {
1673
1719
  get(documentId) {
1674
1720
  const document = this.documents[documentId];
1675
1721
  if (!document) {
1722
+ const drive = this.documents[`drive/${documentId}`];
1723
+ if (drive) {
1724
+ return Promise.resolve(drive);
1725
+ }
1676
1726
  throw new Error(`Document with id ${documentId} not found`);
1677
1727
  }
1678
1728
  return Promise.resolve(document);
1679
1729
  }
1730
+ async delete(documentId) {
1731
+ const drives = await this.getDrives();
1732
+ for (const driveId of drives) {
1733
+ if (driveId === documentId)
1734
+ continue;
1735
+ await this.removeChild(driveId, documentId);
1736
+ }
1737
+ delete this.driveManifests[documentId];
1738
+ if (this.documents[documentId]) {
1739
+ delete this.documents[documentId];
1740
+ return Promise.resolve(true);
1741
+ }
1742
+ return Promise.resolve(false);
1743
+ }
1744
+ async addChild(parentId, childId) {
1745
+ if (parentId === childId) {
1746
+ throw new Error("Cannot associate a document with itself");
1747
+ }
1748
+ const children = await this.getChildren(childId);
1749
+ if (children.includes(parentId)) {
1750
+ throw new Error("Cannot associate a document with its child");
1751
+ }
1752
+ const manifest = this.getManifest(parentId);
1753
+ manifest.documentIds.add(childId);
1754
+ this.updateDriveManifest(parentId, manifest);
1755
+ }
1756
+ async removeChild(parentId, childId) {
1757
+ const manifest = this.getManifest(parentId);
1758
+ if (manifest.documentIds.delete(childId)) {
1759
+ this.updateDriveManifest(parentId, manifest);
1760
+ return true;
1761
+ }
1762
+ return false;
1763
+ }
1764
+ async getChildren(parentId) {
1765
+ const manifest = this.getManifest(parentId);
1766
+ return [...manifest.documentIds];
1767
+ }
1680
1768
  ////////////////////////////////
1681
1769
  // IDriveStorage
1682
1770
  ////////////////////////////////
@@ -1684,27 +1772,19 @@ var MemoryStorage = class {
1684
1772
  return this.exists(id);
1685
1773
  }
1686
1774
  getDocuments(drive) {
1687
- const manifest = this.getDriveManifest(drive);
1775
+ const manifest = this.getManifest(drive);
1688
1776
  return Promise.resolve([...manifest.documentIds]);
1689
1777
  }
1690
1778
  getDocument(driveId, id) {
1691
1779
  return this.get(id);
1692
1780
  }
1693
- async saveDocument(drive, id, document) {
1694
- this.documents[id] = document;
1695
- const manifest = this.getDriveManifest(drive);
1696
- manifest.documentIds.add(id);
1697
- this.updateDriveManifest(drive, manifest);
1698
- }
1699
1781
  async clearStorage() {
1700
1782
  this.documents = {};
1701
- this.drives = {};
1702
1783
  this.driveManifests = {};
1703
- this.slugToDriveId = {};
1704
1784
  }
1705
1785
  async createDocument(drive, id, document) {
1706
1786
  await this.create(id, document);
1707
- const manifest = this.getDriveManifest(drive);
1787
+ const manifest = this.getManifest(drive);
1708
1788
  manifest.documentIds.add(id);
1709
1789
  this.updateDriveManifest(drive, manifest);
1710
1790
  }
@@ -1721,59 +1801,60 @@ var MemoryStorage = class {
1721
1801
  };
1722
1802
  }
1723
1803
  async deleteDocument(drive, id) {
1724
- const drives = await this.getDrives();
1725
- for (const driveId of drives) {
1726
- const manifest = this.getDriveManifest(driveId);
1727
- if (manifest.documentIds.has(id)) {
1728
- manifest.documentIds.delete(id);
1729
- this.updateDriveManifest(driveId, manifest);
1730
- }
1731
- }
1732
- delete this.documents[id];
1804
+ this.delete(id);
1733
1805
  }
1734
1806
  async getDrives() {
1735
- return Object.keys(this.drives);
1807
+ return Object.keys(this.driveManifests);
1736
1808
  }
1737
1809
  async getDrive(id) {
1738
- const drive = this.drives[id];
1810
+ const drive = this.documents[`drive/${id}`];
1739
1811
  if (!drive) {
1740
1812
  throw new DriveNotFoundError(id);
1741
1813
  }
1742
1814
  return drive;
1743
1815
  }
1744
1816
  async getDriveBySlug(slug) {
1745
- const driveId = this.slugToDriveId[slug];
1746
- if (!driveId) {
1747
- throw new Error(`Drive with slug ${slug} not found`);
1817
+ for (const driveId of Object.keys(this.driveManifests)) {
1818
+ const drive = this.documents[`drive/${driveId}`];
1819
+ if (drive.initialState.state.global.slug === slug) {
1820
+ return drive;
1821
+ }
1748
1822
  }
1749
- return this.getDrive(driveId);
1823
+ throw new Error(`Drive with slug ${slug} not found`);
1750
1824
  }
1751
1825
  async createDrive(id, drive) {
1752
- this.drives[id] = drive;
1753
- this.updateDriveManifest(id, { documentIds: /* @__PURE__ */ new Set() });
1754
- const { slug } = drive.initialState.state.global;
1826
+ const slug = drive.initialState.state.global.slug;
1755
1827
  if (slug) {
1756
- this.slugToDriveId[slug] = id;
1828
+ let existingDrive;
1829
+ try {
1830
+ existingDrive = await this.getDriveBySlug(slug);
1831
+ } catch {
1832
+ }
1833
+ if (existingDrive) {
1834
+ throw new Error(`Drive with slug ${slug} already exists`);
1835
+ }
1757
1836
  }
1837
+ await this.create(`drive/${id}`, drive);
1838
+ this.updateDriveManifest(id, { documentIds: /* @__PURE__ */ new Set() });
1758
1839
  }
1759
1840
  async addDriveOperations(id, operations, header) {
1760
1841
  const drive = await this.getDrive(id);
1761
1842
  const mergedOperations = mergeOperations(drive.operations, operations);
1762
- this.drives[id] = {
1843
+ this.documents[`drive/${id}`] = {
1763
1844
  ...drive,
1764
1845
  ...header,
1765
1846
  operations: mergedOperations
1766
1847
  };
1767
1848
  }
1768
1849
  async deleteDrive(id) {
1769
- const manifest = this.getDriveManifest(id);
1850
+ const manifest = this.getManifest(id);
1770
1851
  const drives = await this.getDrives();
1771
1852
  await Promise.all([...manifest.documentIds].map((docId) => {
1772
1853
  for (const driveId of drives) {
1773
1854
  if (driveId === id) {
1774
1855
  continue;
1775
1856
  }
1776
- const manifest2 = this.getDriveManifest(driveId);
1857
+ const manifest2 = this.getManifest(driveId);
1777
1858
  if (manifest2.documentIds.has(docId)) {
1778
1859
  return;
1779
1860
  }
@@ -1781,24 +1862,18 @@ var MemoryStorage = class {
1781
1862
  delete this.documents[docId];
1782
1863
  }));
1783
1864
  delete this.driveManifests[id];
1784
- delete this.drives[id];
1785
- for (const [slug, driveId] of Object.entries(this.slugToDriveId)) {
1786
- if (driveId === id) {
1787
- delete this.slugToDriveId[slug];
1788
- }
1789
- }
1865
+ delete this.documents[id];
1790
1866
  }
1791
1867
  async getSynchronizationUnitsRevision(units) {
1792
1868
  const results = await Promise.allSettled(units.map(async (unit) => {
1793
1869
  try {
1794
- const document = await (unit.documentId ? this.getDocument(unit.driveId, unit.documentId) : this.getDrive(unit.driveId));
1870
+ const document = await this.get(unit.documentId);
1795
1871
  if (!document) {
1796
1872
  return void 0;
1797
1873
  }
1798
1874
  const operation = document.operations[unit.scope].at(-1);
1799
1875
  if (operation) {
1800
1876
  return {
1801
- driveId: unit.driveId,
1802
1877
  documentId: unit.documentId,
1803
1878
  scope: unit.scope,
1804
1879
  branch: unit.branch,
@@ -1820,7 +1895,7 @@ var MemoryStorage = class {
1820
1895
  ////////////////////////////////
1821
1896
  // Private
1822
1897
  ////////////////////////////////
1823
- getDriveManifest(driveId) {
1898
+ getManifest(driveId) {
1824
1899
  if (!this.driveManifests[driveId]) {
1825
1900
  this.driveManifests[driveId] = { documentIds: /* @__PURE__ */ new Set() };
1826
1901
  }
@@ -11823,11 +11898,14 @@ var PULL_DRIVE_INTERVAL = 1500;
11823
11898
 
11824
11899
  // ../../packages/document-drive/dist/src/server/listener/transmitter/pull-responder.js
11825
11900
  var MAX_REVISIONS_PER_ACK = 100;
11901
+ var _staticLogger;
11902
+ var staticLogger = () => {
11903
+ if (!_staticLogger) {
11904
+ _staticLogger = childLogger(["PullResponderTransmitter", "static"]);
11905
+ }
11906
+ return _staticLogger;
11907
+ };
11826
11908
  var PullResponderTransmitter = class _PullResponderTransmitter {
11827
- static staticLogger = childLogger([
11828
- "PullResponderTransmitter",
11829
- "static"
11830
- ]);
11831
11909
  logger = childLogger([
11832
11910
  "PullResponderTransmitter",
11833
11911
  Math.floor(Math.random() * 999).toString()
@@ -11840,8 +11918,18 @@ var PullResponderTransmitter = class _PullResponderTransmitter {
11840
11918
  this.logger.verbose(`constructor(listener: ${listener.listenerId})`);
11841
11919
  }
11842
11920
  getStrands(options) {
11843
- this.logger.verbose(`getStrands(drive: ${this.listener.driveId}, listener: ${this.listener.listenerId})`);
11844
- return this.manager.getStrands(this.listener.driveId, this.listener.listenerId, options);
11921
+ this.logger.verbose(`[SYNC DEBUG] PullResponderTransmitter.getStrands called for drive: ${this.listener.driveId}, listener: ${this.listener.listenerId}, options: ${JSON.stringify(options || {})}`);
11922
+ return this.manager.getStrands(this.listener.driveId, this.listener.listenerId, options).then((strands) => {
11923
+ this.logger.verbose(`[SYNC DEBUG] PullResponderTransmitter.getStrands returning ${strands.length} strands for drive: ${this.listener.driveId}, listener: ${this.listener.listenerId}`);
11924
+ if (strands.length === 0) {
11925
+ this.logger.verbose(`[SYNC DEBUG] No strands returned for drive: ${this.listener.driveId}, listener: ${this.listener.listenerId}`);
11926
+ } else {
11927
+ for (const strand of strands) {
11928
+ this.logger.verbose(`[SYNC DEBUG] Strand for drive: ${strand.driveId}, document: ${strand.documentId}, scope: ${strand.scope}, operations: ${strand.operations.length}`);
11929
+ }
11930
+ }
11931
+ return strands;
11932
+ });
11845
11933
  }
11846
11934
  disconnect() {
11847
11935
  return Promise.resolve();
@@ -11851,7 +11939,7 @@ var PullResponderTransmitter = class _PullResponderTransmitter {
11851
11939
  const syncUnits = await this.manager.getListenerSyncUnitIds(driveId, listenerId);
11852
11940
  let success = true;
11853
11941
  for (const revision of revisions) {
11854
- const syncUnit = syncUnits.find((s) => s.scope === revision.scope && s.branch === revision.branch && s.driveId === revision.driveId && s.documentId == revision.documentId);
11942
+ const syncUnit = syncUnits.find((s) => s.scope === revision.scope && s.branch === revision.branch && s.documentId == revision.documentId);
11855
11943
  if (!syncUnit) {
11856
11944
  this.logger.warn("Unknown sync unit was acknowledged", revision);
11857
11945
  success = false;
@@ -11861,15 +11949,21 @@ var PullResponderTransmitter = class _PullResponderTransmitter {
11861
11949
  }
11862
11950
  return success;
11863
11951
  }
11864
- static async registerPullResponder(driveId, url, filter) {
11865
- _PullResponderTransmitter.staticLogger.verbose(`registerPullResponder(url: ${url})`, filter);
11952
+ static async registerPullResponder(driveId, url, filter, listenerId) {
11953
+ staticLogger().verbose(`registerPullResponder(url: ${url})`, filter);
11866
11954
  const result = await requestGraphql(url, gql`
11867
- mutation registerPullResponderListener($filter: InputListenerFilter!) {
11868
- registerPullResponderListener(filter: $filter) {
11955
+ mutation registerPullResponderListener(
11956
+ $filter: InputListenerFilter!
11957
+ $listenerId: String
11958
+ ) {
11959
+ registerPullResponderListener(
11960
+ filter: $filter
11961
+ listenerId: $listenerId
11962
+ ) {
11869
11963
  listenerId
11870
11964
  }
11871
11965
  }
11872
- `, { filter });
11966
+ `, { filter, listenerId });
11873
11967
  const error = result.errors?.at(0);
11874
11968
  if (error) {
11875
11969
  throw error;
@@ -11880,7 +11974,7 @@ var PullResponderTransmitter = class _PullResponderTransmitter {
11880
11974
  return result.registerPullResponderListener.listenerId;
11881
11975
  }
11882
11976
  static async pullStrands(driveId, url, listenerId, options) {
11883
- this.staticLogger.verbose(`pullStrands(url: ${url}, listener: ${listenerId})`);
11977
+ staticLogger().verbose(`[SYNC DEBUG] PullResponderTransmitter.pullStrands called for drive: ${driveId}, url: ${url}, listener: ${listenerId}, options: ${JSON.stringify(options || {})}`);
11884
11978
  const result = await requestGraphql(url, gql`
11885
11979
  query strands($listenerId: ID!) {
11886
11980
  system {
@@ -11920,27 +12014,34 @@ var PullResponderTransmitter = class _PullResponderTransmitter {
11920
12014
  `, { listenerId });
11921
12015
  const error = result.errors?.at(0);
11922
12016
  if (error) {
12017
+ staticLogger().verbose(`[SYNC DEBUG] Error pulling strands for drive: ${driveId}, listener: ${listenerId}, error: ${JSON.stringify(error)}`);
11923
12018
  throw error;
11924
12019
  }
11925
12020
  if (!result.system) {
12021
+ staticLogger().verbose(`[SYNC DEBUG] No system data returned when pulling strands for drive: ${driveId}, listener: ${listenerId}`);
11926
12022
  return [];
11927
12023
  }
11928
- return result.system.sync.strands.map((s) => ({
12024
+ const strands = result.system.sync.strands.map((s) => ({
11929
12025
  ...s,
11930
12026
  operations: s.operations.map((o) => ({
11931
12027
  ...o,
11932
12028
  input: JSON.parse(o.input)
11933
12029
  }))
11934
12030
  }));
12031
+ staticLogger().verbose(`[SYNC DEBUG] PullResponderTransmitter.pullStrands returning ${strands.length} strands for drive: ${driveId}, listener: ${listenerId}`);
12032
+ if (strands.length > 0) {
12033
+ staticLogger().verbose(`[SYNC DEBUG] Strands being returned: ${strands.map((s) => `${s.documentId}:${s.scope}`).join(", ")}`);
12034
+ }
12035
+ return strands;
11935
12036
  }
11936
12037
  static async acknowledgeStrands(url, listenerId, revisions) {
11937
- this.staticLogger.verbose(`acknowledgeStrands(url: ${url}, listener: ${listenerId})`, revisions);
12038
+ staticLogger().verbose(`acknowledgeStrands(url: ${url}, listener: ${listenerId})`, revisions);
11938
12039
  const chunks = [];
11939
12040
  for (let i = 0; i < revisions.length; i += MAX_REVISIONS_PER_ACK) {
11940
12041
  chunks.push(revisions.slice(i, i + MAX_REVISIONS_PER_ACK));
11941
12042
  }
11942
12043
  if (chunks.length > 1) {
11943
- this.staticLogger.verbose(`Breaking strand acknowledgement into ${chunks.length} chunks...`);
12044
+ staticLogger().verbose(`Breaking strand acknowledgement into ${chunks.length} chunks...`);
11944
12045
  }
11945
12046
  const results = await Promise.allSettled(chunks.map(async (chunk) => {
11946
12047
  const result = await requestGraphql(url, gql`
@@ -11964,74 +12065,124 @@ var PullResponderTransmitter = class _PullResponderTransmitter {
11964
12065
  throw new Error("Error acknowledging strands");
11965
12066
  }
11966
12067
  }
12068
+ /**
12069
+ * This function will only throw if `onError` throws an error (or there is
12070
+ * an unintentionally unhandled error in the pull loop).
12071
+ *
12072
+ * All other errors are caught, logged, and passed to `onError`.
12073
+ *
12074
+ * Because of this, `onError` _may be called multiple times_.
12075
+ */
11967
12076
  static async executePull(driveId, trigger, onStrandUpdate, onError, onRevisions, onAcknowledge) {
11968
- this.staticLogger.verbose(`executePull(driveId: ${driveId}), trigger:`, trigger);
12077
+ staticLogger().verbose(`executePull(driveId: ${driveId}), trigger:`, trigger);
12078
+ staticLogger().info(`[SYNC DEBUG] PullResponderTransmitter.executePull starting for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
12079
+ const { url } = trigger.data;
12080
+ let strands;
12081
+ let error;
12082
+ const listenerId = trigger.data.listenerId;
11969
12083
  try {
11970
- const { url, listenerId } = trigger.data;
11971
- const strands = await _PullResponderTransmitter.pullStrands(driveId, url, listenerId);
11972
- this.staticLogger.verbose("Pulled strands...");
11973
- if (!strands.length) {
11974
- onRevisions?.([]);
11975
- this.staticLogger.verbose("No new strands, skipping...");
11976
- return;
11977
- }
11978
- const listenerRevisions = [];
11979
- for (const strand of strands) {
11980
- const operations = strand.operations.map((op) => ({
11981
- ...op,
11982
- scope: strand.scope,
11983
- branch: strand.branch
11984
- }));
11985
- this.staticLogger.verbose("Processing strand...");
11986
- let error = void 0;
11987
- try {
11988
- const result = await onStrandUpdate(strand, {
11989
- type: "trigger",
11990
- trigger
11991
- });
11992
- if (result.error) {
11993
- throw result.error;
12084
+ strands = await _PullResponderTransmitter.pullStrands(driveId, url, listenerId);
12085
+ } catch (e) {
12086
+ error = e;
12087
+ const graphqlError = error;
12088
+ const errors = graphqlError.response?.errors ?? [];
12089
+ for (const err of errors) {
12090
+ if (err.message === "Listener not found") {
12091
+ staticLogger().verbose(`[SYNC DEBUG] Auto-registering pull responder for drive: ${driveId}`);
12092
+ await _PullResponderTransmitter.registerPullResponder(trigger.driveId, url, trigger.filter, listenerId);
12093
+ try {
12094
+ strands = await _PullResponderTransmitter.pullStrands(driveId, url, listenerId);
12095
+ staticLogger().verbose(`Successfully auto-registered and pulled strands for drive: ${driveId}, listenerId: ${listenerId}`);
12096
+ } catch (error2) {
12097
+ staticLogger().error(`Could not resolve 'Listener not found' error by registering a new pull responder for drive: ${driveId}, listenerId: ${listenerId}: ${error2}`);
12098
+ onError(error2);
12099
+ return;
11994
12100
  }
11995
- } catch (e) {
11996
- error = e;
11997
- onError(error);
11998
- }
11999
- listenerRevisions.push({
12000
- branch: strand.branch,
12001
- documentId: strand.documentId || "",
12002
- driveId: strand.driveId,
12003
- revision: operations.pop()?.index ?? -1,
12004
- scope: strand.scope,
12005
- status: error ? error instanceof OperationError ? error.status : "ERROR" : "SUCCESS",
12006
- error
12007
- });
12101
+ break;
12102
+ }
12008
12103
  }
12009
- this.staticLogger.verbose("Processed strands...");
12010
- onRevisions?.(listenerRevisions);
12011
- this.staticLogger.verbose("Acknowledging strands...");
12012
- let success = false;
12104
+ }
12105
+ if (!strands) {
12106
+ staticLogger().error(`Error pulling strands for drive, and could not auto-register: ${driveId}, listenerId: ${trigger.data.listenerId}: ${error}`);
12107
+ onError(error);
12108
+ return;
12109
+ }
12110
+ if (!strands.length) {
12111
+ staticLogger().verbose(`[SYNC DEBUG] No strands returned in pull cycle for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
12013
12112
  try {
12014
- await _PullResponderTransmitter.acknowledgeStrands(url, listenerId, listenerRevisions.map((revision) => {
12015
- const { error, ...rest } = revision;
12016
- return rest;
12017
- }));
12018
- success = true;
12019
- } catch (error) {
12020
- this.staticLogger.error("ACK error", error);
12113
+ onRevisions?.([]);
12114
+ } catch (error2) {
12115
+ staticLogger().error(`Error calling onRevisions for drive: ${driveId}, listenerId: ${trigger.data.listenerId}: ${error2}`);
12116
+ onError(error2);
12021
12117
  }
12022
- if (success) {
12023
- this.staticLogger.verbose("Acknowledged strands successfully.");
12024
- } else {
12025
- this.staticLogger.error("Failed to acknowledge strands");
12118
+ return;
12119
+ }
12120
+ staticLogger().verbose(`[SYNC DEBUG] Processing ${strands.length} strands in pull cycle for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
12121
+ const listenerRevisions = [];
12122
+ for (const strand of strands) {
12123
+ const operations = strand.operations.map((op) => ({
12124
+ ...op,
12125
+ scope: strand.scope,
12126
+ branch: strand.branch
12127
+ }));
12128
+ staticLogger().verbose(`[SYNC DEBUG] Processing strand for drive: ${strand.driveId}, document: ${strand.documentId}, scope: ${strand.scope}, with ${operations.length} operations`);
12129
+ let error2 = void 0;
12130
+ try {
12131
+ const result = await onStrandUpdate(strand, {
12132
+ type: "trigger",
12133
+ trigger
12134
+ });
12135
+ if (result.error) {
12136
+ throw result.error;
12137
+ }
12138
+ } catch (e) {
12139
+ staticLogger().error(`Error processing strand for drive: ${strand.driveId}, document: ${strand.documentId}, scope: ${strand.scope}, with ${operations.length} operations: ${e}`);
12140
+ error2 = e;
12141
+ onError(error2);
12026
12142
  }
12143
+ listenerRevisions.push({
12144
+ branch: strand.branch,
12145
+ documentId: strand.documentId || "",
12146
+ driveId: strand.driveId,
12147
+ revision: operations.pop()?.index ?? -1,
12148
+ scope: strand.scope,
12149
+ status: error2 ? error2 instanceof OperationError ? error2.status : "ERROR" : "SUCCESS",
12150
+ error: error2
12151
+ });
12152
+ }
12153
+ staticLogger().verbose("Processed strands...");
12154
+ try {
12155
+ onRevisions?.(listenerRevisions);
12156
+ } catch (error2) {
12157
+ staticLogger().error(`Error calling onRevisions for drive: ${driveId}, listenerId: ${trigger.data.listenerId}: ${error2}`);
12158
+ onError(error2);
12159
+ }
12160
+ staticLogger().verbose(`[SYNC DEBUG] Acknowledging ${listenerRevisions.length} strands for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
12161
+ let success = false;
12162
+ try {
12163
+ await _PullResponderTransmitter.acknowledgeStrands(url, trigger.data.listenerId, listenerRevisions.map((revision) => {
12164
+ const { error: error2, ...rest } = revision;
12165
+ return rest;
12166
+ }));
12167
+ success = true;
12168
+ } catch (error2) {
12169
+ staticLogger().error(`Error acknowledging strands for drive: ${driveId}, listenerId: ${trigger.data.listenerId}: ${error2}`);
12170
+ onError(error2);
12171
+ }
12172
+ if (success) {
12173
+ staticLogger().verbose(`[SYNC DEBUG] Successfully acknowledged strands for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
12174
+ } else {
12175
+ staticLogger().error("Failed to acknowledge strands");
12176
+ }
12177
+ try {
12027
12178
  onAcknowledge?.(success);
12028
- } catch (error) {
12029
- this.staticLogger.error("Pull error", error);
12030
- onError(error);
12179
+ } catch (error2) {
12180
+ staticLogger().error(`Error calling onAcknowledge for drive: ${driveId}, listenerId: ${trigger.data.listenerId}: ${error2}`);
12181
+ onError(error2);
12031
12182
  }
12032
12183
  }
12033
12184
  static setupPull(driveId, trigger, onStrandUpdate, onError, onRevisions, onAcknowledge) {
12034
- this.staticLogger.verbose(`setupPull(drive: ${driveId}), trigger:`, trigger);
12185
+ staticLogger().verbose(`[SYNC DEBUG] PullResponderTransmitter.setupPull initiated for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
12035
12186
  const { interval } = trigger.data;
12036
12187
  let loopInterval = PULL_DRIVE_INTERVAL;
12037
12188
  if (interval) {
@@ -12043,20 +12194,25 @@ var PullResponderTransmitter = class _PullResponderTransmitter {
12043
12194
  } catch {
12044
12195
  }
12045
12196
  }
12197
+ staticLogger().verbose(`[SYNC DEBUG] Pull interval set to ${loopInterval}ms for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
12046
12198
  let isCancelled = false;
12047
12199
  let timeout;
12048
12200
  const executeLoop = async () => {
12049
12201
  while (!isCancelled) {
12050
- this.staticLogger.verbose("Execute loop...");
12202
+ staticLogger().verbose(`[SYNC DEBUG] Starting pull cycle for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
12051
12203
  await this.executePull(driveId, trigger, onStrandUpdate, onError, onRevisions, onAcknowledge);
12204
+ staticLogger().verbose(`[SYNC DEBUG] Completed pull cycle for drive: ${driveId}, listenerId: ${trigger.data.listenerId}, waiting ${loopInterval}ms for next cycle`);
12052
12205
  await new Promise((resolve) => {
12053
- this.staticLogger.verbose(`Scheduling next pull in ${loopInterval} ms`);
12206
+ staticLogger().verbose(`Scheduling next pull in ${loopInterval} ms`);
12054
12207
  timeout = setTimeout(resolve, loopInterval);
12055
12208
  });
12056
12209
  }
12057
12210
  };
12058
- executeLoop().catch(this.staticLogger.error);
12211
+ executeLoop().catch((error) => {
12212
+ staticLogger().error(`Error in executeLoop for drive: ${driveId}, listenerId: ${trigger.data.listenerId}: ${error}`);
12213
+ });
12059
12214
  return () => {
12215
+ staticLogger().verbose(`[SYNC DEBUG] Cancelling pull loop for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
12060
12216
  isCancelled = true;
12061
12217
  if (timeout !== void 0) {
12062
12218
  clearTimeout(timeout);
@@ -12064,17 +12220,20 @@ var PullResponderTransmitter = class _PullResponderTransmitter {
12064
12220
  };
12065
12221
  }
12066
12222
  static async createPullResponderTrigger(driveId, url, options) {
12067
- this.staticLogger.verbose(`createPullResponderTrigger(drive: ${driveId}, url: ${url})`);
12223
+ staticLogger().verbose(`createPullResponderTrigger(drive: ${driveId}, url: ${url})`);
12068
12224
  const { pullFilter, pullInterval } = options;
12069
- const listenerId = await _PullResponderTransmitter.registerPullResponder(driveId, url, pullFilter ?? {
12225
+ const filter = pullFilter ?? {
12070
12226
  documentId: ["*"],
12071
12227
  documentType: ["*"],
12072
12228
  branch: ["*"],
12073
12229
  scope: ["*"]
12074
- });
12230
+ };
12231
+ const listenerId = await _PullResponderTransmitter.registerPullResponder(driveId, url, filter);
12075
12232
  const pullTrigger = {
12076
12233
  id: generateUUID(),
12077
12234
  type: "PullResponder",
12235
+ driveId,
12236
+ filter,
12078
12237
  data: {
12079
12238
  url,
12080
12239
  listenerId,
@@ -12088,6 +12247,80 @@ var PullResponderTransmitter = class _PullResponderTransmitter {
12088
12247
  }
12089
12248
  };
12090
12249
 
12250
+ // ../../packages/document-drive/dist/src/server/listener/transmitter/switchboard-push.js
12251
+ var import_json_stringify_deterministic = __toESM(require_lib(), 1);
12252
+ var SYNC_OPS_BATCH_LIMIT = 10;
12253
+ var SwitchboardPushTransmitter = class {
12254
+ targetURL;
12255
+ logger = childLogger([
12256
+ "SwitchboardPushTransmitter",
12257
+ Math.floor(Math.random() * 999).toString()
12258
+ ]);
12259
+ constructor(targetURL) {
12260
+ this.targetURL = targetURL;
12261
+ }
12262
+ async transmit(strands, source) {
12263
+ if (source.type === "trigger" && source.trigger.data?.url === this.targetURL) {
12264
+ this.logger.verbose(`Cutting trigger loop from ${this.targetURL}.`);
12265
+ return strands.map((strand) => ({
12266
+ driveId: strand.driveId,
12267
+ documentId: strand.documentId,
12268
+ scope: strand.scope,
12269
+ branch: strand.branch,
12270
+ status: "SUCCESS",
12271
+ revision: strand.operations.at(-1)?.index ?? -1
12272
+ }));
12273
+ }
12274
+ const culledStrands = [];
12275
+ let opsCounter = 0;
12276
+ for (let s = 0; opsCounter <= SYNC_OPS_BATCH_LIMIT && s < strands.length; s++) {
12277
+ const currentStrand = strands.at(s);
12278
+ if (!currentStrand) {
12279
+ break;
12280
+ }
12281
+ const newOps = Math.min(SYNC_OPS_BATCH_LIMIT - opsCounter, currentStrand.operations.length);
12282
+ culledStrands.push({
12283
+ ...currentStrand,
12284
+ operations: currentStrand.operations.slice(0, newOps)
12285
+ });
12286
+ opsCounter += newOps;
12287
+ }
12288
+ this.logger.verbose(` Total update: [${strands.map((s) => s.operations.length).join(", ")}] operations`);
12289
+ this.logger.verbose(`Culled update: [${culledStrands.map((s) => s.operations.length).join(", ")}] operations`);
12290
+ try {
12291
+ const { pushUpdates } = await requestGraphql(this.targetURL, gql`
12292
+ mutation pushUpdates($strands: [InputStrandUpdate!]) {
12293
+ pushUpdates(strands: $strands) {
12294
+ driveId
12295
+ documentId
12296
+ scope
12297
+ branch
12298
+ status
12299
+ revision
12300
+ error
12301
+ }
12302
+ }
12303
+ `, {
12304
+ strands: culledStrands.map((strand) => ({
12305
+ ...strand,
12306
+ operations: strand.operations.map((op) => ({
12307
+ ...op,
12308
+ input: (0, import_json_stringify_deterministic.default)(op.input)
12309
+ }))
12310
+ }))
12311
+ });
12312
+ if (!pushUpdates) {
12313
+ throw new Error("Couldn't update listener revision");
12314
+ }
12315
+ return pushUpdates;
12316
+ } catch (e) {
12317
+ this.logger.error(e);
12318
+ throw e;
12319
+ }
12320
+ return [];
12321
+ }
12322
+ };
12323
+
12091
12324
  // ../../packages/document-drive/dist/src/server/types.js
12092
12325
  var TransmitterType;
12093
12326
  (function(TransmitterType2) {
@@ -12127,6 +12360,7 @@ function isAtRevision(document, revisions) {
12127
12360
 
12128
12361
  // ../../packages/document-drive/dist/src/server/base-server.js
12129
12362
  var BaseDocumentDriveServer = class {
12363
+ logger = childLogger(["BaseDocumentDriveServer"]);
12130
12364
  // external dependencies
12131
12365
  documentModelModules;
12132
12366
  storage;
@@ -12185,17 +12419,6 @@ var BaseDocumentDriveServer = class {
12185
12419
  taskQueueMethod: options?.taskQueueMethod === void 0 ? RunAsap.runAsap : options.taskQueueMethod
12186
12420
  };
12187
12421
  this.defaultDrivesManager = new DefaultDrivesManager(this, this.defaultDrivesManagerDelegate, options);
12188
- this.storage.setStorageDelegate?.({
12189
- getCachedOperations: async (drive, id) => {
12190
- try {
12191
- const document = await this.cache.getDocument(drive, id);
12192
- return document?.operations;
12193
- } catch (error) {
12194
- logger.error(error);
12195
- return void 0;
12196
- }
12197
- }
12198
- });
12199
12422
  this.initializePromise = this._initialize();
12200
12423
  }
12201
12424
  // workaround for testing the ephemeral listeners -- we don't have DI in place yet
@@ -12209,19 +12432,19 @@ var BaseDocumentDriveServer = class {
12209
12432
  async _initialize() {
12210
12433
  await this.listenerManager.initialize(this.handleListenerError);
12211
12434
  await this.queueManager.init(this.queueDelegate, (error) => {
12212
- logger.error(`Error initializing queue manager`, error);
12435
+ this.logger.error(`Error initializing queue manager`, error);
12213
12436
  errors.push(error);
12214
12437
  });
12215
12438
  try {
12216
12439
  await this.defaultDrivesManager.removeOldremoteDrives();
12217
12440
  } catch (error) {
12218
- logger.error(error);
12441
+ this.logger.error(error);
12219
12442
  }
12220
12443
  const errors = [];
12221
12444
  const drives = await this.getDrives();
12222
12445
  for (const drive of drives) {
12223
12446
  await this._initializeDrive(drive).catch((error) => {
12224
- logger.error(`Error initializing drive ${drive}`, error);
12447
+ this.logger.error(`Error initializing drive ${drive}`, error);
12225
12448
  errors.push(error);
12226
12449
  });
12227
12450
  }
@@ -12251,7 +12474,7 @@ var BaseDocumentDriveServer = class {
12251
12474
  return source.type === "local" ? "push" : "pull";
12252
12475
  }
12253
12476
  handleListenerError(error, driveId, listener) {
12254
- logger.error(`Listener ${listener.listener.label ?? listener.listener.listenerId} error:`, error);
12477
+ this.logger.error(`Listener ${listener.listener.label ?? listener.listener.listenerId} error:`, error);
12255
12478
  const status = error instanceof OperationError ? error.status : "ERROR";
12256
12479
  this.synchronizationManager.updateSyncStatus(driveId, { push: status }, error);
12257
12480
  }
@@ -12311,9 +12534,9 @@ var BaseDocumentDriveServer = class {
12311
12534
  if (pushListener) {
12312
12535
  this.getSynchronizationUnitsRevision(driveId, syncUnits).then((syncUnitRevisions) => {
12313
12536
  for (const revision of syncUnitRevisions) {
12314
- this.listenerManager.updateListenerRevision(pushListener.listenerId, driveId, revision.syncId, revision.revision).catch(logger.error);
12537
+ this.listenerManager.updateListenerRevision(pushListener.listenerId, driveId, revision.syncId, revision.revision).catch(this.logger.error);
12315
12538
  }
12316
- }).catch(logger.error);
12539
+ }).catch(this.logger.error);
12317
12540
  }
12318
12541
  }
12319
12542
  });
@@ -12335,10 +12558,57 @@ var BaseDocumentDriveServer = class {
12335
12558
  }
12336
12559
  async _initializeDrive(driveId) {
12337
12560
  const drive = await this.getDrive(driveId);
12561
+ this.logger.verbose(`[SYNC DEBUG] Initializing drive ${driveId} with slug "${drive.state.global.slug}"`);
12338
12562
  await this.synchronizationManager.initializeDriveSyncStatus(driveId, drive);
12339
12563
  if (this.shouldSyncRemoteDrive(drive)) {
12564
+ this.logger.verbose(`[SYNC DEBUG] Starting sync for remote drive ${driveId}`);
12340
12565
  await this.startSyncRemoteDrive(driveId);
12341
12566
  }
12567
+ this.logger.verbose(`[SYNC DEBUG] Processing ${drive.state.local.listeners.length} listeners for drive ${driveId}`);
12568
+ for (const zodListener of drive.state.local.listeners) {
12569
+ if (zodListener.callInfo?.transmitterType === "SwitchboardPush") {
12570
+ this.logger.verbose(`[SYNC DEBUG] Setting up SwitchboardPush listener ${zodListener.listenerId} for drive ${driveId}`);
12571
+ const transmitter = new SwitchboardPushTransmitter(zodListener.callInfo?.data ?? "");
12572
+ this.logger.verbose(`[SYNC DEBUG] Created SwitchboardPush transmitter with URL: ${zodListener.callInfo?.data || "none"}`);
12573
+ await this.listenerManager.setListener(driveId, {
12574
+ block: zodListener.block,
12575
+ driveId: drive.state.global.id,
12576
+ filter: {
12577
+ branch: zodListener.filter?.branch ?? [],
12578
+ documentId: zodListener.filter?.documentId ?? [],
12579
+ documentType: zodListener.filter?.documentType ?? [],
12580
+ scope: zodListener.filter?.scope ?? []
12581
+ },
12582
+ listenerId: zodListener.listenerId,
12583
+ callInfo: zodListener.callInfo,
12584
+ system: zodListener.system,
12585
+ label: zodListener.label ?? "",
12586
+ transmitter
12587
+ }).then(() => {
12588
+ this.logger.verbose(`[SYNC DEBUG] Successfully set up listener ${zodListener.listenerId} for drive ${driveId}`);
12589
+ });
12590
+ } else if (zodListener.callInfo?.transmitterType === "PullResponder") {
12591
+ this.logger.verbose(`[SYNC DEBUG] Setting up PullResponder listener ${zodListener.listenerId} for drive ${driveId}`);
12592
+ const pullResponderListener = {
12593
+ driveId,
12594
+ listenerId: zodListener.listenerId,
12595
+ block: false,
12596
+ filter: zodListener.filter,
12597
+ system: false,
12598
+ label: `PullResponder #${zodListener.listenerId}`,
12599
+ callInfo: {
12600
+ data: "",
12601
+ name: "PullResponder",
12602
+ transmitterType: "PullResponder"
12603
+ }
12604
+ };
12605
+ const pullResponder = new PullResponderTransmitter(pullResponderListener, this.listenerManager);
12606
+ pullResponderListener.transmitter = pullResponder;
12607
+ await this.listenerManager.setListener(driveId, pullResponderListener);
12608
+ } else {
12609
+ this.logger.error(`Skipping listener ${zodListener.listenerId} with unsupported type ${zodListener.callInfo?.transmitterType || "unknown"}`);
12610
+ }
12611
+ }
12342
12612
  }
12343
12613
  // Delegate synchronization methods to synchronizationManager
12344
12614
  getSynchronizationUnits(driveId, documentId, scope, branch, documentType2) {
@@ -12380,7 +12650,7 @@ var BaseDocumentDriveServer = class {
12380
12650
  };
12381
12651
  await this.storage.createDrive(id, document);
12382
12652
  if (input.global.slug) {
12383
- await this.cache.deleteDocument("drives-slug", input.global.slug);
12653
+ await this.cache.deleteDriveBySlug(input.global.slug);
12384
12654
  }
12385
12655
  await this._initializeDrive(id);
12386
12656
  this.eventEmitter.emit("driveAdded", document);
@@ -12412,7 +12682,7 @@ var BaseDocumentDriveServer = class {
12412
12682
  const result = await Promise.allSettled([
12413
12683
  this.stopSyncRemoteDrive(driveId),
12414
12684
  this.listenerManager.removeDrive(driveId),
12415
- this.cache.deleteDocument("drives", driveId),
12685
+ this.cache.deleteDrive(driveId),
12416
12686
  this.storage.deleteDrive(driveId)
12417
12687
  ]);
12418
12688
  result.forEach((r) => {
@@ -12427,7 +12697,7 @@ var BaseDocumentDriveServer = class {
12427
12697
  async getDrive(driveId, options) {
12428
12698
  let document;
12429
12699
  try {
12430
- const cachedDocument = await this.cache.getDocument("drives", driveId);
12700
+ const cachedDocument = await this.cache.getDrive(driveId);
12431
12701
  if (cachedDocument && isDocumentDrive(cachedDocument)) {
12432
12702
  document = cachedDocument;
12433
12703
  if (isAtRevision(document, options?.revisions)) {
@@ -12435,7 +12705,7 @@ var BaseDocumentDriveServer = class {
12435
12705
  }
12436
12706
  }
12437
12707
  } catch (e) {
12438
- logger.error("Error getting drive from cache", e);
12708
+ this.logger.error("Error getting drive from cache", e);
12439
12709
  }
12440
12710
  const driveStorage = document ?? await this.storage.getDrive(driveId);
12441
12711
  const result = this._buildDocument(driveStorage, options);
@@ -12443,43 +12713,43 @@ var BaseDocumentDriveServer = class {
12443
12713
  throw new Error(`Document with id ${driveId} is not a Document Drive`);
12444
12714
  } else {
12445
12715
  if (!options?.revisions) {
12446
- this.cache.setDocument("drives", driveId, result).catch(logger.error);
12716
+ this.cache.setDrive(driveId, result).catch(this.logger.error);
12447
12717
  }
12448
12718
  return result;
12449
12719
  }
12450
12720
  }
12451
12721
  async getDriveBySlug(slug, options) {
12452
12722
  try {
12453
- const document2 = await this.cache.getDocument("drives-slug", slug);
12454
- if (document2 && isDocumentDrive(document2)) {
12455
- return document2;
12723
+ const drive = await this.cache.getDriveBySlug(slug);
12724
+ if (drive) {
12725
+ return drive;
12456
12726
  }
12457
12727
  } catch (e) {
12458
- logger.error("Error getting drive from cache", e);
12728
+ this.logger.error("Error getting drive from cache", e);
12459
12729
  }
12460
12730
  const driveStorage = await this.storage.getDriveBySlug(slug);
12461
12731
  const document = this._buildDocument(driveStorage, options);
12462
12732
  if (!isDocumentDrive(document)) {
12463
12733
  throw new Error(`Document with slug ${slug} is not a Document Drive`);
12464
12734
  } else {
12465
- this.cache.setDocument("drives-slug", slug, document).catch(logger.error);
12735
+ this.cache.setDriveBySlug(slug, document).catch(this.logger.error);
12466
12736
  return document;
12467
12737
  }
12468
12738
  }
12469
12739
  async getDocument(driveId, documentId, options) {
12470
12740
  let cachedDocument;
12471
12741
  try {
12472
- cachedDocument = await this.cache.getDocument(driveId, documentId);
12742
+ cachedDocument = await this.cache.getDocument(documentId);
12473
12743
  if (cachedDocument && isAtRevision(cachedDocument, options?.revisions)) {
12474
12744
  return cachedDocument;
12475
12745
  }
12476
12746
  } catch (e) {
12477
- logger.error("Error getting document from cache", e);
12747
+ this.logger.error("Error getting document from cache", e);
12478
12748
  }
12479
12749
  const documentStorage = cachedDocument ?? await this.storage.getDocument(driveId, documentId);
12480
12750
  const document = this._buildDocument(documentStorage, options);
12481
12751
  if (!options?.revisions) {
12482
- this.cache.setDocument(driveId, documentId, document).catch(logger.error);
12752
+ this.cache.setDocument(documentId, document).catch(this.logger.error);
12483
12753
  }
12484
12754
  return document;
12485
12755
  }
@@ -12534,9 +12804,9 @@ var BaseDocumentDriveServer = class {
12534
12804
  }
12535
12805
  await this.listenerManager.removeSyncUnits(driveId, syncUnits);
12536
12806
  } catch (error) {
12537
- logger.warn("Error deleting document", error);
12807
+ this.logger.warn("Error deleting document", error);
12538
12808
  }
12539
- await this.cache.deleteDocument(driveId, documentId);
12809
+ await this.cache.deleteDocument(documentId);
12540
12810
  return this.storage.deleteDocument(driveId, documentId);
12541
12811
  }
12542
12812
  async _processOperations(driveId, documentId, documentStorage, operations) {
@@ -12706,33 +12976,35 @@ var BaseDocumentDriveServer = class {
12706
12976
  if (result) {
12707
12977
  return result;
12708
12978
  }
12979
+ let jobId;
12980
+ const promise = new Promise((resolve, reject) => {
12981
+ const unsubscribe = this.queueManager.on("jobCompleted", (job, result2) => {
12982
+ if (job.jobId === jobId) {
12983
+ unsubscribe();
12984
+ unsubscribeError();
12985
+ resolve(result2);
12986
+ }
12987
+ });
12988
+ const unsubscribeError = this.queueManager.on("jobFailed", (job, error) => {
12989
+ if (job.jobId === jobId) {
12990
+ unsubscribe();
12991
+ unsubscribeError();
12992
+ reject(error);
12993
+ }
12994
+ });
12995
+ });
12709
12996
  try {
12710
- const jobId = await this.queueManager.addJob({
12997
+ jobId = await this.queueManager.addJob({
12711
12998
  driveId,
12712
12999
  documentId,
12713
13000
  operations,
12714
13001
  options
12715
13002
  });
12716
- return new Promise((resolve, reject) => {
12717
- const unsubscribe = this.queueManager.on("jobCompleted", (job, result2) => {
12718
- if (job.jobId === jobId) {
12719
- unsubscribe();
12720
- unsubscribeError();
12721
- resolve(result2);
12722
- }
12723
- });
12724
- const unsubscribeError = this.queueManager.on("jobFailed", (job, error) => {
12725
- if (job.jobId === jobId) {
12726
- unsubscribe();
12727
- unsubscribeError();
12728
- reject(error);
12729
- }
12730
- });
12731
- });
12732
13003
  } catch (error) {
12733
- logger.error("Error adding job", error);
13004
+ this.logger.error("Error adding job", error);
12734
13005
  throw error;
12735
13006
  }
13007
+ return promise;
12736
13008
  }
12737
13009
  async queueAction(driveId, documentId, action, options) {
12738
13010
  return this.queueActions(driveId, documentId, [action], options);
@@ -12762,7 +13034,7 @@ var BaseDocumentDriveServer = class {
12762
13034
  });
12763
13035
  });
12764
13036
  } catch (error) {
12765
- logger.error("Error adding job", error);
13037
+ this.logger.error("Error adding job", error);
12766
13038
  throw error;
12767
13039
  }
12768
13040
  }
@@ -12793,7 +13065,7 @@ var BaseDocumentDriveServer = class {
12793
13065
  });
12794
13066
  });
12795
13067
  } catch (error) {
12796
- logger.error("Error adding drive job", error);
13068
+ this.logger.error("Error adding drive job", error);
12797
13069
  throw error;
12798
13070
  }
12799
13071
  }
@@ -12810,7 +13082,7 @@ var BaseDocumentDriveServer = class {
12810
13082
  await this._addOperations(driveId, documentId, async (documentStorage) => {
12811
13083
  const result2 = await this._processOperations(driveId, documentId, documentStorage, operations);
12812
13084
  if (!result2.document) {
12813
- logger.error("Invalid document");
13085
+ this.logger.error("Invalid document");
12814
13086
  throw result2.error ?? new Error("Invalid document");
12815
13087
  }
12816
13088
  document = result2.document;
@@ -12824,7 +13096,7 @@ var BaseDocumentDriveServer = class {
12824
13096
  };
12825
13097
  });
12826
13098
  if (document) {
12827
- this.cache.setDocument(driveId, documentId, document).catch(logger.error);
13099
+ this.cache.setDocument(documentId, document).catch(this.logger.error);
12828
13100
  }
12829
13101
  const { scopes, branches } = operationsApplied.reduce((acc, operation) => {
12830
13102
  if (!acc.scopes.includes(operation.scope)) {
@@ -12857,7 +13129,7 @@ var BaseDocumentDriveServer = class {
12857
13129
  });
12858
13130
  }
12859
13131
  }).catch((error2) => {
12860
- logger.error("Non handled error updating sync revision", error2);
13132
+ this.logger.error("Non handled error updating sync revision", error2);
12861
13133
  this.synchronizationManager.updateSyncStatus(driveId, {
12862
13134
  [operationSource]: "ERROR"
12863
13135
  }, error2);
@@ -12958,7 +13230,7 @@ var BaseDocumentDriveServer = class {
12958
13230
  });
12959
13231
  });
12960
13232
  } catch (error) {
12961
- logger.error("Error adding drive job", error);
13233
+ this.logger.error("Error adding drive job", error);
12962
13234
  throw error;
12963
13235
  }
12964
13236
  }
@@ -12986,7 +13258,7 @@ var BaseDocumentDriveServer = class {
12986
13258
  if (!document || !isDocumentDrive(document)) {
12987
13259
  throw error ?? new Error("Invalid Document Drive document");
12988
13260
  }
12989
- this.cache.setDocument("drives", driveId, document).catch(logger.error);
13261
+ this.cache.setDrive(driveId, document).catch(this.logger.error);
12990
13262
  const lastOperation = operationsApplied.filter((op) => op.scope === "global").slice().pop();
12991
13263
  if (lastOperation) {
12992
13264
  const newOp = operationsApplied.find((appliedOp) => !operations.find((o) => o.id === appliedOp.id && o.index === appliedOp.index && o.skip === appliedOp.skip && o.hash === appliedOp.hash));
@@ -12995,7 +13267,6 @@ var BaseDocumentDriveServer = class {
12995
13267
  this.listenerManager.updateSynchronizationRevisions(driveId, [
12996
13268
  {
12997
13269
  syncId: "0",
12998
- driveId,
12999
13270
  documentId: "",
13000
13271
  scope: "global",
13001
13272
  branch: "main",
@@ -13014,7 +13285,7 @@ var BaseDocumentDriveServer = class {
13014
13285
  });
13015
13286
  }
13016
13287
  }).catch((error2) => {
13017
- logger.error("Non handled error updating sync revision", error2);
13288
+ this.logger.error("Non handled error updating sync revision", error2);
13018
13289
  this.synchronizationManager.updateSyncStatus(driveId, {
13019
13290
  [operationSource]: "ERROR"
13020
13291
  }, error2);
@@ -13116,9 +13387,26 @@ var BaseDocumentDriveServer = class {
13116
13387
  scope: strand.scope,
13117
13388
  branch: strand.branch
13118
13389
  }));
13119
- const result = await (!strand.documentId ? this.queueDriveOperations(strand.driveId, operations, { source }) : this.queueOperations(strand.driveId, strand.documentId, operations, {
13120
- source
13121
- }));
13390
+ let result;
13391
+ if (strand.documentId) {
13392
+ try {
13393
+ result = await this.queueOperations(strand.driveId, strand.documentId, operations, {
13394
+ source
13395
+ });
13396
+ } catch (error) {
13397
+ this.logger.error("Error queueing operations", error);
13398
+ throw error;
13399
+ }
13400
+ } else {
13401
+ try {
13402
+ result = await this.queueDriveOperations(strand.driveId, operations, {
13403
+ source
13404
+ });
13405
+ } catch (error) {
13406
+ this.logger.error("Error queueing operations", error);
13407
+ throw error;
13408
+ }
13409
+ }
13122
13410
  if (result.status === "ERROR") {
13123
13411
  const syncUnits = strand.documentId !== "" ? (await this.getSynchronizationUnitsIds(strand.driveId, [strand.documentId], [strand.scope], [strand.branch])).map((s) => s.syncId) : [strand.driveId];
13124
13412
  const operationSource = this.getOperationSource(source);
@@ -13290,11 +13578,10 @@ var ListenerManager = class _ListenerManager {
13290
13578
  throw new Error("Maximum retries exhausted.");
13291
13579
  }
13292
13580
  const listenerUpdates = [];
13293
- for (const [driveId, drive] of this.listenerStateByDriveId) {
13294
- for (const [listenerId, listenerState] of drive) {
13581
+ for (const [driveId, listenerStateById] of this.listenerStateByDriveId) {
13582
+ for (const [listenerId, listenerState] of listenerStateById) {
13295
13583
  const transmitter = listenerState.listener.transmitter;
13296
13584
  if (!transmitter?.transmit) {
13297
- this.logger.verbose(`Transmitter not set on listener: ${listenerId}`);
13298
13585
  continue;
13299
13586
  }
13300
13587
  const syncUnits = await this.getListenerSyncUnits(driveId, listenerId);
@@ -13306,7 +13593,7 @@ var ListenerManager = class _ListenerManager {
13306
13593
  this.logger.verbose(`Abandoning push for sync unit ${syncUnit.syncId}: already up-to-date (${unitState.listenerRev} >= ${syncUnit.revision})`);
13307
13594
  return;
13308
13595
  } else {
13309
- this.logger.verbose(`Listener out-of-date for sync unit (${syncUnit.driveId}, ${syncUnit.scope}, ${syncUnit.documentId}): ${unitState?.listenerRev} < ${syncUnit.revision}`);
13596
+ this.logger.verbose(`Listener out-of-date for sync unit (${syncUnit.scope}, ${syncUnit.documentId}): ${unitState?.listenerRev} < ${syncUnit.revision}`);
13310
13597
  }
13311
13598
  const opData = [];
13312
13599
  try {
@@ -13445,57 +13732,78 @@ var ListenerManager = class _ListenerManager {
13445
13732
  }
13446
13733
  }
13447
13734
  async getStrands(driveId, listenerId, options) {
13448
- const listenerState = this.getListenerState(driveId, listenerId);
13735
+ this.logger.verbose(`[SYNC DEBUG] ListenerManager.getStrands called for drive: ${driveId}, listener: ${listenerId}, options: ${JSON.stringify(options || {})}`);
13736
+ let listenerState;
13737
+ try {
13738
+ listenerState = this.getListenerState(driveId, listenerId);
13739
+ this.logger.verbose(`[SYNC DEBUG] Found listener state for drive: ${driveId}, listener: ${listenerId}, status: ${listenerState.listenerStatus}`);
13740
+ } catch (error) {
13741
+ this.logger.error(`[SYNC DEBUG] Failed to find listener state for drive: ${driveId}, listener: ${listenerId}. Error: ${error}`);
13742
+ throw error;
13743
+ }
13449
13744
  const strands = [];
13450
- const syncUnits = await this.getListenerSyncUnits(driveId, listenerId);
13451
- const limit = options?.limit;
13452
- let operationsCount = 0;
13453
- const tasks = syncUnits.map((syncUnit) => async () => {
13454
- if (limit && operationsCount >= limit) {
13455
- return;
13456
- }
13457
- if (syncUnit.revision < 0) {
13458
- return;
13459
- }
13460
- const entry = listenerState.syncUnits.get(syncUnit.syncId);
13461
- if (entry && entry.listenerRev >= syncUnit.revision) {
13462
- return;
13463
- }
13464
- const { documentId, driveId: driveId2, scope, branch } = syncUnit;
13465
- try {
13466
- const operations = await this.syncManager.getOperationData(
13467
- // DEAL WITH INVALID SYNC ID ERROR
13468
- driveId2,
13469
- syncUnit.syncId,
13470
- {
13471
- since: options?.since,
13472
- fromRevision: options?.fromRevision ?? entry?.listenerRev,
13473
- limit: limit ? limit - operationsCount : void 0
13745
+ try {
13746
+ const syncUnits = await this.getListenerSyncUnits(driveId, listenerId);
13747
+ this.logger.verbose(`[SYNC DEBUG] Retrieved ${syncUnits.length} sync units for drive: ${driveId}, listener: ${listenerId}`);
13748
+ const limit = options?.limit;
13749
+ let operationsCount = 0;
13750
+ const tasks = syncUnits.map((syncUnit) => async () => {
13751
+ if (limit && operationsCount >= limit) {
13752
+ return;
13753
+ }
13754
+ if (syncUnit.revision < 0) {
13755
+ this.logger.verbose(`[SYNC DEBUG] Skipping sync unit with negative revision: ${syncUnit.syncId}, revision: ${syncUnit.revision}`);
13756
+ return;
13757
+ }
13758
+ const entry = listenerState.syncUnits.get(syncUnit.syncId);
13759
+ if (entry && entry.listenerRev >= syncUnit.revision) {
13760
+ this.logger.verbose(`[SYNC DEBUG] Skipping sync unit - listener already up to date: ${syncUnit.syncId}, listenerRev: ${entry.listenerRev}, revision: ${syncUnit.revision}`);
13761
+ return;
13762
+ }
13763
+ const { documentId, scope, branch } = syncUnit;
13764
+ try {
13765
+ this.logger.verbose(`[SYNC DEBUG] Getting operations for syncUnit: ${syncUnit.syncId}, documentId: ${documentId}, scope: ${scope}, branch: ${branch}`);
13766
+ const operations = await this.syncManager.getOperationData(
13767
+ // DEAL WITH INVALID SYNC ID ERROR
13768
+ driveId,
13769
+ syncUnit.syncId,
13770
+ {
13771
+ since: options?.since,
13772
+ fromRevision: options?.fromRevision ?? entry?.listenerRev,
13773
+ limit: limit ? limit - operationsCount : void 0
13774
+ }
13775
+ );
13776
+ this.logger.verbose(`[SYNC DEBUG] Retrieved ${operations.length} operations for syncUnit: ${syncUnit.syncId}`);
13777
+ if (!operations.length) {
13778
+ return;
13474
13779
  }
13475
- );
13476
- if (!operations.length) {
13780
+ operationsCount += operations.length;
13781
+ strands.push({
13782
+ driveId,
13783
+ documentId,
13784
+ scope,
13785
+ branch,
13786
+ operations
13787
+ });
13788
+ this.logger.verbose(`[SYNC DEBUG] Added strand with ${operations.length} operations for syncUnit: ${syncUnit.syncId}`);
13789
+ } catch (error) {
13790
+ this.logger.error(`Error getting operations for syncUnit: ${syncUnit.syncId}, error: ${error}`);
13477
13791
  return;
13478
13792
  }
13479
- operationsCount += operations.length;
13480
- strands.push({
13481
- driveId: driveId2,
13482
- documentId,
13483
- scope,
13484
- branch,
13485
- operations
13486
- });
13487
- } catch (error) {
13488
- this.logger.error(error);
13489
- return;
13490
- }
13491
- });
13492
- if (this.options.sequentialUpdates) {
13493
- for (const task of tasks) {
13494
- await task();
13793
+ });
13794
+ if (this.options.sequentialUpdates) {
13795
+ this.logger.verbose(`[SYNC DEBUG] Processing ${tasks.length} sync units sequentially`);
13796
+ for (const task of tasks) {
13797
+ await task();
13798
+ }
13799
+ } else {
13800
+ this.logger.verbose(`[SYNC DEBUG] Processing ${tasks.length} sync units in parallel`);
13801
+ await Promise.all(tasks.map((task) => task()));
13495
13802
  }
13496
- } else {
13497
- await Promise.all(tasks.map((task) => task()));
13803
+ } catch (error) {
13804
+ this.logger.error(`Error in getStrands: ${error}`);
13498
13805
  }
13806
+ this.logger.verbose(`ListenerManager.getStrands returning ${strands.length} strands for drive: ${driveId}, listener: ${listenerId}`);
13499
13807
  return strands;
13500
13808
  }
13501
13809
  getListenerState(driveId, listenerId) {
@@ -13520,80 +13828,6 @@ var ListenerManager = class _ListenerManager {
13520
13828
  }
13521
13829
  };
13522
13830
 
13523
- // ../../packages/document-drive/dist/src/server/listener/transmitter/switchboard-push.js
13524
- var import_json_stringify_deterministic = __toESM(require_lib(), 1);
13525
- var SYNC_OPS_BATCH_LIMIT = 10;
13526
- var SwitchboardPushTransmitter = class {
13527
- targetURL;
13528
- logger = childLogger([
13529
- "SwitchboardPushTransmitter",
13530
- Math.floor(Math.random() * 999).toString()
13531
- ]);
13532
- constructor(targetURL) {
13533
- this.targetURL = targetURL;
13534
- }
13535
- async transmit(strands, source) {
13536
- if (source.type === "trigger" && source.trigger.data?.url === this.targetURL) {
13537
- this.logger.verbose(`Cutting trigger loop from ${this.targetURL}.`);
13538
- return strands.map((strand) => ({
13539
- driveId: strand.driveId,
13540
- documentId: strand.documentId,
13541
- scope: strand.scope,
13542
- branch: strand.branch,
13543
- status: "SUCCESS",
13544
- revision: strand.operations.at(-1)?.index ?? -1
13545
- }));
13546
- }
13547
- const culledStrands = [];
13548
- let opsCounter = 0;
13549
- for (let s = 0; opsCounter <= SYNC_OPS_BATCH_LIMIT && s < strands.length; s++) {
13550
- const currentStrand = strands.at(s);
13551
- if (!currentStrand) {
13552
- break;
13553
- }
13554
- const newOps = Math.min(SYNC_OPS_BATCH_LIMIT - opsCounter, currentStrand.operations.length);
13555
- culledStrands.push({
13556
- ...currentStrand,
13557
- operations: currentStrand.operations.slice(0, newOps)
13558
- });
13559
- opsCounter += newOps;
13560
- }
13561
- this.logger.verbose(` Total update: [${strands.map((s) => s.operations.length).join(", ")}] operations`);
13562
- this.logger.verbose(`Culled update: [${culledStrands.map((s) => s.operations.length).join(", ")}] operations`);
13563
- try {
13564
- const { pushUpdates } = await requestGraphql(this.targetURL, gql`
13565
- mutation pushUpdates($strands: [InputStrandUpdate!]) {
13566
- pushUpdates(strands: $strands) {
13567
- driveId
13568
- documentId
13569
- scope
13570
- branch
13571
- status
13572
- revision
13573
- error
13574
- }
13575
- }
13576
- `, {
13577
- strands: culledStrands.map((strand) => ({
13578
- ...strand,
13579
- operations: strand.operations.map((op) => ({
13580
- ...op,
13581
- input: (0, import_json_stringify_deterministic.default)(op.input)
13582
- }))
13583
- }))
13584
- });
13585
- if (!pushUpdates) {
13586
- throw new Error("Couldn't update listener revision");
13587
- }
13588
- return pushUpdates;
13589
- } catch (e) {
13590
- this.logger.error(e);
13591
- throw e;
13592
- }
13593
- return [];
13594
- }
13595
- };
13596
-
13597
13831
  // ../../packages/document-drive/dist/src/server/listener/transmitter/factory.js
13598
13832
  var TransmitterFactory = class {
13599
13833
  listenerManager;
@@ -13634,18 +13868,20 @@ var SynchronizationManager = class {
13634
13868
  }
13635
13869
  async getSynchronizationUnits(driveId, documentId, scope, branch, documentType2) {
13636
13870
  const synchronizationUnitsQuery = await this.getSynchronizationUnitsIds(driveId, documentId, scope, branch, documentType2);
13871
+ this.logger.verbose(`getSynchronizationUnits query: ${JSON.stringify(synchronizationUnitsQuery)}`);
13637
13872
  return this.getSynchronizationUnitsRevision(driveId, synchronizationUnitsQuery);
13638
13873
  }
13639
13874
  async getSynchronizationUnitsRevision(driveId, syncUnitsQuery) {
13640
13875
  const drive = await this.getDrive(driveId);
13641
13876
  const revisions = await this.storage.getSynchronizationUnitsRevision(syncUnitsQuery);
13877
+ this.logger.verbose(`getSynchronizationUnitsRevision: ${JSON.stringify(revisions)}`);
13642
13878
  const synchronizationUnits = syncUnitsQuery.map((s) => ({
13643
13879
  ...s,
13644
13880
  lastUpdated: drive.created,
13645
13881
  revision: -1
13646
13882
  }));
13647
13883
  for (const revision of revisions) {
13648
- const syncUnit = synchronizationUnits.find((s) => revision.driveId === s.driveId && revision.documentId === s.documentId && revision.scope === s.scope && revision.branch === s.branch);
13884
+ const syncUnit = synchronizationUnits.find((s) => revision.documentId === s.documentId && revision.scope === s.scope && revision.branch === s.branch);
13649
13885
  if (syncUnit) {
13650
13886
  syncUnit.revision = revision.revision;
13651
13887
  syncUnit.lastUpdated = revision.lastUpdated;
@@ -13658,7 +13894,7 @@ var SynchronizationManager = class {
13658
13894
  const nodes = drive.state.global.nodes.filter((node) => isFileNode(node) && (!documentId?.length || documentId.includes(node.id) || documentId.includes("*")) && (!documentType2?.length || documentType2.includes(node.documentType) || documentType2.includes("*")));
13659
13895
  if ((!documentId || documentId.includes("*") || documentId.includes("")) && (!documentType2?.length || documentType2.includes("powerhouse/document-drive") || documentType2.includes("*"))) {
13660
13896
  nodes.unshift({
13661
- id: "",
13897
+ id: driveId,
13662
13898
  documentType: "powerhouse/document-drive",
13663
13899
  synchronizationUnits: [
13664
13900
  {
@@ -13700,7 +13936,6 @@ var SynchronizationManager = class {
13700
13936
  syncId,
13701
13937
  scope: syncUnit.scope,
13702
13938
  branch: syncUnit.branch,
13703
- driveId,
13704
13939
  documentId: node.id,
13705
13940
  documentType: node.documentType
13706
13941
  };
@@ -13718,7 +13953,6 @@ var SynchronizationManager = class {
13718
13953
  syncId,
13719
13954
  scope,
13720
13955
  branch,
13721
- driveId,
13722
13956
  documentId,
13723
13957
  documentType: documentType2,
13724
13958
  lastUpdated: lastOperation.timestamp ?? document.lastModified,
@@ -13726,14 +13960,27 @@ var SynchronizationManager = class {
13726
13960
  };
13727
13961
  }
13728
13962
  async getOperationData(driveId, syncId, filter) {
13963
+ this.logger.verbose(`[SYNC DEBUG] SynchronizationManager.getOperationData called for drive: ${driveId}, syncId: ${syncId}, filter: ${JSON.stringify(filter)}`);
13729
13964
  const syncUnit = syncId === "0" ? { documentId: "", scope: "global" } : await this.getSynchronizationUnitIdInfo(driveId, syncId);
13730
13965
  if (!syncUnit) {
13966
+ this.logger.error(`SYNC DEBUG] Invalid Sync Id ${syncId} in drive ${driveId}`);
13731
13967
  throw new Error(`Invalid Sync Id ${syncId} in drive ${driveId}`);
13732
13968
  }
13969
+ this.logger.verbose(`[SYNC DEBUG] Found sync unit: documentId: ${syncUnit.documentId}, scope: ${syncUnit.scope}`);
13733
13970
  const document = syncId === "0" ? await this.getDrive(driveId) : await this.getDocument(driveId, syncUnit.documentId);
13971
+ this.logger.verbose(`[SYNC DEBUG] Retrieved document ${syncUnit.documentId} with type: ${document.documentType}`);
13734
13972
  const operations = document.operations[syncUnit.scope] ?? [];
13973
+ this.logger.verbose(`[SYNC DEBUG] Found ${operations.length} total operations in scope ${syncUnit.scope}`);
13735
13974
  const filteredOperations = operations.filter((operation) => Object.keys(filter).length === 0 || (filter.since === void 0 || isBefore(filter.since, operation.timestamp)) && (filter.fromRevision === void 0 || operation.index > filter.fromRevision));
13975
+ this.logger.verbose(`[SYNC DEBUG] Filtered to ${filteredOperations.length} operations based on filter criteria` + (filter.fromRevision !== void 0 ? ` (fromRevision: ${filter.fromRevision})` : ""));
13736
13976
  const limitedOperations = filter.limit ? filteredOperations.slice(0, filter.limit) : filteredOperations;
13977
+ this.logger.verbose(`[SYNC DEBUG] Returning ${limitedOperations.length} operations after applying limit`);
13978
+ if (limitedOperations.length > 0) {
13979
+ const firstOp = limitedOperations[0];
13980
+ const lastOp = limitedOperations[limitedOperations.length - 1];
13981
+ this.logger.verbose(`[SYNC DEBUG] First operation: index=${firstOp.index}, type=${firstOp.type}`);
13982
+ this.logger.verbose(`[SYNC DEBUG] Last operation: index=${lastOp.index}, type=${lastOp.type}`);
13983
+ }
13737
13984
  return limitedOperations.map((operation) => ({
13738
13985
  hash: operation.hash,
13739
13986
  index: operation.index,
@@ -13747,7 +13994,7 @@ var SynchronizationManager = class {
13747
13994
  }
13748
13995
  async getDrive(driveId) {
13749
13996
  try {
13750
- const cachedDocument = await this.cache.getDocument("drives", driveId);
13997
+ const cachedDocument = await this.cache.getDrive(driveId);
13751
13998
  if (cachedDocument && isDocumentDrive(cachedDocument)) {
13752
13999
  return cachedDocument;
13753
14000
  }
@@ -13763,7 +14010,7 @@ var SynchronizationManager = class {
13763
14010
  }
13764
14011
  async getDocument(driveId, documentId) {
13765
14012
  try {
13766
- const cachedDocument = await this.cache.getDocument(driveId, documentId);
14013
+ const cachedDocument = await this.cache.getDocument(documentId);
13767
14014
  if (cachedDocument) {
13768
14015
  return cachedDocument;
13769
14016
  }