@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
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
import type { AutomergeUrl } from '@automerge/automerge-repo';
|
|
6
6
|
|
|
7
7
|
import { SubscriptionList, UpdateScheduler, scheduleTask } from '@dxos/async';
|
|
8
|
+
import { type RequestOptions } from '@dxos/codec-protobuf';
|
|
8
9
|
import { Stream } from '@dxos/codec-protobuf/stream';
|
|
10
|
+
import { Context } from '@dxos/context';
|
|
9
11
|
import {
|
|
10
12
|
type CredentialProcessor,
|
|
11
13
|
createAdmissionCredentials,
|
|
@@ -13,7 +15,8 @@ import {
|
|
|
13
15
|
getCredentialAssertion,
|
|
14
16
|
} from '@dxos/credentials';
|
|
15
17
|
import { raise } from '@dxos/debug';
|
|
16
|
-
import { type SpaceManager } from '@dxos/echo-pipeline';
|
|
18
|
+
import { type EchoHost, type SpaceManager } from '@dxos/echo-pipeline';
|
|
19
|
+
import { type DatabaseDirectory } from '@dxos/echo-protocol';
|
|
17
20
|
import { writeMessages } from '@dxos/feed-store';
|
|
18
21
|
import { assertArgument, assertState, invariant } from '@dxos/invariant';
|
|
19
22
|
import { SpaceId } from '@dxos/keys';
|
|
@@ -21,6 +24,7 @@ import { log } from '@dxos/log';
|
|
|
21
24
|
import {
|
|
22
25
|
ApiError,
|
|
23
26
|
AuthorizationError,
|
|
27
|
+
FeedProtocol,
|
|
24
28
|
IdentityNotInitializedError,
|
|
25
29
|
SpaceNotFoundError,
|
|
26
30
|
encodeError,
|
|
@@ -40,11 +44,13 @@ import {
|
|
|
40
44
|
type QueryCredentialsRequest,
|
|
41
45
|
type QuerySpacesResponse,
|
|
42
46
|
type Space,
|
|
47
|
+
SpaceArchive,
|
|
43
48
|
SpaceMember,
|
|
44
49
|
SpaceState,
|
|
45
50
|
type SpacesService,
|
|
46
51
|
type SubscribeMessagesRequest,
|
|
47
52
|
type UpdateMemberRoleRequest,
|
|
53
|
+
type CreateSpaceRequest,
|
|
48
54
|
type UpdateSpaceRequest,
|
|
49
55
|
type WriteCredentialsRequest,
|
|
50
56
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
@@ -54,8 +60,14 @@ import { trace } from '@dxos/tracing';
|
|
|
54
60
|
import { type Provider } from '@dxos/util';
|
|
55
61
|
|
|
56
62
|
import { type IdentityManager } from '../identity';
|
|
57
|
-
import {
|
|
58
|
-
|
|
63
|
+
import {
|
|
64
|
+
SpaceArchiveWriter,
|
|
65
|
+
detectSpaceArchiveFormat,
|
|
66
|
+
extractSpaceArchive,
|
|
67
|
+
readSerializedSpaceArchive,
|
|
68
|
+
writeSerializedSpaceArchive,
|
|
69
|
+
objJsonToObjectStructure,
|
|
70
|
+
} from '../space-export';
|
|
59
71
|
import { type DataSpace } from './data-space';
|
|
60
72
|
import { type DataSpaceManager } from './data-space-manager';
|
|
61
73
|
|
|
@@ -63,29 +75,35 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
63
75
|
constructor(
|
|
64
76
|
private readonly _identityManager: IdentityManager,
|
|
65
77
|
private readonly _spaceManager: SpaceManager,
|
|
78
|
+
private readonly _echoHost: EchoHost,
|
|
66
79
|
private readonly _getDataSpaceManager: Provider<Promise<DataSpaceManager>>,
|
|
67
80
|
) {}
|
|
68
81
|
|
|
69
|
-
async createSpace(): Promise<Space> {
|
|
82
|
+
async createSpace(request: CreateSpaceRequest, options?: RequestOptions): Promise<Space> {
|
|
70
83
|
this._requireIdentity();
|
|
84
|
+
const ctx = options?.ctx ?? new Context();
|
|
71
85
|
const dataSpaceManager = await this._getDataSpaceManager();
|
|
72
|
-
const space = await dataSpaceManager.createSpace(
|
|
86
|
+
const space = await dataSpaceManager.createSpace(ctx, {
|
|
87
|
+
tags: request?.tags,
|
|
88
|
+
membershipPolicy: request?.membershipPolicy,
|
|
89
|
+
});
|
|
73
90
|
await this._updateMetrics();
|
|
74
91
|
return this._serializeSpace(space);
|
|
75
92
|
}
|
|
76
93
|
|
|
77
|
-
async updateSpace({ spaceKey, state, edgeReplication }: UpdateSpaceRequest): Promise<void> {
|
|
94
|
+
async updateSpace({ spaceKey, state, edgeReplication }: UpdateSpaceRequest, options?: RequestOptions): Promise<void> {
|
|
95
|
+
const ctx = options?.ctx ?? Context.default();
|
|
78
96
|
const dataSpaceManager = await this._getDataSpaceManager();
|
|
79
97
|
const space = dataSpaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));
|
|
80
98
|
|
|
81
99
|
if (state) {
|
|
82
100
|
switch (state) {
|
|
83
101
|
case SpaceState.SPACE_ACTIVE:
|
|
84
|
-
await space.activate();
|
|
102
|
+
await space.activate(ctx);
|
|
85
103
|
break;
|
|
86
104
|
|
|
87
105
|
case SpaceState.SPACE_INACTIVE:
|
|
88
|
-
await space.deactivate();
|
|
106
|
+
await space.deactivate(ctx);
|
|
89
107
|
break;
|
|
90
108
|
default:
|
|
91
109
|
throw new ApiError({ message: 'Invalid space state' });
|
|
@@ -93,7 +111,7 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
93
111
|
}
|
|
94
112
|
|
|
95
113
|
if (edgeReplication !== undefined) {
|
|
96
|
-
await dataSpaceManager.setSpaceEdgeReplicationSetting(spaceKey, edgeReplication);
|
|
114
|
+
await dataSpaceManager.setSpaceEdgeReplicationSetting(ctx, spaceKey, edgeReplication);
|
|
97
115
|
}
|
|
98
116
|
}
|
|
99
117
|
|
|
@@ -262,18 +280,26 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
262
280
|
});
|
|
263
281
|
}
|
|
264
282
|
|
|
265
|
-
async joinBySpaceKey({ spaceKey }: JoinBySpaceKeyRequest): Promise<JoinSpaceResponse> {
|
|
283
|
+
async joinBySpaceKey({ spaceKey }: JoinBySpaceKeyRequest, options?: RequestOptions): Promise<JoinSpaceResponse> {
|
|
284
|
+
const ctx = options?.ctx ?? Context.default();
|
|
266
285
|
const dataSpaceManager = await this._getDataSpaceManager();
|
|
267
|
-
const credential = await dataSpaceManager.requestSpaceAdmissionCredential(spaceKey);
|
|
268
|
-
return this._joinByAdmission({ credential });
|
|
286
|
+
const credential = await dataSpaceManager.requestSpaceAdmissionCredential(ctx, spaceKey);
|
|
287
|
+
return this._joinByAdmission(ctx, { credential });
|
|
269
288
|
}
|
|
270
289
|
|
|
271
290
|
async exportSpace(request: ExportSpaceRequest): Promise<ExportSpaceResponse> {
|
|
272
|
-
await using writer = await new SpaceArchiveWriter().open();
|
|
273
291
|
assertArgument(SpaceId.isValid(request.spaceId), 'spaceId', 'Invalid space ID');
|
|
274
292
|
|
|
275
293
|
const dataSpaceManager = await this._getDataSpaceManager();
|
|
276
294
|
const space = dataSpaceManager.getSpaceById(request.spaceId) ?? raise(new Error('Space not found'));
|
|
295
|
+
|
|
296
|
+
const format = request.format ?? SpaceArchive.Format.BINARY;
|
|
297
|
+
if (format === SpaceArchive.Format.JSON) {
|
|
298
|
+
const archive = await writeSerializedSpaceArchive({ space, echoHost: this._echoHost });
|
|
299
|
+
return { archive };
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
await using writer = await new SpaceArchiveWriter().open();
|
|
277
303
|
await writer.begin({ spaceId: space.id });
|
|
278
304
|
const rootUrl = space.automergeSpaceState.lastEpoch?.subject.assertion.automergeRoot;
|
|
279
305
|
assertState(rootUrl, 'Space does not have a root URL');
|
|
@@ -283,23 +309,92 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
283
309
|
await writer.writeDocument(documentId, data);
|
|
284
310
|
}
|
|
285
311
|
|
|
312
|
+
const feeds = await space.getAllFeeds();
|
|
313
|
+
for (const feed of feeds) {
|
|
314
|
+
const archiveBlocks = feed.blocks.map((block) => ({
|
|
315
|
+
actorId: block.actorId,
|
|
316
|
+
sequence: block.sequence,
|
|
317
|
+
prevActorId: block.prevActorId,
|
|
318
|
+
prevSequence: block.prevSequence,
|
|
319
|
+
position: block.position,
|
|
320
|
+
timestamp: block.timestamp,
|
|
321
|
+
data: Buffer.from(block.data).toString('base64'),
|
|
322
|
+
}));
|
|
323
|
+
await writer.writeFeed(feed.feedId, feed.feedNamespace, archiveBlocks);
|
|
324
|
+
}
|
|
325
|
+
|
|
286
326
|
const archive = await writer.finish();
|
|
287
327
|
return { archive };
|
|
288
328
|
}
|
|
289
329
|
|
|
290
|
-
async importSpace(request: ImportSpaceRequest): Promise<ImportSpaceResponse> {
|
|
330
|
+
async importSpace(request: ImportSpaceRequest, options?: RequestOptions): Promise<ImportSpaceResponse> {
|
|
331
|
+
const ctx = options?.ctx ?? Context.default();
|
|
291
332
|
const dataSpaceManager = await this._getDataSpaceManager();
|
|
333
|
+
|
|
334
|
+
const format = request.archive.format ?? detectSpaceArchiveFormat(request.archive);
|
|
335
|
+
if (format === SpaceArchive.Format.JSON) {
|
|
336
|
+
const serialized = readSerializedSpaceArchive(request.archive);
|
|
337
|
+
const space = await dataSpaceManager.createSpace(ctx, { tags: request.tags });
|
|
338
|
+
await this._hydrateSpaceFromSerialized(space, serialized);
|
|
339
|
+
await this._updateMetrics();
|
|
340
|
+
return { newSpaceId: space.id };
|
|
341
|
+
}
|
|
342
|
+
|
|
292
343
|
const extracted = await extractSpaceArchive(request.archive);
|
|
293
344
|
invariant(extracted.metadata.echo?.currentRootUrl, 'Space archive does not contain a root URL');
|
|
294
|
-
const space = await dataSpaceManager.createSpace({
|
|
345
|
+
const space = await dataSpaceManager.createSpace(ctx, {
|
|
295
346
|
documents: extracted.documents,
|
|
296
347
|
rootUrl: extracted.metadata.echo?.currentRootUrl as AutomergeUrl,
|
|
348
|
+
tags: request.tags,
|
|
297
349
|
});
|
|
298
350
|
await this._updateMetrics();
|
|
299
351
|
return { newSpaceId: space.id };
|
|
300
352
|
}
|
|
301
353
|
|
|
302
|
-
|
|
354
|
+
/**
|
|
355
|
+
* Populate a freshly-created space with the objects and feed messages described in a {@link SerializedSpace}.
|
|
356
|
+
*
|
|
357
|
+
* Objects are written directly into the space's automerge root document as inline
|
|
358
|
+
* {@link ObjectStructure} entries; feed messages are appended to the appropriate queue
|
|
359
|
+
* via {@link EchoHost.queuesService}.
|
|
360
|
+
*/
|
|
361
|
+
private async _hydrateSpaceFromSerialized(
|
|
362
|
+
space: DataSpace,
|
|
363
|
+
serialized: ReturnType<typeof readSerializedSpaceArchive>,
|
|
364
|
+
): Promise<void> {
|
|
365
|
+
const databaseRoot = space.databaseRoot;
|
|
366
|
+
assertState(databaseRoot, 'Space database root is not ready');
|
|
367
|
+
|
|
368
|
+
databaseRoot.handle.change((doc: DatabaseDirectory) => {
|
|
369
|
+
if (!doc.objects) {
|
|
370
|
+
doc.objects = {};
|
|
371
|
+
}
|
|
372
|
+
for (const obj of serialized.objects) {
|
|
373
|
+
doc.objects[obj.id] = objJsonToObjectStructure(obj);
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
for (const feed of serialized.feeds ?? []) {
|
|
378
|
+
if (feed.messages.length === 0) {
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const namespace =
|
|
383
|
+
feed.namespace === 'trace' ? FeedProtocol.WellKnownNamespaces.trace : FeedProtocol.WellKnownNamespaces.data;
|
|
384
|
+
try {
|
|
385
|
+
await this._echoHost.queuesService.insertIntoQueue({
|
|
386
|
+
spaceId: space.id,
|
|
387
|
+
queueId: feed.feedObjectId,
|
|
388
|
+
subspaceTag: namespace,
|
|
389
|
+
objects: feed.messages.map((message) => JSON.stringify(message)),
|
|
390
|
+
});
|
|
391
|
+
} catch (err) {
|
|
392
|
+
log.warn('failed to import feed data', { feedObjectId: feed.feedObjectId, error: err });
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
private async _joinByAdmission(ctx: Context, { credential }: ContactAdmission): Promise<JoinSpaceResponse> {
|
|
303
398
|
const assertion = getCredentialAssertion(credential);
|
|
304
399
|
invariant(assertion['@type'] === 'dxos.halo.credentials.SpaceMember', 'Invalid credential');
|
|
305
400
|
const myIdentity = this._identityManager.identity;
|
|
@@ -308,9 +403,10 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
308
403
|
const dataSpaceManager = await this._getDataSpaceManager();
|
|
309
404
|
let dataSpace = dataSpaceManager.spaces.get(assertion.spaceKey);
|
|
310
405
|
if (!dataSpace) {
|
|
311
|
-
dataSpace = await dataSpaceManager.acceptSpace({
|
|
406
|
+
dataSpace = await dataSpaceManager.acceptSpace(ctx, {
|
|
312
407
|
spaceKey: assertion.spaceKey,
|
|
313
408
|
genesisFeedKey: assertion.genesisFeedKey,
|
|
409
|
+
tags: assertion.tags,
|
|
314
410
|
});
|
|
315
411
|
await myIdentity.controlPipeline.writer.write({ credential: { credential } });
|
|
316
412
|
}
|
|
@@ -363,6 +459,8 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
363
459
|
}),
|
|
364
460
|
),
|
|
365
461
|
creator: space.inner.spaceState.creator?.key,
|
|
462
|
+
tags: space.tags,
|
|
463
|
+
membershipPolicy: space.membershipPolicy,
|
|
366
464
|
cache: space.cache,
|
|
367
465
|
metrics: space.metrics,
|
|
368
466
|
edgeReplication: space.getEdgeReplicationSetting(),
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { Trigger } from '@dxos/async';
|
|
6
6
|
import { type AuthenticatingInvitation, type CancellableInvitation, InvitationEncoder } from '@dxos/client-protocol';
|
|
7
|
+
import { Context } from '@dxos/context';
|
|
7
8
|
import { invariant } from '@dxos/invariant';
|
|
8
9
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
9
10
|
import { type DeviceProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
@@ -229,7 +230,7 @@ export const createInvitation = async (
|
|
|
229
230
|
};
|
|
230
231
|
|
|
231
232
|
if (host instanceof ServiceContext) {
|
|
232
|
-
return host.invitationsManager.createInvitation({
|
|
233
|
+
return host.invitationsManager.createInvitation(new Context(), {
|
|
233
234
|
kind: Invitation.Kind.SPACE,
|
|
234
235
|
...options,
|
|
235
236
|
});
|
|
@@ -246,7 +247,7 @@ export const acceptInvitation = (
|
|
|
246
247
|
invitation = sanitizeInvitation(invitation);
|
|
247
248
|
|
|
248
249
|
if (guest instanceof ServiceContext) {
|
|
249
|
-
return guest.invitationsManager.acceptInvitation({
|
|
250
|
+
return guest.invitationsManager.acceptInvitation(new Context(), {
|
|
250
251
|
invitation,
|
|
251
252
|
deviceProfile: guestDeviceProfile,
|
|
252
253
|
});
|
|
@@ -29,7 +29,6 @@ import * as SqlTransaction from '@dxos/sql-sqlite/SqlTransaction';
|
|
|
29
29
|
import { type MaybePromise } from '@dxos/util';
|
|
30
30
|
|
|
31
31
|
import { ClientServicesHost } from '../services';
|
|
32
|
-
|
|
33
32
|
import { WorkerSession } from './worker-session';
|
|
34
33
|
|
|
35
34
|
// NOTE: Keep as RpcPorts to avoid dependency on @dxos/rpc-tunnel so we don't depend on browser-specific apis.
|
|
@@ -131,20 +130,32 @@ export class WorkerRuntime {
|
|
|
131
130
|
async start(): Promise<void> {
|
|
132
131
|
log('starting...');
|
|
133
132
|
try {
|
|
133
|
+
log('worker-runtime: acquiring liveness lock (background)');
|
|
134
134
|
void this._livenessLock.acquire();
|
|
135
135
|
|
|
136
136
|
// Steal the lock from the other worker.
|
|
137
|
+
log('worker-runtime: broadcasting stop to displace previous worker');
|
|
137
138
|
this._broadcastChannel = new BroadcastChannel(this._channel);
|
|
138
139
|
this._broadcastChannel.postMessage({ action: 'stop' });
|
|
139
140
|
this._broadcastChannel.onmessage = async (event) => {
|
|
140
141
|
if (event.data?.action === 'stop') {
|
|
142
|
+
log('worker-runtime: received stop broadcast');
|
|
141
143
|
await this.stop();
|
|
142
144
|
}
|
|
143
145
|
};
|
|
144
146
|
|
|
147
|
+
log('worker-runtime: acquiring storage lock');
|
|
145
148
|
await this._acquireLock();
|
|
149
|
+
log('worker-runtime: storage lock acquired, resolving config');
|
|
146
150
|
this._config = await this._configProvider();
|
|
151
|
+
log('worker-runtime: config resolved');
|
|
152
|
+
this._signalTelemetryEnabled = this._config.get('runtime.client.signalTelemetryEnabled') ?? false;
|
|
153
|
+
const observabilityGroup = this._config.get('runtime.client.observabilityGroup');
|
|
154
|
+
if (observabilityGroup) {
|
|
155
|
+
this._signalMetadataTags.group = observabilityGroup;
|
|
156
|
+
}
|
|
147
157
|
const signals = this._config.get('runtime.services.signaling');
|
|
158
|
+
log('worker-runtime: initializing client services host');
|
|
148
159
|
this._clientServices.initialize({
|
|
149
160
|
config: this._config,
|
|
150
161
|
signalManager: this._config.get('runtime.client.edgeFeatures')?.signaling
|
|
@@ -154,8 +165,10 @@ export class WorkerRuntime {
|
|
|
154
165
|
: new MemorySignalManager(new MemorySignalManagerContext()), // TODO(dmaretskyi): Inject this context.
|
|
155
166
|
transportFactory: this._transportFactory,
|
|
156
167
|
});
|
|
168
|
+
log('worker-runtime: client services host initialized, opening');
|
|
157
169
|
|
|
158
170
|
await this._clientServices.open(new Context());
|
|
171
|
+
log('worker-runtime: client services host opened, signalling ready');
|
|
159
172
|
this._ready.wake(undefined);
|
|
160
173
|
log('started');
|
|
161
174
|
setIdentityTags({
|
|
@@ -176,12 +189,36 @@ export class WorkerRuntime {
|
|
|
176
189
|
this._releaseLock();
|
|
177
190
|
this._broadcastChannel?.close();
|
|
178
191
|
this._broadcastChannel = undefined;
|
|
179
|
-
await this._clientServices.close();
|
|
192
|
+
await this._clientServices.close(Context.default());
|
|
180
193
|
await this._runtime.dispose();
|
|
181
194
|
await this._onStop?.();
|
|
182
195
|
await this._livenessLock.release();
|
|
183
196
|
}
|
|
184
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Update signaling telemetry tags from a client-supplied config overlay.
|
|
200
|
+
*
|
|
201
|
+
* The worker services outlive individual client connections, so the first client seeds the
|
|
202
|
+
* worker's core config (storage, signaling, edge features). For fields that can legitimately
|
|
203
|
+
* differ per tab — `observabilityGroup` and `signalTelemetryEnabled` — this method lets later
|
|
204
|
+
* connections refresh the signal metadata the worker attaches to its signaling requests
|
|
205
|
+
* (last-writer-wins, matching the pre-DX-930 per-session RPC behaviour).
|
|
206
|
+
*/
|
|
207
|
+
updateSignalMetadata(config: Config): void {
|
|
208
|
+
const observabilityGroup = config.get('runtime.client.observabilityGroup');
|
|
209
|
+
if (observabilityGroup) {
|
|
210
|
+
this._signalMetadataTags.group = observabilityGroup;
|
|
211
|
+
} else {
|
|
212
|
+
// Clear stale group so a later config that removes observabilityGroup stops attributing
|
|
213
|
+
// telemetry to the previous client's group (last-writer-wins).
|
|
214
|
+
delete this._signalMetadataTags.group;
|
|
215
|
+
}
|
|
216
|
+
const signalTelemetryEnabled = config.get('runtime.client.signalTelemetryEnabled');
|
|
217
|
+
if (signalTelemetryEnabled !== undefined) {
|
|
218
|
+
this._signalTelemetryEnabled = signalTelemetryEnabled;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
185
222
|
/**
|
|
186
223
|
* Create a new session.
|
|
187
224
|
*/
|
|
@@ -214,10 +251,6 @@ export class WorkerRuntime {
|
|
|
214
251
|
!this._signalMetadataTags.origin || this._signalMetadataTags.origin === session.origin,
|
|
215
252
|
`worker origin changed from ${this._signalMetadataTags.origin} to ${session.origin}?`,
|
|
216
253
|
);
|
|
217
|
-
if (session.observabilityGroup) {
|
|
218
|
-
this._signalMetadataTags.group = session.observabilityGroup;
|
|
219
|
-
}
|
|
220
|
-
this._signalTelemetryEnabled = session.signalTelemetryEnabled ?? false;
|
|
221
254
|
this._signalMetadataTags.origin = session.origin;
|
|
222
255
|
this._sessions.add(session);
|
|
223
256
|
|
|
@@ -41,10 +41,6 @@ export class WorkerSession {
|
|
|
41
41
|
@logInfo
|
|
42
42
|
public origin?: string;
|
|
43
43
|
|
|
44
|
-
// TODO(nf): factor out?
|
|
45
|
-
public observabilityGroup?: string;
|
|
46
|
-
public signalTelemetryEnabled?: boolean;
|
|
47
|
-
|
|
48
44
|
@logInfo
|
|
49
45
|
public lockKey?: string;
|
|
50
46
|
|
|
@@ -55,21 +51,21 @@ export class WorkerSession {
|
|
|
55
51
|
this._serviceHost = serviceHost;
|
|
56
52
|
|
|
57
53
|
const middleware: Pick<ClientRpcServerProps, 'handleCall' | 'handleStream'> = {
|
|
58
|
-
handleCall: async (method, params, handler) => {
|
|
54
|
+
handleCall: async (method, params, handler, options) => {
|
|
59
55
|
const error = await readySignal.wait({ timeout: PROXY_CONNECTION_TIMEOUT });
|
|
60
56
|
if (error) {
|
|
61
57
|
throw error;
|
|
62
58
|
}
|
|
63
59
|
|
|
64
|
-
return handler(method, params);
|
|
60
|
+
return handler(method, params, options);
|
|
65
61
|
},
|
|
66
|
-
handleStream: async (method, params, handler) => {
|
|
62
|
+
handleStream: async (method, params, handler, options) => {
|
|
67
63
|
const error = await readySignal.wait({ timeout: PROXY_CONNECTION_TIMEOUT });
|
|
68
64
|
if (error) {
|
|
69
65
|
throw error;
|
|
70
66
|
}
|
|
71
67
|
|
|
72
|
-
return handler(method, params);
|
|
68
|
+
return handler(method, params, options);
|
|
73
69
|
},
|
|
74
70
|
};
|
|
75
71
|
|
|
@@ -95,8 +91,6 @@ export class WorkerSession {
|
|
|
95
91
|
start: async (request) => {
|
|
96
92
|
this.origin = request.origin;
|
|
97
93
|
this.lockKey = request.lockKey;
|
|
98
|
-
this.observabilityGroup = request.observabilityGroup;
|
|
99
|
-
this.signalTelemetryEnabled = request.signalTelemetryEnabled;
|
|
100
94
|
this._startTrigger.wake();
|
|
101
95
|
},
|
|
102
96
|
|
|
@@ -119,7 +113,7 @@ export class WorkerSession {
|
|
|
119
113
|
}
|
|
120
114
|
|
|
121
115
|
async open(): Promise<void> {
|
|
122
|
-
log
|
|
116
|
+
log('opening...');
|
|
123
117
|
await Promise.all([this._clientRpc.open(), this._iframeRpc.open(), this._maybeOpenShell()]);
|
|
124
118
|
|
|
125
119
|
// Wait until the worker's RPC service has started.
|
|
@@ -130,11 +124,11 @@ export class WorkerSession {
|
|
|
130
124
|
void this._afterLockReleases(this.lockKey, () => this.close());
|
|
131
125
|
}
|
|
132
126
|
|
|
133
|
-
log
|
|
127
|
+
log('opened');
|
|
134
128
|
}
|
|
135
129
|
|
|
136
130
|
async close(): Promise<void> {
|
|
137
|
-
log.
|
|
131
|
+
log.debug('closing...');
|
|
138
132
|
try {
|
|
139
133
|
await this.onClose.callIfSet();
|
|
140
134
|
} catch (err: any) {
|
|
@@ -142,7 +136,7 @@ export class WorkerSession {
|
|
|
142
136
|
}
|
|
143
137
|
|
|
144
138
|
await Promise.all([this._clientRpc.close(), this._iframeRpc.close()]);
|
|
145
|
-
log.
|
|
139
|
+
log.debug('closed');
|
|
146
140
|
}
|
|
147
141
|
|
|
148
142
|
private async _maybeOpenShell(): Promise<void> {
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const DXOS_VERSION = "0.8.4-main.
|
|
1
|
+
export const DXOS_VERSION = "0.8.4-main.f466a3d56e";
|