@dxos/client-services 0.1.35 → 0.1.36

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 (95) hide show
  1. package/dist/lib/browser/{chunk-H5IXSSI7.mjs → chunk-2AYYVPWN.mjs} +835 -950
  2. package/dist/lib/browser/chunk-2AYYVPWN.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +9 -11
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/packlets/testing/index.mjs +212 -74
  6. package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
  7. package/dist/lib/node/index.cjs +942 -1058
  8. package/dist/lib/node/index.cjs.map +4 -4
  9. package/dist/lib/node/meta.json +1 -1
  10. package/dist/lib/node/packlets/testing/index.cjs +1089 -1067
  11. package/dist/lib/node/packlets/testing/index.cjs.map +4 -4
  12. package/dist/types/src/packlets/identity/identity-manager.d.ts +1 -0
  13. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  14. package/dist/types/src/packlets/identity/identity.d.ts +3 -3
  15. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  16. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +18 -0
  17. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -0
  18. package/dist/types/src/packlets/invitations/device-invitation-protocol.test.d.ts +2 -0
  19. package/dist/types/src/packlets/invitations/device-invitation-protocol.test.d.ts.map +1 -0
  20. package/dist/types/src/packlets/invitations/index.d.ts +4 -4
  21. package/dist/types/src/packlets/invitations/index.d.ts.map +1 -1
  22. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +12 -0
  23. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -0
  24. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +38 -0
  25. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -0
  26. package/dist/types/src/packlets/invitations/invitations-service.d.ts +13 -15
  27. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  28. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +22 -0
  29. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -0
  30. package/dist/types/src/packlets/invitations/space-invitation-protocol.test.d.ts +2 -0
  31. package/dist/types/src/packlets/invitations/space-invitation-protocol.test.d.ts.map +1 -0
  32. package/dist/types/src/packlets/services/service-context.d.ts +6 -4
  33. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  34. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  35. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +2 -0
  36. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  37. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  38. package/dist/types/src/packlets/testing/invitation-utils.d.ts +31 -2
  39. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  40. package/dist/types/src/packlets/testing/test-builder.d.ts +3 -3
  41. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  42. package/dist/types/src/packlets/tests/invitations.test.d.ts +2 -0
  43. package/dist/types/src/packlets/tests/invitations.test.d.ts.map +1 -0
  44. package/dist/types/src/packlets/vault/worker-runtime.d.ts +2 -0
  45. package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
  46. package/package.json +30 -30
  47. package/src/packlets/identity/identity-manager.ts +2 -1
  48. package/src/packlets/identity/identity.ts +3 -3
  49. package/src/packlets/invitations/{device-invitations-handler.test.ts → device-invitation-protocol.test.ts} +3 -3
  50. package/src/packlets/invitations/device-invitation-protocol.ts +83 -0
  51. package/src/packlets/invitations/index.ts +4 -4
  52. package/src/packlets/invitations/invitation-protocol.ts +21 -0
  53. package/src/packlets/invitations/invitations-handler.ts +462 -0
  54. package/src/packlets/invitations/invitations-service.ts +127 -104
  55. package/src/packlets/invitations/space-invitation-protocol.test.ts +221 -0
  56. package/src/packlets/invitations/space-invitation-protocol.ts +117 -0
  57. package/src/packlets/services/service-context.test.ts +11 -4
  58. package/src/packlets/services/service-context.ts +40 -19
  59. package/src/packlets/services/service-host.ts +4 -12
  60. package/src/packlets/services/service-registry.test.ts +23 -25
  61. package/src/packlets/spaces/data-space-manager.ts +5 -0
  62. package/src/packlets/spaces/spaces-service.ts +7 -2
  63. package/src/packlets/storage/storage.ts +2 -0
  64. package/src/packlets/testing/invitation-utils.ts +219 -31
  65. package/src/packlets/testing/test-builder.ts +33 -22
  66. package/src/packlets/tests/client-services.test.ts +33 -76
  67. package/src/packlets/tests/halo-profile.test.ts +2 -28
  68. package/src/packlets/tests/invitations.test.ts +389 -0
  69. package/src/packlets/tests/spaces-invitations.test.ts +12 -30
  70. package/src/packlets/tests/spaces.test.ts +30 -28
  71. package/src/packlets/vault/worker-runtime.ts +4 -0
  72. package/dist/lib/browser/chunk-H5IXSSI7.mjs.map +0 -7
  73. package/dist/types/src/packlets/invitations/device-invitations-handler.d.ts +0 -30
  74. package/dist/types/src/packlets/invitations/device-invitations-handler.d.ts.map +0 -1
  75. package/dist/types/src/packlets/invitations/device-invitations-handler.test.d.ts +0 -2
  76. package/dist/types/src/packlets/invitations/device-invitations-handler.test.d.ts.map +0 -1
  77. package/dist/types/src/packlets/invitations/device-invitations-service.d.ts +0 -13
  78. package/dist/types/src/packlets/invitations/device-invitations-service.d.ts.map +0 -1
  79. package/dist/types/src/packlets/invitations/device-invitations-service.test.d.ts +0 -2
  80. package/dist/types/src/packlets/invitations/device-invitations-service.test.d.ts.map +0 -1
  81. package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts +0 -26
  82. package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts.map +0 -1
  83. package/dist/types/src/packlets/invitations/space-invitations-handler.test.d.ts +0 -2
  84. package/dist/types/src/packlets/invitations/space-invitations-handler.test.d.ts.map +0 -1
  85. package/dist/types/src/packlets/invitations/space-invitations-service.d.ts +0 -16
  86. package/dist/types/src/packlets/invitations/space-invitations-service.d.ts.map +0 -1
  87. package/dist/types/src/packlets/invitations/space-invitations-service.test.d.ts +0 -2
  88. package/dist/types/src/packlets/invitations/space-invitations-service.test.d.ts.map +0 -1
  89. package/src/packlets/invitations/device-invitations-handler.ts +0 -370
  90. package/src/packlets/invitations/device-invitations-service.test.ts +0 -96
  91. package/src/packlets/invitations/device-invitations-service.ts +0 -24
  92. package/src/packlets/invitations/space-invitations-handler.test.ts +0 -246
  93. package/src/packlets/invitations/space-invitations-handler.ts +0 -463
  94. package/src/packlets/invitations/space-invitations-service.test.ts +0 -129
  95. package/src/packlets/invitations/space-invitations-service.ts +0 -35
@@ -41,6 +41,7 @@ __export(testing_exports, {
41
41
  createSigningContext: () => createSigningContext,
42
42
  joinCommonSpace: () => joinCommonSpace,
43
43
  performInvitation: () => performInvitation,
44
+ sanitizeInvitation: () => sanitizeInvitation,
44
45
  syncItems: () => syncItems,
45
46
  syncItemsLocal: () => syncItemsLocal,
46
47
  testConfigWithLocalSignal: () => testConfigWithLocalSignal,
@@ -72,18 +73,17 @@ var import_testing = require("@dxos/echo-pipeline/testing");
72
73
  var import_feed_store5 = require("@dxos/feed-store");
73
74
  var import_keyring2 = require("@dxos/keyring");
74
75
  var import_messaging4 = require("@dxos/messaging");
75
- var import_network_manager7 = require("@dxos/network-manager");
76
+ var import_network_manager6 = require("@dxos/network-manager");
76
77
  var import_random_access_storage2 = require("@dxos/random-access-storage");
77
78
 
78
79
  // packages/sdk/client-services/src/packlets/services/service-host.ts
79
- var import_node_assert12 = __toESM(require("node:assert"));
80
- var import_async19 = require("@dxos/async");
80
+ var import_node_assert13 = __toESM(require("node:assert"));
81
+ var import_async18 = require("@dxos/async");
81
82
  var import_client8 = require("@dxos/client");
82
- var import_debug7 = require("@dxos/debug");
83
83
  var import_echo_pipeline5 = require("@dxos/echo-pipeline");
84
84
  var import_log16 = require("@dxos/log");
85
85
  var import_protocols7 = require("@dxos/protocols");
86
- var import_services8 = require("@dxos/protocols/proto/dxos/client/services");
86
+ var import_services9 = require("@dxos/protocols/proto/dxos/client/services");
87
87
 
88
88
  // packages/sdk/client-services/src/packlets/deprecated/tracing.ts
89
89
  var TracingServiceImpl = class {
@@ -698,10 +698,11 @@ var IdentityManager = class {
698
698
  async open() {
699
699
  var _a;
700
700
  import_log3.log.trace("dxos.halo.identity-manager", import_protocols2.trace.begin({
701
- id: this._instanceId
701
+ id: this._instanceId,
702
+ parentId: this._traceParent
702
703
  }), {
703
704
  file: "identity-manager.ts",
704
- line: 71,
705
+ line: 72,
705
706
  scope: this,
706
707
  callSite: (f, a) => f(...a)
707
708
  });
@@ -711,7 +712,7 @@ var IdentityManager = class {
711
712
  identityRecord
712
713
  }, {
713
714
  file: "identity-manager.ts",
714
- line: 75,
715
+ line: 76,
715
716
  scope: this,
716
717
  callSite: (f, a) => f(...a)
717
718
  });
@@ -724,7 +725,7 @@ var IdentityManager = class {
724
725
  displayName: (_a = this._identity.profileDocument) == null ? void 0 : _a.displayName
725
726
  }, {
726
727
  file: "identity-manager.ts",
727
- line: 80,
728
+ line: 81,
728
729
  scope: this,
729
730
  callSite: (f, a) => f(...a)
730
731
  });
@@ -738,7 +739,7 @@ var IdentityManager = class {
738
739
  id: this._instanceId
739
740
  }), {
740
741
  file: "identity-manager.ts",
741
- line: 90,
742
+ line: 91,
742
743
  scope: this,
743
744
  callSite: (f, a) => f(...a)
744
745
  });
@@ -748,7 +749,7 @@ var IdentityManager = class {
748
749
  (0, import_node_assert2.default)(!this._identity, "Identity already exists.");
749
750
  (0, import_log3.log)("creating identity...", {}, {
750
751
  file: "identity-manager.ts",
751
- line: 95,
752
+ line: 96,
752
753
  scope: this,
753
754
  callSite: (f, a) => f(...a)
754
755
  });
@@ -797,7 +798,7 @@ var IdentityManager = class {
797
798
  displayName: (_a = this._identity.profileDocument) == null ? void 0 : _a.displayName
798
799
  }, {
799
800
  file: "identity-manager.ts",
800
- line: 150,
801
+ line: 151,
801
802
  scope: this,
802
803
  callSite: (f, a) => f(...a)
803
804
  });
@@ -807,7 +808,7 @@ var IdentityManager = class {
807
808
  deviceKey: identity.deviceKey
808
809
  }, {
809
810
  file: "identity-manager.ts",
810
- line: 156,
811
+ line: 157,
811
812
  scope: this,
812
813
  callSite: (f, a) => f(...a)
813
814
  });
@@ -822,7 +823,7 @@ var IdentityManager = class {
822
823
  params
823
824
  }, {
824
825
  file: "identity-manager.ts",
825
- line: 164,
826
+ line: 165,
826
827
  scope: this,
827
828
  callSite: (f, a) => f(...a)
828
829
  });
@@ -848,7 +849,7 @@ var IdentityManager = class {
848
849
  displayName: (_a = this._identity.profileDocument) == null ? void 0 : _a.displayName
849
850
  }, {
850
851
  file: "identity-manager.ts",
851
- line: 184,
852
+ line: 185,
852
853
  scope: this,
853
854
  callSite: (f, a) => f(...a)
854
855
  });
@@ -858,7 +859,7 @@ var IdentityManager = class {
858
859
  deviceKey: identity.deviceKey
859
860
  }, {
860
861
  file: "identity-manager.ts",
861
- line: 190,
862
+ line: 191,
862
863
  scope: this,
863
864
  callSite: (f, a) => f(...a)
864
865
  });
@@ -870,7 +871,7 @@ var IdentityManager = class {
870
871
  identityRecord
871
872
  }, {
872
873
  file: "identity-manager.ts",
873
- line: 196,
874
+ line: 197,
874
875
  scope: this,
875
876
  callSite: (f, a) => f(...a)
876
877
  });
@@ -903,7 +904,7 @@ var IdentityManager = class {
903
904
  identityKey: identityRecord.identityKey
904
905
  }, {
905
906
  file: "identity-manager.ts",
906
- line: 224,
907
+ line: 225,
907
908
  scope: this,
908
909
  callSite: (f, a) => f(...a)
909
910
  });
@@ -973,8 +974,73 @@ var IdentityServiceImpl = class {
973
974
  }
974
975
  };
975
976
 
976
- // packages/sdk/client-services/src/packlets/invitations/device-invitations-handler.ts
977
+ // packages/sdk/client-services/src/packlets/invitations/device-invitation-protocol.ts
977
978
  var import_node_assert4 = __toESM(require("node:assert"));
979
+ var import_services2 = require("@dxos/protocols/proto/dxos/client/services");
980
+ var DeviceInvitationProtocol = class {
981
+ constructor(_keyring, _getIdentity, _acceptIdentity) {
982
+ this._keyring = _keyring;
983
+ this._getIdentity = _getIdentity;
984
+ this._acceptIdentity = _acceptIdentity;
985
+ }
986
+ toJSON() {
987
+ return {};
988
+ }
989
+ getInvitationContext() {
990
+ return {
991
+ kind: import_services2.Invitation.Kind.DEVICE
992
+ };
993
+ }
994
+ async admit(request) {
995
+ (0, import_node_assert4.default)(request.device);
996
+ const identity = this._getIdentity();
997
+ await identity.admitDevice(request.device);
998
+ return {
999
+ device: {
1000
+ identityKey: identity.identityKey,
1001
+ haloSpaceKey: identity.haloSpaceKey,
1002
+ genesisFeedKey: identity.haloGenesisFeedKey,
1003
+ controlTimeframe: identity.controlPipeline.state.timeframe
1004
+ }
1005
+ };
1006
+ }
1007
+ createIntroduction() {
1008
+ return {};
1009
+ }
1010
+ async createAdmissionRequest() {
1011
+ const deviceKey = await this._keyring.createKey();
1012
+ const controlFeedKey = await this._keyring.createKey();
1013
+ const dataFeedKey = await this._keyring.createKey();
1014
+ return {
1015
+ device: {
1016
+ deviceKey,
1017
+ controlFeedKey,
1018
+ dataFeedKey
1019
+ }
1020
+ };
1021
+ }
1022
+ async accept(response, request) {
1023
+ (0, import_node_assert4.default)(response.device);
1024
+ const { identityKey, haloSpaceKey, genesisFeedKey, controlTimeframe } = response.device;
1025
+ (0, import_node_assert4.default)(request.device);
1026
+ const { deviceKey, controlFeedKey, dataFeedKey } = request.device;
1027
+ await this._acceptIdentity({
1028
+ identityKey,
1029
+ deviceKey,
1030
+ haloSpaceKey,
1031
+ haloGenesisFeedKey: genesisFeedKey,
1032
+ controlFeedKey,
1033
+ dataFeedKey,
1034
+ controlTimeframe
1035
+ });
1036
+ return {
1037
+ identityKey
1038
+ };
1039
+ }
1040
+ };
1041
+
1042
+ // packages/sdk/client-services/src/packlets/invitations/invitations-handler.ts
1043
+ var import_node_assert5 = __toESM(require("node:assert"));
978
1044
  var import_async7 = require("@dxos/async");
979
1045
  var import_client = require("@dxos/client");
980
1046
  var import_context3 = require("@dxos/context");
@@ -983,141 +1049,206 @@ var import_keys6 = require("@dxos/keys");
983
1049
  var import_log4 = require("@dxos/log");
984
1050
  var import_network_manager = require("@dxos/network-manager");
985
1051
  var import_protocols3 = require("@dxos/protocols");
986
- var import_services2 = require("@dxos/protocols/proto/dxos/client/services");
1052
+ var import_services3 = require("@dxos/protocols/proto/dxos/client/services");
987
1053
  var import_invitations = require("@dxos/protocols/proto/dxos/halo/invitations");
988
1054
  var import_teleport = require("@dxos/teleport");
