@dxos/echo-pipeline 0.3.11-main.c8e9429 → 0.3.11-main.cb5abf5

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 (36) hide show
  1. package/dist/lib/browser/{chunk-44D2XTQP.mjs → chunk-IOUMNVGJ.mjs} +259 -72
  2. package/dist/lib/browser/{chunk-44D2XTQP.mjs.map → chunk-IOUMNVGJ.mjs.map} +3 -3
  3. package/dist/lib/browser/index.mjs +1 -3
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/testing/index.mjs +5 -5
  6. package/dist/lib/browser/testing/index.mjs.map +3 -3
  7. package/dist/lib/node/{chunk-PZONK23P.cjs → chunk-PDU65RAS.cjs} +253 -70
  8. package/dist/lib/node/chunk-PDU65RAS.cjs.map +7 -0
  9. package/dist/lib/node/index.cjs +26 -28
  10. package/dist/lib/node/index.cjs.map +2 -2
  11. package/dist/lib/node/meta.json +1 -1
  12. package/dist/lib/node/testing/index.cjs +20 -20
  13. package/dist/lib/node/testing/index.cjs.map +3 -3
  14. package/dist/types/src/automerge/automerge-host.d.ts +27 -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/space/data-pipeline.d.ts.map +1 -1
  19. package/dist/types/src/space/space-manager.d.ts +2 -2
  20. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  21. package/dist/types/src/space/space-protocol.d.ts.map +1 -1
  22. package/dist/types/src/space/space.d.ts +1 -1
  23. package/dist/types/src/space/space.d.ts.map +1 -1
  24. package/dist/types/src/testing/database-test-rig.d.ts.map +1 -1
  25. package/package.json +33 -33
  26. package/src/automerge/automerge-host.test.ts +353 -35
  27. package/src/automerge/automerge-host.ts +138 -21
  28. package/src/automerge/index.ts +1 -1
  29. package/src/pipeline/pipeline-stress.test.ts +9 -2
  30. package/src/space/data-pipeline.ts +4 -3
  31. package/src/space/space-manager.ts +3 -3
  32. package/src/space/space-protocol.ts +4 -0
  33. package/src/space/space.ts +8 -3
  34. package/src/testing/database-test-rig.ts +4 -1
  35. package/src/testing/test-agent-builder.ts +1 -1
  36. package/dist/lib/node/chunk-PZONK23P.cjs.map +0 -7
@@ -1602,22 +1602,23 @@ var DataPipeline = class {
1602
1602
  this._epochCtx = void 0;
1603
1603
  }
1604
1604
  async _consumePipeline() {
1605
+ const pipeline = this._pipeline;
1605
1606
  if (this.currentEpoch) {
1606
1607
  const waitForOneEpoch = this.onNewEpoch.waitForCount(1);
1607
1608
  await this._processEpochInSeparateTask(this.currentEpoch);
1608
1609
  await waitForOneEpoch;
1609
1610
  }
1610
1611
  let messageCounter = 0;
1611
- invariant8(this._pipeline, "Pipeline is not initialized.", {
1612
+ invariant8(pipeline, "Pipeline is not initialized.", {
1612
1613
  F: __dxlog_file9,
1613
- L: 228,
1614
+ L: 229,
1614
1615
  S: this,
1615
1616
  A: [
1616
- "this._pipeline",
1617
+ "pipeline",
1617
1618
  "'Pipeline is not initialized.'"
1618
1619
  ]
1619
1620
  });
1620
- for await (const msg of this._pipeline.consume()) {
1621
+ for await (const msg of pipeline.consume()) {
1621
1622
  const span = this._usage.beginRecording();
1622
1623
  this._mutations.inc();
1623
1624
  const { feedKey, seq, data } = msg;
@@ -1626,7 +1627,7 @@ var DataPipeline = class {
1626
1627
  seq
1627
1628
  }, {
1628
1629
  F: __dxlog_file9,
1629
- L: 234,
1630
+ L: 235,
1630
1631
  S: this,
1631
1632
  C: (f, a) => f(...a)
1632
1633
  });
@@ -1638,7 +1639,7 @@ var DataPipeline = class {
1638
1639
  feedKey
1639
1640
  }, {
1640
1641
  F: __dxlog_file9,
1641
- L: 240,
1642
+ L: 241,
1642
1643
  S: this,
1643
1644
  C: (f, a) => f(...a)
1644
1645
  });
@@ -1661,16 +1662,16 @@ var DataPipeline = class {
1661
1662
  spaceKey: this._params.spaceKey.toHex()
1662
1663
  }, {
1663
1664
  F: __dxlog_file9,
1664
- L: 257,
1665
+ L: 258,
1665
1666
  S: this,
1666
1667
  C: (f, a) => f(...a)
1667
1668
  });
1668
- await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);
1669
+ await this._noteTargetStateIfNeeded(pipeline.state.pendingTimeframe);
1669
1670
  }
