@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
@@ -30,10 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // packages/sdk/client-services/src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
- AbstractInvitationsService: () => AbstractInvitationsService,
34
33
  ClientServicesHost: () => ClientServicesHost,
35
- DeviceInvitationsHandler: () => DeviceInvitationsHandler,
36
- DeviceInvitationsServiceImpl: () => DeviceInvitationsServiceImpl,
34
+ DeviceInvitationProtocol: () => DeviceInvitationProtocol,
37
35
  DevtoolsHostEvents: () => DevtoolsHostEvents,
38
36
  DevtoolsServiceImpl: () => DevtoolsServiceImpl,
39
37
  IFrameHostRuntime: () => IFrameHostRuntime,
@@ -41,13 +39,14 @@ __export(src_exports, {
41
39
  Identity: () => Identity,
42
40
  IdentityManager: () => IdentityManager,
43
41
  IdentityServiceImpl: () => IdentityServiceImpl,
42
+ InvitationsHandler: () => InvitationsHandler,
43
+ InvitationsServiceImpl: () => InvitationsServiceImpl,
44
44
  LocalClientServices: () => LocalClientServices,
45
45
  MemoryShellRuntime: () => MemoryShellRuntime,
46
46
  ServiceContext: () => ServiceContext,
47
47
  ServiceRegistry: () => ServiceRegistry,
48
48
  ShellRuntimeImpl: () => ShellRuntimeImpl,
49
- SpaceInvitationsHandler: () => SpaceInvitationsHandler,
50
- SpaceInvitationsServiceImpl: () => SpaceInvitationsServiceImpl,
49
+ SpaceInvitationProtocol: () => SpaceInvitationProtocol,
51
50
  TrustedKeySetAuthVerifier: () => TrustedKeySetAuthVerifier,
52
51
  VaultResourceLock: () => VaultResourceLock,
53
52
  WorkerRuntime: () => WorkerRuntime,
@@ -927,696 +926,176 @@ var IdentityServiceImpl = class {
927
926
  }
928
927
  };
929
928
 
930
- // packages/sdk/client-services/src/packlets/invitations/device-invitations-handler.ts
929
+ // packages/sdk/client-services/src/packlets/invitations/device-invitation-protocol.ts
931
930
  var import_node_assert4 = __toESM(require("node:assert"));
932
- var import_async6 = require("@dxos/async");
933
- var import_client = require("@dxos/client");
934
- var import_context3 = require("@dxos/context");
935
- var import_credentials7 = require("@dxos/credentials");
936
- var import_keys5 = require("@dxos/keys");
937
- var import_log4 = require("@dxos/log");
938
- var import_network_manager = require("@dxos/network-manager");
939
- var import_protocols3 = require("@dxos/protocols");
940
931
  var import_services = require("@dxos/protocols/proto/dxos/client/services");
941
- var import_invitations = require("@dxos/protocols/proto/dxos/halo/invitations");
942
- var import_teleport = require("@dxos/teleport");
943
- var DeviceInvitationsHandler = class extends import_client.AbstractInvitationsHandler {
944
- // prettier-ignore
945
- constructor(_params) {
946
- super(_params.networkManager);
947
- this._params = _params;
948
- }
949
- /**
950
- * Creates an invitation and listens for a join request from the invited (guest) peer.
951
- */
952
- createInvitation(context, options) {
953
- const { type, timeout = import_client.INVITATION_TIMEOUT, swarmKey } = options != null ? options : {};
954
- (0, import_node_assert4.default)(type !== import_services.Invitation.Type.OFFLINE);
955
- const identity = this._params.getIdentity();
956
- const invitation = {
957
- type,
958
- invitationId: import_keys5.PublicKey.random().toHex(),
959
- swarmKey: swarmKey != null ? swarmKey : import_keys5.PublicKey.random(),
960
- authenticationCode: (0, import_credentials7.generatePasscode)(import_client.AUTHENTICATION_CODE_LENGTH)
961
- };
962
- const ctx = new import_context3.Context({
963
- onError: (err) => {
964
- void ctx.dispose();
965
- observable.callback.onError(err);
966
- }
967
- });
968
- const observable = new import_client.InvitationObservableProvider(async () => {
969
- await ctx.dispose();
970
- });
971
- let authenticationCode;
972
- const complete = new import_async6.Trigger();
973
- const createExtension = () => new HostHaloInvitationExtension({
974
- requestAdmission: async () => {
975
- var _a, _b;
976
- (0, import_log4.log)("responding with admission offer", {
977
- host: identity.deviceKey
978
- }, {
979
- file: "device-invitations-handler.ts",
980
- line: 92,
981
- scope: this,
982
- callSite: (f, a) => f(...a)
983
- });
984
- (_b = (_a = observable.callback).onAuthenticating) == null ? void 0 : _b.call(_a, invitation);
985
- return {
986
- identityKey: identity.identityKey,
987
- haloSpaceKey: identity.haloSpaceKey,
988
- genesisFeedKey: identity.haloGenesisFeedKey,
989
- controlTimeframe: identity.controlPipeline.state.timeframe
990
- };
991
- },
992
- authenticate: async ({ authenticationCode: code }) => {
993
- (0, import_log4.log)("received authentication request", {
994
- authenticationCode: code
995
- }, {
996
- file: "device-invitations-handler.ts",
997
- line: 107,
998
- scope: this,
999
- callSite: (f, a) => f(...a)
1000
- });
1001
- authenticationCode = code;
1002
- return {
1003
- status: import_invitations.AuthenticationResponse.Status.OK
1004
- };
1005
- },
1006
- // TODO(burdon): Not used: controlFeedKey, dataFeedKey.
1007
- presentAdmissionCredentials: async (credentials) => {
1008
- try {
1009
- if (invitation.type !== import_services.Invitation.Type.INTERACTIVE_TESTING) {
1010
- if (invitation.authenticationCode === void 0 || invitation.authenticationCode !== authenticationCode) {
1011
- throw new Error(`invalid authentication code: ${authenticationCode}`);
1012
- }
1013
- }
1014
- (0, import_log4.log)("writing guest credentials", {
1015
- host: identity.deviceKey,
1016
- guest: credentials.deviceKey
1017
- }, {
1018
- file: "device-invitations-handler.ts",
1019
- line: 122,
1020
- scope: this,
1021
- callSite: (f, a) => f(...a)
1022
- });
1023
- await identity.admitDevice(credentials);
1024
- complete.wake(credentials.deviceKey);
1025
- } catch (err) {
1026
- observable.callback.onError(err);
1027
- throw err;
1028
- }
1029
- },
1030
- onOpen: () => {
1031
- (0, import_async6.scheduleTask)(ctx, async () => {
1032
- var _a, _b;
1033
- try {
1034
- (0, import_log4.log)("connected", {
1035
- host: identity.deviceKey
1036
- }, {
1037
- file: "device-invitations-handler.ts",
1038
- line: 138,
1039
- scope: this,
1040
- callSite: (f, a) => f(...a)
1041
- });
1042
- (_b = (_a = observable.callback).onConnected) == null ? void 0 : _b.call(_a, invitation);
1043
- const deviceKey = await complete.wait({
1044
- timeout
1045
- });
1046
- (0, import_log4.log)("admitted guest", {
1047
- host: identity.deviceKey,
1048
- guest: deviceKey
1049
- }, {
1050
- file: "device-invitations-handler.ts",
1051
- line: 141,
1052
- scope: this,
1053
- callSite: (f, a) => f(...a)
1054
- });
1055
- observable.callback.onSuccess(invitation);
1056
- } catch (err) {
1057
- if (!observable.cancelled) {
1058
- import_log4.log.error("failed", err, {
1059
- file: "device-invitations-handler.ts",
1060
- line: 145,
1061
- scope: this,
1062
- callSite: (f, a) => f(...a)
1063
- });
1064
- observable.callback.onError(err);
1065
- }
1066
- } finally {
1067
- await (0, import_async6.sleep)(import_client.ON_CLOSE_DELAY);
1068
- await ctx.dispose();
1069
- }
1070
- });
1071
- }
1072
- });
1073
- (0, import_async6.scheduleTask)(ctx, async () => {
1074
- var _a, _b;
1075
- const topic = invitation.swarmKey;
1076
- const swarmConnection = await this._networkManager.joinSwarm({
1077
- topic,
1078
- peerId: topic,
1079
- protocolProvider: (0, import_network_manager.createTeleportProtocolFactory)(async (teleport) => {
1080
- teleport.addExtension("dxos.halo.invitations", createExtension());
1081
- }),
1082
- topology: new import_network_manager.StarTopology(topic)
1083
- });
1084
- ctx.onDispose(() => swarmConnection.close());
1085
- (_b = (_a = observable.callback).onConnecting) == null ? void 0 : _b.call(_a, invitation);
1086
- });
1087
- return observable;
1088
- }
1089
- /**
1090
- * Waits for the host peer (inviter) to accept our join request.
1091
- * The local guest peer (invitee) then sends the local halo invitation to the host,
1092
- * which then writes the guest's credentials to the halo.
1093
- */
1094
- acceptInvitation(invitation, options) {
1095
- const { timeout = import_client.INVITATION_TIMEOUT } = options != null ? options : {};
1096
- const ctx = new import_context3.Context({
1097
- onError: (err) => {
1098
- void ctx.dispose();
1099
- observable.callback.onError(err);
1100
- }
1101
- });
1102
- const authenticated = new import_async6.Trigger();
1103
- const observable = new import_client.AuthenticatingInvitationProvider({
1104
- onCancel: async () => {
1105
- await ctx.dispose();
1106
- },
1107
- // TODO(burdon): Consider retry.
1108
- onAuthenticate: async (code) => {
1109
- authenticated.wake(code);
1110
- }
1111
- });
1112
- let connectionCount = 0;
1113
- const complete = new import_async6.Trigger();
1114
- const createExtension = () => {
1115
- const extension = new GuestHaloInvitationExtension({
1116
- onOpen: () => {
1117
- (0, import_async6.scheduleTask)(ctx, async () => {
1118
- var _a, _b, _c, _d;
1119
- try {
1120
- if (++connectionCount > 1) {
1121
- throw new Error(`multiple connections detected: ${connectionCount}`);
1122
- }
1123
- (0, import_log4.log)("connected", {}, {
1124
- file: "device-invitations-handler.ts",
1125
- line: 216,
1126
- scope: this,
1127
- callSite: (f, a) => f(...a)
1128
- });
1129
- (_b = (_a = observable.callback).onConnected) == null ? void 0 : _b.call(_a, invitation);
1130
- (0, import_log4.log)("sending admission request", {}, {
1131
- file: "device-invitations-handler.ts",
1132
- line: 220,
1133
- scope: this,
1134
- callSite: (f, a) => f(...a)
1135
- });
1136
- const { identityKey, haloSpaceKey, genesisFeedKey, controlTimeframe } = await extension.rpc.HaloHostService.requestAdmission();
1137
- if (invitation.type === void 0 || invitation.type === import_services.Invitation.Type.INTERACTIVE) {
1138
- (0, import_log4.log)("guest waiting for authentication code...", {}, {
1139
- file: "device-invitations-handler.ts",
1140
- line: 227,
1141
- scope: this,
1142
- callSite: (f, a) => f(...a)
1143
- });
1144
- (_d = (_c = observable.callback).onAuthenticating) == null ? void 0 : _d.call(_c, invitation);
1145
- const authenticationCode = await authenticated.wait({
1146
- timeout
1147
- });
1148
- (0, import_log4.log)("sending authentication request", {}, {
1149
- file: "device-invitations-handler.ts",
1150
- line: 230,
1151
- scope: this,
1152
- callSite: (f, a) => f(...a)
1153
- });
1154
- await extension.rpc.HaloHostService.authenticate({
1155
- authenticationCode
1156
- });
1157
- }
1158
- const deviceKey = await this._params.keyring.createKey();
1159
- const controlFeedKey = await this._params.keyring.createKey();
1160
- const dataFeedKey = await this._params.keyring.createKey();
1161
- (0, import_log4.log)("presenting admission credentials", {
1162
- identityKey,
1163
- deviceKey,
1164
- controlFeedKey,
1165
- dataFeedKey
1166
- }, {
1167
- file: "device-invitations-handler.ts",
1168
- line: 239,
1169
- scope: this,
1170
- callSite: (f, a) => f(...a)
1171
- });
1172
- await extension.rpc.HaloHostService.presentAdmissionCredentials({
1173
- deviceKey,
1174
- controlFeedKey,
1175
- dataFeedKey
1176
- });
1177
- const identity = await this._params.acceptIdentity({
1178
- identityKey,
1179
- deviceKey,
1180
- haloSpaceKey,
1181
- haloGenesisFeedKey: genesisFeedKey,
1182
- controlFeedKey,
1183
- dataFeedKey,
1184
- controlTimeframe
1185
- });
1186
- (0, import_log4.log)("admitted by host", {
1187
- guest: identity.deviceKey,
1188
- identityKey
1189
- }, {
1190
- file: "device-invitations-handler.ts",
1191
- line: 259,
1192
- scope: this,
1193
- callSite: (f, a) => f(...a)
1194
- });
1195
- complete.wake(identityKey);
1196
- } catch (err) {
1197
- if (!observable.cancelled) {
1198
- import_log4.log.warn("auth failed", err, {
1199
- file: "device-invitations-handler.ts",
1200
- line: 263,
1201
- scope: this,
1202
- callSite: (f, a) => f(...a)
1203
- });
1204
- observable.callback.onError(err);
1205
- }
1206
- } finally {
1207
- await ctx.dispose();
1208
- }
1209
- });
1210
- }
1211
- });
1212
- return extension;
1213
- };
1214
- (0, import_async6.scheduleTask)(ctx, async () => {
1215
- var _a, _b;
1216
- (0, import_node_assert4.default)(invitation.swarmKey);
1217
- const topic = invitation.swarmKey;
1218
- const swarmConnection = await this._networkManager.joinSwarm({
1219
- topic,
1220
- peerId: import_keys5.PublicKey.random(),
1221
- protocolProvider: (0, import_network_manager.createTeleportProtocolFactory)(async (teleport) => {
1222
- teleport.addExtension("dxos.halo.invitations", createExtension());
1223
- }),
1224
- topology: new import_network_manager.StarTopology(topic)
1225
- });
1226
- ctx.onDispose(() => swarmConnection.close());
1227
- (_b = (_a = observable.callback).onConnecting) == null ? void 0 : _b.call(_a, invitation);
1228
- invitation.identityKey = await complete.wait();
1229
- observable.callback.onSuccess(invitation);
1230
- await ctx.dispose();
1231
- });
1232
- return observable;
1233
- }
1234
- };
1235
- var HostHaloInvitationExtension = class extends import_teleport.RpcExtension {
1236
- constructor(_callbacks) {
1237
- super({
1238
- exposed: {
1239
- HaloHostService: import_protocols3.schema.getService("dxos.halo.invitations.HaloHostService")
1240
- }
1241
- });
1242
- this._callbacks = _callbacks;
1243
- }
1244
- async getHandlers() {
1245
- return {
1246
- // TODO(dmaretskyi): For now this is just forwarding the data to callbacks since we don't have session-specific logic.
1247
- // Perhaps in the future we will have more complex logic here.
1248
- HaloHostService: {
1249
- requestAdmission: async () => {
1250
- return this._callbacks.requestAdmission();
1251
- },
1252
- authenticate: async (credentials) => {
1253
- return this._callbacks.authenticate(credentials);
1254
- },
1255
- // TODO(burdon): Not used: controlFeedKey, dataFeedKey.
1256
- presentAdmissionCredentials: async (credentials) => {
1257
- return this._callbacks.presentAdmissionCredentials(credentials);
1258
- }
1259
- }
1260
- };
1261
- }
1262
- async onOpen(context) {
1263
- await super.onOpen(context);
1264
- this._callbacks.onOpen();
1265
- }
1266
- };
1267
- var GuestHaloInvitationExtension = class extends import_teleport.RpcExtension {
1268
- constructor(_callbacks) {
1269
- super({
1270
- requested: {
1271
- HaloHostService: import_protocols3.schema.getService("dxos.halo.invitations.HaloHostService")
1272
- }
1273
- });
1274
- this._callbacks = _callbacks;
932
+ var DeviceInvitationProtocol = class {
933
+ constructor(_keyring, _getIdentity, _acceptIdentity) {
934
+ this._keyring = _keyring;
935
+ this._getIdentity = _getIdentity;
936
+ this._acceptIdentity = _acceptIdentity;
1275
937
  }
1276
- async getHandlers() {
938
+ toJSON() {
1277
939
  return {};
1278
940
  }
1279
- async onOpen(context) {
1280
- await super.onOpen(context);
1281
- this._callbacks.onOpen();
1282
- }
1283
- };
1284
-
1285
- // packages/sdk/client-services/src/packlets/invitations/invitations-service.ts
1286
- var import_node_assert5 = __toESM(require("node:assert"));
1287
- var import_codec_protobuf7 = require("@dxos/codec-protobuf");
1288
- var import_log5 = require("@dxos/log");
1289
- var import_services2 = require("@dxos/protocols/proto/dxos/client/services");
1290
- var AbstractInvitationsService = class {
1291
- // prettier-ignore
1292
- constructor(_identityManager, _getInvitationsHandler) {
1293
- this._identityManager = _identityManager;
1294
- this._getInvitationsHandler = _getInvitationsHandler;
1295
- this._createInvitations = /* @__PURE__ */ new Map();
1296
- this._acceptInvitations = /* @__PURE__ */ new Map();
1297
- }
1298
- // TODO(burdon): Guest/host label.
1299
- getLoggingContext() {
1300
- var _a;
1301
- return {
1302
- deviceKey: (_a = this._identityManager.identity) == null ? void 0 : _a.deviceKey
1303
- };
1304
- }
1305
- createInvitation(invitation) {
1306
- return new import_codec_protobuf7.Stream(({ next, close }) => {
1307
- const invitationsHandler = this._getInvitationsHandler();
1308
- const context = this.getContext(invitation);
1309
- (0, import_log5.log)("stream opened", this.getLoggingContext(), {
1310
- file: "invitations-service.ts",
1311
- line: 48,
1312
- scope: this,
1313
- callSite: (f, a) => f(...a)
1314
- });
1315
- let invitationId;
1316
- const { type, swarmKey, authMethod } = invitation;
1317
- const observable = invitationsHandler.createInvitation(context, {
1318
- type,
1319
- swarmKey,
1320
- authMethod
1321
- });
1322
- observable.subscribe({
1323
- onConnecting: (invitation2) => {
1324
- (0, import_node_assert5.default)(invitation2.invitationId);
1325
- invitationId = invitation2.invitationId;
1326
- this._createInvitations.set(invitation2.invitationId, observable);
1327
- invitation2.state = import_services2.Invitation.State.CONNECTING;
1328
- next(invitation2);
1329
- },
1330
- onConnected: (invitation2) => {
1331
- (0, import_node_assert5.default)(invitation2.invitationId);
1332
- invitation2.state = import_services2.Invitation.State.CONNECTED;
1333
- next(invitation2);
1334
- },
1335
- onAuthenticating: (invitation2) => {
1336
- (0, import_node_assert5.default)(invitation2.invitationId);
1337
- invitation2.state = import_services2.Invitation.State.AUTHENTICATING;
1338
- next(invitation2);
1339
- },
1340
- onSuccess: (invitation2) => {
1341
- (0, import_node_assert5.default)(invitation2.invitationId);
1342
- invitation2.state = import_services2.Invitation.State.SUCCESS;
1343
- next(invitation2);
1344
- close();
1345
- },
1346
- onCancelled: () => {
1347
- (0, import_node_assert5.default)(invitationId);
1348
- invitation.invitationId = invitationId;
1349
- invitation.state = import_services2.Invitation.State.CANCELLED;
1350
- next(invitation);
1351
- close();
1352
- },
1353
- onTimeout: (err) => {
1354
- invitation.state = import_services2.Invitation.State.TIMEOUT;
1355
- close(err);
1356
- },
1357
- onError: (err) => {
1358
- invitation.state = import_services2.Invitation.State.ERROR;
1359
- close(err);
1360
- }
1361
- });
1362
- return (err) => {
1363
- const context2 = this.getLoggingContext();
1364
- if (err) {
1365
- import_log5.log.warn("stream closed", {
1366
- ...context2,
1367
- err
1368
- }, {
1369
- file: "invitations-service.ts",
1370
- line: 97,
1371
- scope: this,
1372
- callSite: (f, a) => f(...a)
1373
- });
1374
- } else {
1375
- (0, import_log5.log)("stream closed", context2, {
1376
- file: "invitations-service.ts",
1377
- line: 99,
1378
- scope: this,
1379
- callSite: (f, a) => f(...a)
1380
- });
1381
- }
1382
- this._createInvitations.delete(invitation.invitationId);
1383
- };
1384
- });
1385
- }
1386
- acceptInvitation(invitation, options) {
1387
- return new import_codec_protobuf7.Stream(({ next, close }) => {
1388
- (0, import_log5.log)("stream opened", this.getLoggingContext(), {
1389
- file: "invitations-service.ts",
1390
- line: 109,
1391
- scope: this,
1392
- callSite: (f, a) => f(...a)
1393
- });
1394
- const invitationsHandler = this._getInvitationsHandler();
1395
- let invitationId;
1396
- const observable = invitationsHandler.acceptInvitation(invitation, options);
1397
- observable.subscribe({
1398
- onConnecting: (invitation2) => {
1399
- (0, import_node_assert5.default)(invitation2.invitationId);
1400
- invitationId = invitation2.invitationId;
1401
- this._acceptInvitations.set(invitation2.invitationId, observable);
1402
- invitation2.state = import_services2.Invitation.State.CONNECTING;
1403
- next(invitation2);
1404
- },
1405
- onConnected: (invitation2) => {
1406
- (0, import_node_assert5.default)(invitation2.invitationId);
1407
- invitation2.state = import_services2.Invitation.State.CONNECTED;
1408
- next(invitation2);
1409
- },
1410
- onAuthenticating: (invitation2) => {
1411
- (0, import_node_assert5.default)(invitation2.invitationId);
1412
- invitation2.state = import_services2.Invitation.State.AUTHENTICATING;
1413
- next(invitation2);
1414
- },
1415
- onSuccess: (invitation2) => {
1416
- invitation2.state = import_services2.Invitation.State.SUCCESS;
1417
- next(invitation2);
1418
- close();
1419
- },
1420
- onCancelled: () => {
1421
- (0, import_node_assert5.default)(invitationId);
1422
- invitation.invitationId = invitationId;
1423
- invitation.state = import_services2.Invitation.State.CANCELLED;
1424
- next(invitation);
1425
- close();
1426
- },
1427
- onTimeout: (err) => {
1428
- invitation.state = import_services2.Invitation.State.TIMEOUT;
1429
- close(err);
1430
- },
1431
- onError: (err) => {
1432
- invitation.state = import_services2.Invitation.State.ERROR;
1433
- close(err);
1434
- }
1435
- });
1436
- return (err) => {
1437
- const context = this.getLoggingContext();
1438
- if (err) {
1439
- import_log5.log.warn("stream closed", {
1440
- ...context,
1441
- err
1442
- }, {
1443
- file: "invitations-service.ts",
1444
- line: 157,
1445
- scope: this,
1446
- callSite: (f, a) => f(...a)
1447
- });
1448
- } else {
1449
- (0, import_log5.log)("stream closed", context, {
1450
- file: "invitations-service.ts",
1451
- line: 159,
1452
- scope: this,
1453
- callSite: (f, a) => f(...a)
1454
- });
1455
- }
1456
- this._acceptInvitations.delete(invitation.invitationId);
1457
- };
1458
- });
941
+ getInvitationContext() {
942
+ return {
943
+ kind: import_services.Invitation.Kind.DEVICE
944
+ };
1459
945
  }
1460
- async authenticate({ invitationId, authenticationCode }) {
1461
- (0, import_log5.log)("authenticating...", {}, {
1462
- file: "invitations-service.ts",
1463
- line: 168,
1464
- scope: this,
1465
- callSite: (f, a) => f(...a)
1466
- });
1467
- (0, import_node_assert5.default)(invitationId);
1468
- const observable = this._acceptInvitations.get(invitationId);
1469
- if (!observable) {
1470
- import_log5.log.warn("invalid invitation", {
1471
- invitationId
1472
- }, {
1473
- file: "invitations-service.ts",
1474
- line: 172,
1475
- scope: this,
1476
- callSite: (f, a) => f(...a)
1477
- });
1478
- } else {
1479
- await observable.authenticate(authenticationCode);
1480
- }
946
+ async admit(request) {
947
+ (0, import_node_assert4.default)(request.device);
948
+ const identity = this._getIdentity();
949
+ await identity.admitDevice(request.device);
950
+ return {
951
+ device: {
952
+ identityKey: identity.identityKey,
953
+ haloSpaceKey: identity.haloSpaceKey,
954
+ genesisFeedKey: identity.haloGenesisFeedKey,
955
+ controlTimeframe: identity.controlPipeline.state.timeframe
956
+ }
957
+ };
1481
958
  }
1482
- async cancelInvitation(invitation) {
1483
- var _a;
1484
- (0, import_log5.log)("cancelling...", {}, {
1485
- file: "invitations-service.ts",
1486
- line: 179,
1487
- scope: this,
1488
- callSite: (f, a) => f(...a)
1489
- });
1490
- (0, import_node_assert5.default)(invitation.invitationId);
1491
- const observable = (_a = this._createInvitations.get(invitation.invitationId)) != null ? _a : this._acceptInvitations.get(invitation.invitationId);
1492
- if (!observable) {
1493
- import_log5.log.warn("invalid invitation", {
1494
- invitationId: invitation.invitationId
1495
- }, {
1496
- file: "invitations-service.ts",
1497
- line: 184,
1498
- scope: this,
1499
- callSite: (f, a) => f(...a)
1500
- });
1501
- } else {
1502
- await (observable == null ? void 0 : observable.cancel());
1503
- }
959
+ createIntroduction() {
960
+ return {};
1504
961
  }
1505
- };
1506
-
1507
- // packages/sdk/client-services/src/packlets/invitations/device-invitations-service.ts
1508
- var DeviceInvitationsServiceImpl = class extends AbstractInvitationsService {
1509
- // prettier-ignore
1510
- constructor(identityManager, invitationsHandler) {
1511
- super(identityManager, () => invitationsHandler);
1512
- this.invitationsHandler = invitationsHandler;
962
+ async createAdmissionRequest() {
963
+ const deviceKey = await this._keyring.createKey();
964
+ const controlFeedKey = await this._keyring.createKey();
965
+ const dataFeedKey = await this._keyring.createKey();
966
+ return {
967
+ device: {
968
+ deviceKey,
969
+ controlFeedKey,
970
+ dataFeedKey
971
+ }
972
+ };
1513
973
  }
1514
- getContext(invitation) {
974
+ async accept(response, request) {
975
+ (0, import_node_assert4.default)(response.device);
976
+ const { identityKey, haloSpaceKey, genesisFeedKey, controlTimeframe } = response.device;
977
+ (0, import_node_assert4.default)(request.device);
978
+ const { deviceKey, controlFeedKey, dataFeedKey } = request.device;
979
+ await this._acceptIdentity({
980
+ identityKey,
981
+ deviceKey,
982
+ haloSpaceKey,
983
+ haloGenesisFeedKey: genesisFeedKey,
984
+ controlFeedKey,
985
+ dataFeedKey,
986
+ controlTimeframe
987
+ });
988
+ return {
989
+ identityKey
990
+ };
1515
991
  }
1516
992
  };
1517
993
 
1518
- // packages/sdk/client-services/src/packlets/invitations/space-invitations-handler.ts
1519
- var import_node_assert6 = __toESM(require("node:assert"));
1520
- var import_async7 = require("@dxos/async");
1521
- var import_client2 = require("@dxos/client");
1522
- var import_context4 = require("@dxos/context");
1523
- var import_credentials8 = require("@dxos/credentials");
1524
- var import_feed_store3 = require("@dxos/feed-store");
1525
- var import_keys6 = require("@dxos/keys");
1526
- var import_log6 = require("@dxos/log");
1527
- var import_network_manager2 = require("@dxos/network-manager");
1528
- var import_protocols4 = require("@dxos/protocols");
1529
- var import_services3 = require("@dxos/protocols/proto/dxos/client/services");
1530
- var import_invitations2 = require("@dxos/protocols/proto/dxos/halo/invitations");
1531
- var import_teleport2 = require("@dxos/teleport");
994
+ // packages/sdk/client-services/src/packlets/invitations/invitations-handler.ts
995
+ var import_node_assert5 = __toESM(require("node:assert"));
996
+ var import_async6 = require("@dxos/async");
997
+ var import_client = require("@dxos/client");
998
+ var import_context3 = require("@dxos/context");
999
+ var import_credentials7 = require("@dxos/credentials");
1000
+ var import_keys5 = require("@dxos/keys");
1001
+ var import_log4 = require("@dxos/log");
1002
+ var import_network_manager = require("@dxos/network-manager");
1003
+ var import_protocols3 = require("@dxos/protocols");
1004
+ var import_services2 = require("@dxos/protocols/proto/dxos/client/services");
1005
+ var import_invitations = require("@dxos/protocols/proto/dxos/halo/invitations");
1006
+ var import_teleport = require("@dxos/teleport");
1532
1007
  var MAX_OTP_ATTEMPTS = 3;
1533
- var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHandler {
1534
- constructor(networkManager, _spaceManager, _signingContext, _keyring) {
1535
- super(networkManager);
1536
- this._spaceManager = _spaceManager;
1537
- this._signingContext = _signingContext;
1538
- this._keyring = _keyring;
1008
+ var InvitationsHandler = class {
1009
+ constructor(_networkManager) {
1010
+ this._networkManager = _networkManager;
1539
1011
  }
1540
- /**
1541
- * Creates an invitation and listens for a join request from the invited (guest) peer.
1542
- */
1543
- createInvitation(space, options) {
1012
+ createInvitation(protocol, options) {
1544
1013
  var _a;
1545
- let swarmConnection;
1546
- const { type, timeout = import_client2.INVITATION_TIMEOUT, swarmKey } = options != null ? options : {};
1547
- (0, import_node_assert6.default)(type !== import_services3.Invitation.Type.OFFLINE);
1548
- (0, import_node_assert6.default)(space);
1014
+ const { invitationId = import_keys5.PublicKey.random().toHex(), type = import_services2.Invitation.Type.INTERACTIVE, authMethod = import_services2.Invitation.AuthMethod.SHARED_SECRET, state = import_services2.Invitation.State.INIT, timeout = import_client.INVITATION_TIMEOUT, swarmKey = import_keys5.PublicKey.random() } = options != null ? options : {};
1015
+ const authCode = (_a = options == null ? void 0 : options.authCode) != null ? _a : authMethod === import_services2.Invitation.AuthMethod.SHARED_SECRET ? (0, import_credentials7.generatePasscode)(import_client.AUTHENTICATION_CODE_LENGTH) : void 0;
1016
+ (0, import_node_assert5.default)(protocol);
1549
1017
  const invitation = {
1018
+ invitationId,
1550
1019
  type,
1551
- invitationId: import_keys6.PublicKey.random().toHex(),
1552
- swarmKey: swarmKey != null ? swarmKey : import_keys6.PublicKey.random(),
1553
- spaceKey: space.key,
1554
- authMethod: (_a = options == null ? void 0 : options.authMethod) != null ? _a : import_invitations2.AuthMethod.SHARED_SECRET,
1555
- authenticationCode: (0, import_credentials8.generatePasscode)(import_client2.AUTHENTICATION_CODE_LENGTH)
1556
- // TODO(dmaretskyi): Don't generate if authMethod === NONE .
1020
+ authMethod,
1021
+ state,
1022
+ swarmKey,
1023
+ authCode,
1024
+ timeout,
1025
+ ...protocol.getInvitationContext()
1557
1026
  };
1558
- const ctx = new import_context4.Context({
1027
+ const stream = new import_async6.PushStream();
1028
+ const ctx = new import_context3.Context({
1559
1029
  onError: (err) => {
1560
1030
  void ctx.dispose();
1561
- observable.callback.onError(err);
1031
+ stream.error(err);
1562
1032
  }
1563
1033
  });
1564
- const observable = new import_client2.InvitationObservableProvider(async () => {
1565
- await (swarmConnection == null ? void 0 : swarmConnection.close());
1034
+ ctx.onDispose(() => {
1035
+ (0, import_log4.log)("complete", {
1036
+ ...protocol.toJSON()
1037
+ }, {
1038
+ file: "invitations-handler.ts",
1039
+ line: 102,
1040
+ scope: this,
1041
+ callSite: (f, a) => f(...a)
1042
+ });
1043
+ stream.complete();
1566
1044
  });
1567
- let authenticationPassed = false;
1568
- let authenticationRetry = 0;
1569
1045
  const createExtension = () => {
1570
- const complete = new import_async7.Trigger();
1046
+ const success = new import_async6.Trigger();
1571
1047
  let guestProfile;
1572
- const hostInvitationExtension = new HostSpaceInvitationExtension({
1048
+ let authenticationPassed = false;
1049
+ let authenticationRetry = 0;
1050
+ const extension = new InvitationHostExtension({
1573
1051
  introduce: async ({ profile }) => {
1574
- var _a2, _b;
1575
- (0, import_log6.log)("guest introduced itself", {
1052
+ (0, import_log4.log)("guest introduced itself", {
1576
1053
  guestProfile: profile,
1577
- host: this._signingContext.deviceKey,
1578
- spaceKey: space.key
1054
+ ...protocol.toJSON()
1579
1055
  }, {
1580
- file: "space-invitations-handler.ts",
1581
- line: 101,
1056
+ file: "invitations-handler.ts",
1057
+ line: 115,
1582
1058
  scope: this,
1583
1059
  callSite: (f, a) => f(...a)
1584
1060
  });
1585
1061
  guestProfile = profile;
1586
- (_b = (_a2 = observable.callback).onAuthenticating) == null ? void 0 : _b.call(_a2, invitation);
1062
+ stream.next({
1063
+ ...invitation,
1064
+ state: import_services2.Invitation.State.READY_FOR_AUTHENTICATION
1065
+ });
1587
1066
  return {
1588
- spaceKey: type === import_services3.Invitation.Type.INTERACTIVE_TESTING || type === import_services3.Invitation.Type.MULTIUSE_TESTING ? space.key : void 0,
1589
- authMethod: invitation.authMethod
1067
+ spaceKey: authMethod === import_services2.Invitation.AuthMethod.NONE ? protocol.getInvitationContext().spaceKey : void 0,
1068
+ authMethod
1590
1069
  };
1591
1070
  },
1592
- authenticate: async ({ authenticationCode: code }) => {
1593
- (0, import_log6.log)("received authentication request", {
1594
- authenticationCode: code
1071
+ authenticate: async ({ authCode: code }) => {
1072
+ (0, import_log4.log)("received authentication request", {
1073
+ authCode: code
1595
1074
  }, {
1596
- file: "space-invitations-handler.ts",
1597
- line: 123,
1075
+ file: "invitations-handler.ts",
1076
+ line: 134,
1598
1077
  scope: this,
1599
1078
  callSite: (f, a) => f(...a)
1600
1079
  });
1601
- let status = import_invitations2.AuthenticationResponse.Status.OK;
1080
+ let status = import_invitations.AuthenticationResponse.Status.OK;
1602
1081
  switch (invitation.authMethod) {
1603
- case import_invitations2.AuthMethod.NONE: {
1604
- (0, import_log6.log)("authentication not required", {}, {
1605
- file: "space-invitations-handler.ts",
1606
- line: 128,
1082
+ case import_services2.Invitation.AuthMethod.NONE: {
1083
+ (0, import_log4.log)("authentication not required", {}, {
1084
+ file: "invitations-handler.ts",
1085
+ line: 139,
1607
1086
  scope: this,
1608
1087
  callSite: (f, a) => f(...a)
1609
1088
  });
1610
1089
  return {
1611
- status: import_invitations2.AuthenticationResponse.Status.OK
1090
+ status: import_invitations.AuthenticationResponse.Status.OK
1612
1091
  };
1613
1092
  }
1614
- case import_invitations2.AuthMethod.SHARED_SECRET: {
1615
- if (invitation.authenticationCode) {
1093
+ case import_services2.Invitation.AuthMethod.SHARED_SECRET: {
1094
+ if (invitation.authCode) {
1616
1095
  if (authenticationRetry++ > MAX_OTP_ATTEMPTS) {
1617
- status = import_invitations2.AuthenticationResponse.Status.INVALID_OPT_ATTEMPTS;
1618
- } else if (code !== invitation.authenticationCode) {
1619
- status = import_invitations2.AuthenticationResponse.Status.INVALID_OTP;
1096
+ status = import_invitations.AuthenticationResponse.Status.INVALID_OPT_ATTEMPTS;
1097
+ } else if (code !== invitation.authCode) {
1098
+ status = import_invitations.AuthenticationResponse.Status.INVALID_OTP;
1620
1099
  } else {
1621
1100
  authenticationPassed = true;
1622
1101
  }
@@ -1624,15 +1103,15 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1624
1103
  break;
1625
1104
  }
1626
1105
  default: {
1627
- import_log6.log.error("invalid authentication method", {
1106
+ import_log4.log.error("invalid authentication method", {
1628
1107
  authMethod: invitation.authMethod
1629
1108
  }, {
1630
- file: "space-invitations-handler.ts",
1631
- line: 144,
1109
+ file: "invitations-handler.ts",
1110
+ line: 157,
1632
1111
  scope: this,
1633
1112
  callSite: (f, a) => f(...a)
1634
1113
  });
1635
- status = import_invitations2.AuthenticationResponse.Status.INTERNAL_ERROR;
1114
+ status = import_invitations.AuthenticationResponse.Status.INTERNAL_ERROR;
1636
1115
  break;
1637
1116
  }
1638
1117
  }
@@ -1640,159 +1119,196 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1640
1119
  status
1641
1120
  };
1642
1121
  },
1643
- requestAdmission: async ({ identityKey, deviceKey, controlFeedKey, dataFeedKey }) => {
1644
- var _a2;
1122
+ admit: async (admissionRequest) => {
1123
+ var _a2, _b, _c;
1645
1124
  try {
1646
1125
  if (isAuthenticationRequired(invitation) && !authenticationPassed) {
1647
1126
  throw new Error("Not authenticated");
1648
1127
  }
1649
- (0, import_log6.log)("writing guest credentials", {
1650
- host: this._signingContext.deviceKey,
1651
- guest: deviceKey
1652
- }, {
1653
- file: "space-invitations-handler.ts",
1654
- line: 160,
1655
- scope: this,
1656
- callSite: (f, a) => f(...a)
1657
- });
1658
- const credentials = await (0, import_credentials8.createAdmissionCredentials)(this._signingContext.credentialSigner, identityKey, space.key, space.inner.genesisFeedKey, guestProfile);
1659
- (0, import_node_assert6.default)(credentials[0].credential);
1660
- const spaceMemberCredential = credentials[0].credential.credential;
1661
- (0, import_node_assert6.default)((0, import_credentials8.getCredentialAssertion)(spaceMemberCredential)["@type"] === "dxos.halo.credentials.SpaceMember");
1662
- await (0, import_feed_store3.writeMessages)(space.inner.controlPipeline.writer, credentials);
1663
- complete.wake(deviceKey);
1664
- return {
1665
- credential: spaceMemberCredential,
1666
- controlTimeframe: space.inner.controlPipeline.state.timeframe,
1667
- dataTimeframe: (_a2 = space.dataPipeline.pipelineState) == null ? void 0 : _a2.timeframe
1668
- };
1128
+ const deviceKey = (_c = (_a2 = admissionRequest.device) == null ? void 0 : _a2.deviceKey) != null ? _c : (_b = admissionRequest.space) == null ? void 0 : _b.deviceKey;
1129
+ (0, import_node_assert5.default)(deviceKey);
1130
+ const admissionResponse = await protocol.admit(admissionRequest, guestProfile);
1131
+ success.wake(deviceKey);
1132
+ return admissionResponse;
1669
1133
  } catch (err) {
1670
- observable.callback.onError(err);
1134
+ stream.error(err);
1671
1135
  throw err;
1672
1136
  }
1673
1137
  },
1674
1138
  onOpen: () => {
1675
- (0, import_async7.scheduleTask)(ctx, async () => {
1676
- var _a2, _b;
1139
+ (0, import_async6.scheduleTask)(ctx, async () => {
1677
1140
  try {
1678
- (0, import_log6.log)("connected", {
1679
- host: this._signingContext.deviceKey
1141
+ (0, import_log4.log)("connected", {
1142
+ ...protocol.toJSON()
1680
1143
  }, {
1681
- file: "space-invitations-handler.ts",
1682
- line: 195,
1144
+ file: "invitations-handler.ts",
1145
+ line: 191,
1683
1146
  scope: this,
1684
1147
  callSite: (f, a) => f(...a)
1685
1148
  });
1686
- (_b = (_a2 = observable.callback).onConnected) == null ? void 0 : _b.call(_a2, invitation);
1687
- const deviceKey = await complete.wait({
1149
+ stream.next({
1150
+ ...invitation,
1151
+ state: import_services2.Invitation.State.CONNECTED
1152
+ });
1153
+ const deviceKey = await success.wait({
1688
1154
  timeout
1689
1155
  });
1690
- (0, import_log6.log)("admitted guest", {
1691
- host: this._signingContext.deviceKey,
1692
- guest: deviceKey
1156
+ (0, import_log4.log)("admitted guest", {
1157
+ guest: deviceKey,
1158
+ ...protocol.toJSON()
1693
1159
  }, {
1694
- file: "space-invitations-handler.ts",
1695
- line: 198,
1160
+ file: "invitations-handler.ts",
1161
+ line: 194,
1696
1162
  scope: this,
1697
1163
  callSite: (f, a) => f(...a)
1698
1164
  });
1699
- observable.callback.onSuccess(invitation);
1165
+ stream.next({
1166
+ ...invitation,
1167
+ state: import_services2.Invitation.State.SUCCESS
1168
+ });
1700
1169
  } catch (err) {
1701
- if (!observable.cancelled) {
1702
- import_log6.log.error("failed", err, {
1703
- file: "space-invitations-handler.ts",
1704
- line: 202,
1170
+ if (err instanceof import_async6.TimeoutError) {
1171
+ (0, import_log4.log)("timeout", {
1172
+ ...protocol.toJSON()
1173
+ }, {
1174
+ file: "invitations-handler.ts",
1175
+ line: 198,
1176
+ scope: this,
1177
+ callSite: (f, a) => f(...a)
1178
+ });
1179
+ stream.next({
1180
+ ...invitation,
1181
+ state: import_services2.Invitation.State.TIMEOUT
1182
+ });
1183
+ } else {
1184
+ import_log4.log.error("failed", err, {
1185
+ file: "invitations-handler.ts",
1186
+ line: 201,
1705
1187
  scope: this,
1706
1188
  callSite: (f, a) => f(...a)
1707
1189
  });
1708
- observable.callback.onError(err);
1190
+ stream.error(err);
1709
1191
  }
1710
1192
  } finally {
1711
- if (type !== import_services3.Invitation.Type.MULTIUSE_TESTING) {
1712
- await (0, import_async7.sleep)(import_client2.ON_CLOSE_DELAY);
1193
+ if (type !== import_services2.Invitation.Type.MULTIUSE) {
1194
+ await (0, import_async6.sleep)(import_client.ON_CLOSE_DELAY);
1713
1195
  await ctx.dispose();
1714
1196
  }
1715
1197
  }
1716
1198
  });
1717
1199
  }
1718
1200
  });
1719
- return hostInvitationExtension;
1201
+ return extension;
1720
1202
  };
1721
- (0, import_async7.scheduleTask)(ctx, async () => {
1722
- var _a2, _b;
1203
+ (0, import_async6.scheduleTask)(ctx, async () => {
1723
1204
  const topic = invitation.swarmKey;
1724
- const swarmConnection2 = await this._networkManager.joinSwarm({
1205
+ const swarmConnection = await this._networkManager.joinSwarm({
1725
1206
  topic,
1726
1207
  peerId: topic,
1727
- protocolProvider: (0, import_network_manager2.createTeleportProtocolFactory)(async (teleport) => {
1208
+ protocolProvider: (0, import_network_manager.createTeleportProtocolFactory)(async (teleport) => {
1728
1209
  teleport.addExtension("dxos.halo.invitations", createExtension());
1729
1210
  }),
1730
- topology: new import_network_manager2.StarTopology(topic)
1211
+ topology: new import_network_manager.StarTopology(topic)
1212
+ });
1213
+ ctx.onDispose(() => swarmConnection.close());
1214
+ stream.next({
1215
+ ...invitation,
1216
+ state: import_services2.Invitation.State.CONNECTING
1731
1217
  });
1732
- ctx.onDispose(() => swarmConnection2.close());
1733
- (_b = (_a2 = observable.callback).onConnecting) == null ? void 0 : _b.call(_a2, invitation);
1218
+ });
1219
+ const observable = new import_client.CancellableInvitationObservable({
1220
+ initialInvitation: invitation,
1221
+ subscriber: stream.observable,
1222
+ onCancel: async () => {
1223
+ stream.next({
1224
+ ...invitation,
1225
+ state: import_services2.Invitation.State.CANCELLED
1226
+ });
1227
+ await ctx.dispose();
1228
+ }
1734
1229
  });
1735
1230
  return observable;
1736
1231
  }
1737
- /**
1738
- * Waits for the host peer (inviter) to accept our join request.
1739
- * The local guest peer (invitee) then sends the local space invitation to the host,
1740
- * which then writes the guest's credentials to the space.
1741
- */
1742
- acceptInvitation(invitation, options) {
1743
- const { timeout = import_client2.INVITATION_TIMEOUT } = options != null ? options : {};
1744
- const ctx = new import_context4.Context({
1232
+ acceptInvitation(protocol, invitation) {
1233
+ const { timeout = import_client.INVITATION_TIMEOUT } = invitation;
1234
+ (0, import_node_assert5.default)(protocol);
1235
+ const authenticated = new import_async6.Trigger();
1236
+ const stream = new import_async6.PushStream();
1237
+ const ctx = new import_context3.Context({
1745
1238
  onError: (err) => {
1239
+ if (err instanceof import_async6.TimeoutError) {
1240
+ (0, import_log4.log)("timeout", {
1241
+ ...protocol.toJSON()
1242
+ }, {
1243
+ file: "invitations-handler.ts",
1244
+ line: 255,
1245
+ scope: this,
1246
+ callSite: (f, a) => f(...a)
1247
+ });
1248
+ stream.next({
1249
+ ...invitation,
1250
+ state: import_services2.Invitation.State.TIMEOUT
1251
+ });
1252
+ } else {
1253
+ import_log4.log.warn("auth failed", err, {
1254
+ file: "invitations-handler.ts",
1255
+ line: 258,
1256
+ scope: this,
1257
+ callSite: (f, a) => f(...a)
1258
+ });
1259
+ stream.error(err);
1260
+ }
1746
1261
  void ctx.dispose();
1747
- observable.callback.onError(err);
1748
1262
  }
1749
1263
  });
1750
- const authenticated = new import_async7.Trigger();
1751
- const observable = new import_client2.AuthenticatingInvitationProvider({
1752
- onCancel: async () => {
1753
- await ctx.dispose();
1754
- },
1755
- onAuthenticate: async (code) => {
1756
- authenticated.wake(code);
1757
- }
1264
+ ctx.onDispose(() => {
1265
+ (0, import_log4.log)("complete", {
1266
+ ...protocol.toJSON()
1267
+ }, {
1268
+ file: "invitations-handler.ts",
1269
+ line: 266,
1270
+ scope: this,
1271
+ callSite: (f, a) => f(...a)
1272
+ });
1273
+ stream.complete();
1758
1274
  });
1759
- let connectionCount = 0;
1760
- const complete = new import_async7.Trigger();
1761
1275
  const createExtension = () => {
1762
- const extension = new GuestSpaceInvitationExtension({
1276
+ let connectionCount = 0;
1277
+ const extension = new InvitationGuestExtension({
1763
1278
  onOpen: () => {
1764
- (0, import_async7.scheduleTask)(ctx, async () => {
1765
- var _a, _b, _c, _d, _e, _f;
1279
+ (0, import_async6.scheduleTask)(ctx, async () => {
1766
1280
  try {
1767
1281
  if (++connectionCount > 1) {
1768
1282
  throw new Error(`multiple connections detected: ${connectionCount}`);
1769
1283
  }
1770
- (0, import_log6.log)("connected", {
1771
- guest: this._signingContext.deviceKey
1284
+ (0, import_async6.scheduleTask)(ctx, () => ctx.raise(new import_async6.TimeoutError(timeout)), timeout);
1285
+ (0, import_log4.log)("connected", {
1286
+ ...protocol.toJSON()
1772
1287
  }, {
1773
- file: "space-invitations-handler.ts",
1774
- line: 275,
1288
+ file: "invitations-handler.ts",
1289
+ line: 284,
1775
1290
  scope: this,
1776
1291
  callSite: (f, a) => f(...a)
1777
1292
  });
1778
- (_b = (_a = observable.callback).onConnected) == null ? void 0 : _b.call(_a, invitation);
1779
- (0, import_log6.log)("introduce", {
1780
- guest: this._signingContext.deviceKey
1293
+ stream.next({
1294
+ ...invitation,
1295
+ state: import_services2.Invitation.State.CONNECTED
1296
+ });
1297
+ (0, import_log4.log)("introduce", {
1298
+ ...protocol.toJSON()
1781
1299
  }, {
1782
- file: "space-invitations-handler.ts",
1783
- line: 279,
1300
+ file: "invitations-handler.ts",
1301
+ line: 288,
1784
1302
  scope: this,
1785
1303
  callSite: (f, a) => f(...a)
1786
1304
  });
1787
- const introductionResponse = await extension.rpc.SpaceHostService.introduce({
1788
- profile: this._signingContext.profile
1789
- });
1790
- (0, import_log6.log)("introduce response", {
1791
- guest: this._signingContext.deviceKey,
1305
+ const introductionResponse = await extension.rpc.InvitationHostService.introduce(protocol.createIntroduction());
1306
+ (0, import_log4.log)("introduce response", {
1307
+ ...protocol.toJSON(),
1792
1308
  response: introductionResponse
1793
1309
  }, {
1794
- file: "space-invitations-handler.ts",
1795
- line: 283,
1310
+ file: "invitations-handler.ts",
1311
+ line: 292,
1796
1312
  scope: this,
1797
1313
  callSite: (f, a) => f(...a)
1798
1314
  });
@@ -1801,39 +1317,45 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1801
1317
  invitation.spaceKey = introductionResponse.spaceKey;
1802
1318
  }
1803
1319
  if (isAuthenticationRequired(invitation)) {
1804
- (_d = (_c = observable.callback).onAuthenticating) == null ? void 0 : _d.call(_c, invitation);
1805
1320
  for (let attempt = 1; attempt <= MAX_OTP_ATTEMPTS; attempt++) {
1806
- (0, import_log6.log)("guest waiting for authentication code...", {}, {
1807
- file: "space-invitations-handler.ts",
1808
- line: 297,
1321
+ (0, import_log4.log)("guest waiting for authentication code...", {}, {
1322
+ file: "invitations-handler.ts",
1323
+ line: 301,
1809
1324
  scope: this,
1810
1325
  callSite: (f, a) => f(...a)
1811
1326
  });
1812
- (_f = (_e = observable.callback).onAuthenticating) == null ? void 0 : _f.call(_e, invitation);
1813
- const authenticationCode = await authenticated.wait({
1327
+ stream.next({
1328
+ ...invitation,
1329
+ state: import_services2.Invitation.State.READY_FOR_AUTHENTICATION
1330
+ });
1331
+ const authCode = await authenticated.wait({
1814
1332
  timeout
1815
1333
  });
1816
- (0, import_log6.log)("sending authentication request", {}, {
1817
- file: "space-invitations-handler.ts",
1818
- line: 301,
1334
+ (0, import_log4.log)("sending authentication request", {}, {
1335
+ file: "invitations-handler.ts",
1336
+ line: 305,
1819
1337
  scope: this,
1820
1338
  callSite: (f, a) => f(...a)
1821
1339
  });
1822
- const response = await extension.rpc.SpaceHostService.authenticate({
1823
- authenticationCode
1340
+ stream.next({
1341
+ ...invitation,
1342
+ state: import_services2.Invitation.State.AUTHENTICATING
1824
1343
  });
1825
- if (response.status === void 0 || response.status === import_invitations2.AuthenticationResponse.Status.OK) {
1344
+ const response = await extension.rpc.InvitationHostService.authenticate({
1345
+ authCode
1346
+ });
1347
+ if (response.status === void 0 || response.status === import_invitations.AuthenticationResponse.Status.OK) {
1826
1348
  break;
1827
1349
  }
1828
- if (response.status === import_invitations2.AuthenticationResponse.Status.INVALID_OTP) {
1350
+ if (response.status === import_invitations.AuthenticationResponse.Status.INVALID_OTP) {
1829
1351
  if (attempt === MAX_OTP_ATTEMPTS) {
1830
1352
  throw new Error(`Maximum retry attempts: ${MAX_OTP_ATTEMPTS}`);
1831
1353
  } else {
1832
- (0, import_log6.log)("retrying invalid code", {
1354
+ (0, import_log4.log)("retrying invalid code", {
1833
1355
  attempt
1834
1356
  }, {
1835
- file: "space-invitations-handler.ts",
1836
- line: 311,
1357
+ file: "invitations-handler.ts",
1358
+ line: 316,
1837
1359
  scope: this,
1838
1360
  callSite: (f, a) => f(...a)
1839
1361
  });
@@ -1841,52 +1363,58 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1841
1363
  }
1842
1364
  }
1843
1365
  }
1366
+ } else {
1367
+ stream.next({
1368
+ ...invitation,
1369
+ state: import_services2.Invitation.State.READY_FOR_AUTHENTICATION
1370
+ });
1844
1371
  }
1845
- const controlFeedKey = await this._keyring.createKey();
1846
- const dataFeedKey = await this._keyring.createKey();
1847
- (0, import_log6.log)("request admission", {
1848
- guest: this._signingContext.deviceKey
1372
+ (0, import_log4.log)("request admission", {
1373
+ ...protocol.toJSON()
1849
1374
  }, {
1850
- file: "space-invitations-handler.ts",
1851
- line: 322,
1375
+ file: "invitations-handler.ts",
1376
+ line: 327,
1852
1377
  scope: this,
1853
1378
  callSite: (f, a) => f(...a)
1854
1379
  });
1855
- const { credential, controlTimeframe, dataTimeframe } = await extension.rpc.SpaceHostService.requestAdmission({
1856
- identityKey: this._signingContext.identityKey,
1857
- deviceKey: this._signingContext.deviceKey,
1858
- controlFeedKey,
1859
- dataFeedKey
1860
- });
1861
- const assertion = (0, import_credentials8.getCredentialAssertion)(credential);
1862
- (0, import_node_assert6.default)(assertion["@type"] === "dxos.halo.credentials.SpaceMember", "Invalid credential");
1863
- (0, import_node_assert6.default)(credential.subject.id.equals(this._signingContext.identityKey));
1864
- const space = await this._spaceManager.acceptSpace({
1865
- spaceKey: assertion.spaceKey,
1866
- genesisFeedKey: assertion.genesisFeedKey,
1867
- controlTimeframe,
1868
- dataTimeframe
1869
- });
1870
- await this._signingContext.recordCredential(credential);
1871
- (0, import_log6.log)("admitted by host", {
1872
- guest: this._signingContext.deviceKey,
1873
- spaceKey: space.key
1380
+ const admissionRequest = await protocol.createAdmissionRequest();
1381
+ const admissionResponse = await extension.rpc.InvitationHostService.admit(admissionRequest);
1382
+ const result = await protocol.accept(admissionResponse, admissionRequest);
1383
+ (0, import_log4.log)("admitted by host", {
1384
+ ...protocol.toJSON()
1874
1385
  }, {
1875
- file: "space-invitations-handler.ts",
1876
- line: 347,
1386
+ file: "invitations-handler.ts",
1387
+ line: 335,
1877
1388
  scope: this,
1878
1389
  callSite: (f, a) => f(...a)
1879
1390
  });
1880
- complete.wake();
1391
+ stream.next({
1392
+ ...invitation,
1393
+ ...result,
1394
+ state: import_services2.Invitation.State.SUCCESS
1395
+ });
1881
1396
  } catch (err) {
1882
- if (!observable.cancelled) {
1883
- import_log6.log.warn("auth failed", err, {
1884
- file: "space-invitations-handler.ts",
1885
- line: 351,
1397
+ if (err instanceof import_async6.TimeoutError) {
1398
+ (0, import_log4.log)("timeout", {
1399
+ ...protocol.toJSON()
1400
+ }, {
1401
+ file: "invitations-handler.ts",
1402
+ line: 339,
1886
1403
  scope: this,
1887
1404
  callSite: (f, a) => f(...a)
1888
1405
  });
1889
- observable.callback.onError(err);
1406
+ stream.next({
1407
+ ...invitation,
1408
+ state: import_services2.Invitation.State.TIMEOUT
1409
+ });
1410
+ } else {
1411
+ import_log4.log.warn("auth failed", err, {
1412
+ file: "invitations-handler.ts",
1413
+ line: 342,
1414
+ scope: this,
1415
+ callSite: (f, a) => f(...a)
1416
+ });
1417
+ stream.error(err);
1890
1418
  }
1891
1419
  } finally {
1892
1420
  await ctx.dispose();
@@ -1894,106 +1422,430 @@ var SpaceInvitationsHandler = class extends import_client2.AbstractInvitationsHa
1894
1422
  });
1895
1423
  }
1896
1424
  });
1897
- return extension;
1898
- };
1899
- (0, import_async7.scheduleTask)(ctx, async () => {
1900
- var _a, _b;
1901
- (0, import_node_assert6.default)(invitation.swarmKey);
1902
- const topic = invitation.swarmKey;
1903
- const swarmConnection = await this._networkManager.joinSwarm({
1904
- topic,
1905
- peerId: import_keys6.PublicKey.random(),
1906
- protocolProvider: (0, import_network_manager2.createTeleportProtocolFactory)(async (teleport) => {
1907
- teleport.addExtension("dxos.halo.invitations", createExtension());
1908
- }),
1909
- topology: new import_network_manager2.StarTopology(topic)
1425
+ return extension;
1426
+ };
1427
+ (0, import_async6.scheduleTask)(ctx, async () => {
1428
+ (0, import_node_assert5.default)(invitation.swarmKey);
1429
+ const topic = invitation.swarmKey;
1430
+ const swarmConnection = await this._networkManager.joinSwarm({
1431
+ topic,
1432
+ peerId: import_keys5.PublicKey.random(),
1433
+ protocolProvider: (0, import_network_manager.createTeleportProtocolFactory)(async (teleport) => {
1434
+ teleport.addExtension("dxos.halo.invitations", createExtension());
1435
+ }),
1436
+ topology: new import_network_manager.StarTopology(topic)
1437
+ });
1438
+ ctx.onDispose(() => swarmConnection.close());
1439
+ stream.next({
1440
+ ...invitation,
1441
+ state: import_services2.Invitation.State.CONNECTING
1442
+ });
1443
+ });
1444
+ const observable = new import_client.AuthenticatingInvitationObservable({
1445
+ initialInvitation: invitation,
1446
+ subscriber: stream.observable,
1447
+ onCancel: async () => {
1448
+ stream.next({
1449
+ ...invitation,
1450
+ state: import_services2.Invitation.State.CANCELLED
1451
+ });
1452
+ await ctx.dispose();
1453
+ },
1454
+ onAuthenticate: async (code) => {
1455
+ authenticated.wake(code);
1456
+ }
1457
+ });
1458
+ return observable;
1459
+ }
1460
+ };
1461
+ var isAuthenticationRequired = (invitation) => invitation.authMethod !== import_services2.Invitation.AuthMethod.NONE;
1462
+ var InvitationHostExtension = class extends import_teleport.RpcExtension {
1463
+ constructor(_callbacks) {
1464
+ super({
1465
+ exposed: {
1466
+ InvitationHostService: import_protocols3.schema.getService("dxos.halo.invitations.InvitationHostService")
1467
+ }
1468
+ });
1469
+ this._callbacks = _callbacks;
1470
+ }
1471
+ async getHandlers() {
1472
+ return {
1473
+ // TODO(dmaretskyi): For now this is just forwarding the data to callbacks since we don't have session-specific logic.
1474
+ // Perhaps in the future we will have more complex logic here.
1475
+ InvitationHostService: {
1476
+ introduce: async (request) => {
1477
+ return this._callbacks.introduce(request);
1478
+ },
1479
+ authenticate: async (request) => {
1480
+ return this._callbacks.authenticate(request);
1481
+ },
1482
+ admit: async (request) => {
1483
+ return this._callbacks.admit(request);
1484
+ }
1485
+ }
1486
+ };
1487
+ }
1488
+ async onOpen(context) {
1489
+ await super.onOpen(context);
1490
+ this._callbacks.onOpen();
1491
+ }
1492
+ };
1493
+ var InvitationGuestExtension = class extends import_teleport.RpcExtension {
1494
+ constructor(_callbacks) {
1495
+ super({
1496
+ requested: {
1497
+ InvitationHostService: import_protocols3.schema.getService("dxos.halo.invitations.InvitationHostService")
1498
+ }
1499
+ });
1500
+ this._callbacks = _callbacks;
1501
+ }
1502
+ async getHandlers() {
1503
+ return {};
1504
+ }
1505
+ async onOpen(context) {
1506
+ await super.onOpen(context);
1507
+ this._callbacks.onOpen();
1508
+ }
1509
+ };
1510
+
1511
+ // packages/sdk/client-services/src/packlets/invitations/invitations-service.ts
1512
+ var import_node_assert6 = __toESM(require("node:assert"));
1513
+ var import_codec_protobuf7 = require("@dxos/codec-protobuf");
1514
+ var import_log5 = require("@dxos/log");
1515
+ var import_services3 = require("@dxos/protocols/proto/dxos/client/services");
1516
+ var InvitationsServiceImpl = class {
1517
+ constructor(_invitationsHandler, _getHandler) {
1518
+ this._invitationsHandler = _invitationsHandler;
1519
+ this._getHandler = _getHandler;
1520
+ this._createInvitations = /* @__PURE__ */ new Map();
1521
+ this._acceptInvitations = /* @__PURE__ */ new Map();
1522
+ }
1523
+ // TODO(burdon): Guest/host label.
1524
+ getLoggingContext() {
1525
+ return {};
1526
+ }
1527
+ createInvitation(invitation) {
1528
+ return new import_codec_protobuf7.Stream(({ next, close }) => {
1529
+ const handler = this._getHandler(invitation);
1530
+ (0, import_log5.log)("stream opened", this.getLoggingContext(), {
1531
+ file: "invitations-service.ts",
1532
+ line: 37,
1533
+ scope: this,
1534
+ callSite: (f, a) => f(...a)
1535
+ });
1536
+ let invitationId;
1537
+ const observable = this._invitationsHandler.createInvitation(handler, invitation);
1538
+ observable.subscribe((invitation2) => {
1539
+ switch (invitation2.state) {
1540
+ case import_services3.Invitation.State.CONNECTING: {
1541
+ (0, import_node_assert6.default)(invitation2.invitationId);
1542
+ invitationId = invitation2.invitationId;
1543
+ this._createInvitations.set(invitation2.invitationId, observable);
1544
+ invitation2.state = import_services3.Invitation.State.CONNECTING;
1545
+ next(invitation2);
1546
+ break;
1547
+ }
1548
+ case import_services3.Invitation.State.CONNECTED: {
1549
+ (0, import_node_assert6.default)(invitation2.invitationId);
1550
+ invitation2.state = import_services3.Invitation.State.CONNECTED;
1551
+ next(invitation2);
1552
+ break;
1553
+ }
1554
+ case import_services3.Invitation.State.READY_FOR_AUTHENTICATION: {
1555
+ (0, import_node_assert6.default)(invitation2.invitationId);
1556
+ invitation2.state = import_services3.Invitation.State.READY_FOR_AUTHENTICATION;
1557
+ next(invitation2);
1558
+ break;
1559
+ }
1560
+ case import_services3.Invitation.State.AUTHENTICATING: {
1561
+ (0, import_node_assert6.default)(invitation2.invitationId);
1562
+ invitation2.state = import_services3.Invitation.State.AUTHENTICATING;
1563
+ next(invitation2);
1564
+ break;
1565
+ }
1566
+ case import_services3.Invitation.State.SUCCESS: {
1567
+ (0, import_node_assert6.default)(invitation2.invitationId);
1568
+ invitation2.state = import_services3.Invitation.State.SUCCESS;
1569
+ next(invitation2);
1570
+ break;
1571
+ }
1572
+ case import_services3.Invitation.State.CANCELLED: {
1573
+ (0, import_node_assert6.default)(invitationId);
1574
+ invitation2.invitationId = invitationId;
1575
+ invitation2.state = import_services3.Invitation.State.CANCELLED;
1576
+ next(invitation2);
1577
+ break;
1578
+ }
1579
+ case import_services3.Invitation.State.TIMEOUT: {
1580
+ (0, import_node_assert6.default)(invitationId);
1581
+ invitation2.invitationId = invitationId;
1582
+ invitation2.state = import_services3.Invitation.State.TIMEOUT;
1583
+ next(invitation2);
1584
+ break;
1585
+ }
1586
+ }
1587
+ }, (err) => {
1588
+ close(err);
1589
+ }, () => {
1590
+ close();
1591
+ });
1592
+ return (err) => {
1593
+ const context = this.getLoggingContext();
1594
+ if (err) {
1595
+ import_log5.log.warn("stream closed", {
1596
+ ...context,
1597
+ err
1598
+ }, {
1599
+ file: "invitations-service.ts",
1600
+ line: 103,
1601
+ scope: this,
1602
+ callSite: (f, a) => f(...a)
1603
+ });
1604
+ } else {
1605
+ (0, import_log5.log)("stream closed", context, {
1606
+ file: "invitations-service.ts",
1607
+ line: 105,
1608
+ scope: this,
1609
+ callSite: (f, a) => f(...a)
1610
+ });
1611
+ }
1612
+ this._createInvitations.delete(invitation.invitationId);
1613
+ };
1614
+ });
1615
+ }
1616
+ acceptInvitation(invitation) {
1617
+ return new import_codec_protobuf7.Stream(({ next, close }) => {
1618
+ (0, import_log5.log)("stream opened", this.getLoggingContext(), {
1619
+ file: "invitations-service.ts",
1620
+ line: 115,
1621
+ scope: this,
1622
+ callSite: (f, a) => f(...a)
1623
+ });
1624
+ const handler = this._getHandler(invitation);
1625
+ let invitationId;
1626
+ const observable = this._invitationsHandler.acceptInvitation(handler, invitation);
1627
+ observable.subscribe((invitation2) => {
1628
+ switch (invitation2.state) {
1629
+ case import_services3.Invitation.State.CONNECTING: {
1630
+ (0, import_node_assert6.default)(invitation2.invitationId);
1631
+ invitationId = invitation2.invitationId;
1632
+ this._acceptInvitations.set(invitation2.invitationId, observable);
1633
+ invitation2.state = import_services3.Invitation.State.CONNECTING;
1634
+ next(invitation2);
1635
+ break;
1636
+ }
1637
+ case import_services3.Invitation.State.CONNECTED: {
1638
+ (0, import_node_assert6.default)(invitation2.invitationId);
1639
+ invitation2.state = import_services3.Invitation.State.CONNECTED;
1640
+ next(invitation2);
1641
+ break;
1642
+ }
1643
+ case import_services3.Invitation.State.READY_FOR_AUTHENTICATION: {
1644
+ (0, import_node_assert6.default)(invitation2.invitationId);
1645
+ invitation2.state = import_services3.Invitation.State.READY_FOR_AUTHENTICATION;
1646
+ next(invitation2);
1647
+ break;
1648
+ }
1649
+ case import_services3.Invitation.State.AUTHENTICATING: {
1650
+ (0, import_node_assert6.default)(invitation2.invitationId);
1651
+ invitation2.state = import_services3.Invitation.State.AUTHENTICATING;
1652
+ next(invitation2);
1653
+ break;
1654
+ }
1655
+ case import_services3.Invitation.State.SUCCESS: {
1656
+ invitation2.state = import_services3.Invitation.State.SUCCESS;
1657
+ next(invitation2);
1658
+ break;
1659
+ }
1660
+ case import_services3.Invitation.State.CANCELLED: {
1661
+ (0, import_node_assert6.default)(invitationId);
1662
+ invitation2.invitationId = invitationId;
1663
+ invitation2.state = import_services3.Invitation.State.CANCELLED;
1664
+ next(invitation2);
1665
+ break;
1666
+ }
1667
+ case import_services3.Invitation.State.TIMEOUT: {
1668
+ (0, import_node_assert6.default)(invitationId);
1669
+ invitation2.invitationId = invitationId;
1670
+ invitation2.state = import_services3.Invitation.State.TIMEOUT;
1671
+ next(invitation2);
1672
+ break;
1673
+ }
1674
+ }
1675
+ }, (err) => {
1676
+ close(err);
1677
+ }, () => {
1678
+ close();
1910
1679
  });
1911
- ctx.onDispose(() => swarmConnection.close());
1912
- (_b = (_a = observable.callback).onConnecting) == null ? void 0 : _b.call(_a, invitation);
1913
- await complete.wait();
1914
- observable.callback.onSuccess(invitation);
1915
- await ctx.dispose();
1680
+ return (err) => {
1681
+ const context = this.getLoggingContext();
1682
+ if (err) {
1683
+ import_log5.log.warn("stream closed", {
1684
+ ...context,
1685
+ err
1686
+ }, {
1687
+ file: "invitations-service.ts",
1688
+ line: 181,
1689
+ scope: this,
1690
+ callSite: (f, a) => f(...a)
1691
+ });
1692
+ } else {
1693
+ (0, import_log5.log)("stream closed", context, {
1694
+ file: "invitations-service.ts",
1695
+ line: 183,
1696
+ scope: this,
1697
+ callSite: (f, a) => f(...a)
1698
+ });
1699
+ }
1700
+ this._acceptInvitations.delete(invitation.invitationId);
1701
+ };
1916
1702
  });
1917
- return observable;
1918
1703
  }
1919
- };
1920
- var isAuthenticationRequired = (invitation) => invitation.authMethod !== import_invitations2.AuthMethod.NONE && invitation.type !== import_services3.Invitation.Type.INTERACTIVE_TESTING && invitation.type !== import_services3.Invitation.Type.MULTIUSE_TESTING;
1921
- var HostSpaceInvitationExtension = class extends import_teleport2.RpcExtension {
1922
- constructor(_callbacks) {
1923
- super({
1924
- exposed: {
1925
- SpaceHostService: import_protocols4.schema.getService("dxos.halo.invitations.SpaceHostService")
1926
- }
1704
+ async authenticate({ invitationId, authCode }) {
1705
+ (0, import_log5.log)("authenticating...", {}, {
1706
+ file: "invitations-service.ts",
1707
+ line: 192,
1708
+ scope: this,
1709
+ callSite: (f, a) => f(...a)
1927
1710
  });
1928
- this._callbacks = _callbacks;
1711
+ (0, import_node_assert6.default)(invitationId);
1712
+ const observable = this._acceptInvitations.get(invitationId);
1713
+ if (!observable) {
1714
+ import_log5.log.warn("invalid invitation", {
1715
+ invitationId
1716
+ }, {
1717
+ file: "invitations-service.ts",
1718
+ line: 196,
1719
+ scope: this,
1720
+ callSite: (f, a) => f(...a)
1721
+ });
1722
+ } else {
1723
+ await observable.authenticate(authCode);
1724
+ }
1929
1725
  }
1930
- async getHandlers() {
1726
+ async cancelInvitation({ invitationId }) {
1727
+ var _a;
1728
+ (0, import_log5.log)("cancelling...", {}, {
1729
+ file: "invitations-service.ts",
1730
+ line: 203,
1731
+ scope: this,
1732
+ callSite: (f, a) => f(...a)
1733
+ });
1734
+ (0, import_node_assert6.default)(invitationId);
1735
+ const observable = (_a = this._createInvitations.get(invitationId)) != null ? _a : this._acceptInvitations.get(invitationId);
1736
+ if (!observable) {
1737
+ import_log5.log.warn("invalid invitation", {
1738
+ invitationId
1739
+ }, {
1740
+ file: "invitations-service.ts",
1741
+ line: 207,
1742
+ scope: this,
1743
+ callSite: (f, a) => f(...a)
1744
+ });
1745
+ } else {
1746
+ await (observable == null ? void 0 : observable.cancel());
1747
+ }
1748
+ }
1749
+ };
1750
+
1751
+ // packages/sdk/client-services/src/packlets/invitations/space-invitation-protocol.ts
1752
+ var import_node_assert7 = __toESM(require("node:assert"));
1753
+ var import_credentials8 = require("@dxos/credentials");
1754
+ var import_feed_store3 = require("@dxos/feed-store");
1755
+ var import_log6 = require("@dxos/log");
1756
+ var import_services4 = require("@dxos/protocols/proto/dxos/client/services");
1757
+ var SpaceInvitationProtocol = class {
1758
+ constructor(_spaceManager, _signingContext, _keyring, _spaceKey) {
1759
+ this._spaceManager = _spaceManager;
1760
+ this._signingContext = _signingContext;
1761
+ this._keyring = _keyring;
1762
+ this._spaceKey = _spaceKey;
1763
+ }
1764
+ toJSON() {
1931
1765
  return {
1932
- // TODO(dmaretskyi): For now this is just forwarding the data to callbacks since we don't have session-specific logic.
1933
- // Perhaps in the future we will have more complex logic here.
1934
- SpaceHostService: {
1935
- introduce: async (params) => {
1936
- return this._callbacks.introduce(params);
1937
- },
1938
- authenticate: async (credentials) => {
1939
- return this._callbacks.authenticate(credentials);
1940
- },
1941
- requestAdmission: async (credentials) => {
1942
- return this._callbacks.requestAdmission(credentials);
1943
- }
1944
- }
1766
+ deviceKey: this._signingContext.deviceKey,
1767
+ spaceKey: this._spaceKey
1945
1768
  };
1946
1769
  }
1947
- async onOpen(context) {
1948
- await super.onOpen(context);
1949
- this._callbacks.onOpen();
1770
+ getInvitationContext() {
1771
+ return {
1772
+ kind: import_services4.Invitation.Kind.SPACE,
1773
+ spaceKey: this._spaceKey
1774
+ };
1950
1775
  }
1951
- };
1952
- var GuestSpaceInvitationExtension = class extends import_teleport2.RpcExtension {
1953
- constructor(_callbacks) {
1954
- super({
1955
- requested: {
1956
- SpaceHostService: import_protocols4.schema.getService("dxos.halo.invitations.SpaceHostService")
1957
- }
1776
+ async admit(request, guestProfile) {
1777
+ var _a;
1778
+ (0, import_node_assert7.default)(this._spaceKey);
1779
+ const space = await this._spaceManager.spaces.get(this._spaceKey);
1780
+ (0, import_node_assert7.default)(space);
1781
+ (0, import_node_assert7.default)(request.space);
1782
+ const { identityKey, deviceKey } = request.space;
1783
+ (0, import_log6.log)("writing guest credentials", {
1784
+ host: this._signingContext.deviceKey,
1785
+ guest: deviceKey
1786
+ }, {
1787
+ file: "space-invitation-protocol.ts",
1788
+ line: 51,
1789
+ scope: this,
1790
+ callSite: (f, a) => f(...a)
1958
1791
  });
1959
- this._callbacks = _callbacks;
1792
+ const credentials = await (0, import_credentials8.createAdmissionCredentials)(this._signingContext.credentialSigner, identityKey, space.key, space.inner.genesisFeedKey, guestProfile);
1793
+ (0, import_node_assert7.default)(credentials[0].credential);
1794
+ const spaceMemberCredential = credentials[0].credential.credential;
1795
+ (0, import_node_assert7.default)((0, import_credentials8.getCredentialAssertion)(spaceMemberCredential)["@type"] === "dxos.halo.credentials.SpaceMember");
1796
+ await (0, import_feed_store3.writeMessages)(space.inner.controlPipeline.writer, credentials);
1797
+ return {
1798
+ space: {
1799
+ credential: spaceMemberCredential,
1800
+ controlTimeframe: space.inner.controlPipeline.state.timeframe,
1801
+ dataTimeframe: (_a = space.dataPipeline.pipelineState) == null ? void 0 : _a.timeframe
1802
+ }
1803
+ };
1960
1804
  }
1961
- async getHandlers() {
1962
- return {};
1805
+ createIntroduction() {
1806
+ return {
1807
+ profile: this._signingContext.profile
1808
+ };
1963
1809
  }
1964
- async onOpen(context) {
1965
- await super.onOpen(context);
1966
- this._callbacks.onOpen();
1810
+ async createAdmissionRequest() {
1811
+ const controlFeedKey = await this._keyring.createKey();
1812
+ const dataFeedKey = await this._keyring.createKey();
1813
+ return {
1814
+ space: {
1815
+ identityKey: this._signingContext.identityKey,
1816
+ deviceKey: this._signingContext.deviceKey,
1817
+ controlFeedKey,
1818
+ dataFeedKey
1819
+ }
1820
+ };
1967
1821
  }
1968
- };
1969
-
1970
- // packages/sdk/client-services/src/packlets/invitations/space-invitations-service.ts
1971
- var import_node_assert7 = __toESM(require("node:assert"));
1972
- var SpaceInvitationsServiceImpl = class extends AbstractInvitationsService {
1973
- // prettier-ignore
1974
- constructor(identityManager, invitationsHandler, _getSpaceManager) {
1975
- super(identityManager, invitationsHandler);
1976
- this.invitationsHandler = invitationsHandler;
1977
- this._getSpaceManager = _getSpaceManager;
1978
- }
1979
- getContext(invitation) {
1980
- (0, import_node_assert7.default)(invitation.spaceKey);
1981
- const spaceManager = this._getSpaceManager();
1982
- const space = spaceManager.spaces.get(invitation.spaceKey);
1983
- (0, import_node_assert7.default)(space);
1984
- return space;
1822
+ async accept(response) {
1823
+ (0, import_node_assert7.default)(response.space);
1824
+ const { credential, controlTimeframe, dataTimeframe } = response.space;
1825
+ const assertion = (0, import_credentials8.getCredentialAssertion)(credential);
1826
+ (0, import_node_assert7.default)(assertion["@type"] === "dxos.halo.credentials.SpaceMember", "Invalid credential");
1827
+ (0, import_node_assert7.default)(credential.subject.id.equals(this._signingContext.identityKey));
1828
+ await this._spaceManager.acceptSpace({
1829
+ spaceKey: assertion.spaceKey,
1830
+ genesisFeedKey: assertion.genesisFeedKey,
1831
+ controlTimeframe,
1832
+ dataTimeframe
1833
+ });
1834
+ await this._signingContext.recordCredential(credential);
1835
+ return {
1836
+ spaceKey: assertion.spaceKey
1837
+ };
1985
1838
  }
1986
1839
  };
1987
1840
 
1988
1841
  // packages/sdk/client-services/src/packlets/services/service-host.ts
1989
- var import_node_assert12 = __toESM(require("node:assert"));
1990
- var import_async19 = require("@dxos/async");
1842
+ var import_node_assert13 = __toESM(require("node:assert"));
1843
+ var import_async18 = require("@dxos/async");
1991
1844
  var import_client8 = require("@dxos/client");
1992
- var import_debug7 = require("@dxos/debug");
1993
1845
  var import_echo_pipeline5 = require("@dxos/echo-pipeline");
1994
1846
  var import_log16 = require("@dxos/log");
1995
- var import_protocols7 = require("@dxos/protocols");
1996
- var import_services8 = require("@dxos/protocols/proto/dxos/client/services");
1847
+ var import_protocols6 = require("@dxos/protocols");
1848
+ var import_services9 = require("@dxos/protocols/proto/dxos/client/services");
1997
1849
 
1998
1850
  // packages/sdk/client-services/src/packlets/deprecated/tracing.ts
1999
1851
  var TracingServiceImpl = class {
@@ -2009,9 +1861,9 @@ var TracingServiceImpl = class {
2009
1861
  };
2010
1862
 
2011
1863
  // packages/sdk/client-services/src/packlets/devices/devices-service.ts
2012
- var import_async8 = require("@dxos/async");
1864
+ var import_async7 = require("@dxos/async");
2013
1865
  var import_codec_protobuf8 = require("@dxos/codec-protobuf");
2014
- var import_services4 = require("@dxos/protocols/proto/dxos/client/services");
1866
+ var import_services5 = require("@dxos/protocols/proto/dxos/client/services");
2015
1867
  var DevicesServiceImpl = class {
2016
1868
  constructor(_identityManager) {
2017
1869
  this._identityManager = _identityManager;
@@ -2034,13 +1886,13 @@ var DevicesServiceImpl = class {
2034
1886
  var _a2;
2035
1887
  return {
2036
1888
  deviceKey: key,
2037
- kind: ((_a2 = this._identityManager.identity) == null ? void 0 : _a2.deviceKey.equals(key)) ? import_services4.DeviceKind.CURRENT : import_services4.DeviceKind.TRUSTED
1889
+ kind: ((_a2 = this._identityManager.identity) == null ? void 0 : _a2.deviceKey.equals(key)) ? import_services5.DeviceKind.CURRENT : import_services5.DeviceKind.TRUSTED
2038
1890
  };
2039
1891
  })
2040
1892
  });
2041
1893
  }
2042
1894
  };
2043
- const subscriptions = new import_async8.EventSubscriptions();
1895
+ const subscriptions = new import_async7.EventSubscriptions();
2044
1896
  subscriptions.add(this._identityManager.stateUpdate.on(() => {
2045
1897
  update();
2046
1898
  if (this._identityManager.identity) {
@@ -2079,47 +1931,47 @@ var NetworkServiceImpl = class {
2079
1931
 
2080
1932
  // packages/sdk/client-services/src/packlets/spaces/data-space-manager.ts
2081
1933
  var import_node_assert9 = __toESM(require("node:assert"));
2082
- var import_async11 = require("@dxos/async");
2083
- var import_client4 = require("@dxos/client");
2084
- var import_context7 = require("@dxos/context");
1934
+ var import_async10 = require("@dxos/async");
1935
+ var import_client3 = require("@dxos/client");
1936
+ var import_context6 = require("@dxos/context");
2085
1937
  var import_credentials10 = require("@dxos/credentials");
2086
1938
  var import_echo_pipeline2 = require("@dxos/echo-pipeline");
2087
- var import_keys9 = require("@dxos/keys");
1939
+ var import_keys8 = require("@dxos/keys");
2088
1940
  var import_log9 = require("@dxos/log");
2089
1941
  var import_teleport_extension_gossip = require("@dxos/teleport-extension-gossip");
2090
1942
  var import_util5 = require("@dxos/util");
2091
1943
 
2092
1944
  // packages/sdk/client-services/src/packlets/spaces/data-space.ts
2093
- var import_async10 = require("@dxos/async");
2094
- var import_client3 = require("@dxos/client");
2095
- var import_context6 = require("@dxos/context");
1945
+ var import_async9 = require("@dxos/async");
1946
+ var import_client2 = require("@dxos/client");
1947
+ var import_context5 = require("@dxos/context");
2096
1948
  var import_debug3 = require("@dxos/debug");
2097
1949
  var import_echo_pipeline = require("@dxos/echo-pipeline");
2098
1950
  var import_errors = require("@dxos/errors");
2099
- var import_keys8 = require("@dxos/keys");
1951
+ var import_keys7 = require("@dxos/keys");
2100
1952
  var import_log8 = require("@dxos/log");
2101
1953
  var import_credentials9 = require("@dxos/protocols/proto/dxos/halo/credentials");
2102
1954
  var import_util4 = require("@dxos/util");
2103
1955
 
2104
1956
  // packages/sdk/client-services/src/packlets/spaces/notarization-plugin.ts
2105
1957
  var import_node_assert8 = __toESM(require("node:assert"));
2106
- var import_async9 = require("@dxos/async");
2107
- var import_context5 = require("@dxos/context");
2108
- var import_keys7 = require("@dxos/keys");
1958
+ var import_async8 = require("@dxos/async");
1959
+ var import_context4 = require("@dxos/context");
1960
+ var import_keys6 = require("@dxos/keys");
2109
1961
  var import_log7 = require("@dxos/log");
2110
- var import_protocols5 = require("@dxos/protocols");
2111
- var import_teleport3 = require("@dxos/teleport");
1962
+ var import_protocols4 = require("@dxos/protocols");
1963
+ var import_teleport2 = require("@dxos/teleport");
2112
1964
  var import_util3 = require("@dxos/util");
2113
1965
  var DEFAULT_RETRY_TIMEOUT = 1e3;
2114
1966
  var DEFAULT_SUCCESS_DELAY = 1e3;
2115
1967
  var DEFAULT_NOTARIZE_TIMEOUT = 1e4;
2116
1968
  var NotarizationPlugin = class {
2117
1969
  constructor() {
2118
- this._ctx = new import_context5.Context();
2119
- this._extensionOpened = new import_async9.Event();
1970
+ this._ctx = new import_context4.Context();
1971
+ this._extensionOpened = new import_async8.Event();
2120
1972
  this._extensions = /* @__PURE__ */ new Set();
2121
- this._processedCredentials = new import_util3.ComplexSet(import_keys7.PublicKey.hash);
2122
- this._processCredentialsTriggers = new import_util3.ComplexMap(import_keys7.PublicKey.hash);
1973
+ this._processedCredentials = new import_util3.ComplexSet(import_keys6.PublicKey.hash);
1974
+ this._processCredentialsTriggers = new import_util3.ComplexMap(import_keys6.PublicKey.hash);
2123
1975
  }
2124
1976
  async open() {
2125
1977
  }
@@ -2139,7 +1991,7 @@ var NotarizationPlugin = class {
2139
1991
  callSite: (f, a) => f(...a)
2140
1992
  });
2141
1993
  (0, import_node_assert8.default)(credentials.every((credential) => credential.id), "Credentials must have an id");
2142
- const errors = new import_async9.Trigger();
1994
+ const errors = new import_async8.Trigger();
2143
1995
  const ctx = this._ctx.derive({
2144
1996
  onError: (err) => {
2145
1997
  import_log7.log.warn("Notarization error", {
@@ -2156,7 +2008,7 @@ var NotarizationPlugin = class {
2156
2008
  });
2157
2009
  opCtx == null ? void 0 : opCtx.onDispose(() => ctx.dispose());
2158
2010
  if (timeout !== 0) {
2159
- (0, import_async9.scheduleTask)(ctx, () => {
2011
+ (0, import_async8.scheduleTask)(ctx, () => {
2160
2012
  import_log7.log.warn("Notarization timeout", {
2161
2013
  timeout,
2162
2014
  peers: Array.from(this._extensions).map((extension) => extension.remotePeerId)
@@ -2167,12 +2019,12 @@ var NotarizationPlugin = class {
2167
2019
  callSite: (f, a) => f(...a)
2168
2020
  });
2169
2021
  void ctx.dispose();
2170
- errors.throw(new import_async9.TimeoutError(timeout, "Notarization timed out"));
2022
+ errors.throw(new import_async8.TimeoutError(timeout, "Notarization timed out"));
2171
2023
  }, timeout);
2172
2024
  }
2173
2025
  const allNotarized = Promise.all(credentials.map((credential) => this._waitUntilProcessed(credential.id)));
2174
2026
  const peersTried = /* @__PURE__ */ new Set();
2175
- const notarizeTask = new import_async9.DeferredTask(ctx, async () => {
2027
+ const notarizeTask = new import_async8.DeferredTask(ctx, async () => {
2176
2028
  try {
2177
2029
  if (this._extensions.size === 0) {
2178
2030
  return;
@@ -2190,7 +2042,7 @@ var NotarizationPlugin = class {
2190
2042
  callSite: (f, a) => f(...a)
2191
2043
  });
2192
2044
  peersTried.clear();
2193
- (0, import_async9.scheduleTask)(ctx, () => notarizeTask.schedule(), retryTimeout);
2045
+ (0, import_async8.scheduleTask)(ctx, () => notarizeTask.schedule(), retryTimeout);
2194
2046
  return;
2195
2047
  }
2196
2048
  peersTried.add(peer);
@@ -2212,7 +2064,7 @@ var NotarizationPlugin = class {
2212
2064
  scope: this,
2213
2065
  callSite: (f, a) => f(...a)
2214
2066
  });
2215
- await (0, import_async9.sleep)(successDelay);
2067
+ await (0, import_async8.sleep)(successDelay);
2216
2068
  } catch (err) {
2217
2069
  import_log7.log.warn("error notarizing (recoverable)", err, {
2218
2070
  file: "notarization-plugin.ts",
@@ -2227,7 +2079,7 @@ var NotarizationPlugin = class {
2227
2079
  this._extensionOpened.on(ctx, () => notarizeTask.schedule());
2228
2080
  try {
2229
2081
  await Promise.race([
2230
- (0, import_context5.rejectOnDispose)(ctx),
2082
+ (0, import_context4.rejectOnDispose)(ctx),
2231
2083
  allNotarized,
2232
2084
  errors.wait()
2233
2085
  ]);
@@ -2261,7 +2113,7 @@ var NotarizationPlugin = class {
2261
2113
  if (this._processedCredentials.has(id)) {
2262
2114
  return;
2263
2115
  }
2264
- await (0, import_util3.entry)(this._processCredentialsTriggers, id).orInsert(new import_async9.Trigger()).value.wait();
2116
+ await (0, import_util3.entry)(this._processCredentialsTriggers, id).orInsert(new import_async8.Trigger()).value.wait();
2265
2117
  }
2266
2118
  /**
2267
2119
  * Requests from other peers to notarize credentials.
@@ -2309,14 +2161,14 @@ var NotarizationPlugin = class {
2309
2161
  return extension;
2310
2162
  }
2311
2163
  };
2312
- var NotarizationTeleportExtension = class extends import_teleport3.RpcExtension {
2164
+ var NotarizationTeleportExtension = class extends import_teleport2.RpcExtension {
2313
2165
  constructor(_params) {
2314
2166
  super({
2315
2167
  requested: {
2316
- NotarizationService: import_protocols5.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2168
+ NotarizationService: import_protocols4.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2317
2169
  },
2318
2170
  exposed: {
2319
- NotarizationService: import_protocols5.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2171
+ NotarizationService: import_protocols4.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2320
2172
  }
2321
2173
  });
2322
2174
  this._params = _params;
@@ -2354,9 +2206,9 @@ var __decorate = function(decorators, target, key, desc) {
2354
2206
  var AUTH_TIMEOUT2 = 3e4;
2355
2207
  var DataSpace = class DataSpace2 {
2356
2208
  constructor(params) {
2357
- this._ctx = new import_context6.Context();
2358
- this._state = import_client3.SpaceState.CLOSED;
2359
- this.stateUpdate = new import_async10.Event();
2209
+ this._ctx = new import_context5.Context();
2210
+ this._state = import_client2.SpaceState.CLOSED;
2211
+ this.stateUpdate = new import_async9.Event();
2360
2212
  var _a;
2361
2213
  this._inner = params.inner;
2362
2214
  this._inner.stateUpdate.on(this._ctx, () => this.stateUpdate.emit());
@@ -2377,7 +2229,7 @@ var DataSpace = class DataSpace2 {
2377
2229
  snapshotId: params.snapshotId
2378
2230
  });
2379
2231
  this.authVerifier = new TrustedKeySetAuthVerifier({
2380
- trustedKeysProvider: () => new import_util4.ComplexSet(import_keys8.PublicKey.hash, Array.from(this._inner.spaceState.members.keys())),
2232
+ trustedKeysProvider: () => new import_util4.ComplexSet(import_keys7.PublicKey.hash, Array.from(this._inner.spaceState.members.keys())),
2381
2233
  update: this._inner.stateUpdate,
2382
2234
  authTimeout: AUTH_TIMEOUT2
2383
2235
  });
@@ -2409,10 +2261,10 @@ var DataSpace = class DataSpace2 {
2409
2261
  await this.notarizationPlugin.open();
2410
2262
  await this._notarizationPluginConsumer.open();
2411
2263
  await this._inner.open();
2412
- this._state = import_client3.SpaceState.INACTIVE;
2264
+ this._state = import_client2.SpaceState.INACTIVE;
2413
2265
  }
2414
2266
  async close() {
2415
- this._state = import_client3.SpaceState.CLOSED;
2267
+ this._state = import_client2.SpaceState.CLOSED;
2416
2268
  await this._ctx.dispose();
2417
2269
  await this._dataPipeline.close();
2418
2270
  await this.authVerifier.close();
@@ -2431,7 +2283,7 @@ var DataSpace = class DataSpace2 {
2431
2283
  * Initialize the data pipeline in a separate task.
2432
2284
  */
2433
2285
  initializeDataPipelineAsync() {
2434
- (0, import_async10.scheduleTask)(this._ctx, async () => {
2286
+ (0, import_async9.scheduleTask)(this._ctx, async () => {
2435
2287
  try {
2436
2288
  await this.initializeDataPipeline();
2437
2289
  } catch (err) {
@@ -2455,10 +2307,10 @@ var DataSpace = class DataSpace2 {
2455
2307
  }
2456
2308
  async initializeDataPipeline() {
2457
2309
  var _a, _b, _c, _d;
2458
- if (this._state !== import_client3.SpaceState.INACTIVE) {
2310
+ if (this._state !== import_client2.SpaceState.INACTIVE) {
2459
2311
  throw new import_errors.SystemError("Invalid operation");
2460
2312
  }
2461
- this._state = import_client3.SpaceState.INITIALIZING;
2313
+ this._state = import_client2.SpaceState.INITIALIZING;
2462
2314
  await this._inner.controlPipeline.state.waitUntilReachedTargetTimeframe({
2463
2315
  ctx: this._ctx,
2464
2316
  breakOnStall: false
@@ -2502,7 +2354,7 @@ var DataSpace = class DataSpace2 {
2502
2354
  callSite: (f, a) => f(...a)
2503
2355
  });
2504
2356
  await ((_b = (_a = this._callbacks).beforeReady) == null ? void 0 : _b.call(_a));
2505
- this._state = import_client3.SpaceState.READY;
2357
+ this._state = import_client2.SpaceState.READY;
2506
2358
  this.stateUpdate.emit();
2507
2359
  await ((_d = (_c = this._callbacks).afterReady) == null ? void 0 : _d.call(_c));
2508
2360
  }
@@ -2554,7 +2406,7 @@ __decorate([
2554
2406
  (0, import_debug3.timed)(1e4)
2555
2407
  ], DataSpace.prototype, "_createWritableFeeds", null);
2556
2408
  DataSpace = __decorate([
2557
- (0, import_async10.trackLeaks)("open", "close")
2409
+ (0, import_async9.trackLeaks)("open", "close")
2558
2410
  ], DataSpace);
2559
2411
 
2560
2412
  // packages/sdk/client-services/src/packlets/spaces/data-space-manager.ts
@@ -2578,9 +2430,9 @@ var DataSpaceManager = class DataSpaceManager2 {
2578
2430
  this._modelFactory = _modelFactory;
2579
2431
  this._feedStore = _feedStore;
2580
2432
  this._snapshotStore = _snapshotStore;
2581
- this._ctx = new import_context7.Context();
2582
- this.updated = new import_async11.Event();
2583
- this._spaces = new import_util5.ComplexMap(import_keys9.PublicKey.hash);
2433
+ this._ctx = new import_context6.Context();
2434
+ this.updated = new import_async10.Event();
2435
+ this._spaces = new import_util5.ComplexMap(import_keys8.PublicKey.hash);
2584
2436
  this._isOpen = false;
2585
2437
  }
2586
2438
  // TODO(burdon): Remove.
@@ -2693,9 +2545,9 @@ var DataSpaceManager = class DataSpaceManager2 {
2693
2545
  * TODO(dmaretskyi): Consider removing.
2694
2546
  */
2695
2547
  async waitUntilSpaceReady(spaceKey) {
2696
- await (0, import_context7.cancelWithContext)(this._ctx, this.updated.waitForCondition(() => {
2548
+ await (0, import_context6.cancelWithContext)(this._ctx, this.updated.waitForCondition(() => {
2697
2549
  const space = this._spaces.get(spaceKey);
2698
- return !!space && space.state === import_client4.SpaceState.READY;
2550
+ return !!space && space.state === import_client3.SpaceState.READY;
2699
2551
  }));
2700
2552
  }
2701
2553
  async _constructSpace(metadata) {
@@ -2792,28 +2644,28 @@ var DataSpaceManager = class DataSpaceManager2 {
2792
2644
  }
2793
2645
  };
2794
2646
  __decorate2([
2795
- import_async11.synchronized
2647
+ import_async10.synchronized
2796
2648
  ], DataSpaceManager.prototype, "open", null);
2797
2649
  __decorate2([
2798
- import_async11.synchronized
2650
+ import_async10.synchronized
2799
2651
  ], DataSpaceManager.prototype, "close", null);
2800
2652
  __decorate2([
2801
- import_async11.synchronized
2653
+ import_async10.synchronized
2802
2654
  ], DataSpaceManager.prototype, "createSpace", null);
2803
2655
  __decorate2([
2804
- import_async11.synchronized
2656
+ import_async10.synchronized
2805
2657
  ], DataSpaceManager.prototype, "acceptSpace", null);
2806
2658
  DataSpaceManager = __decorate2([
2807
- (0, import_async11.trackLeaks)("open", "close")
2659
+ (0, import_async10.trackLeaks)("open", "close")
2808
2660
  ], DataSpaceManager);
2809
2661
 
2810
2662
  // packages/sdk/client-services/src/packlets/spaces/spaces-service.ts
2811
- var import_async12 = require("@dxos/async");
2663
+ var import_async11 = require("@dxos/async");
2812
2664
  var import_codec_protobuf10 = require("@dxos/codec-protobuf");
2813
2665
  var import_debug4 = require("@dxos/debug");
2814
2666
  var import_echo_pipeline3 = require("@dxos/echo-pipeline");
2815
2667
  var import_log10 = require("@dxos/log");
2816
- var import_services5 = require("@dxos/protocols/proto/dxos/client/services");
2668
+ var import_services6 = require("@dxos/protocols/proto/dxos/client/services");
2817
2669
  var import_util6 = require("@dxos/util");
2818
2670
  var TIMEFRAME_UPDATE_DEBOUNCE_TIME = 500;
2819
2671
  var SpacesServiceImpl = class {
@@ -2851,9 +2703,9 @@ var SpacesServiceImpl = class {
2851
2703
  spaces
2852
2704
  });
2853
2705
  };
2854
- (0, import_async12.scheduleTask)(ctx, async () => {
2706
+ (0, import_async11.scheduleTask)(ctx, async () => {
2855
2707
  const dataSpaceManager = await this._getDataSpaceManager();
2856
- const subscriptions = new import_async12.EventSubscriptions();
2708
+ const subscriptions = new import_async11.EventSubscriptions();
2857
2709
  ctx.onDispose(() => subscriptions.clear());
2858
2710
  const subscribeSpaces = () => {
2859
2711
  subscriptions.clear();
@@ -2888,7 +2740,7 @@ var SpacesServiceImpl = class {
2888
2740
  }
2889
2741
  subscribeMessages({ spaceKey, channel }) {
2890
2742
  return new import_codec_protobuf10.Stream(({ ctx, next }) => {
2891
- (0, import_async12.scheduleTask)(ctx, async () => {
2743
+ (0, import_async11.scheduleTask)(ctx, async () => {
2892
2744
  var _a;
2893
2745
  const dataSpaceManager = await this._getDataSpaceManager();
2894
2746
  const space = (_a = dataSpaceManager.spaces.get(spaceKey)) != null ? _a : (0, import_debug4.raise)(new import_echo_pipeline3.SpaceNotFoundError(spaceKey));
@@ -2909,7 +2761,7 @@ var SpacesServiceImpl = class {
2909
2761
  }
2910
2762
  });
2911
2763
  ctx.onDispose(() => processor.close());
2912
- (0, import_async12.scheduleTask)(ctx, () => processor.open());
2764
+ (0, import_async11.scheduleTask)(ctx, () => processor.open());
2913
2765
  });
2914
2766
  }
2915
2767
  async writeCredentials({ spaceKey, credentials }) {
@@ -2924,18 +2776,22 @@ var SpacesServiceImpl = class {
2924
2776
  }
2925
2777
  }
2926
2778
  _transformSpace(space) {
2927
- var _a, _b;
2779
+ var _a, _b, _c, _d, _e;
2928
2780
  return {
2929
2781
  spaceKey: space.key,
2930
2782
  state: space.state,
2931
2783
  pipeline: {
2932
- targetControlTimeframe: space.inner.controlPipeline.state.targetTimeframe,
2784
+ controlFeeds: space.inner.controlPipeline.state.feeds.map((feed) => feed.key),
2933
2785
  currentControlTimeframe: space.inner.controlPipeline.state.timeframe,
2934
- currentDataTimeframe: (_a = space.dataPipeline.pipelineState) == null ? void 0 : _a.timeframe,
2935
- targetDataTimeframe: (_b = space.dataPipeline.pipelineState) == null ? void 0 : _b.targetTimeframe
2786
+ targetControlTimeframe: space.inner.controlPipeline.state.targetTimeframe,
2787
+ totalControlTimeframe: space.inner.controlPipeline.state.endTimeframe,
2788
+ dataFeeds: (_b = (_a = space.dataPipeline.pipelineState) == null ? void 0 : _a.feeds.map((feed) => feed.key)) != null ? _b : [],
2789
+ currentDataTimeframe: (_c = space.dataPipeline.pipelineState) == null ? void 0 : _c.timeframe,
2790
+ targetDataTimeframe: (_d = space.dataPipeline.pipelineState) == null ? void 0 : _d.targetTimeframe,
2791
+ totalDataTimeframe: (_e = space.dataPipeline.pipelineState) == null ? void 0 : _e.endTimeframe
2936
2792
  },
2937
2793
  members: Array.from(space.inner.spaceState.members.values()).map((member) => {
2938
- var _a2, _b2, _c;
2794
+ var _a2, _b2, _c2;
2939
2795
  return {
2940
2796
  identity: {
2941
2797
  identityKey: member.key,
@@ -2943,7 +2799,7 @@ var SpacesServiceImpl = class {
2943
2799
  displayName: (_b2 = (_a2 = member.assertion.profile) == null ? void 0 : _a2.displayName) != null ? _b2 : (0, import_util6.humanize)(member.key)
2944
2800
  }
2945
2801
  },
2946
- 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
2802
+ 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
2947
2803
  };
2948
2804
  })
2949
2805
  };
@@ -3035,10 +2891,10 @@ var SystemServiceImpl = class {
3035
2891
  };
3036
2892
 
3037
2893
  // packages/sdk/client-services/src/packlets/vault/iframe-host-runtime.ts
3038
- var import_async14 = require("@dxos/async");
2894
+ var import_async13 = require("@dxos/async");
3039
2895
  var import_log11 = require("@dxos/log");
3040
2896
  var import_messaging = require("@dxos/messaging");
3041
- var import_network_manager3 = require("@dxos/network-manager");
2897
+ var import_network_manager2 = require("@dxos/network-manager");
3042
2898
  var import_util7 = require("@dxos/util");
3043
2899
 
3044
2900
  // packages/sdk/client-services/src/packlets/services/client-rpc-server.ts
@@ -3096,14 +2952,14 @@ var ClientRpcServer = class {
3096
2952
 
3097
2953
  // packages/sdk/client-services/src/packlets/vault/shell-runtime.ts
3098
2954
  var import_node_assert10 = __toESM(require("node:assert"));
3099
- var import_async13 = require("@dxos/async");
3100
- var import_client5 = require("@dxos/client");
2955
+ var import_async12 = require("@dxos/async");
2956
+ var import_client4 = require("@dxos/client");
3101
2957
  var import_iframe = require("@dxos/protocols/proto/dxos/iframe");
3102
2958
  var import_rpc2 = require("@dxos/rpc");
3103
2959
  var ShellRuntimeImpl = class {
3104
2960
  constructor(_port) {
3105
2961
  this._port = _port;
3106
- this.layoutUpdate = new import_async13.Event();
2962
+ this.layoutUpdate = new import_async12.Event();
3107
2963
  this._layout = import_iframe.ShellLayout.DEFAULT;
3108
2964
  }
3109
2965
  get layout() {
@@ -3130,8 +2986,8 @@ var ShellRuntimeImpl = class {
3130
2986
  }
3131
2987
  async open() {
3132
2988
  this._appRpc = (0, import_rpc2.createProtoRpcPeer)({
3133
- requested: import_client5.appServiceBundle,
3134
- exposed: import_client5.shellServiceBundle,
2989
+ requested: import_client4.appServiceBundle,
2990
+ exposed: import_client4.shellServiceBundle,
3135
2991
  handlers: {
3136
2992
  ShellService: {
3137
2993
  setLayout: async (request) => {
@@ -3154,8 +3010,8 @@ var ShellRuntimeImpl = class {
3154
3010
  };
3155
3011
  var MemoryShellRuntime = class {
3156
3012
  constructor({ layout, invitationCode, spaceKey } = {}) {
3157
- this.layoutUpdate = new import_async13.Event();
3158
- this.contextUpdate = new import_async13.Event();
3013
+ this.layoutUpdate = new import_async12.Event();
3014
+ this.contextUpdate = new import_async12.Event();
3159
3015
  this._layout = layout != null ? layout : import_iframe.ShellLayout.DEFAULT;
3160
3016
  this._invitationCode = invitationCode;
3161
3017
  this._spaceKey = spaceKey;
@@ -3197,8 +3053,8 @@ var __decorate3 = function(decorators, target, key, desc) {
3197
3053
  var LOCK_KEY = "DXOS_RESOURCE_LOCK";
3198
3054
  var IFrameHostRuntime = class {
3199
3055
  constructor({ configProvider, appPort, shellPort }) {
3200
- this._transportFactory = (0, import_network_manager3.createWebRTCTransportFactory)();
3201
- this._ready = new import_async14.Trigger();
3056
+ this._transportFactory = (0, import_network_manager2.createWebRTCTransportFactory)();
3057
+ this._ready = new import_async13.Trigger();
3202
3058
  this._configProvider = configProvider;
3203
3059
  this._appPort = appPort;
3204
3060
  this._shellPort = shellPort;
@@ -3226,7 +3082,7 @@ var IFrameHostRuntime = class {
3226
3082
  this._clientServices = new LocalClientServices({
3227
3083
  lockKey: LOCK_KEY,
3228
3084
  config: this._config,
3229
- networkManager: new import_network_manager3.NetworkManager({
3085
+ networkManager: new import_network_manager2.NetworkManager({
3230
3086
  log: true,
3231
3087
  signalManager: signalServer ? new import_messaging.WebsocketSignalManager([
3232
3088
  signalServer
@@ -3305,19 +3161,19 @@ __decorate3([
3305
3161
  ], IFrameHostRuntime.prototype, "origin", void 0);
3306
3162
 
3307
3163
  // packages/sdk/client-services/src/packlets/vault/iframe-proxy-runtime.ts
3308
- var import_client6 = require("@dxos/client");
3309
- var import_network_manager4 = require("@dxos/network-manager");
3164
+ var import_client5 = require("@dxos/client");
3165
+ var import_network_manager3 = require("@dxos/network-manager");
3310
3166
  var import_rpc3 = require("@dxos/rpc");
3311
3167
  var IFrameProxyRuntime = class {
3312
3168
  constructor({ systemPort, workerAppPort, windowAppPort, shellPort }) {
3313
- this._transportService = new import_network_manager4.WebRTCTransportService();
3169
+ this._transportService = new import_network_manager3.WebRTCTransportService();
3314
3170
  this._systemPort = systemPort;
3315
3171
  this._windowAppPort = windowAppPort;
3316
3172
  this._workerAppPort = workerAppPort;
3317
3173
  this._shellPort = shellPort;
3318
3174
  this._systemRpc = (0, import_rpc3.createProtoRpcPeer)({
3319
- requested: import_client6.workerServiceBundle,
3320
- exposed: import_client6.iframeServiceBundle,
3175
+ requested: import_client5.workerServiceBundle,
3176
+ exposed: import_client5.iframeServiceBundle,
3321
3177
  handlers: {
3322
3178
  BridgeService: this._transportService,
3323
3179
  IframeService: {
@@ -3354,7 +3210,7 @@ var IFrameProxyRuntime = class {
3354
3210
  };
3355
3211
 
3356
3212
  // packages/sdk/client-services/src/packlets/vault/vault-resource-lock.ts
3357
- var import_async15 = require("@dxos/async");
3213
+ var import_async14 = require("@dxos/async");
3358
3214
  var import_log12 = require("@dxos/log");
3359
3215
  var __decorate4 = function(decorators, target, key, desc) {
3360
3216
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -3373,7 +3229,7 @@ var Message;
3373
3229
  var VaultResourceLock = class {
3374
3230
  constructor({ lockKey, onAcquire, onRelease }) {
3375
3231
  this._broadcastChannel = new BroadcastChannel("vault-resource-lock");
3376
- this._releaseTrigger = new import_async15.Trigger();
3232
+ this._releaseTrigger = new import_async14.Trigger();
3377
3233
  this._lockKey = lockKey;
3378
3234
  this._onAcquire = onAcquire;
3379
3235
  this._onRelease = onRelease;
@@ -3393,7 +3249,7 @@ var VaultResourceLock = class {
3393
3249
  scope: this,
3394
3250
  callSite: (f, a) => f(...a)
3395
3251
  });
3396
- await (0, import_async15.asyncTimeout)(this._requestLock(), 3e3);
3252
+ await (0, import_async14.asyncTimeout)(this._requestLock(), 3e3);
3397
3253
  (0, import_log12.log)("acquired lock", {}, {
3398
3254
  file: "vault-resource-lock.ts",
3399
3255
  line: 46,
@@ -3433,14 +3289,14 @@ var VaultResourceLock = class {
3433
3289
  scope: this,
3434
3290
  callSite: (f, a) => f(...a)
3435
3291
  });
3436
- const acquired = new import_async15.Trigger();
3292
+ const acquired = new import_async14.Trigger();
3437
3293
  void navigator.locks.request(this._lockKey, {
3438
3294
  steal
3439
3295
  }, async () => {
3440
3296
  var _a, _b;
3441
3297
  await ((_a = this._onAcquire) == null ? void 0 : _a.call(this));
3442
3298
  acquired.wake();
3443
- this._releaseTrigger = new import_async15.Trigger();
3299
+ this._releaseTrigger = new import_async14.Trigger();
3444
3300
  await this._releaseTrigger.wait();
3445
3301
  (0, import_log12.log)("releasing lock...", {}, {
3446
3302
  file: "vault-resource-lock.ts",
@@ -3475,15 +3331,15 @@ __decorate4([
3475
3331
  ], VaultResourceLock.prototype, "lockKey", null);
3476
3332
 
3477
3333
  // packages/sdk/client-services/src/packlets/vault/worker-runtime.ts
3478
- var import_async17 = require("@dxos/async");
3334
+ var import_async16 = require("@dxos/async");
3479
3335
  var import_log14 = require("@dxos/log");
3480
3336
  var import_messaging2 = require("@dxos/messaging");
3481
- var import_network_manager5 = require("@dxos/network-manager");
3337
+ var import_network_manager4 = require("@dxos/network-manager");
3482
3338
 
3483
3339
  // packages/sdk/client-services/src/packlets/vault/worker-session.ts
3484
3340
  var import_node_assert11 = __toESM(require("node:assert"));
3485
- var import_async16 = require("@dxos/async");
3486
- var import_client7 = require("@dxos/client");
3341
+ var import_async15 = require("@dxos/async");
3342
+ var import_client6 = require("@dxos/client");
3487
3343
  var import_log13 = require("@dxos/log");
3488
3344
  var import_rpc4 = require("@dxos/rpc");
3489
3345
  var import_util8 = require("@dxos/util");
@@ -3501,7 +3357,7 @@ var WorkerSession = class {
3501
3357
  constructor({ serviceHost, systemPort, appPort, shellPort, readySignal, options = {
3502
3358
  heartbeatInterval: 1e3
3503
3359
  } }) {
3504
- this._startTrigger = new import_async16.Trigger();
3360
+ this._startTrigger = new import_async15.Trigger();
3505
3361
  this.onClose = new import_util8.Callback();
3506
3362
  (0, import_node_assert11.default)(options);
3507
3363
  (0, import_node_assert11.default)(serviceHost);
@@ -3538,8 +3394,8 @@ var WorkerSession = class {
3538
3394
  ...middleware
3539
3395
  });
3540
3396
  this._iframeRpc = (0, import_rpc4.createProtoRpcPeer)({
3541
- requested: import_client7.iframeServiceBundle,
3542
- exposed: import_client7.workerServiceBundle,
3397
+ requested: import_client6.iframeServiceBundle,
3398
+ exposed: import_client6.workerServiceBundle,
3543
3399
  handlers: {
3544
3400
  WorkerService: {
3545
3401
  start: async (request) => {
@@ -3635,7 +3491,7 @@ var WorkerSession = class {
3635
3491
  }
3636
3492
  async _maybeOpenShell() {
3637
3493
  try {
3638
- await (0, import_async16.asyncTimeout)(this._shellClientRpc.open(), 1e3);
3494
+ await (0, import_async15.asyncTimeout)(this._shellClientRpc.open(), 1e3);
3639
3495
  } catch (e) {
3640
3496
  import_log13.log.info("No shell connected.", {}, {
3641
3497
  file: "worker-session.ts",
@@ -3655,15 +3511,18 @@ var WorkerRuntime = class {
3655
3511
  // prettier-ignore
3656
3512
  constructor(_configProvider) {
3657
3513
  this._configProvider = _configProvider;
3658
- this._transportFactory = new import_network_manager5.WebRTCTransportProxyFactory();
3659
- this._ready = new import_async17.Trigger();
3514
+ this._transportFactory = new import_network_manager4.WebRTCTransportProxyFactory();
3515
+ this._ready = new import_async16.Trigger();
3660
3516
  this.sessions = /* @__PURE__ */ new Set();
3661
3517
  this._clientServices = new ClientServicesHost();
3662
3518
  }
3519
+ get host() {
3520
+ return this._clientServices;
3521
+ }
3663
3522
  async start() {
3664
3523
  (0, import_log14.log)("starting...", {}, {
3665
3524
  file: "worker-runtime.ts",
3666
- line: 44,
3525
+ line: 48,
3667
3526
  scope: this,
3668
3527
  callSite: (f, a) => f(...a)
3669
3528
  });
@@ -3672,7 +3531,7 @@ var WorkerRuntime = class {
3672
3531
  const signalServer = this._config.get("runtime.services.signal.server");
3673
3532
  this._clientServices.initialize({
3674
3533
  config: this._config,
3675
- networkManager: new import_network_manager5.NetworkManager({
3534
+ networkManager: new import_network_manager4.NetworkManager({
3676
3535
  log: true,
3677
3536
  signalManager: signalServer ? new import_messaging2.WebsocketSignalManager([
3678
3537
  signalServer
@@ -3684,7 +3543,7 @@ var WorkerRuntime = class {
3684
3543
  this._ready.wake(void 0);
3685
3544
  (0, import_log14.log)("started", {}, {
3686
3545
  file: "worker-runtime.ts",
3687
- line: 61,
3546
+ line: 65,
3688
3547
  scope: this,
3689
3548
  callSite: (f, a) => f(...a)
3690
3549
  });
@@ -3692,7 +3551,7 @@ var WorkerRuntime = class {
3692
3551
  this._ready.wake(err);
3693
3552
  import_log14.log.catch(err, {}, {
3694
3553
  file: "worker-runtime.ts",
3695
- line: 64,
3554
+ line: 68,
3696
3555
  scope: this,
3697
3556
  callSite: (f, a) => f(...a)
3698
3557
  });
@@ -3742,24 +3601,27 @@ var WorkerRuntime = class {
3742
3601
  };
3743
3602
 
3744
3603
  // packages/sdk/client-services/src/packlets/services/service-context.ts
3745
- var import_async18 = require("@dxos/async");
3604
+ var import_node_assert12 = __toESM(require("node:assert"));
3605
+ var import_async17 = require("@dxos/async");
3606
+ var import_client7 = require("@dxos/client");
3746
3607
  var import_credentials11 = require("@dxos/credentials");
3747
3608
  var import_debug6 = require("@dxos/debug");
3748
3609
  var import_echo_pipeline4 = require("@dxos/echo-pipeline");
3749
3610
  var import_feed_store4 = require("@dxos/feed-store");
3750
3611
  var import_keyring = require("@dxos/keyring");
3751
- var import_keys10 = require("@dxos/keys");
3612
+ var import_keys9 = require("@dxos/keys");
3752
3613
  var import_log15 = require("@dxos/log");
3753
- var import_protocols6 = require("@dxos/protocols");
3614
+ var import_protocols5 = require("@dxos/protocols");
3754
3615
  var ServiceContext = class {
3755
3616
  // prettier-ignore
3756
3617
  constructor(storage, networkManager, modelFactory) {
3757
3618
  this.storage = storage;
3758
3619
  this.networkManager = networkManager;
3759
3620
  this.modelFactory = modelFactory;
3760
- this.initialized = new import_async18.Trigger();
3621
+ this.initialized = new import_async17.Trigger();
3761
3622
  this.dataServiceSubscriptions = new import_echo_pipeline4.DataServiceSubscriptions();
3762
- this._instanceId = import_keys10.PublicKey.random().toHex();
3623
+ this._handlerFactories = /* @__PURE__ */ new Map();
3624
+ this._instanceId = import_keys9.PublicKey.random().toHex();
3763
3625
  this.metadataStore = new import_echo_pipeline4.MetadataStore(storage.createDirectory("metadata"));
3764
3626
  this.snapshotStore = new import_echo_pipeline4.SnapshotStore(storage.createDirectory("snapshots"));
3765
3627
  this.keyring = new import_keyring.Keyring(storage.createDirectory("keyring"));
@@ -3777,28 +3639,24 @@ var ServiceContext = class {
3777
3639
  networkManager: this.networkManager
3778
3640
  });
3779
3641
  this.identityManager = new IdentityManager(this.metadataStore, this.keyring, this.feedStore, this.spaceManager);
3780
- this.deviceInvitations = new DeviceInvitationsHandler({
3781
- networkManager: this.networkManager,
3782
- getIdentity: () => {
3783
- var _a;
3784
- return (_a = this.identityManager.identity) != null ? _a : (0, import_debug6.failUndefined)();
3785
- },
3786
- acceptIdentity: this._acceptIdentity.bind(this),
3787
- keyring: this.keyring
3788
- });
3642
+ this.invitations = new InvitationsHandler(this.networkManager);
3643
+ this._handlerFactories.set(import_client7.Invitation.Kind.DEVICE, () => new DeviceInvitationProtocol(this.keyring, () => {
3644
+ var _a;
3645
+ return (_a = this.identityManager.identity) != null ? _a : (0, import_debug6.failUndefined)();
3646
+ }, this._acceptIdentity.bind(this)));
3789
3647
  }
3790
3648
  async open() {
3791
- import_log15.log.trace("dxos.sdk.client-services", import_protocols6.trace.begin({
3649
+ import_log15.log.trace("dxos.sdk.client-services", import_protocols5.trace.begin({
3792
3650
  id: this._instanceId
3793
3651
  }), {
3794
3652
  file: "service-context.ts",
3795
- line: 98,
3653
+ line: 111,
3796
3654
  scope: this,
3797
3655
  callSite: (f, a) => f(...a)
3798
3656
  });
3799
3657
  (0, import_log15.log)("opening...", {}, {
3800
3658
  file: "service-context.ts",
3801
- line: 100,
3659
+ line: 113,
3802
3660
  scope: this,
3803
3661
  callSite: (f, a) => f(...a)
3804
3662
  });
@@ -3810,7 +3668,7 @@ var ServiceContext = class {
3810
3668
  }
3811
3669
  (0, import_log15.log)("opened", {}, {
3812
3670
  file: "service-context.ts",
3813
- line: 107,
3671
+ line: 120,
3814
3672
  scope: this,
3815
3673
  callSite: (f, a) => f(...a)
3816
3674
  });
@@ -3819,7 +3677,7 @@ var ServiceContext = class {
3819
3677
  var _a, _b;
3820
3678
  (0, import_log15.log)("closing...", {}, {
3821
3679
  file: "service-context.ts",
3822
- line: 111,
3680
+ line: 124,
3823
3681
  scope: this,
3824
3682
  callSite: (f, a) => f(...a)
3825
3683
  });
@@ -3832,15 +3690,15 @@ var ServiceContext = class {
3832
3690
  this.dataServiceSubscriptions.clear();
3833
3691
  (0, import_log15.log)("closed", {}, {
3834
3692
  file: "service-context.ts",
3835
- line: 119,
3693
+ line: 132,
3836
3694
  scope: this,
3837
3695
  callSite: (f, a) => f(...a)
3838
3696
  });
3839
- import_log15.log.trace("dxos.sdk.client-services", import_protocols6.trace.end({
3697
+ import_log15.log.trace("dxos.sdk.client-services", import_protocols5.trace.end({
3840
3698
  id: this._instanceId
3841
3699
  }), {
3842
3700
  file: "service-context.ts",
3843
- line: 121,
3701
+ line: 134,
3844
3702
  scope: this,
3845
3703
  callSite: (f, a) => f(...a)
3846
3704
  });
@@ -3848,7 +3706,7 @@ var ServiceContext = class {
3848
3706
  async reset() {
3849
3707
  (0, import_log15.log)("resetting...", {}, {
3850
3708
  file: "service-context.ts",
3851
- line: 125,
3709
+ line: 138,
3852
3710
  scope: this,
3853
3711
  callSite: (f, a) => f(...a)
3854
3712
  });
@@ -3856,7 +3714,7 @@ var ServiceContext = class {
3856
3714
  await this.storage.reset();
3857
3715
  (0, import_log15.log)("reset", {}, {
3858
3716
  file: "service-context.ts",
3859
- line: 128,
3717
+ line: 141,
3860
3718
  scope: this,
3861
3719
  callSite: (f, a) => f(...a)
3862
3720
  });
@@ -3866,6 +3724,11 @@ var ServiceContext = class {
3866
3724
  await this._initialize();
3867
3725
  return identity;
3868
3726
  }
3727
+ getInvitationHandler(invitation) {
3728
+ const factory = this._handlerFactories.get(invitation.kind);
3729
+ (0, import_node_assert12.default)(factory, `Unknown invitation kind: ${invitation.kind}`);
3730
+ return factory(invitation);
3731
+ }
3869
3732
  async _acceptIdentity(params) {
3870
3733
  const identity = await this.identityManager.acceptIdentity(params);
3871
3734
  await this._initialize();
@@ -3876,7 +3739,7 @@ var ServiceContext = class {
3876
3739
  var _a;
3877
3740
  (0, import_log15.log)("initializing spaces...", {}, {
3878
3741
  file: "service-context.ts",
3879
- line: 147,
3742
+ line: 166,
3880
3743
  scope: this,
3881
3744
  callSite: (f, a) => f(...a)
3882
3745
  });
@@ -3896,7 +3759,10 @@ var ServiceContext = class {
3896
3759
  };
3897
3760
  this.dataSpaceManager = new DataSpaceManager(this.spaceManager, this.metadataStore, this.dataServiceSubscriptions, this.keyring, signingContext, this.modelFactory, this.feedStore, this.snapshotStore);
3898
3761
  await this.dataSpaceManager.open();
3899
- this.spaceInvitations = new SpaceInvitationsHandler(this.networkManager, this.dataSpaceManager, signingContext, this.keyring);
3762
+ this._handlerFactories.set(import_client7.Invitation.Kind.SPACE, (invitation) => {
3763
+ (0, import_node_assert12.default)(this.dataSpaceManager, "dataSpaceManager not initialized yet");
3764
+ return new SpaceInvitationProtocol(this.dataSpaceManager, signingContext, this.keyring, invitation.spaceKey);
3765
+ });
3900
3766
  this.initialized.wake();
3901
3767
  this._deviceSpaceSync = identity.space.spaceState.registerProcessor({
3902
3768
  process: async (credential) => {
@@ -3912,7 +3778,7 @@ var ServiceContext = class {
3912
3778
  details: assertion
3913
3779
  }, {
3914
3780
  file: "service-context.ts",
3915
- line: 190,
3781
+ line: 207,
3916
3782
  scope: this,
3917
3783
  callSite: (f, a) => f(...a)
3918
3784
  });
@@ -3923,7 +3789,7 @@ var ServiceContext = class {
3923
3789
  details: assertion
3924
3790
  }, {
3925
3791
  file: "service-context.ts",
3926
- line: 194,
3792
+ line: 211,
3927
3793
  scope: this,
3928
3794
  callSite: (f, a) => f(...a)
3929
3795
  });
@@ -3934,7 +3800,7 @@ var ServiceContext = class {
3934
3800
  details: assertion
3935
3801
  }, {
3936
3802
  file: "service-context.ts",
3937
- line: 199,
3803
+ line: 216,
3938
3804
  scope: this,
3939
3805
  callSite: (f, a) => f(...a)
3940
3806
  });
@@ -3945,7 +3811,7 @@ var ServiceContext = class {
3945
3811
  } catch (err) {
3946
3812
  import_log15.log.catch(err, {}, {
3947
3813
  file: "service-context.ts",
3948
- line: 205,
3814
+ line: 222,
3949
3815
  scope: this,
3950
3816
  callSite: (f, a) => f(...a)
3951
3817
  });
@@ -3991,7 +3857,7 @@ var ClientServicesHost = class {
3991
3857
  // TODO(wittjosiah): Turn this on by default.
3992
3858
  lockKey
3993
3859
  } = {}) {
3994
- this._statusUpdate = new import_async19.Event();
3860
+ this._statusUpdate = new import_async18.Event();
3995
3861
  this._opening = false;
3996
3862
  this._open = false;
3997
3863
  this._instanceId = import_client8.PublicKey.random().toHex();
@@ -4013,17 +3879,17 @@ var ClientServicesHost = class {
4013
3879
  this._systemService = new SystemServiceImpl({
4014
3880
  config: this._config,
4015
3881
  statusUpdate: this._statusUpdate,
4016
- getCurrentStatus: () => this.isOpen ? import_services8.SystemStatus.ACTIVE : import_services8.SystemStatus.INACTIVE,
3882
+ getCurrentStatus: () => this.isOpen ? import_services9.SystemStatus.ACTIVE : import_services9.SystemStatus.INACTIVE,
4017
3883
  onUpdateStatus: async (status) => {
4018
3884
  var _a, _b;
4019
- if (!this.isOpen && status === import_services8.SystemStatus.ACTIVE) {
3885
+ if (!this.isOpen && status === import_services9.SystemStatus.ACTIVE) {
4020
3886
  await ((_a = this._resourceLock) == null ? void 0 : _a.acquire());
4021
- } else if (this.isOpen && status === import_services8.SystemStatus.INACTIVE) {
3887
+ } else if (this.isOpen && status === import_services9.SystemStatus.INACTIVE) {
4022
3888
  await ((_b = this._resourceLock) == null ? void 0 : _b.release());
4023
3889
  }
4024
3890
  },
4025
3891
  onReset: async () => {
4026
- (0, import_node_assert12.default)(this._serviceContext, "service host is closed");
3892
+ (0, import_node_assert13.default)(this._serviceContext, "service host is closed");
4027
3893
  await this._serviceContext.reset();
4028
3894
  }
4029
3895
  });
@@ -4049,16 +3915,16 @@ var ClientServicesHost = class {
4049
3915
  * Can only be called once.
4050
3916
  */
4051
3917
  initialize({ config, networkManager }) {
4052
- (0, import_node_assert12.default)(!this._open, "service host is open");
3918
+ (0, import_node_assert13.default)(!this._open, "service host is open");
4053
3919
  if (config) {
4054
- (0, import_node_assert12.default)(!this._config, "config already set");
3920
+ (0, import_node_assert13.default)(!this._config, "config already set");
4055
3921
  this._config = config;
4056
3922
  if (!this._storage) {
4057
3923
  this._storage = createStorageObjects(config.get("runtime.client.storage", {})).storage;
4058
3924
  }
4059
3925
  }
4060
3926
  if (networkManager) {
4061
- (0, import_node_assert12.default)(!this._networkManager, "network manager already set");
3927
+ (0, import_node_assert13.default)(!this._networkManager, "network manager already set");
4062
3928
  this._networkManager = networkManager;
4063
3929
  }
4064
3930
  }
@@ -4067,23 +3933,23 @@ var ClientServicesHost = class {
4067
3933
  if (this._open) {
4068
3934
  return;
4069
3935
  }
4070
- import_log16.log.trace("dxos.sdk.client-services-host", import_protocols7.trace.begin({
3936
+ import_log16.log.trace("dxos.sdk.client-services-host", import_protocols6.trace.begin({
4071
3937
  id: this._instanceId
4072
3938
  }), {
4073
3939
  file: "service-host.ts",
4074
- line: 168,
3940
+ line: 167,
4075
3941
  scope: this,
4076
3942
  callSite: (f, a) => f(...a)
4077
3943
  });
4078
- (0, import_node_assert12.default)(this._config, "config not set");
4079
- (0, import_node_assert12.default)(this._storage, "storage not set");
4080
- (0, import_node_assert12.default)(this._networkManager, "network manager not set");
3944
+ (0, import_node_assert13.default)(this._config, "config not set");
3945
+ (0, import_node_assert13.default)(this._storage, "storage not set");
3946
+ (0, import_node_assert13.default)(this._networkManager, "network manager not set");
4081
3947
  this._opening = true;
4082
3948
  (0, import_log16.log)("opening...", {
4083
3949
  lockKey: (_a = this._resourceLock) == null ? void 0 : _a.lockKey
4084
3950
  }, {
4085
3951
  file: "service-host.ts",
4086
- line: 175,
3952
+ line: 174,
4087
3953
  scope: this,
4088
3954
  callSite: (f, a) => f(...a)
4089
3955
  });
@@ -4092,15 +3958,8 @@ var ClientServicesHost = class {
4092
3958
  this._serviceRegistry.setServices({
4093
3959
  SystemService: this._systemService,
4094
3960
  IdentityService: new IdentityServiceImpl(this._serviceContext),
3961
+ InvitationsService: new InvitationsServiceImpl(this._serviceContext.invitations, (invitation) => this._serviceContext.getInvitationHandler(invitation)),
4095
3962
  DevicesService: new DevicesServiceImpl(this._serviceContext.identityManager),
4096
- DeviceInvitationsService: new DeviceInvitationsServiceImpl(this._serviceContext.identityManager, this._serviceContext.deviceInvitations),
4097
- SpaceInvitationsService: new SpaceInvitationsServiceImpl(this._serviceContext.identityManager, () => {
4098
- var _a2;
4099
- return (_a2 = this._serviceContext.spaceInvitations) != null ? _a2 : (0, import_debug7.raise)(new Error("SpaceInvitations not initialized"));
4100
- }, () => {
4101
- var _a2;
4102
- return (_a2 = this._serviceContext.dataSpaceManager) != null ? _a2 : (0, import_debug7.raise)(new Error("SpaceManager not initialized"));
4103
- }),
4104
3963
  SpacesService: new SpacesServiceImpl(this._serviceContext.identityManager, this._serviceContext.spaceManager, this._serviceContext.dataServiceSubscriptions, async () => {
4105
3964
  await this._serviceContext.initialized.wait();
4106
3965
  return this._serviceContext.dataSpaceManager;
@@ -4124,7 +3983,7 @@ var ClientServicesHost = class {
4124
3983
  deviceKey
4125
3984
  }, {
4126
3985
  file: "service-host.ts",
4127
- line: 229,
3986
+ line: 221,
4128
3987
  scope: this,
4129
3988
  callSite: (f, a) => f(...a)
4130
3989
  });
@@ -4139,7 +3998,7 @@ var ClientServicesHost = class {
4139
3998
  deviceKey
4140
3999
  }, {
4141
4000
  file: "service-host.ts",
4142
- line: 238,
4001
+ line: 230,
4143
4002
  scope: this,
4144
4003
  callSite: (f, a) => f(...a)
4145
4004
  });
@@ -4153,15 +4012,15 @@ var ClientServicesHost = class {
4153
4012
  deviceKey
4154
4013
  }, {
4155
4014
  file: "service-host.ts",
4156
- line: 243,
4015
+ line: 235,
4157
4016
  scope: this,
4158
4017
  callSite: (f, a) => f(...a)
4159
4018
  });
4160
- import_log16.log.trace("dxos.sdk.client-services-host", import_protocols7.trace.end({
4019
+ import_log16.log.trace("dxos.sdk.client-services-host", import_protocols6.trace.end({
4161
4020
  id: this._instanceId
4162
4021
  }), {
4163
4022
  file: "service-host.ts",
4164
- line: 245,
4023
+ line: 237,
4165
4024
  scope: this,
4166
4025
  callSite: (f, a) => f(...a)
4167
4026
  });
@@ -4194,7 +4053,7 @@ var LocalClientServices = class {
4194
4053
  var import_config2 = require("@dxos/config");
4195
4054
  var import_log17 = require("@dxos/log");
4196
4055
  var import_messaging3 = require("@dxos/messaging");
4197
- var import_network_manager6 = require("@dxos/network-manager");
4056
+ var import_network_manager5 = require("@dxos/network-manager");
4198
4057
  var fromHost = (config = new import_config2.Config()) => {
4199
4058
  return new LocalClientServices({
4200
4059
  config,
@@ -4206,10 +4065,10 @@ var createNetworkManager = (config, options = {}) => {
4206
4065
  if (signalServer) {
4207
4066
  const { log: log1 = true, signalManager = new import_messaging3.WebsocketSignalManager([
4208
4067
  signalServer
4209
- ]), transportFactory = (0, import_network_manager6.createWebRTCTransportFactory)({
4068
+ ]), transportFactory = (0, import_network_manager5.createWebRTCTransportFactory)({
4210
4069
  iceServers: config.get("runtime.services.ice")
4211
4070
  }) } = options;
4212
- return new import_network_manager6.NetworkManager({
4071
+ return new import_network_manager5.NetworkManager({
4213
4072
  log: log1,
4214
4073
  signalManager,
4215
4074
  transportFactory
@@ -4221,17 +4080,15 @@ var createNetworkManager = (config, options = {}) => {
4221
4080
  scope: void 0,
4222
4081
  callSite: (f, a) => f(...a)
4223
4082
  });
4224
- return new import_network_manager6.NetworkManager({
4083
+ return new import_network_manager5.NetworkManager({
4225
4084
  signalManager: new import_messaging3.MemorySignalManager(new import_messaging3.MemorySignalManagerContext()),
4226
- transportFactory: import_network_manager6.MemoryTransportFactory
4085
+ transportFactory: import_network_manager5.MemoryTransportFactory
4227
4086
  });
4228
4087
  };
4229
4088
  // Annotate the CommonJS export names for ESM import in node:
4230
4089
  0 && (module.exports = {
4231
- AbstractInvitationsService,
4232
4090
  ClientServicesHost,
4233
- DeviceInvitationsHandler,
4234
- DeviceInvitationsServiceImpl,
4091
+ DeviceInvitationProtocol,
4235
4092
  DevtoolsHostEvents,
4236
4093
  DevtoolsServiceImpl,
4237
4094
  IFrameHostRuntime,
@@ -4239,13 +4096,14 @@ var createNetworkManager = (config, options = {}) => {
4239
4096
  Identity,
4240
4097
  IdentityManager,
4241
4098
  IdentityServiceImpl,
4099
+ InvitationsHandler,
4100
+ InvitationsServiceImpl,
4242
4101
  LocalClientServices,
4243
4102
  MemoryShellRuntime,
4244
4103
  ServiceContext,
4245
4104
  ServiceRegistry,
4246
4105
  ShellRuntimeImpl,
4247
- SpaceInvitationsHandler,
4248
- SpaceInvitationsServiceImpl,
4106
+ SpaceInvitationProtocol,
4249
4107
  TrustedKeySetAuthVerifier,
4250
4108
  VaultResourceLock,
4251
4109
  WorkerRuntime,