@dxos/client-services 0.8.4-main.f9ba587 → 0.8.4-main.fcfe5033a5

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 (239) hide show
  1. package/dist/lib/browser/{chunk-ERQJUBAW.mjs → chunk-HYGNOM23.mjs} +4279 -3342
  2. package/dist/lib/browser/chunk-HYGNOM23.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-NQSC7HOE.mjs +22 -0
  4. package/dist/lib/browser/chunk-NQSC7HOE.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-QCWEHHJW.mjs +24 -0
  6. package/dist/lib/browser/chunk-QCWEHHJW.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +539 -98
  8. package/dist/lib/browser/index.mjs.map +4 -4
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +93 -0
  11. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
  12. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
  13. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
  14. package/dist/lib/browser/packlets/locks/browser.mjs +126 -0
  15. package/dist/lib/browser/packlets/locks/browser.mjs.map +7 -0
  16. package/dist/lib/browser/packlets/locks/node.mjs +66 -0
  17. package/dist/lib/browser/packlets/locks/node.mjs.map +7 -0
  18. package/dist/lib/browser/testing/index.mjs +45 -26
  19. package/dist/lib/browser/testing/index.mjs.map +3 -3
  20. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +24 -0
  21. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +7 -0
  22. package/dist/lib/node-esm/{chunk-TMEG7JOG.mjs → chunk-GFT7MAQE.mjs} +3764 -2695
  23. package/dist/lib/node-esm/chunk-GFT7MAQE.mjs.map +7 -0
  24. package/dist/lib/node-esm/chunk-PKEGMOQ4.mjs +22 -0
  25. package/dist/lib/node-esm/chunk-PKEGMOQ4.mjs.map +7 -0
  26. package/dist/lib/node-esm/index.mjs +539 -98
  27. package/dist/lib/node-esm/index.mjs.map +4 -4
  28. package/dist/lib/node-esm/meta.json +1 -1
  29. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +93 -0
  30. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
  31. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
  32. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
  33. package/dist/lib/node-esm/packlets/locks/browser.mjs +126 -0
  34. package/dist/lib/node-esm/packlets/locks/browser.mjs.map +7 -0
  35. package/dist/lib/node-esm/packlets/locks/node.mjs +66 -0
  36. package/dist/lib/node-esm/packlets/locks/node.mjs.map +7 -0
  37. package/dist/lib/node-esm/testing/index.mjs +45 -26
  38. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  39. package/dist/types/src/index.d.ts +1 -0
  40. package/dist/types/src/index.d.ts.map +1 -1
  41. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +3 -2
  42. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
  43. package/dist/types/src/packlets/agents/edge-agent-service.d.ts +3 -2
  44. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  45. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  46. package/dist/types/src/packlets/devtools/devtools.d.ts +20 -20
  47. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  48. package/dist/types/src/packlets/devtools/feeds.d.ts +1 -1
  49. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  50. package/dist/types/src/packlets/devtools/network.d.ts +1 -1
  51. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  52. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts +1 -1
  53. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
  54. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts +1 -1
  55. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
  56. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +2 -3
  57. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  58. package/dist/types/src/packlets/diagnostics/index.d.ts +1 -1
  59. package/dist/types/src/packlets/diagnostics/index.d.ts.map +1 -1
  60. package/dist/types/src/packlets/identity/authenticator.d.ts +2 -2
  61. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  62. package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
  63. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  64. package/dist/types/src/packlets/identity/identity-manager.d.ts +7 -7
  65. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  66. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +7 -6
  67. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  68. package/dist/types/src/packlets/identity/identity-service.d.ts +6 -10
  69. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  70. package/dist/types/src/packlets/identity/identity.d.ts +9 -12
  71. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  72. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +6 -5
  73. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  74. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +2 -2
  75. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
  76. package/dist/types/src/packlets/invitations/index.d.ts +1 -1
  77. package/dist/types/src/packlets/invitations/index.d.ts.map +1 -1
  78. package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
  79. package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
  80. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +8 -5
  81. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
  82. package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +1 -1
  83. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +4 -4
  84. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  85. package/dist/types/src/packlets/invitations/invitations-manager.d.ts +3 -3
  86. package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
  87. package/dist/types/src/packlets/invitations/invitations-service.d.ts +4 -4
  88. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  89. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +5 -4
  90. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  91. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  92. package/dist/types/src/packlets/locks/index.d.ts +2 -2
  93. package/dist/types/src/packlets/locks/index.d.ts.map +1 -1
  94. package/dist/types/src/packlets/logging/logging-service.d.ts +5 -1
  95. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  96. package/dist/types/src/packlets/network/network-service.d.ts +7 -6
  97. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  98. package/dist/types/src/packlets/services/client-rpc-server.d.ts +5 -5
  99. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
  100. package/dist/types/src/packlets/services/feed-syncer.d.ts +59 -0
  101. package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
  102. package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
  103. package/dist/types/src/packlets/services/feed-syncer.test.d.ts.map +1 -0
  104. package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
  105. package/dist/types/src/packlets/services/service-context.d.ts +14 -9
  106. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  107. package/dist/types/src/packlets/services/service-host.d.ts +21 -8
  108. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  109. package/dist/types/src/packlets/space-export/archive-format.d.ts +9 -0
  110. package/dist/types/src/packlets/space-export/archive-format.d.ts.map +1 -0
  111. package/dist/types/src/packlets/space-export/index.d.ts +4 -1
  112. package/dist/types/src/packlets/space-export/index.d.ts.map +1 -1
  113. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts +23 -0
  114. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts.map +1 -0
  115. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts +36 -0
  116. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts.map +1 -0
  117. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +9 -1
  118. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
  119. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +8 -2
  120. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
  121. package/dist/types/src/packlets/space-export/space-archive.test.d.ts +2 -0
  122. package/dist/types/src/packlets/space-export/space-archive.test.d.ts.map +1 -0
  123. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts +1 -1
  124. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
  125. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +29 -17
  126. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  127. package/dist/types/src/packlets/spaces/data-space.d.ts +30 -13
  128. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  129. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +2 -2
  130. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  131. package/dist/types/src/packlets/spaces/genesis.d.ts +2 -1
  132. package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
  133. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -6
  134. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  135. package/dist/types/src/packlets/spaces/spaces-service.d.ts +18 -8
  136. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  137. package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
  138. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  139. package/dist/types/src/packlets/system/system-service.d.ts +1 -1
  140. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  141. package/dist/types/src/packlets/testing/invitation-utils.d.ts +6 -3
  142. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  143. package/dist/types/src/packlets/testing/test-builder.d.ts +8 -7
  144. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  145. package/dist/types/src/packlets/worker/worker-runtime.d.ts +41 -4
  146. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  147. package/dist/types/src/packlets/worker/worker-session.d.ts +2 -4
  148. package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
  149. package/dist/types/src/version.d.ts +1 -1
  150. package/dist/types/src/version.d.ts.map +1 -1
  151. package/dist/types/tsconfig.tsbuildinfo +1 -1
  152. package/package.json +72 -48
  153. package/src/index.ts +1 -0
  154. package/src/packlets/agents/edge-agent-manager.ts +10 -7
  155. package/src/packlets/agents/edge-agent-service.ts +17 -5
  156. package/src/packlets/devices/devices-service.test.ts +3 -3
  157. package/src/packlets/devices/devices-service.ts +2 -2
  158. package/src/packlets/devtools/devtools.ts +29 -29
  159. package/src/packlets/devtools/feeds.ts +2 -2
  160. package/src/packlets/devtools/network.ts +1 -1
  161. package/src/packlets/diagnostics/browser-diagnostics-broadcast.ts +1 -1
  162. package/src/packlets/diagnostics/diagnostics-broadcast.ts +1 -1
  163. package/src/packlets/diagnostics/diagnostics-collector.ts +1 -1
  164. package/src/packlets/diagnostics/diagnostics.ts +2 -3
  165. package/src/packlets/diagnostics/index.ts +1 -1
  166. package/src/packlets/identity/authenticator.node.test.ts +1 -1
  167. package/src/packlets/identity/authenticator.ts +3 -3
  168. package/src/packlets/identity/contacts-service.ts +2 -2
  169. package/src/packlets/identity/identity-manager.test.ts +8 -8
  170. package/src/packlets/identity/identity-manager.ts +23 -20
  171. package/src/packlets/identity/identity-recovery-manager.ts +22 -18
  172. package/src/packlets/identity/identity-service.test.ts +8 -28
  173. package/src/packlets/identity/identity-service.ts +13 -80
  174. package/src/packlets/identity/identity.test.ts +11 -11
  175. package/src/packlets/identity/identity.ts +17 -39
  176. package/src/packlets/invitations/device-invitation-protocol.test.ts +4 -4
  177. package/src/packlets/invitations/device-invitation-protocol.ts +8 -6
  178. package/src/packlets/invitations/edge-invitation-handler.ts +10 -6
  179. package/src/packlets/invitations/index.ts +1 -1
  180. package/src/packlets/invitations/invitation-guest-extenstion.ts +7 -5
  181. package/src/packlets/invitations/invitation-host-extension.ts +8 -6
  182. package/src/packlets/invitations/invitation-protocol.ts +8 -5
  183. package/src/packlets/invitations/invitation-state.ts +0 -10
  184. package/src/packlets/invitations/invitations-handler.test.ts +301 -292
  185. package/src/packlets/invitations/invitations-handler.ts +72 -16
  186. package/src/packlets/invitations/invitations-manager.ts +43 -18
  187. package/src/packlets/invitations/invitations-service.ts +10 -10
  188. package/src/packlets/invitations/space-invitation-protocol.test.ts +26 -25
  189. package/src/packlets/invitations/space-invitation-protocol.ts +13 -17
  190. package/src/packlets/invitations/utils.ts +1 -1
  191. package/src/packlets/locks/browser.ts +1 -1
  192. package/src/packlets/locks/index.ts +2 -2
  193. package/src/packlets/logging/logging-service.ts +8 -3
  194. package/src/packlets/logging/logging.test.ts +1 -1
  195. package/src/packlets/network/network-service.test.ts +3 -3
  196. package/src/packlets/network/network-service.ts +12 -10
  197. package/src/packlets/services/client-rpc-server.ts +20 -17
  198. package/src/packlets/services/feed-syncer.test.ts +340 -0
  199. package/src/packlets/services/feed-syncer.ts +337 -0
  200. package/src/packlets/services/platform.ts +7 -1
  201. package/src/packlets/services/service-context.test.ts +4 -3
  202. package/src/packlets/services/service-context.ts +145 -59
  203. package/src/packlets/services/service-host.test.ts +10 -9
  204. package/src/packlets/services/service-host.ts +85 -38
  205. package/src/packlets/services/service-registry.test.ts +1 -1
  206. package/src/packlets/space-export/archive-format.ts +42 -0
  207. package/src/packlets/space-export/index.ts +4 -1
  208. package/src/packlets/space-export/serialized-space-reader.ts +111 -0
  209. package/src/packlets/space-export/serialized-space-writer.ts +246 -0
  210. package/src/packlets/space-export/space-archive-reader.ts +65 -4
  211. package/src/packlets/space-export/space-archive-writer.ts +44 -6
  212. package/src/packlets/space-export/space-archive.test.ts +461 -0
  213. package/src/packlets/space-export/tar.test.ts +1 -1
  214. package/src/packlets/spaces/automerge-space-state.ts +1 -1
  215. package/src/packlets/spaces/data-space-manager.test.ts +79 -13
  216. package/src/packlets/spaces/data-space-manager.ts +131 -118
  217. package/src/packlets/spaces/data-space.ts +65 -39
  218. package/src/packlets/spaces/edge-feed-replicator.test.ts +4 -4
  219. package/src/packlets/spaces/edge-feed-replicator.ts +13 -11
  220. package/src/packlets/spaces/epoch-migrations.ts +5 -5
  221. package/src/packlets/spaces/genesis.ts +6 -1
  222. package/src/packlets/spaces/notarization-plugin.test.ts +3 -3
  223. package/src/packlets/spaces/notarization-plugin.ts +13 -12
  224. package/src/packlets/spaces/spaces-service.test.ts +20 -12
  225. package/src/packlets/spaces/spaces-service.ts +138 -38
  226. package/src/packlets/storage/profile-archive.ts +1 -1
  227. package/src/packlets/storage/storage.ts +7 -8
  228. package/src/packlets/system/system-service.test.ts +1 -1
  229. package/src/packlets/system/system-service.ts +4 -4
  230. package/src/packlets/testing/invitation-utils.ts +11 -7
  231. package/src/packlets/testing/test-builder.ts +39 -13
  232. package/src/packlets/worker/worker-runtime.ts +180 -17
  233. package/src/packlets/worker/worker-session.ts +15 -21
  234. package/src/version.ts +1 -1
  235. package/dist/lib/browser/chunk-ERQJUBAW.mjs.map +0 -7
  236. package/dist/lib/node-esm/chunk-TMEG7JOG.mjs.map +0 -7
  237. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +0 -19
  238. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +0 -1
  239. package/src/packlets/identity/default-space-state-machine.ts +0 -44
