@dxos/client-services 0.10.0 → 0.11.1

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 (304) hide show
  1. package/dist/lib/chunk-client-services-layer.mjs +11425 -0
  2. package/dist/lib/chunk-client-services-layer.mjs.map +1 -0
  3. package/dist/lib/chunk-decorate.mjs +9 -0
  4. package/dist/lib/index.mjs +731 -0
  5. package/dist/lib/index.mjs.map +1 -0
  6. package/dist/lib/packlets/diagnostics/browser-diagnostics-broadcast.mjs +72 -0
  7. package/dist/lib/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +1 -0
  8. package/dist/lib/packlets/diagnostics/diagnostics-broadcast.mjs +14 -0
  9. package/dist/lib/packlets/diagnostics/diagnostics-broadcast.mjs.map +1 -0
  10. package/dist/lib/packlets/locks/browser.mjs +105 -0
  11. package/dist/lib/packlets/locks/browser.mjs.map +1 -0
  12. package/dist/lib/packlets/locks/node.mjs +53 -0
  13. package/dist/lib/packlets/locks/node.mjs.map +1 -0
  14. package/dist/lib/testing.mjs +570 -0
  15. package/dist/lib/testing.mjs.map +1 -0
  16. package/dist/types/src/index.d.ts +2 -0
  17. package/dist/types/src/index.d.ts.map +1 -1
  18. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +21 -4
  19. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
  20. package/dist/types/src/packlets/agents/edge-agent-service.d.ts +8 -7
  21. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  22. package/dist/types/src/packlets/devices/devices-service.d.ts +7 -5
  23. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  24. package/dist/types/src/packlets/devtools/devtools.d.ts +30 -29
  25. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  26. package/dist/types/src/packlets/devtools/feeds.d.ts +1 -1
  27. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  28. package/dist/types/src/packlets/devtools/network.d.ts +2 -1
  29. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  30. package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
  31. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts +2 -2
  32. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
  33. package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
  34. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +1 -8
  35. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  36. package/dist/types/src/packlets/identity/authenticator.d.ts +1 -1
  37. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  38. package/dist/types/src/packlets/identity/contacts-service.d.ts +9 -6
  39. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  40. package/dist/types/src/packlets/identity/identity-manager.d.ts +32 -3
  41. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  42. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +23 -4
  43. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  44. package/dist/types/src/packlets/identity/identity-service.d.ts +15 -20
  45. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  46. package/dist/types/src/packlets/identity/identity.d.ts +2 -2
  47. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  48. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
  49. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +17 -0
  50. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  51. package/dist/types/src/packlets/invitations/invitations-manager.d.ts +25 -4
  52. package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
  53. package/dist/types/src/packlets/invitations/invitations-service.d.ts +11 -11
  54. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  55. package/dist/types/src/packlets/logging/logging-service.d.ts +14 -12
  56. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  57. package/dist/types/src/packlets/metadata/index.d.ts +3 -0
  58. package/dist/types/src/packlets/metadata/index.d.ts.map +1 -0
  59. package/dist/types/src/packlets/metadata/metadata-store.d.ts +107 -0
  60. package/dist/types/src/packlets/metadata/metadata-store.d.ts.map +1 -0
  61. package/dist/types/src/packlets/metadata/metadata-store.test.d.ts +2 -0
  62. package/dist/types/src/packlets/metadata/metadata-store.test.d.ts.map +1 -0
  63. package/dist/types/src/packlets/metadata/sqlite-metadata-store.d.ts +65 -0
  64. package/dist/types/src/packlets/metadata/sqlite-metadata-store.d.ts.map +1 -0
  65. package/dist/types/src/packlets/network/network-service.d.ts +15 -14
  66. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  67. package/dist/types/src/packlets/pipeline/codec.d.ts +11 -0
  68. package/dist/types/src/packlets/pipeline/codec.d.ts.map +1 -0
  69. package/dist/types/src/packlets/pipeline/feeds.d.ts +7 -0
  70. package/dist/types/src/packlets/pipeline/feeds.d.ts.map +1 -0
  71. package/dist/types/src/packlets/pipeline/index.d.ts +5 -0
  72. package/dist/types/src/packlets/pipeline/index.d.ts.map +1 -0
  73. package/dist/types/src/packlets/pipeline/message-selector.d.ts +11 -0
  74. package/dist/types/src/packlets/pipeline/message-selector.d.ts.map +1 -0
  75. package/dist/types/src/packlets/pipeline/pipeline-stress.test.d.ts +2 -0
  76. package/dist/types/src/packlets/pipeline/pipeline-stress.test.d.ts.map +1 -0
  77. package/dist/types/src/packlets/pipeline/pipeline.d.ts +131 -0
  78. package/dist/types/src/packlets/pipeline/pipeline.d.ts.map +1 -0
  79. package/dist/types/src/packlets/pipeline/pipeline.test.d.ts +2 -0
  80. package/dist/types/src/packlets/pipeline/pipeline.test.d.ts.map +1 -0
  81. package/dist/types/src/packlets/pipeline/testing/index.d.ts +2 -0
  82. package/dist/types/src/packlets/pipeline/testing/index.d.ts.map +1 -0
  83. package/dist/types/src/packlets/pipeline/testing/test-feed-builder.d.ts +9 -0
  84. package/dist/types/src/packlets/pipeline/testing/test-feed-builder.d.ts.map +1 -0
  85. package/dist/types/src/packlets/pipeline/timeframe-clock.d.ts +31 -0
  86. package/dist/types/src/packlets/pipeline/timeframe-clock.d.ts.map +1 -0
  87. package/dist/types/src/packlets/services/client-services-layer.d.ts +21 -0
  88. package/dist/types/src/packlets/services/client-services-layer.d.ts.map +1 -0
  89. package/dist/types/src/packlets/services/cross-device-space-synchronizer.d.ts +28 -0
  90. package/dist/types/src/packlets/services/cross-device-space-synchronizer.d.ts.map +1 -0
  91. package/dist/types/src/packlets/services/effect-rpc.test.d.ts +2 -0
  92. package/dist/types/src/packlets/services/effect-rpc.test.d.ts.map +1 -0
  93. package/dist/types/src/packlets/services/feed-syncer.d.ts +22 -2
  94. package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -1
  95. package/dist/types/src/packlets/services/index.d.ts +2 -2
  96. package/dist/types/src/packlets/services/index.d.ts.map +1 -1
  97. package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
  98. package/dist/types/src/packlets/services/service-context.d.ts +38 -57
  99. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  100. package/dist/types/src/packlets/services/service-host.d.ts +82 -31
  101. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  102. package/dist/types/src/packlets/services/sqlite-storage.d.ts +29 -0
  103. package/dist/types/src/packlets/services/sqlite-storage.d.ts.map +1 -1
  104. package/dist/types/src/packlets/services/sqlite-storage.test.d.ts +2 -0
  105. package/dist/types/src/packlets/services/sqlite-storage.test.d.ts.map +1 -0
  106. package/dist/types/src/packlets/space/admission-discovery-extension.d.ts +30 -0
  107. package/dist/types/src/packlets/space/admission-discovery-extension.d.ts.map +1 -0
  108. package/dist/types/src/packlets/space/auth.d.ts +24 -0
  109. package/dist/types/src/packlets/space/auth.d.ts.map +1 -0
  110. package/dist/types/src/packlets/space/control-pipeline.d.ts +46 -0
  111. package/dist/types/src/packlets/space/control-pipeline.d.ts.map +1 -0
  112. package/dist/types/src/packlets/space/control-pipeline.test.d.ts +2 -0
  113. package/dist/types/src/packlets/space/control-pipeline.test.d.ts.map +1 -0
  114. package/dist/types/src/packlets/space/index.d.ts +6 -0
  115. package/dist/types/src/packlets/space/index.d.ts.map +1 -0
  116. package/dist/types/src/packlets/space/replication.browser.test.d.ts +2 -0
  117. package/dist/types/src/packlets/space/replication.browser.test.d.ts.map +1 -0
  118. package/dist/types/src/packlets/space/space-manager.browser.test.d.ts +2 -0
  119. package/dist/types/src/packlets/space/space-manager.browser.test.d.ts.map +1 -0
  120. package/dist/types/src/packlets/space/space-manager.d.ts +72 -0
  121. package/dist/types/src/packlets/space/space-manager.d.ts.map +1 -0
  122. package/dist/types/src/packlets/space/space-protocol.browser.test.d.ts +2 -0
  123. package/dist/types/src/packlets/space/space-protocol.browser.test.d.ts.map +1 -0
  124. package/dist/types/src/packlets/space/space-protocol.d.ts +99 -0
  125. package/dist/types/src/packlets/space/space-protocol.d.ts.map +1 -0
  126. package/dist/types/src/packlets/space/space-protocol.test.d.ts +2 -0
  127. package/dist/types/src/packlets/space/space-protocol.test.d.ts.map +1 -0
  128. package/dist/types/src/packlets/space/space.d.ts +65 -0
  129. package/dist/types/src/packlets/space/space.d.ts.map +1 -0
  130. package/dist/types/src/packlets/space/space.test.d.ts +2 -0
  131. package/dist/types/src/packlets/space/space.test.d.ts.map +1 -0
  132. package/dist/types/src/packlets/space/testing/change-metadata.d.ts +8 -0
  133. package/dist/types/src/packlets/space/testing/change-metadata.d.ts.map +1 -0
  134. package/dist/types/src/packlets/space/testing/index.d.ts +4 -0
  135. package/dist/types/src/packlets/space/testing/index.d.ts.map +1 -0
  136. package/dist/types/src/packlets/space/testing/test-agent-builder.d.ts +62 -0
  137. package/dist/types/src/packlets/space/testing/test-agent-builder.d.ts.map +1 -0
  138. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts +1 -1
  139. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts.map +1 -1
  140. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts.map +1 -1
  141. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +40 -7
  142. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  143. package/dist/types/src/packlets/spaces/data-space.d.ts +3 -1
  144. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  145. package/dist/types/src/packlets/spaces/genesis.d.ts +1 -1
  146. package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
  147. package/dist/types/src/packlets/spaces/spaces-service.d.ts +25 -23
  148. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  149. package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
  150. package/dist/types/src/packlets/system/system-service.d.ts +18 -18
  151. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  152. package/dist/types/src/packlets/testing/invitation-utils.d.ts +1 -1
  153. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  154. package/dist/types/src/packlets/testing/test-builder.d.ts +7 -6
  155. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  156. package/dist/types/src/packlets/worker/worker-runtime.d.ts +41 -58
  157. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  158. package/dist/types/src/packlets/worker/worker-session.d.ts +21 -8
  159. package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
  160. package/dist/types/src/testing/index.d.ts +1 -0
  161. package/dist/types/src/testing/index.d.ts.map +1 -1
  162. package/dist/types/src/version.d.ts +1 -1
  163. package/dist/types/tsconfig.tsbuildinfo +1 -1
  164. package/package.json +52 -48
  165. package/src/index.ts +2 -0
  166. package/src/packlets/agents/edge-agent-manager.ts +56 -15
  167. package/src/packlets/agents/edge-agent-service.ts +25 -15
  168. package/src/packlets/devices/devices-service.test.ts +20 -19
  169. package/src/packlets/devices/devices-service.ts +17 -17
  170. package/src/packlets/devtools/devtools.ts +133 -75
  171. package/src/packlets/devtools/feeds.ts +2 -1
  172. package/src/packlets/devtools/network.ts +42 -12
  173. package/src/packlets/devtools/spaces.ts +1 -1
  174. package/src/packlets/diagnostics/diagnostics-broadcast.ts +4 -2
  175. package/src/packlets/diagnostics/diagnostics-collector.ts +5 -18
  176. package/src/packlets/diagnostics/diagnostics.ts +0 -11
  177. package/src/packlets/identity/authenticator.ts +2 -1
  178. package/src/packlets/identity/contacts-service.ts +46 -37
  179. package/src/packlets/identity/identity-manager.test.ts +3 -1
  180. package/src/packlets/identity/identity-manager.ts +73 -5
  181. package/src/packlets/identity/identity-recovery-manager.ts +56 -7
  182. package/src/packlets/identity/identity-service.test.ts +27 -18
  183. package/src/packlets/identity/identity-service.ts +114 -71
  184. package/src/packlets/identity/identity.test.ts +4 -9
  185. package/src/packlets/identity/identity.ts +1 -2
  186. package/src/packlets/invitations/edge-invitation-handler.ts +0 -1
  187. package/src/packlets/invitations/invitations-handler.ts +39 -3
  188. package/src/packlets/invitations/invitations-manager.ts +52 -4
  189. package/src/packlets/invitations/invitations-service.ts +54 -28
  190. package/src/packlets/logging/logging-service.ts +41 -29
  191. package/src/packlets/logging/logging.test.ts +28 -15
  192. package/src/packlets/metadata/index.ts +6 -0
  193. package/src/packlets/metadata/metadata-store.test.ts +49 -0
  194. package/src/packlets/metadata/metadata-store.ts +446 -0
  195. package/src/packlets/metadata/sqlite-metadata-store.ts +409 -0
  196. package/src/packlets/network/network-service.test.ts +19 -12
  197. package/src/packlets/network/network-service.ts +96 -29
  198. package/src/packlets/pipeline/codec.ts +18 -0
  199. package/src/packlets/pipeline/feeds.ts +22 -0
  200. package/src/packlets/pipeline/index.ts +8 -0
  201. package/src/packlets/pipeline/message-selector.ts +35 -0
  202. package/src/packlets/pipeline/pipeline-stress.test.ts +230 -0
  203. package/src/packlets/pipeline/pipeline.test.ts +140 -0
  204. package/src/packlets/pipeline/pipeline.ts +439 -0
  205. package/src/packlets/pipeline/testing/index.ts +5 -0
  206. package/src/packlets/pipeline/testing/test-feed-builder.ts +19 -0
  207. package/src/packlets/pipeline/timeframe-clock.ts +81 -0
  208. package/src/packlets/services/client-services-layer.ts +186 -0
  209. package/src/packlets/services/cross-device-space-synchronizer.ts +132 -0
  210. package/src/packlets/services/effect-rpc.test.ts +314 -0
  211. package/src/packlets/services/feed-syncer.ts +57 -3
  212. package/src/packlets/services/index.ts +2 -2
  213. package/src/packlets/services/platform.ts +0 -6
  214. package/src/packlets/services/service-context.ts +219 -522
  215. package/src/packlets/services/service-host.test.ts +34 -11
  216. package/src/packlets/services/service-host.ts +693 -213
  217. package/src/packlets/services/spec.md +106 -0
  218. package/src/packlets/services/sqlite-storage.test.ts +48 -0
  219. package/src/packlets/services/sqlite-storage.ts +117 -20
  220. package/src/packlets/space/admission-discovery-extension.ts +91 -0
  221. package/src/packlets/space/auth.ts +92 -0
  222. package/src/packlets/space/control-pipeline.test.ts +165 -0
  223. package/src/packlets/space/control-pipeline.ts +229 -0
  224. package/src/packlets/space/index.ts +9 -0
  225. package/src/packlets/space/replication.browser.test.ts +58 -0
  226. package/src/packlets/space/space-manager.browser.test.ts +40 -0
  227. package/src/packlets/space/space-manager.ts +224 -0
  228. package/src/packlets/space/space-protocol.browser.test.ts +129 -0
  229. package/src/packlets/space/space-protocol.test.ts +158 -0
  230. package/src/packlets/space/space-protocol.ts +308 -0
  231. package/src/packlets/space/space.test.ts +181 -0
  232. package/src/packlets/space/space.ts +196 -0
  233. package/src/packlets/space/testing/change-metadata.ts +27 -0
  234. package/src/packlets/space/testing/index.ts +7 -0
  235. package/src/packlets/space/testing/test-agent-builder.ts +252 -0
  236. package/src/packlets/space-export/serialized-space-reader.ts +3 -1
  237. package/src/packlets/space-export/serialized-space-writer.ts +53 -30
  238. package/src/packlets/space-export/space-archive.test.ts +30 -0
  239. package/src/packlets/spaces/data-space-manager.test.ts +1 -1
  240. package/src/packlets/spaces/data-space-manager.ts +148 -33
  241. package/src/packlets/spaces/data-space.ts +29 -18
  242. package/src/packlets/spaces/edge-feed-replicator.test.ts +1 -1
  243. package/src/packlets/spaces/genesis.ts +1 -1
  244. package/src/packlets/spaces/spaces-service.test.ts +35 -22
  245. package/src/packlets/spaces/spaces-service.ts +259 -180
  246. package/src/packlets/storage/level.ts +3 -1
  247. package/src/packlets/system/system-service.test.ts +31 -13
  248. package/src/packlets/system/system-service.ts +65 -37
  249. package/src/packlets/testing/invitation-utils.ts +3 -3
  250. package/src/packlets/testing/test-builder.ts +35 -20
  251. package/src/packlets/worker/worker-runtime.ts +222 -260
  252. package/src/packlets/worker/worker-session.ts +108 -91
  253. package/src/testing/index.ts +1 -0
  254. package/src/version.ts +1 -1
  255. package/dist/lib/browser/chunk-QCWEHHJW.mjs +0 -24
  256. package/dist/lib/browser/chunk-QCWEHHJW.mjs.map +0 -7
  257. package/dist/lib/browser/chunk-XJRPB3GA.mjs +0 -22
  258. package/dist/lib/browser/chunk-XJRPB3GA.mjs.map +0 -7
  259. package/dist/lib/browser/chunk-XU5R2BMF.mjs +0 -8837
  260. package/dist/lib/browser/chunk-XU5R2BMF.mjs.map +0 -7
  261. package/dist/lib/browser/index.mjs +0 -876
  262. package/dist/lib/browser/index.mjs.map +0 -7
  263. package/dist/lib/browser/meta.json +0 -1
  264. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +0 -88
  265. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +0 -7
  266. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +0 -11
  267. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs.map +0 -7
  268. package/dist/lib/browser/packlets/locks/browser.mjs +0 -86
  269. package/dist/lib/browser/packlets/locks/browser.mjs.map +0 -7
  270. package/dist/lib/browser/packlets/locks/node.mjs +0 -48
  271. package/dist/lib/browser/packlets/locks/node.mjs.map +0 -7
  272. package/dist/lib/browser/testing/index.mjs +0 -436
  273. package/dist/lib/browser/testing/index.mjs.map +0 -7
  274. package/dist/lib/node-esm/chunk-2DT3MZRL.mjs +0 -22
  275. package/dist/lib/node-esm/chunk-2DT3MZRL.mjs.map +0 -7
  276. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +0 -24
  277. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +0 -7
  278. package/dist/lib/node-esm/chunk-H5YTUD35.mjs +0 -8837
  279. package/dist/lib/node-esm/chunk-H5YTUD35.mjs.map +0 -7
  280. package/dist/lib/node-esm/index.mjs +0 -876
  281. package/dist/lib/node-esm/index.mjs.map +0 -7
  282. package/dist/lib/node-esm/meta.json +0 -1
  283. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +0 -88
  284. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +0 -7
  285. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +0 -11
  286. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs.map +0 -7
  287. package/dist/lib/node-esm/packlets/locks/browser.mjs +0 -86
  288. package/dist/lib/node-esm/packlets/locks/browser.mjs.map +0 -7
  289. package/dist/lib/node-esm/packlets/locks/node.mjs +0 -48
  290. package/dist/lib/node-esm/packlets/locks/node.mjs.map +0 -7
  291. package/dist/lib/node-esm/testing/index.mjs +0 -436
  292. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  293. package/dist/types/src/packlets/services/client-rpc-server.d.ts +0 -24
  294. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +0 -1
  295. package/dist/types/src/packlets/services/service-registry.d.ts +0 -15
  296. package/dist/types/src/packlets/services/service-registry.d.ts.map +0 -1
  297. package/dist/types/src/packlets/services/service-registry.test.d.ts +0 -2
  298. package/dist/types/src/packlets/services/service-registry.test.d.ts.map +0 -1
  299. package/dist/types/src/testing/setup.d.ts +0 -3
  300. package/dist/types/src/testing/setup.d.ts.map +0 -1
  301. package/src/packlets/services/client-rpc-server.ts +0 -111
  302. package/src/packlets/services/service-registry.test.ts +0 -78
  303. package/src/packlets/services/service-registry.ts +0 -36
  304. package/src/testing/setup.ts +0 -11
