@dxos/client-services 0.1.31-next.ea8f0bc → 0.1.32-next.77d513e

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 (57) hide show
  1. package/dist/lib/browser/{chunk-ZIQUYEJS.mjs → chunk-E3FD43YN.mjs} +460 -213
  2. package/dist/lib/browser/chunk-E3FD43YN.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/packlets/testing/index.mjs +64 -6
  6. package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
  7. package/dist/lib/node/index.cjs +462 -215
  8. package/dist/lib/node/index.cjs.map +3 -3
  9. package/dist/lib/node/meta.json +1 -1
  10. package/dist/lib/node/packlets/testing/index.cjs +524 -218
  11. package/dist/lib/node/packlets/testing/index.cjs.map +3 -3
  12. package/dist/types/src/packlets/identity/identity-manager.d.ts +6 -0
  13. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  14. package/dist/types/src/packlets/invitations/device-invitations-handler.d.ts.map +1 -1
  15. package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts.map +1 -1
  16. package/dist/types/src/packlets/services/service-host.d.ts +1 -0
  17. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  18. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +19 -1
  19. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  20. package/dist/types/src/packlets/spaces/data-space.d.ts +32 -5
  21. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  22. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +29 -1
  23. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  24. package/dist/types/src/packlets/spaces/spaces-service.d.ts +4 -1
  25. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  26. package/dist/types/src/packlets/testing/host-test-builder.d.ts +2 -2
  27. package/dist/types/src/packlets/testing/host-test-builder.d.ts.map +1 -1
  28. package/dist/types/src/packlets/testing/test-builder.d.ts +2 -0
  29. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  30. package/dist/types/src/packlets/tests/text.test.d.ts +2 -0
  31. package/dist/types/src/packlets/tests/text.test.d.ts.map +1 -0
  32. package/dist/types/src/packlets/vault/vault-resource-lock.d.ts +1 -0
  33. package/dist/types/src/packlets/vault/vault-resource-lock.d.ts.map +1 -1
  34. package/package.json +31 -30
  35. package/src/packlets/identity/identity-manager.ts +32 -17
  36. package/src/packlets/invitations/device-invitations-handler.ts +5 -3
  37. package/src/packlets/invitations/space-invitations-handler.test.ts +20 -3
  38. package/src/packlets/invitations/space-invitations-handler.ts +15 -8
  39. package/src/packlets/services/service-context.test.ts +6 -5
  40. package/src/packlets/services/service-host.ts +7 -2
  41. package/src/packlets/spaces/data-space-manager.test.ts +77 -2
  42. package/src/packlets/spaces/data-space-manager.ts +87 -37
  43. package/src/packlets/spaces/data-space.ts +103 -16
  44. package/src/packlets/spaces/notarization-plugin.test.ts +3 -1
  45. package/src/packlets/spaces/notarization-plugin.ts +67 -19
  46. package/src/packlets/spaces/spaces-service.test.ts +1 -1
  47. package/src/packlets/spaces/spaces-service.ts +53 -17
  48. package/src/packlets/testing/host-test-builder.ts +2 -2
  49. package/src/packlets/testing/test-builder.ts +45 -5
  50. package/src/packlets/tests/client-services.test.ts +24 -11
  51. package/src/packlets/tests/client.test.ts +3 -6
  52. package/src/packlets/tests/halo-profile.test.ts +5 -5
  53. package/src/packlets/tests/spaces-invitations.test.ts +47 -7
  54. package/src/packlets/tests/spaces.test.ts +86 -9
  55. package/src/packlets/tests/text.test.ts +206 -0
  56. package/src/packlets/vault/vault-resource-lock.ts +10 -1
  57. package/dist/lib/browser/chunk-ZIQUYEJS.mjs.map +0 -7
@@ -587,7 +587,7 @@ var IdentityManager = class {
587
587
  identityRecord
588
588
  }, {
589
589
  file: "identity-manager.ts",
590
- line: 63,
590
+ line: 71,
591
591
  scope: this,
592
592
  callSite: (f, a) => f(...a)
593
593
  });