@@ -4,40 +4,38 @@
4
4
 
5
5
  import { Event } from '@dxos/async';
6
6
  import { AUTH_TIMEOUT, LOAD_CONTROL_FEEDS_TIMEOUT } from '@dxos/client-protocol';
7
- import { type Context } from '@dxos/context';
7
+ import { type Context as DxosContext } from '@dxos/context';
8
8
  import {
9
- DeviceStateMachine,
10
9
  type CredentialSigner,
11
- createCredentialSignerWithKey,
12
- createCredentialSignerWithChain,
10
+ DeviceStateMachine,
13
11
  ProfileStateMachine,
12
+ createCredentialSignerWithChain,
13
+ createCredentialSignerWithKey,
14
14
  } from '@dxos/credentials';
15
15
  import { type Signer } from '@dxos/crypto';
16
16
  import { type Space } from '@dxos/echo-pipeline';
17
17
  import { type EdgeConnection } from '@dxos/edge-client';
18
- import { writeMessages, type FeedWrapper } from '@dxos/feed-store';
18
+ import { type FeedWrapper, writeMessages } from '@dxos/feed-store';
19
19
  import { invariant } from '@dxos/invariant';
20
- import { type IdentityDid, PublicKey, type SpaceId } from '@dxos/keys';
20
+ import { type IdentityDid, PublicKey } from '@dxos/keys';
21
21
  import { log } from '@dxos/log';
