@dxos/client-services 0.1.20 → 0.1.22

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 (49) hide show
  1. package/dist/lib/browser/index.mjs +306 -129
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +333 -152
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  8. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  9. package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts.map +1 -1
  10. package/dist/types/src/packlets/network/index.d.ts +2 -0
  11. package/dist/types/src/packlets/network/index.d.ts.map +1 -0
  12. package/dist/types/src/packlets/network/network-service.d.ts +10 -0
  13. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -0
  14. package/dist/types/src/packlets/services/service-context.d.ts +2 -1
  15. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  16. package/dist/types/src/packlets/services/service-definitions.d.ts +2 -1
  17. package/dist/types/src/packlets/services/service-definitions.d.ts.map +1 -1
  18. package/dist/types/src/packlets/services/service-host.d.ts +4 -1
  19. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  20. package/dist/types/src/packlets/services/service-host.test.d.ts +2 -0
  21. package/dist/types/src/packlets/services/service-host.test.d.ts.map +1 -0
  22. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +4 -2
  23. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  24. package/dist/types/src/packlets/spaces/data-space.d.ts +13 -6
  25. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  26. package/dist/types/src/packlets/spaces/spaces-service.d.ts +6 -1
  27. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  28. package/dist/types/src/packlets/storage/storage.d.ts +0 -2
  29. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  30. package/dist/types/src/packlets/vault/worker-session.d.ts.map +1 -1
  31. package/package.json +28 -34
  32. package/src/packlets/deprecated/space.ts +1 -1
  33. package/src/packlets/devtools/spaces.ts +1 -1
  34. package/src/packlets/identity/identity-manager.ts +3 -9
  35. package/src/packlets/identity/identity.test.ts +4 -33
  36. package/src/packlets/identity/identity.ts +26 -18
  37. package/src/packlets/invitations/space-invitations-handler.test.ts +53 -1
  38. package/src/packlets/invitations/space-invitations-handler.ts +9 -5
  39. package/src/packlets/network/index.ts +5 -0
  40. package/src/packlets/network/network-service.ts +24 -0
  41. package/src/packlets/services/service-context.ts +9 -2
  42. package/src/packlets/services/service-definitions.ts +5 -1
  43. package/src/packlets/services/service-host.test.ts +31 -0
  44. package/src/packlets/services/service-host.ts +13 -9
  45. package/src/packlets/spaces/data-space-manager.ts +46 -9
  46. package/src/packlets/spaces/data-space.ts +28 -10
  47. package/src/packlets/spaces/spaces-service.ts +21 -0
  48. package/src/packlets/storage/storage.ts +4 -41
  49. package/src/packlets/vault/worker-session.ts +1 -0
@@ -41,7 +41,7 @@ var SpaceServiceImpl = class {
41
41
  identityKey: member.key,
42
42
  displayName: (_b = (_a = member.assertion.profile) == null ? void 0 : _a.displayName) != null ? _b : humanize(member.key)
43
43
  },
44
- presenceState: ((_c = this.serviceContext.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
44
+ presence: ((_c = this.serviceContext.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
45
45
  };
46
46
  })
47
47
  }));
@@ -164,11 +164,13 @@ var SystemServiceImpl = class {
164
164
  this._config = _config;
165
165
  this._serviceContext = _serviceContext;
166
166
  }
167
+ // TODO(burdon): Remove.
167
168
  async initSession() {
168
169
  }
169
170
  async getConfig(request) {
170
171
  return this._config.values;
171
172
  }
