@dxos/client-services 0.1.35 → 0.1.36-next.ef27157

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 (87) hide show
  1. package/dist/lib/browser/{chunk-H5IXSSI7.mjs → chunk-OINEQJWM.mjs} +783 -924
  2. package/dist/lib/browser/chunk-OINEQJWM.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 +897 -1039
  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 +1057 -1061
  11. package/dist/lib/node/packlets/testing/index.cjs.map +4 -4
  12. package/dist/types/src/packlets/identity/identity.d.ts +3 -3
  13. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  14. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +18 -0
  15. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -0
  16. package/dist/types/src/packlets/invitations/device-invitation-protocol.test.d.ts +2 -0
  17. package/dist/types/src/packlets/invitations/device-invitation-protocol.test.d.ts.map +1 -0
  18. package/dist/types/src/packlets/invitations/index.d.ts +4 -4
  19. package/dist/types/src/packlets/invitations/index.d.ts.map +1 -1
  20. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +12 -0
  21. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -0
  22. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +38 -0
  23. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -0
  24. package/dist/types/src/packlets/invitations/invitations-service.d.ts +13 -15
  25. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  26. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +22 -0
  27. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -0
  28. package/dist/types/src/packlets/invitations/space-invitation-protocol.test.d.ts +2 -0
  29. package/dist/types/src/packlets/invitations/space-invitation-protocol.test.d.ts.map +1 -0
  30. package/dist/types/src/packlets/services/service-context.d.ts +6 -4
  31. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  32. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  33. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  34. package/dist/types/src/packlets/testing/invitation-utils.d.ts +31 -2
  35. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  36. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  37. package/dist/types/src/packlets/tests/invitations.test.d.ts +2 -0
  38. package/dist/types/src/packlets/tests/invitations.test.d.ts.map +1 -0
  39. package/dist/types/src/packlets/vault/worker-runtime.d.ts +2 -0
  40. package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
  41. package/package.json +30 -30
  42. package/src/packlets/identity/identity.ts +3 -3
  43. package/src/packlets/invitations/{device-invitations-handler.test.ts → device-invitation-protocol.test.ts} +3 -3
  44. package/src/packlets/invitations/device-invitation-protocol.ts +83 -0
  45. package/src/packlets/invitations/index.ts +4 -4
  46. package/src/packlets/invitations/invitation-protocol.ts +21 -0
  47. package/src/packlets/invitations/invitations-handler.ts +462 -0
  48. package/src/packlets/invitations/invitations-service.ts +127 -104
  49. package/src/packlets/invitations/space-invitation-protocol.test.ts +221 -0
  50. package/src/packlets/invitations/space-invitation-protocol.ts +117 -0
  51. package/src/packlets/services/service-context.test.ts +11 -4
  52. package/src/packlets/services/service-context.ts +34 -17
  53. package/src/packlets/services/service-host.ts +4 -12
  54. package/src/packlets/services/service-registry.test.ts +23 -25
  55. package/src/packlets/spaces/spaces-service.ts +7 -2
  56. package/src/packlets/testing/invitation-utils.ts +219 -31
  57. package/src/packlets/testing/test-builder.ts +30 -19
  58. package/src/packlets/tests/client-services.test.ts +33 -76
  59. package/src/packlets/tests/halo-profile.test.ts +2 -28
  60. package/src/packlets/tests/invitations.test.ts +389 -0
  61. package/src/packlets/tests/spaces-invitations.test.ts +12 -30
  62. package/src/packlets/tests/spaces.test.ts +6 -28
  63. package/src/packlets/vault/worker-runtime.ts +4 -0
  64. package/dist/lib/browser/chunk-H5IXSSI7.mjs.map +0 -7
  65. package/dist/types/src/packlets/invitations/device-invitations-handler.d.ts +0 -30
  66. package/dist/types/src/packlets/invitations/device-invitations-handler.d.ts.map +0 -1
  67. package/dist/types/src/packlets/invitations/device-invitations-handler.test.d.ts +0 -2
  68. package/dist/types/src/packlets/invitations/device-invitations-handler.test.d.ts.map +0 -1
  69. package/dist/types/src/packlets/invitations/device-invitations-service.d.ts +0 -13
  70. package/dist/types/src/packlets/invitations/device-invitations-service.d.ts.map +0 -1
  71. package/dist/types/src/packlets/invitations/device-invitations-service.test.d.ts +0 -2
  72. package/dist/types/src/packlets/invitations/device-invitations-service.test.d.ts.map +0 -1
  73. package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts +0 -26
  74. package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts.map +0 -1
  75. package/dist/types/src/packlets/invitations/space-invitations-handler.test.d.ts +0 -2
  76. package/dist/types/src/packlets/invitations/space-invitations-handler.test.d.ts.map +0 -1
  77. package/dist/types/src/packlets/invitations/space-invitations-service.d.ts +0 -16
  78. package/dist/types/src/packlets/invitations/space-invitations-service.d.ts.map +0 -1
  79. package/dist/types/src/packlets/invitations/space-invitations-service.test.d.ts +0 -2
  80. package/dist/types/src/packlets/invitations/space-invitations-service.test.d.ts.map +0 -1
  81. package/src/packlets/invitations/device-invitations-handler.ts +0 -370
  82. package/src/packlets/invitations/device-invitations-service.test.ts +0 -96
  83. package/src/packlets/invitations/device-invitations-service.ts +0 -24
  84. package/src/packlets/invitations/space-invitations-handler.test.ts +0 -246
  85. package/src/packlets/invitations/space-invitations-handler.ts +0 -463
  86. package/src/packlets/invitations/space-invitations-service.test.ts +0 -129
  87. 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
- var import_protocols7 = require("@dxos/protocols");
86
- var import_services8 = require("@dxos/protocols/proto/dxos/client/services");
85
+ var import_protocols6 = require("@dxos/protocols");
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 {
@@ -973,8 +973,73 @@ var IdentityServiceImpl = class {
973
973
  }
974
974
  };
975
975
 
976
- // packages/sdk/client-services/src/packlets/invitations/device-invitations-handler.ts
976
+ // packages/sdk/client-services/src/packlets/invitations/device-invitation-protocol.ts
977
977
  var import_node_assert4 = __toESM(require("node:assert"));
978
+ var import_services2 = require("@dxos/protocols/proto/dxos/client/services");
979
+ var DeviceInvitationProtocol = class {
980
+ constructor(_keyring, _getIdentity, _acceptIdentity) {
981
+ this._keyring = _keyring;
982
+ this._getIdentity = _getIdentity;
983
+ this._acceptIdentity = _acceptIdentity;
984
+ }
985
+ toJSON() {
986
+ return {};
987
+ }
988
+ getInvitationContext() {
989
+ return {
990
+ kind: import_services2.Invitation.Kind.DEVICE
991
+ };
992
+ }
993
+ async admit(request) {
994
+ (0, import_node_assert4.default)(request.device);
995
+ const identity = this._getIdentity();
996
+ await identity.admitDevice(request.device);
997
+ return {
998
+ device: {
999
+ identityKey: identity.identityKey,
1000
+ haloSpaceKey: identity.haloSpaceKey,
1001
+ genesisFeedKey: identity.haloGenesisFeedKey,
1002
+ controlTimeframe: identity.controlPipeline.state.timeframe
1003
+ }
1004
+ };
1005
+ }
1006
+ createIntroduction() {
1007
+ return {};
1008
+ }
1009
+ async createAdmissionRequest() {
1010
+ const deviceKey = await this._keyring.createKey();
1011
+ const controlFeedKey = await this._keyring.createKey();
1012
+ const dataFeedKey = await this._keyring.createKey();
1013
+ return {
1014
+ device: {
1015
+ deviceKey,
1016
+ controlFeedKey,
1017
+ dataFeedKey
1018
+ }
1019
+ };
1020
+ }
1021
+ async accept(response, request) {
1022
+ (0, import_node_assert4.default)(response.device);
1023
+ const { identityKey, haloSpaceKey, genesisFeedKey, controlTimeframe } = response.device;
1024
+ (0, import_node_assert4.default)(request.device);
1025
+ const { deviceKey, controlFeedKey, dataFeedKey } = request.device;
1026
+ await this._acceptIdentity({
1027
+ identityKey,
1028
+ deviceKey,
1029
+ haloSpaceKey,
1030
+ haloGenesisFeedKey: genesisFeedKey,
1031
+ controlFeedKey,
1032
+ dataFeedKey,
1033
+ controlTimeframe
1034
+ });
1035
+ return {
1036
+ identityKey
1037
+ };
1038
+ }
1039
+ };
1040
+
1041
+ // packages/sdk/client-services/src/packlets/invitations/invitations-handler.ts
1042
+ var import_node_assert5 = __toESM(require("node:assert"));
978
1043
  var import_async7 = require("@dxos/async");
979
1044
  var import_client = require("@dxos/client");
980
1045
  var import_context3 = require("@dxos/context");
@@ -983,141 +1048,206 @@ var import_keys6 = require("@dxos/keys");
983
1048
  var import_log4 = require("@dxos/log");
984
1049
  var import_network_manager = require("@dxos/network-manager");
985
1050
  var import_protocols3 = require("@dxos/protocols");
986
- var import_services2 = require("@dxos/protocols/proto/dxos/client/services");
1051
+ var import_services3 = require("@dxos/protocols/proto/dxos/client/services");
987
1052
  var import_invitations = require("@dxos/protocols/proto/dxos/halo/invitations");
988
1053
  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;
1054
+ var MAX_OTP_ATTEMPTS = 3;
1055
+ var InvitationsHandler = class {
1056
+ constructor(_networkManager) {
1057
+ this._networkManager = _networkManager;
994
1058
  }
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();
1059
+ createInvitation(protocol, options) {
1060
+ var _a;
1061
+ 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 : {};
1062
+ 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;
1063
+ (0, import_node_assert5.default)(protocol);
1002
1064
  const invitation = {
1065
+ invitationId,
1003
1066
  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)
1067
+ authMethod,
1068
+ state,
1069
+ swarmKey,
1070
+ authCode,
1071
+ timeout,
1072
+ ...protocol.getInvitationContext()
1007
1073
  };
1074
+ const stream = new import_async7.PushStream();
1008
1075
  const ctx = new import_context3.Context({
1009
1076
  onError: (err) => {
1010
1077
  void ctx.dispose();
1011
- observable.callback.onError(err);
1078
+ stream.error(err);
1012
1079
  }
1013
1080
  });
1014
- const observable = new import_client.InvitationObservableProvider(async () => {
1015
- await ctx.dispose();
1081
+ ctx.onDispose(() => {
1082
+ (0, import_log4.log)("complete", {
1083
+ ...protocol.toJSON()
1084
+ }, {
1085
+ file: "invitations-handler.ts",
1086
+ line: 102,
1087
+ scope: this,
1088
+ callSite: (f, a) => f(...a)
1089
+ });
1090
+ stream.complete();
1016
1091
  });
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
1092
+ const createExtension = () => {
1093
+ const success = new import_async7.Trigger();
1094
+ let guestProfile;
1095
+ let authenticationPassed = false;
1096
+ let authenticationRetry = 0;
1097
+ const extension = new InvitationHostExtension({
1098
+ introduce: async ({ profile }) => {
1099
+ (0, import_log4.log)("guest introduced itself", {
1100
+ guestProfile: profile,
1101
+ ...protocol.toJSON()
1063
1102
  }, {
1064
- file: "device-invitations-handler.ts",
1065
- line: 122,
1103
+ file: "invitations-handler.ts",
1104
+ line: 115,
1066
1105
  scope: this,
1067
1106
  callSite: (f, a) => f(...a)
1068
1107
  });
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;
1108
+ guestProfile = profile;
1109
+ stream.next({
1110
+ ...invitation,
1111
+ state: import_services3.Invitation.State.READY_FOR_AUTHENTICATION
1112
+ });
1113
+ return {
1114
+ spaceKey: authMethod === import_services3.Invitation.AuthMethod.NONE ? protocol.getInvitationContext().spaceKey : void 0,
1115
+ authMethod
1116
+ };
1117
+ },
1118
+ authenticate: async ({ authCode: code }) => {
1119
+ (0, import_log4.log)("received authentication request", {
1120
+ authCode: code
1121
+ }, {
1122
+ file: "invitations-handler.ts",
1123
+ line: 134,
1124
+ scope: this,
1125
+ callSite: (f, a) => f(...a)
1126
+ });
1127
+ let status = import_invitations.AuthenticationResponse.Status.OK;
1128
+ switch (invitation.authMethod) {
1129
+ case import_services3.Invitation.AuthMethod.NONE: {
1130
+ (0, import_log4.log)("authentication not required", {}, {
1131
+ file: "invitations-handler.ts",
1132
+ line: 139,
1133
+ scope: this,
1134
+ callSite: (f, a) => f(...a)
1135
+ });
1136
+ return {
1137
+ status: import_invitations.AuthenticationResponse.Status.OK
1138
+ };
1139
+ }
1140
+ case import_services3.Invitation.AuthMethod.SHARED_SECRET: {
1141
+ if (invitation.authCode) {
1142
+ if (authenticationRetry++ > MAX_OTP_ATTEMPTS) {
1143
+ status = import_invitations.AuthenticationResponse.Status.INVALID_OPT_ATTEMPTS;
1144
+ } else if (code !== invitation.authCode) {
1145
+ status = import_invitations.AuthenticationResponse.Status.INVALID_OTP;
1146
+ } else {
1147
+ authenticationPassed = true;
1148
+ }
1149
+ }
1150
+ break;
1151
+ }
1152
+ default: {
1153
+ import_log4.log.error("invalid authentication method", {
1154
+ authMethod: invitation.authMethod
1155
+ }, {
1156
+ file: "invitations-handler.ts",
1157
+ line: 157,
1158
+ scope: this,
1159
+ callSite: (f, a) => f(...a)
1160
+ });
1161
+ status = import_invitations.AuthenticationResponse.Status.INTERNAL_ERROR;
1162
+ break;
1163
+ }
1164
+ }
1165
+ return {
1166
+ status
1167
+ };
1168
+ },
1169
+ admit: async (admissionRequest) => {
1170
+ var _a2, _b, _c;
1079
1171
  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);
1172
+ if (isAuthenticationRequired(invitation) && !authenticationPassed) {
1173
+ throw new Error("Not authenticated");
1174
+ }
1175
+ const deviceKey = (_c = (_a2 = admissionRequest.device) == null ? void 0 : _a2.deviceKey) != null ? _c : (_b = admissionRequest.space) == null ? void 0 : _b.deviceKey;
1176
+ (0, import_node_assert5.default)(deviceKey);
1177
+ const admissionResponse = await protocol.admit(admissionRequest, guestProfile);
1178
+ success.wake(deviceKey);
1179
+ return admissionResponse;
1102
1180
  } catch (err) {
1103
- if (!observable.cancelled) {
1104
- import_log4.log.error("failed", err, {
1105
- file: "device-invitations-handler.ts",
1106
- line: 145,
1181
+ stream.error(err);
1182
+ throw err;
1183
+ }
1184
+ },
1185
+ onOpen: () => {
1186
+ (0, import_async7.scheduleTask)(ctx, async () => {
1187
+ try {
1188
+ (0, import_log4.log)("connected", {
1189
+ ...protocol.toJSON()
1190
+ }, {
1191
+ file: "invitations-handler.ts",
1192
+ line: 191,
1193
+ scope: this,
1194
+ callSite: (f, a) => f(...a)
1195
+ });
1196
+ stream.next({
1197
+ ...invitation,
1198
+ state: import_services3.Invitation.State.CONNECTED
1199
+ });
1200
+ const deviceKey = await success.wait({
1201
+ timeout
1202
+ });
1203
+ (0, import_log4.log)("admitted guest", {
1204
+ guest: deviceKey,
1205
+ ...protocol.toJSON()
1206
+ }, {
1207
+ file: "invitations-handler.ts",
1208
+ line: 194,
1107
1209
  scope: this,
1108
1210
  callSite: (f, a) => f(...a)
1109
1211
  });
1110
- observable.callback.onError(err);
1212
+ stream.next({
1213
+ ...invitation,
1214
+ state: import_services3.Invitation.State.SUCCESS
1215
+ });
1216
+ } catch (err) {
1217
+ if (err instanceof import_async7.TimeoutError) {
1218
+ (0, import_log4.log)("timeout", {
1219
+ ...protocol.toJSON()
1220
+ }, {
1221
+ file: "invitations-handler.ts",
1222
+ line: 198,
1223
+ scope: this,
1224
+ callSite: (f, a) => f(...a)
1225
+ });
1226
+ stream.next({
1227
+ ...invitation,
1228
+ state: import_services3.Invitation.State.TIMEOUT
1229
+ });
1230
+ } else {
1231
+ import_log4.log.error("failed", err, {
1232
+ file: "invitations-handler.ts",
1233
+ line: 201,
1234
+ scope: this,
1235
+ callSite: (f, a) => f(...a)
1236
+ });
1237
+ stream.error(err);
1238
+ }
1239
+ } finally {
1240
+ if (type !== import_services3.Invitation.Type.MULTIUSE) {
1241
+ await (0, import_async7.sleep)(import_client.ON_CLOSE_DELAY);
1242
+ await ctx.dispose();
1243
+ }
1111
1244
  }
1112
- } finally {
1113
- await (0, import_async7.sleep)(import_client.ON_CLOSE_DELAY);
1114
- await ctx.dispose();
1115
- }
1116
- });
1117
- }
1118
- });
1245
+ });
1246
+ }
1247
+ });
1248
+ return extension;
1249
+ };
1119
1250
  (0, import_async7.scheduleTask)(ctx, async () => {
1120
- var _a, _b;
1121
1251
  const topic = invitation.swarmKey;
1122
1252
  const swarmConnection = await this._networkManager.joinSwarm({
1123
1253
  topic,
@@ -1128,126 +1258,210 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
1128
1258
  topology: new import_network_manager.StarTopology(topic)
1129
1259
  });
1130
1260
  ctx.onDispose(() => swarmConnection.close());
1131
- (_b = (_a = observable.callback).onConnecting) == null ? void 0 : _b.call(_a, invitation);
1261
+ stream.next({
1262
+ ...invitation,
1263
+ state: import_services3.Invitation.State.CONNECTING
1264
+ });
1265
+ });
1266
+ const observable = new import_client.CancellableInvitationObservable({
1267
+ initialInvitation: invitation,
1268
+ subscriber: stream.observable,
1269
+ onCancel: async () => {
1270
+ stream.next({
1271
+ ...invitation,
1272
+ state: import_services3.Invitation.State.CANCELLED
1273
+ });
1274
+ await ctx.dispose();
1275
+ }
1132
1276
  });