22
22
  import { type Runtime } from '@dxos/protocols/proto/dxos/config';
23
23
  import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
24
24
  import {
25
25
  AdmittedFeed,
26
+ type Credential,
26
27
  type DeviceProfileDocument,
27
28
  type ProfileDocument,
28
- type Credential,
29
29
  } from '@dxos/protocols/proto/dxos/halo/credentials';
30
30
  import { type DeviceAdmissionRequest } from '@dxos/protocols/proto/dxos/halo/invitations';
31
31
  import { type Presence } from '@dxos/teleport-extension-gossip';
32
- import { Timeframe } from '@dxos/timeframe';
33
32
  import { trace } from '@dxos/tracing';
34
33
  import { type ComplexMap, ComplexSet } from '@dxos/util';
35
34
 
36
- import { TrustedKeySetAuthVerifier } from './authenticator';
37
- import { DefaultSpaceStateMachine } from './default-space-state-machine';
38
35
  import { EdgeFeedReplicator } from '../spaces';
36
+ import { TrustedKeySetAuthVerifier } from './authenticator';
39
37
 
40
- export type IdentityParams = {
38
+ export type IdentityProps = {
41
39
  did: IdentityDid;
42
40
  identityKey: PublicKey;
43
41
  deviceKey: PublicKey;
@@ -59,7 +57,6 @@ export class Identity {
59
57
  private readonly _presence?: Presence;
60
58
  private readonly _deviceStateMachine: DeviceStateMachine;
61
59
  private readonly _profileStateMachine: ProfileStateMachine;
62
- private readonly _defaultSpaceStateMachine: DefaultSpaceStateMachine;
63
60
  private readonly _edgeFeedReplicator?: EdgeFeedReplicator = undefined;
64
61
 
65
62
  public readonly authVerifier: TrustedKeySetAuthVerifier;
@@ -70,7 +67,7 @@ export class Identity {
70
67
 
71
68
  public readonly stateUpdate = new Event();
72
69
 
73
- constructor(params: IdentityParams) {
70
+ constructor(params: IdentityProps) {
74
71
  this.space = params.space;
75
72
  this._signer = params.signer;
76
73
  this._presence = params.presence;
@@ -90,10 +87,6 @@ export class Identity {
90
87
  identityKey: this.identityKey,
91
88
  onUpdate: () => this.stateUpdate.emit(),
92
89
  });
93
- this._defaultSpaceStateMachine = new DefaultSpaceStateMachine({
94
- identityKey: this.identityKey,
95
- onUpdate: () => this.stateUpdate.emit(),
96
- });
97
90
 
98
91
  this.authVerifier = new TrustedKeySetAuthVerifier({
99
92
  trustedKeysProvider: () => new ComplexSet(PublicKey.hash, this.authorizedDeviceKeys.keys()),
@@ -111,32 +104,26 @@ export class Identity {
111
104
  return this._deviceStateMachine.authorizedDeviceKeys;
112
105
  }
113
106
 
114
- get defaultSpaceId(): SpaceId | undefined {
115
- return this._defaultSpaceStateMachine.spaceId;
116
- }
117
-
118
- @trace.span()
119
- async open(ctx: Context): Promise<void> {
107
+ @trace.span({ op: 'lifecycle' })
108
+ async open(ctx: DxosContext): Promise<void> {
120
109
  await this._presence?.open();
121
110
  await this.space.spaceState.addCredentialProcessor(this._deviceStateMachine);
122
111
  await this.space.spaceState.addCredentialProcessor(this._profileStateMachine);
123
- await this.space.spaceState.addCredentialProcessor(this._defaultSpaceStateMachine);
124
112
  if (this._edgeFeedReplicator) {
125
113
  this.space.protocol.feedAdded.append(this._onFeedAdded);
126
114
  }
127
115
  await this.space.open(ctx);
128
116
  }
129
117
 
130
- public async joinNetwork(): Promise<void> {
131
- await this.space.startProtocol();
118
+ public async joinNetwork(ctx: DxosContext): Promise<void> {
119
+ await this.space.startProtocol(ctx);
132
120
  await this._edgeFeedReplicator?.open();
133
121
  }
134
122
 
135
- @trace.span()
136
- async close(ctx: Context): Promise<void> {
123
+ @trace.span({ op: 'lifecycle' })
124
+ async close(ctx: DxosContext): Promise<void> {
137
125
  await this._presence?.close();
138
126
  await this.authVerifier.close();
139
- await this.space.spaceState.removeCredentialProcessor(this._defaultSpaceStateMachine);
140
127
  await this.space.spaceState.removeCredentialProcessor(this._profileStateMachine);
141
128
  await this.space.spaceState.removeCredentialProcessor(this._deviceStateMachine);
142
129
 
@@ -146,7 +133,7 @@ export class Identity {
146
133
 
147
134
  await this._edgeFeedReplicator?.close();
148
135
 
149
- await this.space.close();
136
+ await this.space.close(ctx);
150
137
  }
151
138
 
152
139
  async ready(): Promise<void> {
@@ -210,15 +197,6 @@ export class Identity {
210
197
  return createCredentialSignerWithKey(this._signer, this.deviceKey);
211
198
  }
212
199
 
213
- async updateDefaultSpace(spaceId: SpaceId): Promise<void> {
214
- const credential = await this.getDeviceCredentialSigner().createCredential({
215
- subject: this.identityKey,
216
- assertion: { '@type': 'dxos.halo.credentials.DefaultSpace', spaceId },
217
- });
218
- const receipt = await this.controlPipeline.writer.write({ credential: { credential } });
219
- await this.controlPipeline.state.waitUntilTimeframe(new Timeframe([[receipt.feedKey, receipt.seq]]));
220
- }
221
-
222
200
  async admitDevice({ deviceKey, controlFeedKey, dataFeedKey }: DeviceAdmissionRequest): Promise<Credential> {
223
201
  log('Admitting device:', {
224
202
  identityKey: this.identityKey,
@@ -2,9 +2,9 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import { describe, expect, test, onTestFinished } from 'vitest';
5
+ import { describe, expect, onTestFinished, test } from 'vitest';
6
6
 
7
- import { asyncChain } from '@dxos/async';
7
+ import { chain } from '@dxos/async';
8
8
  import { Context } from '@dxos/context';
9
9
  import { AlreadyJoinedError } from '@dxos/protocols';
10
10
  import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
@@ -32,7 +32,7 @@ describe('services/device', () => {
32
32
  });
33
33
 
34
34
  test('creates and accepts invitation', async () => {
35
- const [host, guest] = await asyncChain<ServiceContext>([closeAfterTest])(createPeers(2));
35
+ const [host, guest] = await chain<ServiceContext>([closeAfterTest])(createPeers(2));
36
36
 
37
37
  const identity1 = await host.createIdentity();
38
38
  expect(host.identityManager.identity).to.eq(identity1);
@@ -42,7 +42,7 @@ describe('services/device', () => {
42
42
  });
43
43
 
44
44
  test('invitation when already joined', async () => {
45
- const [host, guest] = await asyncChain<ServiceContext>([closeAfterTest])(createPeers(2));
45
+ const [host, guest] = await chain<ServiceContext>([closeAfterTest])(createPeers(2));
46
46
 
47
47
  const identity1 = await host.createIdentity();
48
48
  expect(host.identityManager.identity).to.eq(identity1);
@@ -2,11 +2,12 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import { type Context } from '@dxos/context';
5
6
  import { getCredentialAssertion } from '@dxos/credentials';
6
7
  import { invariant } from '@dxos/invariant';
7
8
  import { type Keyring } from '@dxos/keyring';
8
9
  import { type PublicKey } from '@dxos/keys';
9
- import { AlreadyJoinedError, type ApiError } from '@dxos/protocols';
10
+ import { AlreadyJoinedError } from '@dxos/protocols';
10
11
  import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
11
12
  import type { DeviceProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
12
13
  import {
@@ -15,14 +16,14 @@ import {
15
16
  type IntroductionRequest,
16
17
  } from '@dxos/protocols/proto/dxos/halo/invitations';
17
18
 
19
+ import { type Identity, type JoinIdentityProps } from '../identity';
18
20
  import { type InvitationProtocol } from './invitation-protocol';
19
- import { type Identity, type JoinIdentityParams } from '../identity';
20
21
 
21
22
  export class DeviceInvitationProtocol implements InvitationProtocol {
22
23
  constructor(
23
24
  private readonly _keyring: Keyring,
24
25
  private readonly _getIdentity: () => Identity,
25
- private readonly _acceptIdentity: (identity: JoinIdentityParams) => Promise<Identity>,
26
+ private readonly _acceptIdentity: (identity: JoinIdentityProps) => Promise<Identity>,
26
27
  ) {}
27
28
 
28
29
  toJSON(): object {
@@ -31,7 +32,7 @@ export class DeviceInvitationProtocol implements InvitationProtocol {
31
32
  };
32
33
  }
33
34
 
34
- checkCanInviteNewMembers(): ApiError | undefined {
35
+ checkCanInviteNewMembers(): Error | undefined {
35
36
  return undefined;
36
37
  }
37
38
 
@@ -70,7 +71,7 @@ export class DeviceInvitationProtocol implements InvitationProtocol {
70
71
  try {
71
72
  const identity = this._getIdentity();
72
73
  if (identity) {
73
- return new AlreadyJoinedError('Currently only one identity per client is supported.');
74
+ return new AlreadyJoinedError({ message: 'Currently only one identity per client is supported.' });
74
75
  }
75
76
  } catch {
76
77
  // No identity.
@@ -96,7 +97,7 @@ export class DeviceInvitationProtocol implements InvitationProtocol {
96
97
  };
97
98
  }
98
99
 
99
- async accept(response: AdmissionResponse, request: AdmissionRequest): Promise<Partial<Invitation>> {
100
+ async accept(_ctx: Context, response: AdmissionResponse, request: AdmissionRequest): Promise<Partial<Invitation>> {
100
101
  invariant(response.device);
101
102
  const { identityKey, haloSpaceKey, genesisFeedKey, controlTimeframe } = response.device;
102
103
 
@@ -104,6 +105,7 @@ export class DeviceInvitationProtocol implements InvitationProtocol {
104
105
  const { deviceKey, controlFeedKey, dataFeedKey, profile } = request.device;
105
106
 
106
107
  // TODO(wittjosiah): When multiple identities are supported, verify identity doesn't already exist before accepting.
108
+ // ctx is unused here because _acceptIdentity uses ServiceContext's lifecycle ctx internally.
107
109
 
108
110
  await this._acceptIdentity({
109
111
  identityKey,
@@ -19,17 +19,18 @@ import { schema } from '@dxos/protocols/proto';
19
19
  import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
20
20
  import { type DeviceProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
21
21
  import {
22
- type AdmissionResponse,
23
22
  type AdmissionRequest,
23
+ type AdmissionResponse,
24
24
  type SpaceAdmissionRequest,
25
25
  } from '@dxos/protocols/proto/dxos/halo/invitations';
26
+ import { trace } from '@dxos/tracing';
26
27
 
27
28
  import { type InvitationProtocol } from './invitation-protocol';
28
29
  import { type FlowLockHolder, type GuardedInvitationState } from './invitation-state';
29
30
  import { tryAcquireBeforeContextDisposed } from './utils';
30
31
 
31
32
  export interface EdgeInvitationHandlerCallbacks {
32
- onInvitationSuccess(response: AdmissionResponse, request: AdmissionRequest): Promise<void>;
33
+ onInvitationSuccess(ctx: Context, response: AdmissionResponse, request: AdmissionRequest): Promise<void>;
33
34
  }
34
35
 
35
36
  export const MAX_RETRIES_PER_INVITATION = 5;
@@ -41,6 +42,7 @@ export type EdgeInvitationConfig = {
41
42
  retryJitter?: number;
42
43
  };
43
44
 
45
+ @trace.resource()
44
46
  export class EdgeInvitationHandler implements FlowLockHolder {
45
47
  private _flowLock: MutexGuard | undefined;
46
48
 
@@ -113,6 +115,7 @@ export class EdgeInvitationHandler implements FlowLockHolder {
113
115
  scheduleMicroTask(ctx, tryHandleInvitation);
114
116
  }
115
117
 
118
+ @trace.span({ op: 'invitation.edge' })
116
119
  private async _handleSpaceInvitationFlow(
117
120
  ctx: Context,
118
121
  guardedState: GuardedInvitationState,
@@ -126,13 +129,13 @@ export class EdgeInvitationHandler implements FlowLockHolder {
126
129
 
127
130
  guardedState.set(this, Invitation.State.CONNECTING);
128
131
 
129
- const response = await this._joinSpaceByInvitation(guardedState, spaceId, {
132
+ const response = await this._joinSpaceByInvitation(ctx, guardedState, spaceId, {
130
133
  identityKey: admissionRequest.identityKey.toHex(),
131
134
  invitationId: guardedState.current.invitationId,
132
135
  });
133
136
 
134
137
  const admissionResponse = await this._mapToAdmissionResponse(response);
135
- await this._callbacks.onInvitationSuccess(admissionResponse, { space: admissionRequest });
138
+ await this._callbacks.onInvitationSuccess(ctx, admissionResponse, { space: admissionRequest });
136
139
  } catch (error) {
137
140
  guardedState.set(this, Invitation.State.ERROR);
138
141
  throw error;
@@ -153,13 +156,14 @@ export class EdgeInvitationHandler implements FlowLockHolder {
153
156
  }
154
157
 
155
158
  private async _joinSpaceByInvitation(
159
+ ctx: Context,
156
160
  guardedState: GuardedInvitationState,
157
161
  spaceId: SpaceId,
158
162
  request: JoinSpaceRequest,
159
163
  ): Promise<JoinSpaceResponseBody> {
160
164
  invariant(this._client);
161
165
  try {
162
- return await this._client.joinSpaceByInvitation(spaceId, request);
166
+ return await this._client.joinSpaceByInvitation(ctx, spaceId, request);
163
167
  } catch (error: any) {
164
168
  if (error instanceof EdgeAuthChallengeError) {
165
169
  const publicKey = guardedState.current.guestKeypair?.publicKey;
@@ -168,7 +172,7 @@ export class EdgeInvitationHandler implements FlowLockHolder {
168
172
  throw error;
169
173
  }
170
174
  const signature = sign(Buffer.from(error.challenge, 'base64'), privateKey);
171
- return this._client.joinSpaceByInvitation(spaceId, {
175
+ return this._client.joinSpaceByInvitation(ctx, spaceId, {
172
176
  ...request,
173
177
  signature: Buffer.from(signature).toString('base64'),
174
178
  });
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  export * from './device-invitation-protocol';
6
- export * from './invitation-protocol';
6
+ export type * from './invitation-protocol';
7
7
  export * from './invitations-handler';
8
8
  export * from './invitations-service';
9
9
  export * from './space-invitation-protocol';
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { type Mutex, type MutexGuard, Trigger } from '@dxos/async';
6
- import { cancelWithContext, Context } from '@dxos/context';
6
+ import { Context, cancelWithContext } from '@dxos/context';
7
7
  import { invariant } from '@dxos/invariant';
8
8
  import { log } from '@dxos/log';
9
9
  import { InvalidInvitationExtensionRoleError } from '@dxos/protocols';
@@ -97,10 +97,12 @@ export class InvitationGuestExtension
97
97
  await cancelWithContext(this._ctx, this._remoteOptionsTrigger.wait({ timeout: OPTIONS_TIMEOUT }));
98
98
  log.verbose('options received');
99
99
  if (this._remoteOptions?.role !== InvitationOptions.Role.HOST) {
100
- throw new InvalidInvitationExtensionRoleError(undefined, {
101
- expected: InvitationOptions.Role.HOST,
102
- remoteOptions: this._remoteOptions,
103
- remotePeerId: context.remotePeerId,
100
+ throw new InvalidInvitationExtensionRoleError({
101
+ context: {
102
+ expected: InvitationOptions.Role.HOST,
103
+ remoteOptions: this._remoteOptions,
104
+ remotePeerId: context.remotePeerId,
105
+ },
104
106
  });
105
107
  }
106
108
 
@@ -3,9 +3,9 @@
3
3
  //
4
4
 
5
5
  import { type Mutex, type MutexGuard, Trigger, scheduleTask } from '@dxos/async';
6
- import { cancelWithContext, Context } from '@dxos/context';
6
+ import { Context, cancelWithContext } from '@dxos/context';
7
7
  import { randomBytes, verify } from '@dxos/crypto';
8
- import { invariant, InvariantViolation } from '@dxos/invariant';
8
+ import { InvariantViolation, invariant } from '@dxos/invariant';
9
9
  import { PublicKey } from '@dxos/keys';
10
10
  import { log } from '@dxos/log';
11
11
  import { InvalidInvitationExtensionRoleError, trace } from '@dxos/protocols';
@@ -245,10 +245,12 @@ export class InvitationHostExtension
245
245
  await cancelWithContext(this._ctx, this._remoteOptionsTrigger.wait({ timeout: OPTIONS_TIMEOUT }));
246
246
  log.verbose('options received');
247
247
  if (this._remoteOptions?.role !== InvitationOptions.Role.GUEST) {
248
- throw new InvalidInvitationExtensionRoleError(undefined, {
249
- expected: InvitationOptions.Role.GUEST,
250
- remoteOptions: this._remoteOptions,
251
- remotePeerId: context.remotePeerId,
248
+ throw new InvalidInvitationExtensionRoleError({
249
+ context: {
250
+ expected: InvitationOptions.Role.GUEST,
251
+ remoteOptions: this._remoteOptions,
252
+ remotePeerId: context.remotePeerId,
253
+ },
252
254
  });
253
255
  }
254
256
  this._callbacks.onStateUpdate(Invitation.State.CONNECTED);
@@ -2,10 +2,10 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import { type Context } from '@dxos/context';
5
6
  import { type PublicKey } from '@dxos/keys';
6
- import type { ApiError } from '@dxos/protocols';
7
7
  import type { Invitation } from '@dxos/protocols/proto/dxos/client/services';
8
- import type { ProfileDocument, DeviceProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
8
+ import type { DeviceProfileDocument, ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
9
9
  import type {
10
10
  AdmissionRequest,
11
11
  AdmissionResponse,
@@ -26,7 +26,7 @@ export interface InvitationProtocol {
26
26
  // Host
27
27
  //
28
28
 
29
- checkCanInviteNewMembers(): ApiError | undefined;
29
+ checkCanInviteNewMembers(): Error | undefined;
30
30
 
31
31
  /**
32
32
  * Protocol-specific information to include in the invitation.
@@ -58,7 +58,7 @@ export interface InvitationProtocol {
58
58
  *
59
59
  * For example, the guest may already be a member of the space.
60
60
  */
61
- checkInvitation(invitation: Partial<Invitation>): ApiError | undefined;
61
+ checkInvitation(invitation: Partial<Invitation>): Error | undefined;
62
62
 
63
63
  /**
64
64
  * Get profile information to send to the host to identify the guest.
@@ -72,6 +72,9 @@ export interface InvitationProtocol {
72
72
 
73
73
  /**
74
74
  * Redeem the admission credential.
75
+ * @param ctx - Caller context used for tracing and cancellation. Forwarded to downstream
76
+ * internal methods (e.g. `DataSpaceManager.acceptSpace`) so their spans become children of
77
+ * the invitation flow span.
75
78
  */
76
- accept(response: AdmissionResponse, request: AdmissionRequest): Promise<Partial<Invitation>>;
79
+ accept(ctx: Context, response: AdmissionResponse, request: AdmissionRequest): Promise<Partial<Invitation>>;
77
80
  }
@@ -31,12 +31,6 @@ export const createGuardedInvitationState = (
31
31
  invitation: Invitation,
32
32
  stream: PushStream<Invitation>,
33
33
  ): GuardedInvitationState => {
34
- // the mutex guards invitation flow on host and guest side, making sure only one flow is currently active
35
- // deadlocks seem very unlikely because hosts don't initiate multiple connections
36
- // even if this somehow happens that there are 2 guests (A, B) and 2 hosts (1, 2) and:
37
- // A has lock for flow with 1, B has lock for flow with 2
38
- // 1 has lock for flow with B, 2 has lock for flow with A
39
- // there'll be a 10-second introduction timeout after which connection will be closed and deadlock broken
40
34
  const mutex = new Mutex();
41
35
  let lastActiveLockHolder: FlowLockHolder | null = null;
42
36
  let currentInvitation = { ...invitation };
@@ -44,9 +38,6 @@ export const createGuardedInvitationState = (
44
38
  if (ctx.disposed || (lockHolder !== null && mutex.isLocked() && !lockHolder.hasFlowLock())) {
45
39
  return false;
46
40
  }
47
- // don't allow transitions from a terminal state unless a new extension acquired mutex
48
- // handles a case when error occurs (e.g. connection is closed) after we completed the flow
49
- // successfully or already reported another error
50
41
  return lockHolder == null || lastActiveLockHolder !== lockHolder || isNonTerminalState(currentInvitation.state);
51
42
  };
52
43
  return {
@@ -54,7 +45,6 @@ export const createGuardedInvitationState = (
54
45
  get current() {
55
46
  return currentInvitation;
56
47
  },
57
- // disposing context prevents any further state updates
58
48
  complete: (newState: Partial<Invitation>) => {
59
49
  logStateUpdate(currentInvitation, undefined, invitation.state);
60
50
  currentInvitation = { ...currentInvitation, ...newState };