@@ -1,3 +1,7 @@
1
+ import * as EffectContext from 'effect/Context';
2
+ import * as Effect from 'effect/Effect';
3
+ import * as Layer from 'effect/Layer';
4
+ import * as Option from 'effect/Option';
1
5
  //
2
6
  // Copyright 2022 DXOS.org
3
7
  //
@@ -6,11 +10,11 @@ import platform from 'platform';
6
10
  import { Event } from '@dxos/async';
7
11
  import { Context } from '@dxos/context';
8
12
  import { CredentialGenerator, createCredentialSignerWithKey, createDidFromIdentityKey } from '@dxos/credentials';
9
- import { type IMetadataStore, type SpaceManager, type SwarmIdentity } from '@dxos/echo-host';
10
- import { type EdgeConnection } from '@dxos/edge-client';
11
- import { type FeedStore } from '@dxos/feed-store';
13
+ import { failUndefined } from '@dxos/debug';
14
+ import { type EdgeConnection, EdgeConnectionService } from '@dxos/edge-client';
15
+ import { type FeedStore, FeedStoreService } from '@dxos/feed-store';
12
16
  import { invariant } from '@dxos/invariant';
13
- import { type KeyringApi } from '@dxos/keyring';
17
+ import { type KeyringApi, KeyringApiService } from '@dxos/keyring';
14
18
  import { PublicKey } from '@dxos/keys';