173
+ // TODO(burdon): Connect to iframe RPC heartbeat for network status?
172
174
  async getStatus(request) {
173
175
  return {
174
176
  message: `ok: ${Date.now()}`
@@ -372,7 +374,7 @@ var subscribeToSpaces = (context, { spaceKeys = [] }) => new Stream6(({ next })
372
374
  return {
373
375
  key: space.key,
374
376
  isOpen: space.isOpen,
375
- timeframe: spaceMetadata.latestTimeframe,
377
+ timeframe: spaceMetadata == null ? void 0 : spaceMetadata.latestTimeframe,
376
378
  genesisFeed: space.genesisFeedKey,
377
379
  controlFeed: space.controlFeedKey,
378
380
  dataFeed: space.dataFeedKey
@@ -574,35 +576,45 @@ var Identity = class {
574
576
  this._signer = signer;
575
577
  this.identityKey = identityKey;
576
578
  this.deviceKey = deviceKey;
577
- this._deviceStateMachine = new DeviceStateMachine(this.identityKey, this.deviceKey);
578
- this._profileStateMachine = new ProfileStateMachine(this.identityKey);
579
- this.space.onCredentialProcessed.set(async (credential) => {
580
- await this._deviceStateMachine.process(credential);
581
- await this._profileStateMachine.process(credential);
582
- this.stateUpdate.emit();
583
- });
579
+ this._deviceStateMachine = this.space.spaceState.registerProcessor(new DeviceStateMachine({
580
+ identityKey: this.identityKey,
581
+ deviceKey: this.deviceKey,
582
+ onUpdate: () => this.stateUpdate.emit()
583
+ }));
584
+ this._profileStateMachine = this.space.spaceState.registerProcessor(new ProfileStateMachine({
585
+ identityKey: this.identityKey,
586
+ onUpdate: () => this.stateUpdate.emit()
587
+ }));
584
588
  this.authVerifier = new HaloAuthVerifier({
585
589
  trustedDevicesProvider: () => this.authorizedDeviceKeys,
586
590
  update: this.stateUpdate,
587
591
  authTimeout: AUTH_TIMEOUT
588
592
  });
589
593
  }
594
+ // TODO(burdon): Expose state object?
590
595
  get authorizedDeviceKeys() {
591
- return this._deviceStateMachine.authorizedDeviceKeys;
596
+ return this._deviceStateMachine.processor.authorizedDeviceKeys;
592
597
  }
593
598
  async open() {
599
+ await this._deviceStateMachine.open();
600
+ await this._profileStateMachine.open();
594
601
  await this.space.open();
595
602
  }
596
603
  async close() {
597
604
  await this.authVerifier.close();
605
+ await this._deviceStateMachine.close();
606
+ await this._profileStateMachine.close();
598
607
  await this.space.close();
599
608
  }
600
609
  async ready() {
601
- await this._deviceStateMachine.deviceChainReady.wait();
610
+ await this._deviceStateMachine.processor.deviceChainReady.wait();
602
611
  }
603
612
  get profileDocument() {
604
- return this._profileStateMachine.profile;
613
+ return this._profileStateMachine.processor.profile;
605
614
  }
615
+ /**
616
+ * @test-only
617
+ */
606
618
  get controlPipeline() {
607
619
  return this.space.controlPipeline;
608
620
  }
@@ -619,10 +631,17 @@ var Identity = class {
619
631
  dataFeedKey: this.space.dataFeedKey
620
632
  };
621
633
  }
634
+ /**
635
+ * Issues credentials as identity.
636
+ * Requires identity to be ready.
637
+ */
622
638
  getIdentityCredentialSigner() {
623
- assert2(this._deviceStateMachine.deviceCredentialChain, "Device credential chain is not ready.");
624
- return createCredentialSignerWithChain(this._signer, this._deviceStateMachine.deviceCredentialChain, this.deviceKey);
639
+ assert2(this._deviceStateMachine.processor.deviceCredentialChain, "Device credential chain is not ready.");
640
+ return createCredentialSignerWithChain(this._signer, this._deviceStateMachine.processor.deviceCredentialChain, this.deviceKey);
625
641
  }
642
+ /**
643
+ * Issues credentials as device.
644
+ */
626
645
  getDeviceCredentialSigner() {
627
646
  return createCredentialSignerWithKey(this._signer, this.deviceKey);
628
647
  }
@@ -635,7 +654,7 @@ var Identity = class {
635
654
  dataFeedKey
636
655
  }, {
637
656
  file: "identity.ts",
638
- line: 147,
657
+ line: 155,
639
658
  scope: this,
640
659
  callSite: (f, a) => f(...a)
641
660
  });
@@ -680,12 +699,12 @@ var Identity = class {
680
699
  import assert3 from "@dxos/node-std/assert";
681
700
  import { Event as Event2 } from "@dxos/async";
682
701
  import { createCredentialSignerWithKey as createCredentialSignerWithKey2, CredentialGenerator } from "@dxos/credentials";
683
- import { NoopDataPipelineController } from "@dxos/echo-db";
684
702
  import { log as log4 } from "@dxos/log";
685
703
  import { AdmittedFeed as AdmittedFeed2 } from "@dxos/protocols/proto/dxos/halo/credentials";
686
- import { Presence } from "@dxos/teleport-extension-presence";
687
704
  import { deferFunction } from "@dxos/util";
688
705
  var IdentityManager = class {
706
+ // TODO(burdon): IdentityManagerParams.
707
+ // TODO(dmaretskyi): Perhaps this should take/generate the peerKey outside of an initialized identity.
689
708
  constructor(_metadataStore, _keyring, _spaceManager) {
690
709
  this._metadataStore = _metadataStore;
691
710
  this._keyring = _keyring;
@@ -698,6 +717,14 @@ var IdentityManager = class {
698
717
  async open() {
699
718
  await this._metadataStore.load();
700
719
  const identityRecord = this._metadataStore.getIdentityRecord();
720
+ log4("identity record", {
721
+ identityRecord
722
+ }, {
723
+ file: "identity-manager.ts",
724
+ line: 57,
725
+ scope: this,
726
+ callSite: (f, a) => f(...a)
727
+ });
701
728
  if (identityRecord) {
702
729
  this._identity = await this._constructIdentity(identityRecord);
703
730
  await this._identity.open();
@@ -733,7 +760,9 @@ var IdentityManager = class {
733
760
  {
734
761
  const generator = new CredentialGenerator(this._keyring, identityRecord.identityKey, identityRecord.deviceKey);
735
762
  const credentials = [
763
+ // Space genesis.
736
764
  ...await generator.createSpaceGenesis(identityRecord.haloSpace.spaceKey, identityRecord.haloSpace.genesisFeedKey),
765
+ // Feed admission.
737
766
  await generator.createFeedAdmission(identityRecord.haloSpace.spaceKey, identityRecord.haloSpace.writeDataFeedKey, AdmittedFeed2.Designation.DATA)
738
767
  ];
739
768
  if (displayName) {
@@ -764,6 +793,9 @@ var IdentityManager = class {
764
793
  });
765
794
  return identity;
766
795
  }
796
+ /**
797
+ * Accept an existing identity. Expects it's device key to be authorized (now or later).
798
+ */
767
799
  async acceptIdentity(params) {
768
800
  log4("accepting identity", {
769
801
  params
@@ -834,14 +866,9 @@ var IdentityManager = class {
834
866
  controlFeedKey: spaceRecord.writeControlFeedKey,
835
867
  dataFeedKey: spaceRecord.writeDataFeedKey
836
868
  },
837
- dataPipelineControllerProvider: () => new NoopDataPipelineController(),
838
869
  swarmIdentity,
839
- presence: new Presence({
840
- localPeerId: swarmIdentity.peerKey,
841
- announceInterval: 1e3,
842
- offlineTimeout: 3e4,
843
- identityKey
844
- })
870
+ onNetworkConnection: () => {
871
+ }
845
872
  });
846
873
  }
847
874
  };
@@ -890,6 +917,7 @@ var InvitationObservableProvider = class extends CancellableObservableProvider {
890
917
  }
891
918
  };
892
919
  var AuthenticatingInvitationProvider = class extends InvitationObservableProvider {
920
+ // prettier-ignore
893
921
  constructor(_actions) {
894
922
  super(() => this._actions.onCancel());
895
923
  this._actions = _actions;
@@ -916,6 +944,7 @@ var wrapObservable = async (observable) => {
916
944
 
917
945
  // packages/sdk/client-services/src/packlets/invitations/invitations-handler.ts
918
946
  var AbstractInvitationsHandler = class {
947
+ // prettier-ignore
919
948
  constructor(_networkManager) {
920
949
  this._networkManager = _networkManager;
921
950
  }
@@ -923,10 +952,14 @@ var AbstractInvitationsHandler = class {
923
952
 
924
953
  // packages/sdk/client-services/src/packlets/invitations/halo-invitations-handler.ts
925
954
  var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
955
+ // prettier-ignore
926
956
  constructor(networkManager, _identityManager) {
927
957
  super(networkManager);
928
958
  this._identityManager = _identityManager;
929
959
  }
960
+ /**
961
+ * Creates an invitation and listens for a join request from the invited (guest) peer.
962
+ */
930
963
  createInvitation(context, options) {
931
964
  var _a;
932
965
  const { type, timeout = INVITATION_TIMEOUT, swarmKey } = options != null ? options : {};
@@ -982,6 +1015,7 @@ var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
982
1015
  status: AuthenticationResponse.Status.OK
983
1016
  };
984
1017
  },
1018
+ // TODO(burdon): Not used: controlFeedKey, dataFeedKey.
985
1019
  presentAdmissionCredentials: async (credentials) => {
986
1020
  try {
987
1021
  if (invitation.type !== Invitation2.Type.INTERACTIVE_TESTING) {
@@ -1066,6 +1100,11 @@ var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
1066
1100
  });
1067
1101
  return observable;
1068
1102
  }
1103
+ /**
1104
+ * Waits for the host peer (inviter) to accept our join request.
1105
+ * The local guest peer (invitee) then sends the local halo invitation to the host,
1106
+ * which then writes the guest's credentials to the halo.
1107
+ */
1069
1108
  acceptInvitation(invitation, options) {
1070
1109
  const { timeout = INVITATION_TIMEOUT } = options != null ? options : {};
1071
1110
  const ctx = new Context2({
@@ -1079,6 +1118,7 @@ var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
1079
1118
  onCancel: async () => {
1080
1119
  await ctx.dispose();
1081
1120
  },
1121
+ // TODO(burdon): Consider retry.
1082
1122
  onAuthenticate: async (code) => {
1083
1123
  authenticated.wake(code);
1084
1124
  }
@@ -1204,6 +1244,8 @@ var HostHaloInvitationExtension = class extends RpcExtension {
1204
1244
  }
1205
1245
  async getHandlers() {
1206
1246
  return {
1247
+ // TODO(dmaretskyi): For now this is just forwarding the data to callbacks since we don't have session-specific logic.
1248
+ // Perhaps in the future we will have more complex logic here.
1207
1249
  HaloHostService: {
1208
1250
  requestAdmission: async () => {
1209
1251
  return this._callbacks.requestAdmission();
@@ -1211,6 +1253,7 @@ var HostHaloInvitationExtension = class extends RpcExtension {
1211
1253
  authenticate: async (credentials) => {
1212
1254
  return this._callbacks.authenticate(credentials);
1213
1255
  },
1256
+ // TODO(burdon): Not used: controlFeedKey, dataFeedKey.
1214
1257
  presentAdmissionCredentials: async (credentials) => {
1215
1258
  return this._callbacks.presentAdmissionCredentials(credentials);
1216
1259
  }
@@ -1246,6 +1289,7 @@ import { observableError } from "@dxos/async";
1246
1289
  import { log as log6 } from "@dxos/log";
1247
1290
  import { Invitation as Invitation3 } from "@dxos/protocols/proto/dxos/client/services";
1248
1291
  var AbstractInvitationsProxy = class {
1292
+ // prettier-ignore
1249
1293
  constructor(_invitationsService) {
1250
1294
  this._invitationsService = _invitationsService;
1251
1295
  }
@@ -1386,12 +1430,14 @@ import { Stream as Stream8 } from "@dxos/codec-protobuf";
1386
1430
  import { log as log7 } from "@dxos/log";
1387
1431
  import { Invitation as Invitation4 } from "@dxos/protocols/proto/dxos/client/services";
1388
1432
  var AbstractInvitationsService = class {
1433
+ // prettier-ignore
1389
1434
  constructor(_identityManager, _getInvitationsHandler) {
1390
1435
  this._identityManager = _identityManager;
1391
1436
  this._getInvitationsHandler = _getInvitationsHandler;
1392
1437
  this._createInvitations = /* @__PURE__ */ new Map();
1393
1438
  this._acceptInvitations = /* @__PURE__ */ new Map();
1394
1439
  }
1440
+ // TODO(burdon): Guest/host label.
1395
1441
  getLoggingContext() {
1396
1442
  var _a;
1397
1443
  return {
@@ -1601,6 +1647,7 @@ var AbstractInvitationsService = class {
1601
1647
 
1602
1648
  // packages/sdk/client-services/src/packlets/invitations/halo-invitations-service.ts
1603
1649
  var HaloInvitationsServiceImpl = class extends AbstractInvitationsService {
1650
+ // prettier-ignore
1604
1651
  constructor(identityManager, invitationsHandler) {
1605
1652
  super(identityManager, () => invitationsHandler);
1606
1653
  this.invitationsHandler = invitationsHandler;
@@ -1630,6 +1677,9 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1630
1677
  this._signingContext = _signingContext;
1631
1678
  this._keyring = _keyring;
1632
1679
  }
1680
+ /**
1681
+ * Creates an invitation and listens for a join request from the invited (guest) peer.
1682
+ */
1633
1683
  createInvitation(space, options) {
1634
1684
  let swarmConnection;
1635
1685
  const { type, timeout = INVITATION_TIMEOUT, swarmKey } = options != null ? options : {};
@@ -1653,8 +1703,8 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1653
1703
  });
1654
1704
  let authenticationCode;
1655
1705
  let authenticationRetry = 0;
1656
- const complete = new Trigger3();
1657
1706
  const createExtension = () => {
1707
+ const complete = new Trigger3();
1658
1708
  let guestProfile;
1659
1709
  const hostInvitationExtension = new HostSpaceInvitationExtension({
1660
1710
  introduce: async ({ profile }) => {
@@ -1665,7 +1715,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1665
1715
  spaceKey: space.key
1666
1716
  }, {
1667
1717
  file: "space-invitations-handler.ts",
1668
- line: 98,
1718
+ line: 97,
1669
1719
  scope: this,
1670
1720
  callSite: (f, a) => f(...a)
1671
1721
  });
@@ -1677,7 +1727,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1677
1727
  authenticationCode: code
1678
1728
  }, {
1679
1729
  file: "space-invitations-handler.ts",
1680
- line: 112,
1730
+ line: 111,
1681
1731
  scope: this,
1682
1732
  callSite: (f, a) => f(...a)
1683
1733
  });
@@ -1697,7 +1747,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1697
1747
  },
1698
1748
  requestAdmission: async ({ identityKey, deviceKey, controlFeedKey, dataFeedKey }) => {
1699
1749
  try {
1700
- if (invitation.type !== Invitation5.Type.INTERACTIVE_TESTING) {
1750
+ if (invitation.type !== Invitation5.Type.INTERACTIVE_TESTING && invitation.type !== Invitation5.Type.MULTIUSE_TESTING) {
1701
1751
  if (invitation.authenticationCode === void 0 || invitation.authenticationCode !== authenticationCode) {
1702
1752
  throw new Error(`invalid authentication code: ${authenticationCode}`);
1703
1753
  }
@@ -1707,7 +1757,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1707
1757
  guest: deviceKey
1708
1758
  }, {
1709
1759
  file: "space-invitations-handler.ts",
1710
- line: 136,
1760
+ line: 138,
1711
1761
  scope: this,
1712
1762
  callSite: (f, a) => f(...a)
1713
1763
  });
@@ -1733,7 +1783,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1733
1783
  host: this._signingContext.deviceKey
1734
1784
  }, {
1735
1785
  file: "space-invitations-handler.ts",
1736
- line: 170,
1786
+ line: 172,
1737
1787
  scope: this,
1738
1788
  callSite: (f, a) => f(...a)
1739
1789
  });
@@ -1746,7 +1796,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1746
1796
  guest: deviceKey
1747
1797
  }, {
1748
1798
  file: "space-invitations-handler.ts",
1749
- line: 173,
1799
+ line: 175,
1750
1800
  scope: this,
1751
1801
  callSite: (f, a) => f(...a)
1752
1802
  });
@@ -1755,15 +1805,17 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1755
1805
  if (!observable.cancelled) {
1756
1806
  log8.error("failed", err, {
1757
1807
  file: "space-invitations-handler.ts",
1758
- line: 177,
1808
+ line: 179,
1759
1809
  scope: this,
1760
1810
  callSite: (f, a) => f(...a)
1761
1811
  });
1762
1812
  observable.callback.onError(err);
1763
1813
  }
1764
1814
  } finally {
1765
- await sleep2(ON_CLOSE_DELAY);
1766
- await ctx.dispose();
1815
+ if (type !== Invitation5.Type.MULTIUSE_TESTING) {
1816
+ await sleep2(ON_CLOSE_DELAY);
1817
+ await ctx.dispose();
1818
+ }
1767
1819
  }
1768
1820
  });
1769
1821
  }
@@ -1786,6 +1838,11 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1786
1838
  });
1787
1839
  return observable;
1788
1840
  }
1841
+ /**
1842
+ * Waits for the host peer (inviter) to accept our join request.
1843
+ * The local guest peer (invitee) then sends the local space invitation to the host,
1844
+ * which then writes the guest's credentials to the space.
1845
+ */
1789
1846
  acceptInvitation(invitation, options) {
1790
1847
  const { timeout = INVITATION_TIMEOUT } = options != null ? options : {};
1791
1848
  const ctx = new Context3({
@@ -1818,7 +1875,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1818
1875
  guest: this._signingContext.deviceKey
1819
1876
  }, {
1820
1877
  file: "space-invitations-handler.ts",
1821
- line: 248,
1878
+ line: 252,
1822
1879
  scope: this,
1823
1880
  callSite: (f, a) => f(...a)
1824
1881
  });
@@ -1827,7 +1884,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1827
1884
  guest: this._signingContext.deviceKey
1828
1885
  }, {
1829
1886
  file: "space-invitations-handler.ts",
1830
- line: 252,
1887
+ line: 256,
1831
1888
  scope: this,
1832
1889
  callSite: (f, a) => f(...a)
1833
1890
  });
@@ -1838,7 +1895,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1838
1895
  for (let attempt = 1; attempt <= MAX_OTP_ATTEMPTS; attempt++) {
1839
1896
  log8("guest waiting for authentication code...", {}, {
1840
1897
  file: "space-invitations-handler.ts",
1841
- line: 261,
1898
+ line: 265,
1842
1899
  scope: this,
1843
1900
  callSite: (f, a) => f(...a)
1844
1901
  });
@@ -1848,7 +1905,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1848
1905
  });
1849
1906
  log8("sending authentication request", {}, {
1850
1907
  file: "space-invitations-handler.ts",
1851
- line: 265,
1908
+ line: 269,
1852
1909
  scope: this,
1853
1910
  callSite: (f, a) => f(...a)
1854
1911
  });
@@ -1866,7 +1923,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1866
1923
  attempt
1867
1924
  }, {
1868
1925
  file: "space-invitations-handler.ts",
1869
- line: 275,
1926
+ line: 279,
1870
1927
  scope: this,
1871
1928
  callSite: (f, a) => f(...a)
1872
1929
  });
@@ -1881,7 +1938,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1881
1938
  guest: this._signingContext.deviceKey
1882
1939
  }, {
1883
1940
  file: "space-invitations-handler.ts",
1884
- line: 286,
1941
+ line: 290,
1885
1942
  scope: this,
1886
1943
  callSite: (f, a) => f(...a)
1887
1944
  });
@@ -1905,7 +1962,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1905
1962
  spaceKey: space.key
1906
1963
  }, {
1907
1964
  file: "space-invitations-handler.ts",
1908
- line: 309,
1965
+ line: 313,
1909
1966
  scope: this,
1910
1967
  callSite: (f, a) => f(...a)
1911
1968
  });
@@ -1914,7 +1971,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1914
1971
  if (!observable.cancelled) {
1915
1972
  log8.warn("auth failed", err, {
1916
1973
  file: "space-invitations-handler.ts",
1917
- line: 313,
1974
+ line: 317,
1918
1975
  scope: this,
1919
1976
  callSite: (f, a) => f(...a)
1920
1977
  });
@@ -1960,6 +2017,8 @@ var HostSpaceInvitationExtension = class extends RpcExtension2 {
1960
2017
  }
1961
2018
  async getHandlers() {
1962
2019
  return {
2020
+ // TODO(dmaretskyi): For now this is just forwarding the data to callbacks since we don't have session-specific logic.
2021
+ // Perhaps in the future we will have more complex logic here.
1963
2022
  SpaceHostService: {
1964
2023
  introduce: async (params) => {
1965
2024
  return this._callbacks.introduce(params);
@@ -2008,6 +2067,7 @@ var SpaceInvitationsProxy = class extends AbstractInvitationsProxy {
2008
2067
  // packages/sdk/client-services/src/packlets/invitations/space-invitations-service.ts
2009
2068
  import assert9 from "@dxos/node-std/assert";
2010
2069
  var SpaceInvitationsServiceImpl = class extends AbstractInvitationsService {
2070
+ // prettier-ignore
2011
2071
  constructor(identityManager, invitationsHandler, _getSpaceManager) {
2012
2072
  super(identityManager, invitationsHandler);
2013
2073
  this.invitationsHandler = invitationsHandler;
@@ -2025,31 +2085,49 @@ var SpaceInvitationsServiceImpl = class extends AbstractInvitationsService {
2025
2085
  // packages/sdk/client-services/src/packlets/services/service-context.ts
2026
2086
  import { Trigger as Trigger4 } from "@dxos/async";
2027
2087
  import { failUndefined as failUndefined2 } from "@dxos/debug";
2028
- import { MOCK_AUTH_PROVIDER, MOCK_AUTH_VERIFIER, valueEncoding, DataServiceSubscriptions, MetadataStore, SpaceManager } from "@dxos/echo-db";
2088
+ import { MOCK_AUTH_PROVIDER, MOCK_AUTH_VERIFIER, valueEncoding, DataServiceSubscriptions, MetadataStore, SpaceManager, SnapshotStore } from "@dxos/echo-db";
2029
2089
  import { FeedFactory, FeedStore } from "@dxos/feed-store";
2030
2090
  import { Keyring } from "@dxos/keyring";
2031
2091
  import { log as log10 } from "@dxos/log";
2032
2092
 
2033
2093
  // packages/sdk/client-services/src/packlets/spaces/data-space-manager.ts
2034
- import { Event as Event3, synchronized } from "@dxos/async";
2035
- import { spaceGenesis } from "@dxos/echo-db";
2094
+ import { Event as Event3, synchronized, trackLeaks as trackLeaks2 } from "@dxos/async";
2095
+ import { Context as Context5 } from "@dxos/context";
2096
+ import { spaceGenesis, SnapshotManager } from "@dxos/echo-db";
2036
2097
  import { PublicKey as PublicKey5 } from "@dxos/keys";
2037
2098
  import { log as log9 } from "@dxos/log";
2038
- import { Presence as Presence2 } from "@dxos/teleport-extension-presence";
2099
+ import { Presence } from "@dxos/teleport-extension-presence";
2039
2100
  import { ComplexMap as ComplexMap2 } from "@dxos/util";
2040
2101
 
2041
2102
  // packages/sdk/client-services/src/packlets/spaces/data-space.ts
2042
2103
  import assert10 from "@dxos/node-std/assert";
2104
+ import { trackLeaks } from "@dxos/async";
2043
2105
  import { Context as Context4 } from "@dxos/context";
2044
2106
  import { DataPipelineControllerImpl } from "@dxos/echo-db";
2045
- var DataSpace = class {
2046
- constructor(_inner, _modelFactory, _memberKey, _presence) {
2047
- this._inner = _inner;
2048
- this._modelFactory = _modelFactory;
2049
- this._memberKey = _memberKey;
2050
- this._presence = _presence;
2107
+ var __decorate = function(decorators, target, key, desc) {
2108
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2109
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
2110
+ r = Reflect.decorate(decorators, target, key, desc);
2111
+ else
2112
+ for (var i = decorators.length - 1; i >= 0; i--)
2113
+ if (d = decorators[i])
2114
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2115
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2116
+ };
2117
+ var DataSpace = class DataSpace2 {
2118
+ constructor(params) {
2051
2119
  this._ctx = new Context4();
2052
- this._dataPipelineController = new DataPipelineControllerImpl(_modelFactory, _memberKey, (feedKey) => _inner.spaceState.feeds.get(feedKey));
2120
+ this._inner = params.inner;
2121
+ this._presence = params.presence;
2122
+ this._dataPipelineController = new DataPipelineControllerImpl({
2123
+ modelFactory: params.modelFactory,
2124
+ metadataStore: params.metadataStore,
2125
+ snapshotManager: params.snapshotManager,
2126
+ memberKey: params.memberKey,
2127
+ spaceKey: this._inner.key,
2128
+ feedInfoProvider: (feedKey) => this._inner.spaceState.feeds.get(feedKey),
2129
+ snapshotId: params.snapshotId
2130
+ });
2053
2131
  }
2054
2132
  get key() {
2055
2133
  return this._inner.key;
@@ -2075,6 +2153,7 @@ var DataSpace = class {
2075
2153
  }
2076
2154
  async open() {
2077
2155
  await this._inner.open();
2156
+ await this._inner.initDataPipeline(this._dataPipelineController);
2078
2157
  }
2079
2158
  async close() {
2080
2159
  await this._ctx.dispose();
@@ -2082,9 +2161,12 @@ var DataSpace = class {
2082
2161
  await this._presence.destroy();
2083
2162
  }
2084
2163
  };
2164
+ DataSpace = __decorate([
2165
+ trackLeaks("open", "close")
2166
+ ], DataSpace);
2085
2167
 
2086
2168
  // packages/sdk/client-services/src/packlets/spaces/data-space-manager.ts
2087
- var __decorate = function(decorators, target, key, desc) {
2169
+ var __decorate2 = function(decorators, target, key, desc) {
2088
2170
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2089
2171
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
2090
2172
  r = Reflect.decorate(decorators, target, key, desc);
@@ -2094,28 +2176,65 @@ var __decorate = function(decorators, target, key, desc) {
2094
2176
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2095
2177
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2096
2178
  };
2097
- var DataSpaceManager = class {
2098
- constructor(_spaceManager, _metadataStore, _dataServiceSubscriptions, _keyring, _signingContext, _modelFactory) {
2179
+ var DataSpaceManager = class DataSpaceManager2 {
2180
+ constructor(_spaceManager, _metadataStore, _dataServiceSubscriptions, _keyring, _signingContext, _modelFactory, _snapshotStore) {
2099
2181
  this._spaceManager = _spaceManager;
2100
2182
  this._metadataStore = _metadataStore;
2101
2183
  this._dataServiceSubscriptions = _dataServiceSubscriptions;
2102
2184
  this._keyring = _keyring;
2103
2185
  this._signingContext = _signingContext;
2104
2186
  this._modelFactory = _modelFactory;
2187
+ this._snapshotStore = _snapshotStore;
2188
+ this._ctx = new Context5();
2105
2189
  this.updated = new Event3();
2106
2190
  this._spaces = new ComplexMap2(PublicKey5.hash);
2107
2191
  }
2192
+ // TODO(burdon): Remove.
2108
2193
  get spaces() {
2109
2194
  return this._spaces;
2110
2195
  }
2111
2196
  async open() {
2112
2197
  await this._metadataStore.load();
2198
+ log9("metadata loaded", {
2199
+ spaces: this._metadataStore.spaces.length
2200
+ }, {
2201
+ file: "data-space-manager.ts",
2202
+ line: 54,
2203
+ scope: this,
2204
+ callSite: (f, a) => f(...a)
2205
+ });
2113
2206
  for (const spaceMetadata of this._metadataStore.spaces) {
2114
- await this._constructSpace(spaceMetadata);
2207
+ log9("load space", {
2208
+ spaceMetadata
2209
+ }, {
2210
+ file: "data-space-manager.ts",
2211
+ line: 57,
2212
+ scope: this,
2213
+ callSite: (f, a) => f(...a)
2214
+ });
2215
+ const space = await this._constructSpace(spaceMetadata);
2216
+ if (spaceMetadata.latestTimeframe) {
2217
+ log9("waiting for latest timeframe", {
2218
+ spaceMetadata
2219
+ }, {
2220
+ file: "data-space-manager.ts",
2221
+ line: 60,
2222
+ scope: this,
2223
+ callSite: (f, a) => f(...a)
2224
+ });
2225
+ await space.dataPipelineController.waitUntilTimeframe(spaceMetadata.latestTimeframe);
2226
+ }
2115
2227
  }
2116
2228
  }
2117
2229
  async close() {
2230
+ await this._ctx.dispose();
2231
+ for (const space of this._spaces.values()) {
2232
+ await space.close();
2233
+ }
2118
2234
  }
2235
+ /**
2236
+ * Creates a new space writing the genesis credentials to the control feed.
2237
+ */
2119
2238
  async createSpace() {
2120
2239
  const spaceKey = await this._keyring.createKey();
2121
2240
  const controlFeedKey = await this._keyring.createKey();
@@ -2130,7 +2249,7 @@ var DataSpaceManager = class {
2130
2249
  spaceKey
2131
2250
  }, {
2132
2251
  file: "data-space-manager.ts",
2133
- line: 70,
2252
+ line: 89,
2134
2253
  scope: this,
2135
2254
  callSite: (f, a) => f(...a)
2136
2255
  });
@@ -2140,6 +2259,7 @@ var DataSpaceManager = class {
2140
2259
  this.updated.emit();
2141
2260
  return space;
2142
2261
  }
2262
+ // TODO(burdon): Rename join space.
2143
2263
  async acceptSpace(opts) {
2144
2264
  const metadata = {
2145
2265
  key: opts.spaceKey,
@@ -2153,12 +2273,13 @@ var DataSpaceManager = class {
2153
2273
  return space;
2154
2274
  }
2155
2275
  async _constructSpace(metadata) {
2156
- const presence = new Presence2({
2276
+ const presence = new Presence({
2157
2277
  localPeerId: this._signingContext.deviceKey,
2158
2278
  announceInterval: 1e3,
2159
2279
  offlineTimeout: 3e4,
2160
2280
  identityKey: this._signingContext.identityKey
2161
2281
  });
2282
+ const snapshotManager = new SnapshotManager(this._snapshotStore);
2162
2283
  const space = await this._spaceManager.constructSpace({
2163
2284
  metadata,
2164
2285
  swarmIdentity: {
@@ -2166,25 +2287,47 @@ var DataSpaceManager = class {
2166
2287
  credentialProvider: this._signingContext.credentialProvider,
2167
2288
  credentialAuthenticator: this._signingContext.credentialAuthenticator
2168
2289
  },
2169
- dataPipelineControllerProvider: () => dataSpace.dataPipelineController,
2170
- presence
2290
+ onNetworkConnection: (session) => {
2291
+ session.addExtension("dxos.mesh.teleport.presence", presence.createExtension({
2292
+ remotePeerId: session.remotePeerId
2293
+ }));
2294
+ session.addExtension("dxos.mesh.teleport.objectsync", snapshotManager.objectSync.createExtension());
2295
+ }
2171
2296
  });
2172
- const dataSpace = new DataSpace(space, this._modelFactory, this._signingContext.identityKey, presence);
2173
- await space.open();
2297
+ const dataSpace = new DataSpace({
2298
+ inner: space,
2299
+ modelFactory: this._modelFactory,
2300
+ metadataStore: this._metadataStore,
2301
+ snapshotManager,
2302
+ presence,
2303
+ memberKey: this._signingContext.identityKey,
2304
+ snapshotId: metadata.snapshot
2305
+ });
2306
+ await dataSpace.open();
2174
2307
  this._dataServiceSubscriptions.registerSpace(space.key, dataSpace.database.createDataServiceHost());
2175
2308
  this._spaces.set(metadata.key, dataSpace);
2176
2309
  return dataSpace;
2177
2310
  }
2178
2311
  };
2179
- __decorate([
2312
+ __decorate2([
2180
2313
  synchronized
2181
2314
  ], DataSpaceManager.prototype, "open", null);
2182
- __decorate([
2315
+ __decorate2([
2183
2316
  synchronized
2184
2317
  ], DataSpaceManager.prototype, "close", null);
2318
+ __decorate2([
2319
+ synchronized
2320
+ ], DataSpaceManager.prototype, "createSpace", null);
2321
+ __decorate2([
2322
+ synchronized
2323
+ ], DataSpaceManager.prototype, "acceptSpace", null);
2324
+ DataSpaceManager = __decorate2([
2325
+ trackLeaks2("open", "close")
2326
+ ], DataSpaceManager);
2185
2327
 
2186
2328
  // packages/sdk/client-services/src/packlets/services/service-context.ts
2187
2329
  var ServiceContext = class {
2330
+ // prettier-ignore
2188
2331
  constructor(storage, networkManager, modelFactory) {
2189
2332
  this.storage = storage;
2190
2333
  this.networkManager = networkManager;
@@ -2192,6 +2335,7 @@ var ServiceContext = class {
2192
2335
  this.initialized = new Trigger4();
2193
2336
  this.dataServiceSubscriptions = new DataServiceSubscriptions();
2194
2337
  this.metadataStore = new MetadataStore(storage.createDirectory("metadata"));
2338
+ this.snapshotStore = new SnapshotStore(storage.createDirectory("snapshots"));
2195
2339
  this.keyring = new Keyring(storage.createDirectory("keyring"));
2196
2340
  this.feedStore = new FeedStore({
2197
2341
  factory: new FeedFactory({
@@ -2212,10 +2356,11 @@ var ServiceContext = class {
2212
2356
  async open() {
2213
2357
  log10("opening...", {}, {
2214
2358
  file: "service-context.ts",
2215
- line: 81,
2359
+ line: 85,
2216
2360
  scope: this,
2217
2361
  callSite: (f, a) => f(...a)
2218
2362
  });
2363
+ await this.networkManager.open();
2219
2364
  await this.spaceManager.open();
2220
2365
  await this.identityManager.open();
2221
2366
  if (this.identityManager.identity) {
@@ -2223,7 +2368,7 @@ var ServiceContext = class {
2223
2368
  }
2224
2369
  log10("opened", {}, {
2225
2370
  file: "service-context.ts",
2226
- line: 87,
2371
+ line: 92,
2227
2372
  scope: this,
2228
2373
  callSite: (f, a) => f(...a)
2229
2374
  });
@@ -2232,7 +2377,7 @@ var ServiceContext = class {
2232
2377
  var _a;
2233
2378
  log10("closing...", {}, {
2234
2379
  file: "service-context.ts",
2235
- line: 91,
2380
+ line: 96,
2236
2381
  scope: this,
2237
2382
  callSite: (f, a) => f(...a)
2238
2383
  });
@@ -2244,7 +2389,7 @@ var ServiceContext = class {
2244
2389
  this.dataServiceSubscriptions.clear();
2245
2390
  log10("closed", {}, {
2246
2391
  file: "service-context.ts",
2247
- line: 98,
2392
+ line: 103,
2248
2393
  scope: this,
2249
2394
  callSite: (f, a) => f(...a)
2250
2395
  });
@@ -2252,7 +2397,7 @@ var ServiceContext = class {
2252
2397
  async reset() {
2253
2398
  log10("resetting...", {}, {
2254
2399
  file: "service-context.ts",
2255
- line: 102,
2400
+ line: 107,
2256
2401
  scope: this,
2257
2402
  callSite: (f, a) => f(...a)
2258
2403
  });
@@ -2260,7 +2405,7 @@ var ServiceContext = class {
2260
2405
  await this.storage.reset();
2261
2406
  log10("reset", {}, {
2262
2407
  file: "service-context.ts",
2263
- line: 105,
2408
+ line: 110,
2264
2409
  scope: this,
2265
2410
  callSite: (f, a) => f(...a)
2266
2411
  });
@@ -2270,8 +2415,15 @@ var ServiceContext = class {
2270
2415
  await this._initialize();
2271
2416
  return identity;
2272
2417
  }
2418
+ // Called when identity is created.
2273
2419
  async _initialize() {
2274
2420
  var _a;
2421
+ log10("initializing spaces...", {}, {
2422
+ file: "service-context.ts",
2423
+ line: 122,
2424
+ scope: this,
2425
+ callSite: (f, a) => f(...a)
2426
+ });
2275
2427
  const identity = (_a = this.identityManager.identity) != null ? _a : failUndefined2();
2276
2428
  const signingContext = {
2277
2429
  credentialProvider: MOCK_AUTH_PROVIDER,
@@ -2281,7 +2433,7 @@ var ServiceContext = class {
2281
2433
  deviceKey: identity.deviceKey,
2282
2434
  profile: identity.profileDocument
2283
2435
  };
2284
- this.dataSpaceManager = new DataSpaceManager(this.spaceManager, this.metadataStore, this.dataServiceSubscriptions, this.keyring, signingContext, this.modelFactory);
2436
+ this.dataSpaceManager = new DataSpaceManager(this.spaceManager, this.metadataStore, this.dataServiceSubscriptions, this.keyring, signingContext, this.modelFactory, this.snapshotStore);
2285
2437
  await this.dataSpaceManager.open();
2286
2438
  this.spaceInvitations = new SpaceInvitationsHandler(this.networkManager, this.dataSpaceManager, signingContext, this.keyring);
2287
2439
  this.initialized.wake();
@@ -2296,6 +2448,8 @@ var clientServiceBundle = createServiceBundle({
2296
2448
  DevicesService: schema5.getService("dxos.client.services.DevicesService"),
2297
2449
  SpaceInvitationsService: schema5.getService("dxos.client.services.SpaceInvitationsService"),
2298
2450
  SpacesService: schema5.getService("dxos.client.services.SpacesService"),
2451
+ NetworkService: schema5.getService("dxos.client.services.NetworkService"),
2452
+ // TODO(burdon): Deprecated.
2299
2453
  SpaceService: schema5.getService("dxos.client.SpaceService"),
2300
2454
  DataService: schema5.getService("dxos.echo.service.DataService"),
2301
2455
  ProfileService: schema5.getService("dxos.client.ProfileService"),
@@ -2305,7 +2459,7 @@ var clientServiceBundle = createServiceBundle({
2305
2459
  });
2306
2460
 
2307
2461
  // packages/sdk/client-services/src/packlets/services/service-host.ts
2308
- import { raise } from "@dxos/debug";
2462
+ import { raise as raise2 } from "@dxos/debug";
2309
2463
  import { DataServiceImpl } from "@dxos/echo-db";
2310
2464
  import { log as log11 } from "@dxos/log";
2311
2465
  import { ModelFactory } from "@dxos/model-factory";
@@ -2354,8 +2508,37 @@ var DevicesServiceImpl = class {
2354
2508
  }
2355
2509
  };
2356
2510
 
2511
+ // packages/sdk/client-services/src/packlets/network/network-service.ts
2512
+ import { Stream as Stream10 } from "@dxos/codec-protobuf";
2513
+ var NetworkServiceImpl = class {
2514
+ constructor(networkManager) {
2515
+ this.networkManager = networkManager;
2516
+ }
2517
+ subscribeToNetworkStatus() {
2518
+ return new Stream10(({ next }) => {
2519
+ const unsubscribe = this.networkManager.connectionStateChanged.on((state) => next({
2520
+ state
2521
+ }));
2522
+ next({
2523
+ state: this.networkManager.connectionState
2524
+ });
2525
+ return unsubscribe;
2526
+ });
2527
+ }
2528
+ async setNetworkOptions(request) {
2529
+ await this.networkManager.setConnectionState(request.state);
2530
+ }
2531
+ };
2532
+
2357
2533
  // packages/sdk/client-services/src/packlets/spaces/spaces-service.ts
2534
+ import { scheduleTask as scheduleTask3 } from "@dxos/async";
2535
+ import { Stream as Stream11 } from "@dxos/codec-protobuf";
2536
+ import { raise } from "@dxos/debug";
2537
+ import { SpaceNotFoundError } from "@dxos/echo-db";
2358
2538
  var SpacesServiceImpl = class {
2539
+ constructor(_spaceManager) {
2540
+ this._spaceManager = _spaceManager;
2541
+ }
2359
2542
  async createSpace() {
2360
2543
  throw new Error();
2361
2544
  }
@@ -2365,16 +2548,25 @@ var SpacesServiceImpl = class {
2365
2548
  queryMembers(query) {
2366
2549
  throw new Error();
2367
2550
  }
2551
+ queryCredentials({ spaceKey }) {
2552
+ return new Stream11(({ ctx, next }) => {
2553
+ var _a;
2554
+ const space = (_a = this._spaceManager.spaces.get(spaceKey)) != null ? _a : raise(new SpaceNotFoundError(spaceKey));
2555
+ const processor = space.spaceState.registerProcessor({
2556
+ process: async (credential) => {
2557
+ next(credential);
2558
+ }
2559
+ });
2560
+ ctx.onDispose(() => processor.close());
2561
+ scheduleTask3(ctx, () => processor.open());
2562
+ });
2563
+ }
2368
2564
  };
2369
2565
 
2370
2566
  // packages/sdk/client-services/src/packlets/storage/storage.ts
2371
- import jsondown from "jsondown";
2372
- import leveljs from "level-js";
2373
- import memdown from "memdown";
2374
2567
  import { InvalidConfigError } from "@dxos/errors";
2375
2568
  import { Runtime } from "@dxos/protocols/proto/dxos/config";
2376
2569
  import { createStorage, StorageType } from "@dxos/random-access-storage";
2377
- import { isNode } from "@dxos/util";
2378
2570
  var StorageDriver = Runtime.Client.Storage.StorageDriver;
2379
2571
  var createStorageObjects = (config) => {
2380
2572
  const { path = "dxos/storage", storageType, keyStorage, persistent = false } = config != null ? config : {};
@@ -2394,23 +2586,9 @@ var createStorageObjects = (config) => {
2394
2586
  storage: createStorage({
2395
2587
  type: persistent ? toStorageType(storageType) : StorageType.RAM,
2396
2588
  root: `${path}/`
2397
- }),
2398
- keyStorage: createKeyStorage(`${path}/keystore`, persistent ? toKeyStorageType(keyStorage) : "ram")
2589
+ })
2399
2590
  };
2400
2591
  };
2401
- var createKeyStorage = (path, type) => {
2402
- const defaultedType = type != null ? type : isNode() ? "jsondown" : "leveljs";
2403
- switch (defaultedType) {
2404
- case "leveljs":
2405
- return leveljs(path);
2406
- case "jsondown":
2407
- return jsondown(path);
2408
- case "ram":
2409
- return memdown();
2410
- default:
2411
- throw new InvalidConfigError(`Invalid key storage type: ${defaultedType}`);
2412
- }
2413
- };
2414
2592
  var toStorageType = (type) => {
2415
2593
  switch (type) {
2416
2594
  case void 0:
@@ -2429,23 +2607,10 @@ var toStorageType = (type) => {
2429
2607
  throw new Error(`Invalid storage type: ${StorageDriver[type]}`);
2430
2608
  }
2431
2609
  };
2432
- var toKeyStorageType = (type) => {
2433
- switch (type) {
2434
- case void 0:
2435
- return void 0;
2436
- case StorageDriver.RAM:
2437
- return "ram";
2438
- case StorageDriver.LEVELJS:
2439
- return "leveljs";
2440
- case StorageDriver.JSONDOWN:
2441
- return "jsondown";
2442
- default:
2443
- throw new Error(`Invalid key storage type: ${StorageDriver[type]}`);
2444
- }
2445
- };
2446
2610
 
2447
2611
  // packages/sdk/client-services/src/packlets/services/service-registry.ts
2448
2612
  var ServiceRegistry = class {
2613
+ // prettier-ignore
2449
2614
  constructor(_serviceBundle, _handlers) {
2450
2615
  this._serviceBundle = _serviceBundle;
2451
2616
  this._handlers = _handlers;
@@ -2466,11 +2631,14 @@ var ClientServicesHost = class {
2466
2631
  constructor({
2467
2632
  config,
2468
2633
  modelFactory = createDefaultModelFactory(),
2469
- networkManager
2634
+ // TODO(burdon): Create ApolloLink abstraction (see Client).
2635
+ networkManager,
2636
+ storage = createStorageObjects(config.get("runtime.client.storage", {})).storage
2470
2637
  }) {
2471
2638
  this._config = config;
2472
2639
  this._modelFactory = modelFactory;
2473
2640
  this._networkManager = networkManager;
2641
+ this._storage = storage;
2474
2642
  }
2475
2643
  get descriptors() {
2476
2644
  return this._serviceRegistry.descriptors;
@@ -2480,23 +2648,20 @@ var ClientServicesHost = class {
2480
2648
  }
2481
2649
  async open() {
2482
2650
  var _a;
2483
- await this._initialize();
2484
- const deviceKey = (_a = this._serviceContext.identityManager.identity) == null ? void 0 : _a.deviceKey;
2485
- log11("opening...", {
2486
- deviceKey
2487
- }, {
2651
+ log11("opening...", {}, {
2488
2652
  file: "service-host.ts",
2489
- line: 69,
2653
+ line: 73,
2490
2654
  scope: this,
2491
2655
  callSite: (f, a) => f(...a)
2492
2656
  });
2493
2657
  await this._initialize();
2494
2658
  await this._serviceContext.open();
2659
+ const deviceKey = (_a = this._serviceContext.identityManager.identity) == null ? void 0 : _a.deviceKey;
2495
2660
  log11("opened", {
2496
2661
  deviceKey
2497
2662
  }, {
2498
2663
  file: "service-host.ts",
2499
- line: 72,
2664
+ line: 77,
2500
2665
  scope: this,
2501
2666
  callSite: (f, a) => f(...a)
2502
2667
  });
@@ -2508,7 +2673,7 @@ var ClientServicesHost = class {
2508
2673
  deviceKey
2509
2674
  }, {
2510
2675
  file: "service-host.ts",
2511
- line: 77,
2676
+ line: 82,
2512
2677
  scope: this,
2513
2678
  callSite: (f, a) => f(...a)
2514
2679
  });
@@ -2517,26 +2682,28 @@ var ClientServicesHost = class {
2517
2682
  deviceKey
2518
2683
  }, {
2519
2684
  file: "service-host.ts",
2520
- line: 79,
2685
+ line: 84,
2521
2686
  scope: this,
2522
2687
  callSite: (f, a) => f(...a)
2523
2688
  });
2524
2689
  }
2690
+ // TODO(burdon): Move into open.
2525
2691
  async _initialize() {
2526
- const { storage } = createStorageObjects(this._config.get("runtime.client.storage", {}));
2527
- this._serviceContext = new ServiceContext(storage, this._networkManager, this._modelFactory);
2692
+ this._serviceContext = new ServiceContext(this._storage, this._networkManager, this._modelFactory);
2528
2693
  this._serviceRegistry = new ServiceRegistry(clientServiceBundle, {
2529
2694
  HaloInvitationsService: new HaloInvitationsServiceImpl(this._serviceContext.identityManager, this._serviceContext.haloInvitations),
2530
2695
  DevicesService: new DevicesServiceImpl(this._serviceContext.identityManager),
2531
2696
  SpaceInvitationsService: new SpaceInvitationsServiceImpl(this._serviceContext.identityManager, () => {
2532
2697
  var _a;
2533
- return (_a = this._serviceContext.spaceInvitations) != null ? _a : raise(new Error("SpaceInvitations not initialized"));
2698
+ return (_a = this._serviceContext.spaceInvitations) != null ? _a : raise2(new Error("SpaceInvitations not initialized"));
2534
2699
  }, () => {
2535
2700
  var _a;
2536
- return (_a = this._serviceContext.dataSpaceManager) != null ? _a : raise(new Error("SpaceManager not initialized"));
2701
+ return (_a = this._serviceContext.dataSpaceManager) != null ? _a : raise2(new Error("SpaceManager not initialized"));
2537
2702
  }),
2538
- SpacesService: new SpacesServiceImpl(),
2703
+ SpacesService: new SpacesServiceImpl(this._serviceContext.spaceManager),
2539
2704
  DataService: new DataServiceImpl(this._serviceContext.dataServiceSubscriptions),
2705
+ NetworkService: new NetworkServiceImpl(this._serviceContext.networkManager),
2706
+ // TODO(burdon): Move to new protobuf definitions.
2540
2707
  ProfileService: new ProfileServiceImpl(this._serviceContext),
2541
2708
  SpaceService: new SpaceServiceImpl(this._serviceContext),
2542
2709
  SystemService: new SystemServiceImpl(this._config, this._serviceContext),
@@ -2555,6 +2722,7 @@ import { asyncTimeout } from "@dxos/async";
2555
2722
  import { RemoteServiceConnectionTimeout } from "@dxos/errors";
2556
2723
  import { createProtoRpcPeer } from "@dxos/rpc";
2557
2724
  var ClientServicesProxy = class {
2725
+ // prettier-ignore
2558
2726
  constructor(port, _timeout = 3e4) {
2559
2727
  this._timeout = _timeout;
2560
2728
  this._proxy = createProtoRpcPeer({
@@ -2641,7 +2809,7 @@ import { Trigger as Trigger5 } from "@dxos/async";
2641
2809
  import { log as log12, logInfo } from "@dxos/log";
2642
2810
  import { createProtoRpcPeer as createProtoRpcPeer3 } from "@dxos/rpc";
2643
2811
  import { Callback } from "@dxos/util";
2644
- var __decorate2 = function(decorators, target, key, desc) {
2812
+ var __decorate3 = function(decorators, target, key, desc) {
2645
2813
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2646
2814
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
2647
2815
  r = Reflect.decorate(decorators, target, key, desc);
@@ -2668,6 +2836,7 @@ var WorkerSession = class {
2668
2836
  DevicesService: async () => (await this._getServices()).services.DevicesService,
2669
2837
  SpaceInvitationsService: async () => (await this._getServices()).services.SpaceInvitationsService,
2670
2838
  SpacesService: async () => (await this._getServices()).services.SpacesService,
2839
+ NetworkService: async () => (await this._getServices()).services.NetworkService,
2671
2840
  SpaceService: async () => (await this._getServices()).services.SpaceService,
2672
2841
  DataService: async () => (await this._getServices()).services.DataService,
2673
2842
  ProfileService: async () => (await this._getServices()).services.ProfileService,
@@ -2693,7 +2862,7 @@ var WorkerSession = class {
2693
2862
  } catch (err) {
2694
2863
  log12.catch(err, {}, {
2695
2864
  file: "worker-session.ts",
2696
- line: 89,
2865
+ line: 90,
2697
2866
  scope: this,
2698
2867
  callSite: (f, a) => f(...a)
2699
2868
  });
@@ -2704,13 +2873,14 @@ var WorkerSession = class {
2704
2873
  },
2705
2874
  port: systemPort,
2706
2875
  timeout: 1e3
2876
+ // With low timeout heartbeat may fail if the tab's thread is saturated.
2707
2877
  });
2708
2878
  this.bridgeService = this._iframeRpc.rpc.BridgeService;
2709
2879
  }
2710
2880
  async open() {
2711
2881
  log12.info("opening..", {}, {
2712
2882
  file: "worker-session.ts",
2713
- line: 103,
2883
+ line: 104,
2714
2884
  scope: this,
2715
2885
  callSite: (f, a) => f(...a)
2716
2886
  });
@@ -2729,7 +2899,7 @@ var WorkerSession = class {
2729
2899
  err: err1
2730
2900
  }, {
2731
2901
  file: "worker-session.ts",
2732
- line: 115,
2902
+ line: 116,
2733
2903
  scope: this,
2734
2904
  callSite: (f, a) => f(...a)
2735
2905
  });
@@ -2738,7 +2908,7 @@ var WorkerSession = class {
2738
2908
  } catch (err) {
2739
2909
  log12.catch(err, {}, {
2740
2910
  file: "worker-session.ts",
2741
- line: 119,
2911
+ line: 120,
2742
2912
  scope: this,
2743
2913
  callSite: (f, a) => f(...a)
2744
2914
  });
@@ -2749,7 +2919,7 @@ var WorkerSession = class {
2749
2919
  async close() {
2750
2920
  log12.info("closing..", {}, {
2751
2921
  file: "worker-session.ts",
2752
- line: 126,
2922
+ line: 127,
2753
2923
  scope: this,
2754
2924
  callSite: (f, a) => f(...a)
2755
2925
  });
@@ -2758,7 +2928,7 @@ var WorkerSession = class {
2758
2928
  } catch (err) {
2759
2929
  log12.catch(err, {}, {
2760
2930
  file: "worker-session.ts",
2761
- line: 130,
2931
+ line: 131,
2762
2932
  scope: this,
2763
2933
  callSite: (f, a) => f(...a)
2764
2934
  });
@@ -2772,12 +2942,13 @@ var WorkerSession = class {
2772
2942
  ]);
2773
2943
  }
2774
2944
  };
2775
- __decorate2([
2945
+ __decorate3([
2776
2946
  logInfo
2777
2947
  ], WorkerSession.prototype, "origin", void 0);
2778
2948
 
2779
2949
  // packages/sdk/client-services/src/packlets/vault/worker-runtime.ts
2780
2950
  var WorkerRuntime = class {
2951
+ // prettier-ignore
2781
2952
  constructor(_configProvider) {
2782
2953
  this._configProvider = _configProvider;
2783
2954
  this._transportFactory = new WebRTCTransportProxyFactory();
@@ -2807,6 +2978,9 @@ var WorkerRuntime = class {
2807
2978
  async stop() {
2808
2979
  await this._clientServices.close();
2809
2980
  }
2981
+ /**
2982
+ * Create a new session.
2983
+ */
2810
2984
  async createSession({ appPort, systemPort }) {
2811
2985
  const session = new WorkerSession({
2812
2986
  getServices: async () => {
@@ -2828,6 +3002,9 @@ var WorkerRuntime = class {
2828
3002
  this.sessions.add(session);
2829
3003
  this._reconnectWebrtc();
2830
3004
  }
3005
+ /**
3006
+ * Selects one of the existing session fro WebRTC networking.
3007
+ */
2831
3008
  _reconnectWebrtc() {
2832
3009
  if (this._sessionForNetworking) {
2833
3010
  if (!this.sessions.has(this._sessionForNetworking)) {