989
- var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHandler {
990
- // prettier-ignore
991
- constructor(_params) {
992
- super(_params.networkManager);
993
- this._params = _params;
1055
+ var MAX_OTP_ATTEMPTS = 3;
1056
+ var InvitationsHandler = class {
1057
+ constructor(_networkManager) {
1058
+ this._networkManager = _networkManager;
994
1059
  }
995
- /**
996
- * Creates an invitation and listens for a join request from the invited (guest) peer.
997
- */
998
- createInvitation(context, options) {
999
- const { type, timeout = import_client.INVITATION_TIMEOUT, swarmKey } = options != null ? options : {};
1000
- (0, import_node_assert4.default)(type !== import_services2.Invitation.Type.OFFLINE);
1001
- const identity = this._params.getIdentity();
1060
+ createInvitation(protocol, options) {
1061
+ var _a;
1062
+ const { invitationId = import_keys6.PublicKey.random().toHex(), type = import_services3.Invitation.Type.INTERACTIVE, authMethod = import_services3.Invitation.AuthMethod.SHARED_SECRET, state = import_services3.Invitation.State.INIT, timeout = import_client.INVITATION_TIMEOUT, swarmKey = import_keys6.PublicKey.random() } = options != null ? options : {};
1063
+ const authCode = (_a = options == null ? void 0 : options.authCode) != null ? _a : authMethod === import_services3.Invitation.AuthMethod.SHARED_SECRET ? (0, import_credentials8.generatePasscode)(import_client.AUTHENTICATION_CODE_LENGTH) : void 0;
1064
+ (0, import_node_assert5.default)(protocol);
1002
1065
  const invitation = {
1066
+ invitationId,
1003
1067
  type,
1004
- invitationId: import_keys6.PublicKey.random().toHex(),
1005
- swarmKey: swarmKey != null ? swarmKey : import_keys6.PublicKey.random(),
1006
- authenticationCode: (0, import_credentials8.generatePasscode)(import_client.AUTHENTICATION_CODE_LENGTH)
1068
+ authMethod,
1069
+ state,
1070
+ swarmKey,
1071
+ authCode,
1072
+ timeout,
1073
+ ...protocol.getInvitationContext()
1007
1074
  };
1075
+ const stream = new import_async7.PushStream();
1008
1076
  const ctx = new import_context3.Context({
1009
1077
  onError: (err) => {
1010
1078
  void ctx.dispose();
1011
- observable.callback.onError(err);
1079
+ stream.error(err);
1012
1080
  }
1013
1081
  });
1014
- const observable = new import_client.InvitationObservableProvider(async () => {
1015
- await ctx.dispose();
1082
+ ctx.onDispose(() => {
1083
+ (0, import_log4.log)("complete", {
1084
+ ...protocol.toJSON()
1085
+ }, {
1086
+ file: "invitations-handler.ts",
1087
+ line: 102,
1088
+ scope: this,
1089
+ callSite: (f, a) => f(...a)
1090
+ });
1091
+ stream.complete();
1016
1092
  });
1017
- let authenticationCode;
1018
- const complete = new import_async7.Trigger();
1019
- const createExtension = () => new HostHaloInvitationExtension({
1020
- requestAdmission: async () => {
1021
- var _a, _b;
1022
- (0, import_log4.log)("responding with admission offer", {
1023
- host: identity.deviceKey
1024
- }, {
1025
- file: "device-invitations-handler.ts",
1026
- line: 92,
1027
- scope: this,
1028
- callSite: (f, a) => f(...a)
1029
- });
1030
- (_b = (_a = observable.callback).onAuthenticating) == null ? void 0 : _b.call(_a, invitation);
1031
- return {
1032
- identityKey: identity.identityKey,
1033
- haloSpaceKey: identity.haloSpaceKey,
1034
- genesisFeedKey: identity.haloGenesisFeedKey,
1035
- controlTimeframe: identity.controlPipeline.state.timeframe
1036
- };
1037
- },
1038
- authenticate: async ({ authenticationCode: code }) => {
1039
- (0, import_log4.log)("received authentication request", {
1040
- authenticationCode: code
1041
- }, {
1042
- file: "device-invitations-handler.ts",
1043
- line: 107,
1044
- scope: this,
1045
- callSite: (f, a) => f(...a)
1046
- });
1047
- authenticationCode = code;
1048
- return {
1049
- status: import_invitations.AuthenticationResponse.Status.OK
1050
- };
1051
- },
1052
- // TODO(burdon): Not used: controlFeedKey, dataFeedKey.
1053
- presentAdmissionCredentials: async (credentials) => {
1054
- try {
1055
- if (invitation.type !== import_services2.Invitation.Type.INTERACTIVE_TESTING) {
1056
- if (invitation.authenticationCode === void 0 || invitation.authenticationCode !== authenticationCode) {
1057
- throw new Error(`invalid authentication code: ${authenticationCode}`);
1058
- }
1059
- }
1060
- (0, import_log4.log)("writing guest credentials", {
1061
- host: identity.deviceKey,
1062
- guest: credentials.deviceKey
1093
+ const createExtension = () => {
1094
+ const success = new import_async7.Trigger();
1095
+ let guestProfile;
1096
+ let authenticationPassed = false;
1097
+ let authenticationRetry = 0;
1098
+ const extension = new InvitationHostExtension({
1099
+ introduce: async ({ profile }) => {
1100
+ (0, import_log4.log)("guest introduced itself", {
1101
+ guestProfile: profile,
1102
+ ...protocol.toJSON()
1063
1103
  }, {
1064
- file: "device-invitations-handler.ts",
1065
- line: 122,
1104
+ file: "invitations-handler.ts",
1105
+ line: 115,
1066
1106
  scope: this,
1067
1107
  callSite: (f, a) => f(...a)
1068
1108
  });
1069
- await identity.admitDevice(credentials);
1070
- complete.wake(credentials.deviceKey);
1071
- } catch (err) {
1072
- observable.callback.onError(err);
1073
- throw err;
1074
- }
1075
- },
1076
- onOpen: () => {
1077
- (0, import_async7.scheduleTask)(ctx, async () => {
1078
- var _a, _b;
1109
+ guestProfile = profile;
1110
+ stream.next({
1111
+ ...invitation,
1112
+ state: import_services3.Invitation.State.READY_FOR_AUTHENTICATION
1113
+ });
1114
+ return {
1115
+ spaceKey: authMethod === import_services3.Invitation.AuthMethod.NONE ? protocol.getInvitationContext().spaceKey : void 0,
1116
+ authMethod
1117
+ };
1118
+ },
1119
+ authenticate: async ({ authCode: code }) => {
1120
+ (0, import_log4.log)("received authentication request", {
1121
+ authCode: code
1122
+ }, {
1123
+ file: "invitations-handler.ts",
1124
+ line: 134,
1125
+ scope: this,
1126
+ callSite: (f, a) => f(...a)
1127
+ });
1128
+ let status = import_invitations.AuthenticationResponse.Status.OK;
1129
+ switch (invitation.authMethod) {
1130
+ case import_services3.Invitation.AuthMethod.NONE: {
1131
+ (0, import_log4.log)("authentication not required", {}, {
1132
+ file: "invitations-handler.ts",
1133
+ line: 139,
1134
+ scope: this,
1135
+ callSite: (f, a) => f(...a)
1136
+ });
1137
+ return {
1138
+ status: import_invitations.AuthenticationResponse.Status.OK
1139
+ };
1140
+ }
1141
+ case import_services3.Invitation.AuthMethod.SHARED_SECRET: {
1142
+ if (invitation.authCode) {
1143
+ if (authenticationRetry++ > MAX_OTP_ATTEMPTS) {
1144
+ status = import_invitations.AuthenticationResponse.Status.INVALID_OPT_ATTEMPTS;
1145
+ } else if (code !== invitation.authCode) {
1146
+ status = import_invitations.AuthenticationResponse.Status.INVALID_OTP;
1147
+ } else {
1148
+ authenticationPassed = true;
1149
+ }
1150
+ }
1151
+ break;
1152
+ }
1153
+ default: {
1154
+ import_log4.log.error("invalid authentication method", {
1155
+ authMethod: invitation.authMethod
1156
+ }, {
1157
+ file: "invitations-handler.ts",
1158
+ line: 157,
1159
+ scope: this,
1160
+ callSite: (f, a) => f(...a)
1161
+ });
1162
+ status = import_invitations.AuthenticationResponse.Status.INTERNAL_ERROR;
1163
+ break;
1164
+ }
1165
+ }
1166
+ return {
1167
+ status
1168
+ };
1169
+ },
1170
+ admit: async (admissionRequest) => {
1171
+ var _a2, _b, _c;
1079
1172
  try {
1080
- (0, import_log4.log)("connected", {
1081
- host: identity.deviceKey
1082
- }, {
1083
- file: "device-invitations-handler.ts",
1084
- line: 138,
1085
- scope: this,
1086
- callSite: (f, a) => f(...a)
1087
- });
1088
- (_b = (_a = observable.callback).onConnected) == null ? void 0 : _b.call(_a, invitation);
1089
- const deviceKey = await complete.wait({
1090
- timeout
1091
- });
1092
- (0, import_log4.log)("admitted guest", {
1093
- host: identity.deviceKey,
1094
- guest: deviceKey
1095
- }, {
1096
- file: "device-invitations-handler.ts",
1097
- line: 141,
1098
- scope: this,
1099
- callSite: (f, a) => f(...a)
1100
- });
1101
- observable.callback.onSuccess(invitation);
1173
+ if (isAuthenticationRequired(invitation) && !authenticationPassed) {
1174
+ throw new Error("Not authenticated");
1175
+ }
1176
+ const deviceKey = (_c = (_a2 = admissionRequest.device) == null ? void 0 : _a2.deviceKey) != null ? _c : (_b = admissionRequest.space) == null ? void 0 : _b.deviceKey;
1177
+ (0, import_node_assert5.default)(deviceKey);
1178
+ const admissionResponse = await protocol.admit(admissionRequest, guestProfile);
1179
+ success.wake(deviceKey);
1180
+ return admissionResponse;
1102
1181
  } catch (err) {
1103
- if (!observable.cancelled) {
1104
- import_log4.log.error("failed", err, {
1105
- file: "device-invitations-handler.ts",
1106
- line: 145,
1182
+ stream.error(err);
1183
+ throw err;
1184
+ }
1185
+ },
1186
+ onOpen: () => {
1187
+ (0, import_async7.scheduleTask)(ctx, async () => {
1188
+ try {
1189
+ (0, import_log4.log)("connected", {
1190
+ ...protocol.toJSON()
1191
+ }, {
1192
+ file: "invitations-handler.ts",
1193
+ line: 191,
1194
+ scope: this,
1195
+ callSite: (f, a) => f(...a)
1196
+ });
1197
+ stream.next({
1198
+ ...invitation,
1199
+ state: import_services3.Invitation.State.CONNECTED
1200
+ });
1201
+ const deviceKey = await success.wait({
1202
+ timeout
1203
+ });
1204
+ (0, import_log4.log)("admitted guest", {
1205
+ guest: deviceKey,
1206
+ ...protocol.toJSON()
1207
+ }, {
1208
+ file: "invitations-handler.ts",
1209
+ line: 194,
1107
1210
  scope: this,
1108
1211
  callSite: (f, a) => f(...a)
1109
1212
  });
1110
- observable.callback.onError(err);
1213
+ stream.next({
1214
+ ...invitation,
1215
+ state: import_services3.Invitation.State.SUCCESS
1216
+ });
1217
+ } catch (err) {
1218
+ if (err instanceof import_async7.TimeoutError) {
1219
+ (0, import_log4.log)("timeout", {
1220
+ ...protocol.toJSON()
1221
+ }, {
1222
+ file: "invitations-handler.ts",
1223
+ line: 198,
1224
+ scope: this,
1225
+ callSite: (f, a) => f(...a)
1226
+ });
1227
+ stream.next({
1228
+ ...invitation,
1229
+ state: import_services3.Invitation.State.TIMEOUT
1230
+ });
1231
+ } else {
1232
+ import_log4.log.error("failed", err, {
1233
+ file: "invitations-handler.ts",
1234
+ line: 201,
1235
+ scope: this,
1236
+ callSite: (f, a) => f(...a)
1237
+ });
1238
+ stream.error(err);
1239
+ }
1240
+ } finally {
1241
+ if (type !== import_services3.Invitation.Type.MULTIUSE) {
1242
+ await (0, import_async7.sleep)(import_client.ON_CLOSE_DELAY);
1243
+ await ctx.dispose();
1244
+ }
1111
1245
  }
1112
- } finally {
1113
- await (0, import_async7.sleep)(import_client.ON_CLOSE_DELAY);
1114
- await ctx.dispose();
1115
- }
1116
- });
1117
- }
1118
- });
1246
+ });
1247
+ }
1248
+ });
1249
+ return extension;
1250
+ };
1119
1251
  (0, import_async7.scheduleTask)(ctx, async () => {
1120
- var _a, _b;
1121
1252
  const topic = invitation.swarmKey;
1122
1253
  const swarmConnection = await this._networkManager.joinSwarm({
1123
1254
  topic,
@@ -1128,126 +1259,210 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
1128
1259
  topology: new import_network_manager.StarTopology(topic)
1129
1260
  });
1130
1261
  ctx.onDispose(() => swarmConnection.close());
1131
- (_b = (_a = observable.callback).onConnecting) == null ? void 0 : _b.call(_a, invitation);
1262
+ stream.next({
1263
+ ...invitation,
1264
+ state: import_services3.Invitation.State.CONNECTING
1265
+ });
1266
+ });
1267
+ const observable = new import_client.CancellableInvitationObservable({
1268
+ initialInvitation: invitation,
1269
+ subscriber: stream.observable,
1270
+ onCancel: async () => {
1271
+ stream.next({
1272
+ ...invitation,
1273
+ state: import_services3.Invitation.State.CANCELLED
1274
+ });
1275
+ await ctx.dispose();
1276
+ }
1132
1277
  });
1133
1278
  return observable;
1134
1279
  }
1135
- /**
1136
- * Waits for the host peer (inviter) to accept our join request.
1137
- * The local guest peer (invitee) then sends the local halo invitation to the host,
1138
- * which then writes the guest's credentials to the halo.
1139
- */
1140
- acceptInvitation(invitation, options) {
1141
- const { timeout = import_client.INVITATION_TIMEOUT } = options != null ? options : {};
1280
+ acceptInvitation(protocol, invitation) {
1281
+ const { timeout = import_client.INVITATION_TIMEOUT } = invitation;
1282
+ (0, import_node_assert5.default)(protocol);
1283
+ const authenticated = new import_async7.Trigger();
1284
+ const stream = new import_async7.PushStream();
1142
1285
  const ctx = new import_context3.Context({
1143
1286
  onError: (err) => {
1287
+ if (err instanceof import_async7.TimeoutError) {
1288
+ (0, import_log4.log)("timeout", {
1289
+ ...protocol.toJSON()
1290
+ }, {
1291
+ file: "invitations-handler.ts",
1292
+ line: 255,
1293
+ scope: this,
1294
+ callSite: (f, a) => f(...a)
1295
+ });
1296
+ stream.next({
1297
+ ...invitation,
1298
+ state: import_services3.Invitation.State.TIMEOUT
1299
+ });
1300
+ } else {
1301
+ import_log4.log.warn("auth failed", err, {
1302
+ file: "invitations-handler.ts",
1303
+ line: 258,
1304
+ scope: this,
1305
+ callSite: (f, a) => f(...a)
1306
+ });
1307
+ stream.error(err);
1308
+ }
1144
1309
  void ctx.dispose();
1145
- observable.callback.onError(err);
1146
1310
  }
1147
1311
  });
1148
- const authenticated = new import_async7.Trigger();
1149
- const observable = new import_client.AuthenticatingInvitationProvider({
1150
- onCancel: async () => {
1151
- await ctx.dispose();
1152
- },
1153
- // TODO(burdon): Consider retry.
1154
- onAuthenticate: async (code) => {
1155
- authenticated.wake(code);
1156
- }
1312
+ ctx.onDispose(() => {
1313
+ (0, import_log4.log)("complete", {
1314
+ ...protocol.toJSON()
1315
+ }, {
1316
+ file: "invitations-handler.ts",
1317
+ line: 266,
1318
+ scope: this,
1319
+ callSite: (f, a) => f(...a)
1320
+ });
1321
+ stream.complete();
1157
1322
  });
1158
- let connectionCount = 0;
1159
- const complete = new import_async7.Trigger();
1160
1323
  const createExtension = () => {
1161
- const extension = new GuestHaloInvitationExtension({
1324
+ let connectionCount = 0;
1325
+ const extension = new InvitationGuestExtension({
1162
1326
  onOpen: () => {
1163
1327
  (0, import_async7.scheduleTask)(ctx, async () => {
1164
- var _a, _b, _c, _d;
1165
1328
  try {
1166
1329
  if (++connectionCount > 1) {
1167
1330
  throw new Error(`multiple connections detected: ${connectionCount}`);
1168
1331
  }
1169
- (0, import_log4.log)("connected", {}, {
1170
- file: "device-invitations-handler.ts",
1171
- line: 216,
1332
+ (0, import_async7.scheduleTask)(ctx, () => ctx.raise(new import_async7.TimeoutError(timeout)), timeout);
1333
+ (0, import_log4.log)("connected", {
1334
+ ...protocol.toJSON()
1335
+ }, {
1336
+ file: "invitations-handler.ts",
1337
+ line: 284,
1172
1338
  scope: this,
1173
1339
  callSite: (f, a) => f(...a)
1174
1340
  });
1175
- (_b = (_a = observable.callback).onConnected) == null ? void 0 : _b.call(_a, invitation);
1176
- (0, import_log4.log)("sending admission request", {}, {
1177
- file: "device-invitations-handler.ts",
1178
- line: 220,
1341
+ stream.next({
1342
+ ...invitation,
1343
+ state: import_services3.Invitation.State.CONNECTED
1344
+ });
1345
+ (0, import_log4.log)("introduce", {
1346
+ ...protocol.toJSON()
1347
+ }, {
1348
+ file: "invitations-handler.ts",
1349
+ line: 288,
1179
1350
  scope: this,
1180
1351
  callSite: (f, a) => f(...a)
1181
1352
  });
1182
- const { identityKey, haloSpaceKey, genesisFeedKey, controlTimeframe } = await extension.rpc.HaloHostService.requestAdmission();
1183
- if (invitation.type === void 0 || invitation.type === import_services2.Invitation.Type.INTERACTIVE) {
1184
- (0, import_log4.log)("guest waiting for authentication code...", {}, {
1185
- file: "device-invitations-handler.ts",
1186
- line: 227,
1187
- scope: this,
1188
- callSite: (f, a) => f(...a)
1189
- });
1190
- (_d = (_c = observable.callback).onAuthenticating) == null ? void 0 : _d.call(_c, invitation);
1191
- const authenticationCode = await authenticated.wait({
1192
- timeout
1193
- });
1194
- (0, import_log4.log)("sending authentication request", {}, {
1195
- file: "device-invitations-handler.ts",
1196
- line: 230,
1197
- scope: this,
1198
- callSite: (f, a) => f(...a)
1199
- });
1200
- await extension.rpc.HaloHostService.authenticate({
1201
- authenticationCode
1353
+ const introductionResponse = await extension.rpc.InvitationHostService.introduce(protocol.createIntroduction());
1354
+ (0, import_log4.log)("introduce response", {
1355
+ ...protocol.toJSON(),
1356
+ response: introductionResponse
1357
+ }, {
1358
+ file: "invitations-handler.ts",
1359
+ line: 292,
1360
+ scope: this,
1361
+ callSite: (f, a) => f(...a)
1362
+ });
1363
+ invitation.authMethod = introductionResponse.authMethod;
1364
+ if (introductionResponse.spaceKey) {
1365
+ invitation.spaceKey = introductionResponse.spaceKey;
1366
+ }
1367
+ if (isAuthenticationRequired(invitation)) {
1368
+ for (let attempt = 1; attempt <= MAX_OTP_ATTEMPTS; attempt++) {
1369
+ (0, import_log4.log)("guest waiting for authentication code...", {}, {
1370
+ file: "invitations-handler.ts",
1371
+ line: 301,
1372
+ scope: this,
1373
+ callSite: (f, a) => f(...a)
1374
+ });
1375
+ stream.next({
1376
+ ...invitation,
1377
+ state: import_services3.Invitation.State.READY_FOR_AUTHENTICATION
1378
+ });
1379
+ const authCode = await authenticated.wait({
1380
+ timeout
1381
+ });
1382
+ (0, import_log4.log)("sending authentication request", {}, {
1383
+ file: "invitations-handler.ts",
1384
+ line: 305,
1385
+ scope: this,
1386
+ callSite: (f, a) => f(...a)
1387
+ });
1388
+ stream.next({
1389
+ ...invitation,
1390
+ state: import_services3.Invitation.State.AUTHENTICATING
1391
+ });
1392
+ const response = await extension.rpc.InvitationHostService.authenticate({
1393
+ authCode
1394
+ });
1395
+ if (response.status === void 0 || response.status === import_invitations.AuthenticationResponse.Status.OK) {
1396
+ break;
1397
+ }
1398
+ if (response.status === import_invitations.AuthenticationResponse.Status.INVALID_OTP) {
1399
+ if (attempt === MAX_OTP_ATTEMPTS) {
1400
+ throw new Error(`Maximum retry attempts: ${MAX_OTP_ATTEMPTS}`);
1401
+ } else {
1402
+ (0, import_log4.log)("retrying invalid code", {
1403
+ attempt
1404
+ }, {
1405
+ file: "invitations-handler.ts",
1406
+ line: 316,
1407
+ scope: this,
1408
+ callSite: (f, a) => f(...a)
1409
+ });
1410
+ authenticated.reset();
1411
+ }
1412
+ }
1413
+ }
1414
+ } else {
1415
+ stream.next({
1416
+ ...invitation,
1417
+ state: import_services3.Invitation.State.READY_FOR_AUTHENTICATION
1202
1418
  });
1203
1419
  }
1204
- const deviceKey = await this._params.keyring.createKey();
1205
- const controlFeedKey = await this._params.keyring.createKey();
1206
- const dataFeedKey = await this._params.keyring.createKey();
1207
- (0, import_log4.log)("presenting admission credentials", {
1208
- identityKey,
1209
- deviceKey,
1210
- controlFeedKey,
1211
- dataFeedKey
1420
+ (0, import_log4.log)("request admission", {
1421
+ ...protocol.toJSON()
1212
1422
  }, {
1213
- file: "device-invitations-handler.ts",
1214
- line: 239,
1423
+ file: "invitations-handler.ts",
1424
+ line: 327,
1215
1425
  scope: this,
1216
1426
  callSite: (f, a) => f(...a)
1217
1427
  });
1218
- await extension.rpc.HaloHostService.presentAdmissionCredentials({
1219
- deviceKey,
1220
- controlFeedKey,
1221
- dataFeedKey
1222
- });
1223
- const identity = await this._params.acceptIdentity({
1224
- identityKey,
1225
- deviceKey,
1226
- haloSpaceKey,
1227
- haloGenesisFeedKey: genesisFeedKey,
1228
- controlFeedKey,
1229
- dataFeedKey,
1230
- controlTimeframe
1231
- });
1428
+ const admissionRequest = await protocol.createAdmissionRequest();
1429
+ const admissionResponse = await extension.rpc.InvitationHostService.admit(admissionRequest);
1430
+ const result = await protocol.accept(admissionResponse, admissionRequest);
1232
1431
  (0, import_log4.log)("admitted by host", {
1233
- guest: identity.deviceKey,
1234
- identityKey
1432
+ ...protocol.toJSON()
1235
1433
  }, {
1236
- file: "device-invitations-handler.ts",
1237
- line: 259,
1434
+ file: "invitations-handler.ts",
1435
+ line: 335,
1238
1436
  scope: this,
1239
1437
  callSite: (f, a) => f(...a)
1240
1438
  });
1241
- complete.wake(identityKey);
1439
+ stream.next({
1440
+ ...invitation,
1441
+ ...result,
1442
+ state: import_services3.Invitation.State.SUCCESS
1443
+ });
1242
1444
  } catch (err) {
1243
- if (!observable.cancelled) {
1445
+ if (err instanceof import_async7.TimeoutError) {
1446
+ (0, import_log4.log)("timeout", {
1447
+ ...protocol.toJSON()
1448
+ }, {
1449
+ file: "invitations-handler.ts",
1450
+ line: 339,
1451
+ scope: this,
1452
+ callSite: (f, a) => f(...a)
1453
+ });
1454
+ stream.next({
1455
+ ...invitation,
1456
+ state: import_services3.Invitation.State.TIMEOUT
1457
+ });
1458
+ } else {
1244
1459
  import_log4.log.warn("auth failed", err, {
1245
- file: "device-invitations-handler.ts",
1246
- line: 263,
1460
+ file: "invitations-handler.ts",
1461
+ line: 342,
1247
1462
  scope: this,
1248
1463
  callSite: (f, a) => f(...a)
1249
1464
  });
1250
- observable.callback.onError(err);
1465
+ stream.error(err);
1251
1466
  }
1252
1467
  } finally {
1253
1468
  await ctx.dispose();
@@ -1258,8 +1473,7 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
1258
1473
  return extension;
1259
1474
  };
1260
1475
  (0, import_async7.scheduleTask)(ctx, async () => {
1261
- var _a, _b;
1262
- (0, import_node_assert4.default)(invitation.swarmKey);
1476
+ (0, import_node_assert5.default)(invitation.swarmKey);
1263
1477
  const topic = invitation.swarmKey;
1264
1478
  const swarmConnection = await this._networkManager.joinSwarm({
1265
1479
  topic,
@@ -1270,19 +1484,34 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
1270
1484
  topology: new import_network_manager.StarTopology(topic)
1271
1485
  });
1272
1486
  ctx.onDispose(() => swarmConnection.close());
1273
- (_b = (_a = observable.callback).onConnecting) == null ? void 0 : _b.call(_a, invitation);
1274
- invitation.identityKey = await complete.wait();
1275
- observable.callback.onSuccess(invitation);
1276
- await ctx.dispose();
1487
+ stream.next({
1488
+ ...invitation,
1489
+ state: import_services3.Invitation.State.CONNECTING
1490
+ });
1491
+ });
1492
+ const observable = new import_client.AuthenticatingInvitationObservable({
1493
+ initialInvitation: invitation,
1494
+ subscriber: stream.observable,
1495
+ onCancel: async () => {
1496
+ stream.next({
1497
+ ...invitation,
1498
+ state: import_services3.Invitation.State.CANCELLED
1499
+ });
1500
+ await ctx.dispose();
1501
+ },
1502
+ onAuthenticate: async (code) => {
1503
+ authenticated.wake(code);
1504
+ }
1277
1505
  });
1278
1506
  return observable;
1279
1507
  }
1280
1508
  };
1281
- var HostHaloInvitationExtension = class extends import_teleport.RpcExtension {
1509
+ var isAuthenticationRequired = (invitation) => invitation.authMethod !== import_services3.Invitation.AuthMethod.NONE;
1510
+ var InvitationHostExtension = class extends import_teleport.RpcExtension {
1282
1511
  constructor(_callbacks) {
1283
1512
  super({
1284
1513
  exposed: {
1285
- HaloHostService: import_protocols3.schema.getService("dxos.halo.invitations.HaloHostService")
1514
+ InvitationHostService: import_protocols3.schema.getService("dxos.halo.invitations.InvitationHostService")
1286
1515
  }
1287
1516
  });
1288
1517
  this._callbacks = _callbacks;
@@ -1291,16 +1520,15 @@ var HostHaloInvitationExtension = class extends import_teleport.RpcExtension {
1291
1520
  return {
1292
1521
  // TODO(dmaretskyi): For now this is just forwarding the data to callbacks since we don't have session-specific logic.
1293
1522
  // Perhaps in the future we will have more complex logic here.
1294
- HaloHostService: {
1295
- requestAdmission: async () => {
1296
- return this._callbacks.requestAdmission();
1523
+ InvitationHostService: {
1524
+ introduce: async (request) => {
1525
+ return this._callbacks.introduce(request);
1297
1526
  },
1298
- authenticate: async (credentials) => {
1299
- return this._callbacks.authenticate(credentials);
1527
+ authenticate: async (request) => {
1528
+ return this._callbacks.authenticate(request);
1300
1529
  },
1301
- // TODO(burdon): Not used: controlFeedKey, dataFeedKey.
1302
- presentAdmissionCredentials: async (credentials) => {
1303
- return this._callbacks.presentAdmissionCredentials(credentials);
1530
+ admit: async (request) => {
1531
+ return this._callbacks.admit(request);
1304
1532
  }
1305
1533
  }
1306
1534
  };
@@ -1310,11 +1538,11 @@ var HostHaloInvitationExtension = class extends import_teleport.RpcExtension {
1310
1538
  this._callbacks.onOpen();
1311
1539
  }
1312
1540
  };
1313
- var GuestHaloInvitationExtension = class extends import_teleport.RpcExtension {
1541
+ var InvitationGuestExtension = class extends import_teleport.RpcExtension {
1314
1542
  constructor(_callbacks) {
1315
1543
  super({
1316
1544
  requested: {
1317
- HaloHostService: import_protocols3.schema.getService("dxos.halo.invitations.HaloHostService")
1545
+ InvitationHostService: import_protocols3.schema.getService("dxos.halo.invitations.InvitationHostService")
1318
1546
  }
1319
1547
  });
1320
1548
  this._callbacks = _callbacks;
@@ -1329,98 +1557,102 @@ var GuestHaloInvitationExtension = class extends import_teleport.RpcExtension {
1329
1557
  };
1330
1558
 
1331
1559
  // packages/sdk/client-services/src/packlets/invitations/invitations-service.ts
1332
- var import_node_assert5 = __toESM(require("node:assert"));
1560
+ var import_node_assert6 = __toESM(require("node:assert"));
1333
1561
  var import_codec_protobuf8 = require("@dxos/codec-protobuf");
1334
1562
  var import_log5 = require("@dxos/log");
1335
- var import_services3 = require("@dxos/protocols/proto/dxos/client/services");
1336
- var AbstractInvitationsService = class {
1337
- // prettier-ignore
1338
- constructor(_identityManager, _getInvitationsHandler) {
1339
- this._identityManager = _identityManager;
1340
- this._getInvitationsHandler = _getInvitationsHandler;
1563
+ var import_services4 = require("@dxos/protocols/proto/dxos/client/services");
1564
+ var InvitationsServiceImpl = class {
1565
+ constructor(_invitationsHandler, _getHandler) {
1566
+ this._invitationsHandler = _invitationsHandler;
1567
+ this._getHandler = _getHandler;
1341
1568
  this._createInvitations = /* @__PURE__ */ new Map();
1342
1569
  this._acceptInvitations = /* @__PURE__ */ new Map();
1343
1570
  }
1344
1571
  // TODO(burdon): Guest/host label.
1345
1572
  getLoggingContext() {
1346
- var _a;
1347
- return {
1348
- deviceKey: (_a = this._identityManager.identity) == null ? void 0 : _a.deviceKey
1349
- };
1573
+ return {};
1350
1574
  }
1351
1575
  createInvitation(invitation) {
1352
1576
  return new import_codec_protobuf8.Stream(({ next, close }) => {
1353
- const invitationsHandler = this._getInvitationsHandler();
1354
- const context = this.getContext(invitation);
1577
+ const handler = this._getHandler(invitation);
1355
1578
  (0, import_log5.log)("stream opened", this.getLoggingContext(), {
1356
1579
  file: "invitations-service.ts",
1357
- line: 48,
1580
+ line: 37,
1358
1581
  scope: this,
1359
1582
  callSite: (f, a) => f(...a)
1360
1583
  });
1361
1584
  let invitationId;
1362
- const { type, swarmKey, authMethod } = invitation;
1363
- const observable = invitationsHandler.createInvitation(context, {
1364
- type,
1365
- swarmKey,
1366
- authMethod
1367
- });
1368
- observable.subscribe({
1369
- onConnecting: (invitation2) => {
1370
- (0, import_node_assert5.default)(invitation2.invitationId);
1371
- invitationId = invitation2.invitationId;
1372
- this._createInvitations.set(invitation2.invitationId, observable);
1373
- invitation2.state = import_services3.Invitation.State.CONNECTING;
1374
- next(invitation2);
1375
- },
1376
- onConnected: (invitation2) => {
1377
- (0, import_node_assert5.default)(invitation2.invitationId);
1378
- invitation2.state = import_services3.Invitation.State.CONNECTED;
1379
- next(invitation2);
1380
- },
1381
- onAuthenticating: (invitation2) => {
1382
- (0, import_node_assert5.default)(invitation2.invitationId);
1383
- invitation2.state = import_services3.Invitation.State.AUTHENTICATING;
1384
- next(invitation2);
1385
- },
1386
- onSuccess: (invitation2) => {
1387
- (0, import_node_assert5.default)(invitation2.invitationId);
1388
- invitation2.state = import_services3.Invitation.State.SUCCESS;
1389
- next(invitation2);
1390
- close();
1391
- },
1392
- onCancelled: () => {
1393
- (0, import_node_assert5.default)(invitationId);
1394
- invitation.invitationId = invitationId;
1395
- invitation.state = import_services3.Invitation.State.CANCELLED;
1396
- next(invitation);
1397
- close();
1398
- },
1399
- onTimeout: (err) => {
1400
- invitation.state = import_services3.Invitation.State.TIMEOUT;
1401
- close(err);
1402
- },
1403
- onError: (err) => {
1404
- invitation.state = import_services3.Invitation.State.ERROR;
1405
- close(err);
1585
+ const observable = this._invitationsHandler.createInvitation(handler, invitation);
1586
+ observable.subscribe((invitation2) => {
1587
+ switch (invitation2.state) {
1588
+ case import_services4.Invitation.State.CONNECTING: {
1589
+ (0, import_node_assert6.default)(invitation2.invitationId);
1590
+ invitationId = invitation2.invitationId;
1591
+ this._createInvitations.set(invitation2.invitationId, observable);
1592
+ invitation2.state = import_services4.Invitation.State.CONNECTING;
1593
+ next(invitation2);
1594
+ break;
1595
+ }
1596
+ case import_services4.Invitation.State.CONNECTED: {
1597
+ (0, import_node_assert6.default)(invitation2.invitationId);
1598
+ invitation2.state = import_services4.Invitation.State.CONNECTED;
1599
+ next(invitation2);
1600
+ break;
1601
+ }
1602
+ case import_services4.Invitation.State.READY_FOR_AUTHENTICATION: {
1603
+ (0, import_node_assert6.default)(invitation2.invitationId);
1604
+ invitation2.state = import_services4.Invitation.State.READY_FOR_AUTHENTICATION;
1605
+ next(invitation2);
1606
+ break;
1607
+ }
1608
+ case import_services4.Invitation.State.AUTHENTICATING: {
1609
+ (0, import_node_assert6.default)(invitation2.invitationId);
1610
+ invitation2.state = import_services4.Invitation.State.AUTHENTICATING;
1611
+ next(invitation2);
1612
+ break;
1613
+ }
1614
+ case import_services4.Invitation.State.SUCCESS: {
1615
+ (0, import_node_assert6.default)(invitation2.invitationId);
1616
+ invitation2.state = import_services4.Invitation.State.SUCCESS;
1617
+ next(invitation2);
1618
+ break;
1619
+ }
1620
+ case import_services4.Invitation.State.CANCELLED: {
1621
+ (0, import_node_assert6.default)(invitationId);
1622
+ invitation2.invitationId = invitationId;
1623
+ invitation2.state = import_services4.Invitation.State.CANCELLED;
1624
+ next(invitation2);
1625
+ break;
1626
+ }
1627
+ case import_services4.Invitation.State.TIMEOUT: {
1628
+ (0, import_node_assert6.default)(invitationId);
1629
+ invitation2.invitationId = invitationId;
1630
+ invitation2.state = import_services4.Invitation.State.TIMEOUT;
1631
+ next(invitation2);
1632
+ break;
1633
+ }
1406
1634
  }
1635
+ }, (err) => {
1636
+ close(err);
1637
+ }, () => {
1638
+ close();
1407
1639
  });
1408
1640
  return (err) => {
1409
- const context2 = this.getLoggingContext();
1641
+ const context = this.getLoggingContext();
1410
1642
  if (err) {
1411
1643
  import_log5.log.warn("stream closed", {
1412
- ...context2,
1644
+ ...context,
1413
1645
  err
1414
1646
  }, {
1415
1647
  file: "invitations-service.ts",
1416
- line: 97,
1648
+ line: 103,
1417
1649
  scope: this,
1418
1650
  callSite: (f, a) => f(...a)
1419
1651
  });
1420
1652
  } else {
1421
- (0, import_log5.log)("stream closed", context2, {
1653
+ (0, import_log5.log)("stream closed", context, {
1422
1654
  file: "invitations-service.ts",
1423
- line: 99,
1655
+ line: 105,
1424
1656
  scope: this,
1425
1657
  callSite: (f, a) => f(...a)
1426
1658
  });
@@ -1429,55 +1661,69 @@ var AbstractInvitationsService = class {
1429
1661
  };
1430
1662
  });
1431
1663
  }
1432
- acceptInvitation(invitation, options) {
1664
+ acceptInvitation(invitation) {
1433
1665
  return new import_codec_protobuf8.Stream(({ next, close }) => {
1434
1666
  (0, import_log5.log)("stream opened", this.getLoggingContext(), {
1435
1667
  file: "invitations-service.ts",
1436
- line: 109,
1668
+ line: 115,
1437
1669
  scope: this,
1438
1670
  callSite: (f, a) => f(...a)
1439
1671
  });
1440
- const invitationsHandler = this._getInvitationsHandler();
1672
+ const handler = this._getHandler(invitation);
1441
1673
  let invitationId;
1442
- const observable = invitationsHandler.acceptInvitation(invitation, options);
1443
- observable.subscribe({
1444
- onConnecting: (invitation2) => {
1445
- (0, import_node_assert5.default)(invitation2.invitationId);
1446
- invitationId = invitation2.invitationId;
1447
- this._acceptInvitations.set(invitation2.invitationId, observable);
1448
- invitation2.state = import_services3.Invitation.State.CONNECTING;
1449
- next(invitation2);
1450
- },
1451
- onConnected: (invitation2) => {
1452
- (0, import_node_assert5.default)(invitation2.invitationId);
1453
- invitation2.state = import_services3.Invitation.State.CONNECTED;
1454
- next(invitation2);
1455
- },
1456
- onAuthenticating: (invitation2) => {
1457
- (0, import_node_assert5.default)(invitation2.invitationId);
1458
- invitation2.state = import_services3.Invitation.State.AUTHENTICATING;
1459
- next(invitation2);
1460
- },
1461
- onSuccess: (invitation2) => {
1462
- invitation2.state = import_services3.Invitation.State.SUCCESS;
1463
- next(invitation2);
1464
- close();
1465
- },
1466
- onCancelled: () => {
1467
- (0, import_node_assert5.default)(invitationId);
1468
- invitation.invitationId = invitationId;
1469
- invitation.state = import_services3.Invitation.State.CANCELLED;
1470
- next(invitation);
1471
- close();
1472
- },
1473
- onTimeout: (err) => {
1474
- invitation.state = import_services3.Invitation.State.TIMEOUT;
1475
- close(err);
1476
- },
1477
- onError: (err) => {
1478
- invitation.state = import_services3.Invitation.State.ERROR;
1479
- close(err);
1674
+ const observable = this._invitationsHandler.acceptInvitation(handler, invitation);
1675
+ observable.subscribe((invitation2) => {
1676
+ switch (invitation2.state) {
1677
+ case import_services4.Invitation.State.CONNECTING: {
1678
+ (0, import_node_assert6.default)(invitation2.invitationId);
1679
+ invitationId = invitation2.invitationId;
1680
+ this._acceptInvitations.set(invitation2.invitationId, observable);
1681
+ invitation2.state = import_services4.Invitation.State.CONNECTING;
1682
+ next(invitation2);
1683
+ break;
1684
+ }
1685
+ case import_services4.Invitation.State.CONNECTED: {
1686
+ (0, import_node_assert6.default)(invitation2.invitationId);
1687
+ invitation2.state = import_services4.Invitation.State.CONNECTED;
1688
+ next(invitation2);
1689
+ break;
1690
+ }
1691
+ case import_services4.Invitation.State.READY_FOR_AUTHENTICATION: {
1692
+ (0, import_node_assert6.default)(invitation2.invitationId);
1693
+ invitation2.state = import_services4.Invitation.State.READY_FOR_AUTHENTICATION;
1694
+ next(invitation2);
1695
+ break;
1696
+ }
1697
+ case import_services4.Invitation.State.AUTHENTICATING: {
1698
+ (0, import_node_assert6.default)(invitation2.invitationId);
1699
+ invitation2.state = import_services4.Invitation.State.AUTHENTICATING;
1700
+ next(invitation2);
1701
+ break;
1702
+ }
1703
+ case import_services4.Invitation.State.SUCCESS: {
1704
+ invitation2.state = import_services4.Invitation.State.SUCCESS;
1705
+ next(invitation2);
1706
+ break;
1707
+ }
1708
+ case import_services4.Invitation.State.CANCELLED: {
1709
+ (0, import_node_assert6.default)(invitationId);
1710
+ invitation2.invitationId = invitationId;
1711
+ invitation2.state = import_services4.Invitation.State.CANCELLED;
1712
+ next(invitation2);
1713
+ break;
1714
+ }
1715
+ case import_services4.Invitation.State.TIMEOUT: {
1716
+ (0, import_node_assert6.default)(invitationId);
1717
+ invitation2.invitationId = invitationId;
1718
+ invitation2.state = import_services4.Invitation.State.TIMEOUT;
1719
+ next(invitation2);
1720
+ break;
1721
+ }
1480
1722
  }
1723
+ }, (err) => {
1724
+ close(err);
1725
+ }, () => {
1726
+ close();
1481
1727
  });
1482
1728
  return (err) => {
1483
1729
  const context = this.getLoggingContext();
@@ -1487,14 +1733,14 @@ var AbstractInvitationsService = class {
1487
1733
  err
1488
1734
  }, {
1489
1735
  file: "invitations-service.ts",
1490
- line: 157,
1736
+ line: 181,
1491
1737
  scope: this,
1492
1738
  callSite: (f, a) => f(...a)
1493
1739
  });
1494
1740
  } else {
1495
1741
  (0, import_log5.log)("stream closed", context, {
1496
1742
  file: "invitations-service.ts",
1497
- line: 159,
1743
+ line: 183,
1498
1744
  scope: this,
1499
1745
  callSite: (f, a) => f(...a)
1500
1746
  });
@@ -1503,531 +1749,140 @@ var AbstractInvitationsService = class {
1503
1749
  };
1504
1750
  });
1505
1751
  }
1506
- async authenticate({ invitationId, authenticationCode }) {
1752
+ async authenticate({ invitationId, authCode }) {
1507
1753
  (0, import_log5.log)("authenticating...", {}, {
1508
1754
  file: "invitations-service.ts",
1509
- line: 168,
1755
+ line: 192,
1510
1756
  scope: this,
1511
1757
  callSite: (f, a) => f(...a)
1512
1758
  });
1513
- (0, import_node_assert5.default)(invitationId);
1759
+ (0, import_node_assert6.default)(invitationId);
1514
1760
  const observable = this._acceptInvitations.get(invitationId);
1515
1761
  if (!observable) {
1516
1762
  import_log5.log.warn("invalid invitation", {
1517
1763
  invitationId
1518
1764
  }, {
1519
1765
  file: "invitations-service.ts",
1520
- line: 172,
1766
+ line: 196,
1521
1767
  scope: this,
1522
1768
  callSite: (f, a) => f(...a)
1523
1769
  });
1524
1770
  } else {
1525
- await observable.authenticate(authenticationCode);
1771
+ await observable.authenticate(authCode);
1526
1772
  }
1527
1773
  }
1528
- async cancelInvitation(invitation) {
1774
+ async cancelInvitation({ invitationId }) {
1529
1775
  var _a;
1530
1776
  (0, import_log5.log)("cancelling...", {}, {
1531
1777
  file: "invitations-service.ts",
1532
- line: 179,
1778
+ line: 203,
1533
1779
  scope: this,
1534
1780
  callSite: (f, a) => f(...a)
1535
1781
  });
1536
- (0, import_node_assert5.default)(invitation.invitationId);
1537
- const observable = (_a = this._createInvitations.get(invitation.invitationId)) != null ? _a : this._acceptInvitations.get(invitation.invitationId);
1782
+ (0, import_node_assert6.default)(invitationId);
1783
+ const observable = (_a = this._createInvitations.get(invitationId)) != null ? _a : this._acceptInvitations.get(invitationId);
1538
1784
  if (!observable) {
1539
1785
  import_log5.log.warn("invalid invitation", {
1540
- invitationId: invitation.invitationId
1786
+ invitationId
1541
1787
  }, {
1542
1788
  file: "invitations-service.ts",
1543
- line: 184,
1789
+ line: 207,
1544
1790
  scope: this,
1545
1791
  callSite: (f, a) => f(...a)
1546
1792
  });
1547
1793
  } else {
1548
1794
  await (observable == null ? void 0 : observable.cancel());
1549
- }
1550
- }
1551
- };
1552
-
1553
- // packages/sdk/client-services/src/packlets/invitations/device-invitations-service.ts
1554
- var DeviceInvitationsServiceImpl = class extends AbstractInvitationsService {
1555
- // prettier-ignore
1556
- constructor(identityManager, invitationsHandler) {
1557
- super(identityManager, () => invitationsHandler);
1558
- this.invitationsHandler = invitationsHandler;
1559
- }
1560
- getContext(invitation) {
1561
- }
1562
- };
1563
-
1564
- // packages/sdk/client-services/src/packlets/invitations/space-invitations-handler.ts
1565
- var import_node_assert6 = __toESM(require("node:assert"));
1566
- var import_async8 = require("@dxos/async");
1567
- var import_client2 = require("@dxos/client");
1568
- var import_context4 = require("@dxos/context");
1569
- var import_credentials9 = require("@dxos/credentials");
1570
- var import_feed_store3 = require("@dxos/feed-store");
1571
- var import_keys7 = require("@dxos/keys");
1572
- var import_log6 = require("@dxos/log");
1573
- var import_network_manager2 = require("@dxos/network-manager");
1574
- var import_protocols4 = require("@dxos/protocols");
1575
- var import_services4 = require("@dxos/protocols/proto/dxos/client/services");
1576
- var import_invitations2 = require("@dxos/protocols/proto/dxos/halo/invitations");
1577
- var import_teleport2 = require("@dxos/teleport");
1578
- var MAX_OTP_ATTEMPTS = 3;
1579
- var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHandler {
1580
- constructor(networkManager, _spaceManager, _signingContext, _keyring) {
1581
- super(networkManager);
1582
- this._spaceManager = _spaceManager;
1583
- this._signingContext = _signingContext;
1584
- this._keyring = _keyring;
1585
- }
1586
- /**
1587
- * Creates an invitation and listens for a join request from the invited (guest) peer.
1588
- */
1589
- createInvitation(space, options) {
1590
- var _a;
1591
- let swarmConnection;
1592
- const { type, timeout = import_client2.INVITATION_TIMEOUT, swarmKey } = options != null ? options : {};
1593
- (0, import_node_assert6.default)(type !== import_services4.Invitation.Type.OFFLINE);
1594
- (0, import_node_assert6.default)(space);
1595
- const invitation = {
1596
- type,
1597
- invitationId: import_keys7.PublicKey.random().toHex(),
1598
- swarmKey: swarmKey != null ? swarmKey : import_keys7.PublicKey.random(),
1599
- spaceKey: space.key,
1600
- authMethod: (_a = options == null ? void 0 : options.authMethod) != null ? _a : import_invitations2.AuthMethod.SHARED_SECRET,
1601
- authenticationCode: (0, import_credentials9.generatePasscode)(import_client2.AUTHENTICATION_CODE_LENGTH)
1602
- // TODO(dmaretskyi): Don't generate if authMethod === NONE .
1603
- };
1604
- const ctx = new import_context4.Context({
1605
- onError: (err) => {
1606
- void ctx.dispose();
1607
- observable.callback.onError(err);
1608
- }
1609
- });
1610
- const observable = new import_client2.InvitationObservableProvider(async () => {
1611
- await (swarmConnection == null ? void 0 : swarmConnection.close());
1612
- });
1613
- let authenticationPassed = false;
1614
- let authenticationRetry = 0;
1615
- const createExtension = () => {
1616
- const complete = new import_async8.Trigger();
1617
- let guestProfile;
1618
- const hostInvitationExtension = new HostSpaceInvitationExtension({
1619
- introduce: async ({ profile }) => {
1620
- var _a2, _b;
1621
- (0, import_log6.log)("guest introduced itself", {
1622
- guestProfile: profile,
1623
- host: this._signingContext.deviceKey,
1624
- spaceKey: space.key
1625
- }, {
1626
- file: "space-invitations-handler.ts",
1627
- line: 101,
1628
- scope: this,
1629
- callSite: (f, a) => f(...a)
1630
- });
1631
- guestProfile = profile;
1632
- (_b = (_a2 = observable.callback).onAuthenticating) == null ? void 0 : _b.call(_a2, invitation);
1633
- return {
1634
- spaceKey: type === import_services4.Invitation.Type.INTERACTIVE_TESTING || type === import_services4.Invitation.Type.MULTIUSE_TESTING ? space.key : void 0,
1635
- authMethod: invitation.authMethod
1636
- };
1637
- },
1638
- authenticate: async ({ authenticationCode: code }) => {
1639
- (0, import_log6.log)("received authentication request", {
1640
- authenticationCode: code
1641
- }, {
1642
- file: "space-invitations-handler.ts",
1643
- line: 123,
1644
- scope: this,
1645
- callSite: (f, a) => f(...a)
1646
- });
1647
- let status = import_invitations2.AuthenticationResponse.Status.OK;
1648
- switch (invitation.authMethod) {
1649
- case import_invitations2.AuthMethod.NONE: {
1650
- (0, import_log6.log)("authentication not required", {}, {
1651
- file: "space-invitations-handler.ts",
1652
- line: 128,
1653
- scope: this,
1654
- callSite: (f, a) => f(...a)
1655
- });
1656
- return {
1657
- status: import_invitations2.AuthenticationResponse.Status.OK
1658
- };
1659
- }
1660
- case import_invitations2.AuthMethod.SHARED_SECRET: {
1661
- if (invitation.authenticationCode) {
1662
- if (authenticationRetry++ > MAX_OTP_ATTEMPTS) {
1663
- status = import_invitations2.AuthenticationResponse.Status.INVALID_OPT_ATTEMPTS;
1664
- } else if (code !== invitation.authenticationCode) {
1665
- status = import_invitations2.AuthenticationResponse.Status.INVALID_OTP;
1666
- } else {
1667
- authenticationPassed = true;
1668
- }
1669
- }
1670
- break;
1671
- }
1672
- default: {
1673
- import_log6.log.error("invalid authentication method", {
1674
- authMethod: invitation.authMethod
1675
- }, {
1676
- file: "space-invitations-handler.ts",
1677
- line: 144,
1678
- scope: this,
1679
- callSite: (f, a) => f(...a)
1680
- });
1681
- status = import_invitations2.AuthenticationResponse.Status.INTERNAL_ERROR;
1682
- break;
1683
- }
1684
- }
1685
- return {
1686
- status
1687
- };
1688
- },
1689
- requestAdmission: async ({ identityKey, deviceKey, controlFeedKey, dataFeedKey }) => {
1690
- var _a2;
1691
- try {
1692
- if (isAuthenticationRequired(invitation) && !authenticationPassed) {
1693
- throw new Error("Not authenticated");
1694
- }
1695
- (0, import_log6.log)("writing guest credentials", {
1696
- host: this._signingContext.deviceKey,
1697
- guest: deviceKey
1698
- }, {
1699
- file: "space-invitations-handler.ts",
1700
- line: 160,
1701
- scope: this,
1702
- callSite: (f, a) => f(...a)
1703
- });
1704
- const credentials = await (0, import_credentials9.createAdmissionCredentials)(this._signingContext.credentialSigner, identityKey, space.key, space.inner.genesisFeedKey, guestProfile);
1705
- (0, import_node_assert6.default)(credentials[0].credential);
1706
- const spaceMemberCredential = credentials[0].credential.credential;
1707
- (0, import_node_assert6.default)((0, import_credentials9.getCredentialAssertion)(spaceMemberCredential)["@type"] === "dxos.halo.credentials.SpaceMember");
1708
- await (0, import_feed_store3.writeMessages)(space.inner.controlPipeline.writer, credentials);
1709
- complete.wake(deviceKey);
1710
- return {
1711
- credential: spaceMemberCredential,
1712
- controlTimeframe: space.inner.controlPipeline.state.timeframe,
1713
- dataTimeframe: (_a2 = space.dataPipeline.pipelineState) == null ? void 0 : _a2.timeframe
1714
- };
1715
- } catch (err) {
1716
- observable.callback.onError(err);
1717
- throw err;
1718
- }
1719
- },
1720
- onOpen: () => {
1721
- (0, import_async8.scheduleTask)(ctx, async () => {
1722
- var _a2, _b;
1723
- try {
1724
- (0, import_log6.log)("connected", {
1725
- host: this._signingContext.deviceKey
1726
- }, {
1727
- file: "space-invitations-handler.ts",
1728
- line: 195,
1729
- scope: this,
1730
- callSite: (f, a) => f(...a)
1731
- });
1732
- (_b = (_a2 = observable.callback).onConnected) == null ? void 0 : _b.call(_a2, invitation);
1733
- const deviceKey = await complete.wait({
1734
- timeout
1735
- });
1736
- (0, import_log6.log)("admitted guest", {
1737
- host: this._signingContext.deviceKey,
1738
- guest: deviceKey
1739
- }, {
1740
- file: "space-invitations-handler.ts",
1741
- line: 198,
1742
- scope: this,
1743
- callSite: (f, a) => f(...a)
1744
- });
1745
- observable.callback.onSuccess(invitation);
1746
- } catch (err) {
1747
- if (!observable.cancelled) {
1748
- import_log6.log.error("failed", err, {
1749
- file: "space-invitations-handler.ts",
1750
- line: 202,
1751
- scope: this,
1752
- callSite: (f, a) => f(...a)
1753
- });
1754
- observable.callback.onError(err);
1755
- }
1756
- } finally {
1757
- if (type !== import_services4.Invitation.Type.MULTIUSE_TESTING) {
1758
- await (0, import_async8.sleep)(import_client2.ON_CLOSE_DELAY);
1759
- await ctx.dispose();
1760
- }
1761
- }
1762
- });
1763
- }
1764
- });
1765
- return hostInvitationExtension;
1766
- };
1767
- (0, import_async8.scheduleTask)(ctx, async () => {
1768
- var _a2, _b;
1769
- const topic = invitation.swarmKey;
1770
- const swarmConnection2 = await this._networkManager.joinSwarm({
1771
- topic,
1772
- peerId: topic,
1773
- protocolProvider: (0, import_network_manager2.createTeleportProtocolFactory)(async (teleport) => {
1774
- teleport.addExtension("dxos.halo.invitations", createExtension());
1775
- }),
1776
- topology: new import_network_manager2.StarTopology(topic)
1777
- });
1778
- ctx.onDispose(() => swarmConnection2.close());
1779
- (_b = (_a2 = observable.callback).onConnecting) == null ? void 0 : _b.call(_a2, invitation);
1780
- });
1781
- return observable;
1782
- }
1783
- /**
1784
- * Waits for the host peer (inviter) to accept our join request.
1785
- * The local guest peer (invitee) then sends the local space invitation to the host,
1786
- * which then writes the guest's credentials to the space.
1787
- */
1788
- acceptInvitation(invitation, options) {
1789
- const { timeout = import_client2.INVITATION_TIMEOUT } = options != null ? options : {};
1790
- const ctx = new import_context4.Context({
1791
- onError: (err) => {
1792
- void ctx.dispose();
1793
- observable.callback.onError(err);
1794
- }
1795
- });
1796
- const authenticated = new import_async8.Trigger();
1797
- const observable = new import_client2.AuthenticatingInvitationProvider({
1798
- onCancel: async () => {
1799
- await ctx.dispose();
1800
- },
1801
- onAuthenticate: async (code) => {
1802
- authenticated.wake(code);
1803
- }
1804
- });
1805
- let connectionCount = 0;
1806
- const complete = new import_async8.Trigger();
1807
- const createExtension = () => {
1808
- const extension = new GuestSpaceInvitationExtension({
1809
- onOpen: () => {
1810
- (0, import_async8.scheduleTask)(ctx, async () => {
1811
- var _a, _b, _c, _d, _e, _f;
1812
- try {
1813
- if (++connectionCount > 1) {
1814
- throw new Error(`multiple connections detected: ${connectionCount}`);
1815
- }
1816
- (0, import_log6.log)("connected", {
1817
- guest: this._signingContext.deviceKey
1818
- }, {
1819
- file: "space-invitations-handler.ts",
1820
- line: 275,
1821
- scope: this,
1822
- callSite: (f, a) => f(...a)
1823
- });
1824
- (_b = (_a = observable.callback).onConnected) == null ? void 0 : _b.call(_a, invitation);
1825
- (0, import_log6.log)("introduce", {
1826
- guest: this._signingContext.deviceKey
1827
- }, {
1828
- file: "space-invitations-handler.ts",
1829
- line: 279,
1830
- scope: this,
1831
- callSite: (f, a) => f(...a)
1832
- });
1833
- const introductionResponse = await extension.rpc.SpaceHostService.introduce({
1834
- profile: this._signingContext.profile
1835
- });
1836
- (0, import_log6.log)("introduce response", {
1837
- guest: this._signingContext.deviceKey,
1838
- response: introductionResponse
1839
- }, {
1840
- file: "space-invitations-handler.ts",
1841
- line: 283,
1842
- scope: this,
1843
- callSite: (f, a) => f(...a)
1844
- });
1845
- invitation.authMethod = introductionResponse.authMethod;
1846
- if (introductionResponse.spaceKey) {
1847
- invitation.spaceKey = introductionResponse.spaceKey;
1848
- }
1849
- if (isAuthenticationRequired(invitation)) {
1850
- (_d = (_c = observable.callback).onAuthenticating) == null ? void 0 : _d.call(_c, invitation);
1851
- for (let attempt = 1; attempt <= MAX_OTP_ATTEMPTS; attempt++) {
1852
- (0, import_log6.log)("guest waiting for authentication code...", {}, {
1853
- file: "space-invitations-handler.ts",
1854
- line: 297,
1855
- scope: this,
1856
- callSite: (f, a) => f(...a)
1857
- });
1858
- (_f = (_e = observable.callback).onAuthenticating) == null ? void 0 : _f.call(_e, invitation);
1859
- const authenticationCode = await authenticated.wait({
1860
- timeout
1861
- });
1862
- (0, import_log6.log)("sending authentication request", {}, {
1863
- file: "space-invitations-handler.ts",
1864
- line: 301,
1865
- scope: this,
1866
- callSite: (f, a) => f(...a)
1867
- });
1868
- const response = await extension.rpc.SpaceHostService.authenticate({
1869
- authenticationCode
1870
- });
1871
- if (response.status === void 0 || response.status === import_invitations2.AuthenticationResponse.Status.OK) {
1872
- break;
1873
- }
1874
- if (response.status === import_invitations2.AuthenticationResponse.Status.INVALID_OTP) {
1875
- if (attempt === MAX_OTP_ATTEMPTS) {
1876
- throw new Error(`Maximum retry attempts: ${MAX_OTP_ATTEMPTS}`);
1877
- } else {
1878
- (0, import_log6.log)("retrying invalid code", {
1879
- attempt
1880
- }, {
1881
- file: "space-invitations-handler.ts",
1882
- line: 311,
1883
- scope: this,
1884
- callSite: (f, a) => f(...a)
1885
- });
1886
- authenticated.reset();
1887
- }
1888
- }
1889
- }
1890
- }
1891
- const controlFeedKey = await this._keyring.createKey();
1892
- const dataFeedKey = await this._keyring.createKey();
1893
- (0, import_log6.log)("request admission", {
1894
- guest: this._signingContext.deviceKey
1895
- }, {
1896
- file: "space-invitations-handler.ts",
1897
- line: 322,
1898
- scope: this,
1899
- callSite: (f, a) => f(...a)
1900
- });
1901
- const { credential, controlTimeframe, dataTimeframe } = await extension.rpc.SpaceHostService.requestAdmission({
1902
- identityKey: this._signingContext.identityKey,
1903
- deviceKey: this._signingContext.deviceKey,
1904
- controlFeedKey,
1905
- dataFeedKey
1906
- });
1907
- const assertion = (0, import_credentials9.getCredentialAssertion)(credential);
1908
- (0, import_node_assert6.default)(assertion["@type"] === "dxos.halo.credentials.SpaceMember", "Invalid credential");
1909
- (0, import_node_assert6.default)(credential.subject.id.equals(this._signingContext.identityKey));
1910
- const space = await this._spaceManager.acceptSpace({
1911
- spaceKey: assertion.spaceKey,
1912
- genesisFeedKey: assertion.genesisFeedKey,
1913
- controlTimeframe,
1914
- dataTimeframe
1915
- });
1916
- await this._signingContext.recordCredential(credential);
1917
- (0, import_log6.log)("admitted by host", {
1918
- guest: this._signingContext.deviceKey,
1919
- spaceKey: space.key
1920
- }, {
1921
- file: "space-invitations-handler.ts",
1922
- line: 347,
1923
- scope: this,
1924
- callSite: (f, a) => f(...a)
1925
- });
1926
- complete.wake();
1927
- } catch (err) {
1928
- if (!observable.cancelled) {
1929
- import_log6.log.warn("auth failed", err, {
1930
- file: "space-invitations-handler.ts",
1931
- line: 351,
1932
- scope: this,
1933
- callSite: (f, a) => f(...a)
1934
- });
1935
- observable.callback.onError(err);
1936
- }
1937
- } finally {
1938
- await ctx.dispose();
1939
- }
1940
- });
1941
- }
1942
- });
1943
- return extension;
1944
- };
1945
- (0, import_async8.scheduleTask)(ctx, async () => {
1946
- var _a, _b;
1947
- (0, import_node_assert6.default)(invitation.swarmKey);
1948
- const topic = invitation.swarmKey;
1949
- const swarmConnection = await this._networkManager.joinSwarm({
1950
- topic,
1951
- peerId: import_keys7.PublicKey.random(),
1952
- protocolProvider: (0, import_network_manager2.createTeleportProtocolFactory)(async (teleport) => {
1953
- teleport.addExtension("dxos.halo.invitations", createExtension());
1954
- }),
1955
- topology: new import_network_manager2.StarTopology(topic)
1956
- });
1957
- ctx.onDispose(() => swarmConnection.close());
1958
- (_b = (_a = observable.callback).onConnecting) == null ? void 0 : _b.call(_a, invitation);
1959
- await complete.wait();
1960
- observable.callback.onSuccess(invitation);
1961
- await ctx.dispose();
1962
- });
1963
- return observable;
1795
+ }
1964
1796
  }
1965
1797
  };
1966
- var isAuthenticationRequired = (invitation) => invitation.authMethod !== import_invitations2.AuthMethod.NONE && invitation.type !== import_services4.Invitation.Type.INTERACTIVE_TESTING && invitation.type !== import_services4.Invitation.Type.MULTIUSE_TESTING;
1967
- var HostSpaceInvitationExtension = class extends import_teleport2.RpcExtension {
1968
- constructor(_callbacks) {
1969
- super({
1970
- exposed: {
1971
- SpaceHostService: import_protocols4.schema.getService("dxos.halo.invitations.SpaceHostService")
1972
- }
1973
- });
1974
- this._callbacks = _callbacks;
1798
+
1799
+ // packages/sdk/client-services/src/packlets/invitations/space-invitation-protocol.ts
1800
+ var import_node_assert7 = __toESM(require("node:assert"));
1801
+ var import_credentials9 = require("@dxos/credentials");
1802
+ var import_feed_store3 = require("@dxos/feed-store");
1803
+ var import_log6 = require("@dxos/log");
1804
+ var import_services5 = require("@dxos/protocols/proto/dxos/client/services");
1805
+ var SpaceInvitationProtocol = class {
1806
+ constructor(_spaceManager, _signingContext, _keyring, _spaceKey) {
1807
+ this._spaceManager = _spaceManager;
1808
+ this._signingContext = _signingContext;
1809
+ this._keyring = _keyring;
1810
+ this._spaceKey = _spaceKey;
1975
1811
  }
1976
- async getHandlers() {
1812
+ toJSON() {
1977
1813
  return {
1978
- // TODO(dmaretskyi): For now this is just forwarding the data to callbacks since we don't have session-specific logic.
1979
- // Perhaps in the future we will have more complex logic here.
1980
- SpaceHostService: {
1981
- introduce: async (params) => {
1982
- return this._callbacks.introduce(params);
1983
- },
1984
- authenticate: async (credentials) => {
1985
- return this._callbacks.authenticate(credentials);
1986
- },
1987
- requestAdmission: async (credentials) => {
1988
- return this._callbacks.requestAdmission(credentials);
1989
- }
1990
- }
1814
+ deviceKey: this._signingContext.deviceKey,
1815
+ spaceKey: this._spaceKey
1991
1816
  };
1992
1817
  }
1993
- async onOpen(context) {
1994
- await super.onOpen(context);
1995
- this._callbacks.onOpen();
1818
+ getInvitationContext() {
1819
+ return {
1820
+ kind: import_services5.Invitation.Kind.SPACE,
1821
+ spaceKey: this._spaceKey
1822
+ };
1996
1823
  }
1997
- };
1998
- var GuestSpaceInvitationExtension = class extends import_teleport2.RpcExtension {
1999
- constructor(_callbacks) {
2000
- super({
2001
- requested: {
2002
- SpaceHostService: import_protocols4.schema.getService("dxos.halo.invitations.SpaceHostService")
2003
- }
1824
+ async admit(request, guestProfile) {
1825
+ var _a;
1826
+ (0, import_node_assert7.default)(this._spaceKey);
1827
+ const space = await this._spaceManager.spaces.get(this._spaceKey);
1828
+ (0, import_node_assert7.default)(space);
1829
+ (0, import_node_assert7.default)(request.space);
1830
+ const { identityKey, deviceKey } = request.space;
1831
+ (0, import_log6.log)("writing guest credentials", {
1832
+ host: this._signingContext.deviceKey,
1833
+ guest: deviceKey
1834
+ }, {
1835
+ file: "space-invitation-protocol.ts",
1836
+ line: 51,
1837
+ scope: this,
1838
+ callSite: (f, a) => f(...a)
2004
1839
  });
2005
- this._callbacks = _callbacks;
1840
+ const credentials = await (0, import_credentials9.createAdmissionCredentials)(this._signingContext.credentialSigner, identityKey, space.key, space.inner.genesisFeedKey, guestProfile);
1841
+ (0, import_node_assert7.default)(credentials[0].credential);
1842
+ const spaceMemberCredential = credentials[0].credential.credential;
1843
+ (0, import_node_assert7.default)((0, import_credentials9.getCredentialAssertion)(spaceMemberCredential)["@type"] === "dxos.halo.credentials.SpaceMember");
1844
+ await (0, import_feed_store3.writeMessages)(space.inner.controlPipeline.writer, credentials);
1845
+ return {
1846
+ space: {
1847
+ credential: spaceMemberCredential,
1848
+ controlTimeframe: space.inner.controlPipeline.state.timeframe,
1849
+ dataTimeframe: (_a = space.dataPipeline.pipelineState) == null ? void 0 : _a.timeframe
1850
+ }
1851
+ };
2006
1852
  }
2007
- async getHandlers() {
2008
- return {};
1853
+ createIntroduction() {
1854
+ return {
1855
+ profile: this._signingContext.profile
1856
+ };
2009
1857
  }
2010
- async onOpen(context) {
2011
- await super.onOpen(context);
2012
- this._callbacks.onOpen();
1858
+ async createAdmissionRequest() {
1859
+ const controlFeedKey = await this._keyring.createKey();
1860
+ const dataFeedKey = await this._keyring.createKey();
1861
+ return {
1862
+ space: {
1863
+ identityKey: this._signingContext.identityKey,
1864
+ deviceKey: this._signingContext.deviceKey,
1865
+ controlFeedKey,
1866
+ dataFeedKey
1867
+ }
1868
+ };
2013
1869
  }
2014
- };
2015
-
2016
- // packages/sdk/client-services/src/packlets/invitations/space-invitations-service.ts
2017
- var import_node_assert7 = __toESM(require("node:assert"));
2018
- var SpaceInvitationsServiceImpl = class extends AbstractInvitationsService {
2019
- // prettier-ignore
2020
- constructor(identityManager, invitationsHandler, _getSpaceManager) {
2021
- super(identityManager, invitationsHandler);
2022
- this.invitationsHandler = invitationsHandler;
2023
- this._getSpaceManager = _getSpaceManager;
2024
- }
2025
- getContext(invitation) {
2026
- (0, import_node_assert7.default)(invitation.spaceKey);
2027
- const spaceManager = this._getSpaceManager();
2028
- const space = spaceManager.spaces.get(invitation.spaceKey);
2029
- (0, import_node_assert7.default)(space);
2030
- return space;
1870
+ async accept(response) {
1871
+ (0, import_node_assert7.default)(response.space);
1872
+ const { credential, controlTimeframe, dataTimeframe } = response.space;
1873
+ const assertion = (0, import_credentials9.getCredentialAssertion)(credential);
1874
+ (0, import_node_assert7.default)(assertion["@type"] === "dxos.halo.credentials.SpaceMember", "Invalid credential");
1875
+ (0, import_node_assert7.default)(credential.subject.id.equals(this._signingContext.identityKey));
1876
+ await this._spaceManager.acceptSpace({
1877
+ spaceKey: assertion.spaceKey,
1878
+ genesisFeedKey: assertion.genesisFeedKey,
1879
+ controlTimeframe,
1880
+ dataTimeframe
1881
+ });
1882
+ await this._signingContext.recordCredential(credential);
1883
+ return {
1884
+ spaceKey: assertion.spaceKey
1885
+ };
2031
1886
  }
2032
1887
  };
2033
1888
 
@@ -2055,47 +1910,48 @@ var NetworkServiceImpl = class {
2055
1910
 
2056
1911
  // packages/sdk/client-services/src/packlets/spaces/data-space-manager.ts
2057
1912
  var import_node_assert9 = __toESM(require("node:assert"));
2058
- var import_async11 = require("@dxos/async");
2059
- var import_client4 = require("@dxos/client");
2060
- var import_context7 = require("@dxos/context");
1913
+ var import_async10 = require("@dxos/async");
1914
+ var import_client3 = require("@dxos/client");
1915
+ var import_context6 = require("@dxos/context");
2061
1916
  var import_credentials11 = require("@dxos/credentials");
2062
1917
  var import_echo_pipeline2 = require("@dxos/echo-pipeline");
2063
- var import_keys10 = require("@dxos/keys");
1918
+ var import_keys9 = require("@dxos/keys");
2064
1919
  var import_log9 = require("@dxos/log");
1920
+ var import_protocols5 = require("@dxos/protocols");
2065
1921
  var import_teleport_extension_gossip = require("@dxos/teleport-extension-gossip");
2066
1922
  var import_util5 = require("@dxos/util");
2067
1923
 
2068
1924
  // packages/sdk/client-services/src/packlets/spaces/data-space.ts
2069
- var import_async10 = require("@dxos/async");
2070
- var import_client3 = require("@dxos/client");
2071
- var import_context6 = require("@dxos/context");
1925
+ var import_async9 = require("@dxos/async");
1926
+ var import_client2 = require("@dxos/client");
1927
+ var import_context5 = require("@dxos/context");
2072
1928
  var import_debug3 = require("@dxos/debug");
2073
1929
  var import_echo_pipeline = require("@dxos/echo-pipeline");
2074
1930
  var import_errors = require("@dxos/errors");
2075
- var import_keys9 = require("@dxos/keys");
1931
+ var import_keys8 = require("@dxos/keys");
2076
1932
  var import_log8 = require("@dxos/log");
2077
1933
  var import_credentials10 = require("@dxos/protocols/proto/dxos/halo/credentials");
2078
1934
  var import_util4 = require("@dxos/util");
2079
1935
 
2080
1936
  // packages/sdk/client-services/src/packlets/spaces/notarization-plugin.ts
2081
1937
  var import_node_assert8 = __toESM(require("node:assert"));
2082
- var import_async9 = require("@dxos/async");
2083
- var import_context5 = require("@dxos/context");
2084
- var import_keys8 = require("@dxos/keys");
1938
+ var import_async8 = require("@dxos/async");
1939
+ var import_context4 = require("@dxos/context");
1940
+ var import_keys7 = require("@dxos/keys");
2085
1941
  var import_log7 = require("@dxos/log");
2086
- var import_protocols5 = require("@dxos/protocols");
2087
- var import_teleport3 = require("@dxos/teleport");
1942
+ var import_protocols4 = require("@dxos/protocols");
1943
+ var import_teleport2 = require("@dxos/teleport");
2088
1944
  var import_util3 = require("@dxos/util");
2089
1945
  var DEFAULT_RETRY_TIMEOUT = 1e3;
2090
1946
  var DEFAULT_SUCCESS_DELAY = 1e3;
2091
1947
  var DEFAULT_NOTARIZE_TIMEOUT = 1e4;
2092
1948
  var NotarizationPlugin = class {
2093
1949
  constructor() {
2094
- this._ctx = new import_context5.Context();
2095
- this._extensionOpened = new import_async9.Event();
1950
+ this._ctx = new import_context4.Context();
1951
+ this._extensionOpened = new import_async8.Event();
2096
1952
  this._extensions = /* @__PURE__ */ new Set();
2097
- this._processedCredentials = new import_util3.ComplexSet(import_keys8.PublicKey.hash);
2098
- this._processCredentialsTriggers = new import_util3.ComplexMap(import_keys8.PublicKey.hash);
1953
+ this._processedCredentials = new import_util3.ComplexSet(import_keys7.PublicKey.hash);
1954
+ this._processCredentialsTriggers = new import_util3.ComplexMap(import_keys7.PublicKey.hash);
2099
1955
  }
2100
1956
  async open() {
2101
1957
  }
@@ -2115,7 +1971,7 @@ var NotarizationPlugin = class {
2115
1971
  callSite: (f, a) => f(...a)
2116
1972
  });
2117
1973
  (0, import_node_assert8.default)(credentials.every((credential) => credential.id), "Credentials must have an id");
2118
- const errors = new import_async9.Trigger();
1974
+ const errors = new import_async8.Trigger();
2119
1975
  const ctx = this._ctx.derive({
2120
1976
  onError: (err) => {
2121
1977
  import_log7.log.warn("Notarization error", {
@@ -2132,7 +1988,7 @@ var NotarizationPlugin = class {
2132
1988
  });
2133
1989
  opCtx == null ? void 0 : opCtx.onDispose(() => ctx.dispose());
2134
1990
  if (timeout !== 0) {
2135
- (0, import_async9.scheduleTask)(ctx, () => {
1991
+ (0, import_async8.scheduleTask)(ctx, () => {
2136
1992
  import_log7.log.warn("Notarization timeout", {
2137
1993
  timeout,
2138
1994
  peers: Array.from(this._extensions).map((extension) => extension.remotePeerId)
@@ -2143,12 +1999,12 @@ var NotarizationPlugin = class {
2143
1999
  callSite: (f, a) => f(...a)
2144
2000
  });
2145
2001
  void ctx.dispose();
2146
- errors.throw(new import_async9.TimeoutError(timeout, "Notarization timed out"));
2002
+ errors.throw(new import_async8.TimeoutError(timeout, "Notarization timed out"));
2147
2003
  }, timeout);
2148
2004
  }
2149
2005
  const allNotarized = Promise.all(credentials.map((credential) => this._waitUntilProcessed(credential.id)));
2150
2006
  const peersTried = /* @__PURE__ */ new Set();
2151
- const notarizeTask = new import_async9.DeferredTask(ctx, async () => {
2007
+ const notarizeTask = new import_async8.DeferredTask(ctx, async () => {
2152
2008
  try {
2153
2009
  if (this._extensions.size === 0) {
2154
2010
  return;
@@ -2166,7 +2022,7 @@ var NotarizationPlugin = class {
2166
2022
  callSite: (f, a) => f(...a)
2167
2023
  });
2168
2024
  peersTried.clear();
2169
- (0, import_async9.scheduleTask)(ctx, () => notarizeTask.schedule(), retryTimeout);
2025
+ (0, import_async8.scheduleTask)(ctx, () => notarizeTask.schedule(), retryTimeout);
2170
2026
  return;
2171
2027
  }
2172
2028
  peersTried.add(peer);
@@ -2188,7 +2044,7 @@ var NotarizationPlugin = class {
2188
2044
  scope: this,
2189
2045
  callSite: (f, a) => f(...a)
2190
2046
  });
2191
- await (0, import_async9.sleep)(successDelay);
2047
+ await (0, import_async8.sleep)(successDelay);
2192
2048
  } catch (err) {
2193
2049
  import_log7.log.warn("error notarizing (recoverable)", err, {
2194
2050
  file: "notarization-plugin.ts",
@@ -2203,7 +2059,7 @@ var NotarizationPlugin = class {
2203
2059
  this._extensionOpened.on(ctx, () => notarizeTask.schedule());
2204
2060
  try {
2205
2061
  await Promise.race([
2206
- (0, import_context5.rejectOnDispose)(ctx),
2062
+ (0, import_context4.rejectOnDispose)(ctx),
2207
2063
  allNotarized,
2208
2064
  errors.wait()
2209
2065
  ]);
@@ -2237,7 +2093,7 @@ var NotarizationPlugin = class {
2237
2093
  if (this._processedCredentials.has(id)) {
2238
2094
  return;
2239
2095
  }
2240
- await (0, import_util3.entry)(this._processCredentialsTriggers, id).orInsert(new import_async9.Trigger()).value.wait();
2096
+ await (0, import_util3.entry)(this._processCredentialsTriggers, id).orInsert(new import_async8.Trigger()).value.wait();
2241
2097
  }
2242
2098
  /**
2243
2099
  * Requests from other peers to notarize credentials.
@@ -2285,14 +2141,14 @@ var NotarizationPlugin = class {
2285
2141
  return extension;
2286
2142
  }
2287
2143
  };
2288
- var NotarizationTeleportExtension = class extends import_teleport3.RpcExtension {
2144
+ var NotarizationTeleportExtension = class extends import_teleport2.RpcExtension {
2289
2145
  constructor(_params) {
2290
2146
  super({
2291
2147
  requested: {
2292
- NotarizationService: import_protocols5.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2148
+ NotarizationService: import_protocols4.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2293
2149
  },
2294
2150
  exposed: {
2295
- NotarizationService: import_protocols5.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2151
+ NotarizationService: import_protocols4.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2296
2152
  }
2297
2153
  });
2298
2154
  this._params = _params;
@@ -2330,9 +2186,9 @@ var __decorate = function(decorators, target, key, desc) {
2330
2186
  var AUTH_TIMEOUT2 = 3e4;
2331
2187
  var DataSpace = class DataSpace2 {
2332
2188
  constructor(params) {
2333
- this._ctx = new import_context6.Context();
2334
- this._state = import_client3.SpaceState.CLOSED;
2335
- this.stateUpdate = new import_async10.Event();
2189
+ this._ctx = new import_context5.Context();
2190
+ this._state = import_client2.SpaceState.CLOSED;
2191
+ this.stateUpdate = new import_async9.Event();
2336
2192
  var _a;
2337
2193
  this._inner = params.inner;
2338
2194
  this._inner.stateUpdate.on(this._ctx, () => this.stateUpdate.emit());
@@ -2353,7 +2209,7 @@ var DataSpace = class DataSpace2 {
2353
2209
  snapshotId: params.snapshotId
2354
2210
  });
2355
2211
  this.authVerifier = new TrustedKeySetAuthVerifier({
2356
- trustedKeysProvider: () => new import_util4.ComplexSet(import_keys9.PublicKey.hash, Array.from(this._inner.spaceState.members.keys())),
2212
+ trustedKeysProvider: () => new import_util4.ComplexSet(import_keys8.PublicKey.hash, Array.from(this._inner.spaceState.members.keys())),
2357
2213
  update: this._inner.stateUpdate,
2358
2214
  authTimeout: AUTH_TIMEOUT2
2359
2215
  });
@@ -2385,10 +2241,10 @@ var DataSpace = class DataSpace2 {
2385
2241
  await this.notarizationPlugin.open();
2386
2242
  await this._notarizationPluginConsumer.open();
2387
2243
  await this._inner.open();
2388
- this._state = import_client3.SpaceState.INACTIVE;
2244
+ this._state = import_client2.SpaceState.INACTIVE;
2389
2245
  }
2390
2246
  async close() {
2391
- this._state = import_client3.SpaceState.CLOSED;
2247
+ this._state = import_client2.SpaceState.CLOSED;
2392
2248
  await this._ctx.dispose();
2393
2249
  await this._dataPipeline.close();
2394
2250
  await this.authVerifier.close();
@@ -2407,7 +2263,7 @@ var DataSpace = class DataSpace2 {
2407
2263
  * Initialize the data pipeline in a separate task.
2408
2264
  */
2409
2265
  initializeDataPipelineAsync() {
2410
- (0, import_async10.scheduleTask)(this._ctx, async () => {
2266
+ (0, import_async9.scheduleTask)(this._ctx, async () => {
2411
2267
  try {
2412
2268
  await this.initializeDataPipeline();
2413
2269
  } catch (err) {
@@ -2431,10 +2287,10 @@ var DataSpace = class DataSpace2 {
2431
2287
  }
2432
2288
  async initializeDataPipeline() {
2433
2289
  var _a, _b, _c, _d;
2434
- if (this._state !== import_client3.SpaceState.INACTIVE) {
2290
+ if (this._state !== import_client2.SpaceState.INACTIVE) {
2435
2291
  throw new import_errors.SystemError("Invalid operation");
2436
2292
  }
2437
- this._state = import_client3.SpaceState.INITIALIZING;
2293
+ this._state = import_client2.SpaceState.INITIALIZING;
2438
2294
  await this._inner.controlPipeline.state.waitUntilReachedTargetTimeframe({
2439
2295
  ctx: this._ctx,
2440
2296
  breakOnStall: false
@@ -2478,7 +2334,7 @@ var DataSpace = class DataSpace2 {
2478
2334
  callSite: (f, a) => f(...a)
2479
2335
  });
2480
2336
  await ((_b = (_a = this._callbacks).beforeReady) == null ? void 0 : _b.call(_a));
2481
- this._state = import_client3.SpaceState.READY;
2337
+ this._state = import_client2.SpaceState.READY;
2482
2338
  this.stateUpdate.emit();
2483
2339
  await ((_d = (_c = this._callbacks).afterReady) == null ? void 0 : _d.call(_c));
2484
2340
  }
@@ -2530,7 +2386,7 @@ __decorate([
2530
2386
  (0, import_debug3.timed)(1e4)
2531
2387
  ], DataSpace.prototype, "_createWritableFeeds", null);
2532
2388
  DataSpace = __decorate([
2533
- (0, import_async10.trackLeaks)("open", "close")
2389
+ (0, import_async9.trackLeaks)("open", "close")
2534
2390
  ], DataSpace);
2535
2391
 
2536
2392
  // packages/sdk/client-services/src/packlets/spaces/data-space-manager.ts
@@ -2554,10 +2410,11 @@ var DataSpaceManager = class DataSpaceManager2 {
2554
2410
  this._modelFactory = _modelFactory;
2555
2411
  this._feedStore = _feedStore;
2556
2412
  this._snapshotStore = _snapshotStore;
2557
- this._ctx = new import_context7.Context();
2558
- this.updated = new import_async11.Event();
2559
- this._spaces = new import_util5.ComplexMap(import_keys10.PublicKey.hash);
2413
+ this._ctx = new import_context6.Context();
2414
+ this.updated = new import_async10.Event();
2415
+ this._spaces = new import_util5.ComplexMap(import_keys9.PublicKey.hash);
2560
2416
  this._isOpen = false;
2417
+ this._instanceId = import_keys9.PublicKey.random().toHex();
2561
2418
  }
2562
2419
  // TODO(burdon): Remove.
2563
2420
  get spaces() {
@@ -2566,7 +2423,16 @@ var DataSpaceManager = class DataSpaceManager2 {
2566
2423
  async open() {
2567
2424
  (0, import_log9.log)("open", {}, {
2568
2425
  file: "data-space-manager.ts",
2569
- line: 80,
2426
+ line: 83,
2427
+ scope: this,
2428
+ callSite: (f, a) => f(...a)
2429
+ });
2430
+ import_log9.log.trace("dxos.echo.data-space-manager", import_protocols5.trace.begin({
2431
+ id: this._instanceId,
2432
+ parentId: this._traceParent
2433
+ }), {
2434
+ file: "data-space-manager.ts",
2435
+ line: 84,
2570
2436
  scope: this,
2571
2437
  callSite: (f, a) => f(...a)
2572
2438
  });
@@ -2575,7 +2441,7 @@ var DataSpaceManager = class DataSpaceManager2 {
2575
2441
  spaces: this._metadataStore.spaces.length
2576
2442
  }, {
2577
2443
  file: "data-space-manager.ts",
2578
- line: 82,
2444
+ line: 86,
2579
2445
  scope: this,
2580
2446
  callSite: (f, a) => f(...a)
2581
2447
  });
@@ -2584,7 +2450,7 @@ var DataSpaceManager = class DataSpaceManager2 {
2584
2450
  spaceMetadata
2585
2451
  }, {
2586
2452
  file: "data-space-manager.ts",
2587
- line: 85,
2453
+ line: 89,
2588
2454
  scope: this,
2589
2455
  callSite: (f, a) => f(...a)
2590
2456
  });
@@ -2597,7 +2463,7 @@ var DataSpaceManager = class DataSpaceManager2 {
2597
2463
  async close() {
2598
2464
  (0, import_log9.log)("close", {}, {
2599
2465
  file: "data-space-manager.ts",
2600
- line: 96,
2466
+ line: 100,
2601
2467
  scope: this,
2602
2468
  callSite: (f, a) => f(...a)
2603
2469
  });
@@ -2606,6 +2472,14 @@ var DataSpaceManager = class DataSpaceManager2 {
2606
2472
  for (const space of this._spaces.values()) {
2607
2473
  await space.close();
2608
2474
  }
2475
+ import_log9.log.trace("dxos.echo.data-space-manager", import_protocols5.trace.end({
2476
+ id: this._instanceId
2477
+ }), {
2478
+ file: "data-space-manager.ts",
2479
+ line: 106,
2480
+ scope: this,
2481
+ callSite: (f, a) => f(...a)
2482
+ });
2609
2483
  }
2610
2484
  /**
2611
2485
  * Creates a new space writing the genesis credentials to the control feed.
@@ -2625,7 +2499,7 @@ var DataSpaceManager = class DataSpaceManager2 {
2625
2499
  spaceKey
2626
2500
  }, {
2627
2501
  file: "data-space-manager.ts",
2628
- line: 120,
2502
+ line: 125,
2629
2503
  scope: this,
2630
2504
  callSite: (f, a) => f(...a)
2631
2505
  });
@@ -2645,7 +2519,7 @@ var DataSpaceManager = class DataSpaceManager2 {
2645
2519
  opts
2646
2520
  }, {
2647
2521
  file: "data-space-manager.ts",
2648
- line: 139,
2522
+ line: 144,
2649
2523
  scope: this,
2650
2524
  callSite: (f, a) => f(...a)
2651
2525
  });
@@ -2669,9 +2543,9 @@ var DataSpaceManager = class DataSpaceManager2 {
2669
2543
  * TODO(dmaretskyi): Consider removing.
2670
2544
  */
2671
2545
  async waitUntilSpaceReady(spaceKey) {
2672
- await (0, import_context7.cancelWithContext)(this._ctx, this.updated.waitForCondition(() => {
2546
+ await (0, import_context6.cancelWithContext)(this._ctx, this.updated.waitForCondition(() => {
2673
2547
  const space = this._spaces.get(spaceKey);
2674
- return !!space && space.state === import_client4.SpaceState.READY;
2548
+ return !!space && space.state === import_client3.SpaceState.READY;
2675
2549
  }));
2676
2550
  }
2677
2551
  async _constructSpace(metadata) {
@@ -2679,7 +2553,7 @@ var DataSpaceManager = class DataSpaceManager2 {
2679
2553
  metadata
2680
2554
  }, {
2681
2555
  file: "data-space-manager.ts",
2682
- line: 175,
2556
+ line: 180,
2683
2557
  scope: this,
2684
2558
  callSite: (f, a) => f(...a)
2685
2559
  });
@@ -2734,7 +2608,7 @@ var DataSpaceManager = class DataSpaceManager2 {
2734
2608
  space: space.key
2735
2609
  }, {
2736
2610
  file: "data-space-manager.ts",
2737
- line: 224,
2611
+ line: 229,
2738
2612
  scope: this,
2739
2613
  callSite: (f, a) => f(...a)
2740
2614
  });
@@ -2746,7 +2620,7 @@ var DataSpaceManager = class DataSpaceManager2 {
2746
2620
  open: this._isOpen
2747
2621
  }, {
2748
2622
  file: "data-space-manager.ts",
2749
- line: 231,
2623
+ line: 236,
2750
2624
  scope: this,
2751
2625
  callSite: (f, a) => f(...a)
2752
2626
  });
@@ -2768,28 +2642,28 @@ var DataSpaceManager = class DataSpaceManager2 {
2768
2642
  }
2769
2643
  };
2770
2644
  __decorate2([
2771
- import_async11.synchronized
2645
+ import_async10.synchronized
2772
2646
  ], DataSpaceManager.prototype, "open", null);
2773
2647
  __decorate2([
2774
- import_async11.synchronized
2648
+ import_async10.synchronized
2775
2649
  ], DataSpaceManager.prototype, "close", null);
2776
2650
  __decorate2([
2777
- import_async11.synchronized
2651
+ import_async10.synchronized
2778
2652
  ], DataSpaceManager.prototype, "createSpace", null);
2779
2653
  __decorate2([
2780
- import_async11.synchronized
2654
+ import_async10.synchronized
2781
2655
  ], DataSpaceManager.prototype, "acceptSpace", null);
2782
2656
  DataSpaceManager = __decorate2([
2783
- (0, import_async11.trackLeaks)("open", "close")
2657
+ (0, import_async10.trackLeaks)("open", "close")
2784
2658
  ], DataSpaceManager);
2785
2659
 
2786
2660
  // packages/sdk/client-services/src/packlets/spaces/spaces-service.ts
2787
- var import_async12 = require("@dxos/async");
2661
+ var import_async11 = require("@dxos/async");
2788
2662
  var import_codec_protobuf10 = require("@dxos/codec-protobuf");
2789
2663
  var import_debug4 = require("@dxos/debug");
2790
2664
  var import_echo_pipeline3 = require("@dxos/echo-pipeline");
2791
2665
  var import_log10 = require("@dxos/log");
2792
- var import_services5 = require("@dxos/protocols/proto/dxos/client/services");
2666
+ var import_services6 = require("@dxos/protocols/proto/dxos/client/services");
2793
2667
  var import_util6 = require("@dxos/util");
2794
2668
  var TIMEFRAME_UPDATE_DEBOUNCE_TIME = 500;
2795
2669
  var SpacesServiceImpl = class {
@@ -2827,9 +2701,9 @@ var SpacesServiceImpl = class {
2827
2701
  spaces
2828
2702
  });
2829
2703
  };
2830
- (0, import_async12.scheduleTask)(ctx, async () => {
2704
+ (0, import_async11.scheduleTask)(ctx, async () => {
2831
2705
  const dataSpaceManager = await this._getDataSpaceManager();
2832
- const subscriptions = new import_async12.EventSubscriptions();
2706
+ const subscriptions = new import_async11.EventSubscriptions();
2833
2707
  ctx.onDispose(() => subscriptions.clear());
2834
2708
  const subscribeSpaces = () => {
2835
2709
  subscriptions.clear();
@@ -2864,7 +2738,7 @@ var SpacesServiceImpl = class {
2864
2738
  }
2865
2739
  subscribeMessages({ spaceKey, channel }) {
2866
2740
  return new import_codec_protobuf10.Stream(({ ctx, next }) => {
2867
- (0, import_async12.scheduleTask)(ctx, async () => {
2741
+ (0, import_async11.scheduleTask)(ctx, async () => {
2868
2742
  var _a;
2869
2743
  const dataSpaceManager = await this._getDataSpaceManager();
2870
2744
  const space = (_a = dataSpaceManager.spaces.get(spaceKey)) != null ? _a : (0, import_debug4.raise)(new import_echo_pipeline3.SpaceNotFoundError(spaceKey));
@@ -2885,7 +2759,7 @@ var SpacesServiceImpl = class {
2885
2759
  }
2886
2760
  });
2887
2761
  ctx.onDispose(() => processor.close());
2888
- (0, import_async12.scheduleTask)(ctx, () => processor.open());
2762
+ (0, import_async11.scheduleTask)(ctx, () => processor.open());
2889
2763
  });
2890
2764
  }
2891
2765
  async writeCredentials({ spaceKey, credentials }) {
@@ -2900,18 +2774,22 @@ var SpacesServiceImpl = class {
2900
2774
  }
2901
2775
  }
2902
2776
  _transformSpace(space) {
2903
- var _a, _b;
2777
+ var _a, _b, _c, _d, _e;
2904
2778
  return {
2905
2779
  spaceKey: space.key,
2906
2780
  state: space.state,
2907
2781
  pipeline: {
2908
- targetControlTimeframe: space.inner.controlPipeline.state.targetTimeframe,
2782
+ controlFeeds: space.inner.controlPipeline.state.feeds.map((feed) => feed.key),
2909
2783
  currentControlTimeframe: space.inner.controlPipeline.state.timeframe,
2910
- currentDataTimeframe: (_a = space.dataPipeline.pipelineState) == null ? void 0 : _a.timeframe,
2911
- targetDataTimeframe: (_b = space.dataPipeline.pipelineState) == null ? void 0 : _b.targetTimeframe
2784
+ targetControlTimeframe: space.inner.controlPipeline.state.targetTimeframe,
2785
+ totalControlTimeframe: space.inner.controlPipeline.state.endTimeframe,
2786
+ dataFeeds: (_b = (_a = space.dataPipeline.pipelineState) == null ? void 0 : _a.feeds.map((feed) => feed.key)) != null ? _b : [],
2787
+ currentDataTimeframe: (_c = space.dataPipeline.pipelineState) == null ? void 0 : _c.timeframe,
2788
+ targetDataTimeframe: (_d = space.dataPipeline.pipelineState) == null ? void 0 : _d.targetTimeframe,
2789
+ totalDataTimeframe: (_e = space.dataPipeline.pipelineState) == null ? void 0 : _e.endTimeframe
2912
2790
  },
2913
2791
  members: Array.from(space.inner.spaceState.members.values()).map((member) => {
2914
- var _a2, _b2, _c;
2792
+ var _a2, _b2, _c2;
2915
2793
  return {
2916
2794
  identity: {
2917
2795
  identityKey: member.key,
@@ -2919,7 +2797,7 @@ var SpacesServiceImpl = class {
2919
2797
  displayName: (_b2 = (_a2 = member.assertion.profile) == null ? void 0 : _a2.displayName) != null ? _b2 : (0, import_util6.humanize)(member.key)
2920
2798
  }
2921
2799
  },
2922
- 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
2800
+ presence: ((_c2 = this._identityManager.identity) == null ? void 0 : _c2.identityKey.equals(member.key)) || space.presence.getPeersOnline().filter(({ identityKey }) => identityKey.equals(member.key)).length > 0 ? import_services6.SpaceMember.PresenceState.ONLINE : import_services6.SpaceMember.PresenceState.OFFLINE
2923
2801
  };
2924
2802
  })
2925
2803
  };
@@ -2967,6 +2845,8 @@ var toStorageType = (type) => {
2967
2845
  return import_random_access_storage.StorageType.IDB;
2968
2846
  case StorageDriver.NODE:
2969
2847
  return import_random_access_storage.StorageType.NODE;
2848
+ case StorageDriver.WEBFS:
2849
+ return import_random_access_storage.StorageType.WEBFS;
2970
2850
  default:
2971
2851
  throw new Error(`Invalid storage type: ${StorageDriver[type]}`);
2972
2852
  }
@@ -3011,10 +2891,10 @@ var SystemServiceImpl = class {
3011
2891
  };
3012
2892
 
3013
2893
  // packages/sdk/client-services/src/packlets/vault/iframe-host-runtime.ts
3014
- var import_async14 = require("@dxos/async");
2894
+ var import_async13 = require("@dxos/async");
3015
2895
  var import_log11 = require("@dxos/log");
3016
2896
  var import_messaging = require("@dxos/messaging");
3017
- var import_network_manager3 = require("@dxos/network-manager");
2897
+ var import_network_manager2 = require("@dxos/network-manager");
3018
2898
  var import_util7 = require("@dxos/util");
3019
2899
 
3020
2900
  // packages/sdk/client-services/src/packlets/services/client-rpc-server.ts
@@ -3072,14 +2952,14 @@ var ClientRpcServer = class {
3072
2952
 
3073
2953
  // packages/sdk/client-services/src/packlets/vault/shell-runtime.ts
3074
2954
  var import_node_assert10 = __toESM(require("node:assert"));
3075
- var import_async13 = require("@dxos/async");
3076
- var import_client5 = require("@dxos/client");
2955
+ var import_async12 = require("@dxos/async");
2956
+ var import_client4 = require("@dxos/client");
3077
2957
  var import_iframe = require("@dxos/protocols/proto/dxos/iframe");
3078
2958
  var import_rpc2 = require("@dxos/rpc");
3079
2959
  var ShellRuntimeImpl = class {
3080
2960
  constructor(_port) {
3081
2961
  this._port = _port;
3082
- this.layoutUpdate = new import_async13.Event();
2962
+ this.layoutUpdate = new import_async12.Event();
3083
2963
  this._layout = import_iframe.ShellLayout.DEFAULT;
3084
2964
  }
3085
2965
  get layout() {
@@ -3106,8 +2986,8 @@ var ShellRuntimeImpl = class {
3106
2986
  }
3107
2987
  async open() {
3108
2988
  this._appRpc = (0, import_rpc2.createProtoRpcPeer)({
3109
- requested: import_client5.appServiceBundle,
3110
- exposed: import_client5.shellServiceBundle,
2989
+ requested: import_client4.appServiceBundle,
2990
+ exposed: import_client4.shellServiceBundle,
3111
2991
  handlers: {
3112
2992
  ShellService: {
3113
2993
  setLayout: async (request) => {
@@ -3143,8 +3023,8 @@ var __decorate3 = function(decorators, target, key, desc) {
3143
3023
  var LOCK_KEY = "DXOS_RESOURCE_LOCK";
3144
3024
  var IFrameHostRuntime = class {
3145
3025
  constructor({ configProvider, appPort, shellPort }) {
3146
- this._transportFactory = (0, import_network_manager3.createWebRTCTransportFactory)();
3147
- this._ready = new import_async14.Trigger();
3026
+ this._transportFactory = (0, import_network_manager2.createWebRTCTransportFactory)();
3027
+ this._ready = new import_async13.Trigger();
3148
3028
  this._configProvider = configProvider;
3149
3029
  this._appPort = appPort;
3150
3030
  this._shellPort = shellPort;
@@ -3172,7 +3052,7 @@ var IFrameHostRuntime = class {
3172
3052
  this._clientServices = new LocalClientServices({
3173
3053
  lockKey: LOCK_KEY,
3174
3054
  config: this._config,
3175
- networkManager: new import_network_manager3.NetworkManager({
3055
+ networkManager: new import_network_manager2.NetworkManager({
3176
3056
  log: true,
3177
3057
  signalManager: signalServer ? new import_messaging.WebsocketSignalManager([
3178
3058
  signalServer
@@ -3251,12 +3131,12 @@ __decorate3([
3251
3131
  ], IFrameHostRuntime.prototype, "origin", void 0);
3252
3132
 
3253
3133
  // packages/sdk/client-services/src/packlets/vault/iframe-proxy-runtime.ts
3254
- var import_client6 = require("@dxos/client");
3255
- var import_network_manager4 = require("@dxos/network-manager");
3134
+ var import_client5 = require("@dxos/client");
3135
+ var import_network_manager3 = require("@dxos/network-manager");
3256
3136
  var import_rpc3 = require("@dxos/rpc");
3257
3137
 
3258
3138
  // packages/sdk/client-services/src/packlets/vault/vault-resource-lock.ts
3259
- var import_async15 = require("@dxos/async");
3139
+ var import_async14 = require("@dxos/async");
3260
3140
  var import_log12 = require("@dxos/log");
3261
3141
  var __decorate4 = function(decorators, target, key, desc) {
3262
3142
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -3275,7 +3155,7 @@ var Message;
3275
3155
  var VaultResourceLock = class {
3276
3156
  constructor({ lockKey, onAcquire, onRelease }) {
3277
3157
  this._broadcastChannel = new BroadcastChannel("vault-resource-lock");
3278
- this._releaseTrigger = new import_async15.Trigger();
3158
+ this._releaseTrigger = new import_async14.Trigger();
3279
3159
  this._lockKey = lockKey;
3280
3160
  this._onAcquire = onAcquire;
3281
3161
  this._onRelease = onRelease;
@@ -3295,7 +3175,7 @@ var VaultResourceLock = class {
3295
3175
  scope: this,
3296
3176
  callSite: (f, a) => f(...a)
3297
3177
  });
3298
- await (0, import_async15.asyncTimeout)(this._requestLock(), 3e3);
3178
+ await (0, import_async14.asyncTimeout)(this._requestLock(), 3e3);
3299
3179
  (0, import_log12.log)("acquired lock", {}, {
3300
3180
  file: "vault-resource-lock.ts",
3301
3181
  line: 46,
@@ -3335,14 +3215,14 @@ var VaultResourceLock = class {
3335
3215
  scope: this,
3336
3216
  callSite: (f, a) => f(...a)
3337
3217
  });
3338
- const acquired = new import_async15.Trigger();
3218
+ const acquired = new import_async14.Trigger();
3339
3219
  void navigator.locks.request(this._lockKey, {
3340
3220
  steal
3341
3221
  }, async () => {
3342
3222
  var _a, _b;
3343
3223
  await ((_a = this._onAcquire) == null ? void 0 : _a.call(this));
3344
3224
  acquired.wake();
3345
- this._releaseTrigger = new import_async15.Trigger();
3225
+ this._releaseTrigger = new import_async14.Trigger();
3346
3226
  await this._releaseTrigger.wait();
3347
3227
  (0, import_log12.log)("releasing lock...", {}, {
3348
3228
  file: "vault-resource-lock.ts",
@@ -3377,15 +3257,15 @@ __decorate4([
3377
3257
  ], VaultResourceLock.prototype, "lockKey", null);
3378
3258
 
3379
3259
  // packages/sdk/client-services/src/packlets/vault/worker-runtime.ts
3380
- var import_async17 = require("@dxos/async");
3260
+ var import_async16 = require("@dxos/async");
3381
3261
  var import_log14 = require("@dxos/log");
3382
3262
  var import_messaging2 = require("@dxos/messaging");
3383
- var import_network_manager5 = require("@dxos/network-manager");
3263
+ var import_network_manager4 = require("@dxos/network-manager");
3384
3264
 
3385
3265
  // packages/sdk/client-services/src/packlets/vault/worker-session.ts
3386
3266
  var import_node_assert11 = __toESM(require("node:assert"));
3387
- var import_async16 = require("@dxos/async");
3388
- var import_client7 = require("@dxos/client");
3267
+ var import_async15 = require("@dxos/async");
3268
+ var import_client6 = require("@dxos/client");
3389
3269
  var import_log13 = require("@dxos/log");
3390
3270
  var import_rpc4 = require("@dxos/rpc");
3391
3271
  var import_util8 = require("@dxos/util");
@@ -3403,7 +3283,7 @@ var WorkerSession = class {
3403
3283
  constructor({ serviceHost, systemPort, appPort, shellPort, readySignal, options = {
3404
3284
  heartbeatInterval: 1e3
3405
3285
  } }) {
3406
- this._startTrigger = new import_async16.Trigger();
3286
+ this._startTrigger = new import_async15.Trigger();
3407
3287
  this.onClose = new import_util8.Callback();
3408
3288
  (0, import_node_assert11.default)(options);
3409
3289
  (0, import_node_assert11.default)(serviceHost);
@@ -3440,8 +3320,8 @@ var WorkerSession = class {
3440
3320
  ...middleware
3441
3321
  });
3442
3322
  this._iframeRpc = (0, import_rpc4.createProtoRpcPeer)({
3443
- requested: import_client7.iframeServiceBundle,
3444
- exposed: import_client7.workerServiceBundle,
3323
+ requested: import_client6.iframeServiceBundle,
3324
+ exposed: import_client6.workerServiceBundle,
3445
3325
  handlers: {
3446
3326
  WorkerService: {
3447
3327
  start: async (request) => {
@@ -3537,7 +3417,7 @@ var WorkerSession = class {
3537
3417
  }
3538
3418
  async _maybeOpenShell() {
3539
3419
  try {
3540
- await (0, import_async16.asyncTimeout)(this._shellClientRpc.open(), 1e3);
3420
+ await (0, import_async15.asyncTimeout)(this._shellClientRpc.open(), 1e3);
3541
3421
  } catch (e) {
3542
3422
  import_log13.log.info("No shell connected.", {}, {
3543
3423
  file: "worker-session.ts",
@@ -3553,13 +3433,15 @@ __decorate5([
3553
3433
  ], WorkerSession.prototype, "origin", void 0);
3554
3434
 
3555
3435
  // packages/sdk/client-services/src/packlets/services/service-context.ts
3556
- var import_async18 = require("@dxos/async");
3436
+ var import_node_assert12 = __toESM(require("node:assert"));
3437
+ var import_async17 = require("@dxos/async");
3438
+ var import_client7 = require("@dxos/client");
3557
3439
  var import_credentials12 = require("@dxos/credentials");
3558
3440
  var import_debug6 = require("@dxos/debug");
3559
3441
  var import_echo_pipeline4 = require("@dxos/echo-pipeline");
3560
3442
  var import_feed_store4 = require("@dxos/feed-store");
3561
3443
  var import_keyring = require("@dxos/keyring");
3562
- var import_keys11 = require("@dxos/keys");
3444
+ var import_keys10 = require("@dxos/keys");
3563
3445
  var import_log15 = require("@dxos/log");
3564
3446
  var import_protocols6 = require("@dxos/protocols");
3565
3447
  var ServiceContext = class {
@@ -3568,9 +3450,11 @@ var ServiceContext = class {
3568
3450
  this.storage = storage;
3569
3451
  this.networkManager = networkManager;
3570
3452
  this.modelFactory = modelFactory;
3571
- this.initialized = new import_async18.Trigger();
3453
+ this.initialized = new import_async17.Trigger();
3572
3454
  this.dataServiceSubscriptions = new import_echo_pipeline4.DataServiceSubscriptions();
3573
- this._instanceId = import_keys11.PublicKey.random().toHex();
3455
+ this._handlerFactories = /* @__PURE__ */ new Map();
3456
+ this._instanceId = import_keys10.PublicKey.random().toHex();
3457
+ networkManager._traceParent = this._instanceId;
3574
3458
  this.metadataStore = new import_echo_pipeline4.MetadataStore(storage.createDirectory("metadata"));
3575
3459
  this.snapshotStore = new import_echo_pipeline4.SnapshotStore(storage.createDirectory("snapshots"));
3576
3460
  this.keyring = new import_keyring.Keyring(storage.createDirectory("keyring"));
@@ -3587,29 +3471,27 @@ var ServiceContext = class {
3587
3471
  feedStore: this.feedStore,
3588
3472
  networkManager: this.networkManager
3589
3473
  });
3474
+ this.spaceManager._traceParent = this._instanceId;
3590
3475
  this.identityManager = new IdentityManager(this.metadataStore, this.keyring, this.feedStore, this.spaceManager);
3591
- this.deviceInvitations = new DeviceInvitationsHandler({
3592
- networkManager: this.networkManager,
3593
- getIdentity: () => {
3594
- var _a;
3595
- return (_a = this.identityManager.identity) != null ? _a : (0, import_debug6.failUndefined)();
3596
- },
3597
- acceptIdentity: this._acceptIdentity.bind(this),
3598
- keyring: this.keyring
3599
- });
3476
+ this.identityManager._traceParent = this._instanceId;
3477
+ this.invitations = new InvitationsHandler(this.networkManager);
3478
+ this._handlerFactories.set(import_client7.Invitation.Kind.DEVICE, () => new DeviceInvitationProtocol(this.keyring, () => {
3479
+ var _a;
3480
+ return (_a = this.identityManager.identity) != null ? _a : (0, import_debug6.failUndefined)();
3481
+ }, this._acceptIdentity.bind(this)));
3600
3482
  }
3601
3483
  async open() {
3602
- import_log15.log.trace("dxos.sdk.client-services", import_protocols6.trace.begin({
3484
+ import_log15.log.trace("dxos.sdk.service-context", import_protocols6.trace.begin({
3603
3485
  id: this._instanceId
3604
3486
  }), {
3605
3487
  file: "service-context.ts",
3606
- line: 98,
3488
+ line: 114,
3607
3489
  scope: this,
3608
3490
  callSite: (f, a) => f(...a)
3609
3491
  });
3610
3492
  (0, import_log15.log)("opening...", {}, {
3611
3493
  file: "service-context.ts",
3612
- line: 100,
3494
+ line: 116,
3613
3495
  scope: this,
3614
3496
  callSite: (f, a) => f(...a)
3615
3497
  });
@@ -3621,7 +3503,7 @@ var ServiceContext = class {
3621
3503
  }
3622
3504
  (0, import_log15.log)("opened", {}, {
3623
3505
  file: "service-context.ts",
3624
- line: 107,
3506
+ line: 123,
3625
3507
  scope: this,
3626
3508
  callSite: (f, a) => f(...a)
3627
3509
  });
@@ -3630,7 +3512,7 @@ var ServiceContext = class {
3630
3512
  var _a, _b;
3631
3513
  (0, import_log15.log)("closing...", {}, {
3632
3514
  file: "service-context.ts",
3633
- line: 111,
3515
+ line: 127,
3634
3516
  scope: this,
3635
3517
  callSite: (f, a) => f(...a)
3636
3518
  });
@@ -3643,15 +3525,15 @@ var ServiceContext = class {
3643
3525
  this.dataServiceSubscriptions.clear();
3644
3526
  (0, import_log15.log)("closed", {}, {
3645
3527
  file: "service-context.ts",
3646
- line: 119,
3528
+ line: 135,
3647
3529
  scope: this,
3648
3530
  callSite: (f, a) => f(...a)
3649
3531
  });
3650
- import_log15.log.trace("dxos.sdk.client-services", import_protocols6.trace.end({
3532
+ import_log15.log.trace("dxos.sdk.service-context", import_protocols6.trace.end({
3651
3533
  id: this._instanceId
3652
3534
  }), {
3653
3535
  file: "service-context.ts",
3654
- line: 121,
3536
+ line: 137,
3655
3537
  scope: this,
3656
3538
  callSite: (f, a) => f(...a)
3657
3539
  });
@@ -3659,7 +3541,7 @@ var ServiceContext = class {
3659
3541
  async reset() {
3660
3542
  (0, import_log15.log)("resetting...", {}, {
3661
3543
  file: "service-context.ts",
3662
- line: 125,
3544
+ line: 141,
3663
3545
  scope: this,
3664
3546
  callSite: (f, a) => f(...a)
3665
3547
  });
@@ -3667,7 +3549,7 @@ var ServiceContext = class {
3667
3549
  await this.storage.reset();
3668
3550
  (0, import_log15.log)("reset", {}, {
3669
3551
  file: "service-context.ts",
3670
- line: 128,
3552
+ line: 144,
3671
3553
  scope: this,
3672
3554
  callSite: (f, a) => f(...a)
3673
3555
  });
@@ -3677,6 +3559,11 @@ var ServiceContext = class {
3677
3559
  await this._initialize();
3678
3560
  return identity;
3679
3561
  }
3562
+ getInvitationHandler(invitation) {
3563
+ const factory = this._handlerFactories.get(invitation.kind);
3564
+ (0, import_node_assert12.default)(factory, `Unknown invitation kind: ${invitation.kind}`);
3565
+ return factory(invitation);
3566
+ }
3680
3567
  async _acceptIdentity(params) {
3681
3568
  const identity = await this.identityManager.acceptIdentity(params);
3682
3569
  await this._initialize();
@@ -3687,7 +3574,7 @@ var ServiceContext = class {
3687
3574
  var _a;
3688
3575
  (0, import_log15.log)("initializing spaces...", {}, {
3689
3576
  file: "service-context.ts",
3690
- line: 147,
3577
+ line: 169,
3691
3578
  scope: this,
3692
3579
  callSite: (f, a) => f(...a)
3693
3580
  });
@@ -3706,8 +3593,12 @@ var ServiceContext = class {
3706
3593
  }
3707
3594
  };
3708
3595
  this.dataSpaceManager = new DataSpaceManager(this.spaceManager, this.metadataStore, this.dataServiceSubscriptions, this.keyring, signingContext, this.modelFactory, this.feedStore, this.snapshotStore);
3596
+ this.dataSpaceManager._traceParent = this._instanceId;
3709
3597
  await this.dataSpaceManager.open();
3710
- this.spaceInvitations = new SpaceInvitationsHandler(this.networkManager, this.dataSpaceManager, signingContext, this.keyring);
3598
+ this._handlerFactories.set(import_client7.Invitation.Kind.SPACE, (invitation) => {
3599
+ (0, import_node_assert12.default)(this.dataSpaceManager, "dataSpaceManager not initialized yet");
3600
+ return new SpaceInvitationProtocol(this.dataSpaceManager, signingContext, this.keyring, invitation.spaceKey);
3601
+ });
3711
3602
  this.initialized.wake();
3712
3603
  this._deviceSpaceSync = identity.space.spaceState.registerProcessor({
3713
3604
  process: async (credential) => {
@@ -3723,7 +3614,7 @@ var ServiceContext = class {
3723
3614
  details: assertion
3724
3615
  }, {
3725
3616
  file: "service-context.ts",
3726
- line: 190,
3617
+ line: 211,
3727
3618
  scope: this,
3728
3619
  callSite: (f, a) => f(...a)
3729
3620
  });
@@ -3734,7 +3625,7 @@ var ServiceContext = class {
3734
3625
  details: assertion
3735
3626
  }, {
3736
3627
  file: "service-context.ts",
3737
- line: 194,
3628
+ line: 215,
3738
3629
  scope: this,
3739
3630
  callSite: (f, a) => f(...a)
3740
3631
  });
@@ -3745,7 +3636,7 @@ var ServiceContext = class {
3745
3636
  details: assertion
3746
3637
  }, {
3747
3638
  file: "service-context.ts",
3748
- line: 199,
3639
+ line: 220,
3749
3640
  scope: this,
3750
3641
  callSite: (f, a) => f(...a)
3751
3642
  });
@@ -3756,7 +3647,7 @@ var ServiceContext = class {
3756
3647
  } catch (err) {
3757
3648
  import_log15.log.catch(err, {}, {
3758
3649
  file: "service-context.ts",
3759
- line: 205,
3650
+ line: 226,
3760
3651
  scope: this,
3761
3652
  callSite: (f, a) => f(...a)
3762
3653
  });
@@ -3802,7 +3693,7 @@ var ClientServicesHost = class {
3802
3693
  // TODO(wittjosiah): Turn this on by default.
3803
3694
  lockKey
3804
3695
  } = {}) {
3805
- this._statusUpdate = new import_async19.Event();
3696
+ this._statusUpdate = new import_async18.Event();
3806
3697
  this._opening = false;
3807
3698
  this._open = false;
3808
3699
  this._instanceId = import_client8.PublicKey.random().toHex();
@@ -3824,17 +3715,17 @@ var ClientServicesHost = class {
3824
3715
  this._systemService = new SystemServiceImpl({
3825
3716
  config: this._config,
3826
3717
  statusUpdate: this._statusUpdate,
3827
- getCurrentStatus: () => this.isOpen ? import_services8.SystemStatus.ACTIVE : import_services8.SystemStatus.INACTIVE,
3718
+ getCurrentStatus: () => this.isOpen ? import_services9.SystemStatus.ACTIVE : import_services9.SystemStatus.INACTIVE,
3828
3719
  onUpdateStatus: async (status) => {
3829
3720
  var _a, _b;
3830
- if (!this.isOpen && status === import_services8.SystemStatus.ACTIVE) {
3721
+ if (!this.isOpen && status === import_services9.SystemStatus.ACTIVE) {
3831
3722
  await ((_a = this._resourceLock) == null ? void 0 : _a.acquire());
3832
- } else if (this.isOpen && status === import_services8.SystemStatus.INACTIVE) {
3723
+ } else if (this.isOpen && status === import_services9.SystemStatus.INACTIVE) {
3833
3724
  await ((_b = this._resourceLock) == null ? void 0 : _b.release());
3834
3725
  }
3835
3726
  },
3836
3727
  onReset: async () => {
3837
- (0, import_node_assert12.default)(this._serviceContext, "service host is closed");
3728
+ (0, import_node_assert13.default)(this._serviceContext, "service host is closed");
3838
3729
  await this._serviceContext.reset();
3839
3730
  }
3840
3731
  });
@@ -3860,16 +3751,16 @@ var ClientServicesHost = class {
3860
3751
  * Can only be called once.
3861
3752
  */
3862
3753
  initialize({ config, networkManager }) {
3863
- (0, import_node_assert12.default)(!this._open, "service host is open");
3754
+ (0, import_node_assert13.default)(!this._open, "service host is open");
3864
3755
  if (config) {
3865
- (0, import_node_assert12.default)(!this._config, "config already set");
3756
+ (0, import_node_assert13.default)(!this._config, "config already set");
3866
3757
  this._config = config;
3867
3758
  if (!this._storage) {
3868
3759
  this._storage = createStorageObjects(config.get("runtime.client.storage", {})).storage;
3869
3760
  }
3870
3761
  }
3871
3762
  if (networkManager) {
3872
- (0, import_node_assert12.default)(!this._networkManager, "network manager already set");
3763
+ (0, import_node_assert13.default)(!this._networkManager, "network manager already set");
3873
3764
  this._networkManager = networkManager;
3874
3765
  }
3875
3766
  }
@@ -3882,19 +3773,19 @@ var ClientServicesHost = class {
3882
3773
  id: this._instanceId
3883
3774
  }), {
3884
3775
  file: "service-host.ts",
3885
- line: 168,
3776
+ line: 167,
3886
3777
  scope: this,
3887
3778
  callSite: (f, a) => f(...a)
3888
3779
  });
3889
- (0, import_node_assert12.default)(this._config, "config not set");
3890
- (0, import_node_assert12.default)(this._storage, "storage not set");
3891
- (0, import_node_assert12.default)(this._networkManager, "network manager not set");
3780
+ (0, import_node_assert13.default)(this._config, "config not set");
3781
+ (0, import_node_assert13.default)(this._storage, "storage not set");
3782
+ (0, import_node_assert13.default)(this._networkManager, "network manager not set");
3892
3783
  this._opening = true;
3893
3784
  (0, import_log16.log)("opening...", {
3894
3785
  lockKey: (_a = this._resourceLock) == null ? void 0 : _a.lockKey
3895
3786
  }, {
3896
3787
  file: "service-host.ts",
3897
- line: 175,
3788
+ line: 174,
3898
3789
  scope: this,
3899
3790
  callSite: (f, a) => f(...a)
3900
3791
  });
@@ -3903,15 +3794,8 @@ var ClientServicesHost = class {
3903
3794
  this._serviceRegistry.setServices({
3904
3795
  SystemService: this._systemService,
3905
3796
  IdentityService: new IdentityServiceImpl(this._serviceContext),
3797
+ InvitationsService: new InvitationsServiceImpl(this._serviceContext.invitations, (invitation) => this._serviceContext.getInvitationHandler(invitation)),
3906
3798
  DevicesService: new DevicesServiceImpl(this._serviceContext.identityManager),
3907
- DeviceInvitationsService: new DeviceInvitationsServiceImpl(this._serviceContext.identityManager, this._serviceContext.deviceInvitations),
3908
- SpaceInvitationsService: new SpaceInvitationsServiceImpl(this._serviceContext.identityManager, () => {
3909
- var _a2;
3910
- return (_a2 = this._serviceContext.spaceInvitations) != null ? _a2 : (0, import_debug7.raise)(new Error("SpaceInvitations not initialized"));
3911
- }, () => {
3912
- var _a2;
3913
- return (_a2 = this._serviceContext.dataSpaceManager) != null ? _a2 : (0, import_debug7.raise)(new Error("SpaceManager not initialized"));
3914
- }),
3915
3799
  SpacesService: new SpacesServiceImpl(this._serviceContext.identityManager, this._serviceContext.spaceManager, this._serviceContext.dataServiceSubscriptions, async () => {
3916
3800
  await this._serviceContext.initialized.wait();
3917
3801
  return this._serviceContext.dataSpaceManager;
@@ -3935,7 +3819,7 @@ var ClientServicesHost = class {
3935
3819
  deviceKey
3936
3820
  }, {
3937
3821
  file: "service-host.ts",
3938
- line: 229,
3822
+ line: 221,
3939
3823
  scope: this,
3940
3824
  callSite: (f, a) => f(...a)
3941
3825
  });
@@ -3950,7 +3834,7 @@ var ClientServicesHost = class {
3950
3834
  deviceKey
3951
3835
  }, {
3952
3836
  file: "service-host.ts",
3953
- line: 238,
3837
+ line: 230,
3954
3838
  scope: this,
3955
3839
  callSite: (f, a) => f(...a)
3956
3840
  });
@@ -3964,7 +3848,7 @@ var ClientServicesHost = class {
3964
3848
  deviceKey
3965
3849
  }, {
3966
3850
  file: "service-host.ts",
3967
- line: 243,
3851
+ line: 235,
3968
3852
  scope: this,
3969
3853
  callSite: (f, a) => f(...a)
3970
3854
  });
@@ -3972,7 +3856,7 @@ var ClientServicesHost = class {
3972
3856
  id: this._instanceId
3973
3857
  }), {
3974
3858
  file: "service-host.ts",
3975
- line: 245,
3859
+ line: 237,
3976
3860
  scope: this,
3977
3861
  callSite: (f, a) => f(...a)
3978
3862
  });
@@ -4005,13 +3889,13 @@ var LocalClientServices = class {
4005
3889
  var import_config2 = require("@dxos/config");
4006
3890
  var import_log17 = require("@dxos/log");
4007
3891
  var import_messaging3 = require("@dxos/messaging");
4008
- var import_network_manager6 = require("@dxos/network-manager");
3892
+ var import_network_manager5 = require("@dxos/network-manager");
4009
3893
 
4010
3894
  // packages/sdk/client-services/src/packlets/testing/host-test-builder.ts
4011
3895
  var createServiceHost = (config, signalManagerContext) => {
4012
- const networkManager = new import_network_manager7.NetworkManager({
3896
+ const networkManager = new import_network_manager6.NetworkManager({
4013
3897
  signalManager: new import_messaging4.MemorySignalManager(signalManagerContext),
4014
- transportFactory: import_network_manager7.MemoryTransportFactory
3898
+ transportFactory: import_network_manager6.MemoryTransportFactory
4015
3899
  });
4016
3900
  return new ClientServicesHost({
4017
3901
  config,
@@ -4021,9 +3905,9 @@ var createServiceHost = (config, signalManagerContext) => {
4021
3905
  var createServiceContext = ({ signalContext = new import_messaging4.MemorySignalManagerContext(), storage = (0, import_random_access_storage2.createStorage)({
4022
3906
  type: import_random_access_storage2.StorageType.RAM
4023
3907
  }) } = {}) => {
4024
- const networkManager = new import_network_manager7.NetworkManager({
3908
+ const networkManager = new import_network_manager6.NetworkManager({
4025
3909
  signalManager: new import_messaging4.MemorySignalManager(signalContext),
4026
- transportFactory: import_network_manager7.MemoryTransportFactory
3910
+ transportFactory: import_network_manager6.MemoryTransportFactory
4027
3911
  });
4028
3912
  const modelFactory = (0, import_client9.createDefaultModelFactory)();
4029
3913
  return new ServiceContext(storage, networkManager, modelFactory);
@@ -4091,9 +3975,9 @@ var TestPeer = class {
4091
3975
  }
4092
3976
  get networkManager() {
4093
3977
  var _a, _b;
4094
- return (_b = (_a = this._props).networkManager) != null ? _b : _a.networkManager = new import_network_manager7.NetworkManager({
3978
+ return (_b = (_a = this._props).networkManager) != null ? _b : _a.networkManager = new import_network_manager6.NetworkManager({
4095
3979
  signalManager: new import_messaging4.MemorySignalManager(this.signalContext),
4096
- transportFactory: import_network_manager7.MemoryTransportFactory
3980
+ transportFactory: import_network_manager6.MemoryTransportFactory
4097
3981
  });
4098
3982
  }
4099
3983
  get spaceManager() {
@@ -4120,60 +4004,193 @@ var createSigningContext = async (keyring) => {
4120
4004
  };
4121
4005
 
4122
4006
  // packages/sdk/client-services/src/packlets/testing/invitation-utils.ts
4123
- var import_node_assert13 = __toESM(require("node:assert"));
4124
- var import_async20 = require("@dxos/async");
4125
- var import_debug8 = require("@dxos/debug");
4126
- var import_services10 = require("@dxos/protocols/proto/dxos/client/services");
4127
- var performInvitation = async (host, guest, context) => {
4128
- const done1 = new import_async20.Trigger();
4129
- const done2 = new import_async20.Trigger();
4130
- const observable1 = await host.createInvitation(context, {
4131
- type: import_services10.Invitation.Type.INTERACTIVE_TESTING
4007
+ var import_node_assert14 = __toESM(require("node:assert"));
4008
+ var import_async19 = require("@dxos/async");
4009
+ var import_client10 = require("@dxos/client");
4010
+ var import_services11 = require("@dxos/protocols/proto/dxos/client/services");
4011
+ var sanitizeInvitation = (invitation) => {
4012
+ return {
4013
+ invitationId: invitation.invitationId,
4014
+ type: invitation.type,
4015
+ kind: invitation.kind,
4016
+ authMethod: invitation.authMethod,
4017
+ swarmKey: invitation.swarmKey,
4018
+ state: invitation.state,
4019
+ timeout: invitation.timeout
4020
+ };
4021
+ };
4022
+ var performInvitation = ({ host, guest, options, hooks }) => {
4023
+ const hostComplete = new import_async19.Trigger();
4024
+ const guestComplete = new import_async19.Trigger();
4025
+ const authCode = new import_async19.Trigger();
4026
+ const hostObservable = createInvitation(host, options);
4027
+ hostObservable.subscribe(async (hostInvitation) => {
4028
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
4029
+ switch (hostInvitation.state) {
4030
+ case import_services11.Invitation.State.CONNECTING: {
4031
+ if ((_b = (_a = hooks == null ? void 0 : hooks.host) == null ? void 0 : _a.onConnecting) == null ? void 0 : _b.call(_a, hostObservable)) {
4032
+ break;
4033
+ }
4034
+ const guestObservable = acceptInvitation(guest, hostInvitation);
4035
+ guestObservable.subscribe(async (guestInvitation) => {
4036
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2;
4037
+ switch (guestInvitation.state) {
4038
+ case import_services11.Invitation.State.CONNECTING: {
4039
+ if ((_b2 = (_a2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _a2.onConnecting) == null ? void 0 : _b2.call(_a2, guestObservable)) {
4040
+ break;
4041
+ }
4042
+ (0, import_node_assert14.default)(hostInvitation.swarmKey.equals(guestInvitation.swarmKey));
4043
+ break;
4044
+ }
4045
+ case import_services11.Invitation.State.CONNECTED: {
4046
+ (_d2 = (_c2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _c2.onConnected) == null ? void 0 : _d2.call(_c2, guestObservable);
4047
+ break;
4048
+ }
4049
+ case import_services11.Invitation.State.READY_FOR_AUTHENTICATION: {
4050
+ if ((_f2 = (_e2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _e2.onReady) == null ? void 0 : _f2.call(_e2, guestObservable)) {
4051
+ break;
4052
+ }
4053
+ await guestObservable.authenticate(await authCode.wait());
4054
+ break;
4055
+ }
4056
+ case import_services11.Invitation.State.AUTHENTICATING: {
4057
+ (_h2 = (_g2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _g2.onAuthenticating) == null ? void 0 : _h2.call(_g2, guestObservable);
4058
+ break;
4059
+ }
4060
+ case import_services11.Invitation.State.SUCCESS: {
4061
+ if ((_j2 = (_i2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _i2.onSuccess) == null ? void 0 : _j2.call(_i2, guestObservable)) {
4062
+ break;
4063
+ }
4064
+ guestComplete.wake({
4065
+ invitation: guestInvitation
4066
+ });
4067
+ break;
4068
+ }
4069
+ case import_services11.Invitation.State.CANCELLED: {
4070
+ if ((_l2 = (_k2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _k2.onCancelled) == null ? void 0 : _l2.call(_k2, guestObservable)) {
4071
+ break;
4072
+ }
4073
+ guestComplete.wake({
4074
+ invitation: guestInvitation
4075
+ });
4076
+ break;
4077
+ }
4078
+ case import_services11.Invitation.State.TIMEOUT: {
4079
+ if ((_n2 = (_m2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _m2.onTimeout) == null ? void 0 : _n2.call(_m2, guestObservable)) {
4080
+ return;
4081
+ }
4082
+ guestComplete.wake({
4083
+ invitation: guestInvitation
4084
+ });
4085
+ }
4086
+ }
4087
+ }, (error) => {
4088
+ var _a2, _b2;
4089
+ if ((_b2 = (_a2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _a2.onError) == null ? void 0 : _b2.call(_a2, guestObservable)) {
4090
+ return;
4091
+ }
4092
+ guestComplete.wake({
4093
+ error
4094
+ });
4095
+ });
4096
+ break;
4097
+ }
4098
+ case import_services11.Invitation.State.CONNECTED: {
4099
+ (_d = (_c = hooks == null ? void 0 : hooks.host) == null ? void 0 : _c.onConnected) == null ? void 0 : _d.call(_c, hostObservable);
4100
+ break;
4101
+ }
4102
+ case import_services11.Invitation.State.READY_FOR_AUTHENTICATION: {
4103
+ if ((_f = (_e = hooks == null ? void 0 : hooks.host) == null ? void 0 : _e.onReady) == null ? void 0 : _f.call(_e, hostObservable)) {
4104
+ break;
4105
+ }
4106
+ if (hostInvitation.authCode) {
4107
+ authCode.wake(hostInvitation.authCode);
4108
+ }
4109
+ break;
4110
+ }
4111
+ case import_services11.Invitation.State.AUTHENTICATING: {
4112
+ (_h = (_g = hooks == null ? void 0 : hooks.host) == null ? void 0 : _g.onAuthenticating) == null ? void 0 : _h.call(_g, hostObservable);
4113
+ break;
4114
+ }
4115
+ case import_services11.Invitation.State.SUCCESS: {
4116
+ if ((_j = (_i = hooks == null ? void 0 : hooks.host) == null ? void 0 : _i.onSuccess) == null ? void 0 : _j.call(_i, hostObservable)) {
4117
+ break;
4118
+ }
4119
+ hostComplete.wake({
4120
+ invitation: hostInvitation
4121
+ });
4122
+ break;
4123
+ }
4124
+ case import_services11.Invitation.State.CANCELLED: {
4125
+ if ((_l = (_k = hooks == null ? void 0 : hooks.host) == null ? void 0 : _k.onCancelled) == null ? void 0 : _l.call(_k, hostObservable)) {
4126
+ break;
4127
+ }
4128
+ hostComplete.wake({
4129
+ invitation: hostInvitation
4130
+ });
4131
+ break;
4132
+ }
4133
+ case import_services11.Invitation.State.TIMEOUT: {
4134
+ if ((_n = (_m = hooks == null ? void 0 : hooks.host) == null ? void 0 : _m.onTimeout) == null ? void 0 : _n.call(_m, hostObservable)) {
4135
+ break;
4136
+ }
4137
+ hostComplete.wake({
4138
+ invitation: hostInvitation
4139
+ });
4140
+ break;
4141
+ }
4142
+ }
4143
+ }, (error) => {
4144
+ var _a, _b;
4145
+ if ((_b = (_a = hooks == null ? void 0 : hooks.host) == null ? void 0 : _a.onError) == null ? void 0 : _b.call(_a, hostObservable)) {
4146
+ return;
4147
+ }
4148
+ hostComplete.wake({
4149
+ error
4150
+ });
4132
4151
  });
4133
- observable1.subscribe({
4134
- onConnecting: async (invitation1) => {
4135
- const observable2 = await guest.acceptInvitation(invitation1, {
4136
- type: import_services10.Invitation.Type.INTERACTIVE_TESTING
4137
- });
4138
- observable2.subscribe({
4139
- onConnecting: async (invitation2) => {
4140
- (0, import_node_assert13.default)(invitation1.swarmKey.equals(invitation2.swarmKey));
4141
- },
4142
- onConnected: async (invitation2) => {
4143
- },
4144
- onSuccess: (invitation) => {
4145
- done2.wake(invitation);
4146
- },
4147
- onCancelled: () => (0, import_debug8.raise)(new Error()),
4148
- onTimeout: (err) => (0, import_debug8.raise)(err),
4149
- onError: (err) => (0, import_debug8.raise)(err)
4150
- });
4151
- },
4152
- onConnected: async (invitation1) => {
4153
- },
4154
- onCancelled: () => (0, import_debug8.raise)(new Error("cancelled")),
4155
- onSuccess: (invitation) => {
4156
- done1.wake(invitation);
4157
- },
4158
- onTimeout: (err) => (0, import_debug8.raise)(err),
4159
- onError: (err) => (0, import_debug8.raise)(err)
4152
+ return [
4153
+ hostComplete.wait(),
4154
+ guestComplete.wait()
4155
+ ];
4156
+ };
4157
+ var createInvitation = (host, options) => {
4158
+ options != null ? options : options = {
4159
+ authMethod: import_services11.Invitation.AuthMethod.NONE,
4160
+ ...options != null ? options : {}
4161
+ };
4162
+ if (host instanceof import_client10.InvitationsProxy || host instanceof import_client10.HaloProxy || host instanceof import_client10.SpaceProxy) {
4163
+ return host.createInvitation(options);
4164
+ }
4165
+ const hostHandler = host.getInvitationHandler({
4166
+ kind: import_services11.Invitation.Kind.SPACE,
4167
+ ...options
4168
+ });
4169
+ return host.invitations.createInvitation(hostHandler, options);
4170
+ };
4171
+ var acceptInvitation = (guest, invitation) => {
4172
+ invitation = sanitizeInvitation(invitation);
4173
+ if (guest instanceof import_client10.InvitationsProxy || guest instanceof import_client10.HaloProxy || guest instanceof import_client10.EchoProxy || guest instanceof import_client10.Client) {
4174
+ return guest.acceptInvitation(invitation);
4175
+ }
4176
+ const guestHandler = guest.getInvitationHandler({
4177
+ kind: invitation.kind
4160
4178
  });
4161
- await done1.wait();
4162
- await done2.wait();
4179
+ return guest.invitations.acceptInvitation(guestHandler, invitation);
4163
4180
  };
4164
4181
 
4165
4182
  // packages/sdk/client-services/src/packlets/testing/test-builder.ts
4166
- var import_node_assert14 = __toESM(require("node:assert"));
4167
- var import_async21 = require("@dxos/async");
4168
- var import_client10 = require("@dxos/client");
4183
+ var import_node_assert15 = __toESM(require("node:assert"));
4184
+ var import_async20 = require("@dxos/async");
4185
+ var import_client11 = require("@dxos/client");
4169
4186
  var import_config3 = require("@dxos/config");
4170
- var import_debug9 = require("@dxos/debug");
4187
+ var import_debug7 = require("@dxos/debug");
4171
4188
  var import_document_model = require("@dxos/document-model");
4172
4189
  var import_echo_db = require("@dxos/echo-db");
4173
- var import_keys12 = require("@dxos/keys");
4190
+ var import_keys11 = require("@dxos/keys");
4174
4191
  var import_log18 = require("@dxos/log");
4175
4192
  var import_messaging5 = require("@dxos/messaging");
4176
- var import_network_manager8 = require("@dxos/network-manager");
4193
+ var import_network_manager7 = require("@dxos/network-manager");
4177
4194
  var import_rpc5 = require("@dxos/rpc");
4178
4195
  var testConfigWithLocalSignal = new import_config3.Config({
4179
4196
  version: 1,
@@ -4188,7 +4205,7 @@ var testConfigWithLocalSignal = new import_config3.Config({
4188
4205
  });
4189
4206
  var TestBuilder = class {
4190
4207
  // prettier-ignore
4191
- constructor(config, _modelFactory = (0, import_client10.createDefaultModelFactory)(), _signalManagerContext = new import_messaging5.MemorySignalManagerContext()) {
4208
+ constructor(config, _modelFactory = (0, import_client11.createDefaultModelFactory)(), _signalManagerContext = new import_messaging5.MemorySignalManagerContext()) {
4192
4209
  this._modelFactory = _modelFactory;
4193
4210
  this._signalManagerContext = _signalManagerContext;
4194
4211
  this._config = config != null ? config : new import_config3.Config();
@@ -4202,20 +4219,20 @@ var TestBuilder = class {
4202
4219
  get networkManager() {
4203
4220
  const signalServer = this._config.get("runtime.services.signal.server");
4204
4221
  if (signalServer) {
4205
- return new import_network_manager8.NetworkManager({
4222
+ return new import_network_manager7.NetworkManager({
4206
4223
  log: true,
4207
4224
  signalManager: new import_messaging5.WebsocketSignalManager([
4208
4225
  signalServer
4209
4226
  ]),
4210
- transportFactory: (0, import_network_manager8.createWebRTCTransportFactory)({
4227
+ transportFactory: (0, import_network_manager7.createWebRTCTransportFactory)({
4211
4228
  iceServers: this._config.get("runtime.services.ice")
4212
4229
  })
4213
4230
  });
4214
4231
  }
4215
- return new import_network_manager8.NetworkManager({
4232
+ return new import_network_manager7.NetworkManager({
4216
4233
  log: true,
4217
4234
  signalManager: new import_messaging5.MemorySignalManager(this._signalManagerContext),
4218
- transportFactory: import_network_manager8.MemoryTransportFactory
4235
+ transportFactory: import_network_manager7.MemoryTransportFactory
4219
4236
  });
4220
4237
  }
4221
4238
  /**
@@ -4250,8 +4267,8 @@ var TestBuilder = class {
4250
4267
  handlers: host.services,
4251
4268
  port: hostPort
4252
4269
  });
4253
- const client = new import_client10.Client({
4254
- services: new import_client10.ClientServicesProxy(proxyPort)
4270
+ const client = new import_client11.Client({
4271
+ services: new import_client11.ClientServicesProxy(proxyPort)
4255
4272
  });
4256
4273
  return [
4257
4274
  client,
@@ -4260,11 +4277,11 @@ var TestBuilder = class {
4260
4277
  }
4261
4278
  };
4262
4279
  var testSpace = async (create, check = create) => {
4263
- const objectId = import_keys12.PublicKey.random().toHex();
4280
+ const objectId = import_keys11.PublicKey.random().toHex();
4264
4281
  const result = create.mutate((0, import_echo_db.genesisMutation)(objectId, import_document_model.DocumentModel.meta.type));
4265
4282
  await result.batch.getReceipt();
4266
- (0, import_node_assert14.default)(create._itemManager.entities.has(result.objectsUpdated[0].id));
4267
- await (0, import_async21.asyncTimeout)(check.itemUpdate.waitForCondition(() => check._itemManager.entities.has(objectId)), 1e3);
4283
+ (0, import_node_assert15.default)(create._itemManager.entities.has(result.objectsUpdated[0].id));
4284
+ await (0, import_async20.asyncTimeout)(check.itemUpdate.waitForCondition(() => check._itemManager.entities.has(objectId)), 1e3);
4268
4285
  return result;
4269
4286
  };
4270
4287
  var syncItems = async (db1, db2) => {
@@ -4273,12 +4290,12 @@ var syncItems = async (db1, db2) => {
4273
4290
  };
4274
4291
  var joinCommonSpace = async ([initialPeer, ...peers], spaceKey) => {
4275
4292
  const rootSpace = spaceKey ? initialPeer.getSpace(spaceKey) : await initialPeer.createSpace();
4276
- (0, import_node_assert14.default)(rootSpace, "Space not found.");
4293
+ (0, import_node_assert15.default)(rootSpace, "Space not found.");
4277
4294
  await Promise.all(peers.map(async (peer) => {
4278
- const hostDone = new import_async21.Trigger();
4279
- const guestDone = new import_async21.Trigger();
4280
- const hostObservabli = rootSpace.createInvitation({
4281
- type: import_client10.Invitation.Type.INTERACTIVE_TESTING
4295
+ const hostDone = new import_async20.Trigger();
4296
+ const guestDone = new import_async20.Trigger();
4297
+ const hostObservable = rootSpace.createInvitation({
4298
+ authMethod: import_client11.Invitation.AuthMethod.NONE
4282
4299
  });
4283
4300
  (0, import_log18.log)("invitation created", {}, {
4284
4301
  file: "test-builder.ts",
@@ -4286,39 +4303,43 @@ var joinCommonSpace = async ([initialPeer, ...peers], spaceKey) => {
4286
4303
  scope: void 0,
4287
4304
  callSite: (f, a) => f(...a)
4288
4305
  });
4289
- hostObservabli.subscribe({
4290
- onConnecting: (invitation) => {
4291
- const guestObservable = peer.acceptInvitation(invitation);
4292
- (0, import_log18.log)("invitation accepted", {}, {
4293
- file: "test-builder.ts",
4294
- line: 158,
4295
- scope: void 0,
4296
- callSite: (f, a) => f(...a)
4297
- });
4298
- guestObservable.subscribe({
4299
- onSuccess: (invitation2) => {
4300
- guestDone.wake(invitation2);
4301
- (0, import_log18.log)("invitation guestDone", {}, {
4302
- file: "test-builder.ts",
4303
- line: 163,
4304
- scope: void 0,
4305
- callSite: (f, a) => f(...a)
4306
- });
4307
- },
4308
- onError: (err) => (0, import_debug9.raise)(err)
4309
- });
4310
- },
4311
- onSuccess: (invitation) => {
4312
- hostDone.wake(invitation);
4313
- (0, import_log18.log)("invitation hostDone", {}, {
4314
- file: "test-builder.ts",
4315
- line: 170,
4316
- scope: void 0,
4317
- callSite: (f, a) => f(...a)
4318
- });
4319
- },
4320
- onError: (err) => (0, import_debug9.raise)(err)
4321
- });
4306
+ hostObservable.subscribe((hostInvitation) => {
4307
+ switch (hostInvitation.state) {
4308
+ case import_client11.Invitation.State.CONNECTING: {
4309
+ const guestObservable = peer.acceptInvitation(hostInvitation);
4310
+ (0, import_log18.log)("invitation accepted", {}, {
4311
+ file: "test-builder.ts",
4312
+ line: 160,
4313
+ scope: void 0,
4314
+ callSite: (f, a) => f(...a)
4315
+ });
4316
+ guestObservable.subscribe((guestInvitation) => {
4317
+ switch (guestInvitation.state) {
4318
+ case import_client11.Invitation.State.SUCCESS: {
4319
+ guestDone.wake(guestInvitation);
4320
+ (0, import_log18.log)("invitation guestDone", {}, {
4321
+ file: "test-builder.ts",
4322
+ line: 167,
4323
+ scope: void 0,
4324
+ callSite: (f, a) => f(...a)
4325
+ });
4326
+ break;
4327
+ }
4328
+ }
4329
+ }, (err) => (0, import_debug7.raise)(err));
4330
+ break;
4331
+ }
4332
+ case import_client11.Invitation.State.SUCCESS: {
4333
+ hostDone.wake(hostInvitation);
4334
+ (0, import_log18.log)("invitation hostDone", {}, {
4335
+ file: "test-builder.ts",
4336
+ line: 179,
4337
+ scope: void 0,
4338
+ callSite: (f, a) => f(...a)
4339
+ });
4340
+ }
4341
+ }
4342
+ }, (err) => (0, import_debug7.raise)(err));
4322
4343
  await Promise.all([
4323
4344
  hostDone.wait(),
4324
4345
  guestDone.wait()
@@ -4339,6 +4360,7 @@ var joinCommonSpace = async ([initialPeer, ...peers], spaceKey) => {
4339
4360
  createSigningContext,
4340
4361
  joinCommonSpace,
4341
4362
  performInvitation,
4363
+ sanitizeInvitation,
4342
4364
  syncItems,
4343
4365
  syncItemsLocal,
4344
4366
  testConfigWithLocalSignal,