15
19
  import { log } from '@dxos/log';
16
20
  import { Device, DeviceKind } from '@dxos/protocols/proto/dxos/client/services';
@@ -29,6 +33,8 @@ import { Timeframe } from '@dxos/timeframe';
29
33
  import { trace as Trace } from '@dxos/tracing';
30
34
  import { deferFunction, isNode, isTauri } from '@dxos/util';
31
35
 
36
+ import { type IMetadataStore, IMetadataStoreService } from '../metadata';
37
+ import { type SpaceManager, SpaceManagerService, type SwarmIdentity } from '../space';
32
38
  import { createAuthProvider } from './authenticator';
33
39
  import { Identity } from './identity';
34
40
 
@@ -77,8 +83,36 @@ export type IdentityManagerProps = {
77
83
  devicePresenceOfflineTimeout?: number;
78
84
  };
79
85
 
86
+ /**
87
+ * Resolves the active identity when it becomes available.
88
+ */
89
+ export type IdentityProvider = () => Identity;
90
+
91
+ /**
92
+ * Effect service tag for {@link IdentityProvider}.
93
+ */
94
+ export class IdentityProviderService extends EffectContext.Tag('@dxos/client-services/IdentityProvider')<
95
+ IdentityProviderService,
96
+ IdentityProvider
97
+ >() {}
98
+
99
+ /**
100
+ * Builds an {@link IdentityProvider} from an {@link IdentityManager}.
101
+ */
102
+ export const identityProviderFromManager =
103
+ (identityManager: IdentityManager): IdentityProvider =>
104
+ () =>
105
+ identityManager.identity ?? failUndefined();
106
+
107
+ /**
108
+ * Effect service tag for {@link IdentityManager}.
109
+ */
110
+ export class IdentityManagerService extends EffectContext.Tag('@dxos/client-services/IdentityManager')<
111
+ IdentityManagerService,
112
+ IdentityManager
113
+ >() {}
114
+
80
115
  // TODO(dmaretskyi): Rename: represents the peer's state machine.
