@dxos/client-services 0.1.22 → 0.1.24-next.6b1f434

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 (129) hide show
  1. package/dist/lib/browser/chunk-ZPZBLOQW.mjs +4086 -0
  2. package/dist/lib/browser/chunk-ZPZBLOQW.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +68 -3027
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/packlets/testing/index.mjs +198 -0
  7. package/dist/lib/browser/packlets/testing/index.mjs.map +7 -0
  8. package/dist/lib/node/index.cjs +1694 -667
  9. package/dist/lib/node/index.cjs.map +4 -4
  10. package/dist/lib/node/meta.json +1 -1
  11. package/dist/lib/node/packlets/testing/index.cjs +3806 -0
  12. package/dist/lib/node/packlets/testing/index.cjs.map +7 -0
  13. package/dist/types/src/packlets/deprecated/profile.d.ts +3 -1
  14. package/dist/types/src/packlets/deprecated/profile.d.ts.map +1 -1
  15. package/dist/types/src/packlets/deprecated/space.d.ts.map +1 -1
  16. package/dist/types/src/packlets/deprecated/system.d.ts +15 -9
  17. package/dist/types/src/packlets/deprecated/system.d.ts.map +1 -1
  18. package/dist/types/src/packlets/devtools/devtools.d.ts +2 -2
  19. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  20. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  21. package/dist/types/src/packlets/devtools/network.d.ts +3 -3
  22. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  23. package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
  24. package/dist/types/src/packlets/identity/authenticator.d.ts +9 -9
  25. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  26. package/dist/types/src/packlets/identity/identity-manager.d.ts +8 -2
  27. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  28. package/dist/types/src/packlets/identity/identity.d.ts +5 -4
  29. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  30. package/dist/types/src/packlets/invitations/halo-invitations-handler.d.ts +11 -3
  31. package/dist/types/src/packlets/invitations/halo-invitations-handler.d.ts.map +1 -1
  32. package/dist/types/src/packlets/invitations/invitations.d.ts +1 -1
  33. package/dist/types/src/packlets/invitations/invitations.d.ts.map +1 -1
  34. package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts +1 -1
  35. package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts.map +1 -1
  36. package/dist/types/src/packlets/services/service-context.d.ts +3 -1
  37. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  38. package/dist/types/src/packlets/services/service-context.test.d.ts +2 -0
  39. package/dist/types/src/packlets/services/service-context.test.d.ts.map +1 -0
  40. package/dist/types/src/packlets/services/service-definitions.d.ts +1 -1
  41. package/dist/types/src/packlets/services/service-definitions.d.ts.map +1 -1
  42. package/dist/types/src/packlets/services/service-host.d.ts +9 -6
  43. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  44. package/dist/types/src/packlets/services/service-registry.d.ts +4 -3
  45. package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
  46. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +9 -2
  47. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  48. package/dist/types/src/packlets/spaces/data-space-manager.test.d.ts +2 -0
  49. package/dist/types/src/packlets/spaces/data-space-manager.test.d.ts.map +1 -0
  50. package/dist/types/src/packlets/spaces/data-space.d.ts +20 -4
  51. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  52. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +50 -0
  53. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -0
  54. package/dist/types/src/packlets/spaces/notarization-plugin.test.d.ts +2 -0
  55. package/dist/types/src/packlets/spaces/notarization-plugin.test.d.ts.map +1 -0
  56. package/dist/types/src/packlets/spaces/spaces-service.d.ts +3 -2
  57. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  58. package/dist/types/src/packlets/testing/credential-utils.d.ts +8 -0
  59. package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -0
  60. package/dist/types/src/packlets/testing/index.d.ts +2 -0
  61. package/dist/types/src/packlets/testing/index.d.ts.map +1 -1
  62. package/dist/types/src/packlets/testing/invitation-utils.d.ts +3 -0
  63. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -0
  64. package/dist/types/src/packlets/testing/test-builder.d.ts +31 -2
  65. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  66. package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts +35 -0
  67. package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts.map +1 -0
  68. package/dist/types/src/packlets/vault/{iframe-runtime.d.ts → iframe-proxy-runtime.d.ts} +9 -4
  69. package/dist/types/src/packlets/vault/iframe-proxy-runtime.d.ts.map +1 -0
  70. package/dist/types/src/packlets/vault/index.d.ts +6 -1
  71. package/dist/types/src/packlets/vault/index.d.ts.map +1 -1
  72. package/dist/types/src/packlets/vault/services.d.ts +9 -1
  73. package/dist/types/src/packlets/vault/services.d.ts.map +1 -1
  74. package/dist/types/src/packlets/vault/shell-controller.d.ts +24 -0
  75. package/dist/types/src/packlets/vault/shell-controller.d.ts.map +1 -0
  76. package/dist/types/src/packlets/vault/shell-runtime.d.ts +45 -0
  77. package/dist/types/src/packlets/vault/shell-runtime.d.ts.map +1 -0
  78. package/dist/types/src/packlets/vault/vault-resource-lock.d.ts +19 -0
  79. package/dist/types/src/packlets/vault/vault-resource-lock.d.ts.map +1 -0
  80. package/dist/types/src/packlets/vault/worker-runtime.d.ts +2 -1
  81. package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
  82. package/dist/types/src/packlets/vault/worker-session.d.ts +7 -4
  83. package/dist/types/src/packlets/vault/worker-session.d.ts.map +1 -1
  84. package/package.json +30 -29
  85. package/src/packlets/deprecated/profile.ts +20 -2
  86. package/src/packlets/deprecated/space.ts +41 -37
  87. package/src/packlets/deprecated/system.ts +26 -13
  88. package/src/packlets/devtools/devtools.ts +4 -4
  89. package/src/packlets/devtools/feeds.ts +11 -6
  90. package/src/packlets/devtools/network.ts +20 -9
  91. package/src/packlets/devtools/spaces.ts +8 -7
  92. package/src/packlets/identity/authenticator.test.ts +4 -4
  93. package/src/packlets/identity/authenticator.ts +27 -17
  94. package/src/packlets/identity/identity-manager.test.ts +25 -16
  95. package/src/packlets/identity/identity-manager.ts +25 -13
  96. package/src/packlets/identity/identity.test.ts +22 -23
  97. package/src/packlets/identity/identity.ts +15 -10
  98. package/src/packlets/invitations/halo-invitations-handler.test.ts +4 -45
  99. package/src/packlets/invitations/halo-invitations-handler.ts +33 -17
  100. package/src/packlets/invitations/invitations.ts +2 -1
  101. package/src/packlets/invitations/space-invitations-handler.test.ts +43 -26
  102. package/src/packlets/invitations/space-invitations-handler.ts +9 -12
  103. package/src/packlets/services/service-context.test.ts +56 -0
  104. package/src/packlets/services/service-context.ts +62 -10
  105. package/src/packlets/services/service-definitions.ts +1 -1
  106. package/src/packlets/services/service-host.test.ts +74 -5
  107. package/src/packlets/services/service-host.ts +86 -24
  108. package/src/packlets/services/service-registry.test.ts +2 -1
  109. package/src/packlets/services/service-registry.ts +5 -1
  110. package/src/packlets/spaces/data-space-manager.test.ts +131 -0
  111. package/src/packlets/spaces/data-space-manager.ts +61 -15
  112. package/src/packlets/spaces/data-space.ts +125 -14
  113. package/src/packlets/spaces/notarization-plugin.test.ts +81 -0
  114. package/src/packlets/spaces/notarization-plugin.ts +211 -0
  115. package/src/packlets/spaces/spaces-service.ts +10 -2
  116. package/src/packlets/testing/credential-utils.ts +28 -0
  117. package/src/packlets/testing/index.ts +2 -0
  118. package/src/packlets/testing/invitation-utils.ts +44 -0
  119. package/src/packlets/testing/test-builder.ts +96 -14
  120. package/src/packlets/vault/iframe-host-runtime.ts +131 -0
  121. package/src/packlets/vault/{iframe-runtime.ts → iframe-proxy-runtime.ts} +18 -3
  122. package/src/packlets/vault/index.ts +6 -1
  123. package/src/packlets/vault/services.ts +17 -1
  124. package/src/packlets/vault/shell-controller.ts +77 -0
  125. package/src/packlets/vault/shell-runtime.ts +133 -0
  126. package/src/packlets/vault/vault-resource-lock.ts +76 -0
  127. package/src/packlets/vault/worker-runtime.ts +16 -4
  128. package/src/packlets/vault/worker-session.ts +36 -26
  129. package/dist/types/src/packlets/vault/iframe-runtime.d.ts.map +0 -1
@@ -39,47 +39,55 @@ __export(src_exports, {
39
39
  ClientServicesProxy: () => ClientServicesProxy,
40
40
  DevtoolsHostEvents: () => DevtoolsHostEvents,
41
41
  DevtoolsServiceImpl: () => DevtoolsServiceImpl,
42
- HaloAuthVerifier: () => HaloAuthVerifier,
43
42
  HaloInvitationsHandler: () => HaloInvitationsHandler,
44
43
  HaloInvitationsProxy: () => HaloInvitationsProxy,
45
44
  HaloInvitationsServiceImpl: () => HaloInvitationsServiceImpl,
46
- IFrameRuntime: () => IFrameRuntime,
45
+ IFrameHostRuntime: () => IFrameHostRuntime,
46
+ IFrameProxyRuntime: () => IFrameProxyRuntime,
47
47
  INVITATION_TIMEOUT: () => INVITATION_TIMEOUT,
48
48
  Identity: () => Identity,
49
49
  IdentityManager: () => IdentityManager,
50
50
  InvitationEncoder: () => InvitationEncoder,
51
51
  InvitationObservableProvider: () => InvitationObservableProvider,
52
+ MemoryShellRuntime: () => MemoryShellRuntime,
52
53
  ON_CLOSE_DELAY: () => ON_CLOSE_DELAY,
53
54
  ProfileServiceImpl: () => ProfileServiceImpl,
54
55
  ServiceContext: () => ServiceContext,
55
56
  ServiceRegistry: () => ServiceRegistry,
57
+ ShellController: () => ShellController,
58
+ ShellRuntimeImpl: () => ShellRuntimeImpl,
56
59
  SpaceInvitationsHandler: () => SpaceInvitationsHandler,
57
60
  SpaceInvitationsProxy: () => SpaceInvitationsProxy,
58
61
  SpaceInvitationsServiceImpl: () => SpaceInvitationsServiceImpl,
59
62
  SpaceServiceImpl: () => SpaceServiceImpl,
60
63
  SystemServiceImpl: () => SystemServiceImpl,
61
64
  TracingServiceImpl: () => TracingServiceImpl,
65
+ TrustedKeySetAuthVerifier: () => TrustedKeySetAuthVerifier,
66
+ VaultResourceLock: () => VaultResourceLock,
62
67
  WorkerRuntime: () => WorkerRuntime,
63
68
  WorkerSession: () => WorkerSession,
69
+ appServiceBundle: () => appServiceBundle,
64
70
  clientServiceBundle: () => clientServiceBundle,
71
+ createAuthProvider: () => createAuthProvider,
65
72
  createDefaultModelFactory: () => createDefaultModelFactory,
66
- createHaloAuthProvider: () => createHaloAuthProvider,
67
73
  createStorageObjects: () => createStorageObjects,
68
74
  getNetworkPeers: () => getNetworkPeers,
75
+ iframeServiceBundle: () => iframeServiceBundle,
76
+ shellServiceBundle: () => shellServiceBundle,
69
77
  subscribeToFeedBlocks: () => subscribeToFeedBlocks,
70
78
  subscribeToFeeds: () => subscribeToFeeds,
71
79
  subscribeToNetworkStatus: () => subscribeToNetworkStatus,
72
80
  subscribeToNetworkTopics: () => subscribeToNetworkTopics,
73
- subscribeToSignalTrace: () => subscribeToSignalTrace,
81
+ subscribeToSignal: () => subscribeToSignal,
74
82
  subscribeToSpaces: () => subscribeToSpaces,
75
83
  subscribeToSwarmInfo: () => subscribeToSwarmInfo,
84
+ workerServiceBundle: () => workerServiceBundle,
76
85
  wrapObservable: () => wrapObservable
77
86
  });
78
87
  module.exports = __toCommonJS(src_exports);
79
88
 
80
89
  // packages/sdk/client-services/src/packlets/deprecated/space.ts
81
90
  var import_node_assert = __toESM(require("node:assert"));
82
- var import_async = require("@dxos/async");
83
91
  var import_codec_protobuf = require("@dxos/codec-protobuf");
84
92
  var import_debug = require("@dxos/debug");
85
93
  var import_log = require("@dxos/log");
@@ -103,10 +111,9 @@ var SpaceServiceImpl = class {
103
111
  });
104
112
  }
