@dxos/client-services 0.8.4-main.3eb6e50203 → 0.8.4-main.3fbcb4aa9b
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/dist/lib/browser/{chunk-675YEKTQ.mjs → chunk-OBWND4JJ.mjs} +1701 -3078
- package/dist/lib/browser/chunk-OBWND4JJ.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-RUUAV2BD.mjs → chunk-PB2SRGWV.mjs} +1701 -3078
- package/dist/lib/node-esm/chunk-PB2SRGWV.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 +18 -12
- 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 +42 -49
- 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 +98 -41
- 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 +75 -111
- package/src/packlets/spaces/data-space.ts +49 -29
- 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 +3 -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 +113 -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-675YEKTQ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-RUUAV2BD.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,6 +5,7 @@
|
|
|
5
5
|
import { describe, expect, test } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import { asyncTimeout, latch } from '@dxos/async';
|
|
8
|
+
import { Context } from '@dxos/context';
|
|
8
9
|
import { createAdmissionCredentials } from '@dxos/credentials';
|
|
9
10
|
import { AuthStatus } from '@dxos/echo-pipeline';
|
|
10
11
|
import { writeMessages } from '@dxos/feed-store';
|
|
@@ -22,7 +23,7 @@ describe('DataSpaceManager', () => {
|
|
|
22
23
|
await peer.createIdentity();
|
|
23
24
|
await openAndClose(peer.echoHost, peer.dataSpaceManager);
|
|
24
25
|
|
|
25
|
-
const space = await peer.dataSpaceManager.createSpace();
|
|
26
|
+
const space = await peer.dataSpaceManager.createSpace(new Context());
|
|
26
27
|
|
|
27
28
|
// Process all written mutations.
|
|
28
29
|
await space.inner.controlPipeline.state.waitUntilTimeframe(space.inner.controlPipeline.state.endTimeframe);
|
|
@@ -45,7 +46,7 @@ describe('DataSpaceManager', () => {
|
|
|
45
46
|
await openAndClose(peer1.echoHost, peer1.dataSpaceManager, peer2.echoHost, peer2.dataSpaceManager);
|
|
46
47
|
await connectReplicators([peer1, peer2]);
|
|
47
48
|
|
|
48
|
-
const space1 = await peer1.dataSpaceManager.createSpace();
|
|
49
|
+
const space1 = await peer1.dataSpaceManager.createSpace(new Context());
|
|
49
50
|
await space1.inner.controlPipeline.state.waitUntilTimeframe(space1.inner.controlPipeline.state.endTimeframe);
|
|
50
51
|
|
|
51
52
|
// Admit peer2 to space1.
|
|
@@ -60,7 +61,7 @@ describe('DataSpaceManager', () => {
|
|
|
60
61
|
);
|
|
61
62
|
|
|
62
63
|
// Accept must be called after admission so that the peer can authenticate for notarization.
|
|
63
|
-
const space2 = await peer2.dataSpaceManager.acceptSpace({
|
|
64
|
+
const space2 = await peer2.dataSpaceManager.acceptSpace(new Context(), {
|
|
64
65
|
spaceKey: space1.key,
|
|
65
66
|
genesisFeedKey: space1.inner.genesisFeedKey,
|
|
66
67
|
});
|
|
@@ -115,7 +116,7 @@ describe('DataSpaceManager', () => {
|
|
|
115
116
|
await openAndClose(peer1.echoHost, peer1.dataSpaceManager, peer2.echoHost, peer2.dataSpaceManager);
|
|
116
117
|
await connectReplicators([peer1, peer2]);
|
|
117
118
|
|
|
118
|
-
const space1 = await peer1.dataSpaceManager.createSpace();
|
|
119
|
+
const space1 = await peer1.dataSpaceManager.createSpace(new Context());
|
|
119
120
|
await space1.inner.controlPipeline.state.waitUntilTimeframe(space1.inner.controlPipeline.state.endTimeframe);
|
|
120
121
|
|
|
121
122
|
// Admit peer2 to space1.
|
|
@@ -130,7 +131,7 @@ describe('DataSpaceManager', () => {
|
|
|
130
131
|
);
|
|
131
132
|
|
|
132
133
|
// Accept must be called after admission so that the peer can authenticate for notarization.
|
|
133
|
-
const space2 = await peer2.dataSpaceManager.acceptSpace({
|
|
134
|
+
const space2 = await peer2.dataSpaceManager.acceptSpace(new Context(), {
|
|
134
135
|
spaceKey: space1.key,
|
|
135
136
|
genesisFeedKey: space1.inner.genesisFeedKey,
|
|
136
137
|
});
|
|
@@ -149,6 +150,71 @@ describe('DataSpaceManager', () => {
|
|
|
149
150
|
await receivedMessage();
|
|
150
151
|
});
|
|
151
152
|
|
|
153
|
+
test('create space with tags', async () => {
|
|
154
|
+
const builder = new TestBuilder();
|
|
155
|
+
const peer = builder.createPeer();
|
|
156
|
+
await peer.createIdentity();
|
|
157
|
+
await openAndClose(peer.echoHost, peer.dataSpaceManager);
|
|
158
|
+
|
|
159
|
+
const space = await peer.dataSpaceManager.createSpace(new Context(), { tags: ['personal', 'test'] });
|
|
160
|
+
await space.inner.controlPipeline.state.waitUntilTimeframe(space.inner.controlPipeline.state.endTimeframe);
|
|
161
|
+
|
|
162
|
+
expect(space.inner.spaceState.tags).toEqual(['personal', 'test']);
|
|
163
|
+
expect(space.inner.spaceState.genesisCredential).to.exist;
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
test('create space without tags has empty tags', async () => {
|
|
167
|
+
const builder = new TestBuilder();
|
|
168
|
+
const peer = builder.createPeer();
|
|
169
|
+
await peer.createIdentity();
|
|
170
|
+
await openAndClose(peer.echoHost, peer.dataSpaceManager);
|
|
171
|
+
|
|
172
|
+
const space = await peer.dataSpaceManager.createSpace(new Context());
|
|
173
|
+
await space.inner.controlPipeline.state.waitUntilTimeframe(space.inner.controlPipeline.state.endTimeframe);
|
|
174
|
+
|
|
175
|
+
expect(space.inner.spaceState.tags).toEqual([]);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test('tags propagate through peer admission', async () => {
|
|
179
|
+
const builder = new TestBuilder();
|
|
180
|
+
const peer1 = builder.createPeer();
|
|
181
|
+
await peer1.createIdentity();
|
|
182
|
+
const peer2 = builder.createPeer();
|
|
183
|
+
await peer2.createIdentity();
|
|
184
|
+
|
|
185
|
+
await openAndClose(peer1.echoHost, peer1.dataSpaceManager, peer2.echoHost, peer2.dataSpaceManager);
|
|
186
|
+
await connectReplicators([peer1, peer2]);
|
|
187
|
+
|
|
188
|
+
const space1 = await peer1.dataSpaceManager.createSpace(new Context(), { tags: ['personal'] });
|
|
189
|
+
await space1.inner.controlPipeline.state.waitUntilTimeframe(space1.inner.controlPipeline.state.endTimeframe);
|
|
190
|
+
|
|
191
|
+
// Admit peer2 to space1.
|
|
192
|
+
await writeMessages(
|
|
193
|
+
space1.inner.controlPipeline.writer,
|
|
194
|
+
await createAdmissionCredentials(
|
|
195
|
+
peer1.identity.credentialSigner,
|
|
196
|
+
peer2.identity.identityKey,
|
|
197
|
+
space1.key,
|
|
198
|
+
space1.inner.genesisFeedKey,
|
|
199
|
+
undefined, // role (default ADMIN)
|
|
200
|
+
undefined, // membershipChainHeads
|
|
201
|
+
undefined, // profile
|
|
202
|
+
undefined, // invitationCredentialId
|
|
203
|
+
space1.inner.spaceState.tags, // tags
|
|
204
|
+
),
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
const space2 = await peer2.dataSpaceManager.acceptSpace(new Context(), {
|
|
208
|
+
spaceKey: space1.key,
|
|
209
|
+
genesisFeedKey: space1.inner.genesisFeedKey,
|
|
210
|
+
tags: space1.inner.spaceState.tags,
|
|
211
|
+
});
|
|
212
|
+
await peer2.dataSpaceManager.waitUntilSpaceReady(space2.key);
|
|
213
|
+
|
|
214
|
+
// Peer2's space should have the same tags.
|
|
215
|
+
expect(space2.inner.spaceState.tags).toEqual(['personal']);
|
|
216
|
+
});
|
|
217
|
+
|
|
152
218
|
describe('activation', () => {
|
|
153
219
|
test('can activate and deactivate a space', async () => {
|
|
154
220
|
const builder = new TestBuilder();
|
|
@@ -157,14 +223,14 @@ describe('DataSpaceManager', () => {
|
|
|
157
223
|
await peer.createIdentity();
|
|
158
224
|
await openAndClose(peer.echoHost, peer.dataSpaceManager);
|
|
159
225
|
|
|
160
|
-
const space = await peer.dataSpaceManager.createSpace();
|
|
226
|
+
const space = await peer.dataSpaceManager.createSpace(new Context());
|
|
161
227
|
await space.inner.controlPipeline.state.waitUntilTimeframe(space.inner.controlPipeline.state.endTimeframe);
|
|
162
228
|
expect(space.state).to.equal(SpaceState.SPACE_READY);
|
|
163
229
|
|
|
164
|
-
await space.deactivate();
|
|
230
|
+
await space.deactivate(new Context());
|
|
165
231
|
expect(space.state).to.equal(SpaceState.SPACE_INACTIVE);
|
|
166
232
|
|
|
167
|
-
await space.activate();
|
|
233
|
+
await space.activate(new Context());
|
|
168
234
|
await asyncTimeout(
|
|
169
235
|
space.stateUpdate.waitForCondition(() => space.state === SpaceState.SPACE_READY),
|
|
170
236
|
500,
|
|
@@ -178,12 +244,12 @@ describe('DataSpaceManager', () => {
|
|
|
178
244
|
await peer.createIdentity();
|
|
179
245
|
await openAndClose(peer.echoHost, peer.dataSpaceManager);
|
|
180
246
|
|
|
181
|
-
await peer.dataSpaceManager.createSpace();
|
|
247
|
+
await peer.dataSpaceManager.createSpace(new Context());
|
|
182
248
|
await reloadDataSpaces(peer);
|
|
183
249
|
|
|
184
250
|
const space = getFirstSpace(peer);
|
|
185
251
|
expect(space.state).to.equal(SpaceState.SPACE_CLOSED);
|
|
186
|
-
await space.activate();
|
|
252
|
+
await space.activate(new Context());
|
|
187
253
|
await asyncTimeout(
|
|
188
254
|
space.stateUpdate.waitForCondition(() => space.state === SpaceState.SPACE_READY),
|
|
189
255
|
500,
|
|
@@ -197,10 +263,10 @@ describe('DataSpaceManager', () => {
|
|
|
197
263
|
await peer.createIdentity();
|
|
198
264
|
await openAndClose(peer.echoHost, peer.dataSpaceManager);
|
|
199
265
|
|
|
200
|
-
await peer.dataSpaceManager.createSpace();
|
|
266
|
+
await peer.dataSpaceManager.createSpace(new Context());
|
|
201
267
|
await reloadDataSpaces(peer);
|
|
202
268
|
|
|
203
|
-
await getFirstSpace(peer).deactivate();
|
|
269
|
+
await getFirstSpace(peer).deactivate(new Context());
|
|
204
270
|
|
|
205
271
|
await reloadDataSpaces(peer);
|
|
206
272
|
|
|
@@ -209,7 +275,7 @@ describe('DataSpaceManager', () => {
|
|
|
209
275
|
});
|
|
210
276
|
|
|
211
277
|
const connectReplicators = (peers: TestPeer[]) => {
|
|
212
|
-
return Promise.all(peers.map((peer) => peer.echoHost.addReplicator(peer.meshEchoReplicator)));
|
|
278
|
+
return Promise.all(peers.map((peer) => peer.echoHost.addReplicator(Context.default(), peer.meshEchoReplicator)));
|
|
213
279
|
};
|
|
214
280
|
|
|
215
281
|
const reloadDataSpaces = async (peer: TestPeer) => {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Doc } from '@automerge/automerge';
|
|
6
|
-
import { type AutomergeUrl, type
|
|
6
|
+
import { type AutomergeUrl, type DocumentId, interpretAsDocumentId } from '@automerge/automerge-repo';
|
|
7
7
|
|
|
8
8
|
import { Event, synchronized, trackLeaks } from '@dxos/async';
|
|
9
9
|
import { SpaceProperties } from '@dxos/client-protocol';
|
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
getCredentialAssertion,
|
|
17
17
|
} from '@dxos/credentials';
|
|
18
18
|
import { Type } from '@dxos/echo';
|
|
19
|
-
import { getSchemaDXN } from '@dxos/echo/internal';
|
|
20
19
|
import {
|
|
21
20
|
AuthStatus,
|
|
22
21
|
CredentialServerExtension,
|
|
@@ -31,45 +30,40 @@ import {
|
|
|
31
30
|
type SpaceProtocolSession,
|
|
32
31
|
findInlineObjectOfType,
|
|
33
32
|
} from '@dxos/echo-pipeline';
|
|
34
|
-
import {
|
|
35
|
-
type DatabaseDirectory,
|
|
36
|
-
EncodedReference,
|
|
37
|
-
type ObjectStructure,
|
|
38
|
-
SpaceDocVersion,
|
|
39
|
-
createIdFromSpaceKey,
|
|
40
|
-
} from '@dxos/echo-protocol';
|
|
33
|
+
import { type DatabaseDirectory, createIdFromSpaceKey } from '@dxos/echo-protocol';
|
|
41
34
|
import type { EdgeConnection, EdgeHttpClient } from '@dxos/edge-client';
|
|
42
35
|
import { type FeedStore, writeMessages } from '@dxos/feed-store';
|
|
43
36
|
import { assertArgument, assertState, failedInvariant, invariant } from '@dxos/invariant';
|
|
44
37
|
import { type Keyring } from '@dxos/keyring';
|
|
45
|
-
import {
|
|
38
|
+
import { PublicKey, type SpaceId } from '@dxos/keys';
|
|
46
39
|
import { log } from '@dxos/log';
|
|
47
|
-
import { AlreadyJoinedError
|
|
40
|
+
import { AlreadyJoinedError } from '@dxos/protocols';
|
|
48
41
|
import { Invitation, SpaceState } from '@dxos/protocols/proto/dxos/client/services';
|
|
49
42
|
import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
50
43
|
import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
51
44
|
import { EdgeReplicationSetting, type SpaceMetadata } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
52
|
-
import {
|
|
45
|
+
import {
|
|
46
|
+
type Credential,
|
|
47
|
+
MembershipPolicy,
|
|
48
|
+
type ProfileDocument,
|
|
49
|
+
SpaceMember,
|
|
50
|
+
} from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
53
51
|
import { type DelegateSpaceInvitation } from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
54
52
|
import { type PeerState } from '@dxos/protocols/proto/dxos/mesh/presence';
|
|
55
53
|
import { type Teleport } from '@dxos/teleport';
|
|
56
54
|
import { Gossip, Presence } from '@dxos/teleport-extension-gossip';
|
|
57
55
|
import { type Timeframe } from '@dxos/timeframe';
|
|
58
56
|
import { trace } from '@dxos/tracing';
|
|
59
|
-
import { ComplexMap, deferFunction, forEachAsync
|
|
57
|
+
import { ComplexMap, deferFunction, forEachAsync } from '@dxos/util';
|
|
60
58
|
|
|
61
59
|
import { createAuthProvider } from '../identity';
|
|
62
60
|
import { type InvitationsManager } from '../invitations';
|
|
63
|
-
|
|
64
61
|
import { DataSpace } from './data-space';
|
|
65
62
|
import { spaceGenesis } from './genesis';
|
|
66
63
|
|
|
67
64
|
const PRESENCE_ANNOUNCE_INTERVAL = 10_000;
|
|
68
65
|
const PRESENCE_OFFLINE_TIMEOUT = 20_000;
|
|
69
66
|
|
|
70
|
-
// Space properties key for default metadata.
|
|
71
|
-
const DEFAULT_SPACE_KEY = '__DEFAULT__';
|
|
72
|
-
|
|
73
67
|
export interface SigningContext {
|
|
74
68
|
identityKey: PublicKey;
|
|
75
69
|
deviceKey: PublicKey;
|
|
@@ -94,6 +88,9 @@ export type AcceptSpaceOptions = {
|
|
|
94
88
|
* We will try to catch up to this timeframe before initializing the database.
|
|
95
89
|
*/
|
|
96
90
|
dataTimeframe?: Timeframe;
|
|
91
|
+
|
|
92
|
+
/** Tags assigned to the space member. */
|
|
93
|
+
tags?: string[];
|
|
97
94
|
};
|
|
98
95
|
|
|
99
96
|
export type AdmitMemberOptions = {
|
|
@@ -102,6 +99,7 @@ export type AdmitMemberOptions = {
|
|
|
102
99
|
role: SpaceMember.Role;
|
|
103
100
|
profile?: ProfileDocument;
|
|
104
101
|
delegationCredentialId?: PublicKey;
|
|
102
|
+
tags?: string[];
|
|
105
103
|
};
|
|
106
104
|
|
|
107
105
|
export type DataSpaceManagerProps = {
|
|
@@ -135,16 +133,17 @@ export type DataSpaceManagerRuntimeProps = {
|
|
|
135
133
|
export type CreateSpaceOptions = {
|
|
136
134
|
rootUrl?: AutomergeUrl;
|
|
137
135
|
documents?: Record<DocumentId, Uint8Array>;
|
|
136
|
+
tags?: string[];
|
|
137
|
+
membershipPolicy?: MembershipPolicy;
|
|
138
138
|
};
|
|
139
139
|
|
|
140
140
|
@trackLeaks('open', 'close')
|
|
141
|
+
@trace.resource({ lifecycle: true })
|
|
141
142
|
export class DataSpaceManager extends Resource {
|
|
142
143
|
public readonly updated = new Event();
|
|
143
144
|
|
|
144
145
|
private readonly _spaces = new ComplexMap<PublicKey, DataSpace>(PublicKey.hash);
|
|
145
146
|
|
|
146
|
-
private readonly _instanceId = PublicKey.random().toHex();
|
|
147
|
-
|
|
148
147
|
private readonly _spaceManager: SpaceManager;
|
|
149
148
|
private readonly _metadataStore: MetadataStore;
|
|
150
149
|
private readonly _keyring: Keyring;
|
|
@@ -184,9 +183,8 @@ export class DataSpaceManager extends Resource {
|
|
|
184
183
|
Array.from(this._spaces.values()).map(async (space) => {
|
|
185
184
|
const rootUrl = space.automergeSpaceState.rootUrl;
|
|
186
185
|
const rootHandle = rootUrl
|
|
187
|
-
? await this._echoHost.loadDoc<Doc<DatabaseDirectory>>(
|
|
186
|
+
? await this._echoHost.loadDoc<Doc<DatabaseDirectory>>(this._ctx, rootUrl as AutomergeUrl)
|
|
188
187
|
: undefined;
|
|
189
|
-
await rootHandle?.whenReady();
|
|
190
188
|
const rootDoc = rootHandle?.doc();
|
|
191
189
|
|
|
192
190
|
const properties = rootDoc && findInlineObjectOfType(rootDoc, Type.getTypename(SpaceProperties));
|
|
@@ -217,16 +215,16 @@ export class DataSpaceManager extends Resource {
|
|
|
217
215
|
}
|
|
218
216
|
|
|
219
217
|
@synchronized
|
|
220
|
-
|
|
218
|
+
@trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
|
|
219
|
+
protected override async _open(ctx: Context): Promise<void> {
|
|
221
220
|
log('open');
|
|
222
|
-
log.trace('dxos.echo.data-space-manager.open', Trace.begin({ id: this._instanceId }));
|
|
223
221
|
log('metadata loaded', { spaces: this._metadataStore.spaces.length });
|
|
224
222
|
|
|
225
223
|
const spacesToActivate: DataSpace[] = [];
|
|
226
224
|
await forEachAsync(this._metadataStore.spaces, async (spaceMetadata) => {
|
|
227
225
|
try {
|
|
228
226
|
log('load space', { spaceMetadata });
|
|
229
|
-
const space = await this._constructSpace(spaceMetadata);
|
|
227
|
+
const space = await this._constructSpace(ctx, spaceMetadata);
|
|
230
228
|
// Track spaces that were previously active for auto-activation (used in dedicated worker mode).
|
|
231
229
|
if (this._runtimeProps?.autoActivateSpaces && spaceMetadata.state === SpaceState.SPACE_ACTIVE) {
|
|
232
230
|
spacesToActivate.push(space);
|
|
@@ -239,21 +237,19 @@ export class DataSpaceManager extends Resource {
|
|
|
239
237
|
// Auto-activate spaces that were previously active (used in dedicated worker mode after leader changeover).
|
|
240
238
|
for (const space of spacesToActivate) {
|
|
241
239
|
log('auto-activating space', { spaceKey: space.key });
|
|
242
|
-
space.activate().catch((err) => {
|
|
240
|
+
space.activate(ctx).catch((err) => {
|
|
243
241
|
log.error('Error auto-activating space', { spaceKey: space.key, err });
|
|
244
242
|
});
|
|
245
243
|
}
|
|
246
244
|
|
|
247
245
|
this.updated.emit();
|
|
248
|
-
|
|
249
|
-
log.trace('dxos.echo.data-space-manager.open', Trace.end({ id: this._instanceId }));
|
|
250
246
|
}
|
|
251
247
|
|
|
252
248
|
@synchronized
|
|
253
|
-
protected override async _close(): Promise<void> {
|
|
249
|
+
protected override async _close(ctx: Context): Promise<void> {
|
|
254
250
|
log('close');
|
|
255
251
|
for (const space of this._spaces.values()) {
|
|
256
|
-
await space.close();
|
|
252
|
+
await space.close(ctx);
|
|
257
253
|
}
|
|
258
254
|
this._spaces.clear();
|
|
259
255
|
}
|
|
@@ -262,7 +258,8 @@ export class DataSpaceManager extends Resource {
|
|
|
262
258
|
* Creates a new space writing the genesis credentials to the control feed.
|
|
263
259
|
*/
|
|
264
260
|
@synchronized
|
|
265
|
-
|
|
261
|
+
@trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
|
|
262
|
+
async createSpace(ctx: Context, options: CreateSpaceOptions = {}): Promise<DataSpace> {
|
|
266
263
|
assertArgument(
|
|
267
264
|
!!options.rootUrl === !!options.documents,
|
|
268
265
|
'options',
|
|
@@ -270,6 +267,8 @@ export class DataSpaceManager extends Resource {
|
|
|
270
267
|
);
|
|
271
268
|
|
|
272
269
|
assertState(this._lifecycleState === LifecycleState.OPEN, 'Not open.');
|
|
270
|
+
|
|
271
|
+
const tags = options.tags ? Array.from(options.tags) : [];
|
|
273
272
|
const spaceKey = await this._keyring.createKey();
|
|
274
273
|
const controlFeedKey = await this._keyring.createKey();
|
|
275
274
|
const dataFeedKey = await this._keyring.createKey();
|
|
@@ -282,6 +281,7 @@ export class DataSpaceManager extends Resource {
|
|
|
282
281
|
controlFeedKey,
|
|
283
282
|
dataFeedKey,
|
|
284
283
|
state: SpaceState.SPACE_ACTIVE,
|
|
284
|
+
tags,
|
|
285
285
|
};
|
|
286
286
|
|
|
287
287
|
log('creating space...', { spaceId, spaceKey });
|
|
@@ -319,30 +319,37 @@ export class DataSpaceManager extends Resource {
|
|
|
319
319
|
let root: DatabaseRoot;
|
|
320
320
|
if (options.rootUrl) {
|
|
321
321
|
const newRootDocId = documentIdMapping[interpretAsDocumentId(options.rootUrl)] ?? failedInvariant();
|
|
322
|
-
const rootDocHandle = await this._echoHost.loadDoc<DatabaseDirectory>(
|
|
322
|
+
const rootDocHandle = await this._echoHost.loadDoc<DatabaseDirectory>(ctx, newRootDocId);
|
|
323
323
|
DatabaseRoot.mapLinks(rootDocHandle, documentIdMapping);
|
|
324
324
|
|
|
325
|
-
root = await this._echoHost.openSpaceRoot(spaceId, `automerge:${newRootDocId}` as AutomergeUrl);
|
|
325
|
+
root = await this._echoHost.openSpaceRoot(ctx, spaceId, `automerge:${newRootDocId}` as AutomergeUrl);
|
|
326
326
|
} else {
|
|
327
|
-
root = await this._echoHost.createSpaceRoot(spaceKey);
|
|
327
|
+
root = await this._echoHost.createSpaceRoot(ctx, spaceKey);
|
|
328
328
|
}
|
|
329
|
-
await this._echoHost.flush();
|
|
329
|
+
await this._echoHost.flush(ctx);
|
|
330
330
|
|
|
331
331
|
log('constructing space...', { spaceKey });
|
|
332
332
|
|
|
333
|
-
const space = await this._constructSpace(metadata);
|
|
334
|
-
await space.open();
|
|
333
|
+
const space = await this._constructSpace(ctx, metadata);
|
|
334
|
+
await space.open(ctx);
|
|
335
335
|
|
|
336
336
|
log('adding space...', { spaceKey });
|
|
337
337
|
|
|
338
|
-
const credentials = await spaceGenesis(
|
|
338
|
+
const credentials = await spaceGenesis(
|
|
339
|
+
this._keyring,
|
|
340
|
+
this._signingContext,
|
|
341
|
+
space.inner,
|
|
342
|
+
root.url,
|
|
343
|
+
tags,
|
|
344
|
+
options.membershipPolicy,
|
|
345
|
+
);
|
|
339
346
|
await this._metadataStore.addSpace(metadata);
|
|
340
347
|
|
|
341
348
|
const memberCredential = credentials[1];
|
|
342
349
|
invariant(getCredentialAssertion(memberCredential)['@type'] === 'dxos.halo.credentials.SpaceMember');
|
|
343
350
|
await this._signingContext.recordCredential(memberCredential);
|
|
344
351
|
|
|
345
|
-
await space.initializeDataPipeline();
|
|
352
|
+
await space.initializeDataPipeline(ctx);
|
|
346
353
|
|
|
347
354
|
log('space ready.', { spaceId, spaceKey });
|
|
348
355
|
|
|
@@ -350,86 +357,36 @@ export class DataSpaceManager extends Resource {
|
|
|
350
357
|
return space;
|
|
351
358
|
}
|
|
352
359
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
case SpaceDocVersion.CURRENT: {
|
|
359
|
-
if (!space.databaseRoot.handle.isReady()) {
|
|
360
|
-
log.warn('waiting for space root to be ready', { spaceId: space.id });
|
|
361
|
-
await space.databaseRoot.handle.whenReady();
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
const [_, properties] =
|
|
365
|
-
findInlineObjectOfType(space.databaseRoot.doc()!, Type.getTypename(SpaceProperties)) ?? [];
|
|
366
|
-
return properties?.data?.[DEFAULT_SPACE_KEY] === this._signingContext.identityKey.toHex();
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
case SpaceDocVersion.LEGACY: {
|
|
370
|
-
throw new Error('Legacy space version is not supported');
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
default:
|
|
374
|
-
log.warn('unknown space version', { version: space.databaseRoot.getVersion(), spaceId: space.id });
|
|
375
|
-
return false;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
async createDefaultSpace(): Promise<DataSpace> {
|
|
380
|
-
const space = await this.createSpace();
|
|
381
|
-
const document = await this._getSpaceRootDocument(space);
|
|
382
|
-
|
|
383
|
-
// TODO(dmaretskyi): Better API for low-level data access.
|
|
384
|
-
const properties: ObjectStructure = {
|
|
385
|
-
system: {
|
|
386
|
-
type: EncodedReference.fromDXN(getSchemaDXN(SpaceProperties)!),
|
|
387
|
-
},
|
|
388
|
-
data: {
|
|
389
|
-
[DEFAULT_SPACE_KEY]: this._signingContext.identityKey.toHex(),
|
|
390
|
-
},
|
|
391
|
-
meta: {
|
|
392
|
-
keys: [],
|
|
393
|
-
},
|
|
394
|
-
};
|
|
395
|
-
|
|
396
|
-
const propertiesId = ObjectId.random();
|
|
397
|
-
document.change((doc: DatabaseDirectory) => {
|
|
398
|
-
setDeep(doc, ['objects', propertiesId], properties);
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
await this._echoHost.flush();
|
|
402
|
-
return space;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
private async _getSpaceRootDocument(space: DataSpace): Promise<DocHandle<DatabaseDirectory>> {
|
|
406
|
-
const automergeIndex = space.automergeSpaceState.rootUrl;
|
|
407
|
-
invariant(automergeIndex);
|
|
408
|
-
const document = await this._echoHost.loadDoc<DatabaseDirectory>(Context.default(), automergeIndex as any, {
|
|
409
|
-
fetchFromNetwork: true,
|
|
410
|
-
});
|
|
411
|
-
await document.whenReady();
|
|
412
|
-
return document;
|
|
413
|
-
}
|
|
414
|
-
|
|
360
|
+
/**
|
|
361
|
+
* Accepts an existing space by joining its swarm and initializing the data pipeline.
|
|
362
|
+
* @param ctx - Caller context for cancellation and tracing.
|
|
363
|
+
* @param opts - Space keys and optional timeframes for catch-up.
|
|
364
|
+
*/
|
|
415
365
|
// TODO(burdon): Rename join space.
|
|
416
366
|
@synchronized
|
|
417
|
-
|
|
367
|
+
@trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
|
|
368
|
+
async acceptSpace(ctx: Context, opts: AcceptSpaceOptions): Promise<DataSpace> {
|
|
418
369
|
log('accept space', { opts });
|
|
419
370
|
invariant(this._lifecycleState === LifecycleState.OPEN, 'Not open.');
|
|
420
371
|
invariant(!this._spaces.has(opts.spaceKey), 'Space already exists.');
|
|
421
372
|
|
|
373
|
+
const tags = opts.tags ? Array.from(opts.tags) : [];
|
|
422
374
|
const metadata: SpaceMetadata = {
|
|
423
375
|
key: opts.spaceKey,
|
|
424
376
|
genesisFeedKey: opts.genesisFeedKey,
|
|
425
377
|
controlTimeframe: opts.controlTimeframe,
|
|
426
378
|
dataTimeframe: opts.dataTimeframe,
|
|
379
|
+
tags,
|
|
427
380
|
};
|
|
428
381
|
|
|
429
|
-
const space = await this._constructSpace(metadata);
|
|
430
|
-
await space.open();
|
|
382
|
+
const space = await this._constructSpace(ctx, metadata);
|
|
383
|
+
await space.open(ctx);
|
|
431
384
|
await this._metadataStore.addSpace(metadata);
|
|
432
|
-
|
|
385
|
+
// Use DSM lifecycle ctx: the invitation accept flow disposes `ctx` as soon as
|
|
386
|
+
// `acceptSpace` returns (guardedState.complete -> ctx.dispose). Detached data-pipeline
|
|
387
|
+
// initialization must outlive the invitation flow, and its span must be parented to a
|
|
388
|
+
// long-lived context.
|
|
389
|
+
space.initializeDataPipelineAsync(this._ctx);
|
|
433
390
|
|
|
434
391
|
this.updated.emit();
|
|
435
392
|
return space;
|
|
@@ -453,6 +410,7 @@ export class DataSpaceManager extends Resource {
|
|
|
453
410
|
space.spaceState.membershipChainHeads,
|
|
454
411
|
options.profile,
|
|
455
412
|
options.delegationCredentialId,
|
|
413
|
+
space.spaceState.tags,
|
|
456
414
|
);
|
|
457
415
|
|
|
458
416
|
// TODO(dmaretskyi): Refactor.
|
|
@@ -479,8 +437,8 @@ export class DataSpaceManager extends Resource {
|
|
|
479
437
|
);
|
|
480
438
|
}
|
|
481
439
|
|
|
482
|
-
public async requestSpaceAdmissionCredential(spaceKey: PublicKey): Promise<Credential> {
|
|
483
|
-
return this._spaceManager.requestSpaceAdmissionCredential({
|
|
440
|
+
public async requestSpaceAdmissionCredential(ctx: Context, spaceKey: PublicKey): Promise<Credential> {
|
|
441
|
+
return this._spaceManager.requestSpaceAdmissionCredential(ctx, {
|
|
484
442
|
spaceKey,
|
|
485
443
|
identityKey: this._signingContext.identityKey,
|
|
486
444
|
timeout: 15_000,
|
|
@@ -493,7 +451,11 @@ export class DataSpaceManager extends Resource {
|
|
|
493
451
|
});
|
|
494
452
|
}
|
|
495
453
|
|
|
496
|
-
async setSpaceEdgeReplicationSetting(
|
|
454
|
+
async setSpaceEdgeReplicationSetting(
|
|
455
|
+
ctx: Context,
|
|
456
|
+
spaceKey: PublicKey,
|
|
457
|
+
setting: EdgeReplicationSetting,
|
|
458
|
+
): Promise<void> {
|
|
497
459
|
const space = this._spaces.get(spaceKey);
|
|
498
460
|
invariant(space, 'Space not found.');
|
|
499
461
|
|
|
@@ -505,7 +467,7 @@ export class DataSpaceManager extends Resource {
|
|
|
505
467
|
await this._echoEdgeReplicator?.disconnectFromSpace(space.id);
|
|
506
468
|
break;
|
|
507
469
|
case EdgeReplicationSetting.ENABLED:
|
|
508
|
-
await this._echoEdgeReplicator?.connectToSpace(space.id);
|
|
470
|
+
await this._echoEdgeReplicator?.connectToSpace(ctx, space.id);
|
|
509
471
|
break;
|
|
510
472
|
}
|
|
511
473
|
}
|
|
@@ -513,7 +475,7 @@ export class DataSpaceManager extends Resource {
|
|
|
513
475
|
space.stateUpdate.emit();
|
|
514
476
|
}
|
|
515
477
|
|
|
516
|
-
private async _constructSpace(metadata: SpaceMetadata): Promise<DataSpace> {
|
|
478
|
+
private async _constructSpace(ctx: Context, metadata: SpaceMetadata): Promise<DataSpace> {
|
|
517
479
|
log('construct space', { metadata });
|
|
518
480
|
const gossip = new Gossip({
|
|
519
481
|
localPeerId: this._signingContext.deviceKey,
|
|
@@ -603,6 +565,7 @@ export class DataSpaceManager extends Resource {
|
|
|
603
565
|
},
|
|
604
566
|
},
|
|
605
567
|
cache: metadata.cache,
|
|
568
|
+
tags: metadata.tags,
|
|
606
569
|
edgeConnection: this._edgeConnection,
|
|
607
570
|
edgeHttpClient: this._edgeHttpClient,
|
|
608
571
|
edgeFeatures: this._edgeFeatures,
|
|
@@ -611,7 +574,8 @@ export class DataSpaceManager extends Resource {
|
|
|
611
574
|
dataSpace.postOpen.append(async () => {
|
|
612
575
|
const setting = dataSpace.getEdgeReplicationSetting();
|
|
613
576
|
if (!setting || setting === EdgeReplicationSetting.ENABLED) {
|
|
614
|
-
|
|
577
|
+
// Use lifecycle ctx: the caller ctx from _constructSpace may be disposed by the time postOpen fires.
|
|
578
|
+
await this._echoEdgeReplicator?.connectToSpace(this._ctx, dataSpace.id);
|
|
615
579
|
} else if (this._echoEdgeReplicator) {
|
|
616
580
|
log('not connecting EchoEdgeReplicator because of EdgeReplicationSetting', { spaceId: dataSpace.id });
|
|
617
581
|
}
|
|
@@ -708,7 +672,7 @@ export class DataSpaceManager extends Resource {
|
|
|
708
672
|
invitations: Array<[PublicKey, DelegateSpaceInvitation]>,
|
|
709
673
|
): Promise<void> {
|
|
710
674
|
const tasks = invitations.map(([credentialId, invitation]) => {
|
|
711
|
-
return this._invitationsManager.createInvitation({
|
|
675
|
+
return this._invitationsManager.createInvitation(this._ctx, {
|
|
712
676
|
type: Invitation.Type.DELEGATED,
|
|
713
677
|
kind: Invitation.Kind.SPACE,
|
|
714
678
|
spaceKey: space.key,
|