81
- @Trace.resource()
82
116
  export class IdentityManager {
83
117
  readonly stateUpdate = new Event();
84
118
 
@@ -418,3 +452,37 @@ export class IdentityManager {
418
452
  });
419
453
  }
420
454
  }
455
+
456
+ export type IdentityManagerLayerOptions = Pick<
457
+ IdentityManagerProps,
458
+ 'devicePresenceAnnounceInterval' | 'devicePresenceOfflineTimeout' | 'edgeFeatures'
459
+ >;
460
+
461
+ /**
462
+ * Effect Layer constructing an {@link IdentityManager} from ambient service dependencies.
463
+ */
464
+ export const IdentityManagerLayer = (
465
+ options: IdentityManagerLayerOptions = {},
466
+ ): Layer.Layer<
467
+ IdentityManagerService,
468
+ never,
469
+ IMetadataStoreService | KeyringApiService | FeedStoreService | SpaceManagerService
470
+ > =>
471
+ Layer.effect(
472
+ IdentityManagerService,
473
+ Effect.gen(function* () {
474
+ const metadataStore = yield* IMetadataStoreService;
475
+ const keyring = yield* KeyringApiService;
476
+ const feedStore = yield* FeedStoreService;
477
+ const spaceManager = yield* SpaceManagerService;
478
+ const edgeConnection = yield* Effect.serviceOption(EdgeConnectionService);
479
+ return new IdentityManager({
480
+ metadataStore,
481
+ keyring,
482
+ feedStore,
483
+ spaceManager,
484
+ edgeConnection: Option.getOrUndefined(edgeConnection),
485
+ ...options,
486
+ });
487
+ }),
488
+ );
@@ -2,12 +2,17 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import * as EffectContext from 'effect/Context';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Layer from 'effect/Layer';
8
+ import * as Option from 'effect/Option';
9
+
5
10
  import { type Context } from '@dxos/context';