@@ -606,7 +606,7 @@ var IdentityManager = class {
606
606
  assert2(!this._identity, "Identity already exists.");
607
607
  log3("creating identity...", {}, {
608
608
  file: "identity-manager.ts",
609
- line: 78,
609
+ line: 86,
610
610
  scope: this,
611
611
  callSite: (f, a) => f(...a)
612
612
  });
@@ -615,21 +615,23 @@ var IdentityManager = class {
615
615
  identityKey: await this._keyring.createKey(),
616
616
  deviceKey: await this._keyring.createKey(),
617
617
  haloSpace: {
618
- spaceKey: await this._keyring.createKey(),
618
+ key: await this._keyring.createKey(),
619
619
  genesisFeedKey: controlFeedKey,
620
- writeControlFeedKey: controlFeedKey,
621
- writeDataFeedKey: await this._keyring.createKey()
620
+ controlFeedKey,
621
+ dataFeedKey: await this._keyring.createKey()
622
622
  }
623
623
  };
624
624
  const identity = await this._constructIdentity(identityRecord);
625
625
  await identity.open();
626
626
  {
627
627
  const generator = new CredentialGenerator(this._keyring, identityRecord.identityKey, identityRecord.deviceKey);
628
+ assert2(identityRecord.haloSpace.genesisFeedKey, "Genesis feed key is required.");
629
+ assert2(identityRecord.haloSpace.dataFeedKey, "Data feed key is required.");
628
630
  const credentials = [
629
631
  // Space genesis.
630
- ...await generator.createSpaceGenesis(identityRecord.haloSpace.spaceKey, identityRecord.haloSpace.genesisFeedKey),
632
+ ...await generator.createSpaceGenesis(identityRecord.haloSpace.key, identityRecord.haloSpace.genesisFeedKey),
631
633
  // Feed admission.
632
- await generator.createFeedAdmission(identityRecord.haloSpace.spaceKey, identityRecord.haloSpace.writeDataFeedKey, AdmittedFeed2.Designation.DATA)
634
+ await generator.createFeedAdmission(identityRecord.haloSpace.key, identityRecord.haloSpace.dataFeedKey, AdmittedFeed2.Designation.DATA)
633
635
  ];
634
636
  if (displayName) {
635
637
  credentials.push(await generator.createProfileCredential({
@@ -654,7 +656,7 @@ var IdentityManager = class {
654
656
  deviceKey: identity.deviceKey
655
657
  }, {
656
658
  file: "identity-manager.ts",
657
- line: 136,
659
+ line: 143,
658
660
  scope: this,
659
661
  callSite: (f, a) => f(...a)
660
662
  });
@@ -668,7 +670,7 @@ var IdentityManager = class {
668
670
  params
669
671
  }, {
670
672
  file: "identity-manager.ts",
671
- line: 144,
673
+ line: 151,
672
674
  scope: this,
673
675
  callSite: (f, a) => f(...a)
674
676
  });
@@ -677,10 +679,11 @@ var IdentityManager = class {
677
679
  identityKey: params.identityKey,
678
680
  deviceKey: params.deviceKey,
679
681
  haloSpace: {
680
- spaceKey: params.haloSpaceKey,
682
+ key: params.haloSpaceKey,
681
683
  genesisFeedKey: params.haloGenesisFeedKey,
682
- writeControlFeedKey: params.controlFeedKey,
683
- writeDataFeedKey: params.dataFeedKey
684
+ controlFeedKey: params.controlFeedKey,
685
+ dataFeedKey: params.dataFeedKey,
686
+ controlTimeframe: params.controlTimeframe
684
687
  }
685
688
  };
686
689
  const identity = await this._constructIdentity(identityRecord);
@@ -694,7 +697,7 @@ var IdentityManager = class {
694
697
  deviceKey: identity.deviceKey
695
698
  }, {
696
699
  file: "identity-manager.ts",
697
- line: 164,
700
+ line: 172,
698
701
  scope: this,
699
702
  callSite: (f, a) => f(...a)
700
703
  });
@@ -706,14 +709,16 @@ var IdentityManager = class {
706
709
  identityRecord
707
710
  }, {
708
711
  file: "identity-manager.ts",
709
- line: 170,
712
+ line: 178,
710
713
  scope: this,
711
714
  callSite: (f, a) => f(...a)
712
715
  });
713
- const controlFeed = await this._feedStore.openFeed(identityRecord.haloSpace.writeControlFeedKey, {
716
+ assert2(identityRecord.haloSpace.controlFeedKey);
717
+ const controlFeed = await this._feedStore.openFeed(identityRecord.haloSpace.controlFeedKey, {
714
718
  writable: true
715
719
  });
716
- const dataFeed = await this._feedStore.openFeed(identityRecord.haloSpace.writeDataFeedKey, {
720
+ assert2(identityRecord.haloSpace.dataFeedKey);
721
+ const dataFeed = await this._feedStore.openFeed(identityRecord.haloSpace.dataFeedKey, {
717
722
  writable: true
718
723
  });
719
724
  const space = await this._constructSpace({
@@ -737,16 +742,19 @@ var IdentityManager = class {
737
742
  identityKey: identityRecord.identityKey
738
743
  }, {
739
744
  file: "identity-manager.ts",
740
- line: 196,
745
+ line: 206,
741
746
  scope: this,
742
747
  callSite: (f, a) => f(...a)
743
748
  });
749
+ if (identityRecord.haloSpace.controlTimeframe) {
750
+ identity.controlPipeline.state.setTargetTimeframe(identityRecord.haloSpace.controlTimeframe);
751
+ }
744
752
  return identity;
745
753
  }
746
754
  async _constructSpace({ spaceRecord, swarmIdentity, identityKey }) {
747
755
  return this._spaceManager.constructSpace({
748
756
  metadata: {
749
- key: spaceRecord.spaceKey,
757
+ key: spaceRecord.key,
750
758
  genesisFeedKey: spaceRecord.genesisFeedKey
751
759
  },
752
760
  swarmIdentity,
@@ -862,7 +870,8 @@ var DeviceInvitationsHandler = class extends AbstractInvitationsHandler {
862
870
  return {
863
871
  identityKey: identity.identityKey,
864
872
  haloSpaceKey: identity.haloSpaceKey,
865
- genesisFeedKey: identity.haloGenesisFeedKey
873
+ genesisFeedKey: identity.haloGenesisFeedKey,
874
+ controlTimeframe: identity.controlPipeline.state.timeframe
866
875
  };
867
876
  },
868
877
  authenticate: async ({ authenticationCode: code }) => {
@@ -870,7 +879,7 @@ var DeviceInvitationsHandler = class extends AbstractInvitationsHandler {
870
879
  authenticationCode: code
871
880
  }, {
872
881
  file: "device-invitations-handler.ts",
873
- line: 106,
882
+ line: 107,
874
883
  scope: this,
875
884
  callSite: (f, a) => f(...a)
876
885
  });
@@ -892,7 +901,7 @@ var DeviceInvitationsHandler = class extends AbstractInvitationsHandler {
892
901
  guest: credentials.deviceKey
893
902
  }, {
894
903
  file: "device-invitations-handler.ts",
895
- line: 121,
904
+ line: 122,
896
905
  scope: this,
897
906
  callSite: (f, a) => f(...a)
898
907
  });
@@ -911,7 +920,7 @@ var DeviceInvitationsHandler = class extends AbstractInvitationsHandler {
911
920
  host: identity.deviceKey
912
921
  }, {
913
922
  file: "device-invitations-handler.ts",
914
- line: 137,
923
+ line: 138,
915
924
  scope: this,
916
925
  callSite: (f, a) => f(...a)
917
926
  });
@@ -924,7 +933,7 @@ var DeviceInvitationsHandler = class extends AbstractInvitationsHandler {
924
933
  guest: deviceKey
925
934
  }, {
926
935
  file: "device-invitations-handler.ts",
927
- line: 140,
936
+ line: 141,
928
937
  scope: this,
929
938
  callSite: (f, a) => f(...a)
930
939
  });
@@ -933,7 +942,7 @@ var DeviceInvitationsHandler = class extends AbstractInvitationsHandler {
933
942
  if (!observable.cancelled) {
934
943
  log4.error("failed", err, {
935
944
  file: "device-invitations-handler.ts",
936
- line: 144,
945
+ line: 145,
937
946
  scope: this,
938
947
  callSite: (f, a) => f(...a)
939
948
  });
@@ -998,22 +1007,22 @@ var DeviceInvitationsHandler = class extends AbstractInvitationsHandler {
998
1007
  }
999
1008
  log4("connected", {}, {
1000
1009
  file: "device-invitations-handler.ts",
1001
- line: 215,
1010
+ line: 216,
1002
1011
  scope: this,
1003
1012
  callSite: (f, a) => f(...a)
1004
1013
  });
1005
1014
  (_b = (_a = observable.callback).onConnected) == null ? void 0 : _b.call(_a, invitation);
1006
1015
  log4("sending admission request", {}, {
1007
1016
  file: "device-invitations-handler.ts",
1008
- line: 219,
1017
+ line: 220,
1009
1018
  scope: this,
1010
1019
  callSite: (f, a) => f(...a)
1011
1020
  });
1012
- const { identityKey, haloSpaceKey, genesisFeedKey } = await extension.rpc.HaloHostService.requestAdmission();
1021
+ const { identityKey, haloSpaceKey, genesisFeedKey, controlTimeframe } = await extension.rpc.HaloHostService.requestAdmission();
1013
1022
  if (invitation.type === void 0 || invitation.type === Invitation.Type.INTERACTIVE) {
1014
1023
  log4("guest waiting for authentication code...", {}, {
1015
1024
  file: "device-invitations-handler.ts",
1016
- line: 226,
1025
+ line: 227,
1017
1026
  scope: this,
1018
1027
  callSite: (f, a) => f(...a)
1019
1028
  });
@@ -1023,7 +1032,7 @@ var DeviceInvitationsHandler = class extends AbstractInvitationsHandler {
1023
1032
  });
1024
1033
  log4("sending authentication request", {}, {
1025
1034
  file: "device-invitations-handler.ts",
1026
- line: 229,
1035
+ line: 230,
1027
1036
  scope: this,
1028
1037
  callSite: (f, a) => f(...a)
1029
1038
  });
@@ -1041,7 +1050,7 @@ var DeviceInvitationsHandler = class extends AbstractInvitationsHandler {
1041
1050
  dataFeedKey
1042
1051
  }, {
1043
1052
  file: "device-invitations-handler.ts",
1044
- line: 238,
1053
+ line: 239,
1045
1054
  scope: this,
1046
1055
  callSite: (f, a) => f(...a)
1047
1056
  });
@@ -1056,14 +1065,15 @@ var DeviceInvitationsHandler = class extends AbstractInvitationsHandler {
1056
1065
  haloSpaceKey,
1057
1066
  haloGenesisFeedKey: genesisFeedKey,
1058
1067
  controlFeedKey,
1059
- dataFeedKey
1068
+ dataFeedKey,
1069
+ controlTimeframe
1060
1070
  });
1061
1071
  log4("admitted by host", {
1062
1072
  guest: identity.deviceKey,
1063
1073
  identityKey
1064
1074
  }, {
1065
1075
  file: "device-invitations-handler.ts",
1066
- line: 257,
1076
+ line: 259,
1067
1077
  scope: this,
1068
1078
  callSite: (f, a) => f(...a)
1069
1079
  });
@@ -1072,7 +1082,7 @@ var DeviceInvitationsHandler = class extends AbstractInvitationsHandler {
1072
1082
  if (!observable.cancelled) {
1073
1083
  log4.warn("auth failed", err, {
1074
1084
  file: "device-invitations-handler.ts",
1075
- line: 261,
1085
+ line: 263,
1076
1086
  scope: this,
1077
1087
  callSite: (f, a) => f(...a)
1078
1088
  });
@@ -1516,6 +1526,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1516
1526
  };
1517
1527
  },
1518
1528
  requestAdmission: async ({ identityKey, deviceKey, controlFeedKey, dataFeedKey }) => {
1529
+ var _a2;
1519
1530
  try {
1520
1531
  if (isAuthenticationRequired(invitation) && !authenticationPassed) {
1521
1532
  throw new Error("Not authenticated");
@@ -1536,7 +1547,9 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1536
1547
  await writeMessages2(space.inner.controlPipeline.writer, credentials);
1537
1548
  complete.wake(deviceKey);
1538
1549
  return {
1539
- credential: spaceMemberCredential
1550
+ credential: spaceMemberCredential,
1551
+ controlTimeframe: space.inner.controlPipeline.state.timeframe,
1552
+ dataTimeframe: (_a2 = space.dataPipeline.pipelineState) == null ? void 0 : _a2.timeframe
1540
1553
  };
1541
1554
  } catch (err) {
1542
1555
  observable.callback.onError(err);
@@ -1551,7 +1564,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1551
1564
  host: this._signingContext.deviceKey
1552
1565
  }, {
1553
1566
  file: "space-invitations-handler.ts",
1554
- line: 191,
1567
+ line: 195,
1555
1568
  scope: this,
1556
1569
  callSite: (f, a) => f(...a)
1557
1570
  });
@@ -1564,7 +1577,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1564
1577
  guest: deviceKey
1565
1578
  }, {
1566
1579
  file: "space-invitations-handler.ts",
1567
- line: 194,
1580
+ line: 198,
1568
1581
  scope: this,
1569
1582
  callSite: (f, a) => f(...a)
1570
1583
  });
@@ -1573,7 +1586,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1573
1586
  if (!observable.cancelled) {
1574
1587
  log6.error("failed", err, {
1575
1588
  file: "space-invitations-handler.ts",
1576
- line: 198,
1589
+ line: 202,
1577
1590
  scope: this,
1578
1591
  callSite: (f, a) => f(...a)
1579
1592
  });
@@ -1643,7 +1656,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1643
1656
  guest: this._signingContext.deviceKey
1644
1657
  }, {
1645
1658
  file: "space-invitations-handler.ts",
1646
- line: 271,
1659
+ line: 275,
1647
1660
  scope: this,
1648
1661
  callSite: (f, a) => f(...a)
1649
1662
  });
@@ -1652,7 +1665,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1652
1665
  guest: this._signingContext.deviceKey
1653
1666
  }, {
1654
1667
  file: "space-invitations-handler.ts",
1655
- line: 275,
1668
+ line: 279,
1656
1669
  scope: this,
1657
1670
  callSite: (f, a) => f(...a)
1658
1671
  });
@@ -1664,7 +1677,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1664
1677
  response: introductionResponse
1665
1678
  }, {
1666
1679
  file: "space-invitations-handler.ts",
1667
- line: 279,
1680
+ line: 283,
1668
1681
  scope: this,
1669
1682
  callSite: (f, a) => f(...a)
1670
1683
  });
@@ -1677,7 +1690,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1677
1690
  for (let attempt = 1; attempt <= MAX_OTP_ATTEMPTS; attempt++) {
1678
1691
  log6("guest waiting for authentication code...", {}, {
1679
1692
  file: "space-invitations-handler.ts",
1680
- line: 293,
1693
+ line: 297,
1681
1694
  scope: this,
1682
1695
  callSite: (f, a) => f(...a)
1683
1696
  });
@@ -1687,7 +1700,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1687
1700
  });
1688
1701
  log6("sending authentication request", {}, {
1689
1702
  file: "space-invitations-handler.ts",
1690
- line: 297,
1703
+ line: 301,
1691
1704
  scope: this,
1692
1705
  callSite: (f, a) => f(...a)
1693
1706
  });
@@ -1705,7 +1718,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1705
1718
  attempt
1706
1719
  }, {
1707
1720
  file: "space-invitations-handler.ts",
1708
- line: 307,
1721
+ line: 311,
1709
1722
  scope: this,
1710
1723
  callSite: (f, a) => f(...a)
1711
1724
  });
@@ -1720,11 +1733,11 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1720
1733
  guest: this._signingContext.deviceKey
1721
1734
  }, {
1722
1735
  file: "space-invitations-handler.ts",
1723
- line: 318,
1736
+ line: 322,
1724
1737
  scope: this,
1725
1738
  callSite: (f, a) => f(...a)
1726
1739
  });