1670
1671
  } catch (err) {
1671
1672
  log8.catch(err, void 0, {
1672
1673
  F: __dxlog_file9,
1673
- L: 267,
1674
+ L: 268,
1674
1675
  S: this,
1675
1676
  C: (f, a) => f(...a)
1676
1677
  });
@@ -1685,7 +1686,7 @@ var DataPipeline = class {
1685
1686
  _createSnapshot() {
1686
1687
  invariant8(this.databaseHost, "Database backend is not initialized.", {
1687
1688
  F: __dxlog_file9,
1688
- L: 281,
1689
+ L: 282,
1689
1690
  S: this,
1690
1691
  A: [
1691
1692
  "this.databaseHost",
@@ -1714,7 +1715,7 @@ var DataPipeline = class {
1714
1715
  } catch (err) {
1715
1716
  log8.warn("Failed to cache properties", err, {
1716
1717
  F: __dxlog_file9,
1717
- L: 310,
1718
+ L: 311,
1718
1719
  S: this,
1719
1720
  C: (f, a) => f(...a)
1720
1721
  });
@@ -1743,14 +1744,14 @@ var DataPipeline = class {
1743
1744
  if (err instanceof CancelledError) {
1744
1745
  log8("Epoch processing cancelled.", void 0, {
1745
1746
  F: __dxlog_file9,
1746
- L: 346,
1747
+ L: 347,
1747
1748
  S: this,
1748
1749
  C: (f, a) => f(...a)
1749
1750
  });
1750
1751
  } else {
1751
1752
  log8.catch(err, void 0, {
1752
1753
  F: __dxlog_file9,
1753
- L: 348,
1754
+ L: 349,
1754
1755
  S: this,
1755
1756
  C: (f, a) => f(...a)
1756
1757
  });
@@ -1773,7 +1774,7 @@ var DataPipeline = class {
1773
1774
  async _processEpoch(ctx, epoch) {
1774
1775
  invariant8(this._isOpen, "Space is closed.", {
1775
1776
  F: __dxlog_file9,
1776
- L: 372,
1777
+ L: 373,
1777
1778
  S: this,
1778
1779
  A: [
1779
1780
  "this._isOpen",
@@ -1782,7 +1783,7 @@ var DataPipeline = class {
1782
1783
  });
1783
1784
  invariant8(this._pipeline, void 0, {
1784
1785
  F: __dxlog_file9,
1785
- L: 373,
1786
+ L: 374,
1786
1787
  S: this,
1787
1788
  A: [
1788
1789
  "this._pipeline",
@@ -1794,7 +1795,7 @@ var DataPipeline = class {
1794
1795
  epoch: omit(epoch, "proof")
1795
1796
  }, {
1796
1797
  F: __dxlog_file9,
1797
- L: 376,
1798
+ L: 377,
1798
1799
  S: this,
1799
1800
  C: (f, a) => f(...a)
1800
1801
  });
@@ -1804,7 +1805,7 @@ var DataPipeline = class {
1804
1805
  }
1805
1806
  log8("restarting pipeline from epoch", void 0, {
1806
1807
  F: __dxlog_file9,
1807
- L: 382,
1808
+ L: 383,
1808
1809
  S: this,
1809
1810
  C: (f, a) => f(...a)
1810
1811
  });
@@ -1815,7 +1816,7 @@ var DataPipeline = class {
1815
1816
  async waitUntilTimeframe(timeframe) {
1816
1817
  invariant8(this._pipeline, "Pipeline is not initialized.", {
1817
1818
  F: __dxlog_file9,
1818
- L: 389,
1819
+ L: 390,
1819
1820
  S: this,
1820
1821
  A: [
1821
1822
  "this._pipeline",
@@ -1827,7 +1828,7 @@ var DataPipeline = class {
1827
1828
  async createEpoch() {
1828
1829
  invariant8(this._pipeline, void 0, {
1829
1830
  F: __dxlog_file9,
1830
- L: 395,
1831
+ L: 396,
1831
1832
  S: this,
1832
1833
  A: [
1833
1834
  "this._pipeline",
@@ -1836,7 +1837,7 @@ var DataPipeline = class {
1836
1837
  });
1837
1838
  invariant8(this.currentEpoch, void 0, {
1838
1839
  F: __dxlog_file9,
1839
- L: 396,
1840
+ L: 397,
1840
1841
  S: this,
1841
1842
  A: [
1842
1843
  "this.currentEpoch",
@@ -1867,7 +1868,7 @@ var DataPipeline = class {
1867
1868
  } catch (err) {
1868
1869
  log8.catch(err, void 0, {
1869
1870
  F: __dxlog_file9,
1870
- L: 426,
1871
+ L: 427,
1871
1872
  S: this,
1872
1873
  C: (f, a) => f(...a)
1873
1874
  });
@@ -1924,7 +1925,7 @@ var idle = async (timeout) => {
1924
1925
  };
1925
1926
 
1926
1927
  // packages/core/echo/echo-pipeline/src/space/space.ts
1927
- 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";
1928
1929
  import { invariant as invariant9 } from "@dxos/invariant";
1929
1930
  import { log as log10, logInfo } from "@dxos/log";
1930
1931
  import { AdmittedFeed as AdmittedFeed2 } from "@dxos/protocols/proto/dxos/halo/credentials";
@@ -2203,13 +2204,13 @@ function _ts_decorate6(decorators, target, key, desc) {
2203
2204
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/space.ts";
2204
2205
  var Space = class {
2205
2206
  constructor(params) {
2206
- this._addFeedLock = new Lock();
2207
+ this._addFeedMutex = new Mutex();
2207
2208
  this.onCredentialProcessed = new Callback2();
2208
2209
  this.stateUpdate = new Event5();
2209
2210
  this._isOpen = false;
2210
2211
  invariant9(params.spaceKey && params.feedProvider, void 0, {
2211
2212
  F: __dxlog_file11,
2212
- L: 73,
2213
+ L: 78,
2213
2214
  S: this,
2214
2215
  A: [
2215
2216
  "params.spaceKey && params.feedProvider",
@@ -2253,7 +2254,7 @@ var Space = class {
2253
2254
  credential
2254
2255
  }, {
2255
2256
  F: __dxlog_file11,
2256
- L: 111,
2257
+ L: 116,
2257
2258
  S: this,
2258
2259
  C: (f, a) => f(...a)
2259
2260
  });
@@ -2273,7 +2274,7 @@ var Space = class {
2273
2274
  if (this._dataFeed) {
2274
2275
  pipeline.setWriteFeed(this._dataFeed);
2275
2276
  }
2276
- await this._addFeedLock.executeSynchronized(async () => {
2277
+ await this._addFeedMutex.executeSynchronized(async () => {
2277
2278
  for (const feed of this._controlPipeline.spaceState.feeds.values()) {
2278
2279
  if (feed.assertion.designation === AdmittedFeed2.Designation.DATA && !pipeline.hasFeed(feed.key)) {
2279
2280
  await pipeline.addFeed(await this._feedProvider(feed.key, {
@@ -2318,7 +2319,7 @@ var Space = class {
2318
2319
  setControlFeed(feed) {
2319
2320
  invariant9(!this._controlFeed, "Control feed already set.", {
2320
2321
  F: __dxlog_file11,
2321
- L: 186,
2322
+ L: 191,
2322
2323
  S: this,
2323
2324
  A: [
2324
2325
  "!this._controlFeed",
@@ -2332,7 +2333,7 @@ var Space = class {
2332
2333
  setDataFeed(feed) {
2333
2334
  invariant9(!this._dataFeed, "Data feed already set.", {
2334
2335
  F: __dxlog_file11,
2335
- L: 193,
2336
+ L: 198,
2336
2337
  S: this,
2337
2338
  A: [
2338
2339
  "!this._dataFeed",
@@ -2358,7 +2359,7 @@ var Space = class {
2358
2359
  async open(ctx) {
2359
2360
  log10("opening...", void 0, {
2360
2361
  F: __dxlog_file11,
2361
- L: 215,
2362
+ L: 220,
2362
2363
  S: this,
2363
2364
  C: (f, a) => f(...a)
2364
2365
  });
@@ -2371,7 +2372,7 @@ var Space = class {
2371
2372
  this._isOpen = true;
2372
2373
  log10("opened", void 0, {
2373
2374
  F: __dxlog_file11,
2374
- L: 226,
2375
+ L: 231,
2375
2376
  S: this,
2376
2377
  C: (f, a) => f(...a)
2377
2378
  });
@@ -2381,7 +2382,7 @@ var Space = class {
2381
2382
  key: this._key
2382
2383
  }, {
2383
2384
  F: __dxlog_file11,
2384
- L: 231,
2385
+ L: 236,
2385
2386
  S: this,
2386
2387
  C: (f, a) => f(...a)
2387
2388
  });
@@ -2395,7 +2396,7 @@ var Space = class {
2395
2396
  this._isOpen = false;
2396
2397
  log10("closed", void 0, {
2397
2398
  F: __dxlog_file11,
2398
- L: 244,
2399
+ L: 249,
2399
2400
  S: this,
2400
2401
  C: (f, a) => f(...a)
2401
2402
  });
@@ -2403,13 +2404,13 @@ var Space = class {
2403
2404
  async initializeDataPipeline() {
2404
2405
  log10("initializeDataPipeline", void 0, {
2405
2406
  F: __dxlog_file11,
2406
- L: 249,
2407
+ L: 254,
2407
2408
  S: this,
2408
2409
  C: (f, a) => f(...a)
2409
2410
  });
2410
2411
  invariant9(this._isOpen, "Space must be open to initialize data pipeline.", {
2411
2412
  F: __dxlog_file11,
2412
- L: 250,
2413
+ L: 255,
2413
2414
  S: this,
2414
2415
  A: [
2415
2416
  "this._isOpen",
@@ -2419,6 +2420,15 @@ var Space = class {
2419
2420
  await this._dataPipeline.open();
2420
2421
  }
2421
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);
2422
2432
  _ts_decorate6([
2423
2433
  logInfo,
2424
2434
  trace3.info()
@@ -2446,6 +2456,7 @@ import { MMSTTopology } from "@dxos/network-manager";
2446
2456
  import { Teleport } from "@dxos/teleport";
2447
2457
  import { BlobSync } from "@dxos/teleport-extension-object-sync";
2448
2458
  import { ReplicatorExtension } from "@dxos/teleport-extension-replicator";
2459
+ import { trace as trace4 } from "@dxos/tracing";
2449
2460
  import { ComplexMap as ComplexMap5 } from "@dxos/util";
2450
2461
  function _ts_decorate7(decorators, target, key, desc) {
2451
2462
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -2489,7 +2500,7 @@ var SpaceProtocol = class {
2489
2500
  key: feed.key
2490
2501
  }, {
2491
2502
  F: __dxlog_file12,
2492
- L: 99,
2503
+ L: 103,
2493
2504
  S: this,
2494
2505
  C: (f, a) => f(...a)
2495
2506
  });
@@ -2512,7 +2523,7 @@ var SpaceProtocol = class {
2512
2523
  await this.blobSync.open();
2513
2524
  log11("starting...", void 0, {
2514
2525
  F: __dxlog_file12,
2515
- L: 125,
2526
+ L: 129,
2516
2527
  S: this,
2517
2528
  C: (f, a) => f(...a)
2518
2529
  });
@@ -2526,7 +2537,7 @@ var SpaceProtocol = class {
2526
2537
  });
2527
2538
  log11("started", void 0, {
2528
2539
  F: __dxlog_file12,
2529
- L: 135,
2540
+ L: 139,
2530
2541
  S: this,
2531
2542
  C: (f, a) => f(...a)
2532
2543
  });
@@ -2536,14 +2547,14 @@ var SpaceProtocol = class {
2536
2547
  if (this._connection) {
2537
2548
  log11("stopping...", void 0, {
2538
2549
  F: __dxlog_file12,
2539
- L: 142,
2550
+ L: 146,
2540
2551
  S: this,
2541
2552
  C: (f, a) => f(...a)
2542
2553
  });
2543
2554
  await this._connection.close();
2544
2555
  log11("stopped", void 0, {
2545
2556
  F: __dxlog_file12,
2546
- L: 144,
2557
+ L: 148,
2547
2558
  S: this,
2548
2559
  C: (f, a) => f(...a)
2549
2560
  });
@@ -2567,11 +2578,18 @@ var SpaceProtocol = class {
2567
2578
  }
2568
2579
  };
2569
2580
  _ts_decorate7([
2570
- logInfo2
2581
+ logInfo2,
2582
+ trace4.info()
2571
2583
  ], SpaceProtocol.prototype, "_topic", void 0);
2584
+ _ts_decorate7([
2585
+ trace4.info()
2586
+ ], SpaceProtocol.prototype, "_spaceKey", void 0);
2572
2587
  _ts_decorate7([
2573
2588
  logInfo2
2574
2589
  ], SpaceProtocol.prototype, "_ownPeerKey", null);
2590
+ SpaceProtocol = _ts_decorate7([
2591
+ trace4.resource()
2592
+ ], SpaceProtocol);
2575
2593
  var AuthStatus;
2576
2594
  (function(AuthStatus2) {
2577
2595
  AuthStatus2["INITIAL"] = "INITIAL";
@@ -2610,7 +2628,7 @@ var SpaceProtocolSession = class {
2610
2628
  onAuthSuccess: () => {
2611
2629
  log11("Peer authenticated", void 0, {
2612
2630
  F: __dxlog_file12,
2613
- L: 241,
2631
+ L: 245,
2614
2632
  S: this,
2615
2633
  C: (f, a) => f(...a)
2616
2634
  });
@@ -2628,7 +2646,7 @@ var SpaceProtocolSession = class {
2628
2646
  async close() {
2629
2647
  log11("close", void 0, {
2630
2648
  F: __dxlog_file12,
2631
- L: 257,
2649
+ L: 261,
2632
2650
  S: this,
2633
2651
  C: (f, a) => f(...a)
2634
2652
  });
@@ -2650,7 +2668,7 @@ import { synchronized as synchronized5, trackLeaks as trackLeaks4 } from "@dxos/
2650
2668
  import { failUndefined as failUndefined2 } from "@dxos/debug";
2651
2669
  import { PublicKey as PublicKey7 } from "@dxos/keys";
2652
2670
  import { log as log12 } from "@dxos/log";
2653
- import { trace as trace4 } from "@dxos/protocols";
2671
+ import { trace as trace5 } from "@dxos/protocols";
2654
2672
  import { ComplexMap as ComplexMap6 } from "@dxos/util";
2655
2673
  function _ts_decorate8(decorators, target, key, desc) {
2656
2674
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -2685,8 +2703,8 @@ var SpaceManager = class {
2685
2703
  ...this._spaces.values()
2686
2704
  ].map((space) => space.close()));
2687
2705
  }
2688
- async constructSpace({ metadata, swarmIdentity, onNetworkConnection, onAuthFailure, memberKey }) {
2689
- 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({
2690
2708
  id: this._instanceId
2691
2709
  }), {
2692
2710
  F: __dxlog_file13,
@@ -2708,7 +2726,7 @@ var SpaceManager = class {
2708
2726
  topic: spaceKey,
2709
2727
  swarmIdentity,
2710
2728
  networkManager: this._networkManager,
2711
- onSessionAuth: onNetworkConnection,
2729
+ onSessionAuth: onAuthorizedConnection,
2712
2730
  onAuthFailure,
2713
2731
  blobStore: this._blobStore
2714
2732
  });
@@ -2724,7 +2742,7 @@ var SpaceManager = class {
2724
2742
  memberKey
2725
2743
  });
2726
2744
  this._spaces.set(space.key, space);
2727
- log12.trace("dxos.echo.space-manager.construct-space", trace4.end({
2745
+ log12.trace("dxos.echo.space-manager.construct-space", trace5.end({
2728
2746
  id: this._instanceId
2729
2747
  }), {
2730
2748
  F: __dxlog_file13,
@@ -2746,28 +2764,120 @@ SpaceManager = _ts_decorate8([
2746
2764
  ], SpaceManager);
2747
2765
 
2748
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";
2749
2769
  import { Repo, NetworkAdapter, StorageAdapter, cbor } from "@dxos/automerge/automerge-repo";
2750
2770
  import { IndexedDBStorageAdapter } from "@dxos/automerge/automerge-repo-storage-indexeddb";
2751
2771
  import { Stream as Stream2 } from "@dxos/codec-protobuf";
2752
2772
  import { invariant as invariant10 } from "@dxos/invariant";
2773
+ import { PublicKey as PublicKey8 } from "@dxos/keys";
2753
2774
  import { log as log13 } from "@dxos/log";
2754
2775
  import { StorageType } from "@dxos/random-access-storage";
2755
2776
  import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
2756
- 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
+ }
2757
2789
  var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
2758
2790
  var AutomergeHost = class {
2759
2791
  constructor(storageDirectory) {
2792
+ /**
2793
+ * spaceKey -> deviceKey[]
2794
+ */
2795
+ this._authorizedDevices = new ComplexMap7(PublicKey8.hash);
2760
2796
  this._meshNetwork = new MeshNetworkAdapter();
2761
2797
  this._clientNetwork = new LocalHostNetworkAdapter();
2762
2798
  this._storage = storageDirectory.type === StorageType.IDB ? new IndexedDBStorageAdapter(storageDirectory.path, "data") : new AutomergeStorageAdapter(storageDirectory);
2763
2799
  this._repo = new Repo({
2800
+ peerId: `host-${PublicKey8.random().toHex()}`,
2764
2801
  network: [
2765
2802
  this._clientNetwork,
2766
2803
  this._meshNetwork
2767
2804
  ],
2768
2805
  storage: this._storage,
2769
2806
  // TODO(dmaretskyi): Share based on HALO permissions and space affinity.
2770
- 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
+ }
2771
2881
  });
2772
2882
  this._clientNetwork.ready();
2773
2883
  this._meshNetwork.ready();
@@ -2775,7 +2885,18 @@ var AutomergeHost = class {
2775
2885
  get repo() {
2776
2886
  return this._repo;
2777
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
+ }
2778
2898
  async close() {
2899
+ this._storage instanceof AutomergeStorageAdapter && await this._storage.close();
2779
2900
  await this._clientNetwork.close();
2780
2901
  }
2781
2902
  //
@@ -2787,7 +2908,7 @@ var AutomergeHost = class {
2787
2908
  sendSyncMessage(request) {
2788
2909
  return this._clientNetwork.sendSyncMessage(request);
2789
2910
  }
2790
- getHostInfo() {
2911
+ async getHostInfo() {
2791
2912
  return this._clientNetwork.getHostInfo();
2792
2913
  }
2793
2914
  //
@@ -2796,11 +2917,28 @@ var AutomergeHost = class {
2796
2917
  createExtension() {
2797
2918
  return this._meshNetwork.createExtension();
2798
2919
  }
2920
+ authorizeDevice(spaceKey, deviceKey) {
2921
+ defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey8.hash)).add(deviceKey);
2922
+ }
2799
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);
2800
2937
  var LocalHostNetworkAdapter = class extends NetworkAdapter {
2801
2938
  constructor() {
2802
2939
  super(...arguments);
2803
2940
  this._peers = /* @__PURE__ */ new Map();
2941
+ this._connected = new Trigger2();
2804
2942
  }
2805
2943
  /**
2806
2944
  * Emits `ready` event. That signals to `Repo` that it can start using the adapter.
@@ -2812,12 +2950,13 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
2812
2950
  }
2813
2951
  connect(peerId) {
2814
2952
  this.peerId = peerId;
2953
+ this._connected.wake();
2815
2954
  }
2816
2955
  send(message) {
2817
2956
  const peer = this._peers.get(message.targetId);
2818
2957
  invariant10(peer, "Peer not found.", {
2819
2958
  F: __dxlog_file14,
2820
- L: 114,
2959
+ L: 187,
2821
2960
  S: this,
2822
2961
  A: [
2823
2962
  "peer",
@@ -2837,7 +2976,7 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
2837
2976
  return new Stream2(({ next, close }) => {
2838
2977
  invariant10(!this._peers.has(peerId), "Peer already connected.", {
2839
2978
  F: __dxlog_file14,
2840
- L: 132,
2979
+ L: 205,
2841
2980
  S: this,
2842
2981
  A: [
2843
2982
  "!this._peers.has(peerId)",
@@ -2859,19 +2998,35 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
2859
2998
  });
2860
2999
  }
2861
3000
  });
2862
- this.emit("peer-candidate", {
2863
- peerId
2864
- });
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
+ }));
2865
3014
  });
2866
3015
  }
2867
3016
  async sendSyncMessage({ id, syncMessage }) {
3017
+ await this._connected.wait({
3018
+ timeout: 1e3
3019
+ });
2868
3020
  const message = cbor.decode(syncMessage);
2869
3021
  this.emit("message", message);
2870
3022
  }
2871
- getHostInfo() {
3023
+ async getHostInfo() {
3024
+ await this._connected.wait({
3025
+ timeout: 1e3
3026
+ });
2872
3027
  invariant10(this.peerId, "Peer id not set.", {
2873
3028
  F: __dxlog_file14,
2874
- L: 161,
3029
+ L: 242,
2875
3030
  S: this,
2876
3031
  A: [
2877
3032
  "this.peerId",
@@ -2890,6 +3045,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
2890
3045
  constructor() {
2891
3046
  super(...arguments);
2892
3047
  this._extensions = /* @__PURE__ */ new Map();
3048
+ this._connected = new Trigger2();
2893
3049
  }
2894
3050
  /**
2895
3051
  * Emits `ready` event. That signals to `Repo` that it can start using the adapter.
@@ -2901,13 +3057,14 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
2901
3057
  }
2902
3058
  connect(peerId) {
2903
3059
  this.peerId = peerId;
3060
+ this._connected.wake();
2904
3061
  }
2905
3062
  send(message) {
2906
3063
  const receiverId = message.targetId;
2907
3064
  const extension = this._extensions.get(receiverId);
2908
3065
  invariant10(extension, "Extension not found.", {
2909
3066
  F: __dxlog_file14,
2910
- L: 196,
3067
+ L: 279,
2911
3068
  S: this,
2912
3069
  A: [
2913
3070
  "extension",
@@ -2918,7 +3075,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
2918
3075
  payload: cbor.encode(message)
2919
3076
  }).catch((err) => log13.catch(err, void 0, {
2920
3077
  F: __dxlog_file14,
2921
- L: 197,
3078
+ L: 280,
2922
3079
  S: this,
2923
3080
  C: (f, a) => f(...a)
2924
3081
  }));
@@ -2928,7 +3085,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
2928
3085
  createExtension() {
2929
3086
  invariant10(this.peerId, "Peer id not set.", {
2930
3087
  F: __dxlog_file14,
2931
- L: 205,
3088
+ L: 288,
2932
3089
  S: this,
2933
3090
  A: [
2934
3091
  "this.peerId",
@@ -2939,13 +3096,21 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
2939
3096
  const extension = new AutomergeReplicator({
2940
3097
  peerId: this.peerId
2941
3098
  }, {
2942
- onStartReplication: async (info) => {
2943
- if (this._extensions.has(info.id)) {
2944
- return;
3099
+ onStartReplication: async (info, remotePeerId) => {
3100
+ await this._connected.wait();
3101
+ if (!this._extensions.has(info.id)) {
3102
+ peerInfo = info;
3103
+ this._extensions.set(info.id, extension);
3104
+ } else {
3105
+ this.emit("peer-disconnected", {
3106
+ peerId: info.id
3107
+ });
2945
3108
  }
2946
- peerInfo = info;
2947
- this._extensions.set(info.id, extension);
2948
3109
  this.emit("peer-candidate", {
3110
+ // TODO(mykola): Hack, stop abusing `peerMetadata` field.
3111
+ peerMetadata: {
3112
+ dxos_deviceKey: remotePeerId.toHex()
3113
+ },
2949
3114
  peerId: info.id
2950
3115
  });
2951
3116
  },
@@ -2954,9 +3119,13 @@ var MeshNetworkAdapter = class extends NetworkAdapter {
2954
3119
  this.emit("message", message);
2955
3120
  },
2956
3121
  onClose: async () => {
2957
- peerInfo && this.emit("peer-disconnected", {
3122
+ if (!peerInfo) {
3123
+ return;
3124
+ }
3125
+ this.emit("peer-disconnected", {
2958
3126
  peerId: peerInfo.id
2959
3127
  });
3128
+ this._extensions.delete(peerInfo.id);
2960
3129
  }
2961
3130
  });
2962
3131
  return extension;
@@ -2966,8 +3135,12 @@ var AutomergeStorageAdapter = class extends StorageAdapter {
2966
3135
  constructor(_directory) {
2967
3136
  super();
2968
3137
  this._directory = _directory;
3138
+ this._state = "opened";
2969
3139
  }
2970
3140
  async load(key) {
3141
+ if (this._state !== "opened") {
3142
+ return void 0;
3143
+ }
2971
3144
  const filename = this._getFilename(key);
2972
3145
  const file = this._directory.getOrCreateFile(filename);
2973
3146
  const { size } = await file.stat();
@@ -2978,6 +3151,9 @@ var AutomergeStorageAdapter = class extends StorageAdapter {
2978
3151
  return bufferToArray(buffer);
2979
3152
  }
2980
3153
  async save(key, data) {
3154
+ if (this._state !== "opened") {
3155
+ return void 0;
3156
+ }
2981
3157
  const filename = this._getFilename(key);
2982
3158
  const file = this._directory.getOrCreateFile(filename);
2983
3159
  await file.write(0, arrayToBuffer2(data));
@@ -2985,11 +3161,17 @@ var AutomergeStorageAdapter = class extends StorageAdapter {
2985
3161
  await file.flush?.();
2986
3162
  }
2987
3163
  async remove(key) {
3164
+ if (this._state !== "opened") {
3165
+ return void 0;
3166
+ }
2988
3167
  const filename = this._getFilename(key);
2989
3168
  const file = this._directory.getOrCreateFile(filename);
2990
- await file.truncate?.(0);
3169
+ await file.destroy();
2991
3170
  }
2992
3171
  async loadRange(keyPrefix) {
3172
+ if (this._state !== "opened") {
3173
+ return [];
3174
+ }
2993
3175
  const filename = this._getFilename(keyPrefix);
2994
3176
  const entries = await this._directory.list();
2995
3177
  return Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
@@ -3003,13 +3185,19 @@ var AutomergeStorageAdapter = class extends StorageAdapter {
3003
3185
  }));
3004
3186
  }
3005
3187
  async removeRange(keyPrefix) {
3188
+ if (this._state !== "opened") {
3189
+ return void 0;
3190
+ }
3006
3191
  const filename = this._getFilename(keyPrefix);
3007
3192
  const entries = await this._directory.list();
3008
3193
  await Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
3009
- const file = this._directory.getOrCreateFile(filename);
3010
- await file.truncate?.(0);
3194
+ const file = this._directory.getOrCreateFile(entry);
3195
+ await file.destroy();
3011
3196
  }));
3012
3197
  }
3198
+ async close() {
3199
+ this._state = "closed";
3200
+ }
3013
3201
  _getFilename(key) {
3014
3202
  return key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-");
3015
3203
  }
@@ -3043,7 +3231,6 @@ export {
3043
3231
  AuthStatus,
3044
3232
  SpaceProtocolSession,
3045
3233
  SpaceManager,
3046
- AutomergeHost,
3047
- AutomergeStorageAdapter
3234
+ AutomergeHost
3048
3235
  };
3049
- //# sourceMappingURL=chunk-44D2XTQP.mjs.map
3236
+ //# sourceMappingURL=chunk-IOUMNVGJ.mjs.map