105
113
  subscribeSpaces() {
106
- return new import_codec_protobuf.Stream(({ next }) => {
107
- const subscriptions = new import_async.EventSubscriptions();
114
+ return new import_codec_protobuf.Stream(({ next, ctx }) => {
108
115
  const onUpdate = () => {
109
- const spaces = Array.from(this.serviceContext.dataSpaceManager.spaces.values()).map((space) => ({
116
+ const spaces = Array.from(this.serviceContext.dataSpaceManager.spaces.values()).filter((space) => this.serviceContext.dataServiceSubscriptions.getDataService(space.key)).map((space) => ({
110
117
  publicKey: space.key,
111
118
  isOpen: true,
112
119
  isActive: true,
@@ -126,7 +133,7 @@ var SpaceServiceImpl = class {
126
133
  spaces
127
134
  }, {
128
135
  file: "space.ts",
129
- line: 120,
136
+ line: 119,
130
137
  scope: this,
131
138
  callSite: (f, a) => f(...a)
132
139
  });
@@ -141,26 +148,31 @@ var SpaceServiceImpl = class {
141
148
  });
142
149
  }
143
150
  await this.serviceContext.initialized.wait();
144
- subscriptions.add(this.serviceContext.dataSpaceManager.updated.on(() => {
145
- this.serviceContext.dataSpaceManager.spaces.forEach((space) => {
146
- subscriptions.add(space.stateUpdate.on(onUpdate));
147
- subscriptions.add(space.presence.updated.on(onUpdate));
148
- });
151
+ const subscribeSpaces = () => {
152
+ for (const space of this.serviceContext.dataSpaceManager.spaces.values()) {
153
+ if (!this.serviceContext.dataServiceSubscriptions.getDataService(space.key)) {
154
+ continue;
155
+ }
156
+ space.stateUpdate.on(ctx, onUpdate);
157
+ space.presence.updated.on(ctx, onUpdate);
158
+ }
159
+ };
160
+ this.serviceContext.dataSpaceManager.updated.on(ctx, () => {
161
+ subscribeSpaces();
149
162
  onUpdate();
150
- }));
151
- this.serviceContext.dataSpaceManager.spaces.forEach((space) => {
152
- subscriptions.add(space.stateUpdate.on(onUpdate));
153
- subscriptions.add(space.presence.updated.on(onUpdate));
154
163
  });
164
+ subscribeSpaces();
155
165
  onUpdate();
156
166
  });
157
- return () => subscriptions.clear();
158
167
  });
159
168
  }
160
169
  async getSpaceDetails(request) {
161
170
  return (0, import_debug.todo)();
162
171
  }
163
172
  async createSpace() {
173
+ if (!this.serviceContext.identityManager.identity) {
174
+ throw new Error("This device has no HALO identity available. See https://docs.dxos.org/guide/halo");
175
+ }
164
176
  await this.serviceContext.initialized.wait();
165
177
  const space = await this.serviceContext.dataSpaceManager.createSpace();
166
178
  return {
@@ -193,7 +205,9 @@ var SpaceServiceImpl = class {
193
205
  };
194
206
 
195
207
  // packages/sdk/client-services/src/packlets/deprecated/profile.ts
208
+ var import_node_assert2 = __toESM(require("node:assert"));
196
209
  var import_codec_protobuf2 = require("@dxos/codec-protobuf");
210
+ var import_credentials = require("@dxos/credentials");
197
211
  var import_debug2 = require("@dxos/debug");
198
212
  var ProfileServiceImpl = class {
199
213
  constructor(context) {
@@ -208,7 +222,8 @@ var ProfileServiceImpl = class {
208
222
  profile: this.context.identityManager.identity ? {
209
223
  identityKey: this.context.identityManager.identity.identityKey,
210
224
  deviceKey: this.context.identityManager.identity.deviceKey,
211
- displayName: (_a = this.context.identityManager.identity.profileDocument) == null ? void 0 : _a.displayName
225
+ displayName: (_a = this.context.identityManager.identity.profileDocument) == null ? void 0 : _a.displayName,
226
+ haloSpace: this.context.identityManager.identity.space.key
212
227
  } : void 0
213
228
  });
214
229
  };
@@ -224,7 +239,8 @@ var ProfileServiceImpl = class {
224
239
  return {
225
240
  identityKey: this.context.identityManager.identity.identityKey,
226
241
  deviceKey: this.context.identityManager.identity.deviceKey,
227
- displayName: (_a = this.context.identityManager.identity.profileDocument) == null ? void 0 : _a.displayName
242
+ displayName: (_a = this.context.identityManager.identity.profileDocument) == null ? void 0 : _a.displayName,
243
+ haloSpace: this.context.identityManager.identity.space.key
228
244
  };
229
245
  }
230
246
  async recoverProfile(request) {
@@ -233,28 +249,38 @@ var ProfileServiceImpl = class {
233
249
  throw new Error("Recovery SeedPhrase not provided.");
234
250
  }
235
251
  }
252
+ async signPresentation({ presentation, nonce }) {
253
+ (0, import_node_assert2.default)(this.context.identityManager.identity, "Identity not initialized.");
254
+ return await (0, import_credentials.signPresentation)({
255
+ presentation,
256
+ signer: this.context.keyring,
257
+ signerKey: this.context.identityManager.identity.deviceKey,
258
+ chain: this.context.identityManager.identity.deviceCredentialChain,
259
+ nonce
260
+ });
261
+ }
236
262
  };
237
263
 
238
264
  // packages/sdk/client-services/src/packlets/deprecated/system.ts
239
265
  var SystemServiceImpl = class {
240
- constructor(_config, _serviceContext) {
241
- this._config = _config;
242
- this._serviceContext = _serviceContext;
243
- }
244
- // TODO(burdon): Remove.
245
- async initSession() {
266
+ constructor({ config, onInit, onStatus, onReset }) {
267
+ this._config = config;
268
+ this._onInit = onInit;
269
+ this._onStatus = onStatus;
270
+ this._onReset = onReset;
246
271
  }
247
- async getConfig(request) {
272
+ async getConfig() {
248
273
  return this._config.values;
249
274
  }
250
275
  // TODO(burdon): Connect to iframe RPC heartbeat for network status?
251
- async getStatus(request) {
252
- return {
253
- message: `ok: ${Date.now()}`
254
- };
276
+ async getStatus() {
277
+ return this._onStatus();
278
+ }
279
+ async initSession() {
280
+ await this._onInit();
255
281
  }
256
- async reset(request) {
257
- await this._serviceContext.reset();
282
+ async reset() {
283
+ await this._onReset();
258
284
  }
259
285
  };
260
286
 
@@ -272,79 +298,83 @@ var TracingServiceImpl = class {
272
298
  };
273
299
 
274
300
  // packages/sdk/client-services/src/packlets/devtools/devtools.ts
275
- var import_async3 = require("@dxos/async");
301
+ var import_async2 = require("@dxos/async");
276
302
  var import_codec_protobuf7 = require("@dxos/codec-protobuf");
277
303
 
278
304
  // packages/sdk/client-services/src/packlets/devtools/feeds.ts
279
- var import_async2 = require("@dxos/async");
305
+ var import_async = require("@dxos/async");
280
306
  var import_codec_protobuf3 = require("@dxos/codec-protobuf");
281
307
  var import_feed_store = require("@dxos/feed-store");
282
308
  var import_keys = require("@dxos/keys");
283
309
  var import_util2 = require("@dxos/util");
284
- var subscribeToFeeds = ({ feedStore }, { feedKeys }) => new import_codec_protobuf3.Stream(({ next }) => {
285
- if ((feedKeys == null ? void 0 : feedKeys.length) === 0) {
286
- return;
287
- }
288
- const feedMap = new import_util2.ComplexMap(import_keys.PublicKey.hash);
289
- const subscriptions = new import_async2.EventSubscriptions();
290
- const update = () => {
291
- const feeds = feedStore.feeds;
292
- feeds.filter((feed) => !(feedKeys == null ? void 0 : feedKeys.length) || feedKeys.some((feedKey) => feedKey.equals(feed.key))).forEach((feed) => {
293
- if (!feedMap.has(feed.key)) {
294
- feedMap.set(feed.key, feed);
295
- feed.on("close", update);
296
- subscriptions.add(feed.off("close", update));
297
- }
298
- });
299
- next({
300
- feeds: Array.from(feedMap.values()).map((feed) => ({
301
- feedKey: feed.key,
302
- length: feed.properties.length
303
- }))
304
- });
305
- };
306
- subscriptions.add(feedStore.feedOpened.on(update));
307
- update();
308
- return () => {
309
- subscriptions.clear();
310
- };
311
- });
312
- var subscribeToFeedBlocks = ({ feedStore }, { feedKey, maxBlocks = 10 }) => new import_codec_protobuf3.Stream(({ next }) => {
313
- if (!feedKey) {
314
- return;
315
- }
316
- const subscriptions = new import_async2.EventSubscriptions();
317
- const timeout = setTimeout(async () => {
318
- const feed = feedStore.getFeed(feedKey);
319
- if (!feed) {
310
+ var subscribeToFeeds = ({ feedStore }, { feedKeys }) => {
311
+ return new import_codec_protobuf3.Stream(({ next }) => {
312
+ if ((feedKeys == null ? void 0 : feedKeys.length) === 0) {
320
313
  return;
321
314
  }
322
- const update = async () => {
323
- const iterator = new import_feed_store.FeedIterator(feed);
324
- await iterator.open();
325
- const blocks = [];
326
- for await (const block of iterator) {
327
- blocks.push(block);
328
- if (blocks.length >= feed.properties.length) {
329
- break;
315
+ const subscriptions = new import_async.EventSubscriptions();
316
+ const feedMap = new import_util2.ComplexMap(import_keys.PublicKey.hash);
317
+ const update = () => {
318
+ const { feeds } = feedStore;
319
+ feeds.filter((feed) => !(feedKeys == null ? void 0 : feedKeys.length) || feedKeys.some((feedKey) => feedKey.equals(feed.key))).forEach((feed) => {
320
+ if (!feedMap.has(feed.key)) {
321
+ feedMap.set(feed.key, feed);
322
+ feed.on("close", update);
323
+ subscriptions.add(feed.off("close", update));
330
324
  }
331
- }
325
+ });
332
326
  next({
333
- blocks: blocks.slice(-maxBlocks)
327
+ feeds: Array.from(feedMap.values()).map((feed) => ({
328
+ feedKey: feed.key,
329
+ length: feed.properties.length
330
+ }))
334
331
  });
335
- await iterator.close();
336
332
  };
337
- feed.on("append", update);
338
- subscriptions.add(() => feed.off("append", update));
339
- feed.on("truncate", update);
340
- subscriptions.add(() => feed.off("truncate", update));
341
- await update();
333
+ subscriptions.add(feedStore.feedOpened.on(update));
334
+ update();
335
+ return () => {
336
+ subscriptions.clear();
337
+ };
342
338
  });
343
- return () => {
344
- subscriptions.clear();
345
- clearTimeout(timeout);
346
- };
347
- });
339
+ };
340
+ var subscribeToFeedBlocks = ({ feedStore }, { feedKey, maxBlocks = 10 }) => {
341
+ return new import_codec_protobuf3.Stream(({ next }) => {
342
+ if (!feedKey) {
343
+ return;
344
+ }
345
+ const subscriptions = new import_async.EventSubscriptions();
346
+ const timeout = setTimeout(async () => {
347
+ const feed = feedStore.getFeed(feedKey);
348
+ if (!feed) {
349
+ return;
350
+ }
351
+ const update = async () => {
352
+ const iterator = new import_feed_store.FeedIterator(feed);
353
+ await iterator.open();
354
+ const blocks = [];
355
+ for await (const block of iterator) {
356
+ blocks.push(block);
357
+ if (blocks.length >= feed.properties.length) {
358
+ break;
359
+ }
360
+ }
361
+ next({
362
+ blocks: blocks.slice(-maxBlocks)
363
+ });
364
+ await iterator.close();
365
+ };
366
+ feed.on("append", update);
367
+ subscriptions.add(() => feed.off("append", update));
368
+ feed.on("truncate", update);
369
+ subscriptions.add(() => feed.off("truncate", update));
370
+ await update();
371
+ });
372
+ return () => {
373
+ subscriptions.clear();
374
+ clearTimeout(timeout);
375
+ };
376
+ });
377
+ };
348
378
 
349
379
  // packages/sdk/client-services/src/packlets/devtools/keys.ts
350
380
  var import_codec_protobuf4 = require("@dxos/codec-protobuf");
@@ -361,6 +391,7 @@ var subscribeToKeyringKeys = ({ keyring }) => new import_codec_protobuf4.Stream(
361
391
 
362
392
  // packages/sdk/client-services/src/packlets/devtools/network.ts
363
393
  var import_codec_protobuf5 = require("@dxos/codec-protobuf");
394
+ var import_context = require("@dxos/context");
364
395
  var import_keys2 = require("@dxos/keys");
365
396
  var subscribeToNetworkStatus = ({ networkManager }) => new import_codec_protobuf5.Stream(({ next, close }) => {
366
397
  const update = () => {
@@ -376,17 +407,27 @@ var subscribeToNetworkStatus = ({ networkManager }) => new import_codec_protobuf
376
407
  networkManager.signalManager.statusChanged.on(update);
377
408
  update();
378
409
  });
379
- var subscribeToSignalTrace = ({ networkManager }) => new import_codec_protobuf5.Stream(({ next }) => {
380
- next({
381
- events: []
410
+ var subscribeToSignal = ({ networkManager }) => new import_codec_protobuf5.Stream(({ next }) => {
411
+ const ctx = new import_context.Context();
412
+ networkManager.signalManager.onMessage.on(ctx, (message) => {
413
+ next({
414
+ message: {
415
+ author: message.author.asUint8Array(),
416
+ recipient: message.recipient.asUint8Array(),
417
+ payload: message.payload
418
+ },
419
+ receivedAt: new Date()
420
+ });
382
421
  });
383
- const trace = [];
384
- networkManager.signalManager.commandTrace.on((msg) => {
385
- trace.push(msg);
422
+ networkManager.signalManager.swarmEvent.on(ctx, (swarmEvent) => {
386
423
  next({
387
- events: trace.map((msg2) => JSON.stringify(msg2))
424
+ swarmEvent: swarmEvent.swarmEvent,
425
+ receivedAt: new Date()
388
426
  });
389
427
  });
428
+ return () => {
429
+ return ctx.dispose();
430
+ };
390
431
  });
391
432
  var subscribeToNetworkTopics = ({ networkManager }) => new import_codec_protobuf5.Stream(({ next, close }) => {
392
433
  const update = () => {
@@ -438,42 +479,44 @@ var getNetworkPeers = ({ networkManager }, request) => {
438
479
 
439
480
  // packages/sdk/client-services/src/packlets/devtools/spaces.ts
440
481
  var import_codec_protobuf6 = require("@dxos/codec-protobuf");
441
- var subscribeToSpaces = (context, { spaceKeys = [] }) => new import_codec_protobuf6.Stream(({ next }) => {
442
- let unsubscribe;
443
- const update = async () => {
444
- const spaces = [
445
- ...context.spaceManager.spaces.values()
446
- ];
447
- const filteredSpaces = spaces.filter((space) => !(spaceKeys == null ? void 0 : spaceKeys.length) || spaceKeys.some((spaceKey) => spaceKey.equals(space.key)));
448
- next({
449
- spaces: filteredSpaces.map((space) => {
450
- const spaceMetadata = context.metadataStore.spaces.find((spaceMetadata2) => spaceMetadata2.key.equals(space.key));
451
- return {
452
- key: space.key,
453
- isOpen: space.isOpen,
454
- timeframe: spaceMetadata == null ? void 0 : spaceMetadata.latestTimeframe,
455
- genesisFeed: space.genesisFeedKey,
456
- controlFeed: space.controlFeedKey,
457
- dataFeed: space.dataFeedKey
458
- };
459
- })
482
+ var subscribeToSpaces = (context, { spaceKeys = [] }) => {
483
+ return new import_codec_protobuf6.Stream(({ next }) => {
484
+ let unsubscribe;
485
+ const update = async () => {
486
+ const spaces = [
487
+ ...context.spaceManager.spaces.values()
488
+ ];
489
+ const filteredSpaces = spaces.filter((space) => !(spaceKeys == null ? void 0 : spaceKeys.length) || spaceKeys.some((spaceKey) => spaceKey.equals(space.key)));
490
+ next({
491
+ spaces: filteredSpaces.map((space) => {
492
+ const spaceMetadata = context.metadataStore.spaces.find((spaceMetadata2) => spaceMetadata2.key.equals(space.key));
493
+ return {
494
+ key: space.key,
495
+ isOpen: space.isOpen,
496
+ timeframe: spaceMetadata == null ? void 0 : spaceMetadata.dataTimeframe,
497
+ genesisFeed: space.genesisFeedKey,
498
+ controlFeed: space.controlFeedKey,
499
+ dataFeed: space.dataFeedKey
500
+ };
501
+ })
502
+ });
503
+ };
504
+ const timeout = setTimeout(async () => {
505
+ await context.initialized.wait();
506
+ unsubscribe = context.dataSpaceManager.updated.on(() => update());
507
+ await update();
460
508
  });
461
- };
462
- const timeout = setTimeout(async () => {
463
- await context.initialized.wait();
464
- unsubscribe = context.dataSpaceManager.updated.on(() => update());
465
- await update();
509
+ return () => {
510
+ unsubscribe == null ? void 0 : unsubscribe();
511
+ clearTimeout(timeout);
512
+ };
466
513
  });
467
- return () => {
468
- unsubscribe == null ? void 0 : unsubscribe();
469
- clearTimeout(timeout);
470
- };
471
- });
514
+ };
472
515
 
473
516
  // packages/sdk/client-services/src/packlets/devtools/devtools.ts
474
517
  var DevtoolsHostEvents = class {
475
518
  constructor() {
476
- this.ready = new import_async3.Event();
519
+ this.ready = new import_async2.Event();
477
520
  }
478
521
  };
479
522
  var DevtoolsServiceImpl = class {
@@ -545,8 +588,8 @@ var DevtoolsServiceImpl = class {
545
588
  networkManager: this.params.context.networkManager
546
589
  });
547
590
  }
548
- subscribeToSignalTrace() {
549
- return subscribeToSignalTrace({
591
+ subscribeToSignal() {
592
+ return subscribeToSignal({
550
593
  networkManager: this.params.context.networkManager
551
594
  });
552
595
  }
@@ -558,12 +601,12 @@ var DevtoolsServiceImpl = class {
558
601
  };
559
602
 
560
603
  // packages/sdk/client-services/src/packlets/identity/authenticator.ts
561
- var import_async4 = require("@dxos/async");
562
- var import_context = require("@dxos/context");
563
- var import_credentials = require("@dxos/credentials");
604
+ var import_async3 = require("@dxos/async");
605
+ var import_context2 = require("@dxos/context");
606
+ var import_credentials2 = require("@dxos/credentials");
564
607
  var import_log2 = require("@dxos/log");
565
608
  var import_protocols = require("@dxos/protocols");
566
- var createHaloAuthProvider = (signer) => async (nonce) => {
609
+ var createAuthProvider = (signer) => async (nonce) => {
567
610
  const credential = await signer.createCredential({
568
611
  assertion: {
569
612
  "@type": "dxos.halo.credentials.Auth"
@@ -573,22 +616,27 @@ var createHaloAuthProvider = (signer) => async (nonce) => {
573
616
  });
574
617
  return import_protocols.schema.getCodecForType("dxos.halo.credentials.Credential").encode(credential);
575
618
  };
576
- var HaloAuthVerifier = class {
619
+ var TrustedKeySetAuthVerifier = class {
620
+ // prettier-ignore
577
621
  constructor(_params) {
578
622
  this._params = _params;
579
- this._ctx = new import_context.Context();
623
+ this._ctx = new import_context2.Context();
580
624
  }
581
625
  async close() {
582
626
  await this._ctx.dispose();
583
627
  }
584
- _isTrustedDevice(deviceKey) {
585
- const deviceSet = this._params.trustedDevicesProvider();
586
- return deviceSet.has(deviceKey);
587
- }
588
628
  get verifier() {
589
629
  return async (nonce, auth) => {
590
630
  const credential = import_protocols.schema.getCodecForType("dxos.halo.credentials.Credential").decode(auth);
591
- const result = await (0, import_credentials.verifyCredential)(credential);
631
+ (0, import_log2.log)("authenticating...", {
632
+ credential
633
+ }, {
634
+ file: "authenticator.ts",
635
+ line: 57,
636
+ scope: this,
637
+ callSite: (f, a) => f(...a)
638
+ });
639
+ const result = await (0, import_credentials2.verifyCredential)(credential);
592
640
  if (result.kind === "fail") {
593
641
  (0, import_log2.log)("Invalid credential", {
594
642
  result
@@ -612,23 +660,47 @@ var HaloAuthVerifier = class {
612
660
  });
613
661
  return false;
614
662
  }
615
- if (this._isTrustedDevice(credential.issuer)) {
663
+ if (this._isTrustedKey(credential.issuer)) {
664
+ (0, import_log2.log)("key is not currently in trusted set, waiting...", {
665
+ key: credential.issuer
666
+ }, {
667
+ file: "authenticator.ts",
668
+ line: 71,
669
+ scope: this,
670
+ callSite: (f, a) => f(...a)
671
+ });
616
672
  return true;
617
673
  }
618
- const trigger = new import_async4.Trigger();
674
+ const trigger = new import_async3.Trigger();
619
675
  this._ctx.onDispose(() => {
620
676
  trigger.wake(false);
621
677
  });
622
678
  const clear = this._params.update.on(this._ctx, () => {
623
- if (this._isTrustedDevice(credential.issuer)) {
679
+ if (this._isTrustedKey(credential.issuer)) {
680
+ (0, import_log2.log)("auth success", {
681
+ key: credential.issuer
682
+ }, {
683
+ file: "authenticator.ts",
684
+ line: 82,
685
+ scope: this,
686
+ callSite: (f, a) => f(...a)
687
+ });
624
688
  trigger.wake(true);
689
+ } else {
690
+ (0, import_log2.log)("key is not currently in trusted set, waiting...", {
691
+ key: credential.issuer
692
+ }, {
693
+ file: "authenticator.ts",
694
+ line: 85,
695
+ scope: this,
696
+ callSite: (f, a) => f(...a)
697
+ });
625
698
  }
626
699
  });
627
700
  try {
628
- await trigger.wait({
701
+ return await trigger.wait({
629
702
  timeout: this._params.authTimeout
630
703
  });
631
- return true;
632
704
  } catch (e) {
633
705
  return false;
634
706
  } finally {
@@ -636,34 +708,39 @@ var HaloAuthVerifier = class {
636
708
  }
637
709
  };
638
710
  }
711
+ _isTrustedKey(deviceKey) {
712
+ const deviceSet = this._params.trustedKeysProvider();
713
+ return deviceSet.has(deviceKey);
714
+ }
639
715
  };
640
716
 
641
717
  // packages/sdk/client-services/src/packlets/identity/identity.ts
642
- var import_node_assert2 = __toESM(require("node:assert"));
643
- var import_async5 = require("@dxos/async");
644
- var import_credentials2 = require("@dxos/credentials");
718
+ var import_node_assert3 = __toESM(require("node:assert"));
719
+ var import_async4 = require("@dxos/async");
720
+ var import_credentials3 = require("@dxos/credentials");
721
+ var import_debug3 = require("@dxos/debug");
645
722
  var import_feed_store2 = require("@dxos/feed-store");
646
723
  var import_log3 = require("@dxos/log");
647
- var import_credentials3 = require("@dxos/protocols/proto/dxos/halo/credentials");
724
+ var import_credentials4 = require("@dxos/protocols/proto/dxos/halo/credentials");
648
725
  var AUTH_TIMEOUT = 3e4;
649
726
  var Identity = class {
650
727
  constructor({ space, signer, identityKey, deviceKey }) {
651
- this.stateUpdate = new import_async5.Event();
728
+ this.stateUpdate = new import_async4.Event();
652
729
  this.space = space;
653
730
  this._signer = signer;
654
731
  this.identityKey = identityKey;
655
732
  this.deviceKey = deviceKey;
656
- this._deviceStateMachine = this.space.spaceState.registerProcessor(new import_credentials2.DeviceStateMachine({
733
+ this._deviceStateMachine = this.space.spaceState.registerProcessor(new import_credentials3.DeviceStateMachine({
657
734
  identityKey: this.identityKey,
658
735
  deviceKey: this.deviceKey,
659
736
  onUpdate: () => this.stateUpdate.emit()
660
737
  }));
661
- this._profileStateMachine = this.space.spaceState.registerProcessor(new import_credentials2.ProfileStateMachine({
738
+ this._profileStateMachine = this.space.spaceState.registerProcessor(new import_credentials3.ProfileStateMachine({
662
739
  identityKey: this.identityKey,
663
740
  onUpdate: () => this.stateUpdate.emit()
664
741
  }));
665
- this.authVerifier = new HaloAuthVerifier({
666
- trustedDevicesProvider: () => this.authorizedDeviceKeys,
742
+ this.authVerifier = new TrustedKeySetAuthVerifier({
743
+ trustedKeysProvider: () => this.authorizedDeviceKeys,
667
744
  update: this.stateUpdate,
668
745
  authTimeout: AUTH_TIMEOUT
669
746
  });
@@ -685,6 +762,9 @@ var Identity = class {
685
762
  }
686
763
  async ready() {
687
764
  await this._deviceStateMachine.processor.deviceChainReady.wait();
765
+ await this.controlPipeline.state.waitUntilReachedTargetTimeframe({
766
+ timeout: 3e3
767
+ });
688
768
  }
689
769
  get profileDocument() {
690
770
  return this._profileStateMachine.processor.profile;
@@ -701,11 +781,15 @@ var Identity = class {
701
781
  get haloGenesisFeedKey() {
702
782
  return this.space.genesisFeedKey;
703
783
  }
784
+ get deviceCredentialChain() {
785
+ return this._deviceStateMachine.processor.deviceCredentialChain;
786
+ }
704
787
  getAdmissionCredentials() {
788
+ var _a, _b;
705
789
  return {
706
790
  deviceKey: this.deviceKey,
707
- controlFeedKey: this.space.controlFeedKey,
708
- dataFeedKey: this.space.dataFeedKey
791
+ controlFeedKey: (_a = this.space.controlFeedKey) != null ? _a : (0, import_debug3.failUndefined)(),
792
+ dataFeedKey: (_b = this.space.dataFeedKey) != null ? _b : (0, import_debug3.failUndefined)()
709
793
  };
710
794
  }
711
795
  /**
@@ -713,14 +797,14 @@ var Identity = class {
713
797
  * Requires identity to be ready.
714
798
  */
715
799
  getIdentityCredentialSigner() {
716
- (0, import_node_assert2.default)(this._deviceStateMachine.processor.deviceCredentialChain, "Device credential chain is not ready.");
717
- return (0, import_credentials2.createCredentialSignerWithChain)(this._signer, this._deviceStateMachine.processor.deviceCredentialChain, this.deviceKey);
800
+ (0, import_node_assert3.default)(this._deviceStateMachine.processor.deviceCredentialChain, "Device credential chain is not ready.");
801
+ return (0, import_credentials3.createCredentialSignerWithChain)(this._signer, this._deviceStateMachine.processor.deviceCredentialChain, this.deviceKey);
718
802
  }
719
803
  /**
720
804
  * Issues credentials as device.
721
805
  */
722
806
  getDeviceCredentialSigner() {
723
- return (0, import_credentials2.createCredentialSignerWithKey)(this._signer, this.deviceKey);
807
+ return (0, import_credentials3.createCredentialSignerWithKey)(this._signer, this.deviceKey);
724
808
  }
725
809
  async admitDevice({ deviceKey, controlFeedKey, dataFeedKey }) {
726
810
  (0, import_log3.log)("Admitting device:", {
@@ -731,7 +815,7 @@ var Identity = class {
731
815
  dataFeedKey
732
816
  }, {
733
817
  file: "identity.ts",
734
- line: 155,
818
+ line: 160,
735
819
  scope: this,
736
820
  callSite: (f, a) => f(...a)
737
821
  });
@@ -752,7 +836,7 @@ var Identity = class {
752
836
  spaceKey: this.haloSpaceKey,
753
837
  deviceKey,
754
838
  identityKey: this.identityKey,
755
- designation: import_credentials3.AdmittedFeed.Designation.CONTROL
839
+ designation: import_credentials4.AdmittedFeed.Designation.CONTROL
756
840
  }
757
841
  }),
758
842
  await signer.createCredential({
@@ -762,31 +846,33 @@ var Identity = class {
762
846
  spaceKey: this.haloSpaceKey,
763
847
  deviceKey,
764
848
  identityKey: this.identityKey,
765
- designation: import_credentials3.AdmittedFeed.Designation.DATA
849
+ designation: import_credentials4.AdmittedFeed.Designation.DATA
766
850
  }
767
851
  })
768
852
  ].map((credential) => ({
769
- "@type": "dxos.echo.feed.CredentialsMessage",
770
- credential
853
+ credential: {
854
+ credential
855
+ }
771
856
  })));
772
857
  }
773
858
  };
774
859
 
775
860
  // packages/sdk/client-services/src/packlets/identity/identity-manager.ts
776
- var import_node_assert3 = __toESM(require("node:assert"));
777
- var import_async6 = require("@dxos/async");
778
- var import_credentials4 = require("@dxos/credentials");
861
+ var import_node_assert4 = __toESM(require("node:assert"));
862
+ var import_async5 = require("@dxos/async");
863
+ var import_credentials5 = require("@dxos/credentials");
779
864
  var import_log4 = require("@dxos/log");
780
- var import_credentials5 = require("@dxos/protocols/proto/dxos/halo/credentials");
865
+ var import_credentials6 = require("@dxos/protocols/proto/dxos/halo/credentials");
781
866
  var import_util3 = require("@dxos/util");
782
867
  var IdentityManager = class {
783
868
  // TODO(burdon): IdentityManagerParams.
784
869
  // TODO(dmaretskyi): Perhaps this should take/generate the peerKey outside of an initialized identity.
785
- constructor(_metadataStore, _keyring, _spaceManager) {
870
+ constructor(_metadataStore, _keyring, _feedStore, _spaceManager) {
786
871
  this._metadataStore = _metadataStore;
787
872
  this._keyring = _keyring;
873
+ this._feedStore = _feedStore;
788
874
  this._spaceManager = _spaceManager;
789
- this.stateUpdate = new import_async6.Event();
875
+ this.stateUpdate = new import_async5.Event();
790
876
  }
791
877
  get identity() {
792
878
  return this._identity;
@@ -798,7 +884,7 @@ var IdentityManager = class {
798
884
  identityRecord
799
885
  }, {
800
886
  file: "identity-manager.ts",
801
- line: 57,
887
+ line: 63,
802
888
  scope: this,
803
889
  callSite: (f, a) => f(...a)
804
890
  });
@@ -814,10 +900,10 @@ var IdentityManager = class {
814
900
  await ((_a = this._identity) == null ? void 0 : _a.close());
815
901
  }
816
902
  async createIdentity({ displayName } = {}) {
817
- (0, import_node_assert3.default)(!this._identity, "Identity already exists.");
903
+ (0, import_node_assert4.default)(!this._identity, "Identity already exists.");
818
904
  (0, import_log4.log)("creating identity...", {}, {
819
905
  file: "identity-manager.ts",
820
- line: 72,
906
+ line: 78,
821
907
  scope: this,
822
908
  callSite: (f, a) => f(...a)
823
909
  });
@@ -835,12 +921,12 @@ var IdentityManager = class {
835
921
  const identity = await this._constructIdentity(identityRecord);
836
922
  await identity.open();
837
923
  {
838
- const generator = new import_credentials4.CredentialGenerator(this._keyring, identityRecord.identityKey, identityRecord.deviceKey);
924
+ const generator = new import_credentials5.CredentialGenerator(this._keyring, identityRecord.identityKey, identityRecord.deviceKey);
839
925
  const credentials = [
840
926
  // Space genesis.
841
927
  ...await generator.createSpaceGenesis(identityRecord.haloSpace.spaceKey, identityRecord.haloSpace.genesisFeedKey),
842
928
  // Feed admission.
843
- await generator.createFeedAdmission(identityRecord.haloSpace.spaceKey, identityRecord.haloSpace.writeDataFeedKey, import_credentials5.AdmittedFeed.Designation.DATA)
929
+ await generator.createFeedAdmission(identityRecord.haloSpace.spaceKey, identityRecord.haloSpace.writeDataFeedKey, import_credentials6.AdmittedFeed.Designation.DATA)
844
930
  ];
845
931
  if (displayName) {
846
932
  credentials.push(await generator.createProfileCredential({
@@ -850,8 +936,9 @@ var IdentityManager = class {
850
936
  credentials.push(await generator.createDeviceAuthorization(identityRecord.deviceKey));
851
937
  for (const credential of credentials) {
852
938
  await identity.controlPipeline.writer.write({
853
- "@type": "dxos.echo.feed.CredentialsMessage",
854
- credential
939
+ credential: {
940
+ credential
941
+ }
855
942
  });
856
943
  }
857
944
  }
@@ -864,7 +951,7 @@ var IdentityManager = class {
864
951
  deviceKey: identity.deviceKey
865
952
  }, {
866
953
  file: "identity-manager.ts",
867
- line: 131,
954
+ line: 136,
868
955
  scope: this,
869
956
  callSite: (f, a) => f(...a)
870
957
  });
@@ -878,47 +965,65 @@ var IdentityManager = class {
878
965
  params
879
966
  }, {
880
967
  file: "identity-manager.ts",
881
- line: 139,
968
+ line: 144,
882
969
  scope: this,
883
970
  callSite: (f, a) => f(...a)
884
971
  });
885
- (0, import_node_assert3.default)(!this._identity, "Identity already exists.");
972
+ (0, import_node_assert4.default)(!this._identity, "Identity already exists.");
886
973
  const identityRecord = {
887
974
  identityKey: params.identityKey,
888
- deviceKey: await this._keyring.createKey(),
975
+ deviceKey: params.deviceKey,
889
976
  haloSpace: {
890
977
  spaceKey: params.haloSpaceKey,
891
978
  genesisFeedKey: params.haloGenesisFeedKey,
892
- writeControlFeedKey: await this._keyring.createKey(),
893
- writeDataFeedKey: await this._keyring.createKey()
979
+ writeControlFeedKey: params.controlFeedKey,
980
+ writeDataFeedKey: params.dataFeedKey
894
981
  }
895
982
  };
896
983
  const identity = await this._constructIdentity(identityRecord);
897
984
  await identity.open();
898
985
  this._identity = identity;
899
986
  await this._metadataStore.setIdentityRecord(identityRecord);
987
+ await this._identity.ready();
900
988
  this.stateUpdate.emit();
989
+ (0, import_log4.log)("accepted identity", {
990
+ identityKey: identity.identityKey,
991
+ deviceKey: identity.deviceKey
992
+ }, {
993
+ file: "identity-manager.ts",
994
+ line: 164,
995
+ scope: this,
996
+ callSite: (f, a) => f(...a)
997
+ });
901
998
  return identity;
902
999
  }
903
1000
  async _constructIdentity(identityRecord) {
904
- (0, import_node_assert3.default)(!this._identity);
1001
+ (0, import_node_assert4.default)(!this._identity);
905
1002
  (0, import_log4.log)("constructing identity", {
906
1003
  identityRecord
907
1004
  }, {
908
1005
  file: "identity-manager.ts",
909
- line: 163,
1006
+ line: 170,
910
1007
  scope: this,
911
1008
  callSite: (f, a) => f(...a)
912
1009
  });
1010
+ const controlFeed = await this._feedStore.openFeed(identityRecord.haloSpace.writeControlFeedKey, {
1011
+ writable: true
1012
+ });
1013
+ const dataFeed = await this._feedStore.openFeed(identityRecord.haloSpace.writeDataFeedKey, {
1014
+ writable: true
1015
+ });
913
1016
  const space = await this._constructSpace({
914
1017
  spaceRecord: identityRecord.haloSpace,
915
1018
  swarmIdentity: {
916
1019
  peerKey: identityRecord.deviceKey,
917
- credentialProvider: createHaloAuthProvider((0, import_credentials4.createCredentialSignerWithKey)(this._keyring, identityRecord.deviceKey)),
1020
+ credentialProvider: createAuthProvider((0, import_credentials5.createCredentialSignerWithKey)(this._keyring, identityRecord.deviceKey)),
918
1021
  credentialAuthenticator: (0, import_util3.deferFunction)(() => identity.authVerifier.verifier)
919
1022
  },
920
1023
  identityKey: identityRecord.identityKey
921
1024
  });
1025
+ space.setControlFeed(controlFeed);
1026
+ space.setDataFeed(dataFeed);
922
1027
  const identity = new Identity({
923
1028
  space,
924
1029
  signer: this._keyring,
@@ -929,7 +1034,7 @@ var IdentityManager = class {
929
1034
  identityKey: identityRecord.identityKey
930
1035
  }, {
931
1036
  file: "identity-manager.ts",
932
- line: 182,
1037
+ line: 196,
933
1038
  scope: this,
934
1039
  callSite: (f, a) => f(...a)
935
1040
  });
@@ -939,9 +1044,7 @@ var IdentityManager = class {
939
1044
  return this._spaceManager.constructSpace({
940
1045
  metadata: {
941
1046
  key: spaceRecord.spaceKey,
942
- genesisFeedKey: spaceRecord.genesisFeedKey,
943
- controlFeedKey: spaceRecord.writeControlFeedKey,
944
- dataFeedKey: spaceRecord.writeDataFeedKey
1047
+ genesisFeedKey: spaceRecord.genesisFeedKey
945
1048
  },
946
1049
  swarmIdentity,
947
1050
  onNetworkConnection: () => {
@@ -965,11 +1068,10 @@ var InvitationEncoder = class {
965
1068
  };
966
1069
 
967
1070
  // packages/sdk/client-services/src/packlets/invitations/halo-invitations-handler.ts
968
- var import_node_assert5 = __toESM(require("node:assert"));
969
- var import_async8 = require("@dxos/async");
970
- var import_context2 = require("@dxos/context");
971
- var import_credentials6 = require("@dxos/credentials");
972
- var import_debug3 = require("@dxos/debug");
1071
+ var import_node_assert6 = __toESM(require("node:assert"));
1072
+ var import_async7 = require("@dxos/async");
1073
+ var import_context3 = require("@dxos/context");
1074
+ var import_credentials7 = require("@dxos/credentials");
973
1075
  var import_keys4 = require("@dxos/keys");
974
1076
  var import_log5 = require("@dxos/log");
975
1077
  var import_network_manager = require("@dxos/network-manager");
@@ -979,13 +1081,13 @@ var import_invitations = require("@dxos/protocols/proto/dxos/halo/invitations");
979
1081
  var import_teleport = require("@dxos/teleport");
980
1082
 
981
1083
  // packages/sdk/client-services/src/packlets/invitations/invitations.ts
982
- var import_node_assert4 = __toESM(require("node:assert"));
983
- var import_async7 = require("@dxos/async");
1084
+ var import_node_assert5 = __toESM(require("node:assert"));
1085
+ var import_async6 = require("@dxos/async");
984
1086
  var import_services = require("@dxos/protocols/proto/dxos/client/services");
985
1087
  var AUTHENTICATION_CODE_LENGTH = 6;
986
1088
  var INVITATION_TIMEOUT = 3 * 6e4;
987
- var ON_CLOSE_DELAY = 500;
988
- var InvitationObservableProvider = class extends import_async7.CancellableObservableProvider {
1089
+ var ON_CLOSE_DELAY = 1e3;
1090
+ var InvitationObservableProvider = class extends import_async6.CancellableObservableProvider {
989
1091
  get invitation() {
990
1092
  return this._invitation;
991
1093
  }
@@ -1007,7 +1109,7 @@ var wrapObservable = async (observable) => {
1007
1109
  return new Promise((resolve, reject) => {
1008
1110
  const unsubscribe = observable.subscribe({
1009
1111
  onSuccess: (invitation) => {
1010
- (0, import_node_assert4.default)(invitation.state === import_services.Invitation.State.SUCCESS);
1112
+ (0, import_node_assert5.default)(invitation.state === import_services.Invitation.State.SUCCESS);
1011
1113
  unsubscribe();
1012
1114
  resolve(invitation);
1013
1115
  },
@@ -1030,25 +1132,24 @@ var AbstractInvitationsHandler = class {
1030
1132
  // packages/sdk/client-services/src/packlets/invitations/halo-invitations-handler.ts
1031
1133
  var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
1032
1134
  // prettier-ignore
1033
- constructor(networkManager, _identityManager) {
1034
- super(networkManager);
1035
- this._identityManager = _identityManager;
1135
+ constructor(_params) {
1136
+ super(_params.networkManager);
1137
+ this._params = _params;
1036
1138
  }
1037
1139
  /**
1038
1140
  * Creates an invitation and listens for a join request from the invited (guest) peer.
1039
1141
  */
1040
1142
  createInvitation(context, options) {
1041
- var _a;
1042
1143
  const { type, timeout = INVITATION_TIMEOUT, swarmKey } = options != null ? options : {};
1043
- (0, import_node_assert5.default)(type !== import_services2.Invitation.Type.OFFLINE);
1044
- const identity = (_a = this._identityManager.identity) != null ? _a : (0, import_debug3.failUndefined)();
1144
+ (0, import_node_assert6.default)(type !== import_services2.Invitation.Type.OFFLINE);
1145
+ const identity = this._params.getIdentity();
1045
1146
  const invitation = {
1046
1147
  type,
1047
1148
  invitationId: import_keys4.PublicKey.random().toHex(),
1048
1149
  swarmKey: swarmKey != null ? swarmKey : import_keys4.PublicKey.random(),
1049
- authenticationCode: (0, import_credentials6.generatePasscode)(AUTHENTICATION_CODE_LENGTH)
1150
+ authenticationCode: (0, import_credentials7.generatePasscode)(AUTHENTICATION_CODE_LENGTH)
1050
1151
  };
1051
- const ctx = new import_context2.Context({
1152
+ const ctx = new import_context3.Context({
1052
1153
  onError: (err) => {
1053
1154
  void ctx.dispose();
1054
1155
  observable.callback.onError(err);
@@ -1058,111 +1159,108 @@ var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
1058
1159
  await ctx.dispose();
1059
1160
  });
1060
1161
  let authenticationCode;
1061
- const complete = new import_async8.Trigger();
1062
- const createExtension = () => {
1063
- const hostInvitationExtension = new HostHaloInvitationExtension({
1064
- requestAdmission: async () => {
1065
- var _a2, _b;
1066
- (0, import_log5.log)("responding with admission offer", {
1067
- host: identity.deviceKey
1068
- }, {
1069
- file: "halo-invitations-handler.ts",
1070
- line: 84,
1071
- scope: this,
1072
- callSite: (f, a) => f(...a)
1073
- });
1074
- (_b = (_a2 = observable.callback).onAuthenticating) == null ? void 0 : _b.call(_a2, invitation);
1075
- return {
1076
- identityKey: identity.identityKey,
1077
- haloSpaceKey: identity.haloSpaceKey,
1078
- genesisFeedKey: identity.haloGenesisFeedKey
1079
- };
1080
- },
1081
- authenticate: async ({ authenticationCode: code }) => {
1082
- (0, import_log5.log)("received authentication request", {
1083
- authenticationCode: code
1162
+ const complete = new import_async7.Trigger();
1163
+ const createExtension = () => new HostHaloInvitationExtension({
1164
+ requestAdmission: async () => {
1165
+ var _a, _b;
1166
+ (0, import_log5.log)("responding with admission offer", {
1167
+ host: identity.deviceKey
1168
+ }, {
1169
+ file: "halo-invitations-handler.ts",
1170
+ line: 91,
1171
+ scope: this,
1172
+ callSite: (f, a) => f(...a)
1173
+ });
1174
+ (_b = (_a = observable.callback).onAuthenticating) == null ? void 0 : _b.call(_a, invitation);
1175
+ return {
1176
+ identityKey: identity.identityKey,
1177
+ haloSpaceKey: identity.haloSpaceKey,
1178
+ genesisFeedKey: identity.haloGenesisFeedKey
1179
+ };
1180
+ },
1181
+ authenticate: async ({ authenticationCode: code }) => {
1182
+ (0, import_log5.log)("received authentication request", {
1183
+ authenticationCode: code
1184
+ }, {
1185
+ file: "halo-invitations-handler.ts",
1186
+ line: 105,
1187
+ scope: this,
1188
+ callSite: (f, a) => f(...a)
1189
+ });
1190
+ authenticationCode = code;
1191
+ return {
1192
+ status: import_invitations.AuthenticationResponse.Status.OK
1193
+ };
1194
+ },
1195
+ // TODO(burdon): Not used: controlFeedKey, dataFeedKey.
1196
+ presentAdmissionCredentials: async (credentials) => {
1197
+ try {
1198
+ if (invitation.type !== import_services2.Invitation.Type.INTERACTIVE_TESTING) {
1199
+ if (invitation.authenticationCode === void 0 || invitation.authenticationCode !== authenticationCode) {
1200
+ throw new Error(`invalid authentication code: ${authenticationCode}`);
1201
+ }
1202
+ }
1203
+ (0, import_log5.log)("writing guest credentials", {
1204
+ host: identity.deviceKey,
1205
+ guest: credentials.deviceKey
1084
1206
  }, {
1085
1207
  file: "halo-invitations-handler.ts",
1086
- line: 98,
1208
+ line: 120,
1087
1209
  scope: this,
1088
1210
  callSite: (f, a) => f(...a)
1089
1211
  });
1090
- authenticationCode = code;
1091
- return {
1092
- status: import_invitations.AuthenticationResponse.Status.OK
1093
- };
1094
- },
1095
- // TODO(burdon): Not used: controlFeedKey, dataFeedKey.
1096
- presentAdmissionCredentials: async (credentials) => {
1212
+ await identity.admitDevice(credentials);
1213
+ complete.wake(credentials.deviceKey);
1214
+ } catch (err) {
1215
+ observable.callback.onError(err);
1216
+ throw err;
1217
+ }
1218
+ },
1219
+ onOpen: () => {
1220
+ (0, import_async7.scheduleTask)(ctx, async () => {
1221
+ var _a, _b;
1097
1222
  try {
1098
- if (invitation.type !== import_services2.Invitation.Type.INTERACTIVE_TESTING) {
1099
- if (invitation.authenticationCode === void 0 || invitation.authenticationCode !== authenticationCode) {
1100
- throw new Error(`invalid authentication code: ${authenticationCode}`);
1101
- }
1102
- }
1103
- (0, import_log5.log)("writing guest credentials", {
1223
+ (0, import_log5.log)("connected", {
1224
+ host: identity.deviceKey
1225
+ }, {
1226
+ file: "halo-invitations-handler.ts",
1227
+ line: 136,
1228
+ scope: this,
1229
+ callSite: (f, a) => f(...a)
1230
+ });
1231
+ (_b = (_a = observable.callback).onConnected) == null ? void 0 : _b.call(_a, invitation);
1232
+ const deviceKey = await complete.wait({
1233
+ timeout
1234
+ });
1235
+ (0, import_log5.log)("admitted guest", {
1104
1236
  host: identity.deviceKey,
1105
- guest: credentials.deviceKey
1237
+ guest: deviceKey
1106
1238
  }, {
1107
1239
  file: "halo-invitations-handler.ts",
1108
- line: 113,
1240
+ line: 139,
1109
1241
  scope: this,
1110
1242
  callSite: (f, a) => f(...a)
1111
1243
  });
1112
- await identity.admitDevice(credentials);
1113
- complete.wake(credentials.deviceKey);
1244
+ observable.callback.onSuccess(invitation);
1114
1245
  } catch (err) {
1115
- observable.callback.onError(err);
1116
- throw err;
1117
- }
1118
- },
1119
- onOpen: () => {
1120
- (0, import_async8.scheduleTask)(ctx, async () => {
1121
- var _a2, _b;
1122
- try {
1123
- (0, import_log5.log)("connected", {
1124
- host: identity.deviceKey
1125
- }, {
1126
- file: "halo-invitations-handler.ts",
1127
- line: 129,
1128
- scope: this,
1129
- callSite: (f, a) => f(...a)
1130
- });
1131
- (_b = (_a2 = observable.callback).onConnected) == null ? void 0 : _b.call(_a2, invitation);
1132
- const deviceKey = await complete.wait({
1133
- timeout
1134
- });
1135
- (0, import_log5.log)("admitted guest", {
1136
- host: identity.deviceKey,
1137
- guest: deviceKey
1138
- }, {
1246
+ if (!observable.cancelled) {
1247
+ import_log5.log.error("failed", err, {
1139
1248
  file: "halo-invitations-handler.ts",
1140
- line: 132,
1249
+ line: 143,
1141
1250
  scope: this,
1142
1251
  callSite: (f, a) => f(...a)
1143
1252
  });
1144
- observable.callback.onSuccess(invitation);
1145
- } catch (err) {
1146
- if (!observable.cancelled) {
1147
- import_log5.log.error("failed", err, {
1148
- file: "halo-invitations-handler.ts",
1149
- line: 136,
1150
- scope: this,
1151
- callSite: (f, a) => f(...a)
1152
- });
1153
- observable.callback.onError(err);
1154
- }
1155
- } finally {
1156
- await (0, import_async8.sleep)(ON_CLOSE_DELAY);
1157
- await ctx.dispose();
1253
+ observable.callback.onError(err);
1158
1254
  }
1159
- });
1160
- }
1161
- });
1162
- return hostInvitationExtension;
1163
- };
1164
- (0, import_async8.scheduleTask)(ctx, async () => {
1165
- var _a2, _b;
1255
+ } finally {
1256
+ await (0, import_async7.sleep)(ON_CLOSE_DELAY);
1257
+ await ctx.dispose();
1258
+ }
1259
+ });
1260
+ }
1261
+ });
1262
+ (0, import_async7.scheduleTask)(ctx, async () => {
1263
+ var _a, _b;
1166
1264
  const topic = invitation.swarmKey;
1167
1265
  const swarmConnection = await this._networkManager.joinSwarm({
1168
1266
  topic,
@@ -1173,7 +1271,7 @@ var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
1173
1271
  topology: new import_network_manager.StarTopology(topic)
1174
1272
  });
1175
1273
  ctx.onDispose(() => swarmConnection.close());
1176
- (_b = (_a2 = observable.callback).onConnecting) == null ? void 0 : _b.call(_a2, invitation);
1274
+ (_b = (_a = observable.callback).onConnecting) == null ? void 0 : _b.call(_a, invitation);
1177
1275
  });
1178
1276
  return observable;
1179
1277
  }
@@ -1184,13 +1282,13 @@ var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
1184
1282
  */
1185
1283
  acceptInvitation(invitation, options) {
1186
1284
  const { timeout = INVITATION_TIMEOUT } = options != null ? options : {};
1187
- const ctx = new import_context2.Context({
1285
+ const ctx = new import_context3.Context({
1188
1286
  onError: (err) => {
1189
1287
  void ctx.dispose();
1190
1288
  observable.callback.onError(err);
1191
1289
  }
1192
1290
  });
1193
- const authenticated = new import_async8.Trigger();
1291
+ const authenticated = new import_async7.Trigger();
1194
1292
  const observable = new AuthenticatingInvitationProvider({
1195
1293
  onCancel: async () => {
1196
1294
  await ctx.dispose();
@@ -1201,11 +1299,11 @@ var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
1201
1299
  }
1202
1300
  });
1203
1301
  let connectionCount = 0;
1204
- const complete = new import_async8.Trigger();
1302
+ const complete = new import_async7.Trigger();
1205
1303
  const createExtension = () => {
1206
1304
  const extension = new GuestHaloInvitationExtension({
1207
1305
  onOpen: () => {
1208
- (0, import_async8.scheduleTask)(ctx, async () => {
1306
+ (0, import_async7.scheduleTask)(ctx, async () => {
1209
1307
  var _a, _b, _c, _d;
1210
1308
  try {
1211
1309
  if (++connectionCount > 1) {
@@ -1213,14 +1311,14 @@ var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
1213
1311
  }
1214
1312
  (0, import_log5.log)("connected", {}, {
1215
1313
  file: "halo-invitations-handler.ts",
1216
- line: 209,
1314
+ line: 214,
1217
1315
  scope: this,
1218
1316
  callSite: (f, a) => f(...a)
1219
1317
  });
1220
1318
  (_b = (_a = observable.callback).onConnected) == null ? void 0 : _b.call(_a, invitation);
1221
1319
  (0, import_log5.log)("sending admission request", {}, {
1222
1320
  file: "halo-invitations-handler.ts",
1223
- line: 213,
1321
+ line: 218,
1224
1322
  scope: this,
1225
1323
  callSite: (f, a) => f(...a)
1226
1324
  });
@@ -1228,7 +1326,7 @@ var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
1228
1326
  if (invitation.type === void 0 || invitation.type === import_services2.Invitation.Type.INTERACTIVE) {
1229
1327
  (0, import_log5.log)("guest waiting for authentication code...", {}, {
1230
1328
  file: "halo-invitations-handler.ts",
1231
- line: 220,
1329
+ line: 225,
1232
1330
  scope: this,
1233
1331
  callSite: (f, a) => f(...a)
1234
1332
  });
@@ -1238,7 +1336,7 @@ var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
1238
1336
  });
1239
1337
  (0, import_log5.log)("sending authentication request", {}, {
1240
1338
  file: "halo-invitations-handler.ts",
1241
- line: 223,
1339
+ line: 228,
1242
1340
  scope: this,
1243
1341
  callSite: (f, a) => f(...a)
1244
1342
  });
@@ -1246,27 +1344,39 @@ var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
1246
1344
  authenticationCode
1247
1345
  });
1248
1346
  }
1249
- const identity = await this._identityManager.acceptIdentity({
1347
+ const deviceKey = await this._params.keyring.createKey();
1348
+ const controlFeedKey = await this._params.keyring.createKey();
1349
+ const dataFeedKey = await this._params.keyring.createKey();
1350
+ (0, import_log5.log)("presenting admission credentials", {
1250
1351
  identityKey,
1251
- haloSpaceKey,
1252
- haloGenesisFeedKey: genesisFeedKey
1253
- });
1254
- (0, import_log5.log)("presenting admission credentials", {
1255
- guest: identity.deviceKey,
1256
- identityKey
1352
+ deviceKey,
1353
+ controlFeedKey,
1354
+ dataFeedKey
1257
1355
  }, {
1258
1356
  file: "halo-invitations-handler.ts",
1259
- line: 236,
1357
+ line: 237,
1260
1358
  scope: this,
1261
1359
  callSite: (f, a) => f(...a)
1262
1360
  });
1263
- await extension.rpc.HaloHostService.presentAdmissionCredentials(identity.getAdmissionCredentials());
1361
+ await extension.rpc.HaloHostService.presentAdmissionCredentials({
1362
+ deviceKey,
1363
+ controlFeedKey,
1364
+ dataFeedKey
1365
+ });
1366
+ const identity = await this._params.acceptIdentity({
1367
+ identityKey,
1368
+ deviceKey,
1369
+ haloSpaceKey,
1370
+ haloGenesisFeedKey: genesisFeedKey,
1371
+ controlFeedKey,
1372
+ dataFeedKey
1373
+ });
1264
1374
  (0, import_log5.log)("admitted by host", {
1265
1375
  guest: identity.deviceKey,
1266
1376
  identityKey
1267
1377
  }, {
1268
1378
  file: "halo-invitations-handler.ts",
1269
- line: 240,
1379
+ line: 256,
1270
1380
  scope: this,
1271
1381
  callSite: (f, a) => f(...a)
1272
1382
  });
@@ -1275,7 +1385,7 @@ var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
1275
1385
  if (!observable.cancelled) {
1276
1386
  import_log5.log.warn("auth failed", err, {
1277
1387
  file: "halo-invitations-handler.ts",
1278
- line: 244,
1388
+ line: 260,
1279
1389
  scope: this,
1280
1390
  callSite: (f, a) => f(...a)
1281
1391
  });
@@ -1289,9 +1399,9 @@ var HaloInvitationsHandler = class extends AbstractInvitationsHandler {
1289
1399
  });
1290
1400
  return extension;
1291
1401
  };
1292
- (0, import_async8.scheduleTask)(ctx, async () => {
1402
+ (0, import_async7.scheduleTask)(ctx, async () => {
1293
1403
  var _a, _b;
1294
- (0, import_node_assert5.default)(invitation.swarmKey);
1404
+ (0, import_node_assert6.default)(invitation.swarmKey);
1295
1405
  const topic = invitation.swarmKey;
1296
1406
  const swarmConnection = await this._networkManager.joinSwarm({
1297
1407
  topic,
@@ -1361,8 +1471,8 @@ var GuestHaloInvitationExtension = class extends import_teleport.RpcExtension {
1361
1471
  };
1362
1472
 
1363
1473
  // packages/sdk/client-services/src/packlets/invitations/invitations-proxy.ts
1364
- var import_node_assert6 = __toESM(require("node:assert"));
1365
- var import_async9 = require("@dxos/async");
1474
+ var import_node_assert7 = __toESM(require("node:assert"));
1475
+ var import_async8 = require("@dxos/async");
1366
1476
  var import_log6 = require("@dxos/log");
1367
1477
  var import_services3 = require("@dxos/protocols/proto/dxos/client/services");
1368
1478
  var AbstractInvitationsProxy = class {
@@ -1389,7 +1499,7 @@ var AbstractInvitationsProxy = class {
1389
1499
  observable.setInvitation(invitation2);
1390
1500
  switch (invitation2.state) {
1391
1501
  case import_services3.Invitation.State.CONNECTING: {
1392
- (0, import_node_assert6.default)(invitation2.invitationId);
1502
+ (0, import_node_assert7.default)(invitation2.invitationId);
1393
1503
  invitationId = invitation2.invitationId;
1394
1504
  (_b = (_a = observable.callback).onConnecting) == null ? void 0 : _b.call(_a, invitation2);
1395
1505
  break;
@@ -1421,18 +1531,18 @@ var AbstractInvitationsProxy = class {
1421
1531
  }
1422
1532
  }, (err) => {
1423
1533
  if (err) {
1424
- (0, import_async9.observableError)(observable, err);
1534
+ (0, import_async8.observableError)(observable, err);
1425
1535
  }
1426
1536
  });
1427
1537
  return observable;
1428
1538
  }
1429
1539
  acceptInvitation(invitation, options) {
1430
- (0, import_node_assert6.default)(invitation && invitation.swarmKey);
1540
+ (0, import_node_assert7.default)(invitation && invitation.swarmKey);
1431
1541
  const observable = new AuthenticatingInvitationProvider({
1432
1542
  onCancel: async () => {
1433
1543
  var _a;
1434
1544
  const invitationId = (_a = observable.invitation) == null ? void 0 : _a.invitationId;
1435
- (0, import_node_assert6.default)(invitationId);
1545
+ (0, import_node_assert7.default)(invitationId);
1436
1546
  await this._invitationsService.cancelInvitation({
1437
1547
  invitationId
1438
1548
  });
@@ -1440,7 +1550,7 @@ var AbstractInvitationsProxy = class {
1440
1550
  onAuthenticate: async (authenticationCode) => {
1441
1551
  var _a;
1442
1552
  const invitationId = (_a = observable.invitation) == null ? void 0 : _a.invitationId;
1443
- (0, import_node_assert6.default)(invitationId);
1553
+ (0, import_node_assert7.default)(invitationId);
1444
1554
  await this._invitationsService.authenticate({
1445
1555
  invitationId,
1446
1556
  authenticationCode
@@ -1453,7 +1563,7 @@ var AbstractInvitationsProxy = class {
1453
1563
  });
1454
1564
  stream.subscribe((invitation2) => {
1455
1565
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1456
- (0, import_node_assert6.default)(invitation2.invitationId);
1566
+ (0, import_node_assert7.default)(invitation2.invitationId);
1457
1567
  observable.setInvitation(invitation2);
1458
1568
  switch (invitation2.state) {
1459
1569
  case import_services3.Invitation.State.CONNECTING: {
@@ -1487,7 +1597,7 @@ var AbstractInvitationsProxy = class {
1487
1597
  }
1488
1598
  }, (err) => {
1489
1599
  if (err) {
1490
- (0, import_async9.observableError)(observable, err);
1600
+ (0, import_async8.observableError)(observable, err);
1491
1601
  }
1492
1602
  });
1493
1603
  return observable;
@@ -1502,7 +1612,7 @@ var HaloInvitationsProxy = class extends AbstractInvitationsProxy {
1502
1612
  };
1503
1613
 
1504
1614
  // packages/sdk/client-services/src/packlets/invitations/invitations-service.ts
1505
- var import_node_assert7 = __toESM(require("node:assert"));
1615
+ var import_node_assert8 = __toESM(require("node:assert"));
1506
1616
  var import_codec_protobuf8 = require("@dxos/codec-protobuf");
1507
1617
  var import_log7 = require("@dxos/log");
1508
1618
  var import_services4 = require("@dxos/protocols/proto/dxos/client/services");
@@ -1539,30 +1649,30 @@ var AbstractInvitationsService = class {
1539
1649
  });
1540
1650
  observable.subscribe({
1541
1651
  onConnecting: (invitation2) => {
1542
- (0, import_node_assert7.default)(invitation2.invitationId);
1652
+ (0, import_node_assert8.default)(invitation2.invitationId);
1543
1653
  invitationId = invitation2.invitationId;
1544
1654
  this._createInvitations.set(invitation2.invitationId, observable);
1545
1655
  invitation2.state = import_services4.Invitation.State.CONNECTING;
1546
1656
  next(invitation2);
1547
1657
  },
1548
1658
  onConnected: (invitation2) => {
1549
- (0, import_node_assert7.default)(invitation2.invitationId);
1659
+ (0, import_node_assert8.default)(invitation2.invitationId);
1550
1660
  invitation2.state = import_services4.Invitation.State.CONNECTED;
1551
1661
  next(invitation2);
1552
1662
  },
1553
1663
  onAuthenticating: (invitation2) => {
1554
- (0, import_node_assert7.default)(invitation2.invitationId);
1664
+ (0, import_node_assert8.default)(invitation2.invitationId);
1555
1665
  invitation2.state = import_services4.Invitation.State.AUTHENTICATING;
1556
1666
  next(invitation2);
1557
1667
  },
1558
1668
  onSuccess: (invitation2) => {
1559
- (0, import_node_assert7.default)(invitation2.invitationId);
1669
+ (0, import_node_assert8.default)(invitation2.invitationId);
1560
1670
  invitation2.state = import_services4.Invitation.State.SUCCESS;
1561
1671
  next(invitation2);
1562
1672
  close();
1563
1673
  },
1564
1674
  onCancelled: () => {
1565
- (0, import_node_assert7.default)(invitationId);
1675
+ (0, import_node_assert8.default)(invitationId);
1566
1676
  invitation.invitationId = invitationId;
1567
1677
  invitation.state = import_services4.Invitation.State.CANCELLED;
1568
1678
  next(invitation);
@@ -1614,19 +1724,19 @@ var AbstractInvitationsService = class {
1614
1724
  const observable = invitationsHandler.acceptInvitation(invitation, options);
1615
1725
  observable.subscribe({
1616
1726
  onConnecting: (invitation2) => {
1617
- (0, import_node_assert7.default)(invitation2.invitationId);
1727
+ (0, import_node_assert8.default)(invitation2.invitationId);
1618
1728
  invitationId = invitation2.invitationId;
1619
1729
  this._acceptInvitations.set(invitation2.invitationId, observable);
1620
1730
  invitation2.state = import_services4.Invitation.State.CONNECTING;
1621
1731
  next(invitation2);
1622
1732
  },
1623
1733
  onConnected: (invitation2) => {
1624
- (0, import_node_assert7.default)(invitation2.invitationId);
1734
+ (0, import_node_assert8.default)(invitation2.invitationId);
1625
1735
  invitation2.state = import_services4.Invitation.State.CONNECTED;
1626
1736
  next(invitation2);
1627
1737
  },
1628
1738
  onAuthenticating: (invitation2) => {
1629
- (0, import_node_assert7.default)(invitation2.invitationId);
1739
+ (0, import_node_assert8.default)(invitation2.invitationId);
1630
1740
  invitation2.state = import_services4.Invitation.State.AUTHENTICATING;
1631
1741
  next(invitation2);
1632
1742
  },
@@ -1636,7 +1746,7 @@ var AbstractInvitationsService = class {
1636
1746
  close();
1637
1747
  },
1638
1748
  onCancelled: () => {
1639
- (0, import_node_assert7.default)(invitationId);
1749
+ (0, import_node_assert8.default)(invitationId);
1640
1750
  invitation.invitationId = invitationId;
1641
1751
  invitation.state = import_services4.Invitation.State.CANCELLED;
1642
1752
  next(invitation);
@@ -1682,7 +1792,7 @@ var AbstractInvitationsService = class {
1682
1792
  scope: this,
1683
1793
  callSite: (f, a) => f(...a)
1684
1794
  });
1685
- (0, import_node_assert7.default)(invitationId);
1795
+ (0, import_node_assert8.default)(invitationId);
1686
1796
  const observable = this._acceptInvitations.get(invitationId);
1687
1797
  if (!observable) {
1688
1798
  import_log7.log.warn("invalid invitation", {
@@ -1705,7 +1815,7 @@ var AbstractInvitationsService = class {
1705
1815
  scope: this,
1706
1816
  callSite: (f, a) => f(...a)
1707
1817
  });
1708
- (0, import_node_assert7.default)(invitation.invitationId);
1818
+ (0, import_node_assert8.default)(invitation.invitationId);
1709
1819
  const observable = (_a = this._createInvitations.get(invitation.invitationId)) != null ? _a : this._acceptInvitations.get(invitation.invitationId);
1710
1820
  if (!observable) {
1711
1821
  import_log7.log.warn("invalid invitation", {
@@ -1734,10 +1844,10 @@ var HaloInvitationsServiceImpl = class extends AbstractInvitationsService {
1734
1844
  };
1735
1845
 
1736
1846
  // packages/sdk/client-services/src/packlets/invitations/space-invitations-handler.ts
1737
- var import_node_assert8 = __toESM(require("node:assert"));
1738
- var import_async10 = require("@dxos/async");
1739
- var import_context3 = require("@dxos/context");
1740
- var import_credentials7 = require("@dxos/credentials");
1847
+ var import_node_assert9 = __toESM(require("node:assert"));
1848
+ var import_async9 = require("@dxos/async");
1849
+ var import_context4 = require("@dxos/context");
1850
+ var import_credentials8 = require("@dxos/credentials");
1741
1851
  var import_feed_store3 = require("@dxos/feed-store");
1742
1852
  var import_keys5 = require("@dxos/keys");
1743
1853
  var import_log8 = require("@dxos/log");
@@ -1760,16 +1870,16 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1760
1870
  createInvitation(space, options) {
1761
1871
  let swarmConnection;
1762
1872
  const { type, timeout = INVITATION_TIMEOUT, swarmKey } = options != null ? options : {};
1763
- (0, import_node_assert8.default)(type !== import_services5.Invitation.Type.OFFLINE);
1764
- (0, import_node_assert8.default)(space);
1873
+ (0, import_node_assert9.default)(type !== import_services5.Invitation.Type.OFFLINE);
1874
+ (0, import_node_assert9.default)(space);
1765
1875
  const invitation = {
1766
1876
  type,
1767
1877
  invitationId: import_keys5.PublicKey.random().toHex(),
1768
1878
  swarmKey: swarmKey != null ? swarmKey : import_keys5.PublicKey.random(),
1769
1879
  spaceKey: space.key,
1770
- authenticationCode: (0, import_credentials7.generatePasscode)(AUTHENTICATION_CODE_LENGTH)
1880
+ authenticationCode: (0, import_credentials8.generatePasscode)(AUTHENTICATION_CODE_LENGTH)
1771
1881
  };
1772
- const ctx = new import_context3.Context({
1882
+ const ctx = new import_context4.Context({
1773
1883
  onError: (err) => {
1774
1884
  void ctx.dispose();
1775
1885
  observable.callback.onError(err);
@@ -1781,7 +1891,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1781
1891
  let authenticationCode;
1782
1892
  let authenticationRetry = 0;
1783
1893
  const createExtension = () => {
1784
- const complete = new import_async10.Trigger();
1894
+ const complete = new import_async9.Trigger();
1785
1895
  let guestProfile;
1786
1896
  const hostInvitationExtension = new HostSpaceInvitationExtension({
1787
1897
  introduce: async ({ profile }) => {
@@ -1792,7 +1902,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1792
1902
  spaceKey: space.key
1793
1903
  }, {
1794
1904
  file: "space-invitations-handler.ts",
1795
- line: 97,
1905
+ line: 98,
1796
1906
  scope: this,
1797
1907
  callSite: (f, a) => f(...a)
1798
1908
  });
@@ -1804,7 +1914,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1804
1914
  authenticationCode: code
1805
1915
  }, {
1806
1916
  file: "space-invitations-handler.ts",
1807
- line: 111,
1917
+ line: 112,
1808
1918
  scope: this,
1809
1919
  callSite: (f, a) => f(...a)
1810
1920
  });
@@ -1834,14 +1944,14 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1834
1944
  guest: deviceKey
1835
1945
  }, {
1836
1946
  file: "space-invitations-handler.ts",
1837
- line: 138,
1947
+ line: 139,
1838
1948
  scope: this,
1839
1949
  callSite: (f, a) => f(...a)
1840
1950
  });
1841
- const credentials = await (0, import_credentials7.createAdmissionCredentials)(this._signingContext.credentialSigner, identityKey, deviceKey, space.key, controlFeedKey, dataFeedKey, space.inner.genesisFeedKey, guestProfile);
1842
- (0, import_node_assert8.default)(credentials[0]["@type"] === "dxos.echo.feed.CredentialsMessage");
1843
- const spaceMemberCredential = credentials[0].credential;
1844
- (0, import_node_assert8.default)((0, import_credentials7.getCredentialAssertion)(spaceMemberCredential)["@type"] === "dxos.halo.credentials.SpaceMember");
1951
+ const credentials = await (0, import_credentials8.createAdmissionCredentials)(this._signingContext.credentialSigner, identityKey, space.key, space.inner.genesisFeedKey, guestProfile);
1952
+ (0, import_node_assert9.default)(credentials[0].credential);
1953
+ const spaceMemberCredential = credentials[0].credential.credential;
1954
+ (0, import_node_assert9.default)((0, import_credentials8.getCredentialAssertion)(spaceMemberCredential)["@type"] === "dxos.halo.credentials.SpaceMember");
1845
1955
  await (0, import_feed_store3.writeMessages)(space.inner.controlPipeline.writer, credentials);
1846
1956
  complete.wake(deviceKey);
1847
1957
  return {
@@ -1853,14 +1963,14 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1853
1963
  }
1854
1964
  },
1855
1965
  onOpen: () => {
1856
- (0, import_async10.scheduleTask)(ctx, async () => {
1966
+ (0, import_async9.scheduleTask)(ctx, async () => {
1857
1967
  var _a, _b;
1858
1968
  try {
1859
1969
  (0, import_log8.log)("connected", {
1860
1970
  host: this._signingContext.deviceKey
1861
1971
  }, {
1862
1972
  file: "space-invitations-handler.ts",
1863
- line: 172,
1973
+ line: 170,
1864
1974
  scope: this,
1865
1975
  callSite: (f, a) => f(...a)
1866
1976
  });
@@ -1873,7 +1983,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1873
1983
  guest: deviceKey
1874
1984
  }, {
1875
1985
  file: "space-invitations-handler.ts",
1876
- line: 175,
1986
+ line: 173,
1877
1987
  scope: this,
1878
1988
  callSite: (f, a) => f(...a)
1879
1989
  });
@@ -1882,7 +1992,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1882
1992
  if (!observable.cancelled) {
1883
1993
  import_log8.log.error("failed", err, {
1884
1994
  file: "space-invitations-handler.ts",
1885
- line: 179,
1995
+ line: 177,
1886
1996
  scope: this,
1887
1997
  callSite: (f, a) => f(...a)
1888
1998
  });
@@ -1890,7 +2000,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1890
2000
  }
1891
2001
  } finally {
1892
2002
  if (type !== import_services5.Invitation.Type.MULTIUSE_TESTING) {
1893
- await (0, import_async10.sleep)(ON_CLOSE_DELAY);
2003
+ await (0, import_async9.sleep)(ON_CLOSE_DELAY);
1894
2004
  await ctx.dispose();
1895
2005
  }
1896
2006
  }
@@ -1899,7 +2009,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1899
2009
  });
1900
2010
  return hostInvitationExtension;
1901
2011
  };
1902
- (0, import_async10.scheduleTask)(ctx, async () => {
2012
+ (0, import_async9.scheduleTask)(ctx, async () => {
1903
2013
  var _a, _b;
1904
2014
  const topic = invitation.swarmKey;
1905
2015
  const swarmConnection2 = await this._networkManager.joinSwarm({
@@ -1922,13 +2032,13 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1922
2032
  */
1923
2033
  acceptInvitation(invitation, options) {
1924
2034
  const { timeout = INVITATION_TIMEOUT } = options != null ? options : {};
1925
- const ctx = new import_context3.Context({
2035
+ const ctx = new import_context4.Context({
1926
2036
  onError: (err) => {
1927
2037
  void ctx.dispose();
1928
2038
  observable.callback.onError(err);
1929
2039
  }
1930
2040
  });
1931
- const authenticated = new import_async10.Trigger();
2041
+ const authenticated = new import_async9.Trigger();
1932
2042
  const observable = new AuthenticatingInvitationProvider({
1933
2043
  onCancel: async () => {
1934
2044
  await ctx.dispose();
@@ -1938,11 +2048,11 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1938
2048
  }
1939
2049
  });
1940
2050
  let connectionCount = 0;
1941
- const complete = new import_async10.Trigger();
2051
+ const complete = new import_async9.Trigger();
1942
2052
  const createExtension = () => {
1943
2053
  const extension = new GuestSpaceInvitationExtension({
1944
2054
  onOpen: () => {
1945
- (0, import_async10.scheduleTask)(ctx, async () => {
2055
+ (0, import_async9.scheduleTask)(ctx, async () => {
1946
2056
  var _a, _b, _c, _d;
1947
2057
  try {
1948
2058
  if (++connectionCount > 1) {
@@ -1952,7 +2062,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1952
2062
  guest: this._signingContext.deviceKey
1953
2063
  }, {
1954
2064
  file: "space-invitations-handler.ts",
1955
- line: 252,
2065
+ line: 250,
1956
2066
  scope: this,
1957
2067
  callSite: (f, a) => f(...a)
1958
2068
  });
@@ -1961,7 +2071,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1961
2071
  guest: this._signingContext.deviceKey
1962
2072
  }, {
1963
2073
  file: "space-invitations-handler.ts",
1964
- line: 256,
2074
+ line: 254,
1965
2075
  scope: this,
1966
2076
  callSite: (f, a) => f(...a)
1967
2077
  });
@@ -1972,7 +2082,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1972
2082
  for (let attempt = 1; attempt <= MAX_OTP_ATTEMPTS; attempt++) {
1973
2083
  (0, import_log8.log)("guest waiting for authentication code...", {}, {
1974
2084
  file: "space-invitations-handler.ts",
1975
- line: 265,
2085
+ line: 263,
1976
2086
  scope: this,
1977
2087
  callSite: (f, a) => f(...a)
1978
2088
  });
@@ -1982,7 +2092,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
1982
2092
  });
1983
2093
  (0, import_log8.log)("sending authentication request", {}, {
1984
2094
  file: "space-invitations-handler.ts",
1985
- line: 269,
2095
+ line: 267,
1986
2096
  scope: this,
1987
2097
  callSite: (f, a) => f(...a)
1988
2098
  });
@@ -2000,7 +2110,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
2000
2110
  attempt
2001
2111
  }, {
2002
2112
  file: "space-invitations-handler.ts",
2003
- line: 279,
2113
+ line: 277,
2004
2114
  scope: this,
2005
2115
  callSite: (f, a) => f(...a)
2006
2116
  });
@@ -2015,7 +2125,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
2015
2125
  guest: this._signingContext.deviceKey
2016
2126
  }, {
2017
2127
  file: "space-invitations-handler.ts",
2018
- line: 290,
2128
+ line: 288,
2019
2129
  scope: this,
2020
2130
  callSite: (f, a) => f(...a)
2021
2131
  });
@@ -2025,21 +2135,20 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
2025
2135
  controlFeedKey,
2026
2136
  dataFeedKey
2027
2137
  });
2028
- const assertion = (0, import_credentials7.getCredentialAssertion)(credential);
2029
- (0, import_node_assert8.default)(assertion["@type"] === "dxos.halo.credentials.SpaceMember", "Invalid credential");
2030
- (0, import_node_assert8.default)(credential.subject.id.equals(this._signingContext.identityKey));
2138
+ const assertion = (0, import_credentials8.getCredentialAssertion)(credential);
2139
+ (0, import_node_assert9.default)(assertion["@type"] === "dxos.halo.credentials.SpaceMember", "Invalid credential");
2140
+ (0, import_node_assert9.default)(credential.subject.id.equals(this._signingContext.identityKey));
2031
2141
  const space = await this._spaceManager.acceptSpace({
2032
2142
  spaceKey: assertion.spaceKey,
2033
- genesisFeedKey: assertion.genesisFeedKey,
2034
- controlFeedKey,
2035
- dataFeedKey
2143
+ genesisFeedKey: assertion.genesisFeedKey
2036
2144
  });
2145
+ await this._signingContext.recordCredential(credential);
2037
2146
  (0, import_log8.log)("admitted by host", {
2038
2147
  guest: this._signingContext.deviceKey,
2039
2148
  spaceKey: space.key
2040
2149
  }, {
2041
2150
  file: "space-invitations-handler.ts",
2042
- line: 313,
2151
+ line: 310,
2043
2152
  scope: this,
2044
2153
  callSite: (f, a) => f(...a)
2045
2154
  });
@@ -2048,7 +2157,7 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
2048
2157
  if (!observable.cancelled) {
2049
2158
  import_log8.log.warn("auth failed", err, {
2050
2159
  file: "space-invitations-handler.ts",
2051
- line: 317,
2160
+ line: 314,
2052
2161
  scope: this,
2053
2162
  callSite: (f, a) => f(...a)
2054
2163
  });
@@ -2062,9 +2171,9 @@ var SpaceInvitationsHandler = class extends AbstractInvitationsHandler {
2062
2171
  });
2063
2172
  return extension;
2064
2173
  };
2065
- (0, import_async10.scheduleTask)(ctx, async () => {
2174
+ (0, import_async9.scheduleTask)(ctx, async () => {
2066
2175
  var _a, _b;
2067
- (0, import_node_assert8.default)(invitation.swarmKey);
2176
+ (0, import_node_assert9.default)(invitation.swarmKey);
2068
2177
  const topic = invitation.swarmKey;
2069
2178
  const swarmConnection = await this._networkManager.joinSwarm({
2070
2179
  topic,
@@ -2142,7 +2251,7 @@ var SpaceInvitationsProxy = class extends AbstractInvitationsProxy {
2142
2251
  };
2143
2252
 
2144
2253
  // packages/sdk/client-services/src/packlets/invitations/space-invitations-service.ts
2145
- var import_node_assert9 = __toESM(require("node:assert"));
2254
+ var import_node_assert10 = __toESM(require("node:assert"));
2146
2255
  var SpaceInvitationsServiceImpl = class extends AbstractInvitationsService {
2147
2256
  // prettier-ignore
2148
2257
  constructor(identityManager, invitationsHandler, _getSpaceManager) {
@@ -2151,36 +2260,280 @@ var SpaceInvitationsServiceImpl = class extends AbstractInvitationsService {
2151
2260
  this._getSpaceManager = _getSpaceManager;
2152
2261
  }
2153
2262
  getContext(invitation) {
2154
- (0, import_node_assert9.default)(invitation.spaceKey);
2263
+ (0, import_node_assert10.default)(invitation.spaceKey);
2155
2264
  const spaceManager = this._getSpaceManager();
2156
2265
  const space = spaceManager.spaces.get(invitation.spaceKey);
2157
- (0, import_node_assert9.default)(space);
2266
+ (0, import_node_assert10.default)(space);
2158
2267
  return space;
2159
2268
  }
2160
2269
  };
2161
2270
 
2162
2271
  // packages/sdk/client-services/src/packlets/services/service-context.ts
2163
2272
  var import_async13 = require("@dxos/async");
2164
- var import_debug4 = require("@dxos/debug");
2165
- var import_echo_db3 = require("@dxos/echo-db");
2273
+ var import_credentials11 = require("@dxos/credentials");
2274
+ var import_debug5 = require("@dxos/debug");
2275
+ var import_echo_pipeline3 = require("@dxos/echo-pipeline");
2166
2276
  var import_feed_store4 = require("@dxos/feed-store");
2167
2277
  var import_keyring = require("@dxos/keyring");
2168
- var import_log10 = require("@dxos/log");
2278
+ var import_log11 = require("@dxos/log");
2169
2279
 
2170
2280
  // packages/sdk/client-services/src/packlets/spaces/data-space-manager.ts
2281
+ var import_node_assert12 = __toESM(require("node:assert"));
2171
2282
  var import_async12 = require("@dxos/async");
2283
+ var import_context7 = require("@dxos/context");
2284
+ var import_credentials10 = require("@dxos/credentials");
2285
+ var import_echo_pipeline2 = require("@dxos/echo-pipeline");
2286
+ var import_keys8 = require("@dxos/keys");
2287
+ var import_log10 = require("@dxos/log");
2288
+ var import_teleport_extension_presence = require("@dxos/teleport-extension-presence");
2289
+ var import_util6 = require("@dxos/util");
2290
+
2291
+ // packages/sdk/client-services/src/packlets/spaces/data-space.ts
2292
+ var import_async11 = require("@dxos/async");
2293
+ var import_context6 = require("@dxos/context");
2294
+ var import_debug4 = require("@dxos/debug");
2295
+ var import_echo_pipeline = require("@dxos/echo-pipeline");
2296
+ var import_keys7 = require("@dxos/keys");
2297
+ var import_credentials9 = require("@dxos/protocols/proto/dxos/halo/credentials");
2298
+ var import_util5 = require("@dxos/util");
2299
+
2300
+ // packages/sdk/client-services/src/packlets/spaces/notarization-plugin.ts
2301
+ var import_node_assert11 = __toESM(require("node:assert"));
2302
+ var import_async10 = require("@dxos/async");
2172
2303
  var import_context5 = require("@dxos/context");
2173
- var import_echo_db2 = require("@dxos/echo-db");
2174
2304
  var import_keys6 = require("@dxos/keys");
2175
2305
  var import_log9 = require("@dxos/log");
2176
- var import_teleport_extension_presence = require("@dxos/teleport-extension-presence");
2306
+ var import_protocols5 = require("@dxos/protocols");
2307
+ var import_teleport3 = require("@dxos/teleport");
2177
2308
  var import_util4 = require("@dxos/util");
2309
+ var RETRY_TIMEOUT = 1e3;
2310
+ var NOTARIZE_TIMEOUT = 1e4;
2311
+ var NotarizationPlugin = class {
2312
+ constructor() {
2313
+ this._ctx = new import_context5.Context();
2314
+ this._extensionOpened = new import_async10.Event();
2315
+ this._extensions = /* @__PURE__ */ new Set();
2316
+ this._processedCredentials = new import_util4.ComplexSet(import_keys6.PublicKey.hash);
2317
+ this._processCredentialsTriggers = new import_util4.ComplexMap(import_keys6.PublicKey.hash);
2318
+ }
2319
+ async open() {
2320
+ }
2321
+ async close() {
2322
+ await this._ctx.dispose();
2323
+ }
2324
+ /**
2325
+ * Request credentials to be notarized.
2326
+ */
2327
+ async notarize(credentials) {
2328
+ (0, import_log9.log)("notarize", {
2329
+ credentials
2330
+ }, {
2331
+ file: "notarization-plugin.ts",
2332
+ line: 44,
2333
+ scope: this,
2334
+ callSite: (f, a) => f(...a)
2335
+ });
2336
+ (0, import_node_assert11.default)(credentials.every((credential) => credential.id), "Credentials must have an id");
2337
+ const errors = new import_async10.Trigger();
2338
+ const ctx = this._ctx.derive({
2339
+ onError: (err) => {
2340
+ import_log9.log.warn("Notarization error", {
2341
+ err
2342
+ }, {
2343
+ file: "notarization-plugin.ts",
2344
+ line: 53,
2345
+ scope: this,
2346
+ callSite: (f, a) => f(...a)
2347
+ });
2348
+ void ctx.dispose();
2349
+ errors.throw(err);
2350
+ }
2351
+ });
2352
+ (0, import_async10.scheduleTask)(ctx, () => {
2353
+ import_log9.log.warn("Notarization timeout", {}, {
2354
+ file: "notarization-plugin.ts",
2355
+ line: 61,
2356
+ scope: this,
2357
+ callSite: (f, a) => f(...a)
2358
+ });
2359
+ void ctx.dispose();
2360
+ errors.throw(new import_async10.TimeoutError(NOTARIZE_TIMEOUT, "Notarization timed out"));
2361
+ }, NOTARIZE_TIMEOUT);
2362
+ const allNotarized = Promise.all(credentials.map((credential) => this._waitUntilProcessed(credential.id)));
2363
+ const peersTried = /* @__PURE__ */ new Set();
2364
+ const notarizeTask = new import_async10.DeferredTask(ctx, async () => {
2365
+ try {
2366
+ if (this._extensions.size === 0) {
2367
+ import_log9.log.warn("No peers to notarize with", {}, {
2368
+ file: "notarization-plugin.ts",
2369
+ line: 76,
2370
+ scope: this,
2371
+ callSite: (f, a) => f(...a)
2372
+ });
2373
+ return;
2374
+ }
2375
+ const peer = [
2376
+ ...this._extensions
2377
+ ].find((peer2) => !peersTried.has(peer2));
2378
+ if (!peer) {
2379
+ import_log9.log.warn("Exhausted all peers to notarize with", {
2380
+ retryIn: RETRY_TIMEOUT
2381
+ }, {
2382
+ file: "notarization-plugin.ts",
2383
+ line: 83,
2384
+ scope: this,
2385
+ callSite: (f, a) => f(...a)
2386
+ });
2387
+ peersTried.clear();
2388
+ (0, import_async10.scheduleTask)(ctx, () => notarizeTask.schedule(), RETRY_TIMEOUT);
2389
+ return;
2390
+ }
2391
+ peersTried.add(peer);
2392
+ (0, import_log9.log)("try notarizing", {
2393
+ peer: peer.localPeerId,
2394
+ credentialId: credentials.map((credential) => credential.id)
2395
+ }, {
2396
+ file: "notarization-plugin.ts",
2397
+ line: 90,
2398
+ scope: this,
2399
+ callSite: (f, a) => f(...a)
2400
+ });
2401
+ await peer.rpc.NotarizationService.notarize({
2402
+ credentials: credentials.filter((credential) => !this._processedCredentials.has(credential.id))
2403
+ });
2404
+ (0, import_log9.log)("success", {}, {
2405
+ file: "notarization-plugin.ts",
2406
+ line: 94,
2407
+ scope: this,
2408
+ callSite: (f, a) => f(...a)
2409
+ });
2410
+ } catch (err) {
2411
+ import_log9.log.warn("error notarizing (recoverable)", err, {
2412
+ file: "notarization-plugin.ts",
2413
+ line: 96,
2414
+ scope: this,
2415
+ callSite: (f, a) => f(...a)
2416
+ });
2417
+ notarizeTask.schedule();
2418
+ }
2419
+ });
2420
+ notarizeTask.schedule();
2421
+ this._extensionOpened.on(ctx, () => notarizeTask.schedule());
2422
+ try {
2423
+ await Promise.race([
2424
+ allNotarized,
2425
+ errors.wait()
2426
+ ]);
2427
+ (0, import_log9.log)("done", {}, {
2428
+ file: "notarization-plugin.ts",
2429
+ line: 107,
2430
+ scope: this,
2431
+ callSite: (f, a) => f(...a)
2432
+ });
2433
+ } finally {
2434
+ await ctx.dispose();
2435
+ }
2436
+ }
2437
+ /**
2438
+ * Called with credentials arriving from the control pipeline.
2439
+ */
2440
+ async process(credential) {
2441
+ var _a;
2442
+ if (!credential.id) {
2443
+ return;
2444
+ }
2445
+ (_a = this._processCredentialsTriggers.get(credential.id)) == null ? void 0 : _a.wake();
2446
+ this._processedCredentials.add(credential.id);
2447
+ this._processCredentialsTriggers.delete(credential.id);
2448
+ }
2449
+ setWriter(writer) {
2450
+ (0, import_node_assert11.default)(!this._writer, "Writer already set.");
2451
+ this._writer = writer;
2452
+ }
2453
+ async _waitUntilProcessed(id) {
2454
+ if (this._processedCredentials.has(id)) {
2455
+ return;
2456
+ }
2457
+ await (0, import_util4.entry)(this._processCredentialsTriggers, id).orInsert(new import_async10.Trigger()).value.wait();
2458
+ }
2459
+ /**
2460
+ * Requests from other peers to notarize credentials.
2461
+ */
2462
+ async _onNotarize(request) {
2463
+ var _a;
2464
+ if (!this._writer) {
2465
+ throw new Error("Writer not set");
2466
+ }
2467
+ for (const credential of (_a = request.credentials) != null ? _a : []) {
2468
+ (0, import_node_assert11.default)(credential.id, "Credential must have an id");
2469
+ if (this._processedCredentials.has(credential.id)) {
2470
+ continue;
2471
+ }
2472
+ await this._writer.write(credential);
2473
+ }
2474
+ }
2475
+ createExtension() {
2476
+ const extension = new NotarizationTeleportExtension({
2477
+ onOpen: async () => {
2478
+ (0, import_log9.log)("extension opened", {
2479
+ peer: extension.localPeerId
2480
+ }, {
2481
+ file: "notarization-plugin.ts",
2482
+ line: 156,
2483
+ scope: this,
2484
+ callSite: (f, a) => f(...a)
2485
+ });
2486
+ this._extensions.add(extension);
2487
+ this._extensionOpened.emit();
2488
+ },
2489
+ onClose: async () => {
2490
+ (0, import_log9.log)("extension closed", {
2491
+ peer: extension.localPeerId
2492
+ }, {
2493
+ file: "notarization-plugin.ts",
2494
+ line: 161,
2495
+ scope: this,
2496
+ callSite: (f, a) => f(...a)
2497
+ });
2498
+ this._extensions.delete(extension);
2499
+ },
2500
+ onNotarize: this._onNotarize.bind(this)
2501
+ });
2502
+ return extension;
2503
+ }
2504
+ };
2505
+ var NotarizationTeleportExtension = class extends import_teleport3.RpcExtension {
2506
+ constructor(_params) {
2507
+ super({
2508
+ requested: {
2509
+ NotarizationService: import_protocols5.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2510
+ },
2511
+ exposed: {
2512
+ NotarizationService: import_protocols5.schema.getService("dxos.mesh.teleport.notarization.NotarizationService")
2513
+ }
2514
+ });
2515
+ this._params = _params;
2516
+ }
2517
+ async getHandlers() {
2518
+ return {
2519
+ NotarizationService: {
2520
+ notarize: async (request) => {
2521
+ await this._params.onNotarize(request);
2522
+ }
2523
+ }
2524
+ };
2525
+ }
2526
+ async onOpen(ctx) {
2527
+ await super.onOpen(ctx);
2528
+ await this._params.onOpen();
2529
+ }
2530
+ async onClose(err) {
2531
+ await this._params.onClose();
2532
+ await super.onClose(err);
2533
+ }
2534
+ };
2178
2535
 
2179
2536
  // packages/sdk/client-services/src/packlets/spaces/data-space.ts
2180
- var import_node_assert10 = __toESM(require("node:assert"));
2181
- var import_async11 = require("@dxos/async");
2182
- var import_context4 = require("@dxos/context");
2183
- var import_echo_db = require("@dxos/echo-db");
2184
2537
  var __decorate = function(decorators, target, key, desc) {
2185
2538
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2186
2539
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
@@ -2191,12 +2544,18 @@ var __decorate = function(decorators, target, key, desc) {
2191
2544
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2192
2545
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2193
2546
  };
2547
+ var AUTH_TIMEOUT2 = 3e4;
2548
+ var CONTROL_PIPELINE_READY_TIMEFRAME = 3e3;
2194
2549
  var DataSpace = class DataSpace2 {
2195
2550
  constructor(params) {
2196
- this._ctx = new import_context4.Context();
2551
+ this._ctx = new import_context6.Context();
2197
2552
  this._inner = params.inner;
2198
2553
  this._presence = params.presence;
2199
- this._dataPipelineController = new import_echo_db.DataPipelineControllerImpl({
2554
+ this._keyring = params.keyring;
2555
+ this._feedStore = params.feedStore;
2556
+ this._metadataStore = params.metadataStore;
2557
+ this._signingContext = params.signingContext;
2558
+ this._dataPipelineController = new import_echo_pipeline.DataPipelineControllerImpl({
2200
2559
  modelFactory: params.modelFactory,
2201
2560
  metadataStore: params.metadataStore,
2202
2561
  snapshotManager: params.snapshotManager,
@@ -2205,39 +2564,103 @@ var DataSpace = class DataSpace2 {
2205
2564
  feedInfoProvider: (feedKey) => this._inner.spaceState.feeds.get(feedKey),
2206
2565
  snapshotId: params.snapshotId
2207
2566
  });
2567
+ this.authVerifier = new TrustedKeySetAuthVerifier({
2568
+ trustedKeysProvider: () => new import_util5.ComplexSet(import_keys7.PublicKey.hash, Array.from(this._inner.spaceState.members.keys())),
2569
+ update: this._inner.stateUpdate,
2570
+ authTimeout: AUTH_TIMEOUT2
2571
+ });
2572
+ this._notarizationPluginConsumer = this._inner.spaceState.registerProcessor(new NotarizationPlugin());
2208
2573
  }
2209
2574
  get key() {
2210
2575
  return this._inner.key;
2211
2576
  }
2212
- get inner() {
2213
- return this._inner;
2214
- }
2215
2577
  get isOpen() {
2216
2578
  return this._inner.isOpen;
2217
2579
  }
2580
+ // TODO(burdon): Can we mark this for debugging only?
2581
+ get inner() {
2582
+ return this._inner;
2583
+ }
2218
2584
  get dataPipelineController() {
2219
2585
  return this._dataPipelineController;
2220
2586
  }
2221
- get database() {
2222
- (0, import_node_assert10.default)(this._dataPipelineController.database);
2223
- return this._dataPipelineController.database;
2224
- }
2225
2587
  get stateUpdate() {
2226
2588
  return this._inner.stateUpdate;
2227
2589
  }
2228
2590
  get presence() {
2229
2591
  return this._presence;
2230
2592
  }
2593
+ get notarizationPlugin() {
2594
+ return this._notarizationPluginConsumer.processor;
2595
+ }
2231
2596
  async open() {
2597
+ await this.notarizationPlugin.open();
2598
+ await this._notarizationPluginConsumer.open();
2232
2599
  await this._inner.open();
2233
- await this._inner.initDataPipeline(this._dataPipelineController);
2234
2600
  }
2235
2601
  async close() {
2236
2602
  await this._ctx.dispose();
2603
+ await this.authVerifier.close();
2237
2604
  await this._inner.close();
2605
+ await this._notarizationPluginConsumer.close();
2606
+ await this.notarizationPlugin.close();
2238
2607
  await this._presence.destroy();
2239
2608
  }
2609
+ async initializeDataPipeline() {
2610
+ await this._inner.controlPipeline.state.waitUntilReachedTargetTimeframe({
2611
+ timeout: CONTROL_PIPELINE_READY_TIMEFRAME
2612
+ });
2613
+ await this._createWritableFeeds();
2614
+ this.notarizationPlugin.setWriter((0, import_echo_pipeline.createMappedFeedWriter)((credential) => ({
2615
+ credential: {
2616
+ credential
2617
+ }
2618
+ }), this._inner.controlPipeline.writer));
2619
+ await this._inner.initDataPipeline(this._dataPipelineController);
2620
+ }
2621
+ async _createWritableFeeds() {
2622
+ const credentials = [];
2623
+ if (!this.inner.controlFeedKey) {
2624
+ const controlFeed = await this._feedStore.openFeed(await this._keyring.createKey(), {
2625
+ writable: true
2626
+ });
2627
+ this.inner.setControlFeed(controlFeed);
2628
+ credentials.push(await this._signingContext.credentialSigner.createCredential({
2629
+ subject: controlFeed.key,
2630
+ assertion: {
2631
+ "@type": "dxos.halo.credentials.AdmittedFeed",
2632
+ spaceKey: this.key,
2633
+ deviceKey: this._signingContext.deviceKey,
2634
+ identityKey: this._signingContext.identityKey,
2635
+ designation: import_credentials9.AdmittedFeed.Designation.CONTROL
2636
+ }
2637
+ }));
2638
+ }
2639
+ if (!this.inner.dataFeedKey) {
2640
+ const dataFeed = await this._feedStore.openFeed(await this._keyring.createKey(), {
2641
+ writable: true
2642
+ });
2643
+ this.inner.setDataFeed(dataFeed);
2644
+ credentials.push(await this._signingContext.credentialSigner.createCredential({
2645
+ subject: dataFeed.key,
2646
+ assertion: {
2647
+ "@type": "dxos.halo.credentials.AdmittedFeed",
2648
+ spaceKey: this.key,
2649
+ deviceKey: this._signingContext.deviceKey,
2650
+ identityKey: this._signingContext.identityKey,
2651
+ designation: import_credentials9.AdmittedFeed.Designation.DATA
2652
+ }
2653
+ }));
2654
+ }
2655
+ if (credentials.length > 0) {
2656
+ await this.notarizationPlugin.notarize(credentials);
2657
+ }
2658
+ await this._metadataStore.setWritableFeedKeys(this.key, this.inner.controlFeedKey, this.inner.dataFeedKey);
2659
+ }
2240
2660
  };
2661
+ __decorate([
2662
+ (0, import_debug4.timed)(1e4)
2663
+ ], DataSpace.prototype, "_createWritableFeeds", null);
2241
2664
  DataSpace = __decorate([
2242
2665
  (0, import_async11.trackLeaks)("open", "close")
2243
2666
  ], DataSpace);
@@ -2253,18 +2676,20 @@ var __decorate2 = function(decorators, target, key, desc) {
2253
2676
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2254
2677
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2255
2678
  };
2679
+ var DATA_PIPELINE_READY_TIMEOUT = 3e3;
2256
2680
  var DataSpaceManager = class DataSpaceManager2 {
2257
- constructor(_spaceManager, _metadataStore, _dataServiceSubscriptions, _keyring, _signingContext, _modelFactory, _snapshotStore) {
2681
+ constructor(_spaceManager, _metadataStore, _dataServiceSubscriptions, _keyring, _signingContext, _modelFactory, _feedStore, _snapshotStore) {
2258
2682
  this._spaceManager = _spaceManager;
2259
2683
  this._metadataStore = _metadataStore;
2260
2684
  this._dataServiceSubscriptions = _dataServiceSubscriptions;
2261
2685
  this._keyring = _keyring;
2262
2686
  this._signingContext = _signingContext;
2263
2687
  this._modelFactory = _modelFactory;
2688
+ this._feedStore = _feedStore;
2264
2689
  this._snapshotStore = _snapshotStore;
2265
- this._ctx = new import_context5.Context();
2690
+ this._ctx = new import_context7.Context();
2266
2691
  this.updated = new import_async12.Event();
2267
- this._spaces = new import_util4.ComplexMap(import_keys6.PublicKey.hash);
2692
+ this._spaces = new import_util6.ComplexMap(import_keys8.PublicKey.hash);
2268
2693
  }
2269
2694
  // TODO(burdon): Remove.
2270
2695
  get spaces() {
@@ -2272,35 +2697,40 @@ var DataSpaceManager = class DataSpaceManager2 {
2272
2697
  }
2273
2698
  async open() {
2274
2699
  await this._metadataStore.load();
2275
- (0, import_log9.log)("metadata loaded", {
2700
+ (0, import_log10.log)("metadata loaded", {
2276
2701
  spaces: this._metadataStore.spaces.length
2277
2702
  }, {
2278
2703
  file: "data-space-manager.ts",
2279
- line: 54,
2704
+ line: 67,
2280
2705
  scope: this,
2281
2706
  callSite: (f, a) => f(...a)
2282
2707
  });
2283
2708
  for (const spaceMetadata of this._metadataStore.spaces) {
2284
- (0, import_log9.log)("load space", {
2709
+ (0, import_log10.log)("load space", {
2285
2710
  spaceMetadata
2286
2711
  }, {
2287
2712
  file: "data-space-manager.ts",
2288
- line: 57,
2713
+ line: 70,
2289
2714
  scope: this,
2290
2715
  callSite: (f, a) => f(...a)
2291
2716
  });
2292
2717
  const space = await this._constructSpace(spaceMetadata);
2293
- if (spaceMetadata.latestTimeframe) {
2294
- (0, import_log9.log)("waiting for latest timeframe", {
2718
+ await space.initializeDataPipeline();
2719
+ if (spaceMetadata.dataTimeframe) {
2720
+ (0, import_log10.log)("waiting for latest timeframe", {
2295
2721
  spaceMetadata
2296
2722
  }, {
2297
2723
  file: "data-space-manager.ts",
2298
- line: 60,
2724
+ line: 74,
2299
2725
  scope: this,
2300
2726
  callSite: (f, a) => f(...a)
2301
2727
  });
2302
- await space.dataPipelineController.waitUntilTimeframe(spaceMetadata.latestTimeframe);
2728
+ await space.dataPipelineController.pipelineState.setTargetTimeframe(spaceMetadata.dataTimeframe);
2303
2729
  }
2730
+ await space.dataPipelineController.pipelineState.waitUntilReachedTargetTimeframe({
2731
+ timeout: DATA_PIPELINE_READY_TIMEOUT
2732
+ });
2733
+ this._dataServiceSubscriptions.registerSpace(space.key, space.dataPipelineController.databaseBackend.createDataServiceHost());
2304
2734
  }
2305
2735
  }
2306
2736
  async close() {
@@ -2322,30 +2752,36 @@ var DataSpaceManager = class DataSpaceManager2 {
2322
2752
  controlFeedKey,
2323
2753
  dataFeedKey
2324
2754
  };
2325
- (0, import_log9.log)("creating space...", {
2755
+ (0, import_log10.log)("creating space...", {
2326
2756
  spaceKey
2327
2757
  }, {
2328
2758
  file: "data-space-manager.ts",
2329
- line: 89,
2759
+ line: 110,
2330
2760
  scope: this,
2331
2761
  callSite: (f, a) => f(...a)
2332
2762
  });
2333
2763
  const space = await this._constructSpace(metadata);
2334
- await (0, import_echo_db2.spaceGenesis)(this._keyring, this._signingContext, space.inner);
2764
+ const credentials = await (0, import_echo_pipeline2.spaceGenesis)(this._keyring, this._signingContext, space.inner);
2335
2765
  await this._metadataStore.addSpace(metadata);
2766
+ const memberCredential = credentials[1];
2767
+ (0, import_node_assert12.default)((0, import_credentials10.getCredentialAssertion)(memberCredential)["@type"] === "dxos.halo.credentials.SpaceMember");
2768
+ await this._signingContext.recordCredential(memberCredential);
2769
+ await space.initializeDataPipeline();
2770
+ this._dataServiceSubscriptions.registerSpace(space.key, space.dataPipelineController.databaseBackend.createDataServiceHost());
2336
2771
  this.updated.emit();
2337
2772
  return space;
2338
2773
  }
2339
2774
  // TODO(burdon): Rename join space.
2340
2775
  async acceptSpace(opts) {
2776
+ (0, import_node_assert12.default)(!this._spaces.has(opts.spaceKey), "Space already exists.");
2341
2777
  const metadata = {
2342
2778
  key: opts.spaceKey,
2343
- genesisFeedKey: opts.genesisFeedKey,
2344
- controlFeedKey: opts.controlFeedKey,
2345
- dataFeedKey: opts.dataFeedKey
2779
+ genesisFeedKey: opts.genesisFeedKey
2346
2780
  };
2347
2781
  const space = await this._constructSpace(metadata);
2348
2782
  await this._metadataStore.addSpace(metadata);
2783
+ await space.initializeDataPipeline();
2784
+ this._dataServiceSubscriptions.registerSpace(space.key, space.dataPipelineController.databaseBackend.createDataServiceHost());
2349
2785
  this.updated.emit();
2350
2786
  return space;
2351
2787
  }
@@ -2356,21 +2792,30 @@ var DataSpaceManager = class DataSpaceManager2 {
2356
2792
  offlineTimeout: 3e4,
2357
2793
  identityKey: this._signingContext.identityKey
2358
2794
  });
2359
- const snapshotManager = new import_echo_db2.SnapshotManager(this._snapshotStore);
2795
+ const snapshotManager = new import_echo_pipeline2.SnapshotManager(this._snapshotStore);
2796
+ const controlFeed = metadata.controlFeedKey && await this._feedStore.openFeed(metadata.controlFeedKey, {
2797
+ writable: true
2798
+ });
2799
+ const dataFeed = metadata.dataFeedKey && await this._feedStore.openFeed(metadata.dataFeedKey, {
2800
+ writable: true
2801
+ });
2360
2802
  const space = await this._spaceManager.constructSpace({
2361
2803
  metadata,
2362
2804
  swarmIdentity: {
2363
2805
  peerKey: this._signingContext.deviceKey,
2364
- credentialProvider: this._signingContext.credentialProvider,
2365
- credentialAuthenticator: this._signingContext.credentialAuthenticator
2806
+ credentialProvider: createAuthProvider(this._signingContext.credentialSigner),
2807
+ credentialAuthenticator: (0, import_util6.deferFunction)(() => dataSpace.authVerifier.verifier)
2366
2808
  },
2367
2809
  onNetworkConnection: (session) => {
2368
2810
  session.addExtension("dxos.mesh.teleport.presence", presence.createExtension({
2369
2811
  remotePeerId: session.remotePeerId
2370
2812
  }));
2371
2813
  session.addExtension("dxos.mesh.teleport.objectsync", snapshotManager.objectSync.createExtension());
2814
+ session.addExtension("dxos.mesh.teleport.notarization", dataSpace.notarizationPlugin.createExtension());
2372
2815
  }
2373
2816
  });
2817
+ controlFeed && space.setControlFeed(controlFeed);
2818
+ dataFeed && space.setDataFeed(dataFeed);
2374
2819
  const dataSpace = new DataSpace({
2375
2820
  inner: space,
2376
2821
  modelFactory: this._modelFactory,
@@ -2378,10 +2823,12 @@ var DataSpaceManager = class DataSpaceManager2 {
2378
2823
  snapshotManager,
2379
2824
  presence,
2380
2825
  memberKey: this._signingContext.identityKey,
2826
+ keyring: this._keyring,
2827
+ feedStore: this._feedStore,
2828
+ signingContext: this._signingContext,
2381
2829
  snapshotId: metadata.snapshot
2382
2830
  });
2383
2831
  await dataSpace.open();
2384
- this._dataServiceSubscriptions.registerSpace(space.key, dataSpace.database.createDataServiceHost());
2385
2832
  this._spaces.set(metadata.key, dataSpace);
2386
2833
  return dataSpace;
2387
2834
  }
@@ -2410,30 +2857,38 @@ var ServiceContext = class {
2410
2857
  this.networkManager = networkManager;
2411
2858
  this.modelFactory = modelFactory;
2412
2859
  this.initialized = new import_async13.Trigger();
2413
- this.dataServiceSubscriptions = new import_echo_db3.DataServiceSubscriptions();
2414
- this.metadataStore = new import_echo_db3.MetadataStore(storage.createDirectory("metadata"));
2415
- this.snapshotStore = new import_echo_db3.SnapshotStore(storage.createDirectory("snapshots"));
2860
+ this.dataServiceSubscriptions = new import_echo_pipeline3.DataServiceSubscriptions();
2861
+ this.metadataStore = new import_echo_pipeline3.MetadataStore(storage.createDirectory("metadata"));
2862
+ this.snapshotStore = new import_echo_pipeline3.SnapshotStore(storage.createDirectory("snapshots"));
2416
2863
  this.keyring = new import_keyring.Keyring(storage.createDirectory("keyring"));
2417
2864
  this.feedStore = new import_feed_store4.FeedStore({
2418
2865
  factory: new import_feed_store4.FeedFactory({
2419
2866
  root: storage.createDirectory("feeds"),
2420
2867
  signer: this.keyring,
2421
2868
  hypercore: {
2422
- valueEncoding: import_echo_db3.valueEncoding
2869
+ valueEncoding: import_echo_pipeline3.valueEncoding
2423
2870
  }
2424
2871
  })
2425
2872
  });
2426
- this.spaceManager = new import_echo_db3.SpaceManager({
2873
+ this.spaceManager = new import_echo_pipeline3.SpaceManager({
2427
2874
  feedStore: this.feedStore,
2428
2875
  networkManager: this.networkManager
2429
2876
  });
2430
- this.identityManager = new IdentityManager(this.metadataStore, this.keyring, this.spaceManager);
2431
- this.haloInvitations = new HaloInvitationsHandler(this.networkManager, this.identityManager);
2877
+ this.identityManager = new IdentityManager(this.metadataStore, this.keyring, this.feedStore, this.spaceManager);
2878
+ this.haloInvitations = new HaloInvitationsHandler({
2879
+ networkManager: this.networkManager,
2880
+ getIdentity: () => {
2881
+ var _a;
2882
+ return (_a = this.identityManager.identity) != null ? _a : (0, import_debug5.failUndefined)();
2883
+ },
2884
+ acceptIdentity: this._acceptIdentity.bind(this),
2885
+ keyring: this.keyring
2886
+ });
2432
2887
  }
2433
2888
  async open() {
2434
- (0, import_log10.log)("opening...", {}, {
2889
+ (0, import_log11.log)("opening...", {}, {
2435
2890
  file: "service-context.ts",
2436
- line: 85,
2891
+ line: 94,
2437
2892
  scope: this,
2438
2893
  callSite: (f, a) => f(...a)
2439
2894
  });
@@ -2443,46 +2898,47 @@ var ServiceContext = class {
2443
2898
  if (this.identityManager.identity) {
2444
2899
  await this._initialize();
2445
2900
  }
2446
- (0, import_log10.log)("opened", {}, {
2901
+ (0, import_log11.log)("opened", {}, {
2447
2902
  file: "service-context.ts",
2448
- line: 92,
2903
+ line: 101,
2449
2904
  scope: this,
2450
2905
  callSite: (f, a) => f(...a)
2451
2906
  });
2452
2907
  }
2453
2908
  async close() {
2454
- var _a;
2455
- (0, import_log10.log)("closing...", {}, {
2909
+ var _a, _b;
2910
+ (0, import_log11.log)("closing...", {}, {
2456
2911
  file: "service-context.ts",
2457
- line: 96,
2912
+ line: 105,
2458
2913
  scope: this,
2459
2914
  callSite: (f, a) => f(...a)
2460
2915
  });
2461
- await ((_a = this.dataSpaceManager) == null ? void 0 : _a.close());
2916
+ await ((_a = this._deviceSpaceSync) == null ? void 0 : _a.close());
2917
+ await ((_b = this.dataSpaceManager) == null ? void 0 : _b.close());
2462
2918
  await this.identityManager.close();
2463
2919
  await this.spaceManager.close();
2464
2920
  await this.feedStore.close();
2465
2921
  await this.networkManager.close();
2466
2922
  this.dataServiceSubscriptions.clear();
2467
- (0, import_log10.log)("closed", {}, {
2923
+ (0, import_log11.log)("closed", {}, {
2468
2924
  file: "service-context.ts",
2469
- line: 103,
2925
+ line: 113,
2470
2926
  scope: this,
2471
2927
  callSite: (f, a) => f(...a)
2472
2928
  });
2473
2929
  }
2474
2930
  async reset() {
2475
- (0, import_log10.log)("resetting...", {}, {
2931
+ (0, import_log11.log)("resetting...", {}, {
2476
2932
  file: "service-context.ts",
2477
- line: 107,
2933
+ line: 117,
2478
2934
  scope: this,
2479
2935
  callSite: (f, a) => f(...a)
2480
2936
  });
2481
2937
  await this.close();
2482
2938
  await this.storage.reset();
2483
- (0, import_log10.log)("reset", {}, {
2939
+ (0, import_log11.log)("reset", {}, {
2484
2940
  file: "service-context.ts",
2485
- line: 110,
2941
+ line: 120,
2486
2942
  scope: this,
2487
2943
  callSite: (f, a) => f(...a)
2488
2944
  });
@@ -2492,55 +2948,121 @@ var ServiceContext = class {
2492
2948
  await this._initialize();
2493
2949
  return identity;
2494
2950
  }
2951
+ async _acceptIdentity(params) {
2952
+ const identity = await this.identityManager.acceptIdentity(params);
2953
+ await this._initialize();
2954
+ return identity;
2955
+ }
2495
2956
  // Called when identity is created.
2496
2957
  async _initialize() {
2497
2958
  var _a;
2498
- (0, import_log10.log)("initializing spaces...", {}, {
2959
+ (0, import_log11.log)("initializing spaces...", {}, {
2499
2960
  file: "service-context.ts",
2500
- line: 122,
2961
+ line: 139,
2501
2962
  scope: this,
2502
2963
  callSite: (f, a) => f(...a)
2503
2964
  });
2504
- const identity = (_a = this.identityManager.identity) != null ? _a : (0, import_debug4.failUndefined)();
2965
+ const identity = (_a = this.identityManager.identity) != null ? _a : (0, import_debug5.failUndefined)();
2505
2966
  const signingContext = {
2506
- credentialProvider: import_echo_db3.MOCK_AUTH_PROVIDER,
2507
- credentialAuthenticator: import_echo_db3.MOCK_AUTH_VERIFIER,
2508
2967
  credentialSigner: identity.getIdentityCredentialSigner(),
2509
2968
  identityKey: identity.identityKey,
2510
2969
  deviceKey: identity.deviceKey,
2511
- profile: identity.profileDocument
2970
+ profile: identity.profileDocument,
2971
+ recordCredential: async (credential) => {
2972
+ await identity.controlPipeline.writer.write({
2973
+ credential: {
2974
+ credential
2975
+ }
2976
+ });
2977
+ }
2512
2978
  };
2513
- this.dataSpaceManager = new DataSpaceManager(this.spaceManager, this.metadataStore, this.dataServiceSubscriptions, this.keyring, signingContext, this.modelFactory, this.snapshotStore);
2979
+ this.dataSpaceManager = new DataSpaceManager(this.spaceManager, this.metadataStore, this.dataServiceSubscriptions, this.keyring, signingContext, this.modelFactory, this.feedStore, this.snapshotStore);
2514
2980
  await this.dataSpaceManager.open();
2515
2981
  this.spaceInvitations = new SpaceInvitationsHandler(this.networkManager, this.dataSpaceManager, signingContext, this.keyring);
2516
2982
  this.initialized.wake();
2983
+ this._deviceSpaceSync = identity.space.spaceState.registerProcessor({
2984
+ process: async (credential) => {
2985
+ const assertion = (0, import_credentials11.getCredentialAssertion)(credential);
2986
+ if (assertion["@type"] !== "dxos.halo.credentials.SpaceMember") {
2987
+ return;
2988
+ }
2989
+ if (assertion.spaceKey.equals(identity.space.key)) {
2990
+ return;
2991
+ }
2992
+ if (!this.dataSpaceManager) {
2993
+ (0, import_log11.log)("dataSpaceManager not initialized yet, ignoring space admission", {
2994
+ details: assertion
2995
+ }, {
2996
+ file: "service-context.ts",
2997
+ line: 182,
2998
+ scope: this,
2999
+ callSite: (f, a) => f(...a)
3000
+ });
3001
+ return;
3002
+ }
3003
+ if (this.dataSpaceManager.spaces.has(assertion.spaceKey)) {
3004
+ (0, import_log11.log)("space already exists, ignoring space admission", {
3005
+ details: assertion
3006
+ }, {
3007
+ file: "service-context.ts",
3008
+ line: 186,
3009
+ scope: this,
3010
+ callSite: (f, a) => f(...a)
3011
+ });
3012
+ return;
3013
+ }
3014
+ try {
3015
+ (0, import_log11.log)("accepting space recorded in halo", {
3016
+ details: assertion
3017
+ }, {
3018
+ file: "service-context.ts",
3019
+ line: 191,
3020
+ scope: this,
3021
+ callSite: (f, a) => f(...a)
3022
+ });
3023
+ await this.dataSpaceManager.acceptSpace({
3024
+ spaceKey: assertion.spaceKey,
3025
+ genesisFeedKey: assertion.genesisFeedKey
3026
+ });
3027
+ } catch (err) {
3028
+ import_log11.log.catch(err, {}, {
3029
+ file: "service-context.ts",
3030
+ line: 197,
3031
+ scope: this,
3032
+ callSite: (f, a) => f(...a)
3033
+ });
3034
+ }
3035
+ }
3036
+ });
3037
+ await this._deviceSpaceSync.open();
2517
3038
  }
2518
3039
  };
2519
3040
 
2520
3041
  // packages/sdk/client-services/src/packlets/services/service-definitions.ts
2521
- var import_protocols5 = require("@dxos/protocols");
3042
+ var import_protocols6 = require("@dxos/protocols");
2522
3043
  var import_rpc = require("@dxos/rpc");
2523
3044
  var clientServiceBundle = (0, import_rpc.createServiceBundle)({
2524
- HaloInvitationsService: import_protocols5.schema.getService("dxos.client.services.HaloInvitationsService"),
2525
- DevicesService: import_protocols5.schema.getService("dxos.client.services.DevicesService"),
2526
- SpaceInvitationsService: import_protocols5.schema.getService("dxos.client.services.SpaceInvitationsService"),
2527
- SpacesService: import_protocols5.schema.getService("dxos.client.services.SpacesService"),
2528
- NetworkService: import_protocols5.schema.getService("dxos.client.services.NetworkService"),
3045
+ HaloInvitationsService: import_protocols6.schema.getService("dxos.client.services.HaloInvitationsService"),
3046
+ DevicesService: import_protocols6.schema.getService("dxos.client.services.DevicesService"),
3047
+ SpaceInvitationsService: import_protocols6.schema.getService("dxos.client.services.SpaceInvitationsService"),
3048
+ SpacesService: import_protocols6.schema.getService("dxos.client.services.SpacesService"),
3049
+ NetworkService: import_protocols6.schema.getService("dxos.client.services.NetworkService"),
2529
3050
  // TODO(burdon): Deprecated.
2530
- SpaceService: import_protocols5.schema.getService("dxos.client.SpaceService"),
2531
- DataService: import_protocols5.schema.getService("dxos.echo.service.DataService"),
2532
- ProfileService: import_protocols5.schema.getService("dxos.client.ProfileService"),
2533
- SystemService: import_protocols5.schema.getService("dxos.client.SystemService"),
2534
- DevtoolsHost: import_protocols5.schema.getService("dxos.devtools.host.DevtoolsHost"),
2535
- TracingService: import_protocols5.schema.getService("dxos.devtools.host.TracingService")
3051
+ SpaceService: import_protocols6.schema.getService("dxos.client.SpaceService"),
3052
+ DataService: import_protocols6.schema.getService("dxos.echo.service.DataService"),
3053
+ ProfileService: import_protocols6.schema.getService("dxos.client.ProfileService"),
3054
+ SystemService: import_protocols6.schema.getService("dxos.client.SystemService"),
3055
+ DevtoolsHost: import_protocols6.schema.getService("dxos.devtools.host.DevtoolsHost"),
3056
+ TracingService: import_protocols6.schema.getService("dxos.devtools.host.TracingService")
2536
3057
  });
2537
3058
 
2538
3059
  // packages/sdk/client-services/src/packlets/services/service-host.ts
2539
- var import_debug6 = require("@dxos/debug");
2540
- var import_echo_db5 = require("@dxos/echo-db");
2541
- var import_log11 = require("@dxos/log");
3060
+ var import_debug7 = require("@dxos/debug");
3061
+ var import_document_model = require("@dxos/document-model");
3062
+ var import_echo_pipeline5 = require("@dxos/echo-pipeline");
3063
+ var import_log17 = require("@dxos/log");
2542
3064
  var import_model_factory = require("@dxos/model-factory");
2543
- var import_object_model = require("@dxos/object-model");
3065
+ var import_client2 = require("@dxos/protocols/proto/dxos/client");
2544
3066
  var import_text_model = require("@dxos/text-model");
2545
3067
 
2546
3068
  // packages/sdk/client-services/src/packlets/identity/devices-service-impl.ts
@@ -2610,8 +3132,8 @@ var NetworkServiceImpl = class {
2610
3132
  // packages/sdk/client-services/src/packlets/spaces/spaces-service.ts
2611
3133
  var import_async15 = require("@dxos/async");
2612
3134
  var import_codec_protobuf11 = require("@dxos/codec-protobuf");
2613
- var import_debug5 = require("@dxos/debug");
2614
- var import_echo_db4 = require("@dxos/echo-db");
3135
+ var import_debug6 = require("@dxos/debug");
3136
+ var import_echo_pipeline4 = require("@dxos/echo-pipeline");
2615
3137
  var SpacesServiceImpl = class {
2616
3138
  constructor(_spaceManager) {
2617
3139
  this._spaceManager = _spaceManager;
@@ -2628,7 +3150,7 @@ var SpacesServiceImpl = class {
2628
3150
  queryCredentials({ spaceKey }) {
2629
3151
  return new import_codec_protobuf11.Stream(({ ctx, next }) => {
2630
3152
  var _a;
2631
- const space = (_a = this._spaceManager.spaces.get(spaceKey)) != null ? _a : (0, import_debug5.raise)(new import_echo_db4.SpaceNotFoundError(spaceKey));
3153
+ const space = (_a = this._spaceManager.spaces.get(spaceKey)) != null ? _a : (0, import_debug6.raise)(new import_echo_pipeline4.SpaceNotFoundError(spaceKey));
2632
3154
  const processor = space.spaceState.registerProcessor({
2633
3155
  process: async (credential) => {
2634
3156
  next(credential);
@@ -2638,6 +3160,17 @@ var SpacesServiceImpl = class {
2638
3160
  (0, import_async15.scheduleTask)(ctx, () => processor.open());
2639
3161
  });
2640
3162
  }
3163
+ async writeCredentials({ spaceKey, credentials }) {
3164
+ var _a;
3165
+ const space = (_a = this._spaceManager.spaces.get(spaceKey)) != null ? _a : (0, import_debug6.raise)(new import_echo_pipeline4.SpaceNotFoundError(spaceKey));
3166
+ for (const credential of credentials != null ? credentials : []) {
3167
+ await space.controlPipeline.writer.write({
3168
+ credential: {
3169
+ credential
3170
+ }
3171
+ });
3172
+ }
3173
+ }
2641
3174
  };
2642
3175
 
2643
3176
  // packages/sdk/client-services/src/packlets/storage/storage.ts
@@ -2685,169 +3218,265 @@ var toStorageType = (type) => {
2685
3218
  }
2686
3219
  };
2687
3220
 
2688
- // packages/sdk/client-services/src/packlets/services/service-registry.ts
2689
- var ServiceRegistry = class {
2690
- // prettier-ignore
2691
- constructor(_serviceBundle, _handlers) {
2692
- this._serviceBundle = _serviceBundle;
2693
- this._handlers = _handlers;
3221
+ // packages/sdk/client-services/src/packlets/vault/iframe-host-runtime.ts
3222
+ var import_async17 = require("@dxos/async");
3223
+ var import_log12 = require("@dxos/log");
3224
+ var import_messaging = require("@dxos/messaging");
3225
+ var import_network_manager3 = require("@dxos/network-manager");
3226
+ var import_rpc3 = require("@dxos/rpc");
3227
+ var import_util7 = require("@dxos/util");
3228
+
3229
+ // packages/sdk/client-services/src/packlets/vault/shell-runtime.ts
3230
+ var import_node_assert13 = __toESM(require("node:assert"));
3231
+ var import_async16 = require("@dxos/async");
3232
+ var import_iframe = require("@dxos/protocols/proto/dxos/iframe");
3233
+ var import_rpc2 = require("@dxos/rpc");
3234
+
3235
+ // packages/sdk/client-services/src/packlets/vault/services.ts
3236
+ var import_protocols7 = require("@dxos/protocols");
3237
+ var iframeServiceBundle = {
3238
+ IframeService: import_protocols7.schema.getService("dxos.iframe.IframeService"),
3239
+ BridgeService: import_protocols7.schema.getService("dxos.mesh.bridge.BridgeService")
3240
+ };
3241
+ var workerServiceBundle = {
3242
+ WorkerService: import_protocols7.schema.getService("dxos.iframe.WorkerService")
3243
+ };
3244
+ var appServiceBundle = {
3245
+ AppService: import_protocols7.schema.getService("dxos.iframe.AppService")
3246
+ };
3247
+ var shellServiceBundle = {
3248
+ ShellService: import_protocols7.schema.getService("dxos.iframe.ShellService")
3249
+ };
3250
+
3251
+ // packages/sdk/client-services/src/packlets/vault/shell-runtime.ts
3252
+ var ShellRuntimeImpl = class {
3253
+ constructor(_port) {
3254
+ this._port = _port;
3255
+ this.layoutUpdate = new import_async16.Event();
3256
+ this._layout = import_iframe.ShellLayout.DEFAULT;
3257
+ }
3258
+ get layout() {
3259
+ return this._layout;
3260
+ }
3261
+ get invitationCode() {
3262
+ return this._invitationCode;
3263
+ }
3264
+ get spaceKey() {
3265
+ return this._spaceKey;
3266
+ }
3267
+ setLayout(layout, options = {}) {
3268
+ this._layout = layout;
3269
+ this._invitationCode = options.invitationCode;
3270
+ this._spaceKey = options.spaceKey;
3271
+ this.layoutUpdate.emit({
3272
+ layout,
3273
+ ...options
3274
+ });
2694
3275
  }
2695
- get descriptors() {
2696
- return this._serviceBundle;
3276
+ async setAppContext(context) {
3277
+ (0, import_node_assert13.default)(this._appRpc, "runtime not open");
3278
+ if (context.spaceKey) {
3279
+ this._spaceKey = context.spaceKey;
3280
+ }
3281
+ if (context.invitationCode) {
3282
+ this._invitationCode = context.invitationCode;
3283
+ }
3284
+ await this._appRpc.rpc.AppService.setContext({
3285
+ ...context,
3286
+ spaceKey: this._spaceKey,
3287
+ invitationCode: this._invitationCode
3288
+ });
2697
3289
  }
2698
- get services() {
2699
- return this._handlers;
3290
+ async open() {
3291
+ this._appRpc = (0, import_rpc2.createProtoRpcPeer)({
3292
+ requested: appServiceBundle,
3293
+ exposed: shellServiceBundle,
3294
+ handlers: {
3295
+ ShellService: {
3296
+ setLayout: async (request) => {
3297
+ this._layout = request.layout;
3298
+ this._invitationCode = request.invitationCode;
3299
+ this._spaceKey = request.spaceKey;
3300
+ this.layoutUpdate.emit(request);
3301
+ }
3302
+ }
3303
+ },
3304
+ port: this._port
3305
+ });
3306
+ await this._appRpc.open();
3307
+ }
3308
+ async close() {
3309
+ var _a;
3310
+ await ((_a = this._appRpc) == null ? void 0 : _a.close());
3311
+ this._appRpc = void 0;
3312
+ }
3313
+ };
3314
+ var MemoryShellRuntime = class {
3315
+ constructor({ layout, invitationCode, spaceKey } = {}) {
3316
+ this.layoutUpdate = new import_async16.Event();
3317
+ this.contextUpdate = new import_async16.Event();
3318
+ this._layout = layout != null ? layout : import_iframe.ShellLayout.DEFAULT;
3319
+ this._invitationCode = invitationCode;
3320
+ this._spaceKey = spaceKey;
3321
+ }
3322
+ get layout() {
3323
+ return this._layout;
3324
+ }
3325
+ get invitationCode() {
3326
+ return this._invitationCode;
3327
+ }
3328
+ get spaceKey() {
3329
+ return this._spaceKey;
3330
+ }
3331
+ setLayout(layout, options = {}) {
3332
+ this._layout = layout;
3333
+ this._invitationCode = options.invitationCode;
3334
+ this._spaceKey = options.spaceKey;
3335
+ this.layoutUpdate.emit({
3336
+ layout,
3337
+ ...options
3338
+ });
3339
+ }
3340
+ async setAppContext(context) {
3341
+ this.contextUpdate.emit(context);
2700
3342
  }
2701
3343
  };
2702
3344
 
2703
- // packages/sdk/client-services/src/packlets/services/service-host.ts
2704
- var createDefaultModelFactory = () => {
2705
- return new import_model_factory.ModelFactory().registerModel(import_object_model.ObjectModel).registerModel(import_text_model.TextModel);
3345
+ // packages/sdk/client-services/src/packlets/vault/iframe-host-runtime.ts
3346
+ var __decorate3 = function(decorators, target, key, desc) {
3347
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3348
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
3349
+ r = Reflect.decorate(decorators, target, key, desc);
3350
+ else
3351
+ for (var i = decorators.length - 1; i >= 0; i--)
3352
+ if (d = decorators[i])
3353
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3354
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2706
3355
  };
2707
- var ClientServicesHost = class {
2708
- constructor({
2709
- config,
2710
- modelFactory = createDefaultModelFactory(),
2711
- // TODO(burdon): Create ApolloLink abstraction (see Client).
2712
- networkManager,
2713
- storage = createStorageObjects(config.get("runtime.client.storage", {})).storage
2714
- }) {
2715
- this._config = config;
2716
- this._modelFactory = modelFactory;
2717
- this._networkManager = networkManager;
2718
- this._storage = storage;
2719
- }
2720
- get descriptors() {
2721
- return this._serviceRegistry.descriptors;
3356
+ var LOCK_KEY = "DXOS_RESOURCE_LOCK";
3357
+ var IFrameHostRuntime = class {
3358
+ constructor({ configProvider, appPort, shellPort }) {
3359
+ this._transportFactory = (0, import_network_manager3.createWebRTCTransportFactory)();
3360
+ this._ready = new import_async17.Trigger();
3361
+ this._configProvider = configProvider;
3362
+ this._appPort = appPort;
3363
+ this._shellPort = shellPort;
3364
+ this._getService = async (find) => {
3365
+ const error = await this._ready.wait();
3366
+ if (error) {
3367
+ throw error;
3368
+ }
3369
+ const service = await find(this._clientServices.services);
3370
+ if (!service) {
3371
+ throw new Error("Service not found");
3372
+ }
3373
+ return service;
3374
+ };
3375
+ if (this._shellPort) {
3376
+ this._shellRuntime = new ShellRuntimeImpl(this._shellPort);
3377
+ }
2722
3378
  }
2723
3379
  get services() {
2724
- return this._serviceRegistry.services;
3380
+ return this._clientServices;
2725
3381
  }
2726
- async open() {
3382
+ get shell() {
3383
+ return this._shellRuntime;
3384
+ }
3385
+ async start() {
2727
3386
  var _a;
2728
- (0, import_log11.log)("opening...", {}, {
2729
- file: "service-host.ts",
2730
- line: 73,
2731
- scope: this,
2732
- callSite: (f, a) => f(...a)
2733
- });
2734
- await this._initialize();
2735
- await this._serviceContext.open();
2736
- const deviceKey = (_a = this._serviceContext.identityManager.identity) == null ? void 0 : _a.deviceKey;
2737
- (0, import_log11.log)("opened", {
2738
- deviceKey
2739
- }, {
2740
- file: "service-host.ts",
2741
- line: 77,
3387
+ (0, import_log12.log)("starting...", {}, {
3388
+ file: "iframe-host-runtime.ts",
3389
+ line: 81,
2742
3390
  scope: this,
2743
3391
  callSite: (f, a) => f(...a)
2744
3392
  });
3393
+ try {
3394
+ this._config = await (0, import_util7.getAsyncValue)(this._configProvider);
3395
+ const signalServer = this._config.get("runtime.services.signal.server");
3396
+ this._clientServices = new ClientServicesHost({
3397
+ lockKey: LOCK_KEY,
3398
+ config: this._config,
3399
+ networkManager: new import_network_manager3.NetworkManager({
3400
+ log: true,
3401
+ signalManager: signalServer ? new import_messaging.WebsocketSignalManager([
3402
+ signalServer
3403
+ ]) : new import_messaging.MemorySignalManager(new import_messaging.MemorySignalManagerContext()),
3404
+ transportFactory: this._transportFactory
3405
+ })
3406
+ });
3407
+ this._clientRpc = (0, import_rpc3.createProtoRpcPeer)({
3408
+ exposed: clientServiceBundle,
3409
+ handlers: {
3410
+ DataService: async () => await this._getService((services) => services.DataService),
3411
+ DevicesService: async () => await this._getService((services) => services.DevicesService),
3412
+ DevtoolsHost: async () => await this._getService((services) => services.DevtoolsHost),
3413
+ HaloInvitationsService: async () => await this._getService((services) => services.HaloInvitationsService),
3414
+ NetworkService: async () => await this._getService((services) => services.NetworkService),
3415
+ ProfileService: async () => await this._getService((services) => services.ProfileService),
3416
+ SpaceInvitationsService: async () => await this._getService((services) => services.SpaceInvitationsService),
3417
+ SpaceService: async () => await this._getService((services) => services.SpaceService),
3418
+ SpacesService: async () => await this._getService((services) => services.SpacesService),
3419
+ SystemService: async () => await this._getService((services) => services.SystemService),
3420
+ TracingService: async () => await this._getService((services) => services.TracingService)
3421
+ },
3422
+ port: this._appPort
3423
+ });
3424
+ await Promise.all([
3425
+ this._clientServices.open(),
3426
+ this._clientRpc.open(),
3427
+ (_a = this._shellRuntime) == null ? void 0 : _a.open()
3428
+ ]);
3429
+ this._ready.wake(void 0);
3430
+ (0, import_log12.log)("started", {}, {
3431
+ file: "iframe-host-runtime.ts",
3432
+ line: 117,
3433
+ scope: this,
3434
+ callSite: (f, a) => f(...a)
3435
+ });
3436
+ } catch (err) {
3437
+ this._ready.wake(err);
3438
+ import_log12.log.catch(err, {}, {
3439
+ file: "iframe-host-runtime.ts",
3440
+ line: 120,
3441
+ scope: this,
3442
+ callSite: (f, a) => f(...a)
3443
+ });
3444
+ }
2745
3445
  }
2746
- async close() {
3446
+ async stop() {
2747
3447
  var _a;
2748
- const deviceKey = (_a = this._serviceContext.identityManager.identity) == null ? void 0 : _a.deviceKey;
2749
- (0, import_log11.log)("closing...", {
2750
- deviceKey
2751
- }, {
2752
- file: "service-host.ts",
2753
- line: 82,
3448
+ (0, import_log12.log)("stopping...", {}, {
3449
+ file: "iframe-host-runtime.ts",
3450
+ line: 125,
2754
3451
  scope: this,
2755
3452
  callSite: (f, a) => f(...a)
2756
3453
  });
2757
- await this._serviceContext.close();
2758
- (0, import_log11.log)("closed", {
2759
- deviceKey
2760
- }, {
2761
- file: "service-host.ts",
2762
- line: 84,
3454
+ await this._clientRpc.close();
3455
+ await this._clientServices.close();
3456
+ await ((_a = this._shellRuntime) == null ? void 0 : _a.close());
3457
+ (0, import_log12.log)("stopped", {}, {
3458
+ file: "iframe-host-runtime.ts",
3459
+ line: 129,
2763
3460
  scope: this,
2764
3461
  callSite: (f, a) => f(...a)
2765
3462
  });
2766
3463
  }
2767
- // TODO(burdon): Move into open.
2768
- async _initialize() {
2769
- this._serviceContext = new ServiceContext(this._storage, this._networkManager, this._modelFactory);
2770
- this._serviceRegistry = new ServiceRegistry(clientServiceBundle, {
2771
- HaloInvitationsService: new HaloInvitationsServiceImpl(this._serviceContext.identityManager, this._serviceContext.haloInvitations),
2772
- DevicesService: new DevicesServiceImpl(this._serviceContext.identityManager),
2773
- SpaceInvitationsService: new SpaceInvitationsServiceImpl(this._serviceContext.identityManager, () => {
2774
- var _a;
2775
- return (_a = this._serviceContext.spaceInvitations) != null ? _a : (0, import_debug6.raise)(new Error("SpaceInvitations not initialized"));
2776
- }, () => {
2777
- var _a;
2778
- return (_a = this._serviceContext.dataSpaceManager) != null ? _a : (0, import_debug6.raise)(new Error("SpaceManager not initialized"));
2779
- }),
2780
- SpacesService: new SpacesServiceImpl(this._serviceContext.spaceManager),
2781
- DataService: new import_echo_db5.DataServiceImpl(this._serviceContext.dataServiceSubscriptions),
2782
- NetworkService: new NetworkServiceImpl(this._serviceContext.networkManager),
2783
- // TODO(burdon): Move to new protobuf definitions.
2784
- ProfileService: new ProfileServiceImpl(this._serviceContext),
2785
- SpaceService: new SpaceServiceImpl(this._serviceContext),
2786
- SystemService: new SystemServiceImpl(this._config, this._serviceContext),
2787
- TracingService: new TracingServiceImpl(this._config),
2788
- DevtoolsHost: new DevtoolsServiceImpl({
2789
- events: new DevtoolsHostEvents(),
2790
- config: this._config,
2791
- context: this._serviceContext
2792
- })
2793
- });
2794
- }
2795
- };
2796
-
2797
- // packages/sdk/client-services/src/packlets/services/service-proxy.ts
2798
- var import_async16 = require("@dxos/async");
2799
- var import_errors2 = require("@dxos/errors");
2800
- var import_rpc2 = require("@dxos/rpc");
2801
- var ClientServicesProxy = class {
2802
- // prettier-ignore
2803
- constructor(port, _timeout = 3e4) {
2804
- this._timeout = _timeout;
2805
- this._proxy = (0, import_rpc2.createProtoRpcPeer)({
2806
- requested: clientServiceBundle,
2807
- exposed: {},
2808
- handlers: {},
2809
- port
2810
- });
2811
- }
2812
- get proxy() {
2813
- return this._proxy;
2814
- }
2815
- get descriptors() {
2816
- return clientServiceBundle;
2817
- }
2818
- get services() {
2819
- return this._proxy.rpc;
2820
- }
2821
- async open() {
2822
- await (0, import_async16.asyncTimeout)(this._proxy.open(), this._timeout, new import_errors2.RemoteServiceConnectionTimeout());
2823
- }
2824
- async close() {
2825
- await this._proxy.close();
2826
- }
2827
- };
2828
-
2829
- // packages/sdk/client-services/src/packlets/vault/iframe-runtime.ts
2830
- var import_network_manager3 = require("@dxos/network-manager");
2831
- var import_rpc3 = require("@dxos/rpc");
2832
-
2833
- // packages/sdk/client-services/src/packlets/vault/services.ts
2834
- var import_protocols6 = require("@dxos/protocols");
2835
- var iframeServiceBundle = {
2836
- IframeService: import_protocols6.schema.getService("dxos.iframe.IframeService"),
2837
- BridgeService: import_protocols6.schema.getService("dxos.mesh.bridge.BridgeService")
2838
- };
2839
- var workerServiceBundle = {
2840
- WorkerService: import_protocols6.schema.getService("dxos.iframe.WorkerService")
2841
3464
  };
3465
+ __decorate3([
3466
+ import_log12.logInfo
3467
+ ], IFrameHostRuntime.prototype, "origin", void 0);
2842
3468
 
2843
- // packages/sdk/client-services/src/packlets/vault/iframe-runtime.ts
2844
- var IFrameRuntime = class {
2845
- constructor({ systemPort, workerAppPort, windowAppPort }) {
2846
- this._transportService = new import_network_manager3.WebRTCTransportService();
3469
+ // packages/sdk/client-services/src/packlets/vault/iframe-proxy-runtime.ts
3470
+ var import_network_manager4 = require("@dxos/network-manager");
3471
+ var import_rpc4 = require("@dxos/rpc");
3472
+ var IFrameProxyRuntime = class {
3473
+ constructor({ systemPort, workerAppPort, windowAppPort, shellPort }) {
3474
+ this._transportService = new import_network_manager4.WebRTCTransportService();
2847
3475
  this._systemPort = systemPort;
2848
3476
  this._windowAppPort = windowAppPort;
2849
3477
  this._workerAppPort = workerAppPort;
2850
- this._systemRpc = (0, import_rpc3.createProtoRpcPeer)({
3478
+ this._shellPort = shellPort;
3479
+ this._systemRpc = (0, import_rpc4.createProtoRpcPeer)({
2851
3480
  requested: workerServiceBundle,
2852
3481
  exposed: iframeServiceBundle,
2853
3482
  handlers: {
@@ -2862,31 +3491,191 @@ var IFrameRuntime = class {
2862
3491
  });
2863
3492
  this._workerAppPort.subscribe((msg) => this._windowAppPort.send(msg));
2864
3493
  this._windowAppPort.subscribe((msg) => this._workerAppPort.send(msg));
3494
+ if (this._shellPort) {
3495
+ this._shellRuntime = new ShellRuntimeImpl(this._shellPort);
3496
+ }
3497
+ }
3498
+ get shell() {
3499
+ return this._shellRuntime;
2865
3500
  }
2866
3501
  async open(origin) {
3502
+ var _a;
2867
3503
  await this._systemRpc.open();
2868
3504
  await this._systemRpc.rpc.WorkerService.start({
2869
3505
  origin
2870
3506
  });
3507
+ await ((_a = this._shellRuntime) == null ? void 0 : _a.open());
2871
3508
  }
2872
3509
  async close() {
3510
+ var _a;
3511
+ await ((_a = this._shellRuntime) == null ? void 0 : _a.close());
2873
3512
  await this._systemRpc.rpc.WorkerService.stop();
2874
3513
  await this._systemRpc.close();
2875
3514
  }
2876
3515
  };
2877
3516
 
2878
- // packages/sdk/client-services/src/packlets/vault/worker-runtime.ts
3517
+ // packages/sdk/client-services/src/packlets/vault/shell-controller.ts
2879
3518
  var import_async18 = require("@dxos/async");
2880
- var import_messaging = require("@dxos/messaging");
2881
- var import_network_manager4 = require("@dxos/network-manager");
3519
+ var import_log13 = require("@dxos/log");
3520
+ var import_iframe2 = require("@dxos/protocols/proto/dxos/iframe");
3521
+ var import_rpc5 = require("@dxos/rpc");
3522
+ var ShellController = class {
3523
+ constructor(_port) {
3524
+ this._port = _port;
3525
+ this.contextUpdate = new import_async18.Event();
3526
+ this._display = import_iframe2.ShellDisplay.NONE;
3527
+ }
3528
+ get display() {
3529
+ return this._display;
3530
+ }
3531
+ get spaceKey() {
3532
+ return this._spaceKey;
3533
+ }
3534
+ setSpace(key) {
3535
+ this._spaceKey = key;
3536
+ this._emitUpdate();
3537
+ }
3538
+ async setLayout(layout, options = {}) {
3539
+ var _a;
3540
+ this._display = import_iframe2.ShellDisplay.FULLSCREEN;
3541
+ this._emitUpdate();
3542
+ await ((_a = this._shellRpc) == null ? void 0 : _a.rpc.ShellService.setLayout({
3543
+ layout,
3544
+ ...options
3545
+ }));
3546
+ }
3547
+ async open() {
3548
+ this._shellRpc = (0, import_rpc5.createProtoRpcPeer)({
3549
+ requested: shellServiceBundle,
3550
+ exposed: appServiceBundle,
3551
+ handlers: {
3552
+ AppService: {
3553
+ setContext: async (request) => {
3554
+ (0, import_log13.log)("set context", request, {
3555
+ file: "shell-controller.ts",
3556
+ line: 51,
3557
+ scope: this,
3558
+ callSite: (f, a) => f(...a)
3559
+ });
3560
+ this._display = request.display;
3561
+ this._spaceKey = request.spaceKey;
3562
+ this._invitationCode = request.invitationCode;
3563
+ this.contextUpdate.emit(request);
3564
+ }
3565
+ }
3566
+ },
3567
+ port: this._port
3568
+ });
3569
+ await this._shellRpc.open();
3570
+ }
3571
+ async close() {
3572
+ var _a;
3573
+ await ((_a = this._shellRpc) == null ? void 0 : _a.close());
3574
+ this._shellRpc = void 0;
3575
+ }
3576
+ _emitUpdate() {
3577
+ this.contextUpdate.emit({
3578
+ display: this._display,
3579
+ spaceKey: this._spaceKey,
3580
+ invitationCode: this._invitationCode
3581
+ });
3582
+ }
3583
+ };
3584
+
3585
+ // packages/sdk/client-services/src/packlets/vault/vault-resource-lock.ts
3586
+ var import_async19 = require("@dxos/async");
3587
+ var import_log14 = require("@dxos/log");
3588
+ var Message;
3589
+ (function(Message2) {
3590
+ Message2["ACQUIRING"] = "acquiring";
3591
+ })(Message || (Message = {}));
3592
+ var VaultResourceLock = class {
3593
+ constructor({ lockKey, onAcquire, onRelease }) {
3594
+ this._broadcastChannel = new BroadcastChannel("vault-resource-lock");
3595
+ this._releaseTrigger = new import_async19.Trigger();
3596
+ this._lockKey = lockKey;
3597
+ this._onAcquire = onAcquire;
3598
+ this._onRelease = onRelease;
3599
+ this._broadcastChannel.onmessage = this._onMessage.bind(this);
3600
+ }
3601
+ async acquire() {
3602
+ this._broadcastChannel.postMessage({
3603
+ message: Message.ACQUIRING
3604
+ });
3605
+ try {
3606
+ await (0, import_async19.asyncTimeout)(this._requestLock(), 3e3);
3607
+ } catch (e) {
3608
+ await this._requestLock(true);
3609
+ }
3610
+ }
3611
+ async release() {
3612
+ this._releaseTrigger.wake();
3613
+ }
3614
+ _onMessage(event) {
3615
+ if (event.data.message === Message.ACQUIRING) {
3616
+ this._releaseTrigger.wake();
3617
+ }
3618
+ }
3619
+ async _requestLock(steal = false) {
3620
+ (0, import_log14.log)("requesting lock...", {
3621
+ steal
3622
+ }, {
3623
+ file: "vault-resource-lock.ts",
3624
+ line: 56,
3625
+ scope: this,
3626
+ callSite: (f, a) => f(...a)
3627
+ });
3628
+ const acquired = new import_async19.Trigger();
3629
+ void navigator.locks.request(this._lockKey, {
3630
+ steal
3631
+ }, async () => {
3632
+ var _a, _b;
3633
+ await ((_a = this._onAcquire) == null ? void 0 : _a.call(this));
3634
+ acquired.wake();
3635
+ this._releaseTrigger = new import_async19.Trigger();
3636
+ await this._releaseTrigger.wait();
3637
+ (0, import_log14.log)("releasing lock...", {}, {
3638
+ file: "vault-resource-lock.ts",
3639
+ line: 65,
3640
+ scope: this,
3641
+ callSite: (f, a) => f(...a)
3642
+ });
3643
+ await ((_b = this._onRelease) == null ? void 0 : _b.call(this));
3644
+ (0, import_log14.log)("released lock", {}, {
3645
+ file: "vault-resource-lock.ts",
3646
+ line: 67,
3647
+ scope: this,
3648
+ callSite: (f, a) => f(...a)
3649
+ });
3650
+ }).catch(async () => {
3651
+ var _a;
3652
+ await ((_a = this._onRelease) == null ? void 0 : _a.call(this));
3653
+ });
3654
+ await acquired.wait();
3655
+ (0, import_log14.log)("recieved lock", {
3656
+ steal
3657
+ }, {
3658
+ file: "vault-resource-lock.ts",
3659
+ line: 74,
3660
+ scope: this,
3661
+ callSite: (f, a) => f(...a)
3662
+ });
3663
+ }
3664
+ };
3665
+
3666
+ // packages/sdk/client-services/src/packlets/vault/worker-runtime.ts
3667
+ var import_async21 = require("@dxos/async");
3668
+ var import_log16 = require("@dxos/log");
3669
+ var import_messaging2 = require("@dxos/messaging");
3670
+ var import_network_manager5 = require("@dxos/network-manager");
2882
3671
 
2883
3672
  // packages/sdk/client-services/src/packlets/vault/worker-session.ts
2884
- var import_node_assert11 = __toESM(require("node:assert"));
2885
- var import_async17 = require("@dxos/async");
2886
- var import_log12 = require("@dxos/log");
2887
- var import_rpc4 = require("@dxos/rpc");
2888
- var import_util5 = require("@dxos/util");
2889
- var __decorate3 = function(decorators, target, key, desc) {
3673
+ var import_node_assert14 = __toESM(require("node:assert"));
3674
+ var import_async20 = require("@dxos/async");
3675
+ var import_log15 = require("@dxos/log");
3676
+ var import_rpc6 = require("@dxos/rpc");
3677
+ var import_util8 = require("@dxos/util");
3678
+ var __decorate4 = function(decorators, target, key, desc) {
2890
3679
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2891
3680
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
2892
3681
  r = Reflect.decorate(decorators, target, key, desc);
@@ -2897,33 +3686,39 @@ var __decorate3 = function(decorators, target, key, desc) {
2897
3686
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2898
3687
  };
2899
3688
  var WorkerSession = class {
2900
- constructor({ getServices, systemPort, appPort, options = {
3689
+ constructor({ getService, systemPort, appPort, shellPort, options = {
2901
3690
  heartbeatInterval: 1e3
2902
3691
  } }) {
2903
- this._startTrigger = new import_async17.Trigger();
2904
- this.onClose = new import_util5.Callback();
2905
- (0, import_node_assert11.default)(options);
2906
- (0, import_node_assert11.default)(getServices);
3692
+ this._startTrigger = new import_async20.Trigger();
3693
+ this.onClose = new import_util8.Callback();
3694
+ (0, import_node_assert14.default)(options);
3695
+ (0, import_node_assert14.default)(getService);
2907
3696
  this._options = options;
2908
- this._getServices = getServices;
2909
- this._clientRpc = (0, import_rpc4.createProtoRpcPeer)({
3697
+ this._getService = getService;
3698
+ const handlers = {
3699
+ DataService: async () => await this._getService((services) => services.DataService),
3700
+ DevicesService: async () => await this._getService((services) => services.DevicesService),
3701
+ DevtoolsHost: async () => await this._getService((services) => services.DevtoolsHost),
3702
+ HaloInvitationsService: async () => await this._getService((services) => services.HaloInvitationsService),
3703
+ NetworkService: async () => await this._getService((services) => services.NetworkService),
3704
+ ProfileService: async () => await this._getService((services) => services.ProfileService),
3705
+ SpaceInvitationsService: async () => await this._getService((services) => services.SpaceInvitationsService),
3706
+ SpaceService: async () => await this._getService((services) => services.SpaceService),
3707
+ SpacesService: async () => await this._getService((services) => services.SpacesService),
3708
+ SystemService: async () => await this._getService((services) => services.SystemService),
3709
+ TracingService: async () => await this._getService((services) => services.TracingService)
3710
+ };
3711
+ this._clientRpc = (0, import_rpc6.createProtoRpcPeer)({
2910
3712
  exposed: clientServiceBundle,
2911
- handlers: {
2912
- HaloInvitationsService: async () => (await this._getServices()).services.HaloInvitationsService,
2913
- DevicesService: async () => (await this._getServices()).services.DevicesService,
2914
- SpaceInvitationsService: async () => (await this._getServices()).services.SpaceInvitationsService,
2915
- SpacesService: async () => (await this._getServices()).services.SpacesService,
2916
- NetworkService: async () => (await this._getServices()).services.NetworkService,
2917
- SpaceService: async () => (await this._getServices()).services.SpaceService,
2918
- DataService: async () => (await this._getServices()).services.DataService,
2919
- ProfileService: async () => (await this._getServices()).services.ProfileService,
2920
- SystemService: async () => (await this._getServices()).services.SystemService,
2921
- DevtoolsHost: async () => (await this._getServices()).services.DevtoolsHost,
2922
- TracingService: async () => (await this._getServices()).services.TracingService
2923
- },
3713
+ handlers,
2924
3714
  port: appPort
2925
3715
  });
2926
- this._iframeRpc = (0, import_rpc4.createProtoRpcPeer)({
3716
+ this._shellClientRpc = (0, import_rpc6.createProtoRpcPeer)({
3717
+ exposed: clientServiceBundle,
3718
+ handlers,
3719
+ port: shellPort
3720
+ });
3721
+ this._iframeRpc = (0, import_rpc6.createProtoRpcPeer)({
2927
3722
  requested: iframeServiceBundle,
2928
3723
  exposed: workerServiceBundle,
2929
3724
  handlers: {
@@ -2937,9 +3732,9 @@ var WorkerSession = class {
2937
3732
  try {
2938
3733
  await this.close();
2939
3734
  } catch (err) {
2940
- import_log12.log.catch(err, {}, {
3735
+ import_log15.log.catch(err, {}, {
2941
3736
  file: "worker-session.ts",
2942
- line: 90,
3737
+ line: 92,
2943
3738
  scope: this,
2944
3739
  callSite: (f, a) => f(...a)
2945
3740
  });
@@ -2955,15 +3750,16 @@ var WorkerSession = class {
2955
3750
  this.bridgeService = this._iframeRpc.rpc.BridgeService;
2956
3751
  }
2957
3752
  async open() {
2958
- import_log12.log.info("opening..", {}, {
3753
+ import_log15.log.info("opening..", {}, {
2959
3754
  file: "worker-session.ts",
2960
- line: 104,
3755
+ line: 106,
2961
3756
  scope: this,
2962
3757
  callSite: (f, a) => f(...a)
2963
3758
  });
2964
3759
  await Promise.all([
2965
3760
  this._clientRpc.open(),
2966
- this._iframeRpc.open()
3761
+ this._iframeRpc.open(),
3762
+ this._maybeOpenShell()
2967
3763
  ]);
2968
3764
  await this._startTrigger.wait({
2969
3765
  timeout: 3e3
@@ -2972,20 +3768,20 @@ var WorkerSession = class {
2972
3768
  try {
2973
3769
  await this._iframeRpc.rpc.IframeService.heartbeat();
2974
3770
  } catch (err1) {
2975
- import_log12.log.warn("Heartbeat failed", {
3771
+ import_log15.log.warn("Heartbeat failed", {
2976
3772
  err: err1
2977
3773
  }, {
2978
3774
  file: "worker-session.ts",
2979
- line: 116,
3775
+ line: 118,
2980
3776
  scope: this,
2981
3777
  callSite: (f, a) => f(...a)
2982
3778
  });
2983
3779
  try {
2984
3780
  await this.close();
2985
3781
  } catch (err) {
2986
- import_log12.log.catch(err, {}, {
3782
+ import_log15.log.catch(err, {}, {
2987
3783
  file: "worker-session.ts",
2988
- line: 120,
3784
+ line: 122,
2989
3785
  scope: this,
2990
3786
  callSite: (f, a) => f(...a)
2991
3787
  });
@@ -2994,18 +3790,18 @@ var WorkerSession = class {
2994
3790
  }, this._options.heartbeatInterval);
2995
3791
  }
2996
3792
  async close() {
2997
- import_log12.log.info("closing..", {}, {
3793
+ import_log15.log.info("closing..", {}, {
2998
3794
  file: "worker-session.ts",
2999
- line: 127,
3795
+ line: 129,
3000
3796
  scope: this,
3001
3797
  callSite: (f, a) => f(...a)
3002
3798
  });
3003
3799
  try {
3004
3800
  await this.onClose.callIfSet();
3005
3801
  } catch (err) {
3006
- import_log12.log.catch(err, {}, {
3802
+ import_log15.log.catch(err, {}, {
3007
3803
  file: "worker-session.ts",
3008
- line: 131,
3804
+ line: 133,
3009
3805
  scope: this,
3010
3806
  callSite: (f, a) => f(...a)
3011
3807
  });
@@ -3018,9 +3814,21 @@ var WorkerSession = class {
3018
3814
  this._iframeRpc.close()
3019
3815
  ]);
3020
3816
  }
3817
+ async _maybeOpenShell() {
3818
+ try {
3819
+ await (0, import_async20.asyncTimeout)(this._shellClientRpc.open(), 1e3);
3820
+ } catch (e) {
3821
+ import_log15.log.info("No shell connected.", {}, {
3822
+ file: "worker-session.ts",
3823
+ line: 147,
3824
+ scope: this,
3825
+ callSite: (f, a) => f(...a)
3826
+ });
3827
+ }
3828
+ }
3021
3829
  };
3022
- __decorate3([
3023
- import_log12.logInfo
3830
+ __decorate4([
3831
+ import_log15.logInfo
3024
3832
  ], WorkerSession.prototype, "origin", void 0);
3025
3833
 
3026
3834
  // packages/sdk/client-services/src/packlets/vault/worker-runtime.ts
@@ -3028,28 +3836,46 @@ var WorkerRuntime = class {
3028
3836
  // prettier-ignore
3029
3837
  constructor(_configProvider) {
3030
3838
  this._configProvider = _configProvider;
3031
- this._transportFactory = new import_network_manager4.WebRTCTransportProxyFactory();
3032
- this._ready = new import_async18.Trigger();
3839
+ this._transportFactory = new import_network_manager5.WebRTCTransportProxyFactory();
3840
+ this._ready = new import_async21.Trigger();
3033
3841
  this.sessions = /* @__PURE__ */ new Set();
3034
3842
  }
3035
3843
  async start() {
3844
+ (0, import_log16.log)("starting...", {}, {
3845
+ file: "worker-runtime.ts",
3846
+ line: 42,
3847
+ scope: this,
3848
+ callSite: (f, a) => f(...a)
3849
+ });
3036
3850
  try {
3037
3851
  this._config = await this._configProvider();
3038
3852
  const signalServer = this._config.get("runtime.services.signal.server");
3039
3853
  this._clientServices = new ClientServicesHost({
3040
3854
  config: this._config,
3041
- networkManager: new import_network_manager4.NetworkManager({
3855
+ networkManager: new import_network_manager5.NetworkManager({
3042
3856
  log: true,
3043
- signalManager: signalServer ? new import_messaging.WebsocketSignalManager([
3857
+ signalManager: signalServer ? new import_messaging2.WebsocketSignalManager([
3044
3858
  signalServer
3045
- ]) : new import_messaging.MemorySignalManager(new import_messaging.MemorySignalManagerContext()),
3859
+ ]) : new import_messaging2.MemorySignalManager(new import_messaging2.MemorySignalManagerContext()),
3046
3860
  transportFactory: this._transportFactory
3047
3861
  })
3048
3862
  });
3049
3863
  await this._clientServices.open();
3050
3864
  this._ready.wake(void 0);
3865
+ (0, import_log16.log)("started", {}, {
3866
+ file: "worker-runtime.ts",
3867
+ line: 59,
3868
+ scope: this,
3869
+ callSite: (f, a) => f(...a)
3870
+ });
3051
3871
  } catch (err) {
3052
3872
  this._ready.wake(err);
3873
+ import_log16.log.catch(err, {}, {
3874
+ file: "worker-runtime.ts",
3875
+ line: 62,
3876
+ scope: this,
3877
+ callSite: (f, a) => f(...a)
3878
+ });
3053
3879
  }
3054
3880
  }
3055
3881
  async stop() {
@@ -3058,17 +3884,22 @@ var WorkerRuntime = class {
3058
3884
  /**
3059
3885
  * Create a new session.
3060
3886
  */
3061
- async createSession({ appPort, systemPort }) {
3887
+ async createSession({ appPort, systemPort, shellPort }) {
3062
3888
  const session = new WorkerSession({
3063
- getServices: async () => {
3889
+ getService: async (find) => {
3064
3890
  const error = await this._ready.wait();
3065
- if (error !== void 0) {
3891
+ if (error) {
3066
3892
  throw error;
3067
3893
  }
3068
- return this._clientServices;
3894
+ const service = find(this._clientServices.services);
3895
+ if (!service) {
3896
+ throw new Error("Service not found");
3897
+ }
3898
+ return service;
3069
3899
  },
3070
3900
  appPort,
3071
3901
  systemPort,
3902
+ shellPort,
3072
3903
  readySignal: this._ready
3073
3904
  });
3074
3905
  session.onClose.set(async () => {
@@ -3099,6 +3930,193 @@ var WorkerRuntime = class {
3099
3930
  }
3100
3931
  }
3101
3932
  };
3933
+
3934
+ // packages/sdk/client-services/src/packlets/services/service-registry.ts
3935
+ var ServiceRegistry = class {
3936
+ // prettier-ignore
3937
+ constructor(_serviceBundle, _handlers) {
3938
+ this._serviceBundle = _serviceBundle;
3939
+ this._handlers = _handlers;
3940
+ }
3941
+ get descriptors() {
3942
+ return this._serviceBundle;
3943
+ }
3944
+ get services() {
3945
+ return this._handlers;
3946
+ }
3947
+ setServices(services) {
3948
+ this._handlers = services;
3949
+ }
3950
+ };
3951
+
3952
+ // packages/sdk/client-services/src/packlets/services/service-host.ts
3953
+ var createDefaultModelFactory = () => {
3954
+ return new import_model_factory.ModelFactory().registerModel(import_document_model.DocumentModel).registerModel(import_text_model.TextModel);
3955
+ };
3956
+ var ClientServicesHost = class {
3957
+ constructor({
3958
+ config,
3959
+ modelFactory = createDefaultModelFactory(),
3960
+ // TODO(burdon): Create ApolloLink abstraction (see Client).
3961
+ networkManager,
3962
+ storage = createStorageObjects(config.get("runtime.client.storage", {})).storage,
3963
+ lockKey
3964
+ }) {
3965
+ this._open = false;
3966
+ this._config = config;
3967
+ this._modelFactory = modelFactory;
3968
+ this._networkManager = networkManager;
3969
+ this._storage = storage;
3970
+ this._resourceLock = lockKey ? new VaultResourceLock({
3971
+ lockKey,
3972
+ onAcquire: () => this.open(),
3973
+ onRelease: () => this.close()
3974
+ }) : void 0;
3975
+ this._systemService = new SystemServiceImpl({
3976
+ config: this._config,
3977
+ onInit: async () => {
3978
+ var _a;
3979
+ await ((_a = this._resourceLock) == null ? void 0 : _a.acquire());
3980
+ },
3981
+ onStatus: async () => {
3982
+ if (!this.isOpen) {
3983
+ return {
3984
+ status: import_client2.Status.INACTIVE
3985
+ };
3986
+ }
3987
+ return {
3988
+ status: import_client2.Status.ACTIVE
3989
+ };
3990
+ },
3991
+ onReset: async () => {
3992
+ var _a;
3993
+ await ((_a = this._serviceContext) == null ? void 0 : _a.reset());
3994
+ }
3995
+ });
3996
+ this._serviceRegistry = new ServiceRegistry(clientServiceBundle, {
3997
+ SystemService: this._systemService
3998
+ });
3999
+ }
4000
+ get isOpen() {
4001
+ return this._open;
4002
+ }
4003
+ get descriptors() {
4004
+ return this._serviceRegistry.descriptors;
4005
+ }
4006
+ get services() {
4007
+ return this._serviceRegistry.services;
4008
+ }
4009
+ async open() {
4010
+ var _a;
4011
+ if (this._open) {
4012
+ return;
4013
+ }
4014
+ (0, import_log17.log)("opening...", {}, {
4015
+ file: "service-host.ts",
4016
+ line: 125,
4017
+ scope: this,
4018
+ callSite: (f, a) => f(...a)
4019
+ });
4020
+ this._serviceContext = new ServiceContext(this._storage, this._networkManager, this._modelFactory);
4021
+ this._serviceRegistry.setServices({
4022
+ // TODO(burdon): Move to new protobuf definitions.
4023
+ SystemService: this._systemService,
4024
+ HaloInvitationsService: new HaloInvitationsServiceImpl(this._serviceContext.identityManager, this._serviceContext.haloInvitations),
4025
+ DevicesService: new DevicesServiceImpl(this._serviceContext.identityManager),
4026
+ SpaceInvitationsService: new SpaceInvitationsServiceImpl(this._serviceContext.identityManager, () => {
4027
+ var _a2;
4028
+ return (_a2 = this._serviceContext.spaceInvitations) != null ? _a2 : (0, import_debug7.raise)(new Error("SpaceInvitations not initialized"));
4029
+ }, () => {
4030
+ var _a2;
4031
+ return (_a2 = this._serviceContext.dataSpaceManager) != null ? _a2 : (0, import_debug7.raise)(new Error("SpaceManager not initialized"));
4032
+ }),
4033
+ SpacesService: new SpacesServiceImpl(this._serviceContext.spaceManager),
4034
+ DataService: new import_echo_pipeline5.DataServiceImpl(this._serviceContext.dataServiceSubscriptions),
4035
+ NetworkService: new NetworkServiceImpl(this._serviceContext.networkManager),
4036
+ // TODO(burdon): Move to new protobuf definitions.
4037
+ ProfileService: new ProfileServiceImpl(this._serviceContext),
4038
+ // TODO(burdon): Port old SubscribeSpaces to QueryServices>
4039
+ SpaceService: new SpaceServiceImpl(this._serviceContext),
4040
+ TracingService: new TracingServiceImpl(this._config),
4041
+ DevtoolsHost: new DevtoolsServiceImpl({
4042
+ events: new DevtoolsHostEvents(),
4043
+ config: this._config,
4044
+ context: this._serviceContext
4045
+ })
4046
+ });
4047
+ await this._serviceContext.open();
4048
+ this._open = true;
4049
+ const deviceKey = (_a = this._serviceContext.identityManager.identity) == null ? void 0 : _a.deviceKey;
4050
+ (0, import_log17.log)("opened", {
4051
+ deviceKey
4052
+ }, {
4053
+ file: "service-host.ts",
4054
+ line: 172,
4055
+ scope: this,
4056
+ callSite: (f, a) => f(...a)
4057
+ });
4058
+ }
4059
+ async close() {
4060
+ var _a;
4061
+ if (!this._open) {
4062
+ return;
4063
+ }
4064
+ const deviceKey = (_a = this._serviceContext.identityManager.identity) == null ? void 0 : _a.deviceKey;
4065
+ (0, import_log17.log)("closing...", {
4066
+ deviceKey
4067
+ }, {
4068
+ file: "service-host.ts",
4069
+ line: 181,
4070
+ scope: this,
4071
+ callSite: (f, a) => f(...a)
4072
+ });
4073
+ this._serviceRegistry.setServices({
4074
+ SystemService: this._systemService
4075
+ });
4076
+ await this._serviceContext.close();
4077
+ this._open = false;
4078
+ (0, import_log17.log)("closed", {
4079
+ deviceKey
4080
+ }, {
4081
+ file: "service-host.ts",
4082
+ line: 185,
4083
+ scope: this,
4084
+ callSite: (f, a) => f(...a)
4085
+ });
4086
+ }
4087
+ };
4088
+
4089
+ // packages/sdk/client-services/src/packlets/services/service-proxy.ts
4090
+ var import_async22 = require("@dxos/async");
4091
+ var import_errors2 = require("@dxos/errors");
4092
+ var import_rpc7 = require("@dxos/rpc");
4093
+ var ClientServicesProxy = class {
4094
+ // prettier-ignore
4095
+ constructor(port, _timeout = 3e4) {
4096
+ this._timeout = _timeout;
4097
+ this._proxy = (0, import_rpc7.createProtoRpcPeer)({
4098
+ requested: clientServiceBundle,
4099
+ exposed: {},
4100
+ handlers: {},
4101
+ port
4102
+ });
4103
+ }
4104
+ get proxy() {
4105
+ return this._proxy;
4106
+ }
4107
+ get descriptors() {
4108
+ return clientServiceBundle;
4109
+ }
4110
+ get services() {
4111
+ return this._proxy.rpc;
4112
+ }
4113
+ async open() {
4114
+ await (0, import_async22.asyncTimeout)(this._proxy.open(), this._timeout, new import_errors2.RemoteServiceConnectionTimeout());
4115
+ }
4116
+ async close() {
4117
+ await this._proxy.close();
4118
+ }
4119
+ };
3102
4120
  // Annotate the CommonJS export names for ESM import in node:
3103
4121
  0 && (module.exports = {
3104
4122
  AUTHENTICATION_CODE_LENGTH,
@@ -3110,40 +4128,49 @@ var WorkerRuntime = class {
3110
4128
  ClientServicesProxy,
3111
4129
  DevtoolsHostEvents,
3112
4130
  DevtoolsServiceImpl,
3113
- HaloAuthVerifier,
3114
4131
  HaloInvitationsHandler,
3115
4132
  HaloInvitationsProxy,
3116
4133
  HaloInvitationsServiceImpl,
3117
- IFrameRuntime,
4134
+ IFrameHostRuntime,
4135
+ IFrameProxyRuntime,
3118
4136
  INVITATION_TIMEOUT,
3119
4137
  Identity,
3120
4138
  IdentityManager,
3121
4139
  InvitationEncoder,
3122
4140
  InvitationObservableProvider,
4141
+ MemoryShellRuntime,
3123
4142
  ON_CLOSE_DELAY,
3124
4143
  ProfileServiceImpl,
3125
4144
  ServiceContext,
3126
4145
  ServiceRegistry,
4146
+ ShellController,
4147
+ ShellRuntimeImpl,
3127
4148
  SpaceInvitationsHandler,
3128
4149
  SpaceInvitationsProxy,
3129
4150
  SpaceInvitationsServiceImpl,
3130
4151
  SpaceServiceImpl,
3131
4152
  SystemServiceImpl,
3132
4153
  TracingServiceImpl,
4154
+ TrustedKeySetAuthVerifier,
4155
+ VaultResourceLock,
3133
4156
  WorkerRuntime,
3134
4157
  WorkerSession,
4158
+ appServiceBundle,
3135
4159
  clientServiceBundle,
4160
+ createAuthProvider,
3136
4161
  createDefaultModelFactory,
3137
- createHaloAuthProvider,
3138
4162
  createStorageObjects,
3139
4163
  getNetworkPeers,
4164
+ iframeServiceBundle,
4165
+ shellServiceBundle,
3140
4166
  subscribeToFeedBlocks,
3141
4167
  subscribeToFeeds,
3142
4168
  subscribeToNetworkStatus,
3143
4169
  subscribeToNetworkTopics,
3144
- subscribeToSignalTrace,
4170
+ subscribeToSignal,
3145
4171
  subscribeToSpaces,
3146
4172
  subscribeToSwarmInfo,
4173
+ workerServiceBundle,
3147
4174
  wrapObservable
3148
4175
  });
3149
4176
  //# sourceMappingURL=index.cjs.map