@dxos/echo-pipeline 0.3.11-next.0fb359e → 0.3.11-next.e28df4f

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 (46) hide show
  1. package/dist/lib/browser/{chunk-W3SSYW3X.mjs → chunk-D7UMNYLJ.mjs} +272 -85
  2. package/dist/lib/browser/chunk-D7UMNYLJ.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +1 -1
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/testing/index.mjs +33 -11
  6. package/dist/lib/browser/testing/index.mjs.map +4 -4
  7. package/dist/lib/node/{chunk-KTFCZMAY.cjs → chunk-GQW6RLGD.cjs} +267 -83
  8. package/dist/lib/node/chunk-GQW6RLGD.cjs.map +7 -0
  9. package/dist/lib/node/index.cjs +26 -26
  10. package/dist/lib/node/index.cjs.map +1 -1
  11. package/dist/lib/node/meta.json +1 -1
  12. package/dist/lib/node/testing/index.cjs +46 -25
  13. package/dist/lib/node/testing/index.cjs.map +4 -4
  14. package/dist/types/src/automerge/automerge-host.d.ts +37 -2
  15. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  16. package/dist/types/src/automerge/index.d.ts +1 -1
  17. package/dist/types/src/automerge/index.d.ts.map +1 -1
  18. package/dist/types/src/metadata/metadata-store.d.ts +1 -3
  19. package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
  20. package/dist/types/src/space/data-pipeline.d.ts.map +1 -1
  21. package/dist/types/src/space/space-manager.d.ts +2 -2
  22. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  23. package/dist/types/src/space/space-protocol.d.ts.map +1 -1
  24. package/dist/types/src/space/space.d.ts +1 -1
  25. package/dist/types/src/space/space.d.ts.map +1 -1
  26. package/dist/types/src/testing/change-metadata.d.ts +8 -0
  27. package/dist/types/src/testing/change-metadata.d.ts.map +1 -0
  28. package/dist/types/src/testing/database-test-rig.d.ts.map +1 -1
  29. package/dist/types/src/testing/index.d.ts +1 -0
  30. package/dist/types/src/testing/index.d.ts.map +1 -1
  31. package/package.json +33 -33
  32. package/src/automerge/automerge-host.test.ts +319 -34
  33. package/src/automerge/automerge-host.ts +137 -20
  34. package/src/automerge/index.ts +1 -1
  35. package/src/metadata/metadata-store.ts +12 -2
  36. package/src/pipeline/pipeline-stress.test.ts +9 -2
  37. package/src/space/data-pipeline.ts +4 -3
  38. package/src/space/space-manager.ts +3 -3
  39. package/src/space/space-protocol.ts +4 -0
  40. package/src/space/space.ts +8 -3
  41. package/src/testing/change-metadata.ts +27 -0
  42. package/src/testing/database-test-rig.ts +4 -1
  43. package/src/testing/index.ts +1 -0
  44. package/src/testing/test-agent-builder.ts +1 -1
  45. package/dist/lib/browser/chunk-W3SSYW3X.mjs.map +0 -7
  46. package/dist/lib/node/chunk-KTFCZMAY.cjs.map +0 -7
@@ -519,12 +519,12 @@ var emptyLargeSpaceMetadata = () => ({});
519
519
  var EchoMetadata = schema4.getCodecForType("dxos.echo.metadata.EchoMetadata");
520
520
  var LargeSpaceMetadata = schema4.getCodecForType("dxos.echo.metadata.LargeSpaceMetadata");
521
521
  var MetadataStore = class {
522
- constructor(_directory) {
523
- this._directory = _directory;
522
+ constructor(directory) {
524
523
  this._metadata = emptyEchoMetadata();
525
524
  this._spaceLargeMetadata = new ComplexMap3(PublicKey3.hash);
526
525
  this._metadataFile = void 0;
527
526
  this.update = new Event();
527
+ this._directory = directory;
528
528
  }
529
529
  get metadata() {
530
530
  return this._metadata;
@@ -553,7 +553,7 @@ var MetadataStore = class {
553
553
  name: file.filename
554
554
  }, {
555
555
  F: __dxlog_file4,
556
- L: 78,
556
+ L: 85,
557
557
  S: this,
558
558
  C: (f, a) => f(...a)
559
559
  });
@@ -573,6 +573,9 @@ var MetadataStore = class {
573
573
  await file.close();
574
574
  }
575
575
  }
576
+ /**
577
+ * @internal
578
+ */
576
579
  async _writeFile(file, codec2, data) {
577
580
  const encoded = arrayToBuffer(codec2.encode(data));
578
581
  const checksum = CRC32.buf(encoded);
@@ -586,7 +589,7 @@ var MetadataStore = class {
586
589
  checksum
587
590
  }, {
588
591
  F: __dxlog_file4,
589
- L: 110,
592
+ L: 120,
590
593
  S: this,
591
594
  C: (f, a) => f(...a)
592
595
  });
@@ -618,7 +621,7 @@ var MetadataStore = class {
618
621
  err
619
622
  }, {
620
623
  F: __dxlog_file4,
621
- L: 141,
624
+ L: 151,
622
625
  S: this,
623
626
  C: (f, a) => f(...a)
624
627
  });
@@ -635,7 +638,7 @@ var MetadataStore = class {
635
638
  err
636
639
  }, {
637
640
  F: __dxlog_file4,
638
- L: 153,
641
+ L: 163,
639
642
  S: this,
640
643
  C: (f, a) => f(...a)
641
644
  });
@@ -665,7 +668,7 @@ var MetadataStore = class {
665
668
  err
666
669
  }, {
667
670
  F: __dxlog_file4,
668
- L: 182,
671
+ L: 192,
669
672
  S: this,
670
673
  C: (f, a) => f(...a)
671
674
  });