1133
1277
  return observable;
1134
1278
  }
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 : {};
1279
+ acceptInvitation(protocol, invitation) {
1280
+ const { timeout = import_client.INVITATION_TIMEOUT } = invitation;
1281
+ (0, import_node_assert5.default)(protocol);
1282
+ const authenticated = new import_async7.Trigger();
1283
+ const stream = new import_async7.PushStream();
1142
1284
  const ctx = new import_context3.Context({
1143
1285
  onError: (err) => {
1286
+ if (err instanceof import_async7.TimeoutError) {
1287
+ (0, import_log4.log)("timeout", {
1288
+ ...protocol.toJSON()
1289
+ }, {
1290
+ file: "invitations-handler.ts",
1291
+ line: 255,
1292
+ scope: this,
1293
+ callSite: (f, a) => f(...a)
1294
+ });
1295
+ stream.next({
1296
+ ...invitation,
1297
+ state: import_services3.Invitation.State.TIMEOUT
1298
+ });
1299
+ } else {
1300
+ import_log4.log.warn("auth failed", err, {
1301
+ file: "invitations-handler.ts",
1302
+ line: 258,
1303
+ scope: this,
1304
+ callSite: (f, a) => f(...a)
1305
+ });
1306
+ stream.error(err);
1307
+ }
1144
1308
  void ctx.dispose();
1145
- observable.callback.onError(err);
1146
1309
  }
1147
1310
  });
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
- }
1311
+ ctx.onDispose(() => {
1312
+ (0, import_log4.log)("complete", {
1313
+ ...protocol.toJSON()
1314
+ }, {
1315
+ file: "invitations-handler.ts",
1316
+ line: 266,
1317
+ scope: this,
1318
+ callSite: (f, a) => f(...a)
1319
+ });
1320
+ stream.complete();
1157
1321
  });