1727
- const { credential } = await extension.rpc.SpaceHostService.requestAdmission({
1740
+ const { credential, controlTimeframe, dataTimeframe } = await extension.rpc.SpaceHostService.requestAdmission({
1728
1741
  identityKey: this._signingContext.identityKey,
1729
1742
  deviceKey: this._signingContext.deviceKey,
1730
1743
  controlFeedKey,
@@ -1735,7 +1748,9 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1735
1748
  assert6(credential.subject.id.equals(this._signingContext.identityKey));
1736
1749
  const space = await this._spaceManager.acceptSpace({
1737
1750
  spaceKey: assertion.spaceKey,
1738
- genesisFeedKey: assertion.genesisFeedKey
1751
+ genesisFeedKey: assertion.genesisFeedKey,
1752
+ controlTimeframe,
1753
+ dataTimeframe
1739
1754
  });
1740
1755
  await this._signingContext.recordCredential(credential);
1741
1756
  log6("admitted by host", {
@@ -1743,7 +1758,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1743
1758
  spaceKey: space.key
1744
1759
  }, {
1745
1760
  file: "space-invitations-handler.ts",
1746
- line: 340,
1761
+ line: 347,
1747
1762
  scope: this,
1748
1763
  callSite: (f, a) => f(...a)
1749
1764
  });
@@ -1752,7 +1767,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler2 {
1752
1767
  if (!observable.cancelled) {
1753
1768
  log6.warn("auth failed", err, {
1754
1769
  file: "space-invitations-handler.ts",
1755
- line: 344,
1770
+ line: 351,
1756
1771
  scope: this,
1757
1772
  callSite: (f, a) => f(...a)
1758
1773
  });
@@ -1991,18 +2006,18 @@ var MemoryShellRuntime = class {
1991
2006
 
1992
2007
  // packages/sdk/client-services/src/packlets/vault/iframe-host-runtime.ts
1993
2008
  import { Trigger as Trigger9 } from "@dxos/async";
1994
- import { log as log16, logInfo as logInfo2 } from "@dxos/log";
2009
+ import { log as log17, logInfo as logInfo3 } from "@dxos/log";
1995
2010
  import { MemorySignalManager as MemorySignalManager3, MemorySignalManagerContext as MemorySignalManagerContext3, WebsocketSignalManager as WebsocketSignalManager3 } from "@dxos/messaging";
1996
2011
  import { createWebRTCTransportFactory as createWebRTCTransportFactory2, NetworkManager as NetworkManager3 } from "@dxos/network-manager";
1997
2012
  import { getAsyncValue } from "@dxos/util";
1998
2013
 
1999
2014
  // packages/sdk/client-services/src/packlets/services/service-host.ts
2000
2015
  import assert12 from "@dxos/node-std/assert";
2001
- import { Event as Event6 } from "@dxos/async";
2016
+ import { Event as Event7 } from "@dxos/async";
2002
2017
  import { clientServiceBundle, createDefaultModelFactory } from "@dxos/client";
2003
2018
  import { raise as raise3 } from "@dxos/debug";
2004
2019
  import { DataServiceImpl } from "@dxos/echo-pipeline";
2005
- import { log as log14 } from "@dxos/log";
2020
+ import { log as log15 } from "@dxos/log";
2006
2021
  import { SystemStatus } from "@dxos/protocols/proto/dxos/client/services";
2007
2022
 
2008
2023
  // packages/sdk/client-services/src/packlets/deprecated/tracing.ts
@@ -2089,35 +2104,40 @@ var NetworkServiceImpl = class {
2089
2104
 
2090
2105
  // packages/sdk/client-services/src/packlets/spaces/data-space-manager.ts
2091
2106
  import assert10 from "@dxos/node-std/assert";
2092
- import { Event as Event5, synchronized, trackLeaks as trackLeaks2 } from "@dxos/async";
2093
- import { Context as Context7 } from "@dxos/context";
2107
+ import { Event as Event6, synchronized, trackLeaks as trackLeaks2 } from "@dxos/async";
2108
+ import { SpaceState as SpaceState2 } from "@dxos/client";
2109
+ import { cancelWithContext, Context as Context7 } from "@dxos/context";
2094
2110
  import { getCredentialAssertion as getCredentialAssertion2 } from "@dxos/credentials";
2095
- import { spaceGenesis, SnapshotManager } from "@dxos/echo-pipeline";
2111
+ import { SnapshotManager, spaceGenesis } from "@dxos/echo-pipeline";
2096
2112
  import { PublicKey as PublicKey7 } from "@dxos/keys";
2097
- import { log as log8 } from "@dxos/log";
2098
- import { Presence } from "@dxos/teleport-extension-presence";
2113
+ import { log as log9 } from "@dxos/log";
2114
+ import { Gossip, Presence } from "@dxos/teleport-extension-gossip";
2099
2115
  import { ComplexMap as ComplexMap3, deferFunction as deferFunction2 } from "@dxos/util";
2100
2116
 
2101
2117
  // packages/sdk/client-services/src/packlets/spaces/data-space.ts
2102
- import { trackLeaks } from "@dxos/async";
2118
+ import { Event as Event5, scheduleTask as scheduleTask4, trackLeaks } from "@dxos/async";
2119
+ import { SpaceState } from "@dxos/client";
2103
2120
  import { Context as Context6 } from "@dxos/context";
2104
2121
  import { timed } from "@dxos/debug";
2105
- import { DataPipelineControllerImpl, createMappedFeedWriter } from "@dxos/echo-pipeline";
2122
+ import { createMappedFeedWriter, DataPipeline } from "@dxos/echo-pipeline";
2123
+ import { CancelledError, SystemError } from "@dxos/errors";
2106
2124
  import { PublicKey as PublicKey6 } from "@dxos/keys";
2125
+ import { log as log8 } from "@dxos/log";
2107
2126
  import { AdmittedFeed as AdmittedFeed3 } from "@dxos/protocols/proto/dxos/halo/credentials";
2108
2127
  import { ComplexSet as ComplexSet2 } from "@dxos/util";
2109
2128
 
2110
2129
  // packages/sdk/client-services/src/packlets/spaces/notarization-plugin.ts
2111
2130
  import assert9 from "@dxos/node-std/assert";
2112
- import { DeferredTask, Event as Event4, scheduleTask as scheduleTask3, TimeoutError, Trigger as Trigger4 } from "@dxos/async";
2113
- import { Context as Context5 } from "@dxos/context";
2131
+ import { DeferredTask, Event as Event4, scheduleTask as scheduleTask3, sleep as sleep3, TimeoutError, Trigger as Trigger4 } from "@dxos/async";
2132
+ import { Context as Context5, rejectOnDispose } from "@dxos/context";
2114
2133
  import { PublicKey as PublicKey5 } from "@dxos/keys";
2115
2134
  import { log as log7 } from "@dxos/log";
2116
2135
  import { schema as schema4 } from "@dxos/protocols";
2117
2136
  import { RpcExtension as RpcExtension3 } from "@dxos/teleport";
2118
2137
  import { ComplexMap as ComplexMap2, ComplexSet, entry } from "@dxos/util";
2119
- var RETRY_TIMEOUT = 1e3;
2120
- var NOTARIZE_TIMEOUT = 1e4;
2138
+ var DEFAULT_RETRY_TIMEOUT = 1e3;
2139
+ var DEFAULT_SUCCESS_DELAY = 1e3;
2140
+ var DEFAULT_NOTARIZE_TIMEOUT = 1e4;
2121
2141
  var NotarizationPlugin = class {
2122
2142
  constructor() {
2123
2143
  this._ctx = new Context5();
@@ -2134,12 +2154,12 @@ var NotarizationPlugin = class {
2134
2154
  /**
2135
2155
  * Request credentials to be notarized.
2136
2156
  */
2137
- async notarize(credentials) {
2157
+ async notarize({ ctx: opCtx, credentials, timeout = DEFAULT_NOTARIZE_TIMEOUT, retryTimeout = DEFAULT_RETRY_TIMEOUT, successDelay = DEFAULT_SUCCESS_DELAY }) {
2138
2158
  log7("notarize", {
2139
2159
  credentials
2140
2160
  }, {
2141
2161
  file: "notarization-plugin.ts",
2142
- line: 44,
2162
+ line: 85,
2143
2163
  scope: this,
2144
2164
  callSite: (f, a) => f(...a)
2145
2165
  });
@@ -2151,7 +2171,7 @@ var NotarizationPlugin = class {
2151
2171
  err
2152
2172
  }, {
2153
2173
  file: "notarization-plugin.ts",
2154
- line: 53,
2174
+ line: 94,
2155
2175
  scope: this,
2156
2176
  callSite: (f, a) => f(...a)
2157
2177
  });
@@ -2159,27 +2179,27 @@ var NotarizationPlugin = class {
2159
2179
  errors.throw(err);
2160
2180
  }
2161
2181
  });
2162
- scheduleTask3(ctx, () => {
2163
- log7.warn("Notarization timeout", {}, {
2164
- file: "notarization-plugin.ts",
2165
- line: 61,
2166
- scope: this,
2167
- callSite: (f, a) => f(...a)
2168
- });
2169
- void ctx.dispose();
2170
- errors.throw(new TimeoutError(NOTARIZE_TIMEOUT, "Notarization timed out"));
2171
- }, NOTARIZE_TIMEOUT);
2182
+ opCtx == null ? void 0 : opCtx.onDispose(() => ctx.dispose());
2183
+ if (timeout !== 0) {
2184
+ scheduleTask3(ctx, () => {
2185
+ log7.warn("Notarization timeout", {
2186
+ timeout,
2187
+ peers: Array.from(this._extensions).map((extension) => extension.remotePeerId)
2188
+ }, {
2189
+ file: "notarization-plugin.ts",
2190
+ line: 106,
2191
+ scope: this,
2192
+ callSite: (f, a) => f(...a)
2193
+ });
2194
+ void ctx.dispose();
2195
+ errors.throw(new TimeoutError(timeout, "Notarization timed out"));
2196
+ }, timeout);
2197
+ }
2172
2198
  const allNotarized = Promise.all(credentials.map((credential) => this._waitUntilProcessed(credential.id)));
2173
2199
  const peersTried = /* @__PURE__ */ new Set();
2174
2200
  const notarizeTask = new DeferredTask(ctx, async () => {
2175
2201
  try {
2176
2202
  if (this._extensions.size === 0) {
2177
- log7.warn("No peers to notarize with", {}, {
2178
- file: "notarization-plugin.ts",
2179
- line: 76,
2180
- scope: this,
2181
- callSite: (f, a) => f(...a)
2182
- });
2183
2203
  return;
2184
2204
  }
2185
2205
  const peer = [
@@ -2187,15 +2207,15 @@ var NotarizationPlugin = class {
2187
2207
  ].find((peer2) => !peersTried.has(peer2));
2188
2208
  if (!peer) {
2189
2209
  log7.warn("Exhausted all peers to notarize with", {
2190
- retryIn: RETRY_TIMEOUT
2210
+ retryIn: retryTimeout
2191
2211
  }, {
2192
2212
  file: "notarization-plugin.ts",
2193
- line: 83,
2213
+ line: 131,
2194
2214
  scope: this,
2195
2215
  callSite: (f, a) => f(...a)
2196
2216
  });
2197
2217
  peersTried.clear();
2198
- scheduleTask3(ctx, () => notarizeTask.schedule(), RETRY_TIMEOUT);
2218
+ scheduleTask3(ctx, () => notarizeTask.schedule(), retryTimeout);
2199
2219
  return;
2200
2220
  }
2201
2221
  peersTried.add(peer);
@@ -2204,7 +2224,7 @@ var NotarizationPlugin = class {
2204
2224
  credentialId: credentials.map((credential) => credential.id)
2205
2225
  }, {
2206
2226
  file: "notarization-plugin.ts",
2207
- line: 90,
2227
+ line: 138,
2208
2228
  scope: this,
2209
2229
  callSite: (f, a) => f(...a)
2210
2230
  });
@@ -2213,14 +2233,15 @@ var NotarizationPlugin = class {
2213
2233
  });
2214
2234
  log7("success", {}, {
2215
2235
  file: "notarization-plugin.ts",
2216
- line: 94,
2236
+ line: 142,
2217
2237
  scope: this,
2218
2238
  callSite: (f, a) => f(...a)
2219
2239
  });
2240
+ await sleep3(successDelay);
2220
2241
  } catch (err) {
2221
2242
  log7.warn("error notarizing (recoverable)", err, {
2222
2243
  file: "notarization-plugin.ts",
2223
- line: 96,
2244
+ line: 145,
2224
2245
  scope: this,
2225
2246
  callSite: (f, a) => f(...a)
2226
2247
  });
@@ -2231,12 +2252,13 @@ var NotarizationPlugin = class {
2231
2252
  this._extensionOpened.on(ctx, () => notarizeTask.schedule());
2232
2253
  try {
2233
2254
  await Promise.race([
2255
+ rejectOnDispose(ctx),
2234
2256
  allNotarized,
2235
2257
  errors.wait()
2236
2258
  ]);
2237
2259
  log7("done", {}, {
2238
2260
  file: "notarization-plugin.ts",
2239
- line: 107,
2261
+ line: 155,
2240
2262
  scope: this,
2241
2263
  callSite: (f, a) => f(...a)
2242
2264
  });
@@ -2289,7 +2311,7 @@ var NotarizationPlugin = class {
2289
2311
  peer: extension.localPeerId
2290
2312
  }, {
2291
2313
  file: "notarization-plugin.ts",
2292
- line: 156,
2314
+ line: 204,
2293
2315
  scope: this,
2294
2316
  callSite: (f, a) => f(...a)
2295
2317
  });
@@ -2301,7 +2323,7 @@ var NotarizationPlugin = class {
2301
2323
  peer: extension.localPeerId
2302
2324
  }, {
2303
2325
  file: "notarization-plugin.ts",
2304
- line: 161,
2326
+ line: 209,
2305
2327
  scope: this,
2306
2328
  callSite: (f, a) => f(...a)
2307
2329
  });
@@ -2355,17 +2377,22 @@ var __decorate = function(decorators, target, key, desc) {
2355
2377
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2356
2378
  };
2357
2379
  var AUTH_TIMEOUT2 = 3e4;
2358
- var CONTROL_PIPELINE_READY_TIMEFRAME = 3e3;
2359
2380
  var DataSpace = class DataSpace2 {
2360
2381
  constructor(params) {
2361
2382
  this._ctx = new Context6();
2383
+ this._state = SpaceState.CLOSED;
2384
+ this.stateUpdate = new Event5();
2385
+ var _a;
2362
2386
  this._inner = params.inner;
2387
+ this._inner.stateUpdate.on(this._ctx, () => this.stateUpdate.emit());
2388
+ this._gossip = params.gossip;
2363
2389
  this._presence = params.presence;
2364
2390
  this._keyring = params.keyring;
2365
2391
  this._feedStore = params.feedStore;
2366
2392
  this._metadataStore = params.metadataStore;
2367
2393
  this._signingContext = params.signingContext;
2368
- this._dataPipelineController = new DataPipelineControllerImpl({
2394
+ this._callbacks = (_a = params.callbacks) != null ? _a : {};
2395
+ this._dataPipeline = new DataPipeline({
2369
2396
  modelFactory: params.modelFactory,
2370
2397
  metadataStore: params.metadataStore,
2371
2398
  snapshotManager: params.snapshotManager,
@@ -2387,15 +2414,15 @@ var DataSpace = class DataSpace2 {
2387
2414
  get isOpen() {
2388
2415
  return this._inner.isOpen;
2389
2416
  }
2417
+ get state() {
2418
+ return this._state;
2419
+ }
2390
2420
  // TODO(burdon): Can we mark this for debugging only?
2391
2421
  get inner() {
2392
2422
  return this._inner;
2393
2423
  }
2394
- get dataPipelineController() {
2395
- return this._dataPipelineController;
2396
- }
2397
- get stateUpdate() {
2398
- return this._inner.stateUpdate;
2424
+ get dataPipeline() {
2425
+ return this._dataPipeline;
2399
2426
  }
2400
2427
  get presence() {
2401
2428
  return this._presence;
@@ -2407,26 +2434,102 @@ var DataSpace = class DataSpace2 {
2407
2434
  await this.notarizationPlugin.open();
2408
2435
  await this._notarizationPluginConsumer.open();
2409
2436
  await this._inner.open();
2437
+ this._state = SpaceState.INACTIVE;
2410
2438
  }
2411
2439
  async close() {
2440
+ this._state = SpaceState.CLOSED;
2412
2441
  await this._ctx.dispose();
2442
+ await this._dataPipeline.close();
2413
2443
  await this.authVerifier.close();
2414
2444
  await this._inner.close();
2415
2445
  await this._notarizationPluginConsumer.close();
2416
2446
  await this.notarizationPlugin.close();
2417
2447
  await this._presence.destroy();
2418
2448
  }
2449
+ async postMessage(channel, message) {
2450
+ return this._gossip.postMessage(channel, message);
2451
+ }
2452
+ listen(channel, callback) {
2453
+ return this._gossip.listen(channel, callback);
2454
+ }
2455
+ /**
2456
+ * Initialize the data pipeline in a separate task.
2457
+ */
2458
+ initializeDataPipelineAsync() {
2459
+ scheduleTask4(this._ctx, async () => {
2460
+ try {
2461
+ await this.initializeDataPipeline();
2462
+ } catch (err) {
2463
+ if (err instanceof CancelledError) {
2464
+ log8("Data pipeline initialization cancelled", err, {
2465
+ file: "data-space.ts",
2466
+ line: 178,
2467
+ scope: this,
2468
+ callSite: (f, a) => f(...a)
2469
+ });
2470
+ return;
2471
+ }
2472
+ log8.error("Error initializing data pipeline", err, {
2473
+ file: "data-space.ts",
2474
+ line: 182,
2475
+ scope: this,
2476
+ callSite: (f, a) => f(...a)
2477
+ });
2478
+ }
2479
+ });
2480
+ }
2419
2481
  async initializeDataPipeline() {
2482
+ var _a, _b, _c, _d;
2483
+ if (this._state !== SpaceState.INACTIVE) {
2484
+ throw new SystemError("Invalid operation");
2485
+ }
2486
+ this._state = SpaceState.INITIALIZING;
2420
2487
  await this._inner.controlPipeline.state.waitUntilReachedTargetTimeframe({
2421
- timeout: CONTROL_PIPELINE_READY_TIMEFRAME
2488
+ ctx: this._ctx,
2489
+ breakOnStall: false
2422
2490
  });
2423
2491
  await this._createWritableFeeds();
2492
+ log8("Writable feeds created", {}, {
2493
+ file: "data-space.ts",
2494
+ line: 200,
2495
+ scope: this,
2496
+ callSite: (f, a) => f(...a)
2497
+ });
2498
+ this.stateUpdate.emit();
2424
2499
  this.notarizationPlugin.setWriter(createMappedFeedWriter((credential) => ({
2425
2500
  credential: {
2426
2501
  credential
2427
2502
  }
2428
2503
  }), this._inner.controlPipeline.writer));
2429
- await this._inner.initDataPipeline(this._dataPipelineController);
2504
+ await this._dataPipeline.open({
2505
+ openPipeline: async (start) => {
2506
+ const pipeline = await this._inner.createDataPipeline({
2507
+ start
2508
+ });
2509
+ await pipeline.start();
2510
+ return pipeline;
2511
+ }
2512
+ });
2513
+ log8("waiting for data pipeline to reach target timeframe", {}, {
2514
+ file: "data-space.ts",
2515
+ line: 220,
2516
+ scope: this,
2517
+ callSite: (f, a) => f(...a)
2518
+ });
2519
+ await this._dataPipeline.pipelineState.waitUntilReachedTargetTimeframe({
2520
+ ctx: this._ctx,
2521
+ breakOnStall: false
2522
+ });
2523
+ log8("data pipeline ready", {}, {
2524
+ file: "data-space.ts",
2525
+ line: 227,
2526
+ scope: this,
2527
+ callSite: (f, a) => f(...a)
2528
+ });
2529
+ await ((_b = (_a = this._callbacks).beforeReady) == null ? void 0 : _b.call(_a));
2530
+ this._state = SpaceState.READY;
2531
+ this.stateUpdate.emit();
2532
+ await ((_d = (_c = this._callbacks).afterReady) == null ? void 0 : _d.call(_c));
2430
2533
  }
2431
2534
  async _createWritableFeeds() {
2432
2535
  const credentials = [];
@@ -2463,7 +2566,11 @@ var DataSpace = class DataSpace2 {
2463
2566
  }));
2464
2567
  }
2465
2568
  if (credentials.length > 0) {
2466
- await this.notarizationPlugin.notarize(credentials);
2569
+ await this.notarizationPlugin.notarize({
2570
+ ctx: this._ctx,
2571
+ credentials,
2572
+ timeout: 0
2573
+ });
2467
2574
  }
2468
2575
  await this._metadataStore.setWritableFeedKeys(this.key, this.inner.controlFeedKey, this.inner.dataFeedKey);
2469
2576
  }
@@ -2486,7 +2593,6 @@ var __decorate2 = function(decorators, target, key, desc) {
2486
2593
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2487
2594
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2488
2595
  };
2489
- var DATA_PIPELINE_READY_TIMEOUT = 3e3;
2490
2596
  var DataSpaceManager = class DataSpaceManager2 {
2491
2597
  constructor(_spaceManager, _metadataStore, _dataServiceSubscriptions, _keyring, _signingContext, _modelFactory, _feedStore, _snapshotStore) {
2492
2598
  this._spaceManager = _spaceManager;
@@ -2498,52 +2604,53 @@ var DataSpaceManager = class DataSpaceManager2 {
2498
2604
  this._feedStore = _feedStore;
2499
2605
  this._snapshotStore = _snapshotStore;
2500
2606
  this._ctx = new Context7();
2501
- this.updated = new Event5();
2607
+ this.updated = new Event6();
2502
2608
  this._spaces = new ComplexMap3(PublicKey7.hash);
2609
+ this._isOpen = false;
2503
2610
  }
2504
2611
  // TODO(burdon): Remove.
2505
2612
  get spaces() {
2506
2613
  return this._spaces;
2507
2614
  }
2508
2615
  async open() {
2616
+ log9("open", {}, {
2617
+ file: "data-space-manager.ts",
2618
+ line: 80,
2619
+ scope: this,
2620
+ callSite: (f, a) => f(...a)
2621
+ });
2509
2622
  await this._metadataStore.load();
2510
- log8("metadata loaded", {
2623
+ log9("metadata loaded", {
2511
2624
  spaces: this._metadataStore.spaces.length
2512
2625
  }, {
2513
2626
  file: "data-space-manager.ts",
2514
- line: 67,
2627
+ line: 82,
2515
2628
  scope: this,
2516
2629
  callSite: (f, a) => f(...a)
2517
2630
  });
2518
2631
  for (const spaceMetadata of this._metadataStore.spaces) {
2519
- log8("load space", {
2632
+ log9("load space", {
2520
2633
  spaceMetadata
2521
2634
  }, {
2522
2635
  file: "data-space-manager.ts",
2523
- line: 70,
2636
+ line: 85,
2524
2637
  scope: this,
2525
2638
  callSite: (f, a) => f(...a)
2526
2639
  });
2527
2640
  const space = await this._constructSpace(spaceMetadata);
2528
- await space.initializeDataPipeline();
2529
- if (spaceMetadata.dataTimeframe) {
2530
- log8("waiting for latest timeframe", {
2531
- spaceMetadata
2532
- }, {
2533
- file: "data-space-manager.ts",
2534
- line: 74,
2535
- scope: this,
2536
- callSite: (f, a) => f(...a)
2537
- });
2538
- await space.dataPipelineController.pipelineState.setTargetTimeframe(spaceMetadata.dataTimeframe);
2539
- }
2540
- await space.dataPipelineController.pipelineState.waitUntilReachedTargetTimeframe({
2541
- timeout: DATA_PIPELINE_READY_TIMEOUT
2542
- });
2543
- this._dataServiceSubscriptions.registerSpace(space.key, space.dataPipelineController.databaseBackend.createDataServiceHost());
2641
+ space.initializeDataPipelineAsync();
2544
2642
  }
2643
+ this._isOpen = true;
2644
+ this.updated.emit();
2545
2645
  }
2546
2646
  async close() {
2647
+ log9("close", {}, {
2648
+ file: "data-space-manager.ts",
2649
+ line: 96,
2650
+ scope: this,
2651
+ callSite: (f, a) => f(...a)
2652
+ });
2653
+ this._isOpen = false;
2547
2654
  await this._ctx.dispose();
2548
2655
  for (const space of this._spaces.values()) {
2549
2656
  await space.close();
@@ -2553,6 +2660,7 @@ var DataSpaceManager = class DataSpaceManager2 {
2553
2660
  * Creates a new space writing the genesis credentials to the control feed.
2554
2661
  */
2555
2662
  async createSpace() {
2663
+ assert10(this._isOpen, "Not open.");
2556
2664
  const spaceKey = await this._keyring.createKey();
2557
2665
  const controlFeedKey = await this._keyring.createKey();
2558
2666
  const dataFeedKey = await this._keyring.createKey();
@@ -2562,11 +2670,11 @@ var DataSpaceManager = class DataSpaceManager2 {
2562
2670
  controlFeedKey,
2563
2671
  dataFeedKey
2564
2672
  };
2565
- log8("creating space...", {
2673
+ log9("creating space...", {
2566
2674
  spaceKey
2567
2675
  }, {
2568
2676
  file: "data-space-manager.ts",
2569
- line: 110,
2677
+ line: 120,
2570
2678
  scope: this,
2571
2679
  callSite: (f, a) => f(...a)
2572
2680
  });
@@ -2577,30 +2685,61 @@ var DataSpaceManager = class DataSpaceManager2 {
2577
2685
  assert10(getCredentialAssertion2(memberCredential)["@type"] === "dxos.halo.credentials.SpaceMember");
2578
2686
  await this._signingContext.recordCredential(memberCredential);
2579
2687
  await space.initializeDataPipeline();
2580
- this._dataServiceSubscriptions.registerSpace(space.key, space.dataPipelineController.databaseBackend.createDataServiceHost());
2581
2688
  this.updated.emit();
2582
2689
  return space;
2583
2690
  }
2584
2691
  // TODO(burdon): Rename join space.
2585
2692
  async acceptSpace(opts) {
2693
+ log9("accept space", {
2694
+ opts
2695
+ }, {
2696
+ file: "data-space-manager.ts",
2697
+ line: 139,
2698
+ scope: this,
2699
+ callSite: (f, a) => f(...a)
2700
+ });
2701
+ assert10(this._isOpen, "Not open.");
2586
2702
  assert10(!this._spaces.has(opts.spaceKey), "Space already exists.");
2587
2703
  const metadata = {
2588
2704
  key: opts.spaceKey,
2589
- genesisFeedKey: opts.genesisFeedKey
2705
+ genesisFeedKey: opts.genesisFeedKey,
2706
+ controlTimeframe: opts.controlTimeframe,
2707
+ dataTimeframe: opts.dataTimeframe
2590
2708
  };
2591
2709
  const space = await this._constructSpace(metadata);
2592
2710
  await this._metadataStore.addSpace(metadata);
2593
- await space.initializeDataPipeline();
2594
- this._dataServiceSubscriptions.registerSpace(space.key, space.dataPipelineController.databaseBackend.createDataServiceHost());
2711
+ space.initializeDataPipelineAsync();
2595
2712
  this.updated.emit();
2596
2713
  return space;
2597
2714
  }
2715
+ /**
2716
+ * Wait until the space data pipeline is fully initialized.
2717
+ * Used by invitation handler.
2718
+ * TODO(dmaretskyi): Consider removing.
2719
+ */
2720
+ async waitUntilSpaceReady(spaceKey) {
2721
+ await cancelWithContext(this._ctx, this.updated.waitForCondition(() => {
2722
+ const space = this._spaces.get(spaceKey);
2723
+ return !!space && space.state === SpaceState2.READY;
2724
+ }));
2725
+ }
2598
2726
  async _constructSpace(metadata) {
2727
+ log9("construct space", {
2728
+ metadata
2729
+ }, {
2730
+ file: "data-space-manager.ts",
2731
+ line: 175,
2732
+ scope: this,
2733
+ callSite: (f, a) => f(...a)
2734
+ });
2735
+ const gossip = new Gossip({
2736
+ localPeerId: this._signingContext.deviceKey
2737
+ });
2599
2738
  const presence = new Presence({
2600
- localPeerId: this._signingContext.deviceKey,
2601
- announceInterval: 1e3,
2602
- offlineTimeout: 1e4,
2603
- identityKey: this._signingContext.identityKey
2739
+ announceInterval: 500,
2740
+ offlineTimeout: 5e3,
2741
+ identityKey: this._signingContext.identityKey,
2742
+ gossip
2604
2743
  });
2605
2744
  const snapshotManager = new SnapshotManager(this._snapshotStore);
2606
2745
  const controlFeed = metadata.controlFeedKey && await this._feedStore.openFeed(metadata.controlFeedKey, {
@@ -2617,7 +2756,7 @@ var DataSpaceManager = class DataSpaceManager2 {
2617
2756
  credentialAuthenticator: deferFunction2(() => dataSpace.authVerifier.verifier)
2618
2757
  },
2619
2758
  onNetworkConnection: (session) => {
2620
- session.addExtension("dxos.mesh.teleport.presence", presence.createExtension({
2759
+ session.addExtension("dxos.mesh.teleport.gossip", gossip.createExtension({
2621
2760
  remotePeerId: session.remotePeerId
2622
2761
  }));
2623
2762
  session.addExtension("dxos.mesh.teleport.objectsync", snapshotManager.objectSync.createExtension());
@@ -2631,14 +2770,48 @@ var DataSpaceManager = class DataSpaceManager2 {
2631
2770
  modelFactory: this._modelFactory,
2632
2771
  metadataStore: this._metadataStore,
2633
2772
  snapshotManager,
2773
+ gossip,
2634
2774
  presence,
2635
2775
  memberKey: this._signingContext.identityKey,
2636
2776
  keyring: this._keyring,
2637
2777
  feedStore: this._feedStore,
2638
2778
  signingContext: this._signingContext,
2639
- snapshotId: metadata.snapshot
2779
+ snapshotId: metadata.snapshot,
2780
+ callbacks: {
2781
+ beforeReady: async () => {
2782
+ log9("before space ready", {
2783
+ space: space.key
2784
+ }, {
2785
+ file: "data-space-manager.ts",
2786
+ line: 224,
2787
+ scope: this,
2788
+ callSite: (f, a) => f(...a)
2789
+ });
2790
+ this._dataServiceSubscriptions.registerSpace(space.key, dataSpace.dataPipeline.databaseBackend.createDataServiceHost());
2791
+ },
2792
+ afterReady: async () => {
2793
+ log9("after space ready", {
2794
+ space: space.key,
2795
+ open: this._isOpen
2796
+ }, {
2797
+ file: "data-space-manager.ts",
2798
+ line: 231,
2799
+ scope: this,
2800
+ callSite: (f, a) => f(...a)
2801
+ });
2802
+ if (this._isOpen) {
2803
+ this.updated.emit();
2804
+ }
2805
+ }
2806
+ }
2640
2807
  });
2641
2808
  await dataSpace.open();
2809
+ if (metadata.controlTimeframe) {
2810
+ dataSpace.inner.controlPipeline.state.setTargetTimeframe(metadata.controlTimeframe);
2811
+ }
2812
+ if (metadata.dataTimeframe) {
2813
+ dataSpace.dataPipeline.setTargetTimeframe(metadata.dataTimeframe);
2814
+ }
2642
2815
  this._spaces.set(metadata.key, dataSpace);
2643
2816
  return dataSpace;
2644
2817
  }
@@ -2660,13 +2833,14 @@ DataSpaceManager = __decorate2([
2660
2833
  ], DataSpaceManager);
2661
2834
 
2662
2835
  // packages/sdk/client-services/src/packlets/spaces/spaces-service.ts
2663
- import { EventSubscriptions as EventSubscriptions3, scheduleTask as scheduleTask4 } from "@dxos/async";
2836
+ import { EventSubscriptions as EventSubscriptions3, scheduleTask as scheduleTask5 } from "@dxos/async";
2664
2837
  import { Stream as Stream10 } from "@dxos/codec-protobuf";
2665
2838
  import { raise, todo as todo2 } from "@dxos/debug";
2666
2839
  import { SpaceNotFoundError } from "@dxos/echo-pipeline";
2667
- import { log as log9 } from "@dxos/log";
2668
- import { SpaceMember, SpaceStatus } from "@dxos/protocols/proto/dxos/client/services";
2840
+ import { log as log10 } from "@dxos/log";
2841
+ import { SpaceMember } from "@dxos/protocols/proto/dxos/client/services";
2669
2842
  import { humanize } from "@dxos/util";
2843
+ var TIMEFRAME_UPDATE_DEBOUNCE_TIME = 500;
2670
2844
  var SpacesServiceImpl = class {
2671
2845
  constructor(_identityManager, _spaceManager, _dataServiceSubscriptions, _getDataSpaceManager) {
2672
2846
  this._identityManager = _identityManager;
@@ -2689,12 +2863,12 @@ var SpacesServiceImpl = class {
2689
2863
  return new Stream10(({ next, ctx }) => {
2690
2864
  const onUpdate = async () => {
2691
2865
  const dataSpaceManager = await this._getDataSpaceManager();
2692
- const spaces = Array.from(dataSpaceManager.spaces.values()).filter((space) => this._dataServiceSubscriptions.getDataService(space.key)).map((space) => this._transformSpace(space));
2693
- log9("update", {
2866
+ const spaces = Array.from(dataSpaceManager.spaces.values()).map((space) => this._transformSpace(space));
2867
+ log10("update", {
2694
2868
  spaces
2695
2869
  }, {
2696
2870
  file: "spaces-service.ts",
2697
- line: 59,
2871
+ line: 60,
2698
2872
  scope: this,
2699
2873
  callSite: (f, a) => f(...a)
2700
2874
  });
@@ -2702,28 +2876,27 @@ var SpacesServiceImpl = class {
2702
2876
  spaces
2703
2877
  });
2704
2878
  };
2705
- setTimeout(async () => {
2879
+ scheduleTask5(ctx, async () => {
2706
2880
  const dataSpaceManager = await this._getDataSpaceManager();
2707
2881
  const subscriptions = new EventSubscriptions3();
2882
+ ctx.onDispose(() => subscriptions.clear());
2708
2883
  const subscribeSpaces = () => {
2709
2884
  subscriptions.clear();
2710
2885
  for (const space of dataSpaceManager.spaces.values()) {
2711
- if (!this._dataServiceSubscriptions.getDataService(space.key)) {
2712
- continue;
2713
- }
2714
2886
  subscriptions.add(space.stateUpdate.on(ctx, onUpdate));
2715
2887
  subscriptions.add(space.presence.updated.on(ctx, onUpdate));
2888
+ space.inner.controlPipeline.state.timeframeUpdate.debounce(TIMEFRAME_UPDATE_DEBOUNCE_TIME).on(ctx, onUpdate);
2889
+ if (space.dataPipeline.pipelineState) {
2890
+ subscriptions.add(space.dataPipeline.pipelineState.timeframeUpdate.debounce(TIMEFRAME_UPDATE_DEBOUNCE_TIME).on(ctx, onUpdate));
2891
+ }
2716
2892
  }
2717
2893
  };
2718
2894
  dataSpaceManager.updated.on(ctx, () => {
2719
2895
  subscribeSpaces();
2720
2896
  void onUpdate();
2721
2897
  });
2722
- ctx.onDispose(() => subscriptions.clear());
2723
- scheduleTask4(ctx, () => {
2724
- subscribeSpaces();
2725
- void onUpdate();
2726
- });
2898
+ subscribeSpaces();
2899
+ void onUpdate();
2727
2900
  });
2728
2901
  if (!this._identityManager.identity) {
2729
2902
  next({
@@ -2732,6 +2905,25 @@ var SpacesServiceImpl = class {
2732
2905
  }
2733
2906
  });
2734
2907
  }
2908
+ async postMessage({ spaceKey, channel, message }) {
2909
+ var _a;
2910
+ const dataSpaceManager = await this._getDataSpaceManager();
2911
+ const space = (_a = dataSpaceManager.spaces.get(spaceKey)) != null ? _a : raise(new SpaceNotFoundError(spaceKey));
2912
+ await space.postMessage(getChannelId(channel), message);
2913
+ }
2914
+ subscribeMessages({ spaceKey, channel }) {
2915
+ return new Stream10(({ ctx, next }) => {
2916
+ scheduleTask5(ctx, async () => {
2917
+ var _a;
2918
+ const dataSpaceManager = await this._getDataSpaceManager();
2919
+ const space = (_a = dataSpaceManager.spaces.get(spaceKey)) != null ? _a : raise(new SpaceNotFoundError(spaceKey));
2920
+ const handle = space.listen(getChannelId(channel), (message) => {
2921
+ next(message);
2922
+ });
2923
+ ctx.onDispose(() => handle.unsubscribe());
2924
+ });
2925
+ });
2926
+ }
2735
2927
  queryCredentials({ spaceKey }) {
2736
2928
  return new Stream10(({ ctx, next }) => {
2737
2929
  var _a;
@@ -2742,7 +2934,7 @@ var SpacesServiceImpl = class {
2742
2934
  }
2743
2935
  });
2744
2936
  ctx.onDispose(() => processor.close());
2745
- scheduleTask4(ctx, () => processor.open());
2937
+ scheduleTask5(ctx, () => processor.open());
2746
2938
  });
2747
2939
  }
2748
2940
  async writeCredentials({ spaceKey, credentials }) {
@@ -2757,16 +2949,23 @@ var SpacesServiceImpl = class {
2757
2949
  }
2758
2950
  }
2759
2951
  _transformSpace(space) {
2952
+ var _a, _b;
2760
2953
  return {
2761
2954
  spaceKey: space.key,
2762
- status: space.isOpen ? SpaceStatus.ACTIVE : SpaceStatus.INACTIVE,
2955
+ state: space.state,
2956
+ pipeline: {
2957
+ targetControlTimeframe: space.inner.controlPipeline.state.targetTimeframe,
2958
+ currentControlTimeframe: space.inner.controlPipeline.state.timeframe,
2959
+ currentDataTimeframe: (_a = space.dataPipeline.pipelineState) == null ? void 0 : _a.timeframe,
2960
+ targetDataTimeframe: (_b = space.dataPipeline.pipelineState) == null ? void 0 : _b.targetTimeframe
2961
+ },
2763
2962
  members: Array.from(space.inner.spaceState.members.values()).map((member) => {
2764
- var _a, _b, _c;
2963
+ var _a2, _b2, _c;
2765
2964
  return {
2766
2965
  identity: {
2767
2966
  identityKey: member.key,
2768
2967
  profile: {
2769
- displayName: (_b = (_a = member.assertion.profile) == null ? void 0 : _a.displayName) != null ? _b : humanize(member.key)
2968
+ displayName: (_b2 = (_a2 = member.assertion.profile) == null ? void 0 : _a2.displayName) != null ? _b2 : humanize(member.key)
2770
2969
  }
2771
2970
  },
2772
2971
  presence: ((_c = this._identityManager.identity) == null ? void 0 : _c.identityKey.equals(member.key)) || space.presence.getPeersOnline().filter(({ identityKey }) => identityKey.equals(member.key)).length > 0 ? SpaceMember.PresenceState.ONLINE : SpaceMember.PresenceState.OFFLINE
@@ -2775,6 +2974,7 @@ var SpacesServiceImpl = class {
2775
2974
  };
2776
2975
  }
2777
2976
  };
2977
+ var getChannelId = (channel) => `user-channel/${channel}`;
2778
2978
 
2779
2979
  // packages/sdk/client-services/src/packlets/system/system-service.ts
2780
2980
  import { Stream as Stream11 } from "@dxos/codec-protobuf";
@@ -2865,7 +3065,17 @@ var IFrameProxyRuntime = class {
2865
3065
 
2866
3066
  // packages/sdk/client-services/src/packlets/vault/vault-resource-lock.ts
2867
3067
  import { asyncTimeout, Trigger as Trigger5 } from "@dxos/async";
2868
- import { log as log10 } from "@dxos/log";
3068
+ import { log as log11, logInfo } from "@dxos/log";
3069
+ var __decorate3 = function(decorators, target, key, desc) {
3070
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3071
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
3072
+ r = Reflect.decorate(decorators, target, key, desc);
3073
+ else
3074
+ for (var i = decorators.length - 1; i >= 0; i--)
3075
+ if (d = decorators[i])
3076
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3077
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
3078
+ };
2869
3079
  var Message;
2870
3080
  (function(Message2) {
2871
3081
  Message2["ACQUIRING"] = "acquiring";
@@ -2879,14 +3089,41 @@ var VaultResourceLock = class {
2879
3089
  this._onRelease = onRelease;
2880
3090
  this._broadcastChannel.onmessage = this._onMessage.bind(this);
2881
3091
  }
3092
+ get lockKey() {
3093
+ return this._lockKey;
3094
+ }
2882
3095
  async acquire() {
2883
3096
  this._broadcastChannel.postMessage({
2884
3097
  message: Message.ACQUIRING
2885
3098
  });
2886
3099
  try {
3100
+ log11("aquiring lock...", {}, {
3101
+ file: "vault-resource-lock.ts",
3102
+ line: 44,
3103
+ scope: this,
3104
+ callSite: (f, a) => f(...a)
3105
+ });
2887
3106
  await asyncTimeout(this._requestLock(), 3e3);
3107
+ log11("acquired lock", {}, {
3108
+ file: "vault-resource-lock.ts",
3109
+ line: 46,
3110
+ scope: this,
3111
+ callSite: (f, a) => f(...a)
3112
+ });
2888
3113
  } catch (e) {
3114
+ log11("stealing lock...", {}, {
3115
+ file: "vault-resource-lock.ts",
3116
+ line: 48,
3117
+ scope: this,
3118
+ callSite: (f, a) => f(...a)
3119
+ });
2889
3120
  await this._requestLock(true);
3121
+ log11("stolen lock", {}, {
3122
+ file: "vault-resource-lock.ts",
3123
+ line: 50,
3124
+ scope: this,
3125
+ callSite: (f, a) => f(...a)
3126
+ });
2890
3127
  }
2891
3128
  }
2892
3129
  async release() {
@@ -2898,11 +3135,11 @@ var VaultResourceLock = class {
2898
3135
  }
2899
3136
  }
2900
3137
  async _requestLock(steal = false) {
2901
- log10("requesting lock...", {
3138
+ log11("requesting lock...", {
2902
3139
  steal
2903
3140
  }, {
2904
3141
  file: "vault-resource-lock.ts",
2905
- line: 56,
3142
+ line: 65,
2906
3143
  scope: this,
2907
3144
  callSite: (f, a) => f(...a)
2908
3145
  });
@@ -2915,16 +3152,16 @@ var VaultResourceLock = class {
2915
3152
  acquired.wake();
2916
3153
  this._releaseTrigger = new Trigger5();
2917
3154
  await this._releaseTrigger.wait();
2918
- log10("releasing lock...", {}, {
3155
+ log11("releasing lock...", {}, {
2919
3156
  file: "vault-resource-lock.ts",
2920
- line: 65,
3157
+ line: 74,
2921
3158
  scope: this,
2922
3159
  callSite: (f, a) => f(...a)
2923
3160
  });
2924
3161
  await ((_b = this._onRelease) == null ? void 0 : _b.call(this));
2925
- log10("released lock", {}, {
3162
+ log11("released lock", {}, {
2926
3163
  file: "vault-resource-lock.ts",
2927
- line: 67,
3164
+ line: 76,
2928
3165
  scope: this,
2929
3166
  callSite: (f, a) => f(...a)
2930
3167
  });
@@ -2933,20 +3170,23 @@ var VaultResourceLock = class {
2933
3170
  await ((_a = this._onRelease) == null ? void 0 : _a.call(this));
2934
3171
  });
2935
3172
  await acquired.wait();
2936
- log10("recieved lock", {
3173
+ log11("recieved lock", {
2937
3174
  steal
2938
3175
  }, {
2939
3176
  file: "vault-resource-lock.ts",
2940
- line: 74,
3177
+ line: 83,
2941
3178
  scope: this,
2942
3179
  callSite: (f, a) => f(...a)
2943
3180
  });
2944
3181
  }
2945
3182
  };
3183
+ __decorate3([
3184
+ logInfo
3185
+ ], VaultResourceLock.prototype, "lockKey", null);
2946
3186
 
2947
3187
  // packages/sdk/client-services/src/packlets/vault/worker-runtime.ts
2948
3188
  import { Trigger as Trigger7 } from "@dxos/async";
2949
- import { log as log12 } from "@dxos/log";
3189
+ import { log as log13 } from "@dxos/log";
2950
3190
  import { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from "@dxos/messaging";
2951
3191
  import { NetworkManager, WebRTCTransportProxyFactory } from "@dxos/network-manager";
2952
3192
 
@@ -2954,7 +3194,7 @@ import { NetworkManager, WebRTCTransportProxyFactory } from "@dxos/network-manag
2954
3194
  import assert11 from "@dxos/node-std/assert";
2955
3195
  import { asyncTimeout as asyncTimeout2, Trigger as Trigger6 } from "@dxos/async";
2956
3196
  import { iframeServiceBundle as iframeServiceBundle2, workerServiceBundle as workerServiceBundle2 } from "@dxos/client";
2957
- import { log as log11, logInfo } from "@dxos/log";
3197
+ import { log as log12, logInfo as logInfo2 } from "@dxos/log";
2958
3198
  import { createProtoRpcPeer as createProtoRpcPeer3 } from "@dxos/rpc";
2959
3199
  import { Callback } from "@dxos/util";
2960
3200
 
@@ -3012,7 +3252,7 @@ var ClientRpcServer = class {
3012
3252
  };
3013
3253
 
3014
3254
  // packages/sdk/client-services/src/packlets/vault/worker-session.ts
3015
- var __decorate3 = function(decorators, target, key, desc) {
3255
+ var __decorate4 = function(decorators, target, key, desc) {
3016
3256
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3017
3257
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
3018
3258
  r = Reflect.decorate(decorators, target, key, desc);
@@ -3076,7 +3316,7 @@ var WorkerSession = class {
3076
3316
  try {
3077
3317
  await this.close();
3078
3318
  } catch (err) {
3079
- log11.catch(err, {}, {
3319
+ log12.catch(err, {}, {
3080
3320
  file: "worker-session.ts",
3081
3321
  line: 107,
3082
3322
  scope: this,
@@ -3094,7 +3334,7 @@ var WorkerSession = class {
3094
3334
  this.bridgeService = this._iframeRpc.rpc.BridgeService;
3095
3335
  }
3096
3336
  async open() {
3097
- log11.info("opening..", {}, {
3337
+ log12.info("opening..", {}, {
3098
3338
  file: "worker-session.ts",
3099
3339
  line: 121,
3100
3340
  scope: this,
@@ -3112,7 +3352,7 @@ var WorkerSession = class {
3112
3352
  try {
3113
3353
  await this._iframeRpc.rpc.IframeService.heartbeat();
3114
3354
  } catch (err1) {
3115
- log11.warn("Heartbeat failed", {
3355
+ log12.warn("Heartbeat failed", {
3116
3356
  err: err1
3117
3357
  }, {
3118
3358
  file: "worker-session.ts",
@@ -3123,7 +3363,7 @@ var WorkerSession = class {
3123
3363
  try {
3124
3364
  await this.close();
3125
3365
  } catch (err) {
3126
- log11.catch(err, {}, {
3366
+ log12.catch(err, {}, {
3127
3367
  file: "worker-session.ts",
3128
3368
  line: 137,
3129
3369
  scope: this,
@@ -3134,7 +3374,7 @@ var WorkerSession = class {
3134
3374
  }, this._options.heartbeatInterval);
3135
3375
  }
3136
3376
  async close() {
3137
- log11.info("closing..", {}, {
3377
+ log12.info("closing..", {}, {
3138
3378
  file: "worker-session.ts",
3139
3379
  line: 144,
3140
3380
  scope: this,
@@ -3143,7 +3383,7 @@ var WorkerSession = class {
3143
3383
  try {
3144
3384
  await this.onClose.callIfSet();
3145
3385
  } catch (err) {
3146
- log11.catch(err, {}, {
3386
+ log12.catch(err, {}, {
3147
3387
  file: "worker-session.ts",
3148
3388
  line: 148,
3149
3389
  scope: this,
@@ -3162,7 +3402,7 @@ var WorkerSession = class {
3162
3402
  try {
3163
3403
  await asyncTimeout2(this._shellClientRpc.open(), 1e3);
3164
3404
  } catch (e) {
3165
- log11.info("No shell connected.", {}, {
3405
+ log12.info("No shell connected.", {}, {
3166
3406
  file: "worker-session.ts",
3167
3407
  line: 162,
3168
3408
  scope: this,
@@ -3171,8 +3411,8 @@ var WorkerSession = class {
3171
3411
  }
3172
3412
  }
3173
3413
  };
3174
- __decorate3([
3175
- logInfo
3414
+ __decorate4([
3415
+ logInfo2
3176
3416
  ], WorkerSession.prototype, "origin", void 0);
3177
3417
 
3178
3418
  // packages/sdk/client-services/src/packlets/vault/worker-runtime.ts
@@ -3186,7 +3426,7 @@ var WorkerRuntime = class {
3186
3426
  this._clientServices = new ClientServicesHost();
3187
3427
  }
3188
3428
  async start() {
3189
- log12("starting...", {}, {
3429
+ log13("starting...", {}, {
3190
3430
  file: "worker-runtime.ts",
3191
3431
  line: 44,
3192
3432
  scope: this,
@@ -3207,7 +3447,7 @@ var WorkerRuntime = class {
3207
3447
  });
3208
3448
  await this._clientServices.open();
3209
3449
  this._ready.wake(void 0);
3210
- log12("started", {}, {
3450
+ log13("started", {}, {
3211
3451
  file: "worker-runtime.ts",
3212
3452
  line: 61,
3213
3453
  scope: this,
@@ -3215,7 +3455,7 @@ var WorkerRuntime = class {
3215
3455
  });
3216
3456
  } catch (err) {
3217
3457
  this._ready.wake(err);
3218
- log12.catch(err, {}, {
3458
+ log13.catch(err, {}, {
3219
3459
  file: "worker-runtime.ts",
3220
3460
  line: 64,
3221
3461
  scope: this,
@@ -3273,7 +3513,7 @@ import { failUndefined as failUndefined2 } from "@dxos/debug";
3273
3513
  import { valueEncoding, MetadataStore, SpaceManager, DataServiceSubscriptions, SnapshotStore } from "@dxos/echo-pipeline";
3274
3514
  import { FeedFactory, FeedStore } from "@dxos/feed-store";
3275
3515
  import { Keyring } from "@dxos/keyring";
3276
- import { log as log13 } from "@dxos/log";
3516
+ import { log as log14 } from "@dxos/log";
3277
3517
  var ServiceContext = class {
3278
3518
  // prettier-ignore
3279
3519
  constructor(storage, networkManager, modelFactory) {
@@ -3310,7 +3550,7 @@ var ServiceContext = class {
3310
3550
  });
3311
3551
  }
3312
3552
  async open() {
3313
- log13("opening...", {}, {
3553
+ log14("opening...", {}, {
3314
3554
  file: "service-context.ts",
3315
3555
  line: 94,
3316
3556
  scope: this,
@@ -3322,7 +3562,7 @@ var ServiceContext = class {
3322
3562
  if (this.identityManager.identity) {
3323
3563
  await this._initialize();
3324
3564
  }
3325
- log13("opened", {}, {
3565
+ log14("opened", {}, {
3326
3566
  file: "service-context.ts",
3327
3567
  line: 101,
3328
3568
  scope: this,
@@ -3331,7 +3571,7 @@ var ServiceContext = class {
3331
3571
  }
3332
3572
  async close() {
3333
3573
  var _a, _b;
3334
- log13("closing...", {}, {
3574
+ log14("closing...", {}, {
3335
3575
  file: "service-context.ts",
3336
3576
  line: 105,
3337
3577
  scope: this,
@@ -3344,7 +3584,7 @@ var ServiceContext = class {
3344
3584
  await this.feedStore.close();
3345
3585
  await this.networkManager.close();
3346
3586
  this.dataServiceSubscriptions.clear();
3347
- log13("closed", {}, {
3587
+ log14("closed", {}, {
3348
3588
  file: "service-context.ts",
3349
3589
  line: 113,
3350
3590
  scope: this,
@@ -3352,7 +3592,7 @@ var ServiceContext = class {
3352
3592
  });
3353
3593
  }
3354
3594
  async reset() {
3355
- log13("resetting...", {}, {
3595
+ log14("resetting...", {}, {
3356
3596
  file: "service-context.ts",
3357
3597
  line: 117,
3358
3598
  scope: this,
@@ -3360,7 +3600,7 @@ var ServiceContext = class {
3360
3600
  });
3361
3601
  await this.close();
3362
3602
  await this.storage.reset();
3363
- log13("reset", {}, {
3603
+ log14("reset", {}, {
3364
3604
  file: "service-context.ts",
3365
3605
  line: 120,
3366
3606
  scope: this,
@@ -3380,7 +3620,7 @@ var ServiceContext = class {
3380
3620
  // Called when identity is created.
3381
3621
  async _initialize() {
3382
3622
  var _a;
3383
- log13("initializing spaces...", {}, {
3623
+ log14("initializing spaces...", {}, {
3384
3624
  file: "service-context.ts",
3385
3625
  line: 139,
3386
3626
  scope: this,
@@ -3414,7 +3654,7 @@ var ServiceContext = class {
3414
3654
  return;
3415
3655
  }
3416
3656
  if (!this.dataSpaceManager) {
3417
- log13("dataSpaceManager not initialized yet, ignoring space admission", {
3657
+ log14("dataSpaceManager not initialized yet, ignoring space admission", {
3418
3658
  details: assertion
3419
3659
  }, {
3420
3660
  file: "service-context.ts",
@@ -3425,7 +3665,7 @@ var ServiceContext = class {
3425
3665
  return;
3426
3666
  }
3427
3667
  if (this.dataSpaceManager.spaces.has(assertion.spaceKey)) {
3428
- log13("space already exists, ignoring space admission", {
3668
+ log14("space already exists, ignoring space admission", {
3429
3669
  details: assertion
3430
3670
  }, {
3431
3671
  file: "service-context.ts",
@@ -3436,7 +3676,7 @@ var ServiceContext = class {
3436
3676
  return;
3437
3677
  }
3438
3678
  try {
3439
- log13("accepting space recorded in halo", {
3679
+ log14("accepting space recorded in halo", {
3440
3680
  details: assertion
3441
3681
  }, {
3442
3682
  file: "service-context.ts",
@@ -3449,7 +3689,7 @@ var ServiceContext = class {
3449
3689
  genesisFeedKey: assertion.genesisFeedKey
3450
3690
  });
3451
3691
  } catch (err) {
3452
- log13.catch(err, {}, {
3692
+ log14.catch(err, {}, {
3453
3693
  file: "service-context.ts",
3454
3694
  line: 197,
3455
3695
  scope: this,
@@ -3497,7 +3737,8 @@ var ClientServicesHost = class {
3497
3737
  // TODO(wittjosiah): Turn this on by default.
3498
3738
  lockKey
3499
3739
  } = {}) {
3500
- this._statusUpdate = new Event6();
3740
+ this._statusUpdate = new Event7();
3741
+ this._opening = false;
3501
3742
  this._open = false;
3502
3743
  this._storage = storage;
3503
3744
  this._modelFactory = modelFactory;
@@ -3509,7 +3750,9 @@ var ClientServicesHost = class {
3509
3750
  }
3510
3751
  this._resourceLock = lockKey ? new VaultResourceLock({
3511
3752
  lockKey,
3512
- onAcquire: () => this.open(),
3753
+ onAcquire: () => {
3754
+ this._opening || this.open();
3755
+ },
3513
3756
  onRelease: () => this.close()
3514
3757
  }) : void 0;
3515
3758
  this._systemService = new SystemServiceImpl({
@@ -3565,20 +3808,23 @@ var ClientServicesHost = class {
3565
3808
  }
3566
3809
  }
3567
3810
  async open() {
3568
- var _a, _b;
3811
+ var _a, _b, _c;
3569
3812
  if (this._open) {
3570
3813
  return;
3571
3814
  }
3572
3815
  assert12(this._config, "config not set");
3573
3816
  assert12(this._storage, "storage not set");
3574
3817
  assert12(this._networkManager, "network manager not set");
3575
- log14("opening...", {}, {
3818
+ this._opening = true;
3819
+ log15("opening...", {
3820
+ lockKey: (_a = this._resourceLock) == null ? void 0 : _a.lockKey
3821
+ }, {
3576
3822
  file: "service-host.ts",
3577
- line: 166,
3823
+ line: 170,
3578
3824
  scope: this,
3579
3825
  callSite: (f, a) => f(...a)
3580
3826
  });
3581
- await ((_a = this._resourceLock) == null ? void 0 : _a.acquire());
3827
+ await ((_b = this._resourceLock) == null ? void 0 : _b.acquire());
3582
3828
  this._serviceContext = new ServiceContext(this._storage, this._networkManager, this._modelFactory);
3583
3829
  this._serviceRegistry.setServices({
3584
3830
  SystemService: this._systemService,
@@ -3607,14 +3853,15 @@ var ClientServicesHost = class {
3607
3853
  })
3608
3854
  });
3609
3855
  await this._serviceContext.open();
3856
+ this._opening = false;
3610
3857
  this._open = true;
3611
3858
  this._statusUpdate.emit();
3612
- const deviceKey = (_b = this._serviceContext.identityManager.identity) == null ? void 0 : _b.deviceKey;
3613
- log14("opened", {
3859
+ const deviceKey = (_c = this._serviceContext.identityManager.identity) == null ? void 0 : _c.deviceKey;
3860
+ log15("opened", {
3614
3861
  deviceKey
3615
3862
  }, {
3616
3863
  file: "service-host.ts",
3617
- line: 219,
3864
+ line: 224,
3618
3865
  scope: this,
3619
3866
  callSite: (f, a) => f(...a)
3620
3867
  });
@@ -3625,11 +3872,11 @@ var ClientServicesHost = class {
3625
3872
  return;
3626
3873
  }
3627
3874
  const deviceKey = (_a = this._serviceContext.identityManager.identity) == null ? void 0 : _a.deviceKey;
3628
- log14("closing...", {
3875
+ log15("closing...", {
3629
3876
  deviceKey
3630
3877
  }, {
3631
3878
  file: "service-host.ts",
3632
- line: 228,
3879
+ line: 233,
3633
3880
  scope: this,
3634
3881
  callSite: (f, a) => f(...a)
3635
3882
  });
@@ -3639,11 +3886,11 @@ var ClientServicesHost = class {
3639
3886
  await this._serviceContext.close();
3640
3887
  this._open = false;
3641
3888
  this._statusUpdate.emit();
3642
- log14("closed", {
3889
+ log15("closed", {
3643
3890
  deviceKey
3644
3891
  }, {
3645
3892
  file: "service-host.ts",
3646
- line: 233,
3893
+ line: 238,
3647
3894
  scope: this,
3648
3895
  callSite: (f, a) => f(...a)
3649
3896
  });
@@ -3674,7 +3921,7 @@ var LocalClientServices = class {
3674
3921
 
3675
3922
  // packages/sdk/client-services/src/packlets/services/utils.ts
3676
3923
  import { Config } from "@dxos/config";
3677
- import { log as log15 } from "@dxos/log";
3924
+ import { log as log16 } from "@dxos/log";
3678
3925
  import { MemorySignalManager as MemorySignalManager2, MemorySignalManagerContext as MemorySignalManagerContext2, WebsocketSignalManager as WebsocketSignalManager2 } from "@dxos/messaging";
3679
3926
  import { createWebRTCTransportFactory, MemoryTransportFactory, NetworkManager as NetworkManager2 } from "@dxos/network-manager";
3680
3927
  var fromHost = (config = new Config()) => {
@@ -3697,7 +3944,7 @@ var createNetworkManager = (config, options = {}) => {
3697
3944
  transportFactory
3698
3945
  });
3699
3946
  }
3700
- log15.warn("P2P network is not configured.", {}, {
3947
+ log16.warn("P2P network is not configured.", {}, {
3701
3948
  file: "utils.ts",
3702
3949
  line: 48,
3703
3950
  scope: void 0,
@@ -3710,7 +3957,7 @@ var createNetworkManager = (config, options = {}) => {
3710
3957
  };
3711
3958
 
3712
3959
  // packages/sdk/client-services/src/packlets/vault/iframe-host-runtime.ts
3713
- var __decorate4 = function(decorators, target, key, desc) {
3960
+ var __decorate5 = function(decorators, target, key, desc) {
3714
3961
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3715
3962
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
3716
3963
  r = Reflect.decorate(decorators, target, key, desc);
@@ -3740,7 +3987,7 @@ var IFrameHostRuntime = class {
3740
3987
  }
3741
3988
  async start() {
3742
3989
  var _a;
3743
- log16("starting...", {}, {
3990
+ log17("starting...", {}, {
3744
3991
  file: "iframe-host-runtime.ts",
3745
3992
  line: 67,
3746
3993
  scope: this,
@@ -3791,7 +4038,7 @@ var IFrameHostRuntime = class {
3791
4038
  (_a = this._shellRuntime) == null ? void 0 : _a.open()
3792
4039
  ]);
3793
4040
  this._ready.wake(void 0);
3794
- log16("started", {}, {
4041
+ log17("started", {}, {
3795
4042
  file: "iframe-host-runtime.ts",
3796
4043
  line: 110,
3797
4044
  scope: this,
@@ -3799,7 +4046,7 @@ var IFrameHostRuntime = class {
3799
4046
  });
3800
4047
  } catch (err) {
3801
4048
  this._ready.wake(err);
3802
- log16.catch(err, {}, {
4049
+ log17.catch(err, {}, {
3803
4050
  file: "iframe-host-runtime.ts",
3804
4051
  line: 113,
3805
4052
  scope: this,
@@ -3809,7 +4056,7 @@ var IFrameHostRuntime = class {
3809
4056
  }
3810
4057
  async stop() {
3811
4058
  var _a;
3812
- log16("stopping...", {}, {
4059
+ log17("stopping...", {}, {
3813
4060
  file: "iframe-host-runtime.ts",
3814
4061
  line: 118,
3815
4062
  scope: this,
@@ -3818,7 +4065,7 @@ var IFrameHostRuntime = class {
3818
4065
  await this._clientRpc.close();
3819
4066
  await this._clientServices.close();
3820
4067
  await ((_a = this._shellRuntime) == null ? void 0 : _a.close());
3821
- log16("stopped", {}, {
4068
+ log17("stopped", {}, {
3822
4069
  file: "iframe-host-runtime.ts",
3823
4070
  line: 122,
3824
4071
  scope: this,
@@ -3826,8 +4073,8 @@ var IFrameHostRuntime = class {
3826
4073
  });
3827
4074
  }
3828
4075
  };
3829
- __decorate4([
3830
- logInfo2
4076
+ __decorate5([
4077
+ logInfo3
3831
4078
  ], IFrameHostRuntime.prototype, "origin", void 0);
3832
4079
 
3833
4080
  export {
@@ -3865,4 +4112,4 @@ export {
3865
4112
  LocalClientServices,
3866
4113
  fromHost
3867
4114
  };
3868
- //# sourceMappingURL=chunk-ZIQUYEJS.mjs.map
4115
+ //# sourceMappingURL=chunk-E3FD43YN.mjs.map