@dxos/client-services 0.8.4-main.ae835ea → 0.8.4-main.bc2380dfbc

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 (230) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  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-KPYVJG6G.mjs → chunk-TUCJORVO.mjs} +2153 -3654
  6. package/dist/lib/browser/chunk-TUCJORVO.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-XJRPB3GA.mjs +22 -0
  8. package/dist/lib/browser/chunk-XJRPB3GA.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +424 -137
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/meta.json +1 -1
  12. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +88 -0
  13. package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
  14. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
  15. package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
  16. package/dist/lib/browser/packlets/locks/browser.mjs +86 -0
  17. package/dist/lib/browser/packlets/locks/browser.mjs.map +7 -0
  18. package/dist/lib/browser/packlets/locks/node.mjs +48 -0
  19. package/dist/lib/browser/packlets/locks/node.mjs.map +7 -0
  20. package/dist/lib/browser/testing/index.mjs +28 -29
  21. package/dist/lib/browser/testing/index.mjs.map +3 -3
  22. package/dist/lib/node-esm/chunk-2DT3MZRL.mjs +22 -0
  23. package/dist/lib/node-esm/chunk-2DT3MZRL.mjs.map +7 -0
  24. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +24 -0
  25. package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +7 -0
  26. package/dist/lib/node-esm/{chunk-BBBSS6UL.mjs → chunk-IQLAKNSR.mjs} +2099 -3469
  27. package/dist/lib/node-esm/chunk-IQLAKNSR.mjs.map +7 -0
  28. package/dist/lib/node-esm/index.mjs +424 -137
  29. package/dist/lib/node-esm/index.mjs.map +4 -4
  30. package/dist/lib/node-esm/meta.json +1 -1
  31. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +88 -0
  32. package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
  33. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
  34. package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
  35. package/dist/lib/node-esm/packlets/locks/browser.mjs +86 -0
  36. package/dist/lib/node-esm/packlets/locks/browser.mjs.map +7 -0
  37. package/dist/lib/node-esm/packlets/locks/node.mjs +48 -0
  38. package/dist/lib/node-esm/packlets/locks/node.mjs.map +7 -0
  39. package/dist/lib/node-esm/testing/index.mjs +28 -29
  40. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  41. package/dist/types/src/index.d.ts +1 -0
  42. package/dist/types/src/index.d.ts.map +1 -1
  43. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +3 -2
  44. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
  45. package/dist/types/src/packlets/agents/edge-agent-service.d.ts +2 -1
  46. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
  47. package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
  48. package/dist/types/src/packlets/devtools/devtools.d.ts +2 -2
  49. package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
  50. package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
  51. package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
  52. package/dist/types/src/packlets/devtools/metadata.d.ts.map +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.map +1 -1
  56. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
  57. package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
  58. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +2 -3
  59. package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
  60. package/dist/types/src/packlets/diagnostics/index.d.ts +1 -1
  61. package/dist/types/src/packlets/diagnostics/index.d.ts.map +1 -1
  62. package/dist/types/src/packlets/identity/authenticator.d.ts +2 -2
  63. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  64. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  65. package/dist/types/src/packlets/identity/identity-manager.d.ts +6 -6
  66. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  67. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +8 -7
  68. package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
  69. package/dist/types/src/packlets/identity/identity-service.d.ts +6 -10
  70. package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
  71. package/dist/types/src/packlets/identity/identity.d.ts +8 -11
  72. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  73. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +6 -5
  74. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  75. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +1 -1
  76. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
  77. package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
  78. package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
  79. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +7 -4
  80. package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
  81. package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +1 -1
  82. package/dist/types/src/packlets/invitations/invitation-topology.d.ts.map +1 -1
  83. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +4 -4
  84. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  85. package/dist/types/src/packlets/invitations/invitations-manager.d.ts +3 -3
  86. package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
  87. package/dist/types/src/packlets/invitations/invitations-service.d.ts +3 -3
  88. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  89. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +4 -3
  90. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  91. package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
  92. package/dist/types/src/packlets/locks/browser.d.ts.map +1 -1
  93. package/dist/types/src/packlets/locks/index.d.ts +1 -1
  94. package/dist/types/src/packlets/locks/index.d.ts.map +1 -1
  95. package/dist/types/src/packlets/locks/node.d.ts.map +1 -1
  96. package/dist/types/src/packlets/logging/logging-service.d.ts +4 -0
  97. package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
  98. package/dist/types/src/packlets/network/network-service.d.ts +5 -4
  99. package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
  100. package/dist/types/src/packlets/services/client-rpc-server.d.ts +5 -5
  101. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
  102. package/dist/types/src/packlets/services/feed-syncer.d.ts +59 -0
  103. package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
  104. package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
  105. package/dist/types/src/packlets/services/feed-syncer.test.d.ts.map +1 -0
  106. package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
  107. package/dist/types/src/packlets/services/service-context.d.ts +13 -9
  108. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  109. package/dist/types/src/packlets/services/service-host.d.ts +20 -7
  110. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  111. package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
  112. package/dist/types/src/packlets/services/util.d.ts.map +1 -1
  113. package/dist/types/src/packlets/space-export/archive-format.d.ts +9 -0
  114. package/dist/types/src/packlets/space-export/archive-format.d.ts.map +1 -0
  115. package/dist/types/src/packlets/space-export/index.d.ts +4 -1
  116. package/dist/types/src/packlets/space-export/index.d.ts.map +1 -1
  117. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts +23 -0
  118. package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts.map +1 -0
  119. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts +36 -0
  120. package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts.map +1 -0
  121. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +9 -1
  122. package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
  123. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +7 -1
  124. package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
  125. package/dist/types/src/packlets/space-export/space-archive.test.d.ts +2 -0
  126. package/dist/types/src/packlets/space-export/space-archive.test.d.ts.map +1 -0
  127. package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
  128. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +30 -19
  129. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  130. package/dist/types/src/packlets/spaces/data-space.d.ts +26 -9
  131. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  132. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +2 -2
  133. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  134. package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
  135. package/dist/types/src/packlets/spaces/genesis.d.ts +2 -1
  136. package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
  137. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -9
  138. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  139. package/dist/types/src/packlets/spaces/spaces-service.d.ts +10 -7
  140. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  141. package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
  142. package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
  143. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  144. package/dist/types/src/packlets/storage/util.d.ts.map +1 -1
  145. package/dist/types/src/packlets/system/system-service.d.ts +1 -1
  146. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  147. package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -1
  148. package/dist/types/src/packlets/testing/invitation-utils.d.ts +6 -3
  149. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  150. package/dist/types/src/packlets/testing/test-builder.d.ts +6 -5
  151. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  152. package/dist/types/src/packlets/worker/worker-runtime.d.ts +41 -4
  153. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  154. package/dist/types/src/packlets/worker/worker-session.d.ts +2 -4
  155. package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
  156. package/dist/types/src/testing/setup.d.ts.map +1 -1
  157. package/dist/types/src/version.d.ts +1 -1
  158. package/dist/types/src/version.d.ts.map +1 -1
  159. package/dist/types/tsconfig.tsbuildinfo +1 -1
  160. package/package.json +71 -56
  161. package/src/index.ts +1 -0
  162. package/src/packlets/agents/edge-agent-manager.ts +8 -5
  163. package/src/packlets/agents/edge-agent-service.ts +4 -2
  164. package/src/packlets/devices/devices-service.test.ts +0 -1
  165. package/src/packlets/devtools/devtools.ts +2 -3
  166. package/src/packlets/diagnostics/diagnostics.ts +1 -2
  167. package/src/packlets/diagnostics/index.ts +1 -1
  168. package/src/packlets/identity/authenticator.ts +2 -2
  169. package/src/packlets/identity/contacts-service.ts +0 -1
  170. package/src/packlets/identity/identity-manager.test.ts +5 -5
  171. package/src/packlets/identity/identity-manager.ts +23 -22
  172. package/src/packlets/identity/identity-recovery-manager.ts +22 -18
  173. package/src/packlets/identity/identity-service.test.ts +6 -27
  174. package/src/packlets/identity/identity-service.ts +13 -81
  175. package/src/packlets/identity/identity.test.ts +2 -2
  176. package/src/packlets/identity/identity.ts +11 -34
  177. package/src/packlets/invitations/device-invitation-protocol.ts +8 -7
  178. package/src/packlets/invitations/edge-invitation-handler.ts +9 -5
  179. package/src/packlets/invitations/invitation-guest-extenstion.ts +6 -4
  180. package/src/packlets/invitations/invitation-host-extension.ts +13 -14
  181. package/src/packlets/invitations/invitation-protocol.ts +7 -4
  182. package/src/packlets/invitations/invitation-state.ts +1 -15
  183. package/src/packlets/invitations/invitations-handler.test.ts +4 -5
  184. package/src/packlets/invitations/invitations-handler.ts +74 -22
  185. package/src/packlets/invitations/invitations-manager.ts +40 -15
  186. package/src/packlets/invitations/invitations-service.ts +9 -9
  187. package/src/packlets/invitations/space-invitation-protocol.test.ts +17 -16
  188. package/src/packlets/invitations/space-invitation-protocol.ts +11 -16
  189. package/src/packlets/locks/index.ts +1 -1
  190. package/src/packlets/logging/logging-service.ts +20 -16
  191. package/src/packlets/network/network-service.test.ts +0 -1
  192. package/src/packlets/network/network-service.ts +10 -8
  193. package/src/packlets/services/client-rpc-server.ts +19 -16
  194. package/src/packlets/services/feed-syncer.test.ts +340 -0
  195. package/src/packlets/services/feed-syncer.ts +377 -0
  196. package/src/packlets/services/platform.ts +7 -1
  197. package/src/packlets/services/service-context.test.ts +3 -2
  198. package/src/packlets/services/service-context.ts +153 -61
  199. package/src/packlets/services/service-host.test.ts +8 -8
  200. package/src/packlets/services/service-host.ts +70 -40
  201. package/src/packlets/services/service-registry.test.ts +0 -1
  202. package/src/packlets/space-export/archive-format.ts +42 -0
  203. package/src/packlets/space-export/index.ts +4 -1
  204. package/src/packlets/space-export/serialized-space-reader.ts +111 -0
  205. package/src/packlets/space-export/serialized-space-writer.ts +252 -0
  206. package/src/packlets/space-export/space-archive-reader.ts +64 -3
  207. package/src/packlets/space-export/space-archive-writer.ts +41 -3
  208. package/src/packlets/space-export/space-archive.test.ts +461 -0
  209. package/src/packlets/spaces/data-space-manager.test.ts +79 -13
  210. package/src/packlets/spaces/data-space-manager.ts +108 -120
  211. package/src/packlets/spaces/data-space.ts +64 -36
  212. package/src/packlets/spaces/edge-feed-replicator.test.ts +1 -1
  213. package/src/packlets/spaces/edge-feed-replicator.ts +11 -9
  214. package/src/packlets/spaces/epoch-migrations.ts +6 -5
  215. package/src/packlets/spaces/genesis.ts +6 -1
  216. package/src/packlets/spaces/notarization-plugin.test.ts +2 -2
  217. package/src/packlets/spaces/notarization-plugin.ts +10 -9
  218. package/src/packlets/spaces/spaces-service.test.ts +18 -11
  219. package/src/packlets/spaces/spaces-service.ts +124 -24
  220. package/src/packlets/storage/storage.ts +4 -4
  221. package/src/packlets/testing/invitation-utils.ts +10 -6
  222. package/src/packlets/testing/test-builder.ts +36 -10
  223. package/src/packlets/worker/worker-runtime.ts +188 -17
  224. package/src/packlets/worker/worker-session.ts +12 -18
  225. package/src/version.ts +1 -1
  226. package/dist/lib/browser/chunk-KPYVJG6G.mjs.map +0 -7
  227. package/dist/lib/node-esm/chunk-BBBSS6UL.mjs.map +0 -7
  228. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +0 -19
  229. package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +0 -1
  230. package/src/packlets/identity/default-space-state-machine.ts +0 -44