6
11
  import { generateSeedPhrase, keyPairFromSeedPhrase } from '@dxos/credentials';
7
12
  import { sign } from '@dxos/crypto';
8
- import { type EdgeHttpClient } from '@dxos/edge-client';
13
+ import { type EdgeHttpClient, EdgeHttpClientService } from '@dxos/edge-client';
9
14
  import { invariant } from '@dxos/invariant';
10
- import { type KeyringApi } from '@dxos/keyring';
15
+ import { type KeyringApi, KeyringApiService } from '@dxos/keyring';
11
16
  import { PublicKey } from '@dxos/keys';
12
17
  import { log } from '@dxos/log';
13
18
  import {
@@ -23,16 +28,33 @@ import {
23
28
  import { Timeframe } from '@dxos/timeframe';
24
29
 
25
30
  import { type Identity } from './identity';
26
- import { type JoinIdentityProps } from './identity-manager';
31
+ import { IdentityManagerService, type JoinIdentityProps } from './identity-manager';
32
+
33
+ /**
34
+ * Effect service tag for {@link EdgeIdentityRecoveryManager}.
35
+ */
36
+ export class EdgeIdentityRecoveryManagerService extends EffectContext.Tag(
37
+ '@dxos/client-services/EdgeIdentityRecoveryManager',
38
+ )<EdgeIdentityRecoveryManagerService, EdgeIdentityRecoveryManager>() {}
39
+
40
+ export type AcceptRecoveredIdentity = (params: JoinIdentityProps) => Promise<Identity>;
27
41
 
28
42
  export class EdgeIdentityRecoveryManager {
43
+ private _acceptRecoveredIdentity?: AcceptRecoveredIdentity;
44
+
29
45
  constructor(
30
46
  private readonly _keyring: KeyringApi,
31
47
  private readonly _edgeClient: EdgeHttpClient | undefined,
32
48
  private readonly _identityProvider: () => Identity | undefined,
33
- private readonly _acceptRecoveredIdentity: (params: JoinIdentityProps) => Promise<Identity>,
34
49
  ) {}
35
50
 
51
+ /**
52
+ * Wires identity acceptance after the composing stack is fully constructed.
53
+ */
54
+ setAcceptRecoveredIdentity(acceptRecoveredIdentity: AcceptRecoveredIdentity): void {
55
+ this._acceptRecoveredIdentity = acceptRecoveredIdentity;
56
+ }
57
+
36
58
  public async createRecoveryCredential({
37
59
  data,
38
60
  }: CreateRecoveryCredentialRequest): Promise<{ recoveryCode: string | undefined }> {
@@ -127,7 +149,7 @@ export class EdgeIdentityRecoveryManager {
127
149
 
128
150
  const response = await this._edgeClient.recoverIdentity(ctx, request);
129
151
 
130
- await this._acceptRecoveredIdentity({
152
+ await this.#acceptRecoveredIdentity({
131
153
  authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),
132
154
  haloGenesisFeedKey: PublicKey.fromHex(response.genesisFeedKey),
133
155
  haloSpaceKey: PublicKey.fromHex(response.haloSpaceKey),
@@ -159,7 +181,7 @@ export class EdgeIdentityRecoveryManager {
159
181
 
160
182
  const response = await this._edgeClient.recoverIdentity(ctx, request);
161
183
 
162
- await this._acceptRecoveredIdentity({
184
+ await this.#acceptRecoveredIdentity({
163
185
  authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),
164
186
  haloGenesisFeedKey: PublicKey.fromHex(response.genesisFeedKey),
165
187
  haloSpaceKey: PublicKey.fromHex(response.haloSpaceKey),
@@ -199,7 +221,7 @@ export class EdgeIdentityRecoveryManager {
199
221
 
200
222
  log.info('recovering identity', response);
201
223
 
202
- await this._acceptRecoveredIdentity({
224
+ await this.#acceptRecoveredIdentity({
203
225
  authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),
204
226
  haloGenesisFeedKey: PublicKey.fromHex(response.genesisFeedKey),
205
227
  haloSpaceKey: PublicKey.fromHex(response.haloSpaceKey),
@@ -209,6 +231,11 @@ export class EdgeIdentityRecoveryManager {
209
231
  dataFeedKey: await this._keyring.createKey(),
210
232
  });
211
233
  }
234
+
235
+ #acceptRecoveredIdentity(params: JoinIdentityProps): Promise<Identity> {
236
+ invariant(this._acceptRecoveredIdentity, 'acceptRecoveredIdentity not set');
237
+ return this._acceptRecoveredIdentity(params);
238
+ }
212
239
  }
213
240
 
214
241
  const decodeCredential = (credentialBase64: string) => {
@@ -216,3 +243,25 @@ const decodeCredential = (credentialBase64: string) => {
216
243
  const codec = schema.getCodecForType('dxos.halo.credentials.Credential');
217
244
  return codec.decode(credentialBytes);
218
245
  };
246
+
247
+ /**
248
+ * Effect Layer constructing a dormant {@link EdgeIdentityRecoveryManager}.
249
+ */
250
+ export const EdgeIdentityRecoveryManagerLayer = (): Layer.Layer<
251
+ EdgeIdentityRecoveryManagerService,
252
+ never,
253
+ KeyringApiService | IdentityManagerService
254
+ > =>
255
+ Layer.effect(
256
+ EdgeIdentityRecoveryManagerService,
257
+ Effect.gen(function* () {
258
+ const keyring = yield* KeyringApiService;
259
+ const edgeClient = yield* Effect.serviceOption(EdgeHttpClientService);
260
+ const identityManager = yield* IdentityManagerService;
261
+ return new EdgeIdentityRecoveryManager(
262
+ keyring,
263
+ Option.getOrUndefined(edgeClient),
264
+ () => identityManager.identity,
265
+ );
266
+ }),
267
+ );
@@ -2,12 +2,15 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import * as Runtime from 'effect/Runtime';
5
6
  import { afterEach, beforeEach, describe, expect, onTestFinished, test } from 'vitest';
6
7
 
7
8
  import { Trigger } from '@dxos/async';
8
9
  import { Context } from '@dxos/context';
10
+ import { EffectEx } from '@dxos/effect';
9
11
  import { PublicKey } from '@dxos/keys';
10
- import { type Identity, type IdentityService } from '@dxos/protocols/proto/dxos/client/services';
12
+ import { subscribeStream } from '@dxos/protocols';
13
+ import { type Identity } from '@dxos/protocols/proto/dxos/client/services';
11
14
 
12
15
  import { type ServiceContext } from '../services';
13
16
  import { createServiceContext } from '../testing';
@@ -15,7 +18,7 @@ import { IdentityServiceImpl } from './identity-service';
15
18
 
16
19
  describe('IdentityService', () => {
17
20
  let serviceContext: ServiceContext;
18
- let identityService: IdentityService;
21
+ let identityService: IdentityServiceImpl;
19
22
 
20
23
  beforeEach(async () => {
21
24
  serviceContext = await createServiceContext();
@@ -29,14 +32,16 @@ describe('IdentityService', () => {
29
32
 
30
33
  describe('createIdentity', () => {
31
34
  test('creates a new identity', async () => {
32
- const identity = await identityService.createIdentity({});
35
+ const identity = await EffectEx.runPromise(identityService['IdentityService.createIdentity']({}));
33
36
 
34
37
  expect(identity.identityKey).to.be.instanceof(PublicKey);
35
38
  expect(identity.spaceKey).to.be.instanceof(PublicKey);
36
39
  });
37
40
 
38
41
  test('creates a new identity with a display name', async () => {
39
- const identity = await identityService.createIdentity({ profile: { displayName: 'Example' } });
42
+ const identity = await EffectEx.runPromise(
43
+ identityService['IdentityService.createIdentity']({ profile: { displayName: 'Example' } }),
44
+ );
40
45
 
41
46
  expect(identity.identityKey).to.be.instanceof(PublicKey);
42
47
  expect(identity.spaceKey).to.be.instanceof(PublicKey);
@@ -44,12 +49,14 @@ describe('IdentityService', () => {
44
49
  });
45
50
 
46
51
  test('fails to create identity if one already exists', async () => {
47
- await identityService.createIdentity({});
48
- await expect(identityService.createIdentity({})).rejects.toThrowError('Identity already exists');
52
+ await EffectEx.runPromise(identityService['IdentityService.createIdentity']({}));
53
+ await expect(EffectEx.runPromise(identityService['IdentityService.createIdentity']({}))).rejects.toThrowError(
54
+ 'Identity already exists',
55
+ );
49
56
  });
50
57
 
51
58
  test('creates identity with no spaces', async () => {
52
- await identityService.createIdentity({});
59
+ await EffectEx.runPromise(identityService['IdentityService.createIdentity']({}));
53
60
  const dataSpaces = [...(serviceContext.dataSpaceManager?.spaces?.values() ?? [])];
54
61
  expect(dataSpaces.length).to.eq(0);
55
62
  });
@@ -59,36 +66,38 @@ describe('IdentityService', () => {
59
66
 
60
67
  describe('updateProfile', () => {
61
68
  test('updates profile', async () => {
62
- const identity = await identityService.createIdentity({});
69
+ const identity = await EffectEx.runPromise(identityService['IdentityService.createIdentity']({}));
63
70
  expect(identity.profile?.displayName).to.be.undefined;
64
71
 
65
- const updatedIdentity = await identityService.updateProfile({ displayName: 'Example' });
72
+ const updatedIdentity = await EffectEx.runPromise(
73
+ identityService['IdentityService.updateProfile']({ displayName: 'Example' }),
74
+ );
66
75
  expect(updatedIdentity.profile?.displayName).to.equal('Example');
67
76
  });
68
77
  });
69
78
 
70
79
  describe('queryIdentity', () => {
71
80
  test('returns undefined if no identity is available', async () => {
72
- const query = identityService.queryIdentity();
81
+ const stream = identityService['IdentityService.queryIdentity']();
73
82
  const result = new Trigger<Identity | undefined>();
74
- query.subscribe(({ identity }) => {
75
- result.wake(identity);
83
+ const cleanup = subscribeStream(Runtime.defaultRuntime, stream, {
84
+ onData: ({ identity }) => result.wake(identity),
76
85
  });
77
- onTestFinished(() => query.close());
86
+ onTestFinished(cleanup);
78
87
  expect(await result.wait()).to.be.undefined;
79
88
  });
80
89
 
81
90
  test('updates when identity is created', async () => {
82
- const query = identityService.queryIdentity();
91
+ const stream = identityService['IdentityService.queryIdentity']();
83
92
  let result = new Trigger<Identity | undefined>();
84
- query.subscribe(({ identity }) => {
85
- result.wake(identity);
93
+ const cleanup = subscribeStream(Runtime.defaultRuntime, stream, {
94
+ onData: ({ identity }) => result.wake(identity),
86
95
  });
87
- onTestFinished(() => query.close());
96
+ onTestFinished(cleanup);
88
97
  expect(await result.wait()).to.be.undefined;
89
98
 
90
99
  result = new Trigger<Identity | undefined>();
91
- const identity = await identityService.createIdentity({});
100
+ const identity = await EffectEx.runPromise(identityService['IdentityService.createIdentity']({}));
92
101
  expect(await result.wait()).to.deep.equal(identity);
93
102
  });
94
103
  });
@@ -2,8 +2,9 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { type RequestOptions } from '@dxos/codec-protobuf';
6
- import { Stream } from '@dxos/codec-protobuf/stream';
5
+ import * as Effect from 'effect/Effect';
6
+ import * as EffectStream from 'effect/Stream';
7
+
7
8
  import { Context, Resource } from '@dxos/context';
8
9
  import { createCredential, signPresentation } from '@dxos/credentials';
9
10
  import { invariant } from '@dxos/invariant';
@@ -11,20 +12,22 @@ import { type KeyringApi } from '@dxos/keyring';
11
12
  import {
12
13
  type CreateIdentityRequest,
13
14
  type CreateRecoveryCredentialRequest,
15
+ type CreateRecoveryCredentialResponse,
14
16
  type Identity as IdentityProto,
15
- type IdentityService,
16
17
  type QueryIdentityResponse,
17
18
  type RecoverIdentityRequest,
19
+ type RequestRecoveryChallengeResponse,
18
20
  type SignPresentationRequest,
19
21
  } from '@dxos/protocols/proto/dxos/client/services';
20
- import { type Presentation, type ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
22
+ import { type Credential, type Presentation, type ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
23
+ import { type IdentityService } from '@dxos/protocols/rpc';
21
24
 
22
25
  import { type Identity } from './identity';
23
26
  import { type CreateIdentityOptions, type IdentityManager } from './identity-manager';
24
27
  import { type EdgeIdentityRecoveryManager } from './identity-recovery-manager';
25
28
 
26
- export class IdentityServiceImpl extends Resource implements IdentityService {
27
- constructor(
29
+ export class IdentityServiceImpl extends Resource implements IdentityService.Handlers {
30
+ 'constructor'(
28
31
  private readonly _identityManager: IdentityManager,
29
32
  private readonly _recoveryManager: EdgeIdentityRecoveryManager,
30
33
  private readonly _keyring: KeyringApi,
@@ -34,91 +37,131 @@ export class IdentityServiceImpl extends Resource implements IdentityService {
34
37
  super();
35
38
  }
36
39
 
37
- async createIdentity(request: CreateIdentityRequest, options?: RequestOptions): Promise<IdentityProto> {
38
- const ctx = options?.ctx ?? Context.default();
39
- await this._createIdentity({ profile: request.profile, deviceProfile: request.deviceProfile }, ctx);
40
- return this._getIdentity()!;
40
+ ['IdentityService.createIdentity'](request: CreateIdentityRequest): Effect.Effect<IdentityProto, Error> {
41
+ return Effect.tryPromise({
42
+ try: async () => {
43
+ const ctx = Context.default();
44
+ await this._createIdentity({ profile: request.profile, deviceProfile: request.deviceProfile }, ctx);
45
+ return this._getIdentity()!;
46
+ },
47
+ catch: (error) => error as Error,
48
+ });
41
49
  }
42
50
 
43
- queryIdentity(): Stream<QueryIdentityResponse> {
44
- return new Stream(({ next }) => {
45
- const emitNext = () => next({ identity: this._getIdentity() });
51
+ ['IdentityService.queryIdentity'](): EffectStream.Stream<QueryIdentityResponse, Error> {
52
+ return EffectStream.async<QueryIdentityResponse, Error>((emit) => {
53
+ // Omit `identity` entirely when absent: an explicit `undefined` would still drive the optional
54
+ // protobuf codec, which dereferences the missing message and throws.
55
+ const emitNext = () => {
56
+ const identity = this._getIdentity();
57
+ void emit.single(identity ? { identity } : {});
58
+ };
46
59
 
47
60
  emitNext();
48
- return this._identityManager.stateUpdate.on(emitNext);
61
+ const unsubscribe = this._identityManager.stateUpdate.on(emitNext);
62
+ return Effect.sync(() => unsubscribe());
49
63
  });
50
64
  }
51
65
 
52
- private _getIdentity(): IdentityProto | undefined {
53
- if (!this._identityManager.identity) {
54
- return undefined;
55
- }
56
-
57
- return {
58
- did: this._identityManager.identity.did,
59
- identityKey: this._identityManager.identity.identityKey,
60
- spaceKey: this._identityManager.identity.space.key,
61
- profile: this._identityManager.identity.profileDocument,
62
- };
63
- }
64
-
65
- async updateProfile(profile: ProfileDocument): Promise<IdentityProto> {
66
- invariant(this._identityManager.identity, 'Identity not initialized.');
67
- await this._identityManager.updateProfile(profile);
68
- await this._onProfileUpdate?.(this._identityManager.identity.profileDocument);
69
- return this._getIdentity()!;
66
+ ['IdentityService.updateProfile'](profile: ProfileDocument): Effect.Effect<IdentityProto, Error> {
67
+ return Effect.tryPromise({
68
+ try: async () => {
69
+ invariant(this._identityManager.identity, 'Identity not initialized.');
70
+ await this._identityManager.updateProfile(profile);
71
+ await this._onProfileUpdate?.(this._identityManager.identity.profileDocument);
72
+ return this._getIdentity()!;
73
+ },
74
+ catch: (error) => error as Error,
75
+ });
70
76
  }
71
77
 
72
- async createRecoveryCredential(request: CreateRecoveryCredentialRequest) {
73
- return this._recoveryManager.createRecoveryCredential(request);
78
+ ['IdentityService.createRecoveryCredential'](
79
+ request: CreateRecoveryCredentialRequest,
80
+ ): Effect.Effect<CreateRecoveryCredentialResponse, Error> {
81
+ return Effect.tryPromise({
82
+ try: async () => this._recoveryManager.createRecoveryCredential(request),
83
+ catch: (error) => error as Error,
84
+ });
74
85
  }
75
86
 
76
- async requestRecoveryChallenge(_request: void, options?: RequestOptions) {
77
- return this._recoveryManager.requestRecoveryChallenge(options?.ctx ?? Context.default());
87
+ ['IdentityService.requestRecoveryChallenge'](): Effect.Effect<RequestRecoveryChallengeResponse, Error> {
88
+ return Effect.tryPromise({
89
+ try: async () => this._recoveryManager.requestRecoveryChallenge(Context.default()),
90
+ catch: (error) => error as Error,
91
+ });
78
92
  }
79
93
 
80
- async recoverIdentity(request: RecoverIdentityRequest, options?: RequestOptions): Promise<IdentityProto> {
81
- const ctx = options?.ctx ?? Context.default();
82
- if (request.recoveryCode) {
83
- await this._recoveryManager.recoverIdentity(ctx, { recoveryCode: request.recoveryCode });
84
- } else if (request.external) {
85
- await this._recoveryManager.recoverIdentityWithExternalSignature(ctx, request.external);
86
- } else if (request.token) {
87
- await this._recoveryManager.recoverIdentityWithToken(ctx, { token: request.token });
88
- } else if (request.recoveryProof) {
89
- await this._recoveryManager.recoverIdentityWithToken(ctx, { recoveryProof: request.recoveryProof });
90
- } else {
91
- throw new Error('Invalid request.');
92
- }
93
-
94
- return this._getIdentity()!;
94
+ ['IdentityService.recoverIdentity'](request: RecoverIdentityRequest): Effect.Effect<IdentityProto, Error> {
95
+ return Effect.tryPromise({
96
+ try: async () => {
97
+ const ctx = Context.default();
98
+ if (request.recoveryCode) {
99
+ await this._recoveryManager.recoverIdentity(ctx, { recoveryCode: request.recoveryCode });
100
+ } else if (request.external) {
101
+ await this._recoveryManager.recoverIdentityWithExternalSignature(ctx, request.external);
102
+ } else if (request.token) {
103
+ await this._recoveryManager.recoverIdentityWithToken(ctx, { token: request.token });
104
+ } else if (request.recoveryProof) {
105
+ await this._recoveryManager.recoverIdentityWithToken(ctx, { recoveryProof: request.recoveryProof });
106
+ } else {
107
+ throw new Error('Invalid request.');
108
+ }
109
+
110
+ return this._getIdentity()!;
111
+ },
112
+ catch: (error) => error as Error,
113
+ });
95
114
  }
96
115
 
97
116
  // TODO(burdon): Rename createPresentation?
98
- async signPresentation({ presentation, nonce }: SignPresentationRequest): Promise<Presentation> {
99
- invariant(this._identityManager.identity, 'Identity not initialized.');
100
-
101
- return await signPresentation({
102
- presentation,
103
- signer: this._keyring,
104
- signerKey: this._identityManager.identity.deviceKey,
105
- chain: this._identityManager.identity.deviceCredentialChain,
106
- nonce,
117
+ ['IdentityService.signPresentation'](request: SignPresentationRequest): Effect.Effect<Presentation, Error> {
118
+ return Effect.tryPromise({
119
+ try: async () => {
120
+ const { presentation, nonce } = request;
121
+ invariant(this._identityManager.identity, 'Identity not initialized.');
122
+
123
+ return await signPresentation({
124
+ presentation,
125
+ signer: this._keyring,
126
+ signerKey: this._identityManager.identity.deviceKey,
127
+ chain: this._identityManager.identity.deviceCredentialChain,
128
+ nonce,
129
+ });
130
+ },
131
+ catch: (error) => error as Error,
107
132
  });
108
133
  }
109
134
 
110
- async createAuthCredential() {
111
- const identity = this._identityManager.identity;
135
+ ['IdentityService.createAuthCredential'](): Effect.Effect<Credential, Error> {
136
+ return Effect.tryPromise({
137
+ try: async () => {
138
+ const identity = this._identityManager.identity;
139
+
140
+ invariant(identity, 'Identity not initialized.');
141
+
142
+ return await createCredential({
143
+ assertion: { '@type': 'dxos.halo.credentials.Auth' },
144
+ issuer: identity.identityKey,
145
+ subject: identity.identityKey,
146
+ chain: identity.deviceCredentialChain,
147
+ signingKey: identity.deviceKey,
148
+ signer: this._keyring,
149
+ });
150
+ },
151
+ catch: (error) => error as Error,
152
+ });
153
+ }
112
154
 
113
- invariant(identity, 'Identity not initialized.');
155
+ private '_getIdentity'(): IdentityProto | undefined {
156
+ if (!this._identityManager.identity) {
157
+ return undefined;
158
+ }
114
159
 
115
- return await createCredential({
116
- assertion: { '@type': 'dxos.halo.credentials.Auth' },
117
- issuer: identity.identityKey,
118
- subject: identity.identityKey,
119
- chain: identity.deviceCredentialChain,
120
- signingKey: identity.deviceKey,
121
- signer: this._keyring,
122
- });
160
+ return {
161
+ did: this._identityManager.identity.did,
162
+ identityKey: this._identityManager.identity.identityKey,
163
+ spaceKey: this._identityManager.identity.space.key,
164
+ profile: this._identityManager.identity.profileDocument,
165
+ };
123
166
  }
124
167
  }
@@ -7,15 +7,7 @@ import { describe, expect, onTestFinished, test } from 'vitest';
7
7
  import { Event } from '@dxos/async';
8
8
  import { Context } from '@dxos/context';
9
9
  import { CredentialGenerator, createDidFromIdentityKey, verifyCredential } from '@dxos/credentials';
10
- import {
11
- MetadataStore,
12
- MOCK_AUTH_PROVIDER,
13
- MOCK_AUTH_VERIFIER,
14
- Space,
15
- SpaceProtocol,
16
- createIdFromSpaceKey,
17
- valueEncoding,
18
- } from '@dxos/echo-host';
10
+ import { createIdFromSpaceKey } from '@dxos/echo-protocol';
19
11
  import { type EdgeConnection, type MessageListener } from '@dxos/edge-client';
20
12
  import { FeedFactory, FeedStore } from '@dxos/feed-store';
21
13
  import { type FeedWrapper } from '@dxos/feed-store';
@@ -29,6 +21,9 @@ import { AdmittedFeed } from '@dxos/protocols/proto/dxos/halo/credentials';
29
21
  import { StorageType, createStorage } from '@dxos/random-access-storage';
30
22
  import { BlobStore } from '@dxos/teleport-extension-object-sync';
31
23
 
24
+ import { MetadataStore } from '../metadata';
25
+ import { valueEncoding } from '../pipeline';
26
+ import { MOCK_AUTH_PROVIDER, MOCK_AUTH_VERIFIER, Space, SpaceProtocol } from '../space';
32
27
  import { Identity } from './identity';
33
28
 
34
29
  const createStores = () => {
@@ -13,7 +13,6 @@ import {
13
13
  createCredentialSignerWithKey,
14
14
  } from '@dxos/credentials';
15
15
  import { type Signer } from '@dxos/crypto';
16
- import { type Space } from '@dxos/echo-host';
17
16
  import { type EdgeConnection } from '@dxos/edge-client';
18
17
  import { type FeedWrapper, writeMessages } from '@dxos/feed-store';
19
18
  import { invariant } from '@dxos/invariant';
@@ -32,6 +31,7 @@ import { type Presence } from '@dxos/teleport-extension-gossip';
32
31
  import { trace } from '@dxos/tracing';
33
32
  import { type ComplexMap, ComplexSet } from '@dxos/util';
34
33
 
34
+ import { type Space } from '../space';
35
35
  import { EdgeFeedReplicator } from '../spaces';
36
36
  import { TrustedKeySetAuthVerifier } from './authenticator';
37
37
 
@@ -50,7 +50,6 @@ export type IdentityProps = {
50
50
  /**
51
51
  * Agent identity manager, which includes the agent's Halo space.
52
52
  */
53
- @trace.resource()
54
53
  export class Identity {
55
54
  public readonly space: Space;
56
55
  private readonly _signer: Signer;
@@ -42,7 +42,6 @@ export type EdgeInvitationConfig = {
42
42
  retryJitter?: number;
43
43
  };
44
44
 
45
- @trace.resource()
46
45
  export class EdgeInvitationHandler implements FlowLockHolder {
47
46
  private _flowLock: MutexGuard | undefined;
48
47