@dxos/client-services 0.1.31 → 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 (52) hide show
  1. package/dist/lib/browser/{chunk-DFO3FW2W.mjs → chunk-E3FD43YN.mjs} +423 -209
  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 +3 -3
  6. package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
  7. package/dist/lib/node/index.cjs +424 -210
  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 +432 -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 +24 -4
  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.map +1 -1
  25. package/dist/types/src/packlets/testing/host-test-builder.d.ts +2 -2
  26. package/dist/types/src/packlets/testing/host-test-builder.d.ts.map +1 -1
  27. package/dist/types/src/packlets/vault/vault-resource-lock.d.ts +1 -0
  28. package/dist/types/src/packlets/vault/vault-resource-lock.d.ts.map +1 -1
  29. package/package.json +30 -30
  30. package/src/packlets/identity/identity-manager.ts +32 -17
  31. package/src/packlets/invitations/device-invitations-handler.ts +5 -3
  32. package/src/packlets/invitations/space-invitations-handler.test.ts +20 -3
  33. package/src/packlets/invitations/space-invitations-handler.ts +15 -8
  34. package/src/packlets/services/service-context.test.ts +6 -5
  35. package/src/packlets/services/service-host.ts +7 -2
  36. package/src/packlets/spaces/data-space-manager.test.ts +17 -2
  37. package/src/packlets/spaces/data-space-manager.ts +76 -30
  38. package/src/packlets/spaces/data-space.ts +90 -15
  39. package/src/packlets/spaces/notarization-plugin.test.ts +3 -1
  40. package/src/packlets/spaces/notarization-plugin.ts +64 -23
  41. package/src/packlets/spaces/spaces-service.test.ts +1 -1
  42. package/src/packlets/spaces/spaces-service.ts +28 -17
  43. package/src/packlets/testing/host-test-builder.ts +2 -2
  44. package/src/packlets/testing/test-builder.ts +2 -2
  45. package/src/packlets/tests/client-services.test.ts +24 -11
  46. package/src/packlets/tests/client.test.ts +3 -6
  47. package/src/packlets/tests/halo-profile.test.ts +5 -5
  48. package/src/packlets/tests/spaces-invitations.test.ts +4 -4
  49. package/src/packlets/tests/spaces.test.ts +20 -11
  50. package/src/packlets/tests/text.test.ts +6 -6
  51. package/src/packlets/vault/vault-resource-lock.ts +10 -1
  52. package/dist/lib/browser/chunk-DFO3FW2W.mjs.map +0 -7
@@ -653,7 +653,7 @@ var IdentityManager = class {
653
653
  identityRecord
654
654
  }, {
655
655
  file: "identity-manager.ts",
656
- line: 63,
656
+ line: 71,
657
657
  scope: this,
658
658
  callSite: (f, a) => f(...a)
659
659
  });
@@ -672,7 +672,7 @@ var IdentityManager = class {
672
672
  (0, import_node_assert2.default)(!this._identity, "Identity already exists.");
673
673
  (0, import_log3.log)("creating identity...", {}, {
674
674
  file: "identity-manager.ts",
675
- line: 78,
675
+ line: 86,
676
676
  scope: this,
677
677
  callSite: (f, a) => f(...a)
678
678
  });
@@ -681,21 +681,23 @@ var IdentityManager = class {
681
681
  identityKey: await this._keyring.createKey(),
682
682
  deviceKey: await this._keyring.createKey(),
683
683
  haloSpace: {
684
- spaceKey: await this._keyring.createKey(),
684
+ key: await this._keyring.createKey(),
685
685
  genesisFeedKey: controlFeedKey,
686
- writeControlFeedKey: controlFeedKey,
687
- writeDataFeedKey: await this._keyring.createKey()
686
+ controlFeedKey,
687
+ dataFeedKey: await this._keyring.createKey()
688
688
  }
689
689
  };
690
690
  const identity = await this._constructIdentity(identityRecord);
691
691
  await identity.open();
692
692
  {
693
693
  const generator = new import_credentials4.CredentialGenerator(this._keyring, identityRecord.identityKey, identityRecord.deviceKey);
694
+ (0, import_node_assert2.default)(identityRecord.haloSpace.genesisFeedKey, "Genesis feed key is required.");
695
+ (0, import_node_assert2.default)(identityRecord.haloSpace.dataFeedKey, "Data feed key is required.");
694
696
  const credentials = [
695
697
  // Space genesis.
696
- ...await generator.createSpaceGenesis(identityRecord.haloSpace.spaceKey, identityRecord.haloSpace.genesisFeedKey),
698
+ ...await generator.createSpaceGenesis(identityRecord.haloSpace.key, identityRecord.haloSpace.genesisFeedKey),
697
699
  // Feed admission.
698
- await generator.createFeedAdmission(identityRecord.haloSpace.spaceKey, identityRecord.haloSpace.writeDataFeedKey, import_credentials5.AdmittedFeed.Designation.DATA)
700
+ await generator.createFeedAdmission(identityRecord.haloSpace.key, identityRecord.haloSpace.dataFeedKey, import_credentials5.AdmittedFeed.Designation.DATA)
699
701
  ];
700
702
  if (displayName) {
701
703
  credentials.push(await generator.createProfileCredential({
@@ -720,7 +722,7 @@ var IdentityManager = class {
720
722
  deviceKey: identity.deviceKey
721
723
  }, {
722
724
  file: "identity-manager.ts",
723
- line: 136,
725
+ line: 143,
724
726
  scope: this,
725
727
  callSite: (f, a) => f(...a)
726
728
  });
@@ -734,7 +736,7 @@ var IdentityManager = class {
734
736
  params
735
737
  }, {
736
738
  file: "identity-manager.ts",
737
- line: 144,
739
+ line: 151,
738
740
  scope: this,
739
741
  callSite: (f, a) => f(...a)
740
742
  });
@@ -743,10 +745,11 @@ var IdentityManager = class {
743
745
  identityKey: params.identityKey,
744
746
  deviceKey: params.deviceKey,
745
747
  haloSpace: {
746
- spaceKey: params.haloSpaceKey,
748
+ key: params.haloSpaceKey,
747
749
  genesisFeedKey: params.haloGenesisFeedKey,
748
- writeControlFeedKey: params.controlFeedKey,
749
- writeDataFeedKey: params.dataFeedKey
750
+ controlFeedKey: params.controlFeedKey,
751
+ dataFeedKey: params.dataFeedKey,
752
+ controlTimeframe: params.controlTimeframe
750
753
  }
751
754
  };
752
755
  const identity = await this._constructIdentity(identityRecord);
@@ -760,7 +763,7 @@ var IdentityManager = class {
760
763
  deviceKey: identity.deviceKey
761
764
  }, {
762
765
  file: "identity-manager.ts",
763
- line: 164,
766
+ line: 172,
764
767
  scope: this,
765
768
  callSite: (f, a) => f(...a)
766
769
  });
@@ -772,14 +775,16 @@ var IdentityManager = class {
772
775
  identityRecord
773
776
  }, {
774
777
  file: "identity-manager.ts",
775
- line: 170,
778
+ line: 178,
776
779
  scope: this,
777
780
  callSite: (f, a) => f(...a)
778
781
  });
779
- const controlFeed = await this._feedStore.openFeed(identityRecord.haloSpace.writeControlFeedKey, {
782
+ (0, import_node_assert2.default)(identityRecord.haloSpace.controlFeedKey);
783
+ const controlFeed = await this._feedStore.openFeed(identityRecord.haloSpace.controlFeedKey, {
780
784
  writable: true
781
785
  });
782
- const dataFeed = await this._feedStore.openFeed(identityRecord.haloSpace.writeDataFeedKey, {
786
+ (0, import_node_assert2.default)(identityRecord.haloSpace.dataFeedKey);
787
+ const dataFeed = await this._feedStore.openFeed(identityRecord.haloSpace.dataFeedKey, {
783
788
  writable: true
784
789
  });
785
790
  const space = await this._constructSpace({
@@ -803,16 +808,19 @@ var IdentityManager = class {
803
808
  identityKey: identityRecord.identityKey
804
809
  }, {
805
810
  file: "identity-manager.ts",
806
- line: 196,
811
+ line: 206,
807
812
  scope: this,
808
813
  callSite: (f, a) => f(...a)
809
814
  });
815
+ if (identityRecord.haloSpace.controlTimeframe) {
816
+ identity.controlPipeline.state.setTargetTimeframe(identityRecord.haloSpace.controlTimeframe);
817
+ }
810
818
  return identity;
811
819
  }
812
820
  async _constructSpace({ spaceRecord, swarmIdentity, identityKey }) {
813
821
  return this._spaceManager.constructSpace({
814
822
  metadata: {
815
- key: spaceRecord.spaceKey,
823
+ key: spaceRecord.key,
816
824
  genesisFeedKey: spaceRecord.genesisFeedKey
817
825
  },
818
826
  swarmIdentity,
@@ -928,7 +936,8 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
928
936
  return {
929
937
  identityKey: identity.identityKey,
930
938
  haloSpaceKey: identity.haloSpaceKey,
931
- genesisFeedKey: identity.haloGenesisFeedKey
939
+ genesisFeedKey: identity.haloGenesisFeedKey,
940
+ controlTimeframe: identity.controlPipeline.state.timeframe
932
941
  };
933
942
  },
934
943
  authenticate: async ({ authenticationCode: code }) => {
@@ -936,7 +945,7 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
936
945
  authenticationCode: code
937
946
  }, {
938
947
  file: "device-invitations-handler.ts",
939
- line: 106,
948
+ line: 107,
940
949
  scope: this,
941
950
  callSite: (f, a) => f(...a)
942
951
  });
@@ -958,7 +967,7 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
958
967
  guest: credentials.deviceKey
959
968
  }, {
960
969
  file: "device-invitations-handler.ts",
961
- line: 121,
970
+ line: 122,
962
971
  scope: this,
963
972
  callSite: (f, a) => f(...a)
964
973
  });
@@ -977,7 +986,7 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
977
986
  host: identity.deviceKey
978
987
  }, {
979
988
  file: "device-invitations-handler.ts",
980
- line: 137,
989
+ line: 138,
981
990
  scope: this,
982
991
  callSite: (f, a) => f(...a)
983
992
  });
@@ -990,7 +999,7 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
990
999
  guest: deviceKey
991
1000
  }, {
992
1001
  file: "device-invitations-handler.ts",
993
- line: 140,
1002
+ line: 141,
994
1003
  scope: this,
995
1004
  callSite: (f, a) => f(...a)
996
1005
  });
@@ -999,7 +1008,7 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
999
1008
  if (!observable.cancelled) {
1000
1009
  import_log4.log.error("failed", err, {
1001
1010
  file: "device-invitations-handler.ts",
1002
- line: 144,
1011
+ line: 145,
1003
1012
  scope: this,
1004
1013
  callSite: (f, a) => f(...a)
1005
1014
  });
@@ -1064,22 +1073,22 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
1064
1073
  }
1065
1074
  (0, import_log4.log)("connected", {}, {
1066
1075
  file: "device-invitations-handler.ts",
1067
- line: 215,
1076
+ line: 216,
1068
1077
  scope: this,
1069
1078
  callSite: (f, a) => f(...a)
1070
1079
  });
1071
1080
  (_b = (_a = observable.callback).onConnected) == null ? void 0 : _b.call(_a, invitation);
1072
1081
  (0, import_log4.log)("sending admission request", {}, {
1073
1082
  file: "device-invitations-handler.ts",
1074
- line: 219,
1083
+ line: 220,
1075
1084
  scope: this,
1076
1085
  callSite: (f, a) => f(...a)
1077
1086
  });
1078
- const { identityKey, haloSpaceKey, genesisFeedKey } = await extension.rpc.HaloHostService.requestAdmission();
1087
+ const { identityKey, haloSpaceKey, genesisFeedKey, controlTimeframe } = await extension.rpc.HaloHostService.requestAdmission();
1079
1088
  if (invitation.type === void 0 || invitation.type === import_services.Invitation.Type.INTERACTIVE) {
1080
1089
  (0, import_log4.log)("guest waiting for authentication code...", {}, {
1081
1090
  file: "device-invitations-handler.ts",
1082
- line: 226,
1091
+ line: 227,
1083
1092
  scope: this,
1084
1093
  callSite: (f, a) => f(...a)
1085
1094
  });
@@ -1089,7 +1098,7 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
1089
1098
  });
