@dxos/client-services 0.8.3 → 0.8.4-main.1c7ec43d41

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 (261) hide show
  1. package/dist/lib/browser/{chunk-LBG3C332.mjs → chunk-J7D62ZDJ.mjs} +3826 -5125
  2. package/dist/lib/browser/chunk-J7D62ZDJ.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-QCWEHHJW.mjs +24 -0
  4. package/dist/lib/browser/chunk-QCWEHHJW.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-XJRPB3GA.mjs +22 -0
  6. package/dist/lib/browser/chunk-XJRPB3GA.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +454 -148
  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 +88 -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 +86 -0
  15. package/dist/lib/browser/packlets/locks/browser.mjs.map +7 -0
  16. package/dist/lib/browser/packlets/locks/node.mjs +48 -0
  17. package/dist/lib/browser/packlets/locks/node.mjs.map +7 -0
  18. package/dist/lib/browser/testing/index.mjs +40 -41
  19. package/dist/lib/browser/testing/index.mjs.map +3 -3
  20. package/dist/lib/node-esm/chunk-2DT3MZRL.mjs +22 -0
  21. package/dist/lib/node-esm/chunk-2DT3MZRL.mjs.map +7 -0
  22. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +24 -0
  23. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +7 -0
  24. package/dist/lib/node-esm/{chunk-SKGQLRKS.mjs → chunk-TLUZSZZD.mjs} +3226 -4393
  25. package/dist/lib/node-esm/chunk-TLUZSZZD.mjs.map +7 -0
  26. package/dist/lib/node-esm/index.mjs +454 -148
  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 +88 -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 +86 -0
  34. package/dist/lib/node-esm/packlets/locks/browser.mjs.map +7 -0
  35. package/dist/lib/node-esm/packlets/locks/node.mjs +48 -0
  36. package/dist/lib/node-esm/packlets/locks/node.mjs.map +7 -0
  37. package/dist/lib/node-esm/testing/index.mjs +40 -41
  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/keys.d.ts.map +1 -1
  51. package/dist/types/src/packlets/devtools/metadata.d.ts.map +1 -1
  52. package/dist/types/src/packlets/devtools/network.d.ts +1 -1
  53. package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
  54. package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
  55. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts +1 -1
  56. package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
  57. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts +1 -1
  58. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
  59. package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
  60. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +3 -4
  61. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  62. package/dist/types/src/packlets/diagnostics/index.d.ts +1 -1
  63. package/dist/types/src/packlets/diagnostics/index.d.ts.map +1 -1
  64. package/dist/types/src/packlets/identity/authenticator.d.ts +2 -2
  65. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  66. package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
  67. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  68. package/dist/types/src/packlets/identity/identity-manager.d.ts +7 -7
  69. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  70. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +8 -7
  71. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  72. package/dist/types/src/packlets/identity/identity-service.d.ts +6 -10
  73. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  74. package/dist/types/src/packlets/identity/identity.d.ts +9 -12
  75. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  76. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +6 -5
  77. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  78. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +2 -2
  79. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
  80. package/dist/types/src/packlets/invitations/index.d.ts +1 -1
  81. package/dist/types/src/packlets/invitations/index.d.ts.map +1 -1
  82. package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
  83. package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
  84. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +8 -5
  85. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
  86. package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +1 -1
  87. package/dist/types/src/packlets/invitations/invitation-topology.d.ts.map +1 -1
  88. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +4 -4
  89. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  90. package/dist/types/src/packlets/invitations/invitations-manager.d.ts +3 -3
  91. package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
  92. package/dist/types/src/packlets/invitations/invitations-service.d.ts +4 -4
  93. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  94. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +5 -4
  95. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  96. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  97. package/dist/types/src/packlets/locks/browser.d.ts.map +1 -1
  98. package/dist/types/src/packlets/locks/index.d.ts +2 -2
  99. package/dist/types/src/packlets/locks/index.d.ts.map +1 -1
  100. package/dist/types/src/packlets/locks/node.d.ts.map +1 -1
  101. package/dist/types/src/packlets/logging/logging-service.d.ts +5 -1
  102. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  103. package/dist/types/src/packlets/network/network-service.d.ts +7 -6
  104. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  105. package/dist/types/src/packlets/services/client-rpc-server.d.ts +5 -5
  106. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
  107. package/dist/types/src/packlets/services/feed-syncer.d.ts +59 -0
  108. package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
  109. package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
  110. package/dist/types/src/packlets/services/feed-syncer.test.d.ts.map +1 -0
  111. package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
  112. package/dist/types/src/packlets/services/service-context.d.ts +14 -10
  113. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  114. package/dist/types/src/packlets/services/service-host.d.ts +21 -8
  115. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  116. package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
  117. package/dist/types/src/packlets/services/util.d.ts.map +1 -1
  118. package/dist/types/src/packlets/space-export/archive-format.d.ts +9 -0
  119. package/dist/types/src/packlets/space-export/archive-format.d.ts.map +1 -0
  120. package/dist/types/src/packlets/space-export/index.d.ts +4 -1
  121. package/dist/types/src/packlets/space-export/index.d.ts.map +1 -1
  122. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts +23 -0
  123. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts.map +1 -0
  124. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts +36 -0
  125. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts.map +1 -0
  126. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +9 -1
  127. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
  128. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +8 -2
  129. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
  130. package/dist/types/src/packlets/space-export/space-archive.test.d.ts +2 -0
  131. package/dist/types/src/packlets/space-export/space-archive.test.d.ts.map +1 -0
  132. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts +1 -1
  133. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
  134. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +29 -18
  135. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  136. package/dist/types/src/packlets/spaces/data-space.d.ts +30 -13
  137. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  138. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +2 -2
  139. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  140. package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
  141. package/dist/types/src/packlets/spaces/genesis.d.ts +2 -1
  142. package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
  143. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -9
  144. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  145. package/dist/types/src/packlets/spaces/spaces-service.d.ts +11 -8
  146. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  147. package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
  148. package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
  149. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  150. package/dist/types/src/packlets/storage/util.d.ts.map +1 -1
  151. package/dist/types/src/packlets/system/system-service.d.ts +2 -2
  152. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  153. package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -1
  154. package/dist/types/src/packlets/testing/invitation-utils.d.ts +6 -3
  155. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  156. package/dist/types/src/packlets/testing/test-builder.d.ts +8 -7
  157. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  158. package/dist/types/src/packlets/worker/worker-runtime.d.ts +41 -4
  159. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  160. package/dist/types/src/packlets/worker/worker-session.d.ts +2 -4
  161. package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
  162. package/dist/types/src/testing/setup.d.ts.map +1 -1
  163. package/dist/types/src/version.d.ts +1 -1
  164. package/dist/types/src/version.d.ts.map +1 -1
  165. package/dist/types/tsconfig.tsbuildinfo +1 -1
  166. package/package.json +72 -55
  167. package/src/index.ts +1 -0
  168. package/src/packlets/agents/edge-agent-manager.ts +10 -7
  169. package/src/packlets/agents/edge-agent-service.ts +17 -5
  170. package/src/packlets/devices/devices-service.test.ts +3 -3
  171. package/src/packlets/devices/devices-service.ts +2 -2
  172. package/src/packlets/devtools/devtools.ts +29 -29
  173. package/src/packlets/devtools/feeds.ts +2 -2
  174. package/src/packlets/devtools/network.ts +1 -1
  175. package/src/packlets/diagnostics/browser-diagnostics-broadcast.ts +1 -1
  176. package/src/packlets/diagnostics/diagnostics-broadcast.ts +1 -1
  177. package/src/packlets/diagnostics/diagnostics-collector.ts +1 -1
  178. package/src/packlets/diagnostics/diagnostics.ts +2 -3
  179. package/src/packlets/diagnostics/index.ts +1 -1
  180. package/src/packlets/identity/authenticator.node.test.ts +1 -1
  181. package/src/packlets/identity/authenticator.ts +3 -3
  182. package/src/packlets/identity/contacts-service.ts +2 -2
  183. package/src/packlets/identity/identity-manager.test.ts +8 -8
  184. package/src/packlets/identity/identity-manager.ts +25 -24
  185. package/src/packlets/identity/identity-recovery-manager.ts +22 -18
  186. package/src/packlets/identity/identity-service.test.ts +8 -28
  187. package/src/packlets/identity/identity-service.ts +13 -80
  188. package/src/packlets/identity/identity.test.ts +11 -11
  189. package/src/packlets/identity/identity.ts +17 -39
  190. package/src/packlets/invitations/device-invitation-protocol.test.ts +4 -4
  191. package/src/packlets/invitations/device-invitation-protocol.ts +8 -6
  192. package/src/packlets/invitations/edge-invitation-handler.ts +10 -6
  193. package/src/packlets/invitations/index.ts +1 -1
  194. package/src/packlets/invitations/invitation-guest-extenstion.ts +7 -5
  195. package/src/packlets/invitations/invitation-host-extension.ts +15 -16
  196. package/src/packlets/invitations/invitation-protocol.ts +8 -5
  197. package/src/packlets/invitations/invitation-state.ts +1 -15
  198. package/src/packlets/invitations/invitations-handler.test.ts +301 -292
  199. package/src/packlets/invitations/invitations-handler.ts +77 -25
  200. package/src/packlets/invitations/invitations-manager.ts +43 -18
  201. package/src/packlets/invitations/invitations-service.ts +10 -10
  202. package/src/packlets/invitations/space-invitation-protocol.test.ts +26 -25
  203. package/src/packlets/invitations/space-invitation-protocol.ts +13 -17
  204. package/src/packlets/invitations/utils.ts +1 -1
  205. package/src/packlets/locks/browser.ts +1 -1
  206. package/src/packlets/locks/index.ts +2 -2
  207. package/src/packlets/logging/logging-service.ts +22 -17
  208. package/src/packlets/logging/logging.test.ts +1 -1
  209. package/src/packlets/network/network-service.test.ts +3 -3
  210. package/src/packlets/network/network-service.ts +12 -10
  211. package/src/packlets/services/client-rpc-server.ts +20 -17
  212. package/src/packlets/services/feed-syncer.test.ts +340 -0
  213. package/src/packlets/services/feed-syncer.ts +377 -0
  214. package/src/packlets/services/platform.ts +7 -1
  215. package/src/packlets/services/service-context.test.ts +4 -3
  216. package/src/packlets/services/service-context.ts +148 -64
  217. package/src/packlets/services/service-host.test.ts +10 -9
  218. package/src/packlets/services/service-host.ts +88 -49
  219. package/src/packlets/services/service-registry.test.ts +1 -1
  220. package/src/packlets/space-export/archive-format.ts +42 -0
  221. package/src/packlets/space-export/index.ts +4 -1
  222. package/src/packlets/space-export/serialized-space-reader.ts +111 -0
  223. package/src/packlets/space-export/serialized-space-writer.ts +252 -0
  224. package/src/packlets/space-export/space-archive-reader.ts +65 -4
  225. package/src/packlets/space-export/space-archive-writer.ts +44 -6
  226. package/src/packlets/space-export/space-archive.test.ts +461 -0
  227. package/src/packlets/space-export/tar.test.ts +1 -1
  228. package/src/packlets/spaces/automerge-space-state.ts +1 -1
  229. package/src/packlets/spaces/data-space-manager.test.ts +79 -13
  230. package/src/packlets/spaces/data-space-manager.ts +129 -125
  231. package/src/packlets/spaces/data-space.ts +65 -40
  232. package/src/packlets/spaces/edge-feed-replicator.test.ts +4 -4
  233. package/src/packlets/spaces/edge-feed-replicator.ts +13 -11
  234. package/src/packlets/spaces/epoch-migrations.ts +5 -5
  235. package/src/packlets/spaces/genesis.ts +6 -1
  236. package/src/packlets/spaces/notarization-plugin.test.ts +3 -3
  237. package/src/packlets/spaces/notarization-plugin.ts +13 -12
  238. package/src/packlets/spaces/spaces-service.test.ts +20 -12
  239. package/src/packlets/spaces/spaces-service.ts +138 -38
  240. package/src/packlets/storage/profile-archive.ts +1 -1
  241. package/src/packlets/storage/storage.ts +7 -8
  242. package/src/packlets/system/system-service.test.ts +1 -1
  243. package/src/packlets/system/system-service.ts +4 -4
  244. package/src/packlets/testing/invitation-utils.ts +11 -7
  245. package/src/packlets/testing/test-builder.ts +39 -13
  246. package/src/packlets/worker/worker-runtime.ts +189 -17
  247. package/src/packlets/worker/worker-session.ts +15 -21
  248. package/src/version.ts +1 -5
  249. package/README.yml +0 -5
  250. package/dist/lib/browser/chunk-LBG3C332.mjs.map +0 -7
  251. package/dist/lib/node/chunk-LMGLGOUU.cjs +0 -9311
  252. package/dist/lib/node/chunk-LMGLGOUU.cjs.map +0 -7
  253. package/dist/lib/node/index.cjs +0 -437
  254. package/dist/lib/node/index.cjs.map +0 -7
  255. package/dist/lib/node/meta.json +0 -1
  256. package/dist/lib/node/testing/index.cjs +0 -452
  257. package/dist/lib/node/testing/index.cjs.map +0 -7
  258. package/dist/lib/node-esm/chunk-SKGQLRKS.mjs.map +0 -7
  259. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +0 -19
  260. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +0 -1
  261. package/src/packlets/identity/default-space-state-machine.ts +0 -44
