@dxos/client-services 0.8.4-main.ef1bc66f44 → 0.8.4-main.f466a3d56e
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.
- package/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/browser/{chunk-NTZOEM4P.mjs → chunk-SNHT4M6V.mjs} +1731 -3089
- package/dist/lib/browser/chunk-SNHT4M6V.mjs.map +7 -0
- package/dist/lib/browser/{chunk-NQSC7HOE.mjs → chunk-XJRPB3GA.mjs} +1 -1
- package/dist/lib/browser/index.mjs +106 -194
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +1 -6
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +2 -2
- package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +1 -1
- package/dist/lib/browser/packlets/locks/browser.mjs +9 -49
- package/dist/lib/browser/packlets/locks/browser.mjs.map +2 -2
- package/dist/lib/browser/packlets/locks/node.mjs +4 -22
- package/dist/lib/browser/packlets/locks/node.mjs.map +2 -2
- package/dist/lib/browser/testing/index.mjs +9 -22
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/{chunk-PKEGMOQ4.mjs → chunk-2DT3MZRL.mjs} +1 -1
- package/dist/lib/node-esm/{chunk-DQWA5ILA.mjs → chunk-2TVKX6UU.mjs} +1731 -3089
- package/dist/lib/node-esm/chunk-2TVKX6UU.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +106 -194
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +1 -6
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +2 -2
- package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +1 -1
- package/dist/lib/node-esm/packlets/locks/browser.mjs +9 -49
- package/dist/lib/node-esm/packlets/locks/browser.mjs.map +2 -2
- package/dist/lib/node-esm/packlets/locks/node.mjs +4 -22
- package/dist/lib/node-esm/packlets/locks/node.mjs.map +2 -2
- package/dist/lib/node-esm/testing/index.mjs +9 -22
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +3 -2
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts +2 -1
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
- package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/metadata.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +2 -3
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-manager.d.ts +3 -3
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +6 -5
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-service.d.ts +6 -10
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +6 -9
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +2 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +1 -1
- package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +5 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-topology.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts +3 -3
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-service.d.ts +3 -3
- package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +2 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
- package/dist/types/src/packlets/locks/browser.d.ts.map +1 -1
- package/dist/types/src/packlets/locks/node.d.ts.map +1 -1
- package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
- package/dist/types/src/packlets/network/network-service.d.ts +5 -4
- package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
- package/dist/types/src/packlets/services/client-rpc-server.d.ts +3 -3
- package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
- package/dist/types/src/packlets/services/feed-syncer.d.ts +22 -4
- package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -1
- package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
- package/dist/types/src/packlets/services/feed-syncer.test.d.ts.map +1 -0
- package/dist/types/src/packlets/services/service-context.d.ts +2 -4
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +2 -3
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
- package/dist/types/src/packlets/services/util.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/archive-format.d.ts +9 -0
- package/dist/types/src/packlets/space-export/archive-format.d.ts.map +1 -0
- package/dist/types/src/packlets/space-export/index.d.ts +4 -1
- package/dist/types/src/packlets/space-export/index.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts +23 -0
- package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts.map +1 -0
- package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts +36 -0
- package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts.map +1 -0
- package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +9 -1
- package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +7 -1
- package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/space-archive.test.d.ts +2 -0
- package/dist/types/src/packlets/space-export/space-archive.test.d.ts.map +1 -0
- package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +20 -14
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +24 -7
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/genesis.d.ts +2 -1
- package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +1 -4
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts +10 -7
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/util.d.ts.map +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-runtime.d.ts +11 -1
- package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-session.d.ts +0 -2
- package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
- package/dist/types/src/testing/setup.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +43 -50
- package/src/index.ts +1 -0
- package/src/packlets/agents/edge-agent-manager.ts +8 -5
- package/src/packlets/agents/edge-agent-service.ts +4 -2
- package/src/packlets/devices/devices-service.test.ts +0 -1
- package/src/packlets/devtools/devtools.ts +0 -1
- package/src/packlets/diagnostics/diagnostics.ts +1 -2
- package/src/packlets/identity/contacts-service.ts +0 -1
- package/src/packlets/identity/identity-manager.test.ts +5 -5
- package/src/packlets/identity/identity-manager.ts +18 -17
- package/src/packlets/identity/identity-recovery-manager.ts +20 -16
- package/src/packlets/identity/identity-service.test.ts +6 -27
- package/src/packlets/identity/identity-service.ts +13 -81
- package/src/packlets/identity/identity.test.ts +2 -2
- package/src/packlets/identity/identity.ts +9 -32
- package/src/packlets/invitations/device-invitation-protocol.ts +3 -2
- package/src/packlets/invitations/edge-invitation-handler.ts +9 -5
- package/src/packlets/invitations/invitation-host-extension.ts +7 -10
- package/src/packlets/invitations/invitation-protocol.ts +5 -1
- package/src/packlets/invitations/invitation-state.ts +1 -15
- package/src/packlets/invitations/invitations-handler.test.ts +4 -5
- package/src/packlets/invitations/invitations-handler.ts +67 -15
- package/src/packlets/invitations/invitations-manager.ts +40 -15
- package/src/packlets/invitations/invitations-service.ts +9 -9
- package/src/packlets/invitations/space-invitation-protocol.test.ts +17 -16
- package/src/packlets/invitations/space-invitation-protocol.ts +4 -3
- package/src/packlets/logging/logging-service.ts +15 -15
- package/src/packlets/network/network-service.test.ts +0 -1
- package/src/packlets/network/network-service.ts +10 -8
- package/src/packlets/services/client-rpc-server.ts +15 -12
- package/src/packlets/services/feed-syncer.test.ts +340 -0
- package/src/packlets/services/feed-syncer.ts +175 -25
- package/src/packlets/services/service-context.test.ts +3 -2
- package/src/packlets/services/service-context.ts +113 -47
- package/src/packlets/services/service-host.test.ts +8 -8
- package/src/packlets/services/service-host.ts +17 -27
- package/src/packlets/services/service-registry.test.ts +0 -1
- package/src/packlets/space-export/archive-format.ts +42 -0
- package/src/packlets/space-export/index.ts +4 -1
- package/src/packlets/space-export/serialized-space-reader.ts +111 -0
- package/src/packlets/space-export/serialized-space-writer.ts +252 -0
- package/src/packlets/space-export/space-archive-reader.ts +64 -3
- package/src/packlets/space-export/space-archive-writer.ts +38 -2
- package/src/packlets/space-export/space-archive.test.ts +461 -0
- package/src/packlets/spaces/data-space-manager.test.ts +79 -13
- package/src/packlets/spaces/data-space-manager.ts +80 -115
- package/src/packlets/spaces/data-space.ts +55 -31
- package/src/packlets/spaces/edge-feed-replicator.test.ts +1 -1
- package/src/packlets/spaces/edge-feed-replicator.ts +9 -7
- package/src/packlets/spaces/epoch-migrations.ts +4 -3
- package/src/packlets/spaces/genesis.ts +6 -1
- package/src/packlets/spaces/notarization-plugin.ts +2 -1
- package/src/packlets/spaces/spaces-service.test.ts +18 -11
- package/src/packlets/spaces/spaces-service.ts +115 -17
- package/src/packlets/testing/invitation-utils.ts +3 -2
- package/src/packlets/worker/worker-runtime.ts +39 -6
- package/src/packlets/worker/worker-session.ts +8 -14
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-NTZOEM4P.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-DQWA5ILA.mjs.map +0 -7
- package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +0 -19
- package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +0 -1
- package/src/packlets/identity/default-space-state-machine.ts +0 -44
- /package/dist/lib/browser/{chunk-NQSC7HOE.mjs.map → chunk-XJRPB3GA.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-PKEGMOQ4.mjs.map → chunk-2DT3MZRL.mjs.map} +0 -0
|
@@ -10,7 +10,9 @@ import { type CredentialProcessor, getCredentialAssertion } from '@dxos/credenti
|
|
|
10
10
|
import { failUndefined, warnAfterTimeout } from '@dxos/debug';
|
|
11
11
|
import {
|
|
12
12
|
EchoEdgeReplicator,
|
|
13
|
+
EchoEdgeSubductionReplicator,
|
|
13
14
|
EchoHost,
|
|
15
|
+
type EdgeAutomergeReplicator,
|
|
14
16
|
MeshEchoReplicator,
|
|
15
17
|
MetadataStore,
|
|
16
18
|
SpaceManager,
|
|
@@ -22,12 +24,12 @@ import { type RuntimeProvider } from '@dxos/effect';
|
|
|
22
24
|
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
23
25
|
import { invariant } from '@dxos/invariant';
|
|
24
26
|
import { Keyring } from '@dxos/keyring';
|
|
25
|
-
import {
|
|
27
|
+
import { type SpaceId } from '@dxos/keys';
|
|
26
28
|
import { type LevelDB } from '@dxos/kv-store';
|
|
27
29
|
import { log } from '@dxos/log';
|
|
28
30
|
import { type SignalManager } from '@dxos/messaging';
|
|
29
31
|
import { type SwarmNetworkManager } from '@dxos/network-manager';
|
|
30
|
-
import { InvalidStorageVersionError, STORAGE_VERSION
|
|
32
|
+
import { InvalidStorageVersionError, STORAGE_VERSION } from '@dxos/protocols';
|
|
31
33
|
import { FeedProtocol } from '@dxos/protocols';
|
|
32
34
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
33
35
|
import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
@@ -42,6 +44,7 @@ import { safeInstanceof } from '@dxos/util';
|
|
|
42
44
|
import { EdgeAgentManager } from '../agents';
|
|
43
45
|
import {
|
|
44
46
|
type CreateIdentityOptions,
|
|
47
|
+
type Identity,
|
|
45
48
|
IdentityManager,
|
|
46
49
|
type IdentityManagerProps,
|
|
47
50
|
type JoinIdentityProps,
|
|
@@ -56,7 +59,6 @@ import {
|
|
|
56
59
|
SpaceInvitationProtocol,
|
|
57
60
|
} from '../invitations';
|
|
58
61
|
import { DataSpaceManager, type DataSpaceManagerRuntimeProps, type SigningContext } from '../spaces';
|
|
59
|
-
|
|
60
62
|
import { FeedSyncer } from './feed-syncer';
|
|
61
63
|
|
|
62
64
|
export type ServiceContextRuntimeProps = Pick<
|
|
@@ -67,7 +69,6 @@ export type ServiceContextRuntimeProps = Pick<
|
|
|
67
69
|
invitationConnectionDefaultProps?: InvitationConnectionProps;
|
|
68
70
|
disableP2pReplication?: boolean;
|
|
69
71
|
enableVectorIndexing?: boolean;
|
|
70
|
-
enableLocalQueues?: boolean;
|
|
71
72
|
};
|
|
72
73
|
/**
|
|
73
74
|
* Shared backend for all client services.
|
|
@@ -75,7 +76,7 @@ export type ServiceContextRuntimeProps = Pick<
|
|
|
75
76
|
// TODO(burdon): Rename/break-up into smaller components. And/or make members private.
|
|
76
77
|
// TODO(dmaretskyi): Gets duplicated in CJS build between normal and testing bundles.
|
|
77
78
|
@safeInstanceof('dxos.client-services.ServiceContext')
|
|
78
|
-
@Trace.resource()
|
|
79
|
+
@Trace.resource({ lifecycle: true })
|
|
79
80
|
export class ServiceContext extends Resource {
|
|
80
81
|
private readonly _edgeIdentityUpdateMutex = new Mutex();
|
|
81
82
|
|
|
@@ -91,7 +92,7 @@ export class ServiceContext extends Resource {
|
|
|
91
92
|
public readonly invitationsManager: InvitationsManager;
|
|
92
93
|
public readonly echoHost: EchoHost;
|
|
93
94
|
private readonly _meshReplicator?: MeshEchoReplicator = undefined;
|
|
94
|
-
private readonly _echoEdgeReplicator?:
|
|
95
|
+
private readonly _echoEdgeReplicator?: EdgeAutomergeReplicator = undefined;
|
|
95
96
|
private readonly _feedSyncer?: FeedSyncer = undefined;
|
|
96
97
|
|
|
97
98
|
// Initialized after identity is initialized.
|
|
@@ -105,8 +106,6 @@ export class ServiceContext extends Resource {
|
|
|
105
106
|
|
|
106
107
|
private _deviceSpaceSync?: CredentialProcessor;
|
|
107
108
|
|
|
108
|
-
private readonly _instanceId = PublicKey.random().toHex();
|
|
109
|
-
|
|
110
109
|
constructor(
|
|
111
110
|
public readonly storage: Storage,
|
|
112
111
|
public readonly level: LevelDB,
|
|
@@ -170,7 +169,15 @@ export class ServiceContext extends Resource {
|
|
|
170
169
|
peerIdProvider: () => this.identityManager.identity?.deviceKey?.toHex(),
|
|
171
170
|
getSpaceKeyByRootDocumentId: (documentId) => this.spaceManager.findSpaceByRootDocumentId(documentId)?.key,
|
|
172
171
|
runtime: this._runtime,
|
|
173
|
-
|
|
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
|
+
});
|
|
180
|
+
},
|
|
174
181
|
});
|
|
175
182
|
|
|
176
183
|
this.invitations = new InvitationsHandler(
|
|
@@ -199,11 +206,18 @@ export class ServiceContext extends Resource {
|
|
|
199
206
|
if (!this._runtimeProps?.disableP2pReplication) {
|
|
200
207
|
this._meshReplicator = new MeshEchoReplicator();
|
|
201
208
|
}
|
|
202
|
-
if (this._edgeConnection && this.
|
|
203
|
-
this.
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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
|
+
}
|
|
207
221
|
}
|
|
208
222
|
|
|
209
223
|
if (this.echoHost.feedStore && this._edgeConnection) {
|
|
@@ -213,49 +227,80 @@ export class ServiceContext extends Resource {
|
|
|
213
227
|
edgeClient: this._edgeConnection,
|
|
214
228
|
peerId: this.identityManager.identity?.deviceKey?.toHex() ?? '',
|
|
215
229
|
getSpaceIds: () => this.echoHost!.spaceIds,
|
|
216
|
-
|
|
230
|
+
syncNamespaces: [FeedProtocol.WellKnownNamespaces.data, FeedProtocol.WellKnownNamespaces.trace],
|
|
217
231
|
});
|
|
218
232
|
}
|
|
219
233
|
}
|
|
220
234
|
|
|
221
|
-
@Trace.span()
|
|
235
|
+
@Trace.span({ op: 'lifecycle' })
|
|
222
236
|
protected override async _open(ctx: Context): Promise<void> {
|
|
223
237
|
await this._checkStorageVersion();
|
|
224
238
|
|
|
225
239
|
log('opening...');
|
|
226
|
-
log.trace('dxos.sdk.service-context.open', trace.begin({ id: this._instanceId }));
|
|
227
240
|
|
|
241
|
+
log('opening identityManager...');
|
|
228
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');
|
|
229
248
|
|
|
230
|
-
|
|
249
|
+
log('opening edge connection...');
|
|
250
|
+
await this._edgeConnection?.open(ctx);
|
|
251
|
+
log('edge connection opened');
|
|
231
252
|
|
|
232
|
-
|
|
233
|
-
await this.signalManager.open();
|
|
253
|
+
log('opening signal manager...');
|
|
254
|
+
await this.signalManager.open(ctx);
|
|
255
|
+
log('signal manager opened');
|
|
256
|
+
|
|
257
|
+
log('opening network manager...');
|
|
234
258
|
await this.networkManager.open();
|
|
259
|
+
log('network manager opened');
|
|
235
260
|
|
|
261
|
+
log('opening echo host...');
|
|
236
262
|
await this.echoHost.open(ctx);
|
|
263
|
+
log('echo host opened');
|
|
237
264
|
|
|
238
265
|
if (this._meshReplicator) {
|
|
239
|
-
|
|
266
|
+
log('adding mesh replicator...');
|
|
267
|
+
await this.echoHost.addReplicator(ctx, this._meshReplicator);
|
|
268
|
+
log('mesh replicator added');
|
|
240
269
|
}
|
|
241
270
|
if (this._echoEdgeReplicator) {
|
|
242
|
-
|
|
271
|
+
log('adding edge replicator...');
|
|
272
|
+
await this.echoHost.addReplicator(ctx, this._echoEdgeReplicator);
|
|
273
|
+
log('edge replicator added');
|
|
243
274
|
}
|
|
244
275
|
|
|
276
|
+
log('loading metadata store...');
|
|
245
277
|
await this.metadataStore.load();
|
|
278
|
+
log('metadata store loaded');
|
|
279
|
+
|
|
280
|
+
log('opening space manager...');
|
|
246
281
|
await this.spaceManager.open();
|
|
282
|
+
log('space manager opened');
|
|
247
283
|
|
|
248
284
|
if (this.identityManager.identity) {
|
|
249
|
-
|
|
285
|
+
log('joining network...');
|
|
286
|
+
await this.identityManager.identity.joinNetwork(ctx);
|
|
287
|
+
log('network joined');
|
|
288
|
+
|
|
289
|
+
log('initializing spaces...(calling _initialize)');
|
|
250
290
|
await this._initialize(ctx);
|
|
291
|
+
log('spaces initialized');
|
|
292
|
+
} else {
|
|
293
|
+
log('no identity, skipping network join and space initialization');
|
|
251
294
|
}
|
|
252
295
|
|
|
253
|
-
|
|
296
|
+
log('opening feed syncer...');
|
|
297
|
+
await this._feedSyncer?.open(ctx);
|
|
298
|
+
log('feed syncer opened');
|
|
254
299
|
|
|
255
|
-
|
|
300
|
+
log('loading persistent invitations...');
|
|
301
|
+
const loadedInvitations = await this.invitationsManager.loadPersistentInvitations(ctx);
|
|
256
302
|
log('loaded persistent invitations', { count: loadedInvitations.invitations?.length });
|
|
257
303
|
|
|
258
|
-
log.trace('dxos.sdk.service-context.open', trace.end({ id: this._instanceId }));
|
|
259
304
|
log('opened');
|
|
260
305
|
}
|
|
261
306
|
|
|
@@ -267,13 +312,13 @@ export class ServiceContext extends Resource {
|
|
|
267
312
|
if (this._deviceSpaceSync && this.identityManager.identity) {
|
|
268
313
|
await this.identityManager.identity.space.spaceState.removeCredentialProcessor(this._deviceSpaceSync);
|
|
269
314
|
}
|
|
270
|
-
await this.dataSpaceManager?.close();
|
|
315
|
+
await this.dataSpaceManager?.close(ctx);
|
|
271
316
|
await this.edgeAgentManager?.close();
|
|
272
|
-
await this.identityManager.close();
|
|
317
|
+
await this.identityManager.close(ctx);
|
|
273
318
|
await this.spaceManager.close();
|
|
274
319
|
await this.echoHost.close(ctx);
|
|
275
320
|
|
|
276
|
-
await this.networkManager.close();
|
|
321
|
+
await this.networkManager.close(ctx);
|
|
277
322
|
await this.signalManager.close();
|
|
278
323
|
await this._edgeConnection?.close();
|
|
279
324
|
await this.feedStore.close();
|
|
@@ -282,11 +327,12 @@ export class ServiceContext extends Resource {
|
|
|
282
327
|
log('closed');
|
|
283
328
|
}
|
|
284
329
|
|
|
285
|
-
async createIdentity(params: CreateIdentityOptions = {}) {
|
|
286
|
-
|
|
287
|
-
await this.
|
|
288
|
-
await
|
|
289
|
-
await
|
|
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);
|
|
290
336
|
return identity;
|
|
291
337
|
}
|
|
292
338
|
|
|
@@ -310,11 +356,11 @@ export class ServiceContext extends Resource {
|
|
|
310
356
|
}
|
|
311
357
|
|
|
312
358
|
private async _acceptIdentity(params: JoinIdentityProps) {
|
|
313
|
-
const { identity, identityRecord } = await this.identityManager.prepareIdentity(params);
|
|
314
|
-
await this._setNetworkIdentity({ deviceCredential: params.authorizedDeviceCredential
|
|
315
|
-
await identity.joinNetwork();
|
|
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);
|
|
316
362
|
await this.identityManager.acceptIdentity(identity, identityRecord, params.deviceProfile);
|
|
317
|
-
await this._initialize(
|
|
363
|
+
await this._initialize(this._ctx);
|
|
318
364
|
return identity;
|
|
319
365
|
}
|
|
320
366
|
|
|
@@ -329,7 +375,7 @@ export class ServiceContext extends Resource {
|
|
|
329
375
|
// Called when identity is created.
|
|
330
376
|
@Trace.span()
|
|
331
377
|
private async _initialize(ctx: Context): Promise<void> {
|
|
332
|
-
log('
|
|
378
|
+
log('_initialize: start');
|
|
333
379
|
const identity = this.identityManager.identity ?? failUndefined();
|
|
334
380
|
const signingContext: SigningContext = {
|
|
335
381
|
credentialSigner: identity.getIdentityCredentialSigner(),
|
|
@@ -341,6 +387,7 @@ export class ServiceContext extends Resource {
|
|
|
341
387
|
},
|
|
342
388
|
};
|
|
343
389
|
|
|
390
|
+
log('_initialize: creating DataSpaceManager');
|
|
344
391
|
this.dataSpaceManager = new DataSpaceManager({
|
|
345
392
|
spaceManager: this.spaceManager,
|
|
346
393
|
metadataStore: this.metadataStore,
|
|
@@ -356,7 +403,9 @@ export class ServiceContext extends Resource {
|
|
|
356
403
|
runtimeProps: this._runtimeProps as DataSpaceManagerRuntimeProps,
|
|
357
404
|
edgeFeatures: this._edgeFeatures,
|
|
358
405
|
});
|
|
359
|
-
|
|
406
|
+
log('_initialize: opening DataSpaceManager...');
|
|
407
|
+
await this.dataSpaceManager.open(ctx);
|
|
408
|
+
log('_initialize: DataSpaceManager opened');
|
|
360
409
|
|
|
361
410
|
this.edgeAgentManager = new EdgeAgentManager(
|
|
362
411
|
this._edgeFeatures,
|
|
@@ -364,13 +413,16 @@ export class ServiceContext extends Resource {
|
|
|
364
413
|
this.dataSpaceManager,
|
|
365
414
|
identity,
|
|
366
415
|
);
|
|
367
|
-
|
|
416
|
+
log('_initialize: opening EdgeAgentManager...');
|
|
417
|
+
await this.edgeAgentManager.open(ctx);
|
|
418
|
+
log('_initialize: EdgeAgentManager opened');
|
|
368
419
|
|
|
369
420
|
this._handlerFactories.set(Invitation.Kind.SPACE, (invitation) => {
|
|
370
421
|
invariant(this.dataSpaceManager, 'dataSpaceManager not initialized yet');
|
|
371
422
|
return new SpaceInvitationProtocol(this.dataSpaceManager, signingContext, this.keyring, invitation.spaceKey);
|
|
372
423
|
});
|
|
373
424
|
this.initialized.wake();
|
|
425
|
+
log('_initialize: initialized.wake() called');
|
|
374
426
|
|
|
375
427
|
this._deviceSpaceSync = {
|
|
376
428
|
processCredential: async (credential: Credential) => {
|
|
@@ -393,9 +445,10 @@ export class ServiceContext extends Resource {
|
|
|
393
445
|
|
|
394
446
|
try {
|
|
395
447
|
log('accepting space recorded in halo', { details: assertion });
|
|
396
|
-
await this.dataSpaceManager.acceptSpace({
|
|
448
|
+
await this.dataSpaceManager.acceptSpace(this._ctx, {
|
|
397
449
|
spaceKey: assertion.spaceKey,
|
|
398
450
|
genesisFeedKey: assertion.genesisFeedKey,
|
|
451
|
+
tags: assertion.tags,
|
|
399
452
|
});
|
|
400
453
|
} catch (err) {
|
|
401
454
|
log.catch(err);
|
|
@@ -406,33 +459,42 @@ export class ServiceContext extends Resource {
|
|
|
406
459
|
await identity.space.spaceState.addCredentialProcessor(this._deviceSpaceSync);
|
|
407
460
|
}
|
|
408
461
|
|
|
409
|
-
private async _setNetworkIdentity(params?: { deviceCredential
|
|
462
|
+
private async _setNetworkIdentity(params?: { deviceCredential?: Credential; identity?: Identity }): Promise<void> {
|
|
463
|
+
log('_setNetworkIdentity: acquiring mutex...');
|
|
410
464
|
using _ = await this._edgeIdentityUpdateMutex.acquire();
|
|
465
|
+
log('_setNetworkIdentity: mutex acquired');
|
|
411
466
|
|
|
412
467
|
let edgeIdentity: EdgeIdentity;
|
|
413
|
-
const identity =
|
|
468
|
+
const identity = params?.identity;
|
|
414
469
|
if (identity) {
|
|
415
|
-
log('
|
|
470
|
+
log('_setNetworkIdentity: has identity', {
|
|
416
471
|
identity: identity.identityKey.toHex(),
|
|
417
|
-
|
|
472
|
+
hasDeviceCredential: !!params?.deviceCredential,
|
|
418
473
|
});
|
|
419
474
|
|
|
420
475
|
if (params?.deviceCredential) {
|
|
476
|
+
log('_setNetworkIdentity: creating chain edge identity with device credential...');
|
|
421
477
|
edgeIdentity = await createChainEdgeIdentity(
|
|
422
478
|
identity.signer,
|
|
423
479
|
identity.identityKey,
|
|
424
480
|
identity.deviceKey,
|
|
425
|
-
|
|
481
|
+
{ credential: params.deviceCredential },
|
|
426
482
|
[], // TODO(dmaretskyi): Service access credentials.
|
|
427
483
|
);
|
|
484
|
+
log('_setNetworkIdentity: chain edge identity created');
|
|
428
485
|
} else {
|
|
486
|
+
log('_setNetworkIdentity: waiting for identity.ready()...');
|
|
429
487
|
// TODO: throw here or from identity if device chain can't be loaded, to avoid indefinite hangup
|
|
430
488
|
await warnAfterTimeout(10_000, 'Waiting for identity to be ready for edge connection', async () => {
|
|
431
489
|
await identity.ready();
|
|
432
490
|
});
|
|
491
|
+
log('_setNetworkIdentity: identity.ready() resolved', {
|
|
492
|
+
hasDeviceCredentialChain: !!identity.deviceCredentialChain,
|
|
493
|
+
});
|
|
433
494
|
|
|
434
495
|
invariant(identity.deviceCredentialChain);
|
|
435
496
|
|
|
497
|
+
log('_setNetworkIdentity: creating chain edge identity...');
|
|
436
498
|
edgeIdentity = await createChainEdgeIdentity(
|
|
437
499
|
identity.signer,
|
|
438
500
|
identity.identityKey,
|
|
@@ -440,9 +502,12 @@ export class ServiceContext extends Resource {
|
|
|
440
502
|
identity.deviceCredentialChain,
|
|
441
503
|
[], // TODO(dmaretskyi): Service access credentials.
|
|
442
504
|
);
|
|
505
|
+
log('_setNetworkIdentity: chain edge identity created');
|
|
443
506
|
}
|
|
444
507
|
} else {
|
|
508
|
+
log('_setNetworkIdentity: no identity, creating ephemeral edge identity...');
|
|
445
509
|
edgeIdentity = await createEphemeralEdgeIdentity();
|
|
510
|
+
log('_setNetworkIdentity: ephemeral edge identity created');
|
|
446
511
|
}
|
|
447
512
|
|
|
448
513
|
this._edgeConnection?.setIdentity(edgeIdentity);
|
|
@@ -451,5 +516,6 @@ export class ServiceContext extends Resource {
|
|
|
451
516
|
identityKey: edgeIdentity.identityKey,
|
|
452
517
|
peerKey: edgeIdentity.peerKey,
|
|
453
518
|
});
|
|
519
|
+
log('_setNetworkIdentity: done');
|
|
454
520
|
}
|
|
455
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
|
});
|
|
@@ -7,12 +7,11 @@ import * as Effect from 'effect/Effect';
|
|
|
7
7
|
|
|
8
8
|
import { Event, synchronized } from '@dxos/async';
|
|
9
9
|
import { type ClientServices, clientServiceBundle } from '@dxos/client-protocol';
|
|
10
|
-
import { type Config } from '@dxos/config';
|
|
10
|
+
import { type Config, resolveTelemetryTag } from '@dxos/config';
|
|
11
11
|
import { Context } from '@dxos/context';
|
|
12
12
|
import { EdgeClient, type EdgeConnection, EdgeHttpClient, createStubEdgeIdentity } from '@dxos/edge-client';
|
|
13
13
|
import { RuntimeProvider } from '@dxos/effect';
|
|
14
14
|
import { invariant } from '@dxos/invariant';
|
|
15
|
-
import { PublicKey } from '@dxos/keys';
|
|
16
15
|
import { type LevelDB } from '@dxos/kv-store';
|
|
17
16
|
import { log } from '@dxos/log';
|
|
18
17
|
import { EdgeSignalManager, type SignalManager, WebsocketSignalManager } from '@dxos/messaging';
|
|
@@ -22,12 +21,11 @@ import {
|
|
|
22
21
|
createIceProvider,
|
|
23
22
|
createRtcTransportFactory,
|
|
24
23
|
} from '@dxos/network-manager';
|
|
25
|
-
import { trace } from '@dxos/protocols';
|
|
26
24
|
import { SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
|
|
27
25
|
import { type Storage } from '@dxos/random-access-storage';
|
|
28
26
|
import * as SqlExport from '@dxos/sql-sqlite/SqlExport';
|
|
29
27
|
import type * as SqlTransaction from '@dxos/sql-sqlite/SqlTransaction';
|
|
30
|
-
import {
|
|
28
|
+
import { trace as Trace } from '@dxos/tracing';
|
|
31
29
|
import { WebsocketRpcClient } from '@dxos/websocket-rpc';
|
|
32
30
|
|
|
33
31
|
import { EdgeAgentServiceImpl } from '../agents';
|
|
@@ -47,7 +45,6 @@ import { NetworkServiceImpl } from '../network';
|
|
|
47
45
|
import { SpacesServiceImpl } from '../spaces';
|
|
48
46
|
import { createLevel, createStorageObjects } from '../storage';
|
|
49
47
|
import { SystemServiceImpl } from '../system';
|
|
50
|
-
|
|
51
48
|
import { ServiceContext, type ServiceContextRuntimeProps } from './service-context';
|
|
52
49
|
import { ServiceRegistry } from './service-registry';
|
|
53
50
|
|
|
@@ -87,8 +84,6 @@ export class ClientServicesHost {
|
|
|
87
84
|
private readonly _serviceRegistry: ServiceRegistry<ClientServices>;
|
|
88
85
|
private readonly _systemService: SystemServiceImpl;
|
|
89
86
|
private readonly _loggingService: LoggingServiceImpl;
|
|
90
|
-
private readonly _tracingService = TRACE_PROCESSOR.createTraceSender();
|
|
91
|
-
|
|
92
87
|
private readonly _statusUpdate = new Event<void>();
|
|
93
88
|
|
|
94
89
|
private _config?: Config;
|
|
@@ -147,7 +142,7 @@ export class ClientServicesHost {
|
|
|
147
142
|
void this.open(new Context());
|
|
148
143
|
}
|
|
149
144
|
},
|
|
150
|
-
onRelease: () => this.close(),
|
|
145
|
+
onRelease: () => this.close(Context.default()),
|
|
151
146
|
});
|
|
152
147
|
}
|
|
153
148
|
|
|
@@ -176,7 +171,6 @@ export class ClientServicesHost {
|
|
|
176
171
|
|
|
177
172
|
this._serviceRegistry = new ServiceRegistry<ClientServices>(clientServiceBundle, {
|
|
178
173
|
SystemService: this._systemService,
|
|
179
|
-
TracingService: this._tracingService,
|
|
180
174
|
});
|
|
181
175
|
}
|
|
182
176
|
|
|
@@ -244,9 +238,6 @@ export class ClientServicesHost {
|
|
|
244
238
|
if (this._runtimeProps.enableVectorIndexing === undefined) {
|
|
245
239
|
this._runtimeProps.enableVectorIndexing = config?.get('runtime.client.enableVectorIndexing', false);
|
|
246
240
|
}
|
|
247
|
-
if (this._runtimeProps.enableLocalQueues === undefined) {
|
|
248
|
-
this._runtimeProps.enableLocalQueues = config?.get('runtime.client.enableLocalQueues', false);
|
|
249
|
-
}
|
|
250
241
|
|
|
251
242
|
invariant(!this._config, 'config already set');
|
|
252
243
|
this._config = config;
|
|
@@ -262,8 +253,9 @@ export class ClientServicesHost {
|
|
|
262
253
|
|
|
263
254
|
const endpoint = config?.get('runtime.services.edge.url');
|
|
264
255
|
if (endpoint) {
|
|
265
|
-
|
|
266
|
-
this.
|
|
256
|
+
const clientTag = resolveTelemetryTag(config);
|
|
257
|
+
this._edgeConnection = new EdgeClient(createStubEdgeIdentity(), { socketEndpoint: endpoint, clientTag });
|
|
258
|
+
this._edgeHttpClient = new EdgeHttpClient(endpoint, { clientTag });
|
|
267
259
|
}
|
|
268
260
|
|
|
269
261
|
const {
|
|
@@ -302,8 +294,7 @@ export class ClientServicesHost {
|
|
|
302
294
|
return;
|
|
303
295
|
}
|
|
304
296
|
|
|
305
|
-
|
|
306
|
-
log.trace('dxos.client-services.host.open', trace.begin({ id: traceId }));
|
|
297
|
+
log('opening service host');
|
|
307
298
|
|
|
308
299
|
invariant(this._config, 'config not set');
|
|
309
300
|
invariant(this._storage, 'storage not set');
|
|
@@ -348,8 +339,7 @@ export class ClientServicesHost {
|
|
|
348
339
|
this._serviceContext.identityManager,
|
|
349
340
|
this._serviceContext.recoveryManager,
|
|
350
341
|
this._serviceContext.keyring,
|
|
351
|
-
() => this.
|
|
352
|
-
(params) => this._createIdentity(params),
|
|
342
|
+
(params, ctx) => this._createIdentity(params, ctx),
|
|
353
343
|
(profile) => this._serviceContext.broadcastProfileUpdate(profile),
|
|
354
344
|
);
|
|
355
345
|
|
|
@@ -369,6 +359,7 @@ export class ClientServicesHost {
|
|
|
369
359
|
SpacesService: new SpacesServiceImpl(
|
|
370
360
|
this._serviceContext.identityManager,
|
|
371
361
|
this._serviceContext.spaceManager,
|
|
362
|
+
this._serviceContext.echoHost,
|
|
372
363
|
dataSpaceManagerProvider,
|
|
373
364
|
),
|
|
374
365
|
|
|
@@ -383,7 +374,6 @@ export class ClientServicesHost {
|
|
|
383
374
|
),
|
|
384
375
|
|
|
385
376
|
LoggingService: this._loggingService,
|
|
386
|
-
TracingService: this._tracingService,
|
|
387
377
|
|
|
388
378
|
// TODO(burdon): Move to new protobuf definitions.
|
|
389
379
|
DevtoolsHost: new DevtoolsServiceImpl({
|
|
@@ -395,8 +385,13 @@ export class ClientServicesHost {
|
|
|
395
385
|
EdgeAgentService: new EdgeAgentServiceImpl(agentManagerProvider, this._edgeConnection),
|
|
396
386
|
});
|
|
397
387
|
|
|
388
|
+
log('service-host: opening service context...');
|
|
398
389
|
await this._serviceContext.open(ctx);
|
|
390
|
+
log('service-host: service context opened');
|
|
391
|
+
|
|
392
|
+
log('service-host: opening identity service...');
|
|
399
393
|
await identityService.open();
|
|
394
|
+
log('service-host: identity service opened');
|
|
400
395
|
|
|
401
396
|
const devtoolsProxy = this._config?.get('runtime.client.devtoolsProxy');
|
|
402
397
|
if (devtoolsProxy) {
|
|
@@ -415,12 +410,11 @@ export class ClientServicesHost {
|
|
|
415
410
|
this._statusUpdate.emit();
|
|
416
411
|
const deviceKey = this._serviceContext.identityManager.identity?.deviceKey;
|
|
417
412
|
log('opened', { deviceKey });
|
|
418
|
-
log.trace('dxos.client-services.host.open', trace.end({ id: traceId }));
|
|
419
413
|
}
|
|
420
414
|
|
|
421
415
|
@synchronized
|
|
422
416
|
@Trace.span()
|
|
423
|
-
async close(): Promise<void> {
|
|
417
|
+
async close(ctx: Context): Promise<void> {
|
|
424
418
|
if (!this._open) {
|
|
425
419
|
return;
|
|
426
420
|
}
|
|
@@ -439,9 +433,6 @@ export class ClientServicesHost {
|
|
|
439
433
|
}
|
|
440
434
|
|
|
441
435
|
async reset(): Promise<void> {
|
|
442
|
-
const traceId = PublicKey.random().toHex();
|
|
443
|
-
log.trace('dxos.sdk.client-services-host.reset', trace.begin({ id: traceId }));
|
|
444
|
-
|
|
445
436
|
log.info('resetting...');
|
|
446
437
|
// Emit this status update immediately so app returns to fallback.
|
|
447
438
|
// This state is never cleared because the app reloads.
|
|
@@ -456,12 +447,11 @@ export class ClientServicesHost {
|
|
|
456
447
|
}
|
|
457
448
|
await this._storage!.reset();
|
|
458
449
|
log.info('reset');
|
|
459
|
-
log.trace('dxos.sdk.client-services-host.reset', trace.end({ id: traceId }));
|
|
460
450
|
await this._callbacks?.onReset?.();
|
|
461
451
|
}
|
|
462
452
|
|
|
463
|
-
private async _createIdentity(params: CreateIdentityOptions) {
|
|
464
|
-
const identity = await this._serviceContext.createIdentity(params);
|
|
453
|
+
private async _createIdentity(params: CreateIdentityOptions, ctx?: Context) {
|
|
454
|
+
const identity = await this._serviceContext.createIdentity(params, ctx);
|
|
465
455
|
await this._serviceContext.initialized.wait();
|
|
466
456
|
return identity;
|
|
467
457
|
}
|
|
@@ -15,7 +15,6 @@ import { createLinkedPorts, createProtoRpcPeer, createServiceBundle } from '@dxo
|
|
|
15
15
|
|
|
16
16
|
import { SystemServiceImpl } from '../system';
|
|
17
17
|
import { createServiceContext } from '../testing';
|
|
18
|
-
|
|
19
18
|
import { ServiceRegistry } from './service-registry';
|
|
20
19
|
|
|
21
20
|
// TODO(burdon): Create TestService (that doesn't require peers).
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { SpaceArchive } from '@dxos/protocols/proto/dxos/client/services';
|
|
6
|
+
|
|
7
|
+
const JSON_EXTENSIONS = ['.dx.json', '.dx.json.gz', '.json'];
|
|
8
|
+
const BINARY_EXTENSIONS = ['.tar', '.tar.gz'];
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Detect the format of a space archive.
|
|
12
|
+
*
|
|
13
|
+
* Uses filename extension as the primary signal, and falls back to sniffing
|
|
14
|
+
* the first bytes of the archive contents to distinguish JSON from tar.
|
|
15
|
+
*/
|
|
16
|
+
export const detectSpaceArchiveFormat = (archive: Pick<SpaceArchive, 'filename' | 'contents'>): SpaceArchive.Format => {
|
|
17
|
+
const filename = archive.filename?.toLowerCase() ?? '';
|
|
18
|
+
if (JSON_EXTENSIONS.some((ext) => filename.endsWith(ext))) {
|
|
19
|
+
return SpaceArchive.Format.JSON;
|
|
20
|
+
}
|
|
21
|
+
if (BINARY_EXTENSIONS.some((ext) => filename.endsWith(ext))) {
|
|
22
|
+
return SpaceArchive.Format.BINARY;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Fall back to byte sniffing: JSON archives start with '{' (0x7B) or whitespace.
|
|
26
|
+
const bytes = archive.contents;
|
|
27
|
+
if (bytes && bytes.length > 0) {
|
|
28
|
+
for (let i = 0; i < Math.min(bytes.length, 16); i++) {
|
|
29
|
+
const byte = bytes[i];
|
|
30
|
+
// Skip whitespace.
|
|
31
|
+
if (byte === 0x20 || byte === 0x09 || byte === 0x0a || byte === 0x0d) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (byte === 0x7b /* '{' */) {
|
|
35
|
+
return SpaceArchive.Format.JSON;
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return SpaceArchive.Format.BINARY;
|
|
42
|
+
};
|
|
@@ -2,5 +2,8 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
export * from './
|
|
5
|
+
export * from './archive-format';
|
|
6
|
+
export * from './serialized-space-reader';
|
|
7
|
+
export * from './serialized-space-writer';
|
|
6
8
|
export * from './space-archive-reader';
|
|
9
|
+
export * from './space-archive-writer';
|