1158
- let connectionCount = 0;
1159
- const complete = new import_async7.Trigger();
1160
1322
  const createExtension = () => {
1161
- const extension = new GuestHaloInvitationExtension({
1323
+ let connectionCount = 0;
1324
+ const extension = new InvitationGuestExtension({
1162
1325
  onOpen: () => {
1163
1326
  (0, import_async7.scheduleTask)(ctx, async () => {
1164
- var _a, _b, _c, _d;
1165
1327
  try {
1166
1328
  if (++connectionCount > 1) {
1167
1329
  throw new Error(`multiple connections detected: ${connectionCount}`);
1168
1330
  }
1169
- (0, import_log4.log)("connected", {}, {
1170
- file: "device-invitations-handler.ts",
1171
- line: 216,
1331
+ (0, import_async7.scheduleTask)(ctx, () => ctx.raise(new import_async7.TimeoutError(timeout)), timeout);
1332
+ (0, import_log4.log)("connected", {
1333
+ ...protocol.toJSON()
1334
+ }, {
1335
+ file: "invitations-handler.ts",
1336
+ line: 284,
1172
1337
  scope: this,
1173
1338
  callSite: (f, a) => f(...a)
1174
1339
  });
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,
1340
+ stream.next({
1341
+ ...invitation,
1342
+ state: import_services3.Invitation.State.CONNECTED
1343
+ });
1344
+ (0, import_log4.log)("introduce", {
1345
+ ...protocol.toJSON()
1346
+ }, {
1347
+ file: "invitations-handler.ts",
1348
+ line: 288,
1179
1349
  scope: this,
1180
1350
  callSite: (f, a) => f(...a)
1181
1351
  });
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
1352
+ const introductionResponse = await extension.rpc.InvitationHostService.introduce(protocol.createIntroduction());
1353
+ (0, import_log4.log)("introduce response", {
1354
+ ...protocol.toJSON(),
1355
+ response: introductionResponse
1356
+ }, {
1357
+ file: "invitations-handler.ts",
1358
+ line: 292,
1359
+ scope: this,
1360
+ callSite: (f, a) => f(...a)
1361
+ });
1362
+ invitation.authMethod = introductionResponse.authMethod;
1363
+ if (introductionResponse.spaceKey) {
1364
+ invitation.spaceKey = introductionResponse.spaceKey;
1365
+ }
1366
+ if (isAuthenticationRequired(invitation)) {
1367
+ for (let attempt = 1; attempt <= MAX_OTP_ATTEMPTS; attempt++) {
1368
+ (0, import_log4.log)("guest waiting for authentication code...", {}, {
1369
+ file: "invitations-handler.ts",
1370
+ line: 301,
1371
+ scope: this,
1372
+ callSite: (f, a) => f(...a)
1373
+ });
1374
+ stream.next({
1375
+ ...invitation,
1376
+ state: import_services3.Invitation.State.READY_FOR_AUTHENTICATION
1377
+ });
1378
+ const authCode = await authenticated.wait({
1379
+ timeout
1380
+ });
1381
+ (0, import_log4.log)("sending authentication request", {}, {
1382
+ file: "invitations-handler.ts",
1383
+ line: 305,
1384
+ scope: this,
1385
+ callSite: (f, a) => f(...a)
1386
+ });
1387
+ stream.next({
1388
+ ...invitation,
1389
+ state: import_services3.Invitation.State.AUTHENTICATING
1390
+ });
1391
+ const response = await extension.rpc.InvitationHostService.authenticate({
1392
+ authCode
1393
+ });
1394
+ if (response.status === void 0 || response.status === import_invitations.AuthenticationResponse.Status.OK) {
1395
+ break;
1396
+ }
1397
+ if (response.status === import_invitations.AuthenticationResponse.Status.INVALID_OTP) {
1398
+ if (attempt === MAX_OTP_ATTEMPTS) {
1399
+ throw new Error(`Maximum retry attempts: ${MAX_OTP_ATTEMPTS}`);
1400
+ } else {
1401
+ (0, import_log4.log)("retrying invalid code", {
1402
+ attempt
1403
+ }, {
1404
+ file: "invitations-handler.ts",
1405
+ line: 316,
1406
+ scope: this,
1407
+ callSite: (f, a) => f(...a)
1408
+ });
1409
+ authenticated.reset();
1410
+ }
1411
+ }
1412
+ }
1413
+ } else {
1414
+ stream.next({
1415
+ ...invitation,
1416
+ state: import_services3.Invitation.State.READY_FOR_AUTHENTICATION
1202
1417
  });
1203
1418
  }
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
1419
+ (0, import_log4.log)("request admission", {
1420
+ ...protocol.toJSON()
1212
1421
  }, {
1213
- file: "device-invitations-handler.ts",
1214
- line: 239,
1422
+ file: "invitations-handler.ts",
1423
+ line: 327,
1215
1424
  scope: this,
1216
1425
  callSite: (f, a) => f(...a)
1217
1426
  });
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
- });
1427
+ const admissionRequest = await protocol.createAdmissionRequest();
1428
+ const admissionResponse = await extension.rpc.InvitationHostService.admit(admissionRequest);
1429
+ const result = await protocol.accept(admissionResponse, admissionRequest);
1232
1430
  (0, import_log4.log)("admitted by host", {
1233
- guest: identity.deviceKey,
1234
- identityKey
1431
+ ...protocol.toJSON()
1235
1432
  }, {
1236
- file: "device-invitations-handler.ts",
1237
- line: 259,
1433
+ file: "invitations-handler.ts",
1434
+ line: 335,
1238
1435
  scope: this,
1239
1436
  callSite: (f, a) => f(...a)
1240
1437
  });
1241
- complete.wake(identityKey);
1438
+ stream.next({
1439
+ ...invitation,
1440
+ ...result,
1441
+ state: import_services3.Invitation.State.SUCCESS
1442
+ });
1242
1443
  } catch (err) {
1243
- if (!observable.cancelled) {
1444
+ if (err instanceof import_async7.TimeoutError) {
1445
+ (0, import_log4.log)("timeout", {
1446
+ ...protocol.toJSON()
1447
+ }, {
1448
+ file: "invitations-handler.ts",
1449
+ line: 339,
1450
+ scope: this,
1451
+ callSite: (f, a) => f(...a)
1452
+ });
1453
+ stream.next({
1454
+ ...invitation,
1455
+ state: import_services3.Invitation.State.TIMEOUT
1456
+ });
1457
+ } else {
1244
1458
  import_log4.log.warn("auth failed", err, {
1245
- file: "device-invitations-handler.ts",
1246
- line: 263,
1459
+ file: "invitations-handler.ts",
1460
+ line: 342,
1247
1461
  scope: this,
1248
1462
  callSite: (f, a) => f(...a)
1249
1463
  });
1250
- observable.callback.onError(err);
1464
+ stream.error(err);
1251
1465
  }
1252
1466
  } finally {
1253
1467
  await ctx.dispose();
@@ -1258,8 +1472,7 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
1258
1472
  return extension;
1259
1473
  };
1260
1474
  (0, import_async7.scheduleTask)(ctx, async () => {
1261
- var _a, _b;
1262
- (0, import_node_assert4.default)(invitation.swarmKey);
1475
+ (0, import_node_assert5.default)(invitation.swarmKey);
1263
1476
  const topic = invitation.swarmKey;
1264
1477
  const swarmConnection = await this._networkManager.joinSwarm({
1265
1478
  topic,
@@ -1270,19 +1483,34 @@ var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHa
1270
1483
  topology: new import_network_manager.StarTopology(topic)
1271
1484
  });
1272
1485
  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();
1486
+ stream.next({
1487
+ ...invitation,
1488
+ state: import_services3.Invitation.State.CONNECTING
1489
+ });
1490
+ });
1491
+ const observable = new import_client.AuthenticatingInvitationObservable({
1492
+ initialInvitation: invitation,
1493
+ subscriber: stream.observable,
1494
+ onCancel: async () => {
1495
+ stream.next({
1496
+ ...invitation,
1497
+ state: import_services3.Invitation.State.CANCELLED
1498
+ });
1499
+ await ctx.dispose();
1500
+ },
1501
+ onAuthenticate: async (code) => {
1502
+ authenticated.wake(code);
1503
+ }
1277
1504
  });
1278
1505
  return observable;
1279
1506
  }
1280
1507
  };
1281
- var HostHaloInvitationExtension = class extends import_teleport.RpcExtension {
1508
+ var isAuthenticationRequired = (invitation) => invitation.authMethod !== import_services3.Invitation.AuthMethod.NONE;
1509
+ var InvitationHostExtension = class extends import_teleport.RpcExtension {
1282
1510
  constructor(_callbacks) {
1283
1511
  super({
1284
1512
  exposed: {
1285
- HaloHostService: import_protocols3.schema.getService("dxos.halo.invitations.HaloHostService")
1513
+ InvitationHostService: import_protocols3.schema.getService("dxos.halo.invitations.InvitationHostService")
1286
1514
  }
1287
1515
  });
1288
1516
  this._callbacks = _callbacks;
@@ -1291,16 +1519,15 @@ var HostHaloInvitationExtension = class extends import_teleport.RpcExtension {
1291
1519
  return {
1292
1520
  // TODO(dmaretskyi): For now this is just forwarding the data to callbacks since we don't have session-specific logic.
1293
1521
  // Perhaps in the future we will have more complex logic here.
1294
- HaloHostService: {
1295
- requestAdmission: async () => {
1296
- return this._callbacks.requestAdmission();
1522
+ InvitationHostService: {
1523
+ introduce: async (request) => {
1524
+ return this._callbacks.introduce(request);
1297
1525
  },
1298
- authenticate: async (credentials) => {
1299
- return this._callbacks.authenticate(credentials);
1526
+ authenticate: async (request) => {
1527
+ return this._callbacks.authenticate(request);
1300
1528
  },
1301
- // TODO(burdon): Not used: controlFeedKey, dataFeedKey.
1302
- presentAdmissionCredentials: async (credentials) => {
1303
- return this._callbacks.presentAdmissionCredentials(credentials);
1529
+ admit: async (request) => {
1530
+ return this._callbacks.admit(request);
1304
1531
  }
1305
1532
  }
1306
1533
  };
@@ -1310,11 +1537,11 @@ var HostHaloInvitationExtension = class extends import_teleport.RpcExtension {
1310
1537
  this._callbacks.onOpen();
1311
1538
  }
1312
1539
  };
1313
- var GuestHaloInvitationExtension = class extends import_teleport.RpcExtension {
1540
+ var InvitationGuestExtension = class extends import_teleport.RpcExtension {
1314
1541
  constructor(_callbacks) {
1315
1542
  super({
1316
1543
  requested: {
1317
- HaloHostService: import_protocols3.schema.getService("dxos.halo.invitations.HaloHostService")
1544
+ InvitationHostService: import_protocols3.schema.getService("dxos.halo.invitations.InvitationHostService")
1318
1545
  }
1319
1546
  });
1320
1547
  this._callbacks = _callbacks;
@@ -1329,98 +1556,102 @@ var GuestHaloInvitationExtension = class extends import_teleport.RpcExtension {
1329
1556
  };
1330
1557
 
1331
1558
  // packages/sdk/client-services/src/packlets/invitations/invitations-service.ts
1332
- var import_node_assert5 = __toESM(require("node:assert"));
1559
+ var import_node_assert6 = __toESM(require("node:assert"));
1333
1560
  var import_codec_protobuf8 = require("@dxos/codec-protobuf");
1334
1561
  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;
1562
+ var import_services4 = require("@dxos/protocols/proto/dxos/client/services");
1563
+ var InvitationsServiceImpl = class {
1564
+ constructor(_invitationsHandler, _getHandler) {
1565
+ this._invitationsHandler = _invitationsHandler;
1566
+ this._getHandler = _getHandler;
1341
1567
  this._createInvitations = /* @__PURE__ */ new Map();
1342
1568
  this._acceptInvitations = /* @__PURE__ */ new Map();
1343
1569
  }
1344
1570
  // TODO(burdon): Guest/host label.
1345
1571
  getLoggingContext() {
1346
- var _a;
1347
- return {
1348
- deviceKey: (_a = this._identityManager.identity) == null ? void 0 : _a.deviceKey
1349
- };
1572
+ return {};
1350
1573
  }
1351
1574
  createInvitation(invitation) {
1352
1575
  return new import_codec_protobuf8.Stream(({ next, close }) => {
1353
- const invitationsHandler = this._getInvitationsHandler();
1354
- const context = this.getContext(invitation);
1576
+ const handler = this._getHandler(invitation);
1355
1577
  (0, import_log5.log)("stream opened", this.getLoggingContext(), {
1356
1578
  file: "invitations-service.ts",
1357
- line: 48,
1579
+ line: 37,
1358
1580
  scope: this,
1359
1581
  callSite: (f, a) => f(...a)
1360
1582
  });
1361
1583
  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);
1584
+ const observable = this._invitationsHandler.createInvitation(handler, invitation);
1585
+ observable.subscribe((invitation2) => {
1586
+ switch (invitation2.state) {
1587
+ case import_services4.Invitation.State.CONNECTING: {
1588
+ (0, import_node_assert6.default)(invitation2.invitationId);
1589
+ invitationId = invitation2.invitationId;
1590
+ this._createInvitations.set(invitation2.invitationId, observable);
1591
+ invitation2.state = import_services4.Invitation.State.CONNECTING;
1592
+ next(invitation2);
1593
+ break;
1594
+ }
1595
+ case import_services4.Invitation.State.CONNECTED: {
1596
+ (0, import_node_assert6.default)(invitation2.invitationId);
1597
+ invitation2.state = import_services4.Invitation.State.CONNECTED;
1598
+ next(invitation2);
1599
+ break;
1600
+ }
1601
+ case import_services4.Invitation.State.READY_FOR_AUTHENTICATION: {
1602
+ (0, import_node_assert6.default)(invitation2.invitationId);
1603
+ invitation2.state = import_services4.Invitation.State.READY_FOR_AUTHENTICATION;
1604
+ next(invitation2);
1605
+ break;
1606
+ }
1607
+ case import_services4.Invitation.State.AUTHENTICATING: {
1608
+ (0, import_node_assert6.default)(invitation2.invitationId);
1609
+ invitation2.state = import_services4.Invitation.State.AUTHENTICATING;
1610
+ next(invitation2);
1611
+ break;
1612
+ }
1613
+ case import_services4.Invitation.State.SUCCESS: {
1614
+ (0, import_node_assert6.default)(invitation2.invitationId);
1615
+ invitation2.state = import_services4.Invitation.State.SUCCESS;
1616
+ next(invitation2);
1617
+ break;
1618
+ }
1619
+ case import_services4.Invitation.State.CANCELLED: {
1620
+ (0, import_node_assert6.default)(invitationId);
1621
+ invitation2.invitationId = invitationId;
1622
+ invitation2.state = import_services4.Invitation.State.CANCELLED;
1623
+ next(invitation2);
1624
+ break;
1625
+ }
1626
+ case import_services4.Invitation.State.TIMEOUT: {
1627
+ (0, import_node_assert6.default)(invitationId);
1628
+ invitation2.invitationId = invitationId;
1629
+ invitation2.state = import_services4.Invitation.State.TIMEOUT;
1630
+ next(invitation2);
1631
+ break;
1632
+ }
1406
1633
  }
1634
+ }, (err) => {
1635
+ close(err);
1636
+ }, () => {
1637
+ close();
1407
1638
  });
1408
1639
  return (err) => {
1409
- const context2 = this.getLoggingContext();
1640
+ const context = this.getLoggingContext();
1410
1641
  if (err) {
1411
1642
  import_log5.log.warn("stream closed", {
1412
- ...context2,
1643
+ ...context,
1413
1644
  err
1414
1645
  }, {
1415
1646
  file: "invitations-service.ts",
1416
- line: 97,
1647
+ line: 103,
1417
1648
  scope: this,
1418
1649
  callSite: (f, a) => f(...a)
1419
1650
  });
1420
1651
  } else {
1421
- (0, import_log5.log)("stream closed", context2, {
1652
+ (0, import_log5.log)("stream closed", context, {
1422
1653
  file: "invitations-service.ts",
1423
- line: 99,
1654
+ line: 105,
1424
1655
  scope: this,
1425
1656
  callSite: (f, a) => f(...a)
1426
1657
  });
@@ -1429,55 +1660,69 @@ var AbstractInvitationsService = class {
1429
1660
  };
1430
1661
  });
1431
1662
  }
1432
- acceptInvitation(invitation, options) {
1663
+ acceptInvitation(invitation) {
1433
1664
  return new import_codec_protobuf8.Stream(({ next, close }) => {
1434
1665
  (0, import_log5.log)("stream opened", this.getLoggingContext(), {
1435
1666
  file: "invitations-service.ts",
1436
- line: 109,
1667
+ line: 115,
1437
1668
  scope: this,
1438
1669
  callSite: (f, a) => f(...a)
1439
1670
  });
1440
- const invitationsHandler = this._getInvitationsHandler();
1671
+ const handler = this._getHandler(invitation);
1441
1672
  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);
1673
+ const observable = this._invitationsHandler.acceptInvitation(handler, invitation);
1674
+ observable.subscribe((invitation2) => {
1675
+ switch (invitation2.state) {
1676
+ case import_services4.Invitation.State.CONNECTING: {
1677
+ (0, import_node_assert6.default)(invitation2.invitationId);
1678
+ invitationId = invitation2.invitationId;
1679
+ this._acceptInvitations.set(invitation2.invitationId, observable);
1680
+ invitation2.state = import_services4.Invitation.State.CONNECTING;
1681
+ next(invitation2);
1682
+ break;
1683
+ }
1684
+ case import_services4.Invitation.State.CONNECTED: {
1685
+ (0, import_node_assert6.default)(invitation2.invitationId);
1686
+ invitation2.state = import_services4.Invitation.State.CONNECTED;
1687
+ next(invitation2);
1688
+ break;
1689
+ }
1690
+ case import_services4.Invitation.State.READY_FOR_AUTHENTICATION: {
1691
+ (0, import_node_assert6.default)(invitation2.invitationId);
1692
+ invitation2.state = import_services4.Invitation.State.READY_FOR_AUTHENTICATION;
1693
+ next(invitation2);
1694
+ break;
1695
+ }
1696
+ case import_services4.Invitation.State.AUTHENTICATING: {
1697
+ (0, import_node_assert6.default)(invitation2.invitationId);
1698
+ invitation2.state = import_services4.Invitation.State.AUTHENTICATING;
1699
+ next(invitation2);
1700
+ break;
1701
+ }
1702
+ case import_services4.Invitation.State.SUCCESS: {
1703
+ invitation2.state = import_services4.Invitation.State.SUCCESS;
1704
+ next(invitation2);
1705
+ break;
1706
+ }
1707
+ case import_services4.Invitation.State.CANCELLED: {
1708
+ (0, import_node_assert6.default)(invitationId);
1709
+ invitation2.invitationId = invitationId;
1710
+ invitation2.state = import_services4.Invitation.State.CANCELLED;
1711
+ next(invitation2);
1712
+ break;
1713
+ }
1714
+ case import_services4.Invitation.State.TIMEOUT: {
1715
+ (0, import_node_assert6.default)(invitationId);
1716
+ invitation2.invitationId = invitationId;
1717
+ invitation2.state = import_services4.Invitation.State.TIMEOUT;
1718
+ next(invitation2);
1719
+ break;
1720
+ }
1480
1721
  }
1722
+ }, (err) => {
1723
+ close(err);
1724
+ }, () => {
1725
+ close();
1481
1726
  });
1482
1727
  return (err) => {
1483
1728
  const context = this.getLoggingContext();
@@ -1487,14 +1732,14 @@ var AbstractInvitationsService = class {
1487
1732
  err
1488
1733
  }, {
1489
1734
  file: "invitations-service.ts",
1490
- line: 157,
1735
+ line: 181,
1491
1736
  scope: this,
1492
1737
  callSite: (f, a) => f(...a)
1493
1738
  });
1494
1739
  } else {
1495
1740
  (0, import_log5.log)("stream closed", context, {
1496
1741
  file: "invitations-service.ts",
1497
- line: 159,
1742
+ line: 183,
1498
1743
  scope: this,
1499
1744
  callSite: (f, a) => f(...a)
1500
1745
  });
@@ -1503,531 +1748,140 @@ var AbstractInvitationsService = class {
1503
1748
  };
1504
1749
  });
1505
1750
  }
1506
- async authenticate({ invitationId, authenticationCode }) {
1751
+ async authenticate({ invitationId, authCode }) {
1507
1752
  (0, import_log5.log)("authenticating...", {}, {
1508
1753
  file: "invitations-service.ts",
1509
- line: 168,
1754
+ line: 192,
1510
1755
  scope: this,
1511
1756
  callSite: (f, a) => f(...a)
1512
1757
  });
1513
- (0, import_node_assert5.default)(invitationId);
1758
+ (0, import_node_assert6.default)(invitationId);
1514
1759
  const observable = this._acceptInvitations.get(invitationId);
1515
1760
  if (!observable) {
1516
1761
  import_log5.log.warn("invalid invitation", {
1517
1762
  invitationId
1518
1763
  }, {
1519
1764
  file: "invitations-service.ts",
1520
- line: 172,
1765
+ line: 196,
1521
1766
  scope: this,
1522
1767
  callSite: (f, a) => f(...a)
1523
1768
  });
1524
1769
  } else {
1525
- await observable.authenticate(authenticationCode);
1770
+ await observable.authenticate(authCode);
1526
1771
  }
1527
1772
  }
1528
- async cancelInvitation(invitation) {
1773
+ async cancelInvitation({ invitationId }) {
1529
1774
  var _a;
1530
1775
  (0, import_log5.log)("cancelling...", {}, {
1531
- file: "invitations-service.ts",
1532
- line: 179,
1533
- scope: this,
1534
- callSite: (f, a) => f(...a)
1535
- });
1536
- (0, import_node_assert5.default)(invitation.invitationId);
1537
- const observable = (_a = this._createInvitations.get(invitation.invitationId)) != null ? _a : this._acceptInvitations.get(invitation.invitationId);
1538
- if (!observable) {
1539
- import_log5.log.warn("invalid invitation", {
1540
- invitationId: invitation.invitationId
1541
- }, {
1542
- file: "invitations-service.ts",
1543
- line: 184,
1544
- scope: this,
1545
- callSite: (f, a) => f(...a)
1546
- });
1547
- } else {
1548
- 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();
1776
+ file: "invitations-service.ts",
1777
+ line: 203,
1778
+ scope: this,
1779
+ callSite: (f, a) => f(...a)
1962
1780
  });
1963
- return observable;
1781
+ (0, import_node_assert6.default)(invitationId);
1782
+ const observable = (_a = this._createInvitations.get(invitationId)) != null ? _a : this._acceptInvitations.get(invitationId);
1783
+ if (!observable) {
1784
+ import_log5.log.warn("invalid invitation", {
1785
+ invitationId
1786
+ }, {
1787
+ file: "invitations-service.ts",
1788
+ line: 207,
1789
+ scope: this,
1790
+ callSite: (f, a) => f(...a)
1791
+ });
1792
+ } else {
1793
+ await (observable == null ? void 0 : observable.cancel());
1794
+ }
1964
1795
  }
1965
1796
  };
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;
1797
+
1798
+ // packages/sdk/client-services/src/packlets/invitations/space-invitation-protocol.ts
1799
+ var import_node_assert7 = __toESM(require("node:assert"));
1800
+ var import_credentials9 = require("@dxos/credentials");
1801
+ var import_feed_store3 = require("@dxos/feed-store");
1802
+ var import_log6 = require("@dxos/log");
1803
+ var import_services5 = require("@dxos/protocols/proto/dxos/client/services");
1804
+ var SpaceInvitationProtocol = class {
1805
+ constructor(_spaceManager, _signingContext, _keyring, _spaceKey) {
1806
+ this._spaceManager = _spaceManager;
1807
+ this._signingContext = _signingContext;
1808
+ this._keyring = _keyring;
1809
+ this._spaceKey = _spaceKey;
1975
1810
  }
1976
- async getHandlers() {
1811
+ toJSON() {
1977
1812
  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
- }
1813
+ deviceKey: this._signingContext.deviceKey,
1814
+ spaceKey: this._spaceKey
1991
1815
  };
1992
1816
  }
1993
- async onOpen(context) {
1994
- await super.onOpen(context);
1995
- this._callbacks.onOpen();
1817
+ getInvitationContext() {
1818
+ return {
1819
+ kind: import_services5.Invitation.Kind.SPACE,
1820
+ spaceKey: this._spaceKey
1821
+ };
1996
1822
  }
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
- }
1823
+ async admit(request, guestProfile) {
1824
+ var _a;
1825
+ (0, import_node_assert7.default)(this._spaceKey);
1826
+ const space = await this._spaceManager.spaces.get(this._spaceKey);
1827
+ (0, import_node_assert7.default)(space);
1828
+ (0, import_node_assert7.default)(request.space);
1829
+ const { identityKey, deviceKey } = request.space;
1830
+ (0, import_log6.log)("writing guest credentials", {
1831
+ host: this._signingContext.deviceKey,
1832
+ guest: deviceKey
1833
+ }, {
1834
+ file: "space-invitation-protocol.ts",
1835
+ line: 51,
1836
+ scope: this,
1837
+ callSite: (f, a) => f(...a)
2004
1838
  });
2005
- this._callbacks = _callbacks;
1839
+ const credentials = await (0, import_credentials9.createAdmissionCredentials)(this._signingContext.credentialSigner, identityKey, space.key, space.inner.genesisFeedKey, guestProfile);
1840
+ (0, import_node_assert7.default)(credentials[0].credential);
1841
+ const spaceMemberCredential = credentials[0].credential.credential;
1842
+ (0, import_node_assert7.default)((0, import_credentials9.getCredentialAssertion)(spaceMemberCredential)["@type"] === "dxos.halo.credentials.SpaceMember");
1843
+ await (0, import_feed_store3.writeMessages)(space.inner.controlPipeline.writer, credentials);
1844
+ return {
1845
+ space: {
1846
+ credential: spaceMemberCredential,
1847
+ controlTimeframe: space.inner.controlPipeline.state.timeframe,
1848
+ dataTimeframe: (_a = space.dataPipeline.pipelineState) == null ? void 0 : _a.timeframe
1849
+ }
1850
+ };
2006
1851
  }
2007
- async getHandlers() {
2008
- return {};
1852
+ createIntroduction() {
1853
+ return {
1854
+ profile: this._signingContext.profile
1855
+ };
2009
1856
  }
2010
- async onOpen(context) {
2011
- await super.onOpen(context);
2012
- this._callbacks.onOpen();
1857
+ async createAdmissionRequest() {
1858
+ const controlFeedKey = await this._keyring.createKey();
1859
+ const dataFeedKey = await this._keyring.createKey();
1860
+ return {
1861
+ space: {
1862
+ identityKey: this._signingContext.identityKey,
1863
+ deviceKey: this._signingContext.deviceKey,
1864
+ controlFeedKey,
1865
+ dataFeedKey
1866
+ }
1867
+ };
2013
1868
  }
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;
1869
+ async accept(response) {
1870
+ (0, import_node_assert7.default)(response.space);
1871
+ const { credential, controlTimeframe, dataTimeframe } = response.space;
1872
+ const assertion = (0, import_credentials9.getCredentialAssertion)(credential);
1873
+ (0, import_node_assert7.default)(assertion["@type"] === "dxos.halo.credentials.SpaceMember", "Invalid credential");
1874
+ (0, import_node_assert7.default)(credential.subject.id.equals(this._signingContext.identityKey));
1875
+ await this._spaceManager.acceptSpace({
1876
+ spaceKey: assertion.spaceKey,
1877
+ genesisFeedKey: assertion.genesisFeedKey,
1878
+ controlTimeframe,
1879
+ dataTimeframe
1880
+ });
1881
+ await this._signingContext.recordCredential(credential);
1882
+ return {
1883
+ spaceKey: assertion.spaceKey
1884
+ };
2031
1885
  }
2032
1886
  };
2033
1887
 
@@ -2055,47 +1909,47 @@ var NetworkServiceImpl = class {
2055
1909
 
2056
1910
  // packages/sdk/client-services/src/packlets/spaces/data-space-manager.ts
2057
1911
  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");
1912
+ var import_async10 = require("@dxos/async");
1913
+ var import_client3 = require("@dxos/client");
1914
+ var import_context6 = require("@dxos/context");
2061
1915
  var import_credentials11 = require("@dxos/credentials");
2062
1916
  var import_echo_pipeline2 = require("@dxos/echo-pipeline");
2063
- var import_keys10 = require("@dxos/keys");
1917
+ var import_keys9 = require("@dxos/keys");
2064
1918
  var import_log9 = require("@dxos/log");
2065
1919
  var import_teleport_extension_gossip = require("@dxos/teleport-extension-gossip");
2066
1920
  var import_util5 = require("@dxos/util");
2067
1921
 
2068
1922
  // 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");
1923
+ var import_async9 = require("@dxos/async");
1924
+ var import_client2 = require("@dxos/client");
1925
+ var import_context5 = require("@dxos/context");
2072
1926
  var import_debug3 = require("@dxos/debug");
2073
1927
  var import_echo_pipeline = require("@dxos/echo-pipeline");
2074
1928
  var import_errors = require("@dxos/errors");
2075
- var import_keys9 = require("@dxos/keys");
1929
+ var import_keys8 = require("@dxos/keys");
2076
1930
  var import_log8 = require("@dxos/log");
2077
1931
  var import_credentials10 = require("@dxos/protocols/proto/dxos/halo/credentials");
2078
1932
  var import_util4 = require("@dxos/util");
2079
1933
 
2080
1934
  // packages/sdk/client-services/src/packlets/spaces/notarization-plugin.ts
2081
1935
  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");
1936
+ var import_async8 = require("@dxos/async");
1937
+ var import_context4 = require("@dxos/context");
1938
+ var import_keys7 = require("@dxos/keys");
2085
1939
  var import_log7 = require("@dxos/log");
2086
- var import_protocols5 = require("@dxos/protocols");
2087
- var import_teleport3 = require("@dxos/teleport");
1940
+ var import_protocols4 = require("@dxos/protocols");
1941
+ var import_teleport2 = require("@dxos/teleport");
2088
1942
  var import_util3 = require("@dxos/util");
2089
1943
  var DEFAULT_RETRY_TIMEOUT = 1e3;
2090
1944
  var DEFAULT_SUCCESS_DELAY = 1e3;
2091
1945
  var DEFAULT_NOTARIZE_TIMEOUT = 1e4;
2092
1946
  var NotarizationPlugin = class {
2093
1947
  constructor() {
2094
- this._ctx = new import_context5.Context();
2095
- this._extensionOpened = new import_async9.Event();
1948
+ this._ctx = new import_context4.Context();
1949
+ this._extensionOpened = new import_async8.Event();
2096
1950
  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);
1951
+ this._processedCredentials = new import_util3.ComplexSet(import_keys7.PublicKey.hash);
1952
+ this._processCredentialsTriggers = new import_util3.ComplexMap(import_keys7.PublicKey.hash);
2099
1953
  }
2100
1954
  async open() {
2101
1955
  }
@@ -2115,7 +1969,7 @@ var NotarizationPlugin = class {
2115
1969
  callSite: (f, a) => f(...a)
2116
1970
  });
2117
1971
  (0, import_node_assert8.default)(credentials.every((credential) => credential.id), "Credentials must have an id");
2118
- const errors = new import_async9.Trigger();
1972
+ const errors = new import_async8.Trigger();
2119
1973
  const ctx = this._ctx.derive({
2120
1974
  onError: (err) => {
2121
1975
  import_log7.log.warn("Notarization error", {
@@ -2132,7 +1986,7 @@ var NotarizationPlugin = class {
2132
1986
  });
2133
1987
  opCtx == null ? void 0 : opCtx.onDispose(() => ctx.dispose());
2134
1988
  if (timeout !== 0) {
2135
- (0, import_async9.scheduleTask)(ctx, () => {
1989
+ (0, import_async8.scheduleTask)(ctx, () => {
2136
1990
  import_log7.log.warn("Notarization timeout", {
2137
1991
  timeout,
2138
1992
  peers: Array.from(this._extensions).map((extension) => extension.remotePeerId)
@@ -2143,12 +1997,12 @@ var NotarizationPlugin = class {
2143
1997
  callSite: (f, a) => f(...a)
2144
1998
  });
2145
1999
  void ctx.dispose();
2146
- errors.throw(new import_async9.TimeoutError(timeout, "Notarization timed out"));
2000
+ errors.throw(new import_async8.TimeoutError(timeout, "Notarization timed out"));
2147
2001
  }, timeout);
2148
2002
  }
2149
2003
  const allNotarized = Promise.all(credentials.map((credential) => this._waitUntilProcessed(credential.id)));
2150
2004
  const peersTried = /* @__PURE__ */ new Set();
2151
- const notarizeTask = new import_async9.DeferredTask(ctx, async () => {
2005
+ const notarizeTask = new import_async8.DeferredTask(ctx, async () => {
2152
2006
  try {
2153
2007
  if (this._extensions.size === 0) {
2154
2008
  return;
@@ -2166,7 +2020,7 @@ var NotarizationPlugin = class {
2166
2020
  callSite: (f, a) => f(...a)
2167
2021
  });
2168
2022
  peersTried.clear();
2169
- (0, import_async9.scheduleTask)(ctx, () => notarizeTask.schedule(), retryTimeout);
2023
+ (0, import_async8.scheduleTask)(ctx, () => notarizeTask.schedule(), retryTimeout);
2170
2024
  return;
2171
2025
  }
2172
2026
  peersTried.add(peer);
@@ -2188,7 +2042,7 @@ var NotarizationPlugin = class {
2188
2042
  scope: this,
2189
2043
  callSite: (f, a) => f(...a)
2190
2044
  });
2191
- await (0, import_async9.sleep)(successDelay);
2045
+ await (0, import_async8.sleep)(successDelay);
2192
2046
  } catch (err) {
2193
2047
  import_log7.log.warn("error notarizing (recoverable)", err, {
2194
2048
  file: "notarization-plugin.ts",
@@ -2203,7 +2057,7 @@ var NotarizationPlugin = class {
2203
2057
  this._extensionOpened.on(ctx, () => notarizeTask.schedule());
2204
2058
  try {
2205
2059
  await Promise.race([
2206
- (0, import_context5.rejectOnDispose)(ctx),
2060
+ (0, import_context4.rejectOnDispose)(ctx),
2207
2061
  allNotarized,
2208
2062
  errors.wait()
2209
2063
  ]);
@@ -2237,7 +2091,7 @@ var NotarizationPlugin = class {
2237
2091
  if (this._processedCredentials.has(id)) {
2238
2092
  return;
2239
2093
  }
2240
- await (0, import_util3.entry)(this._processCredentialsTriggers, id).orInsert(new import_async9.Trigger()).value.wait();
2094
+ await (0, import_util3.entry)(this._processCredentialsTriggers, id).orInsert(new import_async8.Trigger()).value.wait();
2241
2095
  }
2242
2096
  /**
2243
2097
  * Requests from other peers to notarize credentials.
@@ -2285,14 +2139,14 @@ var NotarizationPlugin = class {
2285
2139
  return extension;
2286
2140
  }
2287
2141
  };
2288
- var NotarizationTeleportExtension = class extends import_teleport3.RpcExtension {
2142
+ var NotarizationTeleportExtension = class extends import_teleport2.RpcExtension {
2289
2143
  constructor(_params) {
2290
2144
  super({
2291
2145
  requested: {
2292
- NotarizationService: import_protocols5.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2146
+ NotarizationService: import_protocols4.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2293
2147
  },
2294
2148
  exposed: {
2295
- NotarizationService: import_protocols5.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2149
+ NotarizationService: import_protocols4.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2296
2150
  }
2297
2151
  });
2298
2152
  this._params = _params;
@@ -2330,9 +2184,9 @@ var __decorate = function(decorators, target, key, desc) {
2330
2184
  var AUTH_TIMEOUT2 = 3e4;
2331
2185
  var DataSpace = class DataSpace2 {
2332
2186
  constructor(params) {
2333
- this._ctx = new import_context6.Context();
2334
- this._state = import_client3.SpaceState.CLOSED;
2335
- this.stateUpdate = new import_async10.Event();
2187
+ this._ctx = new import_context5.Context();
2188
+ this._state = import_client2.SpaceState.CLOSED;
2189
+ this.stateUpdate = new import_async9.Event();
2336
2190
  var _a;
2337
2191
  this._inner = params.inner;
2338
2192
  this._inner.stateUpdate.on(this._ctx, () => this.stateUpdate.emit());
@@ -2353,7 +2207,7 @@ var DataSpace = class DataSpace2 {
2353
2207
  snapshotId: params.snapshotId
2354
2208
  });
2355
2209
  this.authVerifier = new TrustedKeySetAuthVerifier({
2356
- trustedKeysProvider: () => new import_util4.ComplexSet(import_keys9.PublicKey.hash, Array.from(this._inner.spaceState.members.keys())),
2210
+ trustedKeysProvider: () => new import_util4.ComplexSet(import_keys8.PublicKey.hash, Array.from(this._inner.spaceState.members.keys())),
2357
2211
  update: this._inner.stateUpdate,
2358
2212
  authTimeout: AUTH_TIMEOUT2
2359
2213
  });
@@ -2385,10 +2239,10 @@ var DataSpace = class DataSpace2 {
2385
2239
  await this.notarizationPlugin.open();
2386
2240
  await this._notarizationPluginConsumer.open();
2387
2241
  await this._inner.open();
2388
- this._state = import_client3.SpaceState.INACTIVE;
2242
+ this._state = import_client2.SpaceState.INACTIVE;
2389
2243
  }
2390
2244
  async close() {
2391
- this._state = import_client3.SpaceState.CLOSED;
2245
+ this._state = import_client2.SpaceState.CLOSED;
2392
2246
  await this._ctx.dispose();
2393
2247
  await this._dataPipeline.close();
2394
2248
  await this.authVerifier.close();
@@ -2407,7 +2261,7 @@ var DataSpace = class DataSpace2 {
2407
2261
  * Initialize the data pipeline in a separate task.
2408
2262
  */
2409
2263
  initializeDataPipelineAsync() {
2410
- (0, import_async10.scheduleTask)(this._ctx, async () => {
2264
+ (0, import_async9.scheduleTask)(this._ctx, async () => {
2411
2265
  try {
2412
2266
  await this.initializeDataPipeline();
2413
2267
  } catch (err) {
@@ -2431,10 +2285,10 @@ var DataSpace = class DataSpace2 {
2431
2285
  }
2432
2286
  async initializeDataPipeline() {
2433
2287
  var _a, _b, _c, _d;
2434
- if (this._state !== import_client3.SpaceState.INACTIVE) {
2288
+ if (this._state !== import_client2.SpaceState.INACTIVE) {
2435
2289
  throw new import_errors.SystemError("Invalid operation");
2436
2290
  }
2437
- this._state = import_client3.SpaceState.INITIALIZING;
2291
+ this._state = import_client2.SpaceState.INITIALIZING;
2438
2292
  await this._inner.controlPipeline.state.waitUntilReachedTargetTimeframe({
2439
2293
  ctx: this._ctx,
2440
2294
  breakOnStall: false
@@ -2478,7 +2332,7 @@ var DataSpace = class DataSpace2 {
2478
2332
  callSite: (f, a) => f(...a)
2479
2333
  });
2480
2334
  await ((_b = (_a = this._callbacks).beforeReady) == null ? void 0 : _b.call(_a));
2481
- this._state = import_client3.SpaceState.READY;
2335
+ this._state = import_client2.SpaceState.READY;
2482
2336
  this.stateUpdate.emit();
2483
2337
  await ((_d = (_c = this._callbacks).afterReady) == null ? void 0 : _d.call(_c));
2484
2338
  }
@@ -2530,7 +2384,7 @@ __decorate([
2530
2384
  (0, import_debug3.timed)(1e4)
2531
2385
  ], DataSpace.prototype, "_createWritableFeeds", null);
2532
2386
  DataSpace = __decorate([
2533
- (0, import_async10.trackLeaks)("open", "close")
2387
+ (0, import_async9.trackLeaks)("open", "close")
2534
2388
  ], DataSpace);
2535
2389
 
2536
2390
  // packages/sdk/client-services/src/packlets/spaces/data-space-manager.ts
@@ -2554,9 +2408,9 @@ var DataSpaceManager = class DataSpaceManager2 {
2554
2408
  this._modelFactory = _modelFactory;
2555
2409
  this._feedStore = _feedStore;
2556
2410
  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);
2411
+ this._ctx = new import_context6.Context();
2412
+ this.updated = new import_async10.Event();
2413
+ this._spaces = new import_util5.ComplexMap(import_keys9.PublicKey.hash);
2560
2414
  this._isOpen = false;
2561
2415
  }
2562
2416
  // TODO(burdon): Remove.
@@ -2669,9 +2523,9 @@ var DataSpaceManager = class DataSpaceManager2 {
2669
2523
  * TODO(dmaretskyi): Consider removing.
2670
2524
  */
2671
2525
  async waitUntilSpaceReady(spaceKey) {
2672
- await (0, import_context7.cancelWithContext)(this._ctx, this.updated.waitForCondition(() => {
2526
+ await (0, import_context6.cancelWithContext)(this._ctx, this.updated.waitForCondition(() => {
2673
2527
  const space = this._spaces.get(spaceKey);
2674
- return !!space && space.state === import_client4.SpaceState.READY;
2528
+ return !!space && space.state === import_client3.SpaceState.READY;
2675
2529
  }));
2676
2530
  }
2677
2531
  async _constructSpace(metadata) {
@@ -2768,28 +2622,28 @@ var DataSpaceManager = class DataSpaceManager2 {
2768
2622
  }
2769
2623
  };
2770
2624
  __decorate2([
2771
- import_async11.synchronized
2625
+ import_async10.synchronized
2772
2626
  ], DataSpaceManager.prototype, "open", null);
2773
2627
  __decorate2([
2774
- import_async11.synchronized
2628
+ import_async10.synchronized
2775
2629
  ], DataSpaceManager.prototype, "close", null);
2776
2630
  __decorate2([
2777
- import_async11.synchronized
2631
+ import_async10.synchronized
2778
2632
  ], DataSpaceManager.prototype, "createSpace", null);
2779
2633
  __decorate2([
2780
- import_async11.synchronized
2634
+ import_async10.synchronized
2781
2635
  ], DataSpaceManager.prototype, "acceptSpace", null);
2782
2636
  DataSpaceManager = __decorate2([
2783
- (0, import_async11.trackLeaks)("open", "close")
2637
+ (0, import_async10.trackLeaks)("open", "close")
2784
2638
  ], DataSpaceManager);
2785
2639
 
2786
2640
  // packages/sdk/client-services/src/packlets/spaces/spaces-service.ts
2787
- var import_async12 = require("@dxos/async");
2641
+ var import_async11 = require("@dxos/async");
2788
2642
  var import_codec_protobuf10 = require("@dxos/codec-protobuf");
2789
2643
  var import_debug4 = require("@dxos/debug");
2790
2644
  var import_echo_pipeline3 = require("@dxos/echo-pipeline");
2791
2645
  var import_log10 = require("@dxos/log");
2792
- var import_services5 = require("@dxos/protocols/proto/dxos/client/services");
2646
+ var import_services6 = require("@dxos/protocols/proto/dxos/client/services");
2793
2647
  var import_util6 = require("@dxos/util");
2794
2648
  var TIMEFRAME_UPDATE_DEBOUNCE_TIME = 500;
2795
2649
  var SpacesServiceImpl = class {
@@ -2827,9 +2681,9 @@ var SpacesServiceImpl = class {
2827
2681
  spaces
2828
2682
  });
2829
2683
  };
2830
- (0, import_async12.scheduleTask)(ctx, async () => {
2684
+ (0, import_async11.scheduleTask)(ctx, async () => {
2831
2685
  const dataSpaceManager = await this._getDataSpaceManager();
2832
- const subscriptions = new import_async12.EventSubscriptions();
2686
+ const subscriptions = new import_async11.EventSubscriptions();
2833
2687
  ctx.onDispose(() => subscriptions.clear());
2834
2688
  const subscribeSpaces = () => {
2835
2689
  subscriptions.clear();
@@ -2864,7 +2718,7 @@ var SpacesServiceImpl = class {
2864
2718
  }
2865
2719
  subscribeMessages({ spaceKey, channel }) {
2866
2720
  return new import_codec_protobuf10.Stream(({ ctx, next }) => {
2867
- (0, import_async12.scheduleTask)(ctx, async () => {
2721
+ (0, import_async11.scheduleTask)(ctx, async () => {
2868
2722
  var _a;
2869
2723
  const dataSpaceManager = await this._getDataSpaceManager();
2870
2724
  const space = (_a = dataSpaceManager.spaces.get(spaceKey)) != null ? _a : (0, import_debug4.raise)(new import_echo_pipeline3.SpaceNotFoundError(spaceKey));
@@ -2885,7 +2739,7 @@ var SpacesServiceImpl = class {
2885
2739
  }
2886
2740
  });
2887
2741
  ctx.onDispose(() => processor.close());
2888
- (0, import_async12.scheduleTask)(ctx, () => processor.open());
2742
+ (0, import_async11.scheduleTask)(ctx, () => processor.open());
2889
2743
  });
2890
2744
  }
2891
2745
  async writeCredentials({ spaceKey, credentials }) {
@@ -2900,18 +2754,22 @@ var SpacesServiceImpl = class {
2900
2754
  }
2901
2755
  }
2902
2756
  _transformSpace(space) {
2903
- var _a, _b;
2757
+ var _a, _b, _c, _d, _e;
2904
2758
  return {
2905
2759
  spaceKey: space.key,
2906
2760
  state: space.state,
2907
2761
  pipeline: {
2908
- targetControlTimeframe: space.inner.controlPipeline.state.targetTimeframe,
2762
+ controlFeeds: space.inner.controlPipeline.state.feeds.map((feed) => feed.key),
2909
2763
  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
2764
+ targetControlTimeframe: space.inner.controlPipeline.state.targetTimeframe,
2765
+ totalControlTimeframe: space.inner.controlPipeline.state.endTimeframe,
2766
+ dataFeeds: (_b = (_a = space.dataPipeline.pipelineState) == null ? void 0 : _a.feeds.map((feed) => feed.key)) != null ? _b : [],
2767
+ currentDataTimeframe: (_c = space.dataPipeline.pipelineState) == null ? void 0 : _c.timeframe,
2768
+ targetDataTimeframe: (_d = space.dataPipeline.pipelineState) == null ? void 0 : _d.targetTimeframe,
2769
+ totalDataTimeframe: (_e = space.dataPipeline.pipelineState) == null ? void 0 : _e.endTimeframe
2912
2770
  },
2913
2771
  members: Array.from(space.inner.spaceState.members.values()).map((member) => {
2914
- var _a2, _b2, _c;
2772
+ var _a2, _b2, _c2;
2915
2773
  return {
2916
2774
  identity: {
2917
2775
  identityKey: member.key,
@@ -2919,7 +2777,7 @@ var SpacesServiceImpl = class {
2919
2777
  displayName: (_b2 = (_a2 = member.assertion.profile) == null ? void 0 : _a2.displayName) != null ? _b2 : (0, import_util6.humanize)(member.key)
2920
2778
  }
2921
2779
  },
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
2780
+ 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
2781
  };
2924
2782
  })
2925
2783
  };
@@ -3011,10 +2869,10 @@ var SystemServiceImpl = class {
3011
2869
  };
3012
2870
 
3013
2871
  // packages/sdk/client-services/src/packlets/vault/iframe-host-runtime.ts
3014
- var import_async14 = require("@dxos/async");
2872
+ var import_async13 = require("@dxos/async");
3015
2873
  var import_log11 = require("@dxos/log");
3016
2874
  var import_messaging = require("@dxos/messaging");
3017
- var import_network_manager3 = require("@dxos/network-manager");
2875
+ var import_network_manager2 = require("@dxos/network-manager");
3018
2876
  var import_util7 = require("@dxos/util");
3019
2877
 
3020
2878
  // packages/sdk/client-services/src/packlets/services/client-rpc-server.ts
@@ -3072,14 +2930,14 @@ var ClientRpcServer = class {
3072
2930
 
3073
2931
  // packages/sdk/client-services/src/packlets/vault/shell-runtime.ts
3074
2932
  var import_node_assert10 = __toESM(require("node:assert"));
3075
- var import_async13 = require("@dxos/async");
3076
- var import_client5 = require("@dxos/client");
2933
+ var import_async12 = require("@dxos/async");
2934
+ var import_client4 = require("@dxos/client");
3077
2935
  var import_iframe = require("@dxos/protocols/proto/dxos/iframe");
3078
2936
  var import_rpc2 = require("@dxos/rpc");
3079
2937
  var ShellRuntimeImpl = class {
3080
2938
  constructor(_port) {
3081
2939
  this._port = _port;
3082
- this.layoutUpdate = new import_async13.Event();
2940
+ this.layoutUpdate = new import_async12.Event();
3083
2941
  this._layout = import_iframe.ShellLayout.DEFAULT;
3084
2942
  }
3085
2943
  get layout() {
@@ -3106,8 +2964,8 @@ var ShellRuntimeImpl = class {
3106
2964
  }
3107
2965
  async open() {
3108
2966
  this._appRpc = (0, import_rpc2.createProtoRpcPeer)({
3109
- requested: import_client5.appServiceBundle,
3110
- exposed: import_client5.shellServiceBundle,
2967
+ requested: import_client4.appServiceBundle,
2968
+ exposed: import_client4.shellServiceBundle,
3111
2969
  handlers: {
3112
2970
  ShellService: {
3113
2971
  setLayout: async (request) => {
@@ -3143,8 +3001,8 @@ var __decorate3 = function(decorators, target, key, desc) {
3143
3001
  var LOCK_KEY = "DXOS_RESOURCE_LOCK";
3144
3002
  var IFrameHostRuntime = class {
3145
3003
  constructor({ configProvider, appPort, shellPort }) {
3146
- this._transportFactory = (0, import_network_manager3.createWebRTCTransportFactory)();
3147
- this._ready = new import_async14.Trigger();
3004
+ this._transportFactory = (0, import_network_manager2.createWebRTCTransportFactory)();
3005
+ this._ready = new import_async13.Trigger();
3148
3006
  this._configProvider = configProvider;
3149
3007
  this._appPort = appPort;
3150
3008
  this._shellPort = shellPort;
@@ -3172,7 +3030,7 @@ var IFrameHostRuntime = class {
3172
3030
  this._clientServices = new LocalClientServices({
3173
3031
  lockKey: LOCK_KEY,
3174
3032
  config: this._config,
3175
- networkManager: new import_network_manager3.NetworkManager({
3033
+ networkManager: new import_network_manager2.NetworkManager({
3176
3034
  log: true,
3177
3035
  signalManager: signalServer ? new import_messaging.WebsocketSignalManager([
3178
3036
  signalServer
@@ -3251,12 +3109,12 @@ __decorate3([
3251
3109
  ], IFrameHostRuntime.prototype, "origin", void 0);
3252
3110
 
3253
3111
  // 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");
3112
+ var import_client5 = require("@dxos/client");
3113
+ var import_network_manager3 = require("@dxos/network-manager");
3256
3114
  var import_rpc3 = require("@dxos/rpc");
3257
3115
 
3258
3116
  // packages/sdk/client-services/src/packlets/vault/vault-resource-lock.ts
3259
- var import_async15 = require("@dxos/async");
3117
+ var import_async14 = require("@dxos/async");
3260
3118
  var import_log12 = require("@dxos/log");
3261
3119
  var __decorate4 = function(decorators, target, key, desc) {
3262
3120
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -3275,7 +3133,7 @@ var Message;
3275
3133
  var VaultResourceLock = class {
3276
3134
  constructor({ lockKey, onAcquire, onRelease }) {
3277
3135
  this._broadcastChannel = new BroadcastChannel("vault-resource-lock");
3278
- this._releaseTrigger = new import_async15.Trigger();
3136
+ this._releaseTrigger = new import_async14.Trigger();
3279
3137
  this._lockKey = lockKey;
3280
3138
  this._onAcquire = onAcquire;
3281
3139
  this._onRelease = onRelease;
@@ -3295,7 +3153,7 @@ var VaultResourceLock = class {
3295
3153
  scope: this,
3296
3154
  callSite: (f, a) => f(...a)
3297
3155
  });
3298
- await (0, import_async15.asyncTimeout)(this._requestLock(), 3e3);
3156
+ await (0, import_async14.asyncTimeout)(this._requestLock(), 3e3);
3299
3157
  (0, import_log12.log)("acquired lock", {}, {
3300
3158
  file: "vault-resource-lock.ts",
3301
3159
  line: 46,
@@ -3335,14 +3193,14 @@ var VaultResourceLock = class {
3335
3193
  scope: this,
3336
3194
  callSite: (f, a) => f(...a)
3337
3195
  });
3338
- const acquired = new import_async15.Trigger();
3196
+ const acquired = new import_async14.Trigger();
3339
3197
  void navigator.locks.request(this._lockKey, {
3340
3198
  steal
3341
3199
  }, async () => {
3342
3200
  var _a, _b;
3343
3201
  await ((_a = this._onAcquire) == null ? void 0 : _a.call(this));
3344
3202
  acquired.wake();
3345
- this._releaseTrigger = new import_async15.Trigger();
3203
+ this._releaseTrigger = new import_async14.Trigger();
3346
3204
  await this._releaseTrigger.wait();
3347
3205
  (0, import_log12.log)("releasing lock...", {}, {
3348
3206
  file: "vault-resource-lock.ts",
@@ -3377,15 +3235,15 @@ __decorate4([
3377
3235
  ], VaultResourceLock.prototype, "lockKey", null);
3378
3236
 
3379
3237
  // packages/sdk/client-services/src/packlets/vault/worker-runtime.ts
3380
- var import_async17 = require("@dxos/async");
3238
+ var import_async16 = require("@dxos/async");
3381
3239
  var import_log14 = require("@dxos/log");
3382
3240
  var import_messaging2 = require("@dxos/messaging");
3383
- var import_network_manager5 = require("@dxos/network-manager");
3241
+ var import_network_manager4 = require("@dxos/network-manager");
3384
3242
 
3385
3243
  // packages/sdk/client-services/src/packlets/vault/worker-session.ts
3386
3244
  var import_node_assert11 = __toESM(require("node:assert"));
3387
- var import_async16 = require("@dxos/async");
3388
- var import_client7 = require("@dxos/client");
3245
+ var import_async15 = require("@dxos/async");
3246
+ var import_client6 = require("@dxos/client");
3389
3247
  var import_log13 = require("@dxos/log");
3390
3248
  var import_rpc4 = require("@dxos/rpc");
3391
3249
  var import_util8 = require("@dxos/util");
@@ -3403,7 +3261,7 @@ var WorkerSession = class {
3403
3261
  constructor({ serviceHost, systemPort, appPort, shellPort, readySignal, options = {
3404
3262
  heartbeatInterval: 1e3
3405
3263
  } }) {
3406
- this._startTrigger = new import_async16.Trigger();
3264
+ this._startTrigger = new import_async15.Trigger();
3407
3265
  this.onClose = new import_util8.Callback();
3408
3266
  (0, import_node_assert11.default)(options);
3409
3267
  (0, import_node_assert11.default)(serviceHost);
@@ -3440,8 +3298,8 @@ var WorkerSession = class {
3440
3298
  ...middleware
3441
3299
  });
3442
3300
  this._iframeRpc = (0, import_rpc4.createProtoRpcPeer)({
3443
- requested: import_client7.iframeServiceBundle,
3444
- exposed: import_client7.workerServiceBundle,
3301
+ requested: import_client6.iframeServiceBundle,
3302
+ exposed: import_client6.workerServiceBundle,
3445
3303
  handlers: {
3446
3304
  WorkerService: {
3447
3305
  start: async (request) => {
@@ -3537,7 +3395,7 @@ var WorkerSession = class {
3537
3395
  }
3538
3396
  async _maybeOpenShell() {
3539
3397
  try {
3540
- await (0, import_async16.asyncTimeout)(this._shellClientRpc.open(), 1e3);
3398
+ await (0, import_async15.asyncTimeout)(this._shellClientRpc.open(), 1e3);
3541
3399
  } catch (e) {
3542
3400
  import_log13.log.info("No shell connected.", {}, {
3543
3401
  file: "worker-session.ts",
@@ -3553,24 +3411,27 @@ __decorate5([
3553
3411
  ], WorkerSession.prototype, "origin", void 0);
3554
3412
 
3555
3413
  // packages/sdk/client-services/src/packlets/services/service-context.ts
3556
- var import_async18 = require("@dxos/async");
3414
+ var import_node_assert12 = __toESM(require("node:assert"));
3415
+ var import_async17 = require("@dxos/async");
3416
+ var import_client7 = require("@dxos/client");
3557
3417
  var import_credentials12 = require("@dxos/credentials");
3558
3418
  var import_debug6 = require("@dxos/debug");
3559
3419
  var import_echo_pipeline4 = require("@dxos/echo-pipeline");
3560
3420
  var import_feed_store4 = require("@dxos/feed-store");
3561
3421
  var import_keyring = require("@dxos/keyring");
3562
- var import_keys11 = require("@dxos/keys");
3422
+ var import_keys10 = require("@dxos/keys");
3563
3423
  var import_log15 = require("@dxos/log");
3564
- var import_protocols6 = require("@dxos/protocols");
3424
+ var import_protocols5 = require("@dxos/protocols");
3565
3425
  var ServiceContext = class {
3566
3426
  // prettier-ignore
3567
3427
  constructor(storage, networkManager, modelFactory) {
3568
3428
  this.storage = storage;
3569
3429
  this.networkManager = networkManager;
3570
3430
  this.modelFactory = modelFactory;
3571
- this.initialized = new import_async18.Trigger();
3431
+ this.initialized = new import_async17.Trigger();
3572
3432
  this.dataServiceSubscriptions = new import_echo_pipeline4.DataServiceSubscriptions();
3573
- this._instanceId = import_keys11.PublicKey.random().toHex();
3433
+ this._handlerFactories = /* @__PURE__ */ new Map();
3434
+ this._instanceId = import_keys10.PublicKey.random().toHex();
3574
3435
  this.metadataStore = new import_echo_pipeline4.MetadataStore(storage.createDirectory("metadata"));
3575
3436
  this.snapshotStore = new import_echo_pipeline4.SnapshotStore(storage.createDirectory("snapshots"));
3576
3437
  this.keyring = new import_keyring.Keyring(storage.createDirectory("keyring"));
@@ -3588,28 +3449,24 @@ var ServiceContext = class {
3588
3449
  networkManager: this.networkManager
3589
3450
  });
3590
3451
  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
- });
3452
+ this.invitations = new InvitationsHandler(this.networkManager);
3453
+ this._handlerFactories.set(import_client7.Invitation.Kind.DEVICE, () => new DeviceInvitationProtocol(this.keyring, () => {
3454
+ var _a;
3455
+ return (_a = this.identityManager.identity) != null ? _a : (0, import_debug6.failUndefined)();
3456
+ }, this._acceptIdentity.bind(this)));
3600
3457
  }
3601
3458
  async open() {
3602
- import_log15.log.trace("dxos.sdk.client-services", import_protocols6.trace.begin({
3459
+ import_log15.log.trace("dxos.sdk.client-services", import_protocols5.trace.begin({
3603
3460
  id: this._instanceId
3604
3461
  }), {
3605
3462
  file: "service-context.ts",
3606
- line: 98,
3463
+ line: 111,
3607
3464
  scope: this,
3608
3465
  callSite: (f, a) => f(...a)
3609
3466
  });
3610
3467
  (0, import_log15.log)("opening...", {}, {
3611
3468
  file: "service-context.ts",
3612
- line: 100,
3469
+ line: 113,
3613
3470
  scope: this,
3614
3471
  callSite: (f, a) => f(...a)
3615
3472
  });
@@ -3621,7 +3478,7 @@ var ServiceContext = class {
3621
3478
  }
3622
3479
  (0, import_log15.log)("opened", {}, {
3623
3480
  file: "service-context.ts",
3624
- line: 107,
3481
+ line: 120,
3625
3482
  scope: this,
3626
3483
  callSite: (f, a) => f(...a)
3627
3484
  });
@@ -3630,7 +3487,7 @@ var ServiceContext = class {
3630
3487
  var _a, _b;
3631
3488
  (0, import_log15.log)("closing...", {}, {
3632
3489
  file: "service-context.ts",
3633
- line: 111,
3490
+ line: 124,
3634
3491
  scope: this,
3635
3492
  callSite: (f, a) => f(...a)
3636
3493
  });
@@ -3643,15 +3500,15 @@ var ServiceContext = class {
3643
3500
  this.dataServiceSubscriptions.clear();
3644
3501
  (0, import_log15.log)("closed", {}, {
3645
3502
  file: "service-context.ts",
3646
- line: 119,
3503
+ line: 132,
3647
3504
  scope: this,
3648
3505
  callSite: (f, a) => f(...a)
3649
3506
  });
3650
- import_log15.log.trace("dxos.sdk.client-services", import_protocols6.trace.end({
3507
+ import_log15.log.trace("dxos.sdk.client-services", import_protocols5.trace.end({
3651
3508
  id: this._instanceId
3652
3509
  }), {
3653
3510
  file: "service-context.ts",
3654
- line: 121,
3511
+ line: 134,
3655
3512
  scope: this,
3656
3513
  callSite: (f, a) => f(...a)
3657
3514
  });
@@ -3659,7 +3516,7 @@ var ServiceContext = class {
3659
3516
  async reset() {
3660
3517
  (0, import_log15.log)("resetting...", {}, {
3661
3518
  file: "service-context.ts",
3662
- line: 125,
3519
+ line: 138,
3663
3520
  scope: this,
3664
3521
  callSite: (f, a) => f(...a)
3665
3522
  });
@@ -3667,7 +3524,7 @@ var ServiceContext = class {
3667
3524
  await this.storage.reset();
3668
3525
  (0, import_log15.log)("reset", {}, {
3669
3526
  file: "service-context.ts",
3670
- line: 128,
3527
+ line: 141,
3671
3528
  scope: this,
3672
3529
  callSite: (f, a) => f(...a)
3673
3530
  });
@@ -3677,6 +3534,11 @@ var ServiceContext = class {
3677
3534
  await this._initialize();
3678
3535
  return identity;
3679
3536
  }
3537
+ getInvitationHandler(invitation) {
3538
+ const factory = this._handlerFactories.get(invitation.kind);
3539
+ (0, import_node_assert12.default)(factory, `Unknown invitation kind: ${invitation.kind}`);
3540
+ return factory(invitation);
3541
+ }
3680
3542
  async _acceptIdentity(params) {
3681
3543
  const identity = await this.identityManager.acceptIdentity(params);
3682
3544
  await this._initialize();
@@ -3687,7 +3549,7 @@ var ServiceContext = class {
3687
3549
  var _a;
3688
3550
  (0, import_log15.log)("initializing spaces...", {}, {
3689
3551
  file: "service-context.ts",
3690
- line: 147,
3552
+ line: 166,
3691
3553
  scope: this,
3692
3554
  callSite: (f, a) => f(...a)
3693
3555
  });
@@ -3707,7 +3569,10 @@ var ServiceContext = class {
3707
3569
  };
3708
3570
  this.dataSpaceManager = new DataSpaceManager(this.spaceManager, this.metadataStore, this.dataServiceSubscriptions, this.keyring, signingContext, this.modelFactory, this.feedStore, this.snapshotStore);
3709
3571
  await this.dataSpaceManager.open();
3710
- this.spaceInvitations = new SpaceInvitationsHandler(this.networkManager, this.dataSpaceManager, signingContext, this.keyring);
3572
+ this._handlerFactories.set(import_client7.Invitation.Kind.SPACE, (invitation) => {
3573
+ (0, import_node_assert12.default)(this.dataSpaceManager, "dataSpaceManager not initialized yet");
3574
+ return new SpaceInvitationProtocol(this.dataSpaceManager, signingContext, this.keyring, invitation.spaceKey);
3575
+ });
3711
3576
  this.initialized.wake();
3712
3577
  this._deviceSpaceSync = identity.space.spaceState.registerProcessor({
3713
3578
  process: async (credential) => {
@@ -3723,7 +3588,7 @@ var ServiceContext = class {
3723
3588
  details: assertion
3724
3589
  }, {
3725
3590
  file: "service-context.ts",
3726
- line: 190,
3591
+ line: 207,
3727
3592
  scope: this,
3728
3593
  callSite: (f, a) => f(...a)
3729
3594
  });
@@ -3734,7 +3599,7 @@ var ServiceContext = class {
3734
3599
  details: assertion
3735
3600
  }, {
3736
3601
  file: "service-context.ts",
3737
- line: 194,
3602
+ line: 211,
3738
3603
  scope: this,
3739
3604
  callSite: (f, a) => f(...a)
3740
3605
  });
@@ -3745,7 +3610,7 @@ var ServiceContext = class {
3745
3610
  details: assertion
3746
3611
  }, {
3747
3612
  file: "service-context.ts",
3748
- line: 199,
3613
+ line: 216,
3749
3614
  scope: this,
3750
3615
  callSite: (f, a) => f(...a)
3751
3616
  });
@@ -3756,7 +3621,7 @@ var ServiceContext = class {
3756
3621
  } catch (err) {
3757
3622
  import_log15.log.catch(err, {}, {
3758
3623
  file: "service-context.ts",
3759
- line: 205,
3624
+ line: 222,
3760
3625
  scope: this,
3761
3626
  callSite: (f, a) => f(...a)
3762
3627
  });
@@ -3802,7 +3667,7 @@ var ClientServicesHost = class {
3802
3667
  // TODO(wittjosiah): Turn this on by default.
3803
3668
  lockKey
3804
3669
  } = {}) {
3805
- this._statusUpdate = new import_async19.Event();
3670
+ this._statusUpdate = new import_async18.Event();
3806
3671
  this._opening = false;
3807
3672
  this._open = false;
3808
3673
  this._instanceId = import_client8.PublicKey.random().toHex();
@@ -3824,17 +3689,17 @@ var ClientServicesHost = class {
3824
3689
  this._systemService = new SystemServiceImpl({
3825
3690
  config: this._config,
3826
3691
  statusUpdate: this._statusUpdate,
3827
- getCurrentStatus: () => this.isOpen ? import_services8.SystemStatus.ACTIVE : import_services8.SystemStatus.INACTIVE,
3692
+ getCurrentStatus: () => this.isOpen ? import_services9.SystemStatus.ACTIVE : import_services9.SystemStatus.INACTIVE,
3828
3693
  onUpdateStatus: async (status) => {
3829
3694
  var _a, _b;
3830
- if (!this.isOpen && status === import_services8.SystemStatus.ACTIVE) {
3695
+ if (!this.isOpen && status === import_services9.SystemStatus.ACTIVE) {
3831
3696
  await ((_a = this._resourceLock) == null ? void 0 : _a.acquire());
3832
- } else if (this.isOpen && status === import_services8.SystemStatus.INACTIVE) {
3697
+ } else if (this.isOpen && status === import_services9.SystemStatus.INACTIVE) {
3833
3698
  await ((_b = this._resourceLock) == null ? void 0 : _b.release());
3834
3699
  }
3835
3700
  },
3836
3701
  onReset: async () => {
3837
- (0, import_node_assert12.default)(this._serviceContext, "service host is closed");
3702
+ (0, import_node_assert13.default)(this._serviceContext, "service host is closed");
3838
3703
  await this._serviceContext.reset();
3839
3704
  }
3840
3705
  });
@@ -3860,16 +3725,16 @@ var ClientServicesHost = class {
3860
3725
  * Can only be called once.
3861
3726
  */
3862
3727
  initialize({ config, networkManager }) {
3863
- (0, import_node_assert12.default)(!this._open, "service host is open");
3728
+ (0, import_node_assert13.default)(!this._open, "service host is open");
3864
3729
  if (config) {
3865
- (0, import_node_assert12.default)(!this._config, "config already set");
3730
+ (0, import_node_assert13.default)(!this._config, "config already set");
3866
3731
  this._config = config;
3867
3732
  if (!this._storage) {
3868
3733
  this._storage = createStorageObjects(config.get("runtime.client.storage", {})).storage;
3869
3734
  }
3870
3735
  }
3871
3736
  if (networkManager) {
3872
- (0, import_node_assert12.default)(!this._networkManager, "network manager already set");
3737
+ (0, import_node_assert13.default)(!this._networkManager, "network manager already set");
3873
3738
  this._networkManager = networkManager;
3874
3739
  }
3875
3740
  }
@@ -3878,23 +3743,23 @@ var ClientServicesHost = class {
3878
3743
  if (this._open) {
3879
3744
  return;
3880
3745
  }
3881
- import_log16.log.trace("dxos.sdk.client-services-host", import_protocols7.trace.begin({
3746
+ import_log16.log.trace("dxos.sdk.client-services-host", import_protocols6.trace.begin({
3882
3747
  id: this._instanceId
3883
3748
  }), {
3884
3749
  file: "service-host.ts",
3885
- line: 168,
3750
+ line: 167,
3886
3751
  scope: this,
3887
3752
  callSite: (f, a) => f(...a)
3888
3753
  });
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");
3754
+ (0, import_node_assert13.default)(this._config, "config not set");
3755
+ (0, import_node_assert13.default)(this._storage, "storage not set");
3756
+ (0, import_node_assert13.default)(this._networkManager, "network manager not set");
3892
3757
  this._opening = true;
3893
3758
  (0, import_log16.log)("opening...", {
3894
3759
  lockKey: (_a = this._resourceLock) == null ? void 0 : _a.lockKey
3895
3760
  }, {
3896
3761
  file: "service-host.ts",
3897
- line: 175,
3762
+ line: 174,
3898
3763
  scope: this,
3899
3764
  callSite: (f, a) => f(...a)
3900
3765
  });
@@ -3903,15 +3768,8 @@ var ClientServicesHost = class {
3903
3768
  this._serviceRegistry.setServices({
3904
3769
  SystemService: this._systemService,
3905
3770
  IdentityService: new IdentityServiceImpl(this._serviceContext),
3771
+ InvitationsService: new InvitationsServiceImpl(this._serviceContext.invitations, (invitation) => this._serviceContext.getInvitationHandler(invitation)),
3906
3772
  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
3773
  SpacesService: new SpacesServiceImpl(this._serviceContext.identityManager, this._serviceContext.spaceManager, this._serviceContext.dataServiceSubscriptions, async () => {
3916
3774
  await this._serviceContext.initialized.wait();
3917
3775
  return this._serviceContext.dataSpaceManager;
@@ -3935,7 +3793,7 @@ var ClientServicesHost = class {
3935
3793
  deviceKey
3936
3794
  }, {
3937
3795
  file: "service-host.ts",
3938
- line: 229,
3796
+ line: 221,
3939
3797
  scope: this,
3940
3798
  callSite: (f, a) => f(...a)
3941
3799
  });
@@ -3950,7 +3808,7 @@ var ClientServicesHost = class {
3950
3808
  deviceKey
3951
3809
  }, {
3952
3810
  file: "service-host.ts",
3953
- line: 238,
3811
+ line: 230,
3954
3812
  scope: this,
3955
3813
  callSite: (f, a) => f(...a)
3956
3814
  });
@@ -3964,15 +3822,15 @@ var ClientServicesHost = class {
3964
3822
  deviceKey
3965
3823
  }, {
3966
3824
  file: "service-host.ts",
3967
- line: 243,
3825
+ line: 235,
3968
3826
  scope: this,
3969
3827
  callSite: (f, a) => f(...a)
3970
3828
  });
3971
- import_log16.log.trace("dxos.sdk.client-services-host", import_protocols7.trace.end({
3829
+ import_log16.log.trace("dxos.sdk.client-services-host", import_protocols6.trace.end({
3972
3830
  id: this._instanceId
3973
3831
  }), {
3974
3832
  file: "service-host.ts",
3975
- line: 245,
3833
+ line: 237,
3976
3834
  scope: this,
3977
3835
  callSite: (f, a) => f(...a)
3978
3836
  });
@@ -4005,13 +3863,13 @@ var LocalClientServices = class {
4005
3863
  var import_config2 = require("@dxos/config");
4006
3864
  var import_log17 = require("@dxos/log");
4007
3865
  var import_messaging3 = require("@dxos/messaging");
4008
- var import_network_manager6 = require("@dxos/network-manager");
3866
+ var import_network_manager5 = require("@dxos/network-manager");
4009
3867
 
4010
3868
  // packages/sdk/client-services/src/packlets/testing/host-test-builder.ts
4011
3869
  var createServiceHost = (config, signalManagerContext) => {
4012
- const networkManager = new import_network_manager7.NetworkManager({
3870
+ const networkManager = new import_network_manager6.NetworkManager({
4013
3871
  signalManager: new import_messaging4.MemorySignalManager(signalManagerContext),
4014
- transportFactory: import_network_manager7.MemoryTransportFactory
3872
+ transportFactory: import_network_manager6.MemoryTransportFactory
4015
3873
  });
4016
3874
  return new ClientServicesHost({
4017
3875
  config,
@@ -4021,9 +3879,9 @@ var createServiceHost = (config, signalManagerContext) => {
4021
3879
  var createServiceContext = ({ signalContext = new import_messaging4.MemorySignalManagerContext(), storage = (0, import_random_access_storage2.createStorage)({
4022
3880
  type: import_random_access_storage2.StorageType.RAM
4023
3881
  }) } = {}) => {
4024
- const networkManager = new import_network_manager7.NetworkManager({
3882
+ const networkManager = new import_network_manager6.NetworkManager({
4025
3883
  signalManager: new import_messaging4.MemorySignalManager(signalContext),
4026
- transportFactory: import_network_manager7.MemoryTransportFactory
3884
+ transportFactory: import_network_manager6.MemoryTransportFactory
4027
3885
  });
4028
3886
  const modelFactory = (0, import_client9.createDefaultModelFactory)();
4029
3887
  return new ServiceContext(storage, networkManager, modelFactory);
@@ -4091,9 +3949,9 @@ var TestPeer = class {
4091
3949
  }
4092
3950
  get networkManager() {
4093
3951
  var _a, _b;
4094
- return (_b = (_a = this._props).networkManager) != null ? _b : _a.networkManager = new import_network_manager7.NetworkManager({
3952
+ return (_b = (_a = this._props).networkManager) != null ? _b : _a.networkManager = new import_network_manager6.NetworkManager({
4095
3953
  signalManager: new import_messaging4.MemorySignalManager(this.signalContext),
4096
- transportFactory: import_network_manager7.MemoryTransportFactory
3954
+ transportFactory: import_network_manager6.MemoryTransportFactory
4097
3955
  });
4098
3956
  }
4099
3957
  get spaceManager() {
@@ -4120,60 +3978,193 @@ var createSigningContext = async (keyring) => {
4120
3978
  };
4121
3979
 
4122
3980
  // 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
3981
+ var import_node_assert14 = __toESM(require("node:assert"));
3982
+ var import_async19 = require("@dxos/async");
3983
+ var import_client10 = require("@dxos/client");
3984
+ var import_services11 = require("@dxos/protocols/proto/dxos/client/services");
3985
+ var sanitizeInvitation = (invitation) => {
3986
+ return {
3987
+ invitationId: invitation.invitationId,
3988
+ type: invitation.type,
3989
+ kind: invitation.kind,
3990
+ authMethod: invitation.authMethod,
3991
+ swarmKey: invitation.swarmKey,
3992
+ state: invitation.state,
3993
+ timeout: invitation.timeout
3994
+ };
3995
+ };
3996
+ var performInvitation = ({ host, guest, options, hooks }) => {
3997
+ const hostComplete = new import_async19.Trigger();
3998
+ const guestComplete = new import_async19.Trigger();
3999
+ const authCode = new import_async19.Trigger();
4000
+ const hostObservable = createInvitation(host, options);
4001
+ hostObservable.subscribe(async (hostInvitation) => {
4002
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
4003
+ switch (hostInvitation.state) {
4004
+ case import_services11.Invitation.State.CONNECTING: {
4005
+ if ((_b = (_a = hooks == null ? void 0 : hooks.host) == null ? void 0 : _a.onConnecting) == null ? void 0 : _b.call(_a, hostObservable)) {
4006
+ break;
4007
+ }
4008
+ const guestObservable = acceptInvitation(guest, hostInvitation);
4009
+ guestObservable.subscribe(async (guestInvitation) => {
4010
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2;
4011
+ switch (guestInvitation.state) {
4012
+ case import_services11.Invitation.State.CONNECTING: {
4013
+ if ((_b2 = (_a2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _a2.onConnecting) == null ? void 0 : _b2.call(_a2, guestObservable)) {
4014
+ break;
4015
+ }
4016
+ (0, import_node_assert14.default)(hostInvitation.swarmKey.equals(guestInvitation.swarmKey));
4017
+ break;
4018
+ }
4019
+ case import_services11.Invitation.State.CONNECTED: {
4020
+ (_d2 = (_c2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _c2.onConnected) == null ? void 0 : _d2.call(_c2, guestObservable);
4021
+ break;
4022
+ }
4023
+ case import_services11.Invitation.State.READY_FOR_AUTHENTICATION: {
4024
+ if ((_f2 = (_e2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _e2.onReady) == null ? void 0 : _f2.call(_e2, guestObservable)) {
4025
+ break;
4026
+ }
4027
+ await guestObservable.authenticate(await authCode.wait());
4028
+ break;
4029
+ }
4030
+ case import_services11.Invitation.State.AUTHENTICATING: {
4031
+ (_h2 = (_g2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _g2.onAuthenticating) == null ? void 0 : _h2.call(_g2, guestObservable);
4032
+ break;
4033
+ }
4034
+ case import_services11.Invitation.State.SUCCESS: {
4035
+ if ((_j2 = (_i2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _i2.onSuccess) == null ? void 0 : _j2.call(_i2, guestObservable)) {
4036
+ break;
4037
+ }
4038
+ guestComplete.wake({
4039
+ invitation: guestInvitation
4040
+ });
4041
+ break;
4042
+ }
4043
+ case import_services11.Invitation.State.CANCELLED: {
4044
+ if ((_l2 = (_k2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _k2.onCancelled) == null ? void 0 : _l2.call(_k2, guestObservable)) {
4045
+ break;
4046
+ }
4047
+ guestComplete.wake({
4048
+ invitation: guestInvitation
4049
+ });
4050
+ break;
4051
+ }
4052
+ case import_services11.Invitation.State.TIMEOUT: {
4053
+ if ((_n2 = (_m2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _m2.onTimeout) == null ? void 0 : _n2.call(_m2, guestObservable)) {
4054
+ return;
4055
+ }
4056
+ guestComplete.wake({
4057
+ invitation: guestInvitation
4058
+ });
4059
+ }
4060
+ }
4061
+ }, (error) => {
4062
+ var _a2, _b2;
4063
+ if ((_b2 = (_a2 = hooks == null ? void 0 : hooks.guest) == null ? void 0 : _a2.onError) == null ? void 0 : _b2.call(_a2, guestObservable)) {
4064
+ return;
4065
+ }
4066
+ guestComplete.wake({
4067
+ error
4068
+ });
4069
+ });
4070
+ break;
4071
+ }
4072
+ case import_services11.Invitation.State.CONNECTED: {
4073
+ (_d = (_c = hooks == null ? void 0 : hooks.host) == null ? void 0 : _c.onConnected) == null ? void 0 : _d.call(_c, hostObservable);
4074
+ break;
4075
+ }
4076
+ case import_services11.Invitation.State.READY_FOR_AUTHENTICATION: {
4077
+ if ((_f = (_e = hooks == null ? void 0 : hooks.host) == null ? void 0 : _e.onReady) == null ? void 0 : _f.call(_e, hostObservable)) {
4078
+ break;
4079
+ }
4080
+ if (hostInvitation.authCode) {
4081
+ authCode.wake(hostInvitation.authCode);
4082
+ }
4083
+ break;
4084
+ }
4085
+ case import_services11.Invitation.State.AUTHENTICATING: {
4086
+ (_h = (_g = hooks == null ? void 0 : hooks.host) == null ? void 0 : _g.onAuthenticating) == null ? void 0 : _h.call(_g, hostObservable);
4087
+ break;
4088
+ }
4089
+ case import_services11.Invitation.State.SUCCESS: {
4090
+ if ((_j = (_i = hooks == null ? void 0 : hooks.host) == null ? void 0 : _i.onSuccess) == null ? void 0 : _j.call(_i, hostObservable)) {
4091
+ break;
4092
+ }
4093
+ hostComplete.wake({
4094
+ invitation: hostInvitation
4095
+ });
4096
+ break;
4097
+ }
4098
+ case import_services11.Invitation.State.CANCELLED: {
4099
+ if ((_l = (_k = hooks == null ? void 0 : hooks.host) == null ? void 0 : _k.onCancelled) == null ? void 0 : _l.call(_k, hostObservable)) {
4100
+ break;
4101
+ }
4102
+ hostComplete.wake({
4103
+ invitation: hostInvitation
4104
+ });
4105
+ break;
4106
+ }
4107
+ case import_services11.Invitation.State.TIMEOUT: {
4108
+ if ((_n = (_m = hooks == null ? void 0 : hooks.host) == null ? void 0 : _m.onTimeout) == null ? void 0 : _n.call(_m, hostObservable)) {
4109
+ break;
4110
+ }
4111
+ hostComplete.wake({
4112
+ invitation: hostInvitation
4113
+ });
4114
+ break;
4115
+ }
4116
+ }
4117
+ }, (error) => {
4118
+ var _a, _b;
4119
+ if ((_b = (_a = hooks == null ? void 0 : hooks.host) == null ? void 0 : _a.onError) == null ? void 0 : _b.call(_a, hostObservable)) {
4120
+ return;
4121
+ }
4122
+ hostComplete.wake({
4123
+ error
4124
+ });
4132
4125
  });
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)
4126
+ return [
4127
+ hostComplete.wait(),
4128
+ guestComplete.wait()
4129
+ ];
4130
+ };
4131
+ var createInvitation = (host, options) => {
4132
+ options != null ? options : options = {
4133
+ authMethod: import_services11.Invitation.AuthMethod.NONE,
4134
+ ...options != null ? options : {}
4135
+ };
4136
+ if (host instanceof import_client10.InvitationsProxy || host instanceof import_client10.HaloProxy || host instanceof import_client10.SpaceProxy) {
4137
+ return host.createInvitation(options);
4138
+ }
4139
+ const hostHandler = host.getInvitationHandler({
4140
+ kind: import_services11.Invitation.Kind.SPACE,
4141
+ ...options
4142
+ });
4143
+ return host.invitations.createInvitation(hostHandler, options);
4144
+ };
4145
+ var acceptInvitation = (guest, invitation) => {
4146
+ invitation = sanitizeInvitation(invitation);
4147
+ if (guest instanceof import_client10.InvitationsProxy || guest instanceof import_client10.HaloProxy || guest instanceof import_client10.EchoProxy || guest instanceof import_client10.Client) {
4148
+ return guest.acceptInvitation(invitation);
4149
+ }
4150
+ const guestHandler = guest.getInvitationHandler({
4151
+ kind: invitation.kind
4160
4152
  });
4161
- await done1.wait();
4162
- await done2.wait();
4153
+ return guest.invitations.acceptInvitation(guestHandler, invitation);
4163
4154
  };
4164
4155
 
4165
4156
  // 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");
4157
+ var import_node_assert15 = __toESM(require("node:assert"));
4158
+ var import_async20 = require("@dxos/async");
4159
+ var import_client11 = require("@dxos/client");
4169
4160
  var import_config3 = require("@dxos/config");
4170
- var import_debug9 = require("@dxos/debug");
4161
+ var import_debug7 = require("@dxos/debug");
4171
4162
  var import_document_model = require("@dxos/document-model");
4172
4163
  var import_echo_db = require("@dxos/echo-db");
4173
- var import_keys12 = require("@dxos/keys");
4164
+ var import_keys11 = require("@dxos/keys");
4174
4165
  var import_log18 = require("@dxos/log");
4175
4166
  var import_messaging5 = require("@dxos/messaging");
4176
- var import_network_manager8 = require("@dxos/network-manager");
4167
+ var import_network_manager7 = require("@dxos/network-manager");
4177
4168
  var import_rpc5 = require("@dxos/rpc");
4178
4169
  var testConfigWithLocalSignal = new import_config3.Config({
4179
4170
  version: 1,
@@ -4188,7 +4179,7 @@ var testConfigWithLocalSignal = new import_config3.Config({
4188
4179
  });
4189
4180
  var TestBuilder = class {
4190
4181
  // prettier-ignore
4191
- constructor(config, _modelFactory = (0, import_client10.createDefaultModelFactory)(), _signalManagerContext = new import_messaging5.MemorySignalManagerContext()) {
4182
+ constructor(config, _modelFactory = (0, import_client11.createDefaultModelFactory)(), _signalManagerContext = new import_messaging5.MemorySignalManagerContext()) {
4192
4183
  this._modelFactory = _modelFactory;
4193
4184
  this._signalManagerContext = _signalManagerContext;
4194
4185
  this._config = config != null ? config : new import_config3.Config();
@@ -4202,20 +4193,20 @@ var TestBuilder = class {
4202
4193
  get networkManager() {
4203
4194
  const signalServer = this._config.get("runtime.services.signal.server");
4204
4195
  if (signalServer) {
4205
- return new import_network_manager8.NetworkManager({
4196
+ return new import_network_manager7.NetworkManager({
4206
4197
  log: true,
4207
4198
  signalManager: new import_messaging5.WebsocketSignalManager([
4208
4199
  signalServer
4209
4200
  ]),
4210
- transportFactory: (0, import_network_manager8.createWebRTCTransportFactory)({
4201
+ transportFactory: (0, import_network_manager7.createWebRTCTransportFactory)({
4211
4202
  iceServers: this._config.get("runtime.services.ice")
4212
4203
  })
4213
4204
  });
4214
4205
  }
4215
- return new import_network_manager8.NetworkManager({
4206
+ return new import_network_manager7.NetworkManager({
4216
4207
  log: true,
4217
4208
  signalManager: new import_messaging5.MemorySignalManager(this._signalManagerContext),
4218
- transportFactory: import_network_manager8.MemoryTransportFactory
4209
+ transportFactory: import_network_manager7.MemoryTransportFactory
4219
4210
  });
4220
4211
  }
4221
4212
  /**
@@ -4250,8 +4241,8 @@ var TestBuilder = class {
4250
4241
  handlers: host.services,
4251
4242
  port: hostPort
4252
4243
  });
4253
- const client = new import_client10.Client({
4254
- services: new import_client10.ClientServicesProxy(proxyPort)
4244
+ const client = new import_client11.Client({
4245
+ services: new import_client11.ClientServicesProxy(proxyPort)
4255
4246
  });
4256
4247
  return [
4257
4248
  client,
@@ -4260,11 +4251,11 @@ var TestBuilder = class {
4260
4251
  }
4261
4252
  };
4262
4253
  var testSpace = async (create, check = create) => {
4263
- const objectId = import_keys12.PublicKey.random().toHex();
4254
+ const objectId = import_keys11.PublicKey.random().toHex();
4264
4255
  const result = create.mutate((0, import_echo_db.genesisMutation)(objectId, import_document_model.DocumentModel.meta.type));
4265
4256
  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);
4257
+ (0, import_node_assert15.default)(create._itemManager.entities.has(result.objectsUpdated[0].id));
4258
+ await (0, import_async20.asyncTimeout)(check.itemUpdate.waitForCondition(() => check._itemManager.entities.has(objectId)), 1e3);
4268
4259
  return result;
4269
4260
  };
4270
4261
  var syncItems = async (db1, db2) => {
@@ -4273,12 +4264,12 @@ var syncItems = async (db1, db2) => {
4273
4264
  };
4274
4265
  var joinCommonSpace = async ([initialPeer, ...peers], spaceKey) => {
4275
4266
  const rootSpace = spaceKey ? initialPeer.getSpace(spaceKey) : await initialPeer.createSpace();
4276
- (0, import_node_assert14.default)(rootSpace, "Space not found.");
4267
+ (0, import_node_assert15.default)(rootSpace, "Space not found.");
4277
4268
  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
4269
+ const hostDone = new import_async20.Trigger();
4270
+ const guestDone = new import_async20.Trigger();
4271
+ const hostObservable = rootSpace.createInvitation({
4272
+ authMethod: import_client11.Invitation.AuthMethod.NONE
4282
4273
  });
4283
4274
  (0, import_log18.log)("invitation created", {}, {
4284
4275
  file: "test-builder.ts",
@@ -4286,39 +4277,43 @@ var joinCommonSpace = async ([initialPeer, ...peers], spaceKey) => {
4286
4277
  scope: void 0,
4287
4278
  callSite: (f, a) => f(...a)
4288
4279
  });
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
- });
4280
+ hostObservable.subscribe((hostInvitation) => {
4281
+ switch (hostInvitation.state) {
4282
+ case import_client11.Invitation.State.CONNECTING: {
4283
+ const guestObservable = peer.acceptInvitation(hostInvitation);
4284
+ (0, import_log18.log)("invitation accepted", {}, {
4285
+ file: "test-builder.ts",
4286
+ line: 160,
4287
+ scope: void 0,
4288
+ callSite: (f, a) => f(...a)
4289
+ });
4290
+ guestObservable.subscribe((guestInvitation) => {
4291
+ switch (guestInvitation.state) {
4292
+ case import_client11.Invitation.State.SUCCESS: {
4293
+ guestDone.wake(guestInvitation);
4294
+ (0, import_log18.log)("invitation guestDone", {}, {
4295
+ file: "test-builder.ts",
4296
+ line: 167,
4297
+ scope: void 0,
4298
+ callSite: (f, a) => f(...a)
4299
+ });
4300
+ break;
4301
+ }
4302
+ }
4303
+ }, (err) => (0, import_debug7.raise)(err));
4304
+ break;
4305
+ }
4306
+ case import_client11.Invitation.State.SUCCESS: {
4307
+ hostDone.wake(hostInvitation);
4308
+ (0, import_log18.log)("invitation hostDone", {}, {
4309
+ file: "test-builder.ts",
4310
+ line: 179,
4311
+ scope: void 0,
4312
+ callSite: (f, a) => f(...a)
4313
+ });
4314
+ }
4315
+ }
4316
+ }, (err) => (0, import_debug7.raise)(err));
4322
4317
  await Promise.all([
4323
4318
  hostDone.wait(),
4324
4319
  guestDone.wait()
@@ -4339,6 +4334,7 @@ var joinCommonSpace = async ([initialPeer, ...peers], spaceKey) => {
4339
4334
  createSigningContext,
4340
4335
  joinCommonSpace,
4341
4336
  performInvitation,
4337
+ sanitizeInvitation,
4342
4338
  syncItems,
4343
4339
  syncItemsLocal,
4344
4340
  testConfigWithLocalSignal,