@@ -2,13 +2,17 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
+ import type * as SqlClient from '@effect/sql/SqlClient';
6
+
5
7
  import { Mutex, Trigger } from '@dxos/async';
6
8
  import { Context, Resource } from '@dxos/context';
7
9
  import { type CredentialProcessor, getCredentialAssertion } from '@dxos/credentials';
8
10
  import { failUndefined, warnAfterTimeout } from '@dxos/debug';
9
11
  import {
10
12
  EchoEdgeReplicator,
13
+ EchoEdgeSubductionReplicator,
11
14
  EchoHost,
15
+ type EdgeAutomergeReplicator,
12
16
  MeshEchoReplicator,
13
17
  MetadataStore,
14
18
  SpaceManager,
@@ -16,20 +20,23 @@ import {
16
20
  } from '@dxos/echo-pipeline';
17
21
  import { createChainEdgeIdentity, createEphemeralEdgeIdentity } from '@dxos/edge-client';
18
22
  import type { EdgeConnection, EdgeHttpClient, EdgeIdentity } from '@dxos/edge-client';
23
+ import { type RuntimeProvider } from '@dxos/effect';
19
24
  import { FeedFactory, FeedStore } from '@dxos/feed-store';
20
25
  import { invariant } from '@dxos/invariant';
21
26
  import { Keyring } from '@dxos/keyring';
22
- import { PublicKey } from '@dxos/keys';
27
+ import { type SpaceId } from '@dxos/keys';
23
28
  import { type LevelDB } from '@dxos/kv-store';
24
29
  import { log } from '@dxos/log';
25
30
  import { type SignalManager } from '@dxos/messaging';
26
31
  import { type SwarmNetworkManager } from '@dxos/network-manager';
27
- import { InvalidStorageVersionError, STORAGE_VERSION, trace } from '@dxos/protocols';
32
+ import { InvalidStorageVersionError, STORAGE_VERSION } from '@dxos/protocols';
33
+ import { FeedProtocol } from '@dxos/protocols';
28
34
  import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
29
35
  import { type Runtime } from '@dxos/protocols/proto/dxos/config';
30
36
  import type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
31
37
  import { type Credential, type ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
32
38
  import { type Storage } from '@dxos/random-access-storage';
39
+ import type * as SqlTransaction from '@dxos/sql-sqlite/SqlTransaction';
33
40
  import { BlobStore } from '@dxos/teleport-extension-object-sync';
34
41
  import { trace as Trace } from '@dxos/tracing';
35
42
  import { safeInstanceof } from '@dxos/util';
@@ -37,27 +44,29 @@ import { safeInstanceof } from '@dxos/util';
37
44
  import { EdgeAgentManager } from '../agents';
38
45
  import {
39
46
  type CreateIdentityOptions,
47
+ type Identity,
40
48
  IdentityManager,
41
- type IdentityManagerParams,
42
- type JoinIdentityParams,
49
+ type IdentityManagerProps,
50
+ type JoinIdentityProps,
43
51
  } from '../identity';
44
52
  import { EdgeIdentityRecoveryManager } from '../identity/identity-recovery-manager';
45
53
  import {
46
54
  DeviceInvitationProtocol,
47
- type InvitationConnectionParams,
55
+ type InvitationConnectionProps,
48
56
  type InvitationProtocol,
49
57
  InvitationsHandler,
50
58
  InvitationsManager,
51
59
  SpaceInvitationProtocol,
52
60
  } from '../invitations';
53
- import { DataSpaceManager, type DataSpaceManagerRuntimeParams, type SigningContext } from '../spaces';
61
+ import { DataSpaceManager, type DataSpaceManagerRuntimeProps, type SigningContext } from '../spaces';
62
+ import { FeedSyncer } from './feed-syncer';
54
63
 
55
- export type ServiceContextRuntimeParams = Pick<
56
- IdentityManagerParams,
64
+ export type ServiceContextRuntimeProps = Pick<
65
+ IdentityManagerProps,
57
66
  'devicePresenceOfflineTimeout' | 'devicePresenceAnnounceInterval'
58
67
  > &
59
- DataSpaceManagerRuntimeParams & {
60
- invitationConnectionDefaultParams?: InvitationConnectionParams;
68
+ DataSpaceManagerRuntimeProps & {
69
+ invitationConnectionDefaultProps?: InvitationConnectionProps;
61
70
  disableP2pReplication?: boolean;
62
71
  enableVectorIndexing?: boolean;
63
72
  };
@@ -67,7 +76,7 @@ export type ServiceContextRuntimeParams = Pick<
67
76
  // TODO(burdon): Rename/break-up into smaller components. And/or make members private.
68
77
  // TODO(dmaretskyi): Gets duplicated in CJS build between normal and testing bundles.
69
78
  @safeInstanceof('dxos.client-services.ServiceContext')
70
- @Trace.resource()
79
+ @Trace.resource({ lifecycle: true })
71
80
  export class ServiceContext extends Resource {
72
81
  private readonly _edgeIdentityUpdateMutex = new Mutex();
73
82
 
@@ -83,7 +92,8 @@ export class ServiceContext extends Resource {
83
92
  public readonly invitationsManager: InvitationsManager;
84
93
  public readonly echoHost: EchoHost;
85
94
  private readonly _meshReplicator?: MeshEchoReplicator = undefined;
86
- private readonly _echoEdgeReplicator?: EchoEdgeReplicator = undefined;
95
+ private readonly _echoEdgeReplicator?: EdgeAutomergeReplicator = undefined;
96
+ private readonly _feedSyncer?: FeedSyncer = undefined;
87
97
 
88
98
  // Initialized after identity is initialized.
89
99
  public dataSpaceManager?: DataSpaceManager;
@@ -96,8 +106,6 @@ export class ServiceContext extends Resource {
96
106
 
97
107
  private _deviceSpaceSync?: CredentialProcessor;
98
108
 
99
- private readonly _instanceId = PublicKey.random().toHex();
100
-
101
109
  constructor(
102
110
  public readonly storage: Storage,
103
111
  public readonly level: LevelDB,
@@ -105,11 +113,15 @@ export class ServiceContext extends Resource {
105
113
  public readonly signalManager: SignalManager,
106
114
  private readonly _edgeConnection: EdgeConnection | undefined,
107
115
  private readonly _edgeHttpClient: EdgeHttpClient | undefined,
108
- public readonly _runtimeParams?: ServiceContextRuntimeParams,
116
+ private readonly _runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient | SqlTransaction.SqlTransaction>,
117
+ public readonly _runtimeProps?: ServiceContextRuntimeProps,
109
118
  private readonly _edgeFeatures?: Runtime.Client.EdgeFeatures,
110
119
  ) {
111
120
  super();
112
121
 
122
+ log('runtimeProps', this._runtimeProps);
123
+ log('edgeFeatures', this._edgeFeatures);
124
+
113
125
  // TODO(burdon): Move strings to constants.
114
126
  this.metadataStore = new MetadataStore(storage.createDirectory('metadata'));
115
127
  this.blobStore = new BlobStore(storage.createDirectory('blobs'));
@@ -131,7 +143,7 @@ export class ServiceContext extends Resource {
131
143
  networkManager: this.networkManager,
132
144
  blobStore: this.blobStore,
133
145
  metadataStore: this.metadataStore,
134
- disableP2pReplication: this._runtimeParams?.disableP2pReplication,
146
+ disableP2pReplication: this._runtimeProps?.disableP2pReplication,
135
147
  });
136
148
 
137
149
  this.identityManager = new IdentityManager({
@@ -139,8 +151,8 @@ export class ServiceContext extends Resource {
139
151
  keyring: this.keyring,
140
152
  feedStore: this.feedStore,
141
153
  spaceManager: this.spaceManager,
142
- devicePresenceOfflineTimeout: this._runtimeParams?.devicePresenceOfflineTimeout,
143
- devicePresenceAnnounceInterval: this._runtimeParams?.devicePresenceAnnounceInterval,
154
+ devicePresenceOfflineTimeout: this._runtimeProps?.devicePresenceOfflineTimeout,
155
+ devicePresenceAnnounceInterval: this._runtimeProps?.devicePresenceAnnounceInterval,
144
156
  edgeConnection: this._edgeConnection,
145
157
  edgeFeatures: this._edgeFeatures,
146
158
  });
@@ -156,17 +168,22 @@ export class ServiceContext extends Resource {
156
168
  kv: this.level,
157
169
  peerIdProvider: () => this.identityManager.identity?.deviceKey?.toHex(),
158
170
  getSpaceKeyByRootDocumentId: (documentId) => this.spaceManager.findSpaceByRootDocumentId(documentId)?.key,
159
- indexing: {
160
- vector: this._runtimeParams?.enableVectorIndexing,
171
+ runtime: this._runtime,
172
+ useSubduction: this._edgeFeatures?.subductionReplicator,
173
+ syncQueue: async (ctx, request) => {
174
+ return this._feedSyncer?.syncBlocking(ctx, {
175
+ spaceId: request.spaceId as SpaceId,
176
+ subspaceTag: request.subspaceTag,
177
+ shouldPush: request.shouldPush,
178
+ shouldPull: request.shouldPull,
179
+ });
161
180
  },
162
181
  });
163
182
 
164
- this._meshReplicator = new MeshEchoReplicator();
165
-
166
183
  this.invitations = new InvitationsHandler(
167
184
  this.networkManager, //
168
185
  this._edgeHttpClient,
169
- _runtimeParams?.invitationConnectionDefaultParams,
186
+ _runtimeProps?.invitationConnectionDefaultProps,
170
187
  );
171
188
  this.invitationsManager = new InvitationsManager(
172
189
  this.invitations,
@@ -186,68 +203,122 @@ export class ServiceContext extends Resource {
186
203
  ),
187
204
  );
188
205
 
189
- if (!this._runtimeParams?.disableP2pReplication) {
206
+ if (!this._runtimeProps?.disableP2pReplication) {
190
207
  this._meshReplicator = new MeshEchoReplicator();
191
208
  }
192
- if (this._edgeConnection && this._edgeFeatures?.echoReplicator && this._edgeHttpClient) {
193
- this._echoEdgeReplicator = new EchoEdgeReplicator({
194
- edgeConnection: this._edgeConnection,
195
- edgeHttpClient: this._edgeHttpClient,
209
+ if (this._edgeConnection && this._edgeHttpClient) {
210
+ if (this._edgeFeatures?.subductionReplicator) {
211
+ this._echoEdgeReplicator = new EchoEdgeSubductionReplicator({
212
+ edgeConnection: this._edgeConnection,
213
+ edgeHttpClient: this._edgeHttpClient,
214
+ });
215
+ } else if (this._edgeFeatures?.echoReplicator) {
216
+ this._echoEdgeReplicator = new EchoEdgeReplicator({
217
+ edgeConnection: this._edgeConnection,
218
+ edgeHttpClient: this._edgeHttpClient,
219
+ });
220
+ }
221
+ }
222
+
223
+ if (this.echoHost.feedStore && this._edgeConnection) {
224
+ this._feedSyncer = new FeedSyncer({
225
+ runtime: this._runtime,
226
+ feedStore: this.echoHost.feedStore,
227
+ edgeClient: this._edgeConnection,
228
+ peerId: this.identityManager.identity?.deviceKey?.toHex() ?? '',
229
+ getSpaceIds: () => this.echoHost!.spaceIds,
230
+ syncNamespaces: [FeedProtocol.WellKnownNamespaces.data, FeedProtocol.WellKnownNamespaces.trace],
196
231
  });
197
232
  }
198
233
  }
199
234
 
200
- @Trace.span()
235
+ @Trace.span({ op: 'lifecycle' })
201
236
  protected override async _open(ctx: Context): Promise<void> {
202
237
  await this._checkStorageVersion();
203
238
 
204
239
  log('opening...');
205
- log.trace('dxos.sdk.service-context.open', trace.begin({ id: this._instanceId }));
206
240
 
241
+ log('opening identityManager...');
207
242
  await this.identityManager.open(ctx);
243
+ log('identityManager opened', { hasIdentity: !!this.identityManager.identity });
244
+
245
+ log('setting network identity...');
246
+ await this._setNetworkIdentity({ identity: this.identityManager.identity });
247
+ log('network identity set');
248
+
249
+ log('opening edge connection...');
250
+ await this._edgeConnection?.open(ctx);
251
+ log('edge connection opened');
208
252
 
209
- await this._setNetworkIdentity();
253
+ log('opening signal manager...');
254
+ await this.signalManager.open(ctx);
255
+ log('signal manager opened');
210
256
 
211
- await this._edgeConnection?.open();
212
- await this.signalManager.open();
257
+ log('opening network manager...');
213
258
  await this.networkManager.open();
259
+ log('network manager opened');
214
260
 
261
+ log('opening echo host...');
215
262
  await this.echoHost.open(ctx);
263
+ log('echo host opened');
216
264
 
217
265
  if (this._meshReplicator) {
218
- await this.echoHost.addReplicator(this._meshReplicator);
266
+ log('adding mesh replicator...');
267
+ await this.echoHost.addReplicator(ctx, this._meshReplicator);
268
+ log('mesh replicator added');
219
269
  }
220
270
  if (this._echoEdgeReplicator) {
221
- await this.echoHost.addReplicator(this._echoEdgeReplicator);
271
+ log('adding edge replicator...');
272
+ await this.echoHost.addReplicator(ctx, this._echoEdgeReplicator);
273
+ log('edge replicator added');
222
274
  }
223
275
 
276
+ log('loading metadata store...');
224
277
  await this.metadataStore.load();
278
+ log('metadata store loaded');
279
+
280
+ log('opening space manager...');
225
281
  await this.spaceManager.open();
282
+ log('space manager opened');
226
283
 
227
284
  if (this.identityManager.identity) {
228
- await this.identityManager.identity.joinNetwork();
285
+ log('joining network...');
286
+ await this.identityManager.identity.joinNetwork(ctx);
287
+ log('network joined');
288
+
289
+ log('initializing spaces...(calling _initialize)');
229
290
  await this._initialize(ctx);
291
+ log('spaces initialized');
292
+ } else {
293
+ log('no identity, skipping network join and space initialization');
230
294
  }
231
295
 
232
- const loadedInvitations = await this.invitationsManager.loadPersistentInvitations();
296
+ log('opening feed syncer...');
297
+ await this._feedSyncer?.open(ctx);
298
+ log('feed syncer opened');
299
+
300
+ log('loading persistent invitations...');
301
+ const loadedInvitations = await this.invitationsManager.loadPersistentInvitations(ctx);
233
302
  log('loaded persistent invitations', { count: loadedInvitations.invitations?.length });
234
303
 
235
- log.trace('dxos.sdk.service-context.open', trace.end({ id: this._instanceId }));
236
304
  log('opened');
237
305
  }
238
306
 
239
307
  protected override async _close(ctx: Context): Promise<void> {
240
308
  log('closing...');
309
+
310
+ await this._feedSyncer?.close();
311
+
241
312
  if (this._deviceSpaceSync && this.identityManager.identity) {
242
313
  await this.identityManager.identity.space.spaceState.removeCredentialProcessor(this._deviceSpaceSync);
243
314
  }
244
- await this.dataSpaceManager?.close();
315
+ await this.dataSpaceManager?.close(ctx);
245
316
  await this.edgeAgentManager?.close();
246
- await this.identityManager.close();
317
+ await this.identityManager.close(ctx);
247
318
  await this.spaceManager.close();
248
319
  await this.echoHost.close(ctx);
249
320
 
250
- await this.networkManager.close();
321
+ await this.networkManager.close(ctx);
251
322
  await this.signalManager.close();
252
323
  await this._edgeConnection?.close();
253
324
  await this.feedStore.close();
@@ -256,11 +327,12 @@ export class ServiceContext extends Resource {
256
327
  log('closed');
257
328
  }
258
329
 
259
- async createIdentity(params: CreateIdentityOptions = {}) {
260
- const identity = await this.identityManager.createIdentity(params);
261
- await this._setNetworkIdentity();
262
- await identity.joinNetwork();
263
- await this._initialize(new Context());
330
+ async createIdentity(params: CreateIdentityOptions = {}, ctx?: Context) {
331
+ ctx ??= this._ctx;
332
+ const identity = await this.identityManager.createIdentity(params, ctx);
333
+ await this._setNetworkIdentity({ identity });
334
+ await identity.joinNetwork(ctx);
335
+ await this._initialize(ctx);
264
336
  return identity;
265
337
  }
266
338
 
@@ -283,12 +355,12 @@ export class ServiceContext extends Resource {
283
355
  }
284
356
  }
285
357
 
286
- private async _acceptIdentity(params: JoinIdentityParams) {
287
- const { identity, identityRecord } = await this.identityManager.prepareIdentity(params);
288
- await this._setNetworkIdentity({ deviceCredential: params.authorizedDeviceCredential! });
289
- await identity.joinNetwork();
358
+ private async _acceptIdentity(params: JoinIdentityProps) {
359
+ const { identity, identityRecord } = await this.identityManager.prepareIdentity(params, this._ctx);
360
+ await this._setNetworkIdentity({ deviceCredential: params.authorizedDeviceCredential!, identity });
361
+ await identity.joinNetwork(this._ctx);
290
362
  await this.identityManager.acceptIdentity(identity, identityRecord, params.deviceProfile);
291
- await this._initialize(new Context());
363
+ await this._initialize(this._ctx);
292
364
  return identity;
293
365
  }
294
366
 
@@ -303,7 +375,7 @@ export class ServiceContext extends Resource {
303
375
  // Called when identity is created.
304
376
  @Trace.span()
305
377
  private async _initialize(ctx: Context): Promise<void> {
306
- log('initializing spaces...');
378
+ log('_initialize: start');
307
379
  const identity = this.identityManager.identity ?? failUndefined();
308
380
  const signingContext: SigningContext = {
309
381
  credentialSigner: identity.getIdentityCredentialSigner(),
@@ -315,6 +387,7 @@ export class ServiceContext extends Resource {
315
387
  },
316
388
  };
317
389
 
390
+ log('_initialize: creating DataSpaceManager');
318
391
  this.dataSpaceManager = new DataSpaceManager({
319
392
  spaceManager: this.spaceManager,
320
393
  metadataStore: this.metadataStore,
@@ -327,10 +400,12 @@ export class ServiceContext extends Resource {
327
400
  edgeHttpClient: this._edgeHttpClient,
328
401
  echoEdgeReplicator: this._echoEdgeReplicator,
329
402
  meshReplicator: this._meshReplicator,
330
- runtimeParams: this._runtimeParams as DataSpaceManagerRuntimeParams,
403
+ runtimeProps: this._runtimeProps as DataSpaceManagerRuntimeProps,
331
404
  edgeFeatures: this._edgeFeatures,
332
405
  });
333
- await this.dataSpaceManager.open();
406
+ log('_initialize: opening DataSpaceManager...');
407
+ await this.dataSpaceManager.open(ctx);
408
+ log('_initialize: DataSpaceManager opened');
334
409
 
335
410
  this.edgeAgentManager = new EdgeAgentManager(
336
411
  this._edgeFeatures,
@@ -338,13 +413,16 @@ export class ServiceContext extends Resource {
338
413
  this.dataSpaceManager,
339
414
  identity,
340
415
  );
341
- await this.edgeAgentManager.open();
416
+ log('_initialize: opening EdgeAgentManager...');
417
+ await this.edgeAgentManager.open(ctx);
418
+ log('_initialize: EdgeAgentManager opened');
342
419
 
343
420
  this._handlerFactories.set(Invitation.Kind.SPACE, (invitation) => {
344
421
  invariant(this.dataSpaceManager, 'dataSpaceManager not initialized yet');
345
422
  return new SpaceInvitationProtocol(this.dataSpaceManager, signingContext, this.keyring, invitation.spaceKey);
346
423
  });
347
424
  this.initialized.wake();
425
+ log('_initialize: initialized.wake() called');
348
426
 
349
427
  this._deviceSpaceSync = {
350
428
  processCredential: async (credential: Credential) => {
@@ -367,9 +445,10 @@ export class ServiceContext extends Resource {
367
445
 
368
446
  try {
369
447
  log('accepting space recorded in halo', { details: assertion });
370
- await this.dataSpaceManager.acceptSpace({
448
+ await this.dataSpaceManager.acceptSpace(this._ctx, {
371
449
  spaceKey: assertion.spaceKey,
372
450
  genesisFeedKey: assertion.genesisFeedKey,
451
+ tags: assertion.tags,
373
452
  });
374
453
  } catch (err) {
375
454
  log.catch(err);
@@ -380,33 +459,42 @@ export class ServiceContext extends Resource {
380
459
  await identity.space.spaceState.addCredentialProcessor(this._deviceSpaceSync);
381
460
  }
382
461
 
383
- private async _setNetworkIdentity(params?: { deviceCredential: Credential }): Promise<void> {
462
+ private async _setNetworkIdentity(params?: { deviceCredential?: Credential; identity?: Identity }): Promise<void> {
463
+ log('_setNetworkIdentity: acquiring mutex...');
384
464
  using _ = await this._edgeIdentityUpdateMutex.acquire();
465
+ log('_setNetworkIdentity: mutex acquired');
385
466
 
386
467
  let edgeIdentity: EdgeIdentity;
387
- const identity = this.identityManager.identity;
468
+ const identity = params?.identity;
388
469
  if (identity) {
389
- log('setting identity on edge connection', {
470
+ log('_setNetworkIdentity: has identity', {
390
471
  identity: identity.identityKey.toHex(),
391
- swarms: this.networkManager.topics,
472
+ hasDeviceCredential: !!params?.deviceCredential,
392
473
  });
393
474
 
394
475
  if (params?.deviceCredential) {
476
+ log('_setNetworkIdentity: creating chain edge identity with device credential...');
395
477
  edgeIdentity = await createChainEdgeIdentity(
396
478
  identity.signer,
397
479
  identity.identityKey,
398
480
  identity.deviceKey,
399
- params?.deviceCredential && { credential: params.deviceCredential },
481
+ { credential: params.deviceCredential },
400
482
  [], // TODO(dmaretskyi): Service access credentials.
401
483
  );
484
+ log('_setNetworkIdentity: chain edge identity created');
402
485
  } else {
486
+ log('_setNetworkIdentity: waiting for identity.ready()...');
403
487
  // TODO: throw here or from identity if device chain can't be loaded, to avoid indefinite hangup
404
488
  await warnAfterTimeout(10_000, 'Waiting for identity to be ready for edge connection', async () => {
405
489
  await identity.ready();
406
490
  });
491
+ log('_setNetworkIdentity: identity.ready() resolved', {
492
+ hasDeviceCredentialChain: !!identity.deviceCredentialChain,
493
+ });
407
494
 
408
495
  invariant(identity.deviceCredentialChain);
409
496
 
497
+ log('_setNetworkIdentity: creating chain edge identity...');
410
498
  edgeIdentity = await createChainEdgeIdentity(
411
499
  identity.signer,
412
500
  identity.identityKey,
@@ -414,9 +502,12 @@ export class ServiceContext extends Resource {
414
502
  identity.deviceCredentialChain,
415
503
  [], // TODO(dmaretskyi): Service access credentials.
416
504
  );
505
+ log('_setNetworkIdentity: chain edge identity created');
417
506
  }
418
507
  } else {
508
+ log('_setNetworkIdentity: no identity, creating ephemeral edge identity...');
419
509
  edgeIdentity = await createEphemeralEdgeIdentity();
510
+ log('_setNetworkIdentity: ephemeral edge identity created');
420
511
  }
421
512
 
422
513
  this._edgeConnection?.setIdentity(edgeIdentity);
@@ -425,5 +516,6 @@ export class ServiceContext extends Resource {
425
516
  identityKey: edgeIdentity.identityKey,
426
517
  peerKey: edgeIdentity.peerKey,
427
518
  });
519
+ log('_setNetworkIdentity: done');
428
520
  }
429
521
  }
@@ -3,7 +3,6 @@
3
3
  //
4
4
 
5
5
  import { rmSync } from 'node:fs';
6
-
7
6
  import { afterEach, describe, expect, onTestFinished, test } from 'vitest';
8
7
 
9
8
  import { Trigger, asyncTimeout, latch } from '@dxos/async';
@@ -13,6 +12,7 @@ import { verifyPresentation } from '@dxos/credentials';
13
12
  import { type PublicKey } from '@dxos/keys';
14
13
  import { MemorySignalManagerContext } from '@dxos/messaging';
15
14
  import { type Identity } from '@dxos/protocols/proto/dxos/client/services';
15
+ import { MembershipPolicy } from '@dxos/protocols/proto/dxos/halo/credentials';
16
16
  import { type Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
17
17
  import { isNode } from '@dxos/util';
18
18
 
@@ -29,16 +29,16 @@ describe('ClientServicesHost', () => {
29
29
  test('open and close', async () => {
30
30
  const host = createServiceHost(new Config(), new MemorySignalManagerContext());
31
31
  await host.open(new Context());
32
- await host.close();
32
+ await host.close(Context.default());
33
33
  });
34
34
 
35
35
  test('queryCredentials', async () => {
36
36
  const host = createServiceHost(new Config(), new MemorySignalManagerContext());
37
37
  await host.open(new Context());
38
- onTestFinished(() => host.close());
38
+ onTestFinished(() => host.close(Context.default()));
39
39
 
40
40
  await host.services.IdentityService!.createIdentity({});
41
- const { spaceKey } = await host.services.SpacesService!.createSpace();
41
+ const { spaceKey } = await host.services.SpacesService!.createSpace({ membershipPolicy: MembershipPolicy.INVITE });
42
42
 
43
43
  const stream = host.services.SpacesService!.queryCredentials({ spaceKey });
44
44
  const [done, tick] = latch({ count: 3 });
@@ -54,7 +54,7 @@ describe('ClientServicesHost', () => {
54
54
  test('write and query credentials', async () => {
55
55
  const host = createServiceHost(new Config(), new MemorySignalManagerContext());
56
56
  await host.open(new Context());
57
- onTestFinished(() => host.close());
57
+ onTestFinished(() => host.close(Context.default()));
58
58
 
59
59
  await host.services.IdentityService!.createIdentity({});
60
60
 
@@ -91,7 +91,7 @@ describe('ClientServicesHost', () => {
91
91
  test('sign presentation', async () => {
92
92
  const host = createServiceHost(new Config(), new MemorySignalManagerContext());
93
93
  await host.open(new Context());
94
- onTestFinished(() => host.close());
94
+ onTestFinished(() => host.close(Context.default()));
95
95
 
96
96
  await host.services.IdentityService!.createIdentity({});
97
97
 
@@ -128,7 +128,7 @@ describe('ClientServicesHost', () => {
128
128
  expect(host.context.storage.size).to.exist;
129
129
 
130
130
  await asyncTimeout(host.reset(), 1000);
131
- await host.close();
131
+ await host.close(Context.default());
132
132
  }
133
133
 
134
134
  {
@@ -146,7 +146,7 @@ describe('ClientServicesHost', () => {
146
146
  });
147
147
  await expect(asyncTimeout(trigger.wait(), 200)).rejects.toBeInstanceOf(Error);
148
148
  await stream?.close();
149
- await host.close();
149
+ await host.close(Context.default());
150
150
  }
151
151
  });
152
152
  });