@@ -686,7 +689,7 @@ var MetadataStore = class {
686
689
  const space = this.spaces.find((space2) => space2.key === spaceKey);
687
690
  invariant4(space, "Space not found", {
688
691
  F: __dxlog_file4,
689
- L: 204,
692
+ L: 214,
690
693
  S: this,
691
694
  A: [
692
695
  "space",
@@ -710,7 +713,7 @@ var MetadataStore = class {
710
713
  async clear() {
711
714
  log3("clearing all metadata", void 0, {
712
715
  F: __dxlog_file4,
713
- L: 223,
716
+ L: 233,
714
717
  S: this,
715
718
  C: (f, a) => f(...a)
716
719
  });
@@ -723,7 +726,7 @@ var MetadataStore = class {
723
726
  async setIdentityRecord(record) {
724
727
  invariant4(!this._metadata.identity, "Cannot overwrite existing identity in metadata", {
725
728
  F: __dxlog_file4,
726
- L: 233,
729
+ L: 243,
727
730
  S: this,
728
731
  A: [
729
732
  "!this._metadata.identity",
@@ -737,7 +740,7 @@ var MetadataStore = class {
737
740
  async addSpace(record) {
738
741
  invariant4(!(this._metadata.spaces ?? []).find((space) => space.key === record.key), "Cannot overwrite existing space in metadata", {
739
742
  F: __dxlog_file4,
740
- L: 241,
743
+ L: 251,
741
744
  S: this,
742
745
  A: [
743
746
  "!(this._metadata.spaces ?? []).find((space) => space.key === record.key)",
@@ -1478,7 +1481,7 @@ var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipelin
1478
1481
  var MESSAGES_PER_SNAPSHOT = 10;
1479
1482
  var AUTOMATIC_SNAPSHOT_DEBOUNCE_INTERVAL = 5e3;
1480
1483
  var TIMEFRAME_SAVE_DEBOUNCE_INTERVAL = 5e3;
1481
- var DataPipeline = class DataPipeline2 {
1484
+ var DataPipeline = class {
1482
1485
  constructor(_params) {
1483
1486
  this._params = _params;
1484
1487
  this._ctx = new Context4();
@@ -1599,22 +1602,23 @@ var DataPipeline = class DataPipeline2 {
1599
1602
  this._epochCtx = void 0;
1600
1603
  }
1601
1604
  async _consumePipeline() {
1605
+ const pipeline = this._pipeline;
1602
1606
  if (this.currentEpoch) {
1603
1607
  const waitForOneEpoch = this.onNewEpoch.waitForCount(1);
1604
1608
  await this._processEpochInSeparateTask(this.currentEpoch);
1605
1609
  await waitForOneEpoch;
1606
1610
  }
1607
1611
  let messageCounter = 0;
1608
- invariant8(this._pipeline, "Pipeline is not initialized.", {
1612
+ invariant8(pipeline, "Pipeline is not initialized.", {
1609
1613
  F: __dxlog_file9,
1610
- L: 228,
1614
+ L: 229,
1611
1615
  S: this,
1612
1616
  A: [
1613
- "this._pipeline",
1617
+ "pipeline",
1614
1618
  "'Pipeline is not initialized.'"
1615
1619
  ]
1616
1620
  });
1617
- for await (const msg of this._pipeline.consume()) {
1621
+ for await (const msg of pipeline.consume()) {
1618
1622
  const span = this._usage.beginRecording();
1619
1623
  this._mutations.inc();
1620
1624
  const { feedKey, seq, data } = msg;
@@ -1623,7 +1627,7 @@ var DataPipeline = class DataPipeline2 {
1623
1627
  seq
1624
1628
  }, {
1625
1629
  F: __dxlog_file9,
1626
- L: 234,
1630
+ L: 235,
1627
1631
  S: this,
1628
1632
  C: (f, a) => f(...a)
1629
1633
  });
@@ -1635,7 +1639,7 @@ var DataPipeline = class DataPipeline2 {
1635
1639
  feedKey
1636
1640
  }, {
1637
1641
  F: __dxlog_file9,
1638
- L: 240,
1642
+ L: 241,
1639
1643
  S: this,
1640
1644
  C: (f, a) => f(...a)
1641
1645
  });
@@ -1658,16 +1662,16 @@ var DataPipeline = class DataPipeline2 {
1658
1662
  spaceKey: this._params.spaceKey.toHex()
1659
1663
  }, {
1660
1664
  F: __dxlog_file9,
1661
- L: 257,
1665
+ L: 258,
1662
1666
  S: this,
1663
1667
  C: (f, a) => f(...a)
1664
1668
  });
1665
- await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);
1669
+ await this._noteTargetStateIfNeeded(pipeline.state.pendingTimeframe);
1666
1670
  }
1667
1671
  } catch (err) {
1668
1672
  log8.catch(err, void 0, {
1669
1673
  F: __dxlog_file9,
1670
- L: 267,
1674
+ L: 268,
1671
1675
  S: this,
1672
1676
  C: (f, a) => f(...a)
1673
1677
  });
@@ -1682,7 +1686,7 @@ var DataPipeline = class DataPipeline2 {
1682
1686
  _createSnapshot() {
1683
1687
  invariant8(this.databaseHost, "Database backend is not initialized.", {
1684
1688
  F: __dxlog_file9,
1685
- L: 281,
1689
+ L: 282,
1686
1690
  S: this,
1687
1691
  A: [
1688
1692
  "this.databaseHost",
@@ -1711,7 +1715,7 @@ var DataPipeline = class DataPipeline2 {
1711
1715
  } catch (err) {
1712
1716
  log8.warn("Failed to cache properties", err, {
1713
1717
  F: __dxlog_file9,
1714
- L: 310,
1718
+ L: 311,
1715
1719
  S: this,
1716
1720
  C: (f, a) => f(...a)
1717
1721
  });
@@ -1740,14 +1744,14 @@ var DataPipeline = class DataPipeline2 {
1740
1744
  if (err instanceof CancelledError) {
1741
1745
  log8("Epoch processing cancelled.", void 0, {
1742
1746
  F: __dxlog_file9,
1743
- L: 346,
1747
+ L: 347,
1744
1748
  S: this,
1745
1749
  C: (f, a) => f(...a)
1746
1750
  });
1747
1751
  } else {
1748
1752
  log8.catch(err, void 0, {
1749
1753
  F: __dxlog_file9,
1750
- L: 348,
1754
+ L: 349,
1751
1755
  S: this,
1752
1756
  C: (f, a) => f(...a)
1753
1757
  });
@@ -1770,7 +1774,7 @@ var DataPipeline = class DataPipeline2 {
1770
1774
  async _processEpoch(ctx, epoch) {
1771
1775
  invariant8(this._isOpen, "Space is closed.", {
1772
1776
  F: __dxlog_file9,
1773
- L: 372,
1777
+ L: 373,
1774
1778
  S: this,
1775
1779
  A: [
1776
1780
  "this._isOpen",
@@ -1779,7 +1783,7 @@ var DataPipeline = class DataPipeline2 {
1779
1783
  });
1780
1784
  invariant8(this._pipeline, void 0, {
1781
1785
  F: __dxlog_file9,
1782
- L: 373,
1786
+ L: 374,
1783
1787
  S: this,
1784
1788
  A: [
1785
1789
  "this._pipeline",
@@ -1791,7 +1795,7 @@ var DataPipeline = class DataPipeline2 {
1791
1795
  epoch: omit(epoch, "proof")
1792
1796
  }, {
1793
1797
  F: __dxlog_file9,
1794
- L: 376,
1798
+ L: 377,
1795
1799
  S: this,
1796
1800
  C: (f, a) => f(...a)
1797
1801
  });
@@ -1801,7 +1805,7 @@ var DataPipeline = class DataPipeline2 {
1801
1805
  }
1802
1806
  log8("restarting pipeline from epoch", void 0, {
1803
1807
  F: __dxlog_file9,
1804
- L: 382,
1808
+ L: 383,
1805
1809
  S: this,
1806
1810
  C: (f, a) => f(...a)
1807
1811
  });
@@ -1812,7 +1816,7 @@ var DataPipeline = class DataPipeline2 {
1812
1816
  async waitUntilTimeframe(timeframe) {
1813
1817
  invariant8(this._pipeline, "Pipeline is not initialized.", {
1814
1818
  F: __dxlog_file9,
1815
- L: 389,
1819
+ L: 390,
1816
1820
  S: this,
1817
1821
  A: [
1818
1822
  "this._pipeline",
@@ -1824,7 +1828,7 @@ var DataPipeline = class DataPipeline2 {
1824
1828
  async createEpoch() {
1825
1829
  invariant8(this._pipeline, void 0, {
1826
1830
  F: __dxlog_file9,
1827
- L: 395,
1831
+ L: 396,
1828
1832
  S: this,
1829
1833
  A: [
1830
1834
  "this._pipeline",
@@ -1833,7 +1837,7 @@ var DataPipeline = class DataPipeline2 {
1833
1837
  });
1834
1838
  invariant8(this.currentEpoch, void 0, {
1835
1839
  F: __dxlog_file9,
1836
- L: 396,
1840
+ L: 397,
1837
1841
  S: this,
1838
1842
  A: [
1839
1843
  "this.currentEpoch",
@@ -1864,7 +1868,7 @@ var DataPipeline = class DataPipeline2 {
1864
1868
  } catch (err) {
1865
1869
  log8.catch(err, void 0, {
1866
1870
  F: __dxlog_file9,
1867
- L: 426,
1871
+ L: 427,
1868
1872
  S: this,
1869
1873
  C: (f, a) => f(...a)
1870
1874
  });
@@ -1921,7 +1925,7 @@ var idle = async (timeout) => {
1921
1925
  };
1922
1926
 
1923
1927
  // packages/core/echo/echo-pipeline/src/space/space.ts
1924
- import { Event as Event5, synchronized as synchronized4, trackLeaks as trackLeaks3, Lock } from "@dxos/async";
1928
+ import { Event as Event5, synchronized as synchronized4, trackLeaks as trackLeaks3, Mutex } from "@dxos/async";
1925
1929
  import { invariant as invariant9 } from "@dxos/invariant";
1926
1930
  import { log as log10, logInfo } from "@dxos/log";
1927
1931
  import { AdmittedFeed as AdmittedFeed2 } from "@dxos/protocols/proto/dxos/halo/credentials";
@@ -1952,7 +1956,7 @@ var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeli
1952
1956
  var TIMEFRAME_SAVE_DEBOUNCE_INTERVAL2 = 500;
1953
1957
  var CONTROL_PIPELINE_SNAPSHOT_DELAY = 1e4;
1954
1958
  var USE_SNAPSHOTS = true;
1955
- var ControlPipeline = class ControlPipeline2 {
1959
+ var ControlPipeline = class {
1956
1960
  constructor({ spaceKey, genesisFeed, feedProvider, metadataStore }) {
1957
1961
  this._ctx = new Context5();
1958
1962
  this._lastTimeframeSaveTime = Date.now();
@@ -2198,15 +2202,15 @@ function _ts_decorate6(decorators, target, key, desc) {
2198
2202
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2199
2203
  }
2200
2204
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/space.ts";
2201
- var Space = class Space2 {
2205
+ var Space = class {
2202
2206
  constructor(params) {
2203
- this._addFeedLock = new Lock();
2207
+ this._addFeedMutex = new Mutex();
2204
2208
  this.onCredentialProcessed = new Callback2();
2205
2209
  this.stateUpdate = new Event5();
2206
2210
  this._isOpen = false;
2207
2211
  invariant9(params.spaceKey && params.feedProvider, void 0, {
2208
2212
  F: __dxlog_file11,
2209
- L: 73,
2213
+ L: 78,
2210
2214
  S: this,
2211
2215
  A: [
2212
2216
  "params.spaceKey && params.feedProvider",
@@ -2250,7 +2254,7 @@ var Space = class Space2 {
2250
2254
  credential
2251
2255
  }, {
2252
2256
  F: __dxlog_file11,
2253
- L: 111,
2257
+ L: 116,
2254
2258
  S: this,
2255
2259
  C: (f, a) => f(...a)
2256
2260
  });
@@ -2270,7 +2274,7 @@ var Space = class Space2 {
2270
2274
  if (this._dataFeed) {
2271
2275
  pipeline.setWriteFeed(this._dataFeed);
2272
2276
  }
2273
- await this._addFeedLock.executeSynchronized(async () => {
2277
+ await this._addFeedMutex.executeSynchronized(async () => {
2274
2278
  for (const feed of this._controlPipeline.spaceState.feeds.values()) {
2275
2279
  if (feed.assertion.designation === AdmittedFeed2.Designation.DATA && !pipeline.hasFeed(feed.key)) {
2276
2280
  await pipeline.addFeed(await this._feedProvider(feed.key, {
@@ -2315,7 +2319,7 @@ var Space = class Space2 {
2315
2319
  setControlFeed(feed) {
2316
2320
  invariant9(!this._controlFeed, "Control feed already set.", {
2317
2321
  F: __dxlog_file11,
2318
- L: 186,
2322
+ L: 191,
2319
2323
  S: this,
2320
2324
  A: [
2321
2325
  "!this._controlFeed",
@@ -2329,7 +2333,7 @@ var Space = class Space2 {
2329
2333
  setDataFeed(feed) {
2330
2334
  invariant9(!this._dataFeed, "Data feed already set.", {
2331
2335
  F: __dxlog_file11,
2332
- L: 193,
2336
+ L: 198,
2333
2337
  S: this,
2334
2338
  A: [
2335
2339
  "!this._dataFeed",
@@ -2355,7 +2359,7 @@ var Space = class Space2 {
2355
2359
  async open(ctx) {
2356
2360
  log10("opening...", void 0, {
2357
2361
  F: __dxlog_file11,
2358
- L: 215,
2362
+ L: 220,
2359
2363
  S: this,
2360
2364
  C: (f, a) => f(...a)
2361
2365
  });
@@ -2368,7 +2372,7 @@ var Space = class Space2 {
2368
2372
  this._isOpen = true;
2369
2373
  log10("opened", void 0, {
2370
2374
  F: __dxlog_file11,
2371
- L: 226,
2375
+ L: 231,
2372
2376
  S: this,
2373
2377
  C: (f, a) => f(...a)
2374
2378
  });
@@ -2378,7 +2382,7 @@ var Space = class Space2 {
2378
2382
  key: this._key
2379
2383
  }, {
2380
2384
  F: __dxlog_file11,
2381
- L: 231,
2385
+ L: 236,
2382
2386
  S: this,
2383
2387
  C: (f, a) => f(...a)
2384
2388
  });
@@ -2392,7 +2396,7 @@ var Space = class Space2 {
2392
2396
  this._isOpen = false;
2393
2397
  log10("closed", void 0, {
2394
2398
  F: __dxlog_file11,
2395
- L: 244,
2399
+ L: 249,
2396
2400
  S: this,
2397
2401
  C: (f, a) => f(...a)
2398
2402
  });
@@ -2400,13 +2404,13 @@ var Space = class Space2 {
2400
2404
  async initializeDataPipeline() {
2401
2405
  log10("initializeDataPipeline", void 0, {
2402
2406
  F: __dxlog_file11,
2403
- L: 249,
2407
+ L: 254,
2404
2408
  S: this,
2405
2409
  C: (f, a) => f(...a)
2406
2410
  });
2407
2411
  invariant9(this._isOpen, "Space must be open to initialize data pipeline.", {
2408
2412
  F: __dxlog_file11,
2409
- L: 250,
2413
+ L: 255,
2410
2414
  S: this,
2411
2415
  A: [
2412
2416
  "this._isOpen",
@@ -2416,6 +2420,15 @@ var Space = class Space2 {
2416
2420
  await this._dataPipeline.open();
2417
2421
  }
2418
2422
  };
2423
+ _ts_decorate6([
2424
+ trace3.info()
2425
+ ], Space.prototype, "protocol", void 0);
2426
+ _ts_decorate6([
2427
+ trace3.info()
2428
+ ], Space.prototype, "_controlPipeline", void 0);
2429
+ _ts_decorate6([
2430
+ trace3.info()
2431
+ ], Space.prototype, "_dataPipeline", void 0);
2419
2432
  _ts_decorate6([
2420
2433
  logInfo,
2421
2434
  trace3.info()
@@ -2443,6 +2456,7 @@ import { MMSTTopology } from "@dxos/network-manager";
2443
2456
  import { Teleport } from "@dxos/teleport";
2444
2457
  import { BlobSync } from "@dxos/teleport-extension-object-sync";
2445
2458
  import { ReplicatorExtension } from "@dxos/teleport-extension-replicator";
2459
+ import { trace as trace4 } from "@dxos/tracing";
2446
2460
  import { ComplexMap as ComplexMap5 } from "@dxos/util";
2447
2461
  function _ts_decorate7(decorators, target, key, desc) {
2448
2462
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -2486,7 +2500,7 @@ var SpaceProtocol = class {
2486
2500
  key: feed.key
2487
2501
  }, {
2488
2502
  F: __dxlog_file12,
2489
- L: 99,
2503
+ L: 103,
2490
2504
  S: this,
2491
2505
  C: (f, a) => f(...a)
2492
2506
  });
@@ -2509,7 +2523,7 @@ var SpaceProtocol = class {
2509
2523
  await this.blobSync.open();
2510
2524
  log11("starting...", void 0, {
2511
2525
  F: __dxlog_file12,
2512
- L: 125,
2526
+ L: 129,
2513
2527
  S: this,
2514
2528
  C: (f, a) => f(...a)
2515
2529
  });
@@ -2523,7 +2537,7 @@ var SpaceProtocol = class {
2523
2537
  });
2524
2538
  log11("started", void 0, {
2525
2539
  F: __dxlog_file12,
2526
- L: 135,
2540
+ L: 139,
2527
2541
  S: this,
2528
2542
  C: (f, a) => f(...a)
2529
2543
  });
@@ -2533,14 +2547,14 @@ var SpaceProtocol = class {
2533
2547
  if (this._connection) {
2534
2548
  log11("stopping...", void 0, {
2535
2549
  F: __dxlog_file12,
2536
- L: 142,
2550
+ L: 146,
2537
2551
  S: this,
2538
2552
  C: (f, a) => f(...a)
2539
2553
  });
2540
2554
  await this._connection.close();
2541
2555
  log11("stopped", void 0, {
2542
2556
  F: __dxlog_file12,
2543
- L: 144,
2557
+ L: 148,
2544
2558
  S: this,
2545
2559
  C: (f, a) => f(...a)
2546
2560
  });
@@ -2564,11 +2578,18 @@ var SpaceProtocol = class {
2564
2578
  }
2565
2579
  };
2566
2580
  _ts_decorate7([
2567
- logInfo2
2581
+ logInfo2,
2582
+ trace4.info()
2568
2583
  ], SpaceProtocol.prototype, "_topic", void 0);
2584
+ _ts_decorate7([
2585
+ trace4.info()
2586
+ ], SpaceProtocol.prototype, "_spaceKey", void 0);
2569
2587
  _ts_decorate7([
2570
2588
  logInfo2
2571
2589
  ], SpaceProtocol.prototype, "_ownPeerKey", null);
2590
+ SpaceProtocol = _ts_decorate7([
2591
+ trace4.resource()
2592
+ ], SpaceProtocol);
2572
2593
  var AuthStatus;
2573
2594
  (function(AuthStatus2) {
2574
2595
  AuthStatus2["INITIAL"] = "INITIAL";
@@ -2582,7 +2603,7 @@ var SpaceProtocolSession = class {
2582
2603
  this.replicator = new ReplicatorExtension().setOptions({
2583
2604
  upload: true
2584
2605
  });
2585
- this._authStatus = AuthStatus.INITIAL;
2606
+ this._authStatus = "INITIAL";
2586
2607
  this._wireParams = wireParams;
2587
2608
  this._swarmIdentity = swarmIdentity;
2588
2609
  this._onSessionAuth = onSessionAuth;
@@ -2607,15 +2628,15 @@ var SpaceProtocolSession = class {
2607
2628
  onAuthSuccess: () => {
2608
2629
  log11("Peer authenticated", void 0, {
2609
2630
  F: __dxlog_file12,
2610
- L: 241,
2631
+ L: 245,
2611
2632
  S: this,
2612
2633
  C: (f, a) => f(...a)
2613
2634
  });
2614
- this._authStatus = AuthStatus.SUCCESS;
2635
+ this._authStatus = "SUCCESS";
2615
2636
  this._onSessionAuth?.(this._teleport);
2616
2637
  },
2617
2638
  onAuthFailure: () => {
2618
- this._authStatus = AuthStatus.FAILURE;
2639
+ this._authStatus = "FAILURE";
2619
2640
  this._onAuthFailure?.(this._teleport);
2620
2641
  }
2621
2642
  }));
@@ -2625,7 +2646,7 @@ var SpaceProtocolSession = class {
2625
2646
  async close() {
2626
2647
  log11("close", void 0, {
2627
2648
  F: __dxlog_file12,
2628
- L: 257,
2649
+ L: 261,
2629
2650
  S: this,
2630
2651
  C: (f, a) => f(...a)
2631
2652
  });
@@ -2647,7 +2668,7 @@ import { synchronized as synchronized5, trackLeaks as trackLeaks4 } from "@dxos/
2647
2668
  import { failUndefined as failUndefined2 } from "@dxos/debug";
2648
2669
  import { PublicKey as PublicKey7 } from "@dxos/keys";
2649
2670
  import { log as log12 } from "@dxos/log";
2650
- import { trace as trace4 } from "@dxos/protocols";
2671
+ import { trace as trace5 } from "@dxos/protocols";
2651
2672
  import { ComplexMap as ComplexMap6 } from "@dxos/util";
2652
2673
  function _ts_decorate8(decorators, target, key, desc) {
2653
2674
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -2660,7 +2681,7 @@ function _ts_decorate8(decorators, target, key, desc) {
2660
2681
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2661
2682
  }
2662
2683
  var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/space-manager.ts";
2663
- var SpaceManager = class SpaceManager2 {
2684
+ var SpaceManager = class {
2664
2685
  constructor({ feedStore, networkManager, modelFactory, metadataStore, snapshotStore, blobStore }) {
2665
2686
  this._spaces = new ComplexMap6(PublicKey7.hash);
2666
2687
  this._instanceId = PublicKey7.random().toHex();
@@ -2682,8 +2703,8 @@ var SpaceManager = class SpaceManager2 {
2682
2703
  ...this._spaces.values()
2683
2704
  ].map((space) => space.close()));
2684
2705
  }
2685
- async constructSpace({ metadata, swarmIdentity, onNetworkConnection, onAuthFailure, memberKey }) {
2686
- log12.trace("dxos.echo.space-manager.construct-space", trace4.begin({
2706
+ async constructSpace({ metadata, swarmIdentity, onAuthorizedConnection, onAuthFailure, memberKey }) {
2707
+ log12.trace("dxos.echo.space-manager.construct-space", trace5.begin({
2687
2708
  id: this._instanceId
2688
2709
  }), {
2689
2710
  F: __dxlog_file13,
@@ -2705,7 +2726,7 @@ var SpaceManager = class SpaceManager2 {
2705
2726
  topic: spaceKey,
2706
2727
  swarmIdentity,
2707
2728
  networkManager: this._networkManager,
2708
- onSessionAuth: onNetworkConnection,
2729
+ onSessionAuth: onAuthorizedConnection,
2709
2730
  onAuthFailure,
2710
2731
  blobStore: this._blobStore
2711
2732
  });
@@ -2721,7 +2742,7 @@ var SpaceManager = class SpaceManager2 {
2721
2742
  memberKey
2722
2743
  });
2723
2744
  this._spaces.set(space.key, space);
2724
- log12.trace("dxos.echo.space-manager.construct-space", trace4.end({
2745
+ log12.trace("dxos.echo.space-manager.construct-space", trace5.end({
2725
2746
  id: this._instanceId
2726
2747
  }), {
2727
2748
  F: __dxlog_file13,
@@ -2743,26 +2764,120 @@ SpaceManager = _ts_decorate8([
2743
2764
  ], SpaceManager);
2744
2765
 
2745
2766
  // packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
2767
+ import { Trigger as Trigger2 } from "@dxos/async";
2768
+ import { next as automerge } from "@dxos/automerge/automerge";
2746
2769
  import { Repo, NetworkAdapter, StorageAdapter, cbor } from "@dxos/automerge/automerge-repo";
2770
+ import { IndexedDBStorageAdapter } from "@dxos/automerge/automerge-repo-storage-indexeddb";
2747
2771
  import { Stream as Stream2 } from "@dxos/codec-protobuf";
2748
2772
  import { invariant as invariant10 } from "@dxos/invariant";
2773
+ import { PublicKey as PublicKey8 } from "@dxos/keys";
2749
2774
  import { log as log13 } from "@dxos/log";
2775
+ import { StorageType } from "@dxos/random-access-storage";
2750
2776
  import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
2751
- import { arrayToBuffer as arrayToBuffer2, bufferToArray } from "@dxos/util";
2777
+ import { trace as trace6 } from "@dxos/tracing";
2778
+ import { ComplexMap as ComplexMap7, ComplexSet, arrayToBuffer as arrayToBuffer2, bufferToArray, defaultMap, mapValues } from "@dxos/util";
2779
+ function _ts_decorate9(decorators, target, key, desc) {
2780
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2781
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
2782
+ r = Reflect.decorate(decorators, target, key, desc);
2783
+ else
2784
+ for (var i = decorators.length - 1; i >= 0; i--)
2785
+ if (d = decorators[i])
2786
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2787
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2788
+ }
2752
2789
  var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
2753
2790
  var AutomergeHost = class {
2754
2791
  constructor(storageDirectory) {
2792
+ /**
2793
+ * spaceKey -> deviceKey[]
2794
+ */
2795
+ this._authorizedDevices = new ComplexMap7(PublicKey8.hash);
2755
2796
  this._meshNetwork = new MeshNetworkAdapter();
2756
2797
  this._clientNetwork = new LocalHostNetworkAdapter();
2757
- this._storage = new AutomergeStorageAdapter(storageDirectory);
2798
+ this._storage = storageDirectory.type === StorageType.IDB ? new IndexedDBStorageAdapter(storageDirectory.path, "data") : new AutomergeStorageAdapter(storageDirectory);
2758
2799
  this._repo = new Repo({
2800
+ peerId: `host-${PublicKey8.random().toHex()}`,
2759
2801
  network: [
2760
2802
  this._clientNetwork,
2761
2803
  this._meshNetwork
2762
2804
  ],
2763
2805
  storage: this._storage,
2764
2806
  // TODO(dmaretskyi): Share based on HALO permissions and space affinity.
2765
- sharePolicy: async (peerId, documentId) => true
2807
+ // Hosts, running in the worker, don't share documents unless requested by other peers.
2808
+ sharePolicy: async (peerId, documentId) => {
2809
+ if (peerId.startsWith("client-")) {
2810
+ return true;
2811
+ }
2812
+ if (!documentId) {
2813
+ return false;
2814
+ }
2815
+ const doc = this._repo.handles[documentId]?.docSync();
2816
+ if (!doc) {
2817
+ log13("doc not found for share policy check", {
2818
+ peerId,
2819
+ documentId
2820
+ }, {
2821
+ F: __dxlog_file14,
2822
+ L: 68,
2823
+ S: this,
2824
+ C: (f, a) => f(...a)
2825
+ });
2826
+ return false;
2827
+ }
2828
+ try {
2829
+ if (!doc.experimental_spaceKey) {
2830
+ log13("space key not found for share policy check", {
2831
+ peerId,
2832
+ documentId
2833
+ }, {
2834
+ F: __dxlog_file14,
2835
+ L: 74,
2836
+ S: this,
2837
+ C: (f, a) => f(...a)
2838
+ });
2839
+ return false;
2840
+ }
2841
+ const spaceKey = PublicKey8.from(doc.experimental_spaceKey);
2842
+ const authorizedDevices = this._authorizedDevices.get(spaceKey);
2843
+ const deviceKeyHex = this.repo.peerMetadataByPeerId[peerId]?.dxos_deviceKey;
2844
+ if (!deviceKeyHex) {
2845
+ log13("device key not found for share policy check", {
2846
+ peerId,
2847
+ documentId
2848
+ }, {
2849
+ F: __dxlog_file14,
2850
+ L: 84,
2851
+ S: this,
2852
+ C: (f, a) => f(...a)
2853
+ });
2854
+ return false;
2855
+ }
2856
+ const deviceKey = PublicKey8.from(deviceKeyHex);
2857
+ const isAuthorized = authorizedDevices?.has(deviceKey) ?? false;
2858
+ log13("share policy check", {
2859
+ peerId,
2860
+ documentId,
2861
+ deviceKey,
2862
+ spaceKey,
2863
+ isAuthorized
2864
+ }, {
2865
+ F: __dxlog_file14,
2866
+ L: 90,
2867
+ S: this,
2868
+ C: (f, a) => f(...a)
2869
+ });
2870
+ return isAuthorized;
2871
+ } catch (err) {
2872
+ log13.catch(err, void 0, {
2873
+ F: __dxlog_file14,
2874
+ L: 93,
2875
+ S: this,
2876
+ C: (f, a) => f(...a)
2877
+ });
2878
+ return false;
2879
+ }
2880
+ }
2766
2881
  });
2767
2882
  this._clientNetwork.ready();
2768
2883
  this._meshNetwork.ready();
@@ -2770,7 +2885,18 @@ var AutomergeHost = class {
2770
2885
  get repo() {
2771
2886
  return this._repo;
2772
2887
  }
2888
+ _automergeDocs() {
2889
+ return mapValues(this._repo.handles, (handle) => ({
2890
+ state: handle.state,
2891
+ hasDoc: !!handle.docSync(),
2892
+ heads: handle.docSync() ? automerge.getHeads(handle.docSync()) : null
2893
+ }));
2894
+ }
2895
+ _automergePeers() {
2896
+ return this._repo.peers;
2897
+ }
2773
2898
  async close() {
2899
+ this._storage instanceof AutomergeStorageAdapter && await this._storage.close();
2774
2900
  await this._clientNetwork.close();
2775
2901
  }
2776
2902
  //
@@ -2782,7 +2908,7 @@ var AutomergeHost = class {
2782
2908
  sendSyncMessage(request) {
2783
2909
  return this._clientNetwork.sendSyncMessage(request);
2784
2910
  }
2785
- getHostInfo() {
2911
+ async getHostInfo() {
2786
2912
  return this._clientNetwork.getHostInfo();
2787
2913
  }
2788
2914
  //
@@ -2791,11 +2917,28 @@ var AutomergeHost = class {
2791
2917
  createExtension() {
2792
2918
  return this._meshNetwork.createExtension();
2793
2919
  }
2920
+ authorizeDevice(spaceKey, deviceKey) {
2921
+ defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey8.hash)).add(deviceKey);
2922
+ }
2794
2923
  };
2924
+ _ts_decorate9([
2925
+ trace6.info({
2926
+ depth: null
2927
+ })
2928
+ ], AutomergeHost.prototype, "_automergeDocs", null);
2929
+ _ts_decorate9([
2930
+ trace6.info({
2931
+ depth: null
2932
+ })
2933
+ ], AutomergeHost.prototype, "_automergePeers", null);
2934
+ AutomergeHost = _ts_decorate9([
2935
+ trace6.resource()
2936
+ ], AutomergeHost);
2795
2937
  var LocalHostNetworkAdapter = class extends NetworkAdapter {
2796
2938
  constructor() {
2797
2939
  super(...arguments);
2798
2940
  this._peers = /* @__PURE__ */ new Map();
2941
+ this._connected = new Trigger2();
2799
2942
  }
2800
2943
  /**
2801
2944
  * Emits `ready` event. That signals to `Repo` that it can start using the adapter.
@@ -2807,12 +2950,13 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
2807
2950
  }
2808
2951
  connect(peerId) {
2809
2952
  this.peerId = peerId;
2953
+ this._connected.wake();
2810
2954
  }
2811
2955
  send(message) {
2812
2956
  const peer = this._peers.get(message.targetId);
2813
2957
  invariant10(peer, "Peer not found.", {
2814
2958
  F: __dxlog_file14,
2815
- L: 108,
2959
+ L: 187,
2816
2960
  S: this,
2817
2961
  A: [
2818
2962
  "peer",
@@ -2832,7 +2976,7 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
2832
2976
  return new Stream2(({ next, close }) => {
2833
2977
  invariant10(!this._peers.has(peerId), "Peer already connected.", {
2834
2978
  F: __dxlog_file14,
2835
- L: 126,
2979
+ L: 205,
2836
2980
  S: this,
2837
2981
  A: [
2838
2982
  "!this._peers.has(peerId)",
@@ -2854,19 +2998,35 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
2854
2998
  });
2855
2999
  }
2856
3000
  });
2857
- this.emit("peer-candidate", {
2858
- peerId
2859
- });
3001
+ this._connected.wait({
3002
+ timeout: 1e3
3003
+ }).then(() => {
3004
+ this.emit("peer-candidate", {
3005
+ peerMetadata: {},
3006
+ peerId
3007
+ });
3008
+ }).catch((err) => log13.catch(err, void 0, {
3009
+ F: __dxlog_file14,
3010
+ L: 230,
3011
+ S: this,
3012
+ C: (f, a) => f(...a)
3013
+ }));
2860
3014
  });
2861
3015
  }
2862
3016
  async sendSyncMessage({ id, syncMessage }) {
3017
+ await this._connected.wait({
3018
+ timeout: 1e3
3019
+ });
2863
3020
  const message = cbor.decode(syncMessage);
2864
3021
  this.emit("message", message);
2865
3022
  }
2866
- getHostInfo() {
3023
+ async getHostInfo() {
3024
+ await this._connected.wait({
3025
+ timeout: 1e3
3026
+ });
2867
3027
  invariant10(this.peerId, "Peer id not set.", {
2868
3028
  F: __dxlog_file14,
2869
- L: 155,
3029
+ L: 242,
2870
3030
  S: this,
2871
3031
  A: [
2872
3032
  "this.peerId",
@@ -2902,7 +3062,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
2902
3062
  const extension = this._extensions.get(receiverId);
2903
3063
  invariant10(extension, "Extension not found.", {
2904
3064
  F: __dxlog_file14,
2905
- L: 190,
3065
+ L: 277,
2906
3066
  S: this,
2907
3067
  A: [
2908
3068
  "extension",
@@ -2913,7 +3073,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
2913
3073
  payload: cbor.encode(message)
2914
3074
  }).catch((err) => log13.catch(err, void 0, {
2915
3075
  F: __dxlog_file14,
2916
- L: 191,
3076
+ L: 278,
2917
3077
  S: this,
2918
3078
  C: (f, a) => f(...a)
2919
3079
  }));
@@ -2923,7 +3083,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
2923
3083
  createExtension() {
2924
3084
  invariant10(this.peerId, "Peer id not set.", {
2925
3085
  F: __dxlog_file14,
2926
- L: 199,
3086
+ L: 286,
2927
3087
  S: this,
2928
3088
  A: [
2929
3089
  "this.peerId",
@@ -2934,13 +3094,17 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
2934
3094
  const extension = new AutomergeReplicator({
2935
3095
  peerId: this.peerId
2936
3096
  }, {
2937
- onStartReplication: async (info) => {
3097
+ onStartReplication: async (info, remotePeerId) => {
2938
3098
  if (this._extensions.has(info.id)) {
2939
3099
  return;
2940
3100
  }
2941
3101
  peerInfo = info;
2942
3102
  this._extensions.set(info.id, extension);
2943
3103
  this.emit("peer-candidate", {
3104
+ // TODO(mykola): Hack, stop abusing `peerMetadata` field.
3105
+ peerMetadata: {
3106
+ dxos_deviceKey: remotePeerId.toHex()
3107
+ },
2944
3108
  peerId: info.id
2945
3109
  });
2946
3110
  },
@@ -2949,9 +3113,13 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
2949
3113
  this.emit("message", message);
2950
3114
  },
2951
3115
  onClose: async () => {
2952
- peerInfo && this.emit("peer-disconnected", {
3116
+ if (!peerInfo) {
3117
+ return;
3118
+ }
3119
+ this.emit("peer-disconnected", {
2953
3120
  peerId: peerInfo.id
2954
3121
  });
3122
+ this._extensions.delete(peerInfo.id);
2955
3123
  }
2956
3124
  });
2957
3125
  return extension;
@@ -2961,8 +3129,12 @@ var AutomergeStorageAdapter = class extends StorageAdapter {
2961
3129
  constructor(_directory) {
2962
3130
  super();
2963
3131
  this._directory = _directory;
3132
+ this._state = "opened";
2964
3133
  }
2965
3134
  async load(key) {
3135
+ if (this._state !== "opened") {
3136
+ return void 0;
3137
+ }
2966
3138
  const filename = this._getFilename(key);
2967
3139
  const file = this._directory.getOrCreateFile(filename);
2968
3140
  const { size } = await file.stat();
@@ -2973,6 +3145,9 @@ var AutomergeStorageAdapter = class extends StorageAdapter {
2973
3145
  return bufferToArray(buffer);
2974
3146
  }
2975
3147
  async save(key, data) {
3148
+ if (this._state !== "opened") {
3149
+ return void 0;
3150
+ }
2976
3151
  const filename = this._getFilename(key);
2977
3152
  const file = this._directory.getOrCreateFile(filename);
2978
3153
  await file.write(0, arrayToBuffer2(data));
@@ -2980,11 +3155,17 @@ var AutomergeStorageAdapter = class extends StorageAdapter {
2980
3155
  await file.flush?.();
2981
3156
  }
2982
3157
  async remove(key) {
3158
+ if (this._state !== "opened") {
3159
+ return void 0;
3160
+ }
2983
3161
  const filename = this._getFilename(key);
2984
3162
  const file = this._directory.getOrCreateFile(filename);
2985
- await file.truncate?.(0);
3163
+ await file.destroy();
2986
3164
  }
2987
3165
  async loadRange(keyPrefix) {
3166
+ if (this._state !== "opened") {
3167
+ return [];
3168
+ }
2988
3169
  const filename = this._getFilename(keyPrefix);
2989
3170
  const entries = await this._directory.list();
2990
3171
  return Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
@@ -2998,13 +3179,19 @@ var AutomergeStorageAdapter = class extends StorageAdapter {
2998
3179
  }));
2999
3180
  }
3000
3181
  async removeRange(keyPrefix) {
3182
+ if (this._state !== "opened") {
3183
+ return void 0;
3184
+ }
3001
3185
  const filename = this._getFilename(keyPrefix);
3002
3186
  const entries = await this._directory.list();
3003
3187
  await Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
3004
- const file = this._directory.getOrCreateFile(filename);
3005
- await file.truncate?.(0);
3188
+ const file = this._directory.getOrCreateFile(entry);
3189
+ await file.destroy();
3006
3190
  }));
3007
3191
  }
3192
+ async close() {
3193
+ this._state = "closed";
3194
+ }
3008
3195
  _getFilename(key) {
3009
3196
  return key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-");
3010
3197
  }
@@ -3040,4 +3227,4 @@ export {
3040
3227
  SpaceManager,
3041
3228
  AutomergeHost
3042
3229
  };
3043
- //# sourceMappingURL=chunk-W3SSYW3X.mjs.map
3230
+ //# sourceMappingURL=chunk-D7UMNYLJ.mjs.map