@@ -2,16 +2,17 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { afterEach, onTestFinished, beforeEach, describe, expect, test } from 'vitest';
5
+ import { afterEach, beforeEach, describe, expect, onTestFinished, test } from 'vitest';
6
6
 
7
7
  import { Trigger } from '@dxos/async';
8
8
  import { Context } from '@dxos/context';
9
9
  import { PublicKey } from '@dxos/keys';
10
10
  import { type Space, type SpacesService } from '@dxos/protocols/proto/dxos/client/services';
11
+ import { MembershipPolicy } from '@dxos/protocols/proto/dxos/halo/credentials';
11
12
 
12
- import { SpacesServiceImpl } from './spaces-service';
13
13
  import { type ServiceContext } from '../services';
14
14
  import { createServiceContext } from '../testing';
15
+ import { SpacesServiceImpl } from './spaces-service';
15
16
 
16
17
  describe('SpacesService', () => {
17
18
  let serviceContext: ServiceContext;
@@ -20,10 +21,15 @@ describe('SpacesService', () => {
20
21
  beforeEach(async () => {
21
22
  serviceContext = await createServiceContext();
22
23
  await serviceContext.open(new Context());
23
- spacesService = new SpacesServiceImpl(serviceContext.identityManager, serviceContext.spaceManager, async () => {
24
- await serviceContext.initialized.wait();
25
- return serviceContext.dataSpaceManager!;
26
- });
24
+ spacesService = new SpacesServiceImpl(
25
+ serviceContext.identityManager,
26
+ serviceContext.spaceManager,
27
+ serviceContext.echoHost,
28
+ async () => {
29
+ await serviceContext.initialized.wait();
30
+ return serviceContext.dataSpaceManager!;
31
+ },
32
+ );
27
33
  });
28
34
 
29
35
  afterEach(async () => {
@@ -32,12 +38,14 @@ describe('SpacesService', () => {
32
38
 
33
39
  describe('createSpace', () => {
34
40
  test('fails if no identity is available', async () => {
35
- await expect(spacesService.createSpace()).rejects.toBeInstanceOf(Error);
41
+ await expect(spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE })).rejects.toBeInstanceOf(
42
+ Error,
43
+ );
36
44
  });
37
45
 
38
46
  test('creates a new space', async () => {
39
47
  await serviceContext.createIdentity();
40
- const space = await spacesService.createSpace();
48
+ const space = await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE });
41
49
  expect(space).to.exist;
42
50
  expect(space.spaceKey).to.be.instanceof(PublicKey);
43
51
  });
@@ -59,9 +67,9 @@ describe('SpacesService', () => {
59
67
  test('returns list of existing spaces', async () => {
60
68
  await serviceContext.createIdentity();
61
69
  const existingSpaces = [
62
- await spacesService.createSpace(),
63
- await spacesService.createSpace(),
64
- await spacesService.createSpace(),
70
+ await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE }),
71
+ await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE }),
72
+ await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE }),
65
73
  ];
66
74
 
67
75
  const query = spacesService.querySpaces();
@@ -87,7 +95,7 @@ describe('SpacesService', () => {
87
95
  expect(await result.wait()).to.be.length(0);
88
96
 
89
97
  result.reset();
90
- const space = await spacesService.createSpace();
98
+ const space = await spacesService.createSpace({ membershipPolicy: MembershipPolicy.INVITE });
91
99
  const spaces = await result.wait();
92
100
  expect(spaces).to.be.length(1);
93
101
  expect(spaces?.[0].spaceKey.equals(space.spaceKey)).to.be.true;
@@ -5,7 +5,9 @@
5
5
  import type { AutomergeUrl } from '@automerge/automerge-repo';
6
6
 
7
7
  import { SubscriptionList, UpdateScheduler, scheduleTask } from '@dxos/async';
8
+ import { type RequestOptions } from '@dxos/codec-protobuf';
8
9
  import { Stream } from '@dxos/codec-protobuf/stream';
10
+ import { Context } from '@dxos/context';
9
11
  import {
10
12
  type CredentialProcessor,
11
13
  createAdmissionCredentials,
@@ -13,86 +15,103 @@ import {
13
15
  getCredentialAssertion,
14
16
  } from '@dxos/credentials';
15
17
  import { raise } from '@dxos/debug';
16
- import { type SpaceManager } from '@dxos/echo-pipeline';
18
+ import { type EchoHost, type SpaceManager } from '@dxos/echo-pipeline';
19
+ import { type DatabaseDirectory } from '@dxos/echo-protocol';
17
20
  import { writeMessages } from '@dxos/feed-store';
18
21
  import { assertArgument, assertState, invariant } from '@dxos/invariant';
19
22
  import { SpaceId } from '@dxos/keys';
20
23
  import { log } from '@dxos/log';
21
24
  import {
22
- encodeError,
23
25
  ApiError,
24
26
  AuthorizationError,
27
+ FeedProtocol,
25
28
  IdentityNotInitializedError,
26
29
  SpaceNotFoundError,
30
+ encodeError,
27
31
  } from '@dxos/protocols';
28
32
  import {
29
- SpaceMember,
30
- SpaceState,
33
+ type AdmitContactRequest,
34
+ type ContactAdmission,
31
35
  type CreateEpochRequest,
36
+ type CreateEpochResponse,
37
+ type ExportSpaceRequest,
38
+ type ExportSpaceResponse,
39
+ type ImportSpaceRequest,
40
+ type ImportSpaceResponse,
41
+ type JoinBySpaceKeyRequest,
42
+ type JoinSpaceResponse,
32
43
  type PostMessageRequest,
33
44
  type QueryCredentialsRequest,
34
45
  type QuerySpacesResponse,
35
46
  type Space,
47
+ SpaceArchive,
48
+ SpaceMember,
49
+ SpaceState,
36
50
  type SpacesService,
37
51
  type SubscribeMessagesRequest,
52
+ type UpdateMemberRoleRequest,
53
+ type CreateSpaceRequest,
38
54
  type UpdateSpaceRequest,
39
55
  type WriteCredentialsRequest,
40
- type UpdateMemberRoleRequest,
41
- type AdmitContactRequest,
42
- type ContactAdmission,
43
- type JoinSpaceResponse,
44
- type JoinBySpaceKeyRequest,
45
- type CreateEpochResponse,
46
- type ExportSpaceResponse,
47
- type ExportSpaceRequest,
48
- type ImportSpaceRequest,
49
- type ImportSpaceResponse,
50
56
  } from '@dxos/protocols/proto/dxos/client/services';
51
57
  import { type Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
52
58
  import { type GossipMessage } from '@dxos/protocols/proto/dxos/mesh/teleport/gossip';
53
59
  import { trace } from '@dxos/tracing';
54
60
  import { type Provider } from '@dxos/util';
55
61
 
62
+ import { type IdentityManager } from '../identity';
63
+ import {
64
+ SpaceArchiveWriter,
65
+ detectSpaceArchiveFormat,
66
+ extractSpaceArchive,
67
+ readSerializedSpaceArchive,
68
+ writeSerializedSpaceArchive,
69
+ objJsonToObjectStructure,
70
+ } from '../space-export';
56
71
  import { type DataSpace } from './data-space';
57
72
  import { type DataSpaceManager } from './data-space-manager';
58
- import { type IdentityManager } from '../identity';
59
- import { extractSpaceArchive, SpaceArchiveWriter } from '../space-export';
60
73
 
61
74
  export class SpacesServiceImpl implements SpacesService {
62
75
  constructor(
63
76
  private readonly _identityManager: IdentityManager,
64
77
  private readonly _spaceManager: SpaceManager,
78
+ private readonly _echoHost: EchoHost,
65
79
  private readonly _getDataSpaceManager: Provider<Promise<DataSpaceManager>>,
66
80
  ) {}
67
81
 
68
- async createSpace(): Promise<Space> {
82
+ async createSpace(request: CreateSpaceRequest, options?: RequestOptions): Promise<Space> {
69
83
  this._requireIdentity();
84
+ const ctx = options?.ctx ?? new Context();
70
85
  const dataSpaceManager = await this._getDataSpaceManager();
71
- const space = await dataSpaceManager.createSpace();
86
+ const space = await dataSpaceManager.createSpace(ctx, {
87
+ tags: request?.tags,
88
+ membershipPolicy: request?.membershipPolicy,
89
+ });
72
90
  await this._updateMetrics();
73
91
  return this._serializeSpace(space);
74
92
  }
75
93
 
76
- async updateSpace({ spaceKey, state, edgeReplication }: UpdateSpaceRequest): Promise<void> {
94
+ async updateSpace({ spaceKey, state, edgeReplication }: UpdateSpaceRequest, options?: RequestOptions): Promise<void> {
95
+ const ctx = options?.ctx ?? Context.default();
77
96
  const dataSpaceManager = await this._getDataSpaceManager();
78
97
  const space = dataSpaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));
79
98
 
80
99
  if (state) {
81
100
  switch (state) {
82
101
  case SpaceState.SPACE_ACTIVE:
83
- await space.activate();
102
+ await space.activate(ctx);
84
103
  break;
85
104
 
86
105
  case SpaceState.SPACE_INACTIVE:
87
- await space.deactivate();
106
+ await space.deactivate(ctx);
88
107
  break;
89
108
  default:
90
- throw new ApiError('Invalid space state');
109
+ throw new ApiError({ message: 'Invalid space state' });
91
110
  }
92
111
  }
93
112
 
94
113
  if (edgeReplication !== undefined) {
95
- await dataSpaceManager.setSpaceEdgeReplicationSetting(spaceKey, edgeReplication);
114
+ await dataSpaceManager.setSpaceEdgeReplicationSetting(ctx, spaceKey, edgeReplication);
96
115
  }
97
116
  }
98
117
 
@@ -103,9 +122,12 @@ export class SpacesServiceImpl implements SpacesService {
103
122
  throw new SpaceNotFoundError(request.spaceKey);
104
123
  }
105
124
  if (!space.spaceState.hasMembershipManagementPermission(identity.identityKey)) {
106
- throw new AuthorizationError('No member management permission.', {
107
- spaceKey: space.key,
108
- role: space.spaceState.getMemberRole(identity.identityKey),
125
+ throw new AuthorizationError({
126
+ message: 'No member management permission.',
127
+ context: {
128
+ spaceKey: space.key,
129
+ role: space.spaceState.getMemberRole(identity.identityKey),
130
+ },
109
131
  });
110
132
  }
111
133
  const credentials = await createAdmissionCredentials(
@@ -258,18 +280,26 @@ export class SpacesServiceImpl implements SpacesService {
258
280
  });
259
281
  }
260
282
 
261
- async joinBySpaceKey({ spaceKey }: JoinBySpaceKeyRequest): Promise<JoinSpaceResponse> {
283
+ async joinBySpaceKey({ spaceKey }: JoinBySpaceKeyRequest, options?: RequestOptions): Promise<JoinSpaceResponse> {
284
+ const ctx = options?.ctx ?? Context.default();
262
285
  const dataSpaceManager = await this._getDataSpaceManager();
263
- const credential = await dataSpaceManager.requestSpaceAdmissionCredential(spaceKey);
264
- return this._joinByAdmission({ credential });
286
+ const credential = await dataSpaceManager.requestSpaceAdmissionCredential(ctx, spaceKey);
287
+ return this._joinByAdmission(ctx, { credential });
265
288
  }
266
289
 
267
290
  async exportSpace(request: ExportSpaceRequest): Promise<ExportSpaceResponse> {
268
- await using writer = await new SpaceArchiveWriter().open();
269
- assertArgument(SpaceId.isValid(request.spaceId), 'Invalid space ID');
291
+ assertArgument(SpaceId.isValid(request.spaceId), 'spaceId', 'Invalid space ID');
270
292
 
271
293
  const dataSpaceManager = await this._getDataSpaceManager();
272
294
  const space = dataSpaceManager.getSpaceById(request.spaceId) ?? raise(new Error('Space not found'));
295
+
296
+ const format = request.format ?? SpaceArchive.Format.BINARY;
297
+ if (format === SpaceArchive.Format.JSON) {
298
+ const archive = await writeSerializedSpaceArchive({ space, echoHost: this._echoHost });
299
+ return { archive };
300
+ }
301
+
302
+ await using writer = await new SpaceArchiveWriter().open();
273
303
  await writer.begin({ spaceId: space.id });
274
304
  const rootUrl = space.automergeSpaceState.lastEpoch?.subject.assertion.automergeRoot;
275
305
  assertState(rootUrl, 'Space does not have a root URL');
@@ -279,15 +309,40 @@ export class SpacesServiceImpl implements SpacesService {
279
309
  await writer.writeDocument(documentId, data);
280
310
  }
281
311
 
312
+ const feeds = await space.getAllFeeds();
313
+ for (const feed of feeds) {
314
+ const archiveBlocks = feed.blocks.map((block) => ({
315
+ actorId: block.actorId,
316
+ sequence: block.sequence,
317
+ prevActorId: block.prevActorId,
318
+ prevSequence: block.prevSequence,
319
+ position: block.position,
320
+ timestamp: block.timestamp,
321
+ data: Buffer.from(block.data).toString('base64'),
322
+ }));
323
+ await writer.writeFeed(feed.feedId, feed.feedNamespace, archiveBlocks);
324
+ }
325
+
282
326
  const archive = await writer.finish();
283
327
  return { archive };
284
328
  }
285
329
 
286
- async importSpace(request: ImportSpaceRequest): Promise<ImportSpaceResponse> {
330
+ async importSpace(request: ImportSpaceRequest, options?: RequestOptions): Promise<ImportSpaceResponse> {
331
+ const ctx = options?.ctx ?? Context.default();
287
332
  const dataSpaceManager = await this._getDataSpaceManager();
333
+
334
+ const format = request.archive.format ?? detectSpaceArchiveFormat(request.archive);
335
+ if (format === SpaceArchive.Format.JSON) {
336
+ const serialized = readSerializedSpaceArchive(request.archive);
337
+ const space = await dataSpaceManager.createSpace(ctx);
338
+ await this._hydrateSpaceFromSerialized(space, serialized);
339
+ await this._updateMetrics();
340
+ return { newSpaceId: space.id };
341
+ }
342
+
288
343
  const extracted = await extractSpaceArchive(request.archive);
289
344
  invariant(extracted.metadata.echo?.currentRootUrl, 'Space archive does not contain a root URL');
290
- const space = await dataSpaceManager.createSpace({
345
+ const space = await dataSpaceManager.createSpace(ctx, {
291
346
  documents: extracted.documents,
292
347
  rootUrl: extracted.metadata.echo?.currentRootUrl as AutomergeUrl,
293
348
  });
@@ -295,7 +350,49 @@ export class SpacesServiceImpl implements SpacesService {
295
350
  return { newSpaceId: space.id };
296
351
  }
297
352
 
298
- private async _joinByAdmission({ credential }: ContactAdmission): Promise<JoinSpaceResponse> {
353
+ /**
354
+ * Populate a freshly-created space with the objects and feed messages described in a {@link SerializedSpace}.
355
+ *
356
+ * Objects are written directly into the space's automerge root document as inline
357
+ * {@link ObjectStructure} entries; feed messages are appended to the appropriate queue
358
+ * via {@link EchoHost.queuesService}.
359
+ */
360
+ private async _hydrateSpaceFromSerialized(
361
+ space: DataSpace,
362
+ serialized: ReturnType<typeof readSerializedSpaceArchive>,
363
+ ): Promise<void> {
364
+ const databaseRoot = space.databaseRoot;
365
+ assertState(databaseRoot, 'Space database root is not ready');
366
+
367
+ databaseRoot.handle.change((doc: DatabaseDirectory) => {
368
+ if (!doc.objects) {
369
+ doc.objects = {};
370
+ }
371
+ for (const obj of serialized.objects) {
372
+ doc.objects[obj.id] = objJsonToObjectStructure(obj);
373
+ }
374
+ });
375
+
376
+ for (const feed of serialized.feeds ?? []) {
377
+ if (feed.messages.length === 0) {
378
+ continue;
379
+ }
380
+ const namespace =
381
+ feed.namespace === 'trace' ? FeedProtocol.WellKnownNamespaces.trace : FeedProtocol.WellKnownNamespaces.data;
382
+ try {
383
+ await this._echoHost.queuesService.insertIntoQueue({
384
+ spaceId: space.id,
385
+ queueId: feed.feedObjectId,
386
+ subspaceTag: namespace,
387
+ objects: feed.messages.map((message) => JSON.stringify(message)),
388
+ });
389
+ } catch (err) {
390
+ log.warn('failed to import feed data', { feedObjectId: feed.feedObjectId, error: err });
391
+ }
392
+ }
393
+ }
394
+
395
+ private async _joinByAdmission(ctx: Context, { credential }: ContactAdmission): Promise<JoinSpaceResponse> {
299
396
  const assertion = getCredentialAssertion(credential);
300
397
  invariant(assertion['@type'] === 'dxos.halo.credentials.SpaceMember', 'Invalid credential');
301
398
  const myIdentity = this._identityManager.identity;
@@ -304,9 +401,10 @@ export class SpacesServiceImpl implements SpacesService {
304
401
  const dataSpaceManager = await this._getDataSpaceManager();
305
402
  let dataSpace = dataSpaceManager.spaces.get(assertion.spaceKey);
306
403
  if (!dataSpace) {
307
- dataSpace = await dataSpaceManager.acceptSpace({
404
+ dataSpace = await dataSpaceManager.acceptSpace(ctx, {
308
405
  spaceKey: assertion.spaceKey,
309
406
  genesisFeedKey: assertion.genesisFeedKey,
407
+ tags: assertion.tags,
310
408
  });
311
409
  await myIdentity.controlPipeline.writer.write({ credential: { credential } });
312
410
  }
@@ -359,6 +457,8 @@ export class SpacesServiceImpl implements SpacesService {
359
457
  }),
360
458
  ),
361
459
  creator: space.inner.spaceState.creator?.key,
460
+ tags: space.tags,
461
+ membershipPolicy: space.membershipPolicy,
362
462
  cache: space.cache,
363
463
  metrics: space.metrics,
364
464
  edgeReplication: space.getEdgeReplicationSetting(),
@@ -367,9 +467,9 @@ export class SpacesServiceImpl implements SpacesService {
367
467
 
368
468
  private _requireIdentity() {
369
469
  if (!this._identityManager.identity) {
370
- throw new IdentityNotInitializedError(
371
- 'This device has no HALO identity available. See https://docs.dxos.org/guide/platform/halo',
372
- );
470
+ throw new IdentityNotInitializedError({
471
+ message: 'This device has no HALO identity available. See https://docs.dxos.org/guide/platform/halo',
472
+ });
373
473
  }
374
474
  return this._identityManager.identity;
375
475
  }
@@ -7,7 +7,7 @@ import { cbor } from '@automerge/automerge-repo';
7
7
  import { invariant } from '@dxos/invariant';
8
8
  import type { LevelDB } from '@dxos/kv-store';
9
9
  import { log } from '@dxos/log';
10
- import { ProfileArchiveEntryType, type ProfileArchive } from '@dxos/protocols';
10
+ import { type ProfileArchive, ProfileArchiveEntryType } from '@dxos/protocols';
11
11
  import type { Storage } from '@dxos/random-access-storage';
12
12
  import { arrayToBuffer } from '@dxos/util';
13
13
 
@@ -1,30 +1,29 @@
1
- //
2
-
3
1
  //
4
2
  // Copyright 2023 DXOS.org
5
3
  //
6
4
 
7
5
  import { InvalidConfigError } from '@dxos/protocols';
8
6
  import { Runtime } from '@dxos/protocols/proto/dxos/config';
9
- import { createStorage, StorageType } from '@dxos/random-access-storage';
7
+ import { StorageType, createStorage } from '@dxos/random-access-storage';
10
8
 
11
- import StorageDriver = Runtime.Client.Storage.StorageDriver;
12
9
  import { getRootPath } from './util';
13
10
 
11
+ import StorageDriver = Runtime.Client.Storage.StorageDriver;
12
+
14
13
  // TODO(burdon): Factor out.
15
14
  export const createStorageObjects = (config: Runtime.Client.Storage) => {
16
15
  const { persistent = false, keyStore, dataStore } = config ?? {};
17
16
  if (persistent && dataStore === StorageDriver.RAM) {
18
- throw new InvalidConfigError('RAM storage cannot be used in persistent mode.');
17
+ throw new InvalidConfigError({ message: 'RAM storage cannot be used in persistent mode.' });
19
18
  }
20
19
  if (!persistent && dataStore !== undefined && dataStore !== StorageDriver.RAM) {
21
- throw new InvalidConfigError('Cannot use a persistent storage in not persistent mode.');
20
+ throw new InvalidConfigError({ message: 'Cannot use a persistent storage in not persistent mode.' });
22
21
  }
23
22
  if (persistent && keyStore === StorageDriver.RAM) {
24
- throw new InvalidConfigError('RAM key storage cannot be used in persistent mode.');
23
+ throw new InvalidConfigError({ message: 'RAM key storage cannot be used in persistent mode.' });
25
24
  }
26
25
  if (!persistent && keyStore !== StorageDriver.RAM && keyStore !== undefined) {
27
- throw new InvalidConfigError('Cannot use a persistent key storage in not persistent mode.');
26
+ throw new InvalidConfigError({ message: 'Cannot use a persistent key storage in not persistent mode.' });
28
27
  }
29
28
 
30
29
  return {
@@ -6,7 +6,7 @@ import { beforeEach, describe, expect, test } from 'vitest';
6
6
 
7
7
  import { Event, Trigger } from '@dxos/async';
8
8
  import { Config } from '@dxos/config';
9
- import { type SystemService, SystemStatus, type QueryStatusResponse } from '@dxos/protocols/proto/dxos/client/services';
9
+ import { type QueryStatusResponse, type SystemService, SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
10
10
 
11
11
  import { SystemServiceImpl } from './system-service';
12
12
 
@@ -7,14 +7,14 @@ import { Stream } from '@dxos/codec-protobuf/stream';
7
7
  import { type Config } from '@dxos/config';
8
8
  import {
9
9
  GetDiagnosticsRequest,
10
+ type Platform,
11
+ type QueryStatusRequest,
12
+ type QueryStatusResponse,
10
13
  type SystemService,
11
14
  type SystemStatus,
12
15
  type UpdateStatusRequest,
13
- type QueryStatusRequest,
14
- type QueryStatusResponse,
15
- type Platform,
16
16
  } from '@dxos/protocols/proto/dxos/client/services';
17
- import { jsonKeyReplacer, type MaybePromise } from '@dxos/util';
17
+ import { type MaybePromise, jsonKeyReplacer } from '@dxos/util';
18
18
 
19
19
  import { type Diagnostics } from '../diagnostics';
20
20
  import { getPlatform } from '../services/platform';
@@ -3,7 +3,8 @@
3
3
  //
4
4
 
5
5
  import { Trigger } from '@dxos/async';
6
- import { InvitationEncoder, type AuthenticatingInvitation, type CancellableInvitation } from '@dxos/client-protocol';
6
+ import { type AuthenticatingInvitation, type CancellableInvitation, InvitationEncoder } from '@dxos/client-protocol';
7
+ import { Context } from '@dxos/context';
7
8
  import { invariant } from '@dxos/invariant';
8
9
  import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
9
10
  import { type DeviceProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
@@ -36,15 +37,15 @@ export type PerformInvitationCallbacks<T> = {
36
37
  onError?: (value: T) => boolean | void;
37
38
  };
38
39
 
39
- export type PerformInvitationParams = {
40
+ export type PerformInvitationProps = {
40
41
  host: ServiceContext | InvitationHost;
41
42
  guest: ServiceContext | InvitationGuest;
43
+ guestDeviceProfile?: DeviceProfileDocument;
42
44
  options?: Partial<Invitation>;
43
45
  hooks?: {
44
46
  host?: PerformInvitationCallbacks<CancellableInvitation>;
45
47
  guest?: PerformInvitationCallbacks<AuthenticatingInvitation>;
46
48
  };
47
- guestDeviceProfile?: DeviceProfileDocument;
48
49
  codeInputDelay?: number;
49
50
  };
50
51
 
@@ -52,14 +53,17 @@ export type Result = { invitation?: Invitation; error?: Error };
52
53
 
53
54
  // TODO(burdon): Make async.
54
55
  // TODO(burdon): Rename startInvitation.
56
+ /**
57
+ *
58
+ */
55
59
  export const performInvitation = ({
56
60
  host,
57
61
  guest,
62
+ guestDeviceProfile,
58
63
  options,
59
64
  hooks,
60
- guestDeviceProfile,
61
65
  codeInputDelay,
62
- }: PerformInvitationParams): [Promise<Result>, Promise<Result>] => {
66
+ }: PerformInvitationProps): [Promise<Result>, Promise<Result>] => {
63
67
  let guestError = false;
64
68
  let guestConnected = false;
65
69
  let wereConnected = false;
@@ -226,7 +230,7 @@ export const createInvitation = async (
226
230
  };
227
231
 
228
232
  if (host instanceof ServiceContext) {
229
- return host.invitationsManager.createInvitation({
233
+ return host.invitationsManager.createInvitation(new Context(), {
230
234
  kind: Invitation.Kind.SPACE,
231
235
  ...options,
232
236
  });
@@ -243,7 +247,7 @@ export const acceptInvitation = (
243
247
  invitation = sanitizeInvitation(invitation);
244
248
 
245
249
  if (guest instanceof ServiceContext) {
246
- return guest.invitationsManager.acceptInvitation({
250
+ return guest.invitationsManager.acceptInvitation(new Context(), {
247
251
  invitation,
248
252
  deviceProfile: guestDeviceProfile,
249
253
  });
@@ -2,11 +2,15 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
+ import * as Reactivity from '@effect/experimental/Reactivity';
6
+ import * as Layer from 'effect/Layer';
7
+ import * as ManagedRuntime from 'effect/ManagedRuntime';
8
+
5
9
  import { type Config } from '@dxos/config';
6
10
  import { Context } from '@dxos/context';
7
- import { createCredentialSignerWithChain, CredentialGenerator } from '@dxos/credentials';
11
+ import { CredentialGenerator, createCredentialSignerWithChain } from '@dxos/credentials';
8
12
  import { failUndefined } from '@dxos/debug';
9
- import { EchoHost, MetadataStore, SpaceManager, valueEncoding, MeshEchoReplicator } from '@dxos/echo-pipeline';
13
+ import { EchoHost, MeshEchoReplicator, MetadataStore, SpaceManager, valueEncoding } from '@dxos/echo-pipeline';
10
14
  import { FeedFactory, FeedStore } from '@dxos/feed-store';
11
15
  import { Keyring } from '@dxos/keyring';
12
16
  import { type LevelDB } from '@dxos/kv-store';
@@ -14,12 +18,14 @@ import { createTestLevel } from '@dxos/kv-store/testing';
14
18
  import { MemorySignalManager, MemorySignalManagerContext, type SignalManager } from '@dxos/messaging';
15
19
  import { MemoryTransportFactory, SwarmNetworkManager } from '@dxos/network-manager';
16
20
  import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
17
- import { createStorage, StorageType, type Storage } from '@dxos/random-access-storage';
21
+ import { type Storage, StorageType, createStorage } from '@dxos/random-access-storage';
22
+ import { layerMemory as sqliteLayerMemory } from '@dxos/sql-sqlite/platform';
23
+ import * as SqlTransaction from '@dxos/sql-sqlite/SqlTransaction';
18
24
  import { BlobStore } from '@dxos/teleport-extension-object-sync';
19
25
 
20
26
  import { InvitationsHandler, InvitationsManager, SpaceInvitationProtocol } from '../invitations';
21
- import { ClientServicesHost, ServiceContext, type ServiceContextRuntimeParams } from '../services';
22
- import { DataSpaceManager, type DataSpaceManagerRuntimeParams, type SigningContext } from '../spaces';
27
+ import { ClientServicesHost, ServiceContext, type ServiceContextRuntimeProps } from '../services';
28
+ import { DataSpaceManager, type DataSpaceManagerRuntimeProps, type SigningContext } from '../spaces';
23
29
 
24
30
  //
25
31
  // TODO(burdon): Replace with test builder.
@@ -30,6 +36,11 @@ export const createServiceHost = (config: Config, signalManagerContext: MemorySi
30
36
  config,
31
37
  signalManager: new MemorySignalManager(signalManagerContext),
32
38
  transportFactory: MemoryTransportFactory,
39
+ runtime: ManagedRuntime.make(
40
+ SqlTransaction.layer
41
+ .pipe(Layer.provideMerge(sqliteLayerMemory), Layer.provideMerge(Reactivity.layer))
42
+ .pipe(Layer.orDie),
43
+ ).runtimeEffect,
33
44
  });
34
45
  };
35
46
 
@@ -39,11 +50,11 @@ export const createServiceContext = async ({
39
50
  return new MemorySignalManager(signalContext);
40
51
  },
41
52
  storage = createStorage({ type: StorageType.RAM }),
42
- runtimeParams,
53
+ runtimeProps,
43
54
  }: {
44
55
  signalManagerFactory?: () => Promise<SignalManager>;
45
56
  storage?: Storage;
46
- runtimeParams?: ServiceContextRuntimeParams;
57
+ runtimeProps?: ServiceContextRuntimeProps;
47
58
  } = {}) => {
48
59
  const signalManager = await signalManagerFactory();
49
60
  const networkManager = new SwarmNetworkManager({
@@ -53,9 +64,15 @@ export const createServiceContext = async ({
53
64
  const level = createTestLevel();
54
65
  await level.open();
55
66
 
56
- return new ServiceContext(storage, level, networkManager, signalManager, undefined, undefined, {
57
- invitationConnectionDefaultParams: { teleport: { controlHeartbeatInterval: 200 } },
58
- ...runtimeParams,
67
+ const runtime = ManagedRuntime.make(
68
+ SqlTransaction.layer
69
+ .pipe(Layer.provideMerge(sqliteLayerMemory), Layer.provideMerge(Reactivity.layer))
70
+ .pipe(Layer.orDie),
71
+ ).runtimeEffect;
72
+
73
+ return new ServiceContext(storage, level, networkManager, signalManager, undefined, undefined, runtime, {
74
+ invitationConnectionDefaultProps: { teleport: { controlHeartbeatInterval: 200 } },
75
+ ...runtimeProps,
59
76
  });
60
77
  };
61
78
 
@@ -95,7 +112,7 @@ export class TestBuilder {
95
112
 
96
113
  export type TestPeerOpts = {
97
114
  dataStore?: StorageType;
98
- dataSpaceParams?: DataSpaceManagerRuntimeParams;
115
+ dataSpaceProps?: DataSpaceManagerRuntimeProps;
99
116
  };
100
117
 
101
118
  export type TestPeerProps = {
@@ -116,6 +133,11 @@ export type TestPeerProps = {
116
133
 
117
134
  export class TestPeer {
118
135
  private _props: TestPeerProps = {};
136
+ private readonly _runtime = ManagedRuntime.make(
137
+ SqlTransaction.layer
138
+ .pipe(Layer.provideMerge(sqliteLayerMemory), Layer.provideMerge(Reactivity.layer))
139
+ .pipe(Layer.orDie),
140
+ );
119
141
 
120
142
  constructor(
121
143
  private readonly _signalContext: MemorySignalManagerContext,
@@ -179,7 +201,10 @@ export class TestPeer {
179
201
  }
180
202
 
181
203
  get echoHost() {
182
- return (this._props.echoHost ??= new EchoHost({ kv: this.level }));
204
+ return (this._props.echoHost ??= new EchoHost({
205
+ kv: this.level,
206
+ runtime: this._runtime.runtimeEffect,
207
+ }));
183
208
  }
184
209
 
185
210
  get meshEchoReplicator() {
@@ -198,7 +223,7 @@ export class TestPeer {
198
223
  edgeConnection: undefined,
199
224
  meshReplicator: this.meshEchoReplicator,
200
225
  echoEdgeReplicator: undefined,
201
- runtimeParams: this._opts.dataSpaceParams,
226
+ runtimeProps: this._opts.dataSpaceProps,
202
227
  }));
203
228
  }
204
229
 
@@ -227,6 +252,7 @@ export class TestPeer {
227
252
  async destroy(): Promise<void> {
228
253
  await this.level.close();
229
254
  await this.storage.reset();
255
+ await this._runtime.dispose();
230
256
  }
231
257
  }
232
258