@dxos/client-services 0.8.4-main.72ec0f3 → 0.8.4-main.74a063c4e0

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