1090
1099
  (0, import_log4.log)("sending authentication request", {}, {
1091
1100
  file: "device-invitations-handler.ts",
1092
- line: 229,
1101
+ line: 230,
1093
1102
  scope: this,
1094
1103
  callSite: (f, a) => f(...a)
1095
1104
  });
@@ -1107,7 +1116,7 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
1107
1116
  dataFeedKey
1108
1117
  }, {
1109
1118
  file: "device-invitations-handler.ts",
1110
- line: 238,
1119
+ line: 239,
1111
1120
  scope: this,
1112
1121
  callSite: (f, a) => f(...a)
1113
1122
  });
@@ -1122,14 +1131,15 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
1122
1131
  haloSpaceKey,
1123
1132
  haloGenesisFeedKey: genesisFeedKey,
1124
1133
  controlFeedKey,
1125
- dataFeedKey
1134
+ dataFeedKey,
1135
+ controlTimeframe
1126
1136
  });
1127
1137
  (0, import_log4.log)("admitted by host", {
1128
1138
  guest: identity.deviceKey,
1129
1139
  identityKey
1130
1140
  }, {
1131
1141
  file: "device-invitations-handler.ts",
1132
- line: 257,
1142
+ line: 259,
1133
1143
  scope: this,
1134
1144
  callSite: (f, a) => f(...a)
1135
1145
  });
@@ -1138,7 +1148,7 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
1138
1148
  if (!observable.cancelled) {
1139
1149
  import_log4.log.warn("auth failed", err, {
1140
1150
  file: "device-invitations-handler.ts",
1141
- line: 261,
1151
+ line: 263,
1142
1152
  scope: this,
1143
1153
  callSite: (f, a) => f(...a)
1144
1154
  });
@@ -1582,6 +1592,7 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1582
1592
  };
1583
1593
  },
1584
1594
  requestAdmission: async ({ identityKey, deviceKey, controlFeedKey, dataFeedKey }) => {
1595
+ var _a2;
1585
1596
  try {
1586
1597
  if (isAuthenticationRequired(invitation) && !authenticationPassed) {
1587
1598
  throw new Error("Not authenticated");
@@ -1602,7 +1613,9 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1602
1613
  await (0, import_feed_store3.writeMessages)(space.inner.controlPipeline.writer, credentials);
1603
1614
  complete.wake(deviceKey);
1604
1615
  return {
1605
- credential: spaceMemberCredential
1616
+ credential: spaceMemberCredential,
1617
+ controlTimeframe: space.inner.controlPipeline.state.timeframe,
1618
+ dataTimeframe: (_a2 = space.dataPipeline.pipelineState) == null ? void 0 : _a2.timeframe
1606
1619
  };
1607
1620
  } catch (err) {
1608
1621
  observable.callback.onError(err);
@@ -1617,7 +1630,7 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1617
1630
  host: this._signingContext.deviceKey
1618
1631
  }, {
1619
1632
  file: "space-invitations-handler.ts",
1620
- line: 191,
1633
+ line: 195,
1621
1634
  scope: this,
1622
1635
  callSite: (f, a) => f(...a)
1623
1636
  });
@@ -1630,7 +1643,7 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1630
1643
  guest: deviceKey
1631
1644
  }, {
1632
1645
  file: "space-invitations-handler.ts",
1633
- line: 194,
1646
+ line: 198,
1634
1647
  scope: this,
1635
1648
  callSite: (f, a) => f(...a)
1636
1649
  });
@@ -1639,7 +1652,7 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1639
1652
  if (!observable.cancelled) {
1640
1653
  import_log6.log.error("failed", err, {
1641
1654
  file: "space-invitations-handler.ts",
1642
- line: 198,
1655
+ line: 202,
1643
1656
  scope: this,
1644
1657
  callSite: (f, a) => f(...a)
1645
1658
  });
@@ -1709,7 +1722,7 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1709
1722
  guest: this._signingContext.deviceKey
1710
1723
  }, {
1711
1724
  file: "space-invitations-handler.ts",
1712
- line: 271,
1725
+ line: 275,
1713
1726
  scope: this,
1714
1727
  callSite: (f, a) => f(...a)
1715
1728
  });
@@ -1718,7 +1731,7 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1718
1731
  guest: this._signingContext.deviceKey
1719
1732
  }, {
1720
1733
  file: "space-invitations-handler.ts",
1721
- line: 275,
1734
+ line: 279,
1722
1735
  scope: this,
1723
1736
  callSite: (f, a) => f(...a)
1724
1737
  });
@@ -1730,7 +1743,7 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1730
1743
  response: introductionResponse
1731
1744
  }, {
1732
1745
  file: "space-invitations-handler.ts",
1733
- line: 279,
1746
+ line: 283,
1734
1747
  scope: this,
1735
1748
  callSite: (f, a) => f(...a)
1736
1749
  });
@@ -1743,7 +1756,7 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1743
1756
  for (let attempt = 1; attempt <= MAX_OTP_ATTEMPTS; attempt++) {
1744
1757
  (0, import_log6.log)("guest waiting for authentication code...", {}, {
1745
1758
  file: "space-invitations-handler.ts",
1746
- line: 293,
1759
+ line: 297,
1747
1760
  scope: this,
1748
1761
  callSite: (f, a) => f(...a)
1749
1762
  });
@@ -1753,7 +1766,7 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1753
1766
  });
1754
1767
  (0, import_log6.log)("sending authentication request", {}, {
1755
1768
  file: "space-invitations-handler.ts",
1756
- line: 297,
1769
+ line: 301,
1757
1770
  scope: this,
1758
1771
  callSite: (f, a) => f(...a)
1759
1772
  });
@@ -1771,7 +1784,7 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1771
1784
  attempt
1772
1785
  }, {
1773
1786
  file: "space-invitations-handler.ts",
1774
- line: 307,
1787
+ line: 311,
1775
1788
  scope: this,
1776
1789
  callSite: (f, a) => f(...a)
1777
1790
  });
@@ -1786,11 +1799,11 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1786
1799
  guest: this._signingContext.deviceKey
1787
1800
  }, {
1788
1801
  file: "space-invitations-handler.ts",
1789
- line: 318,
1802
+ line: 322,
1790
1803
  scope: this,
1791
1804
  callSite: (f, a) => f(...a)
1792
1805
  });
1793
- const { credential } = await extension.rpc.SpaceHostService.requestAdmission({
1806
+ const { credential, controlTimeframe, dataTimeframe } = await extension.rpc.SpaceHostService.requestAdmission({
1794
1807
  identityKey: this._signingContext.identityKey,
1795
1808
  deviceKey: this._signingContext.deviceKey,
1796
1809
  controlFeedKey,
@@ -1801,7 +1814,9 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1801
1814
  (0, import_node_assert6.default)(credential.subject.id.equals(this._signingContext.identityKey));
1802
1815
  const space = await this._spaceManager.acceptSpace({
1803
1816
  spaceKey: assertion.spaceKey,
1804
- genesisFeedKey: assertion.genesisFeedKey
1817
+ genesisFeedKey: assertion.genesisFeedKey,
1818
+ controlTimeframe,
1819
+ dataTimeframe
1805
1820
  });
1806
1821
  await this._signingContext.recordCredential(credential);
1807
1822
  (0, import_log6.log)("admitted by host", {
@@ -1809,7 +1824,7 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1809
1824
  spaceKey: space.key
1810
1825
  }, {
1811
1826
  file: "space-invitations-handler.ts",
1812
- line: 340,
1827
+ line: 347,
1813
1828
  scope: this,
1814
1829
  callSite: (f, a) => f(...a)
1815
1830
  });
@@ -1818,7 +1833,7 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1818
1833
  if (!observable.cancelled) {
1819
1834
  import_log6.log.warn("auth failed", err, {
1820
1835
  file: "space-invitations-handler.ts",
1821
- line: 344,
1836
+ line: 351,
1822
1837
  scope: this,
1823
1838
  callSite: (f, a) => f(...a)
1824
1839
  });
@@ -1924,10 +1939,10 @@ var SpaceInvitationsServiceImpl = class extends AbstractInvitationsService {
1924
1939
  // packages/sdk/client-services/src/packlets/services/service-host.ts
1925
1940
  var import_node_assert12 = __toESM(require("node:assert"));
1926
1941
  var import_async19 = require("@dxos/async");
1927
- var import_client6 = require("@dxos/client");
1942
+ var import_client8 = require("@dxos/client");
1928
1943
  var import_debug7 = require("@dxos/debug");
1929
1944
  var import_echo_pipeline5 = require("@dxos/echo-pipeline");
1930
- var import_log15 = require("@dxos/log");
1945
+ var import_log16 = require("@dxos/log");
1931
1946
  var import_services8 = require("@dxos/protocols/proto/dxos/client/services");
1932
1947
 
1933
1948
  // packages/sdk/client-services/src/packlets/deprecated/tracing.ts
@@ -2015,20 +2030,24 @@ var NetworkServiceImpl = class {
2015
2030
  // packages/sdk/client-services/src/packlets/spaces/data-space-manager.ts
2016
2031
  var import_node_assert9 = __toESM(require("node:assert"));
2017
2032
  var import_async11 = require("@dxos/async");
2033
+ var import_client4 = require("@dxos/client");
2018
2034
  var import_context7 = require("@dxos/context");
2019
2035
  var import_credentials10 = require("@dxos/credentials");
2020
2036
  var import_echo_pipeline2 = require("@dxos/echo-pipeline");
2021
2037
  var import_keys8 = require("@dxos/keys");
2022
- var import_log8 = require("@dxos/log");
2038
+ var import_log9 = require("@dxos/log");
2023
2039
  var import_teleport_extension_gossip = require("@dxos/teleport-extension-gossip");
2024
2040
  var import_util5 = require("@dxos/util");
2025
2041
 
2026
2042
  // packages/sdk/client-services/src/packlets/spaces/data-space.ts
2027
2043
  var import_async10 = require("@dxos/async");
2044
+ var import_client3 = require("@dxos/client");
2028
2045
  var import_context6 = require("@dxos/context");
2029
2046
  var import_debug3 = require("@dxos/debug");
2030
2047
  var import_echo_pipeline = require("@dxos/echo-pipeline");
2048
+ var import_errors = require("@dxos/errors");
2031
2049
  var import_keys7 = require("@dxos/keys");
2050
+ var import_log8 = require("@dxos/log");
2032
2051
  var import_credentials9 = require("@dxos/protocols/proto/dxos/halo/credentials");
2033
2052
  var import_util4 = require("@dxos/util");
2034
2053
 
@@ -2041,9 +2060,9 @@ var import_log7 = require("@dxos/log");
2041
2060
  var import_protocols4 = require("@dxos/protocols");
2042
2061
  var import_teleport3 = require("@dxos/teleport");
2043
2062
  var import_util3 = require("@dxos/util");
2044
- var RETRY_TIMEOUT = 1e3;
2045
- var SUCCESS_DELAY = 1e3;
2046
- var NOTARIZE_TIMEOUT = 1e4;
2063
+ var DEFAULT_RETRY_TIMEOUT = 1e3;
2064
+ var DEFAULT_SUCCESS_DELAY = 1e3;
2065
+ var DEFAULT_NOTARIZE_TIMEOUT = 1e4;
2047
2066
  var NotarizationPlugin = class {
2048
2067
  constructor() {
2049
2068
  this._ctx = new import_context5.Context();
@@ -2060,12 +2079,12 @@ var NotarizationPlugin = class {
2060
2079
  /**
2061
2080
  * Request credentials to be notarized.
2062
2081
  */
2063
- async notarize(credentials) {
2082
+ async notarize({ ctx: opCtx, credentials, timeout = DEFAULT_NOTARIZE_TIMEOUT, retryTimeout = DEFAULT_RETRY_TIMEOUT, successDelay = DEFAULT_SUCCESS_DELAY }) {
2064
2083
  (0, import_log7.log)("notarize", {
2065
2084
  credentials
2066
2085
  }, {
2067
2086
  file: "notarization-plugin.ts",
2068
- line: 50,
2087
+ line: 85,
2069
2088
  scope: this,
2070
2089
  callSite: (f, a) => f(...a)
2071
2090
  });
@@ -2077,7 +2096,7 @@ var NotarizationPlugin = class {
2077
2096
  err
2078
2097
  }, {
2079
2098
  file: "notarization-plugin.ts",
2080
- line: 59,
2099
+ line: 94,
2081
2100
  scope: this,
2082
2101
  callSite: (f, a) => f(...a)
2083
2102
  });
@@ -2085,27 +2104,27 @@ var NotarizationPlugin = class {
2085
2104
  errors.throw(err);
2086
2105
  }
2087
2106
  });
2088
- (0, import_async9.scheduleTask)(ctx, () => {
2089
- import_log7.log.warn("Notarization timeout", {}, {
2090
- file: "notarization-plugin.ts",
2091
- line: 67,
2092
- scope: this,
2093
- callSite: (f, a) => f(...a)
2094
- });
2095
- void ctx.dispose();
2096
- errors.throw(new import_async9.TimeoutError(NOTARIZE_TIMEOUT, "Notarization timed out"));
2097
- }, NOTARIZE_TIMEOUT);
2107
+ opCtx == null ? void 0 : opCtx.onDispose(() => ctx.dispose());
2108
+ if (timeout !== 0) {
2109
+ (0, import_async9.scheduleTask)(ctx, () => {
2110
+ import_log7.log.warn("Notarization timeout", {
2111
+ timeout,
2112
+ peers: Array.from(this._extensions).map((extension) => extension.remotePeerId)
2113
+ }, {
2114
+ file: "notarization-plugin.ts",
2115
+ line: 106,
2116
+ scope: this,
2117
+ callSite: (f, a) => f(...a)
2118
+ });
2119
+ void ctx.dispose();
2120
+ errors.throw(new import_async9.TimeoutError(timeout, "Notarization timed out"));
2121
+ }, timeout);
2122
+ }
2098
2123
  const allNotarized = Promise.all(credentials.map((credential) => this._waitUntilProcessed(credential.id)));
2099
2124
  const peersTried = /* @__PURE__ */ new Set();
2100
2125
  const notarizeTask = new import_async9.DeferredTask(ctx, async () => {
2101
2126
  try {
2102
2127
  if (this._extensions.size === 0) {
2103
- import_log7.log.warn("No peers to notarize with", {}, {
2104
- file: "notarization-plugin.ts",
2105
- line: 82,
2106
- scope: this,
2107
- callSite: (f, a) => f(...a)
2108
- });
2109
2128
  return;
2110
2129
  }
2111
2130
  const peer = [
@@ -2113,15 +2132,15 @@ var NotarizationPlugin = class {
2113
2132
  ].find((peer2) => !peersTried.has(peer2));
2114
2133
  if (!peer) {
2115
2134
  import_log7.log.warn("Exhausted all peers to notarize with", {
2116
- retryIn: RETRY_TIMEOUT
2135
+ retryIn: retryTimeout
2117
2136
  }, {
2118
2137
  file: "notarization-plugin.ts",
2119
- line: 89,
2138
+ line: 131,
2120
2139
  scope: this,
2121
2140
  callSite: (f, a) => f(...a)
2122
2141
  });
2123
2142
  peersTried.clear();
2124
- (0, import_async9.scheduleTask)(ctx, () => notarizeTask.schedule(), RETRY_TIMEOUT);
2143
+ (0, import_async9.scheduleTask)(ctx, () => notarizeTask.schedule(), retryTimeout);
2125
2144
  return;
2126
2145
  }
2127
2146
  peersTried.add(peer);
@@ -2130,7 +2149,7 @@ var NotarizationPlugin = class {
2130
2149
  credentialId: credentials.map((credential) => credential.id)
2131
2150
  }, {
2132
2151
  file: "notarization-plugin.ts",
2133
- line: 96,
2152
+ line: 138,
2134
2153
  scope: this,
2135
2154
  callSite: (f, a) => f(...a)
2136
2155
  });
@@ -2139,15 +2158,15 @@ var NotarizationPlugin = class {
2139
2158
  });
2140
2159
  (0, import_log7.log)("success", {}, {
2141
2160
  file: "notarization-plugin.ts",
2142
- line: 100,
2161
+ line: 142,
2143
2162
  scope: this,
2144
2163
  callSite: (f, a) => f(...a)
2145
2164
  });
2146
- await (0, import_async9.sleep)(SUCCESS_DELAY);
2165
+ await (0, import_async9.sleep)(successDelay);
2147
2166
  } catch (err) {
2148
2167
  import_log7.log.warn("error notarizing (recoverable)", err, {
2149
2168
  file: "notarization-plugin.ts",
2150
- line: 103,
2169
+ line: 145,
2151
2170
  scope: this,
2152
2171
  callSite: (f, a) => f(...a)
2153
2172
  });
@@ -2158,12 +2177,13 @@ var NotarizationPlugin = class {
2158
2177
  this._extensionOpened.on(ctx, () => notarizeTask.schedule());
2159
2178
  try {
2160
2179
  await Promise.race([
2180
+ (0, import_context5.rejectOnDispose)(ctx),
2161
2181
  allNotarized,
2162
2182
  errors.wait()
2163
2183
  ]);
2164
2184
  (0, import_log7.log)("done", {}, {
2165
2185
  file: "notarization-plugin.ts",
2166
- line: 114,
2186
+ line: 155,
2167
2187
  scope: this,
2168
2188
  callSite: (f, a) => f(...a)
2169
2189
  });
@@ -2216,7 +2236,7 @@ var NotarizationPlugin = class {
2216
2236
  peer: extension.localPeerId
2217
2237
  }, {
2218
2238
  file: "notarization-plugin.ts",
2219
- line: 163,
2239
+ line: 204,
2220
2240
  scope: this,
2221
2241
  callSite: (f, a) => f(...a)
2222
2242
  });
@@ -2228,7 +2248,7 @@ var NotarizationPlugin = class {
2228
2248
  peer: extension.localPeerId
2229
2249
  }, {
2230
2250
  file: "notarization-plugin.ts",
2231
- line: 168,
2251
+ line: 209,
2232
2252
  scope: this,
2233
2253
  callSite: (f, a) => f(...a)
2234
2254
  });
@@ -2282,18 +2302,22 @@ var __decorate = function(decorators, target, key, desc) {
2282
2302
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2283
2303
  };
2284
2304
  var AUTH_TIMEOUT2 = 3e4;
2285
- var CONTROL_PIPELINE_READY_TIMEFRAME = 3e3;
2286
2305
  var DataSpace = class DataSpace2 {
2287
2306
  constructor(params) {
2288
2307
  this._ctx = new import_context6.Context();
2308
+ this._state = import_client3.SpaceState.CLOSED;
2309
+ this.stateUpdate = new import_async10.Event();
2310
+ var _a;
2289
2311
  this._inner = params.inner;
2312
+ this._inner.stateUpdate.on(this._ctx, () => this.stateUpdate.emit());
2290
2313
  this._gossip = params.gossip;
2291
2314
  this._presence = params.presence;
2292
2315
  this._keyring = params.keyring;
2293
2316
  this._feedStore = params.feedStore;
2294
2317
  this._metadataStore = params.metadataStore;
2295
2318
  this._signingContext = params.signingContext;
2296
- this._dataPipelineController = new import_echo_pipeline.DataPipelineControllerImpl({
2319
+ this._callbacks = (_a = params.callbacks) != null ? _a : {};
2320
+ this._dataPipeline = new import_echo_pipeline.DataPipeline({
2297
2321
  modelFactory: params.modelFactory,
2298
2322
  metadataStore: params.metadataStore,
2299
2323
  snapshotManager: params.snapshotManager,
@@ -2315,15 +2339,15 @@ var DataSpace = class DataSpace2 {
2315
2339
  get isOpen() {
2316
2340
  return this._inner.isOpen;
2317
2341
  }
2342
+ get state() {
2343
+ return this._state;
2344
+ }
2318
2345
  // TODO(burdon): Can we mark this for debugging only?
2319
2346
  get inner() {
2320
2347
  return this._inner;
2321
2348
  }
2322
- get dataPipelineController() {
2323
- return this._dataPipelineController;
2324
- }
2325
- get stateUpdate() {
2326
- return this._inner.stateUpdate;
2349
+ get dataPipeline() {
2350
+ return this._dataPipeline;
2327
2351
  }
2328
2352
  get presence() {
2329
2353
  return this._presence;
@@ -2335,9 +2359,12 @@ var DataSpace = class DataSpace2 {
2335
2359
  await this.notarizationPlugin.open();
2336
2360
  await this._notarizationPluginConsumer.open();
2337
2361
  await this._inner.open();
2362
+ this._state = import_client3.SpaceState.INACTIVE;
2338
2363
  }
2339
2364
  async close() {
2365
+ this._state = import_client3.SpaceState.CLOSED;
2340
2366
  await this._ctx.dispose();
2367
+ await this._dataPipeline.close();
2341
2368
  await this.authVerifier.close();
2342
2369
  await this._inner.close();
2343
2370
  await this._notarizationPluginConsumer.close();
@@ -2350,17 +2377,84 @@ var DataSpace = class DataSpace2 {
2350
2377
  listen(channel, callback) {
2351
2378
  return this._gossip.listen(channel, callback);
2352
2379
  }
2380
+ /**
2381
+ * Initialize the data pipeline in a separate task.
2382
+ */
2383
+ initializeDataPipelineAsync() {
2384
+ (0, import_async10.scheduleTask)(this._ctx, async () => {
2385
+ try {
2386
+ await this.initializeDataPipeline();
2387
+ } catch (err) {
2388
+ if (err instanceof import_errors.CancelledError) {
2389
+ (0, import_log8.log)("Data pipeline initialization cancelled", err, {
2390
+ file: "data-space.ts",
2391
+ line: 178,
2392
+ scope: this,
2393
+ callSite: (f, a) => f(...a)
2394
+ });
2395
+ return;
2396
+ }
2397
+ import_log8.log.error("Error initializing data pipeline", err, {
2398
+ file: "data-space.ts",
2399
+ line: 182,
2400
+ scope: this,
2401
+ callSite: (f, a) => f(...a)
2402
+ });
2403
+ }
2404
+ });
2405
+ }
2353
2406
  async initializeDataPipeline() {
2407
+ var _a, _b, _c, _d;
2408
+ if (this._state !== import_client3.SpaceState.INACTIVE) {
2409
+ throw new import_errors.SystemError("Invalid operation");
2410
+ }
2411
+ this._state = import_client3.SpaceState.INITIALIZING;
2354
2412
  await this._inner.controlPipeline.state.waitUntilReachedTargetTimeframe({
2355
- timeout: CONTROL_PIPELINE_READY_TIMEFRAME
2413
+ ctx: this._ctx,
2414
+ breakOnStall: false
2356
2415
  });
2357
2416
  await this._createWritableFeeds();
2417
+ (0, import_log8.log)("Writable feeds created", {}, {
2418
+ file: "data-space.ts",
2419
+ line: 200,
2420
+ scope: this,
2421
+ callSite: (f, a) => f(...a)
2422
+ });
2423
+ this.stateUpdate.emit();
2358
2424
  this.notarizationPlugin.setWriter((0, import_echo_pipeline.createMappedFeedWriter)((credential) => ({
2359
2425
  credential: {
2360
2426
  credential
2361
2427
  }
2362
2428
  }), this._inner.controlPipeline.writer));
2363
- await this._inner.initDataPipeline(this._dataPipelineController);
2429
+ await this._dataPipeline.open({
2430
+ openPipeline: async (start) => {
2431
+ const pipeline = await this._inner.createDataPipeline({
2432
+ start
2433
+ });
2434
+ await pipeline.start();
2435
+ return pipeline;
2436
+ }
2437
+ });
2438
+ (0, import_log8.log)("waiting for data pipeline to reach target timeframe", {}, {
2439
+ file: "data-space.ts",
2440
+ line: 220,
2441
+ scope: this,
2442
+ callSite: (f, a) => f(...a)
2443
+ });
2444
+ await this._dataPipeline.pipelineState.waitUntilReachedTargetTimeframe({
2445
+ ctx: this._ctx,
2446
+ breakOnStall: false
2447
+ });
2448
+ (0, import_log8.log)("data pipeline ready", {}, {
2449
+ file: "data-space.ts",
2450
+ line: 227,
2451
+ scope: this,
2452
+ callSite: (f, a) => f(...a)
2453
+ });
2454
+ await ((_b = (_a = this._callbacks).beforeReady) == null ? void 0 : _b.call(_a));
2455
+ this._state = import_client3.SpaceState.READY;
2456
+ this.stateUpdate.emit();
2457
+ await ((_d = (_c = this._callbacks).afterReady) == null ? void 0 : _d.call(_c));
2364
2458
  }
2365
2459
  async _createWritableFeeds() {
2366
2460
  const credentials = [];
@@ -2397,7 +2491,11 @@ var DataSpace = class DataSpace2 {
2397
2491
  }));
2398
2492
  }
2399
2493
  if (credentials.length > 0) {
2400
- await this.notarizationPlugin.notarize(credentials);
2494
+ await this.notarizationPlugin.notarize({
2495
+ ctx: this._ctx,
2496
+ credentials,
2497
+ timeout: 0
2498
+ });
2401
2499
  }
2402
2500
  await this._metadataStore.setWritableFeedKeys(this.key, this.inner.controlFeedKey, this.inner.dataFeedKey);
2403
2501
  }
@@ -2420,7 +2518,6 @@ var __decorate2 = function(decorators, target, key, desc) {
2420
2518
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2421
2519
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2422
2520
  };
2423
- var DATA_PIPELINE_READY_TIMEOUT = 3e3;
2424
2521
  var DataSpaceManager = class DataSpaceManager2 {
2425
2522
  constructor(_spaceManager, _metadataStore, _dataServiceSubscriptions, _keyring, _signingContext, _modelFactory, _feedStore, _snapshotStore) {
2426
2523
  this._spaceManager = _spaceManager;
@@ -2434,50 +2531,51 @@ var DataSpaceManager = class DataSpaceManager2 {
2434
2531
  this._ctx = new import_context7.Context();
2435
2532
  this.updated = new import_async11.Event();
2436
2533
  this._spaces = new import_util5.ComplexMap(import_keys8.PublicKey.hash);
2534
+ this._isOpen = false;
2437
2535
  }
2438
2536
  // TODO(burdon): Remove.
2439
2537
  get spaces() {
2440
2538
  return this._spaces;
2441
2539
  }
2442
2540
  async open() {
2541
+ (0, import_log9.log)("open", {}, {
2542
+ file: "data-space-manager.ts",
2543
+ line: 80,
2544
+ scope: this,
2545
+ callSite: (f, a) => f(...a)
2546
+ });
2443
2547
  await this._metadataStore.load();
2444
- (0, import_log8.log)("metadata loaded", {
2548
+ (0, import_log9.log)("metadata loaded", {
2445
2549
  spaces: this._metadataStore.spaces.length
2446
2550
  }, {
2447
2551
  file: "data-space-manager.ts",
2448
- line: 67,
2552
+ line: 82,
2449
2553
  scope: this,
2450
2554
  callSite: (f, a) => f(...a)
2451
2555
  });
2452
2556
  for (const spaceMetadata of this._metadataStore.spaces) {
2453
- (0, import_log8.log)("load space", {
2557
+ (0, import_log9.log)("load space", {
2454
2558
  spaceMetadata
2455
2559
  }, {
2456
2560
  file: "data-space-manager.ts",
2457
- line: 70,
2561
+ line: 85,
2458
2562
  scope: this,
2459
2563
  callSite: (f, a) => f(...a)
2460
2564
  });
2461
2565
  const space = await this._constructSpace(spaceMetadata);
2462
- await space.initializeDataPipeline();
2463
- if (spaceMetadata.dataTimeframe) {
2464
- (0, import_log8.log)("waiting for latest timeframe", {
2465
- spaceMetadata
2466
- }, {
2467
- file: "data-space-manager.ts",
2468
- line: 74,
2469
- scope: this,
2470
- callSite: (f, a) => f(...a)
2471
- });
2472
- await space.dataPipelineController.pipelineState.setTargetTimeframe(spaceMetadata.dataTimeframe);
2473
- }
2474
- await space.dataPipelineController.pipelineState.waitUntilReachedTargetTimeframe({
2475
- timeout: DATA_PIPELINE_READY_TIMEOUT
2476
- });
2477
- this._dataServiceSubscriptions.registerSpace(space.key, space.dataPipelineController.databaseBackend.createDataServiceHost());
2566
+ space.initializeDataPipelineAsync();
2478
2567
  }
2568
+ this._isOpen = true;
2569
+ this.updated.emit();
2479
2570
  }
2480
2571
  async close() {
2572
+ (0, import_log9.log)("close", {}, {
2573
+ file: "data-space-manager.ts",
2574
+ line: 96,
2575
+ scope: this,
2576
+ callSite: (f, a) => f(...a)
2577
+ });
2578
+ this._isOpen = false;
2481
2579
  await this._ctx.dispose();
2482
2580
  for (const space of this._spaces.values()) {
2483
2581
  await space.close();
@@ -2487,6 +2585,7 @@ var DataSpaceManager = class DataSpaceManager2 {
2487
2585
  * Creates a new space writing the genesis credentials to the control feed.
2488
2586
  */
2489
2587
  async createSpace() {
2588
+ (0, import_node_assert9.default)(this._isOpen, "Not open.");
2490
2589
  const spaceKey = await this._keyring.createKey();
2491
2590
  const controlFeedKey = await this._keyring.createKey();
2492
2591
  const dataFeedKey = await this._keyring.createKey();
@@ -2496,11 +2595,11 @@ var DataSpaceManager = class DataSpaceManager2 {
2496
2595
  controlFeedKey,
2497
2596
  dataFeedKey
2498
2597
  };
2499
- (0, import_log8.log)("creating space...", {
2598
+ (0, import_log9.log)("creating space...", {
2500
2599
  spaceKey
2501
2600
  }, {
2502
2601
  file: "data-space-manager.ts",
2503
- line: 110,
2602
+ line: 120,
2504
2603
  scope: this,
2505
2604
  callSite: (f, a) => f(...a)
2506
2605
  });
@@ -2511,25 +2610,53 @@ var DataSpaceManager = class DataSpaceManager2 {
2511
2610
  (0, import_node_assert9.default)((0, import_credentials10.getCredentialAssertion)(memberCredential)["@type"] === "dxos.halo.credentials.SpaceMember");
2512
2611
  await this._signingContext.recordCredential(memberCredential);
2513
2612
  await space.initializeDataPipeline();
2514
- this._dataServiceSubscriptions.registerSpace(space.key, space.dataPipelineController.databaseBackend.createDataServiceHost());
2515
2613
  this.updated.emit();
2516
2614
  return space;
2517
2615
  }
2518
2616
  // TODO(burdon): Rename join space.
2519
2617
  async acceptSpace(opts) {
2618
+ (0, import_log9.log)("accept space", {
2619
+ opts
2620
+ }, {
2621
+ file: "data-space-manager.ts",
2622
+ line: 139,
2623
+ scope: this,
2624
+ callSite: (f, a) => f(...a)
2625
+ });
2626
+ (0, import_node_assert9.default)(this._isOpen, "Not open.");
2520
2627
  (0, import_node_assert9.default)(!this._spaces.has(opts.spaceKey), "Space already exists.");
2521
2628
  const metadata = {
2522
2629
  key: opts.spaceKey,
2523
- genesisFeedKey: opts.genesisFeedKey
2630
+ genesisFeedKey: opts.genesisFeedKey,
2631
+ controlTimeframe: opts.controlTimeframe,
2632
+ dataTimeframe: opts.dataTimeframe
2524
2633
  };
2525
2634
  const space = await this._constructSpace(metadata);
2526
2635
  await this._metadataStore.addSpace(metadata);
2527
- await space.initializeDataPipeline();
2528
- this._dataServiceSubscriptions.registerSpace(space.key, space.dataPipelineController.databaseBackend.createDataServiceHost());
2636
+ space.initializeDataPipelineAsync();
2529
2637
  this.updated.emit();
2530
2638
  return space;
2531
2639
  }
2640
+ /**
2641
+ * Wait until the space data pipeline is fully initialized.
2642
+ * Used by invitation handler.
2643
+ * TODO(dmaretskyi): Consider removing.
2644
+ */
2645
+ async waitUntilSpaceReady(spaceKey) {
2646
+ await (0, import_context7.cancelWithContext)(this._ctx, this.updated.waitForCondition(() => {
2647
+ const space = this._spaces.get(spaceKey);
2648
+ return !!space && space.state === import_client4.SpaceState.READY;
2649
+ }));
2650
+ }
2532
2651
  async _constructSpace(metadata) {
2652
+ (0, import_log9.log)("construct space", {
2653
+ metadata
2654
+ }, {
2655
+ file: "data-space-manager.ts",
2656
+ line: 175,
2657
+ scope: this,
2658
+ callSite: (f, a) => f(...a)
2659
+ });
2533
2660
  const gossip = new import_teleport_extension_gossip.Gossip({
2534
2661
  localPeerId: this._signingContext.deviceKey
2535
2662
  });
@@ -2574,9 +2701,42 @@ var DataSpaceManager = class DataSpaceManager2 {
2574
2701
  keyring: this._keyring,
2575
2702
  feedStore: this._feedStore,
2576
2703
  signingContext: this._signingContext,
2577
- snapshotId: metadata.snapshot
2704
+ snapshotId: metadata.snapshot,
2705
+ callbacks: {
2706
+ beforeReady: async () => {
2707
+ (0, import_log9.log)("before space ready", {
2708
+ space: space.key
2709
+ }, {
2710
+ file: "data-space-manager.ts",
2711
+ line: 224,
2712
+ scope: this,
2713
+ callSite: (f, a) => f(...a)
2714
+ });
2715
+ this._dataServiceSubscriptions.registerSpace(space.key, dataSpace.dataPipeline.databaseBackend.createDataServiceHost());
2716
+ },
2717
+ afterReady: async () => {
2718
+ (0, import_log9.log)("after space ready", {
2719
+ space: space.key,
2720
+ open: this._isOpen
2721
+ }, {
2722
+ file: "data-space-manager.ts",
2723
+ line: 231,
2724
+ scope: this,
2725
+ callSite: (f, a) => f(...a)
2726
+ });
2727
+ if (this._isOpen) {
2728
+ this.updated.emit();
2729
+ }
2730
+ }
2731
+ }
2578
2732
  });
2579
2733
  await dataSpace.open();
2734
+ if (metadata.controlTimeframe) {
2735
+ dataSpace.inner.controlPipeline.state.setTargetTimeframe(metadata.controlTimeframe);
2736
+ }
2737
+ if (metadata.dataTimeframe) {
2738
+ dataSpace.dataPipeline.setTargetTimeframe(metadata.dataTimeframe);
2739
+ }
2580
2740
  this._spaces.set(metadata.key, dataSpace);
2581
2741
  return dataSpace;
2582
2742
  }
@@ -2602,9 +2762,10 @@ var import_async12 = require("@dxos/async");
2602
2762
  var import_codec_protobuf10 = require("@dxos/codec-protobuf");
2603
2763
  var import_debug4 = require("@dxos/debug");
2604
2764
  var import_echo_pipeline3 = require("@dxos/echo-pipeline");
2605
- var import_log9 = require("@dxos/log");
2765
+ var import_log10 = require("@dxos/log");
2606
2766
  var import_services5 = require("@dxos/protocols/proto/dxos/client/services");
2607
2767
  var import_util6 = require("@dxos/util");
2768
+ var TIMEFRAME_UPDATE_DEBOUNCE_TIME = 500;
2608
2769
  var SpacesServiceImpl = class {
2609
2770
  constructor(_identityManager, _spaceManager, _dataServiceSubscriptions, _getDataSpaceManager) {
2610
2771
  this._identityManager = _identityManager;
@@ -2627,12 +2788,12 @@ var SpacesServiceImpl = class {
2627
2788
  return new import_codec_protobuf10.Stream(({ next, ctx }) => {
2628
2789
  const onUpdate = async () => {
2629
2790
  const dataSpaceManager = await this._getDataSpaceManager();
2630
- const spaces = Array.from(dataSpaceManager.spaces.values()).filter((space) => this._dataServiceSubscriptions.getDataService(space.key)).map((space) => this._transformSpace(space));
2631
- (0, import_log9.log)("update", {
2791
+ const spaces = Array.from(dataSpaceManager.spaces.values()).map((space) => this._transformSpace(space));
2792
+ (0, import_log10.log)("update", {
2632
2793
  spaces
2633
2794
  }, {
2634
2795
  file: "spaces-service.ts",
2635
- line: 62,
2796
+ line: 60,
2636
2797
  scope: this,
2637
2798
  callSite: (f, a) => f(...a)
2638
2799
  });
@@ -2640,28 +2801,27 @@ var SpacesServiceImpl = class {
2640
2801
  spaces
2641
2802
  });
2642
2803
  };
2643
- setTimeout(async () => {
2804
+ (0, import_async12.scheduleTask)(ctx, async () => {
2644
2805
  const dataSpaceManager = await this._getDataSpaceManager();
2645
2806
  const subscriptions = new import_async12.EventSubscriptions();
2807
+ ctx.onDispose(() => subscriptions.clear());
2646
2808
  const subscribeSpaces = () => {
2647
2809
  subscriptions.clear();
2648
2810
  for (const space of dataSpaceManager.spaces.values()) {
2649
- if (!this._dataServiceSubscriptions.getDataService(space.key)) {
2650
- continue;
2651
- }
2652
2811
  subscriptions.add(space.stateUpdate.on(ctx, onUpdate));
2653
2812
  subscriptions.add(space.presence.updated.on(ctx, onUpdate));
2813
+ space.inner.controlPipeline.state.timeframeUpdate.debounce(TIMEFRAME_UPDATE_DEBOUNCE_TIME).on(ctx, onUpdate);
2814
+ if (space.dataPipeline.pipelineState) {
2815
+ subscriptions.add(space.dataPipeline.pipelineState.timeframeUpdate.debounce(TIMEFRAME_UPDATE_DEBOUNCE_TIME).on(ctx, onUpdate));
2816
+ }
2654
2817
  }
2655
2818
  };
2656
2819
  dataSpaceManager.updated.on(ctx, () => {
2657
2820
  subscribeSpaces();
2658
2821
  void onUpdate();
2659
2822
  });
2660
- ctx.onDispose(() => subscriptions.clear());
2661
- (0, import_async12.scheduleTask)(ctx, () => {
2662
- subscribeSpaces();
2663
- void onUpdate();
2664
- });
2823
+ subscribeSpaces();
2824
+ void onUpdate();
2665
2825
  });
2666
2826
  if (!this._identityManager.identity) {
2667
2827
  next({
@@ -2714,16 +2874,23 @@ var SpacesServiceImpl = class {
2714
2874
  }
2715
2875
  }
2716
2876
  _transformSpace(space) {
2877
+ var _a, _b;
2717
2878
  return {
2718
2879
  spaceKey: space.key,
2719
- status: space.isOpen ? import_services5.SpaceStatus.ACTIVE : import_services5.SpaceStatus.INACTIVE,
2880
+ state: space.state,
2881
+ pipeline: {
2882
+ targetControlTimeframe: space.inner.controlPipeline.state.targetTimeframe,
2883
+ currentControlTimeframe: space.inner.controlPipeline.state.timeframe,
2884
+ currentDataTimeframe: (_a = space.dataPipeline.pipelineState) == null ? void 0 : _a.timeframe,
2885
+ targetDataTimeframe: (_b = space.dataPipeline.pipelineState) == null ? void 0 : _b.targetTimeframe
2886
+ },
2720
2887
  members: Array.from(space.inner.spaceState.members.values()).map((member) => {
2721
- var _a, _b, _c;
2888
+ var _a2, _b2, _c;
2722
2889
  return {
2723
2890
  identity: {
2724
2891
  identityKey: member.key,
2725
2892
  profile: {
2726
- displayName: (_b = (_a = member.assertion.profile) == null ? void 0 : _a.displayName) != null ? _b : (0, import_util6.humanize)(member.key)
2893
+ displayName: (_b2 = (_a2 = member.assertion.profile) == null ? void 0 : _a2.displayName) != null ? _b2 : (0, import_util6.humanize)(member.key)
2727
2894
  }
2728
2895
  },
2729
2896
  presence: ((_c = this._identityManager.identity) == null ? void 0 : _c.identityKey.equals(member.key)) || space.presence.getPeersOnline().filter(({ identityKey }) => identityKey.equals(member.key)).length > 0 ? import_services5.SpaceMember.PresenceState.ONLINE : import_services5.SpaceMember.PresenceState.OFFLINE
@@ -2735,23 +2902,23 @@ var SpacesServiceImpl = class {
2735
2902
  var getChannelId = (channel) => `user-channel/${channel}`;
2736
2903
 
2737
2904
  // packages/sdk/client-services/src/packlets/storage/storage.ts
2738
- var import_errors = require("@dxos/errors");
2905
+ var import_errors2 = require("@dxos/errors");
2739
2906
  var import_config = require("@dxos/protocols/proto/dxos/config");
2740
2907
  var import_random_access_storage = require("@dxos/random-access-storage");
2741
2908
  var StorageDriver = import_config.Runtime.Client.Storage.StorageDriver;
2742
2909
  var createStorageObjects = (config) => {
2743
2910
  const { path = "dxos/storage", storageType, keyStorage, persistent = false } = config != null ? config : {};
2744
2911
  if (persistent && storageType === StorageDriver.RAM) {
2745
- throw new import_errors.InvalidConfigError("RAM storage cannot be used in persistent mode.");
2912
+ throw new import_errors2.InvalidConfigError("RAM storage cannot be used in persistent mode.");
2746
2913
  }
2747
2914
  if (!persistent && storageType !== void 0 && storageType !== StorageDriver.RAM) {
2748
- throw new import_errors.InvalidConfigError("Cannot use a persistent storage in not persistent mode.");
2915
+ throw new import_errors2.InvalidConfigError("Cannot use a persistent storage in not persistent mode.");
2749
2916
  }
2750
2917
  if (persistent && keyStorage === StorageDriver.RAM) {
2751
- throw new import_errors.InvalidConfigError("RAM key storage cannot be used in persistent mode.");
2918
+ throw new import_errors2.InvalidConfigError("RAM key storage cannot be used in persistent mode.");
2752
2919
  }
2753
2920
  if (!persistent && keyStorage !== StorageDriver.RAM && keyStorage !== void 0) {
2754
- throw new import_errors.InvalidConfigError("Cannot use a persistent key storage in not persistent mode.");
2921
+ throw new import_errors2.InvalidConfigError("Cannot use a persistent key storage in not persistent mode.");
2755
2922
  }
2756
2923
  return {
2757
2924
  storage: (0, import_random_access_storage.createStorage)({
@@ -2819,7 +2986,7 @@ var SystemServiceImpl = class {
2819
2986
 
2820
2987
  // packages/sdk/client-services/src/packlets/vault/iframe-host-runtime.ts
2821
2988
  var import_async14 = require("@dxos/async");
2822
- var import_log10 = require("@dxos/log");
2989
+ var import_log11 = require("@dxos/log");
2823
2990
  var import_messaging = require("@dxos/messaging");
2824
2991
  var import_network_manager3 = require("@dxos/network-manager");
2825
2992
  var import_util7 = require("@dxos/util");
@@ -2880,7 +3047,7 @@ var ClientRpcServer = class {
2880
3047
  // packages/sdk/client-services/src/packlets/vault/shell-runtime.ts
2881
3048
  var import_node_assert10 = __toESM(require("node:assert"));
2882
3049
  var import_async13 = require("@dxos/async");
2883
- var import_client3 = require("@dxos/client");
3050
+ var import_client5 = require("@dxos/client");
2884
3051
  var import_iframe = require("@dxos/protocols/proto/dxos/iframe");
2885
3052
  var import_rpc2 = require("@dxos/rpc");
2886
3053
  var ShellRuntimeImpl = class {
@@ -2913,8 +3080,8 @@ var ShellRuntimeImpl = class {
2913
3080
  }
2914
3081
  async open() {
2915
3082
  this._appRpc = (0, import_rpc2.createProtoRpcPeer)({
2916
- requested: import_client3.appServiceBundle,
2917
- exposed: import_client3.shellServiceBundle,
3083
+ requested: import_client5.appServiceBundle,
3084
+ exposed: import_client5.shellServiceBundle,
2918
3085
  handlers: {
2919
3086
  ShellService: {
2920
3087
  setLayout: async (request) => {
@@ -2997,7 +3164,7 @@ var IFrameHostRuntime = class {
2997
3164
  }
2998
3165
  async start() {
2999
3166
  var _a;
3000
- (0, import_log10.log)("starting...", {}, {
3167
+ (0, import_log11.log)("starting...", {}, {
3001
3168
  file: "iframe-host-runtime.ts",
3002
3169
  line: 67,
3003
3170
  scope: this,
@@ -3048,7 +3215,7 @@ var IFrameHostRuntime = class {
3048
3215
  (_a = this._shellRuntime) == null ? void 0 : _a.open()
3049
3216
  ]);
3050
3217
  this._ready.wake(void 0);
3051
- (0, import_log10.log)("started", {}, {
3218
+ (0, import_log11.log)("started", {}, {
3052
3219
  file: "iframe-host-runtime.ts",
3053
3220
  line: 110,
3054
3221
  scope: this,
@@ -3056,7 +3223,7 @@ var IFrameHostRuntime = class {
3056
3223
  });
3057
3224
  } catch (err) {
3058
3225
  this._ready.wake(err);
3059
- import_log10.log.catch(err, {}, {
3226
+ import_log11.log.catch(err, {}, {
3060
3227
  file: "iframe-host-runtime.ts",
3061
3228
  line: 113,
3062
3229
  scope: this,
@@ -3066,7 +3233,7 @@ var IFrameHostRuntime = class {
3066
3233
  }
3067
3234
  async stop() {
3068
3235
  var _a;
3069
- (0, import_log10.log)("stopping...", {}, {
3236
+ (0, import_log11.log)("stopping...", {}, {
3070
3237
  file: "iframe-host-runtime.ts",
3071
3238
  line: 118,
3072
3239
  scope: this,
@@ -3075,7 +3242,7 @@ var IFrameHostRuntime = class {
3075
3242
  await this._clientRpc.close();
3076
3243
  await this._clientServices.close();
3077
3244
  await ((_a = this._shellRuntime) == null ? void 0 : _a.close());
3078
- (0, import_log10.log)("stopped", {}, {
3245
+ (0, import_log11.log)("stopped", {}, {
3079
3246
  file: "iframe-host-runtime.ts",
3080
3247
  line: 122,
3081
3248
  scope: this,
@@ -3084,11 +3251,11 @@ var IFrameHostRuntime = class {
3084
3251
  }
3085
3252
  };
3086
3253
  __decorate3([
3087
- import_log10.logInfo
3254
+ import_log11.logInfo
3088
3255
  ], IFrameHostRuntime.prototype, "origin", void 0);
3089
3256
 
3090
3257
  // packages/sdk/client-services/src/packlets/vault/iframe-proxy-runtime.ts
3091
- var import_client4 = require("@dxos/client");
3258
+ var import_client6 = require("@dxos/client");
3092
3259
  var import_network_manager4 = require("@dxos/network-manager");
3093
3260
  var import_rpc3 = require("@dxos/rpc");
3094
3261
  var IFrameProxyRuntime = class {
@@ -3099,8 +3266,8 @@ var IFrameProxyRuntime = class {
3099
3266
  this._workerAppPort = workerAppPort;
3100
3267
  this._shellPort = shellPort;
3101
3268
  this._systemRpc = (0, import_rpc3.createProtoRpcPeer)({
3102
- requested: import_client4.workerServiceBundle,
3103
- exposed: import_client4.iframeServiceBundle,
3269
+ requested: import_client6.workerServiceBundle,
3270
+ exposed: import_client6.iframeServiceBundle,
3104
3271
  handlers: {
3105
3272
  BridgeService: this._transportService,
3106
3273
  IframeService: {
@@ -3138,7 +3305,17 @@ var IFrameProxyRuntime = class {
3138
3305
 
3139
3306
  // packages/sdk/client-services/src/packlets/vault/vault-resource-lock.ts
3140
3307
  var import_async15 = require("@dxos/async");
3141
- var import_log11 = require("@dxos/log");
3308
+ var import_log12 = require("@dxos/log");
3309
+ var __decorate4 = function(decorators, target, key, desc) {
3310
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3311
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
3312
+ r = Reflect.decorate(decorators, target, key, desc);
3313
+ else
3314
+ for (var i = decorators.length - 1; i >= 0; i--)
3315
+ if (d = decorators[i])
3316
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3317
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
3318
+ };
3142
3319
  var Message;
3143
3320
  (function(Message2) {
3144
3321
  Message2["ACQUIRING"] = "acquiring";
@@ -3152,14 +3329,41 @@ var VaultResourceLock = class {
3152
3329
  this._onRelease = onRelease;
3153
3330
  this._broadcastChannel.onmessage = this._onMessage.bind(this);
3154
3331
  }
3332
+ get lockKey() {
3333
+ return this._lockKey;
3334
+ }
3155
3335
  async acquire() {
3156
3336
  this._broadcastChannel.postMessage({
3157
3337
  message: Message.ACQUIRING
3158
3338
  });
3159
3339
  try {
3340
+ (0, import_log12.log)("aquiring lock...", {}, {
3341
+ file: "vault-resource-lock.ts",
3342
+ line: 44,
3343
+ scope: this,
3344
+ callSite: (f, a) => f(...a)
3345
+ });
3160
3346
  await (0, import_async15.asyncTimeout)(this._requestLock(), 3e3);
3347
+ (0, import_log12.log)("acquired lock", {}, {
3348
+ file: "vault-resource-lock.ts",
3349
+ line: 46,
3350
+ scope: this,
3351
+ callSite: (f, a) => f(...a)
3352
+ });
3161
3353
  } catch (e) {
3354
+ (0, import_log12.log)("stealing lock...", {}, {
3355
+ file: "vault-resource-lock.ts",
3356
+ line: 48,
3357
+ scope: this,
3358
+ callSite: (f, a) => f(...a)
3359
+ });
3162
3360
  await this._requestLock(true);
3361
+ (0, import_log12.log)("stolen lock", {}, {
3362
+ file: "vault-resource-lock.ts",
3363
+ line: 50,
3364
+ scope: this,
3365
+ callSite: (f, a) => f(...a)
3366
+ });
3163
3367
  }
3164
3368
  }
3165
3369
  async release() {
@@ -3171,11 +3375,11 @@ var VaultResourceLock = class {
3171
3375
  }
3172
3376
  }
3173
3377
  async _requestLock(steal = false) {
3174
- (0, import_log11.log)("requesting lock...", {
3378
+ (0, import_log12.log)("requesting lock...", {
3175
3379
  steal
3176
3380
  }, {
3177
3381
  file: "vault-resource-lock.ts",
3178
- line: 56,
3382
+ line: 65,
3179
3383
  scope: this,
3180
3384
  callSite: (f, a) => f(...a)
3181
3385
  });
@@ -3188,16 +3392,16 @@ var VaultResourceLock = class {
3188
3392
  acquired.wake();
3189
3393
  this._releaseTrigger = new import_async15.Trigger();
3190
3394
  await this._releaseTrigger.wait();
3191
- (0, import_log11.log)("releasing lock...", {}, {
3395
+ (0, import_log12.log)("releasing lock...", {}, {
3192
3396
  file: "vault-resource-lock.ts",
3193
- line: 65,
3397
+ line: 74,
3194
3398
  scope: this,
3195
3399
  callSite: (f, a) => f(...a)
3196
3400
  });
3197
3401
  await ((_b = this._onRelease) == null ? void 0 : _b.call(this));
3198
- (0, import_log11.log)("released lock", {}, {
3402
+ (0, import_log12.log)("released lock", {}, {
3199
3403
  file: "vault-resource-lock.ts",
3200
- line: 67,
3404
+ line: 76,
3201
3405
  scope: this,
3202
3406
  callSite: (f, a) => f(...a)
3203
3407
  });
@@ -3206,31 +3410,34 @@ var VaultResourceLock = class {
3206
3410
  await ((_a = this._onRelease) == null ? void 0 : _a.call(this));
3207
3411
  });
3208
3412
  await acquired.wait();
3209
- (0, import_log11.log)("recieved lock", {
3413
+ (0, import_log12.log)("recieved lock", {
3210
3414
  steal
3211
3415
  }, {
3212
3416
  file: "vault-resource-lock.ts",
3213
- line: 74,
3417
+ line: 83,
3214
3418
  scope: this,
3215
3419
  callSite: (f, a) => f(...a)
3216
3420
  });
3217
3421
  }
3218
3422
  };
3423
+ __decorate4([
3424
+ import_log12.logInfo
3425
+ ], VaultResourceLock.prototype, "lockKey", null);
3219
3426
 
3220
3427
  // packages/sdk/client-services/src/packlets/vault/worker-runtime.ts
3221
3428
  var import_async17 = require("@dxos/async");
3222
- var import_log13 = require("@dxos/log");
3429
+ var import_log14 = require("@dxos/log");
3223
3430
  var import_messaging2 = require("@dxos/messaging");
3224
3431
  var import_network_manager5 = require("@dxos/network-manager");
3225
3432
 
3226
3433
  // packages/sdk/client-services/src/packlets/vault/worker-session.ts
3227
3434
  var import_node_assert11 = __toESM(require("node:assert"));
3228
3435
  var import_async16 = require("@dxos/async");
3229
- var import_client5 = require("@dxos/client");
3230
- var import_log12 = require("@dxos/log");
3436
+ var import_client7 = require("@dxos/client");
3437
+ var import_log13 = require("@dxos/log");
3231
3438
  var import_rpc4 = require("@dxos/rpc");
3232
3439
  var import_util8 = require("@dxos/util");
3233
- var __decorate4 = function(decorators, target, key, desc) {
3440
+ var __decorate5 = function(decorators, target, key, desc) {
3234
3441
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3235
3442
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
3236
3443
  r = Reflect.decorate(decorators, target, key, desc);
@@ -3281,8 +3488,8 @@ var WorkerSession = class {
3281
3488
  ...middleware
3282
3489
  });
3283
3490
  this._iframeRpc = (0, import_rpc4.createProtoRpcPeer)({
3284
- requested: import_client5.iframeServiceBundle,
3285
- exposed: import_client5.workerServiceBundle,
3491
+ requested: import_client7.iframeServiceBundle,
3492
+ exposed: import_client7.workerServiceBundle,
3286
3493
  handlers: {
3287
3494
  WorkerService: {
3288
3495
  start: async (request) => {
@@ -3294,7 +3501,7 @@ var WorkerSession = class {
3294
3501
  try {
3295
3502
  await this.close();
3296
3503
  } catch (err) {
3297
- import_log12.log.catch(err, {}, {
3504
+ import_log13.log.catch(err, {}, {
3298
3505
  file: "worker-session.ts",
3299
3506
  line: 107,
3300
3507
  scope: this,
@@ -3312,7 +3519,7 @@ var WorkerSession = class {
3312
3519
  this.bridgeService = this._iframeRpc.rpc.BridgeService;
3313
3520
  }
3314
3521
  async open() {
3315
- import_log12.log.info("opening..", {}, {
3522
+ import_log13.log.info("opening..", {}, {
3316
3523
  file: "worker-session.ts",
3317
3524
  line: 121,
3318
3525
  scope: this,
@@ -3330,7 +3537,7 @@ var WorkerSession = class {
3330
3537
  try {
3331
3538
  await this._iframeRpc.rpc.IframeService.heartbeat();
3332
3539
  } catch (err1) {
3333
- import_log12.log.warn("Heartbeat failed", {
3540
+ import_log13.log.warn("Heartbeat failed", {
3334
3541
  err: err1
3335
3542
  }, {
3336
3543
  file: "worker-session.ts",
@@ -3341,7 +3548,7 @@ var WorkerSession = class {
3341
3548
  try {
3342
3549
  await this.close();
3343
3550
  } catch (err) {
3344
- import_log12.log.catch(err, {}, {
3551
+ import_log13.log.catch(err, {}, {
3345
3552
  file: "worker-session.ts",
3346
3553
  line: 137,
3347
3554
  scope: this,
@@ -3352,7 +3559,7 @@ var WorkerSession = class {
3352
3559
  }, this._options.heartbeatInterval);
3353
3560
  }
3354
3561
  async close() {
3355
- import_log12.log.info("closing..", {}, {
3562
+ import_log13.log.info("closing..", {}, {
3356
3563
  file: "worker-session.ts",
3357
3564
  line: 144,
3358
3565
  scope: this,
@@ -3361,7 +3568,7 @@ var WorkerSession = class {
3361
3568
  try {
3362
3569
  await this.onClose.callIfSet();
3363
3570
  } catch (err) {
3364
- import_log12.log.catch(err, {}, {
3571
+ import_log13.log.catch(err, {}, {
3365
3572
  file: "worker-session.ts",
3366
3573
  line: 148,
3367
3574
  scope: this,
@@ -3380,7 +3587,7 @@ var WorkerSession = class {
3380
3587
  try {
3381
3588
  await (0, import_async16.asyncTimeout)(this._shellClientRpc.open(), 1e3);
3382
3589
  } catch (e) {
3383
- import_log12.log.info("No shell connected.", {}, {
3590
+ import_log13.log.info("No shell connected.", {}, {
3384
3591
  file: "worker-session.ts",
3385
3592
  line: 162,
3386
3593
  scope: this,
@@ -3389,8 +3596,8 @@ var WorkerSession = class {
3389
3596
  }
3390
3597
  }
3391
3598
  };
3392
- __decorate4([
3393
- import_log12.logInfo
3599
+ __decorate5([
3600
+ import_log13.logInfo
3394
3601
  ], WorkerSession.prototype, "origin", void 0);
3395
3602
 
3396
3603
  // packages/sdk/client-services/src/packlets/vault/worker-runtime.ts
@@ -3404,7 +3611,7 @@ var WorkerRuntime = class {
3404
3611
  this._clientServices = new ClientServicesHost();
3405
3612
  }
3406
3613
  async start() {
3407
- (0, import_log13.log)("starting...", {}, {
3614
+ (0, import_log14.log)("starting...", {}, {
3408
3615
  file: "worker-runtime.ts",
3409
3616
  line: 44,
3410
3617
  scope: this,
@@ -3425,7 +3632,7 @@ var WorkerRuntime = class {
3425
3632
  });
3426
3633
  await this._clientServices.open();
3427
3634
  this._ready.wake(void 0);
3428
- (0, import_log13.log)("started", {}, {
3635
+ (0, import_log14.log)("started", {}, {
3429
3636
  file: "worker-runtime.ts",
3430
3637
  line: 61,
3431
3638
  scope: this,
@@ -3433,7 +3640,7 @@ var WorkerRuntime = class {
3433
3640
  });
3434
3641
  } catch (err) {
3435
3642
  this._ready.wake(err);
3436
- import_log13.log.catch(err, {}, {
3643
+ import_log14.log.catch(err, {}, {
3437
3644
  file: "worker-runtime.ts",
3438
3645
  line: 64,
3439
3646
  scope: this,
@@ -3491,7 +3698,7 @@ var import_debug6 = require("@dxos/debug");
3491
3698
  var import_echo_pipeline4 = require("@dxos/echo-pipeline");
3492
3699
  var import_feed_store4 = require("@dxos/feed-store");
3493
3700
  var import_keyring = require("@dxos/keyring");
3494
- var import_log14 = require("@dxos/log");
3701
+ var import_log15 = require("@dxos/log");
3495
3702
  var ServiceContext = class {
3496
3703
  // prettier-ignore
3497
3704
  constructor(storage, networkManager, modelFactory) {
@@ -3528,7 +3735,7 @@ var ServiceContext = class {
3528
3735
  });
3529
3736
  }
3530
3737
  async open() {
3531
- (0, import_log14.log)("opening...", {}, {
3738
+ (0, import_log15.log)("opening...", {}, {
3532
3739
  file: "service-context.ts",
3533
3740
  line: 94,
3534
3741
  scope: this,
@@ -3540,7 +3747,7 @@ var ServiceContext = class {
3540
3747
  if (this.identityManager.identity) {
3541
3748
  await this._initialize();
3542
3749
  }
3543
- (0, import_log14.log)("opened", {}, {
3750
+ (0, import_log15.log)("opened", {}, {
3544
3751
  file: "service-context.ts",
3545
3752
  line: 101,
3546
3753
  scope: this,
@@ -3549,7 +3756,7 @@ var ServiceContext = class {
3549
3756
  }
3550
3757
  async close() {
3551
3758
  var _a, _b;
3552
- (0, import_log14.log)("closing...", {}, {
3759
+ (0, import_log15.log)("closing...", {}, {
3553
3760
  file: "service-context.ts",
3554
3761
  line: 105,
3555
3762
  scope: this,
@@ -3562,7 +3769,7 @@ var ServiceContext = class {
3562
3769
  await this.feedStore.close();
3563
3770
  await this.networkManager.close();
3564
3771
  this.dataServiceSubscriptions.clear();
3565
- (0, import_log14.log)("closed", {}, {
3772
+ (0, import_log15.log)("closed", {}, {
3566
3773
  file: "service-context.ts",
3567
3774
  line: 113,
3568
3775
  scope: this,
@@ -3570,7 +3777,7 @@ var ServiceContext = class {
3570
3777
  });
3571
3778
  }
3572
3779
  async reset() {
3573
- (0, import_log14.log)("resetting...", {}, {
3780
+ (0, import_log15.log)("resetting...", {}, {
3574
3781
  file: "service-context.ts",
3575
3782
  line: 117,
3576
3783
  scope: this,
@@ -3578,7 +3785,7 @@ var ServiceContext = class {
3578
3785
  });
3579
3786
  await this.close();
3580
3787
  await this.storage.reset();
3581
- (0, import_log14.log)("reset", {}, {
3788
+ (0, import_log15.log)("reset", {}, {
3582
3789
  file: "service-context.ts",
3583
3790
  line: 120,
3584
3791
  scope: this,
@@ -3598,7 +3805,7 @@ var ServiceContext = class {
3598
3805
  // Called when identity is created.
3599
3806
  async _initialize() {
3600
3807
  var _a;
3601
- (0, import_log14.log)("initializing spaces...", {}, {
3808
+ (0, import_log15.log)("initializing spaces...", {}, {
3602
3809
  file: "service-context.ts",
3603
3810
  line: 139,
3604
3811
  scope: this,
@@ -3632,7 +3839,7 @@ var ServiceContext = class {
3632
3839
  return;
3633
3840
  }
3634
3841
  if (!this.dataSpaceManager) {
3635
- (0, import_log14.log)("dataSpaceManager not initialized yet, ignoring space admission", {
3842
+ (0, import_log15.log)("dataSpaceManager not initialized yet, ignoring space admission", {
3636
3843
  details: assertion
3637
3844
  }, {
3638
3845
  file: "service-context.ts",
@@ -3643,7 +3850,7 @@ var ServiceContext = class {
3643
3850
  return;
3644
3851
  }
3645
3852
  if (this.dataSpaceManager.spaces.has(assertion.spaceKey)) {
3646
- (0, import_log14.log)("space already exists, ignoring space admission", {
3853
+ (0, import_log15.log)("space already exists, ignoring space admission", {
3647
3854
  details: assertion
3648
3855
  }, {
3649
3856
  file: "service-context.ts",
@@ -3654,7 +3861,7 @@ var ServiceContext = class {
3654
3861
  return;
3655
3862
  }
3656
3863
  try {
3657
- (0, import_log14.log)("accepting space recorded in halo", {
3864
+ (0, import_log15.log)("accepting space recorded in halo", {
3658
3865
  details: assertion
3659
3866
  }, {
3660
3867
  file: "service-context.ts",
@@ -3667,7 +3874,7 @@ var ServiceContext = class {
3667
3874
  genesisFeedKey: assertion.genesisFeedKey
3668
3875
  });
3669
3876
  } catch (err) {
3670
- import_log14.log.catch(err, {}, {
3877
+ import_log15.log.catch(err, {}, {
3671
3878
  file: "service-context.ts",
3672
3879
  line: 197,
3673
3880
  scope: this,
@@ -3708,7 +3915,7 @@ var ServiceRegistry = class {
3708
3915
  var ClientServicesHost = class {
3709
3916
  constructor({
3710
3917
  config,
3711
- modelFactory = (0, import_client6.createDefaultModelFactory)(),
3918
+ modelFactory = (0, import_client8.createDefaultModelFactory)(),
3712
3919
  // TODO(burdon): Create ApolloLink abstraction (see Client).
3713
3920
  networkManager,
3714
3921
  storage,
@@ -3716,6 +3923,7 @@ var ClientServicesHost = class {
3716
3923
  lockKey
3717
3924
  } = {}) {
3718
3925
  this._statusUpdate = new import_async19.Event();
3926
+ this._opening = false;
3719
3927
  this._open = false;
3720
3928
  this._storage = storage;
3721
3929
  this._modelFactory = modelFactory;
@@ -3727,7 +3935,9 @@ var ClientServicesHost = class {
3727
3935
  }
3728
3936
  this._resourceLock = lockKey ? new VaultResourceLock({
3729
3937
  lockKey,
3730
- onAcquire: () => this.open(),
3938
+ onAcquire: () => {
3939
+ this._opening || this.open();
3940
+ },
3731
3941
  onRelease: () => this.close()
3732
3942
  }) : void 0;
3733
3943
  this._systemService = new SystemServiceImpl({
@@ -3747,7 +3957,7 @@ var ClientServicesHost = class {
3747
3957
  await this._serviceContext.reset();
3748
3958
  }
3749
3959
  });
3750
- this._serviceRegistry = new ServiceRegistry(import_client6.clientServiceBundle, {
3960
+ this._serviceRegistry = new ServiceRegistry(import_client8.clientServiceBundle, {
3751
3961
  SystemService: this._systemService
3752
3962
  });
3753
3963
  }
@@ -3783,20 +3993,23 @@ var ClientServicesHost = class {
3783
3993
  }
3784
3994
  }
3785
3995
  async open() {
3786
- var _a, _b;
3996
+ var _a, _b, _c;
3787
3997
  if (this._open) {
3788
3998
  return;
3789
3999
  }
3790
4000
  (0, import_node_assert12.default)(this._config, "config not set");
3791
4001
  (0, import_node_assert12.default)(this._storage, "storage not set");
3792
4002
  (0, import_node_assert12.default)(this._networkManager, "network manager not set");
3793
- (0, import_log15.log)("opening...", {}, {
4003
+ this._opening = true;
4004
+ (0, import_log16.log)("opening...", {
4005
+ lockKey: (_a = this._resourceLock) == null ? void 0 : _a.lockKey
4006
+ }, {
3794
4007
  file: "service-host.ts",
3795
- line: 166,
4008
+ line: 170,
3796
4009
  scope: this,
3797
4010
  callSite: (f, a) => f(...a)
3798
4011
  });
3799
- await ((_a = this._resourceLock) == null ? void 0 : _a.acquire());
4012
+ await ((_b = this._resourceLock) == null ? void 0 : _b.acquire());
3800
4013
  this._serviceContext = new ServiceContext(this._storage, this._networkManager, this._modelFactory);
3801
4014
  this._serviceRegistry.setServices({
3802
4015
  SystemService: this._systemService,
@@ -3825,14 +4038,15 @@ var ClientServicesHost = class {
3825
4038
  })
3826
4039
  });
3827
4040
  await this._serviceContext.open();
4041
+ this._opening = false;
3828
4042
  this._open = true;
3829
4043
  this._statusUpdate.emit();
3830
- const deviceKey = (_b = this._serviceContext.identityManager.identity) == null ? void 0 : _b.deviceKey;
3831
- (0, import_log15.log)("opened", {
4044
+ const deviceKey = (_c = this._serviceContext.identityManager.identity) == null ? void 0 : _c.deviceKey;
4045
+ (0, import_log16.log)("opened", {
3832
4046
  deviceKey
3833
4047
  }, {
3834
4048
  file: "service-host.ts",
3835
- line: 219,
4049
+ line: 224,
3836
4050
  scope: this,
3837
4051
  callSite: (f, a) => f(...a)
3838
4052
  });
@@ -3843,11 +4057,11 @@ var ClientServicesHost = class {
3843
4057
  return;
3844
4058
  }
3845
4059
  const deviceKey = (_a = this._serviceContext.identityManager.identity) == null ? void 0 : _a.deviceKey;
3846
- (0, import_log15.log)("closing...", {
4060
+ (0, import_log16.log)("closing...", {
3847
4061
  deviceKey
3848
4062
  }, {
3849
4063
  file: "service-host.ts",
3850
- line: 228,
4064
+ line: 233,
3851
4065
  scope: this,
3852
4066
  callSite: (f, a) => f(...a)
3853
4067
  });
@@ -3857,11 +4071,11 @@ var ClientServicesHost = class {
3857
4071
  await this._serviceContext.close();
3858
4072
  this._open = false;
3859
4073
  this._statusUpdate.emit();
3860
- (0, import_log15.log)("closed", {
4074
+ (0, import_log16.log)("closed", {
3861
4075
  deviceKey
3862
4076
  }, {
3863
4077
  file: "service-host.ts",
3864
- line: 233,
4078
+ line: 238,
3865
4079
  scope: this,
3866
4080
  callSite: (f, a) => f(...a)
3867
4081
  });
@@ -3892,7 +4106,7 @@ var LocalClientServices = class {
3892
4106
 
3893
4107
  // packages/sdk/client-services/src/packlets/services/utils.ts
3894
4108
  var import_config2 = require("@dxos/config");
3895
- var import_log16 = require("@dxos/log");
4109
+ var import_log17 = require("@dxos/log");
3896
4110
  var import_messaging3 = require("@dxos/messaging");
3897
4111
  var import_network_manager6 = require("@dxos/network-manager");
3898
4112
  var fromHost = (config = new import_config2.Config()) => {
@@ -3915,7 +4129,7 @@ var createNetworkManager = (config, options = {}) => {
3915
4129
  transportFactory
3916
4130
  });
3917
4131
  }
3918
- import_log16.log.warn("P2P network is not configured.", {}, {
4132
+ import_log17.log.warn("P2P network is not configured.", {}, {
3919
4133
  file: "utils.ts",
3920
4134
  line: 48,
3921
4135
  scope: void 0,