@dxos/client-services 0.4.10-main.fd4f2a3 → 0.4.10-main.fd8ea31
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-V2ALN47T.mjs → chunk-WLE7E36I.mjs} +1402 -1074
- package/dist/lib/browser/chunk-WLE7E36I.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +13 -3
- package/dist/lib/browser/index.mjs.map +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/testing/index.mjs +133 -115
- package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-7WXQVUAE.cjs → chunk-YXZQQAQN.cjs} +1308 -1063
- package/dist/lib/node/chunk-YXZQQAQN.cjs.map +7 -0
- package/dist/lib/node/index.cjs +49 -39
- package/dist/lib/node/index.cjs.map +1 -1
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/packlets/testing/index.cjs +133 -118
- package/dist/lib/node/packlets/testing/index.cjs.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/diagnostics/browser-diagnostics-broadcast.d.ts +5 -0
- package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -0
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts +5 -0
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -0
- package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts +15 -0
- package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -0
- package/dist/types/src/packlets/{services → diagnostics}/diagnostics.d.ts +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -0
- package/dist/types/src/packlets/diagnostics/index.d.ts +4 -0
- package/dist/types/src/packlets/diagnostics/index.d.ts.map +1 -0
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/indexing/util.d.ts +2 -6
- package/dist/types/src/packlets/indexing/util.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +3 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/index.d.ts +1 -0
- package/dist/types/src/packlets/invitations/index.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-extension.d.ts +1 -0
- package/dist/types/src/packlets/invitations/invitation-extension.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +6 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +8 -4
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts +44 -0
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/invitations-service.d.ts +7 -23
- 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/services/index.d.ts +1 -1
- package/dist/types/src/packlets/services/index.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +2 -0
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +5 -1
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/services/util.d.ts +1 -0
- package/dist/types/src/packlets/services/util.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +5 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.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/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts +6 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/package.json +35 -34
- package/src/index.ts +1 -0
- package/src/packlets/diagnostics/browser-diagnostics-broadcast.ts +94 -0
- package/src/packlets/diagnostics/diagnostics-broadcast.ts +20 -0
- package/src/packlets/diagnostics/diagnostics-collector.ts +65 -0
- package/src/packlets/{services → diagnostics}/diagnostics.ts +2 -2
- package/src/packlets/diagnostics/index.ts +7 -0
- package/src/packlets/identity/identity-manager.ts +1 -0
- package/src/packlets/identity/identity.test.ts +3 -0
- package/src/packlets/indexing/util.ts +9 -66
- package/src/packlets/invitations/device-invitation-protocol.ts +6 -1
- package/src/packlets/invitations/index.ts +1 -0
- package/src/packlets/invitations/invitation-extension.ts +28 -1
- package/src/packlets/invitations/invitation-protocol.ts +7 -1
- package/src/packlets/invitations/invitations-handler.ts +75 -96
- package/src/packlets/invitations/invitations-manager.ts +271 -0
- package/src/packlets/invitations/invitations-service.ts +23 -168
- package/src/packlets/invitations/space-invitation-protocol.ts +45 -3
- package/src/packlets/services/automerge-host.test.ts +10 -4
- package/src/packlets/services/index.ts +1 -1
- package/src/packlets/services/service-context.test.ts +4 -1
- package/src/packlets/services/service-context.ts +19 -5
- package/src/packlets/services/service-host.ts +34 -19
- package/src/packlets/services/util.ts +2 -0
- package/src/packlets/spaces/data-space-manager.test.ts +4 -4
- package/src/packlets/spaces/data-space-manager.ts +48 -2
- package/src/packlets/spaces/data-space.ts +1 -1
- package/src/packlets/storage/level.ts +1 -1
- package/src/packlets/system/system-service.ts +1 -1
- package/src/packlets/testing/invitation-utils.ts +100 -97
- package/src/packlets/testing/test-builder.ts +39 -5
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-V2ALN47T.mjs.map +0 -7
- package/dist/lib/node/chunk-7WXQVUAE.cjs.map +0 -7
- package/dist/types/src/packlets/services/diagnostics.d.ts.map +0 -1
|
@@ -20,7 +20,7 @@ describe('DataSpaceManager', () => {
|
|
|
20
20
|
|
|
21
21
|
const peer = builder.createPeer();
|
|
22
22
|
await peer.createIdentity();
|
|
23
|
-
await openAndClose(peer.dataSpaceManager);
|
|
23
|
+
await openAndClose(peer.automergeHost, peer.dataSpaceManager);
|
|
24
24
|
|
|
25
25
|
const space = await peer.dataSpaceManager.createSpace();
|
|
26
26
|
|
|
@@ -42,7 +42,7 @@ describe('DataSpaceManager', () => {
|
|
|
42
42
|
const peer2 = builder.createPeer();
|
|
43
43
|
await peer2.createIdentity();
|
|
44
44
|
|
|
45
|
-
await openAndClose(peer1.dataSpaceManager, peer2.dataSpaceManager);
|
|
45
|
+
await openAndClose(peer1.automergeHost, peer1.dataSpaceManager, peer2.automergeHost, peer2.dataSpaceManager);
|
|
46
46
|
|
|
47
47
|
const space1 = await peer1.dataSpaceManager.createSpace();
|
|
48
48
|
await space1.inner.controlPipeline.state.waitUntilTimeframe(space1.inner.controlPipeline.state.endTimeframe);
|
|
@@ -111,7 +111,7 @@ describe('DataSpaceManager', () => {
|
|
|
111
111
|
await peer2.createIdentity();
|
|
112
112
|
await peer2.dataSpaceManager.open();
|
|
113
113
|
|
|
114
|
-
await openAndClose(peer1.dataSpaceManager, peer2.dataSpaceManager);
|
|
114
|
+
await openAndClose(peer1.automergeHost, peer1.dataSpaceManager, peer2.automergeHost, peer2.dataSpaceManager);
|
|
115
115
|
|
|
116
116
|
const space1 = await peer1.dataSpaceManager.createSpace();
|
|
117
117
|
await space1.inner.controlPipeline.state.waitUntilTimeframe(space1.inner.controlPipeline.state.endTimeframe);
|
|
@@ -153,7 +153,7 @@ describe('DataSpaceManager', () => {
|
|
|
153
153
|
|
|
154
154
|
const peer = builder.createPeer();
|
|
155
155
|
await peer.createIdentity();
|
|
156
|
-
await openAndClose(peer.dataSpaceManager);
|
|
156
|
+
await openAndClose(peer.automergeHost, peer.dataSpaceManager);
|
|
157
157
|
|
|
158
158
|
const space = await peer.dataSpaceManager.createSpace();
|
|
159
159
|
await space.inner.controlPipeline.state.waitUntilTimeframe(space.inner.controlPipeline.state.endTimeframe);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { Event, synchronized, trackLeaks } from '@dxos/async';
|
|
6
6
|
import { Context, cancelWithContext } from '@dxos/context';
|
|
7
|
-
import { getCredentialAssertion, type CredentialSigner } from '@dxos/credentials';
|
|
7
|
+
import { getCredentialAssertion, type CredentialSigner, type DelegateInvitationCredential } from '@dxos/credentials';
|
|
8
8
|
import { type AutomergeHost, type MetadataStore, type Space, type SpaceManager } from '@dxos/echo-pipeline';
|
|
9
9
|
import { type FeedStore } from '@dxos/feed-store';
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
@@ -12,10 +12,11 @@ import { type Keyring } from '@dxos/keyring';
|
|
|
12
12
|
import { PublicKey } from '@dxos/keys';
|
|
13
13
|
import { log } from '@dxos/log';
|
|
14
14
|
import { trace } from '@dxos/protocols';
|
|
15
|
-
import { SpaceState } from '@dxos/protocols/proto/dxos/client/services';
|
|
15
|
+
import { Invitation, SpaceState } from '@dxos/protocols/proto/dxos/client/services';
|
|
16
16
|
import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
17
17
|
import { type SpaceMetadata } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
18
18
|
import { type Credential, type ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
19
|
+
import { type DelegateSpaceInvitation } from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
19
20
|
import { Gossip, Presence } from '@dxos/teleport-extension-gossip';
|
|
20
21
|
import { type Timeframe } from '@dxos/timeframe';
|
|
21
22
|
import { ComplexMap, deferFunction, forEachAsync } from '@dxos/util';
|
|
@@ -23,6 +24,7 @@ import { ComplexMap, deferFunction, forEachAsync } from '@dxos/util';
|
|
|
23
24
|
import { DataSpace } from './data-space';
|
|
24
25
|
import { spaceGenesis } from './genesis';
|
|
25
26
|
import { createAuthProvider } from '../identity';
|
|
27
|
+
import { type InvitationsManager } from '../invitations';
|
|
26
28
|
|
|
27
29
|
const PRESENCE_ANNOUNCE_INTERVAL = 10_000;
|
|
28
30
|
const PRESENCE_OFFLINE_TIMEOUT = 20_000;
|
|
@@ -78,6 +80,7 @@ export class DataSpaceManager {
|
|
|
78
80
|
private readonly _signingContext: SigningContext,
|
|
79
81
|
private readonly _feedStore: FeedStore<FeedMessage>,
|
|
80
82
|
private readonly _automergeHost: AutomergeHost,
|
|
83
|
+
private readonly _invitationsManager: InvitationsManager,
|
|
81
84
|
params?: DataSpaceManagerRuntimeParams,
|
|
82
85
|
) {
|
|
83
86
|
const {
|
|
@@ -247,6 +250,9 @@ export class DataSpaceManager {
|
|
|
247
250
|
log.warn('auth failure');
|
|
248
251
|
},
|
|
249
252
|
memberKey: this._signingContext.identityKey,
|
|
253
|
+
onDelegatedInvitationStatusChange: (invitation, isActive) => {
|
|
254
|
+
return this._handleInvitationStatusChange(dataSpace, invitation, isActive);
|
|
255
|
+
},
|
|
250
256
|
});
|
|
251
257
|
controlFeed && (await space.setControlFeed(controlFeed));
|
|
252
258
|
dataFeed && (await space.setDataFeed(dataFeed));
|
|
@@ -267,6 +273,7 @@ export class DataSpaceManager {
|
|
|
267
273
|
afterReady: async () => {
|
|
268
274
|
log('after space ready', { space: space.key, open: this._isOpen });
|
|
269
275
|
if (this._isOpen) {
|
|
276
|
+
await this._createDelegatedInvitations(dataSpace, [...space.spaceState.invitations.entries()]);
|
|
270
277
|
this.updated.emit();
|
|
271
278
|
}
|
|
272
279
|
},
|
|
@@ -289,4 +296,43 @@ export class DataSpaceManager {
|
|
|
289
296
|
this._spaces.set(metadata.key, dataSpace);
|
|
290
297
|
return dataSpace;
|
|
291
298
|
}
|
|
299
|
+
|
|
300
|
+
private async _handleInvitationStatusChange(
|
|
301
|
+
dataSpace: DataSpace | undefined,
|
|
302
|
+
delegatedInvitation: DelegateInvitationCredential,
|
|
303
|
+
isActive: boolean,
|
|
304
|
+
): Promise<void> {
|
|
305
|
+
if (dataSpace?.state !== SpaceState.READY) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (isActive) {
|
|
309
|
+
await this._createDelegatedInvitations(dataSpace, [
|
|
310
|
+
[delegatedInvitation.credentialId, delegatedInvitation.invitation],
|
|
311
|
+
]);
|
|
312
|
+
} else {
|
|
313
|
+
await this._invitationsManager.cancelInvitation(delegatedInvitation.invitation);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
private async _createDelegatedInvitations(
|
|
318
|
+
space: DataSpace,
|
|
319
|
+
invitations: Array<[PublicKey, DelegateSpaceInvitation]>,
|
|
320
|
+
): Promise<void> {
|
|
321
|
+
const tasks = invitations.map(([credentialId, invitation]) => {
|
|
322
|
+
return this._invitationsManager.createInvitation({
|
|
323
|
+
type: Invitation.Type.DELEGATED,
|
|
324
|
+
kind: Invitation.Kind.SPACE,
|
|
325
|
+
spaceKey: space.key,
|
|
326
|
+
authMethod: invitation.authMethod,
|
|
327
|
+
invitationId: invitation.invitationId,
|
|
328
|
+
swarmKey: invitation.swarmKey,
|
|
329
|
+
guestKeypair: invitation.guestKey ? { publicKey: invitation.guestKey } : undefined,
|
|
330
|
+
lifetime: invitation.expiresOn ? invitation.expiresOn.getTime() - Date.now() : undefined,
|
|
331
|
+
multiUse: invitation.multiUse,
|
|
332
|
+
delegationCredentialId: credentialId,
|
|
333
|
+
persistent: false,
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
await Promise.all(tasks);
|
|
337
|
+
}
|
|
292
338
|
}
|
|
@@ -6,7 +6,6 @@ import { Event, asyncTimeout, scheduleTask, sleep, synchronized, trackLeaks } fr
|
|
|
6
6
|
import { AUTH_TIMEOUT } from '@dxos/client-protocol';
|
|
7
7
|
import { cancelWithContext, Context, ContextDisposedError } from '@dxos/context';
|
|
8
8
|
import { timed, warnAfterTimeout } from '@dxos/debug';
|
|
9
|
-
import { TYPE_PROPERTIES } from '@dxos/echo-db';
|
|
10
9
|
import {
|
|
11
10
|
type MetadataStore,
|
|
12
11
|
type Space,
|
|
@@ -15,6 +14,7 @@ import {
|
|
|
15
14
|
type SpaceDoc,
|
|
16
15
|
} from '@dxos/echo-pipeline';
|
|
17
16
|
import { AutomergeDocumentLoaderImpl } from '@dxos/echo-pipeline';
|
|
17
|
+
import { TYPE_PROPERTIES } from '@dxos/echo-schema';
|
|
18
18
|
import { type FeedStore } from '@dxos/feed-store';
|
|
19
19
|
import { failedInvariant, invariant } from '@dxos/invariant';
|
|
20
20
|
import { type Keyring } from '@dxos/keyring';
|
|
@@ -12,7 +12,7 @@ import { getRootPath, isPersistent } from './util';
|
|
|
12
12
|
|
|
13
13
|
export const createLevel = async (config: Runtime.Client.Storage) => {
|
|
14
14
|
const persistent = isPersistent(config);
|
|
15
|
-
const storagePath = persistent ? getRootPath(config)
|
|
15
|
+
const storagePath = persistent ? path.join(getRootPath(config), 'level') : `/tmp/dxos-${PublicKey.random().toHex()}`;
|
|
16
16
|
const level = new Level<string, string>(storagePath);
|
|
17
17
|
await level.open();
|
|
18
18
|
return level;
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
17
17
|
import { jsonKeyReplacer, type MaybePromise } from '@dxos/util';
|
|
18
18
|
|
|
19
|
-
import { type Diagnostics } from '../
|
|
19
|
+
import { type Diagnostics } from '../diagnostics';
|
|
20
20
|
import { getPlatform } from '../services/platform';
|
|
21
21
|
|
|
22
22
|
export type SystemServiceOptions = {
|
|
@@ -60,146 +60,149 @@ export const performInvitation = ({
|
|
|
60
60
|
const guestComplete = new Trigger<Result>();
|
|
61
61
|
const authCode = new Trigger<string>();
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
63
|
+
void createInvitation(host, options).then((hostObservable) => {
|
|
64
|
+
hostObservable.subscribe(
|
|
65
|
+
async (hostInvitation: Invitation) => {
|
|
66
|
+
switch (hostInvitation.state) {
|
|
67
|
+
case Invitation.State.CONNECTING: {
|
|
68
|
+
if (hooks?.host?.onConnecting?.(hostObservable)) {
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
const guestObservable = acceptInvitation(guest, hostInvitation, guestDeviceProfile);
|
|
72
|
+
guestObservable.subscribe(
|
|
73
|
+
async (guestInvitation: Invitation) => {
|
|
74
|
+
switch (guestInvitation.state) {
|
|
75
|
+
case Invitation.State.CONNECTING: {
|
|
76
|
+
if (hooks?.guest?.onConnecting?.(guestObservable)) {
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
invariant(hostInvitation.swarmKey!.equals(guestInvitation.swarmKey!));
|
|
77
80
|
break;
|
|
78
81
|
}
|
|
79
|
-
invariant(hostInvitation.swarmKey!.equals(guestInvitation.swarmKey!));
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
case Invitation.State.CONNECTED: {
|
|
84
|
+
hooks?.guest?.onConnected?.(guestObservable);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
case Invitation.State.READY_FOR_AUTHENTICATION: {
|
|
89
|
+
if (hooks?.guest?.onReady?.(guestObservable)) {
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
await guestObservable.authenticate(await authCode.wait());
|
|
90
93
|
break;
|
|
91
94
|
}
|
|
92
|
-
await guestObservable.authenticate(await authCode.wait());
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
case Invitation.State.AUTHENTICATING: {
|
|
97
|
+
hooks?.guest?.onAuthenticating?.(guestObservable);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
case Invitation.State.SUCCESS: {
|
|
102
|
+
if (hooks?.guest?.onSuccess?.(guestObservable)) {
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
guestComplete.wake({ invitation: guestInvitation });
|
|
103
106
|
break;
|
|
104
107
|
}
|
|
105
|
-
guestComplete.wake({ invitation: guestInvitation });
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
case Invitation.State.CANCELLED: {
|
|
110
|
+
if (hooks?.guest?.onCancelled?.(guestObservable)) {
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
guestComplete.wake({ invitation: guestInvitation });
|
|
111
114
|
break;
|
|
112
115
|
}
|
|
113
|
-
guestComplete.wake({ invitation: guestInvitation });
|
|
114
|
-
break;
|
|
115
|
-
}
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
case Invitation.State.TIMEOUT: {
|
|
118
|
+
if (hooks?.guest?.onTimeout?.(guestObservable)) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
guestComplete.wake({ invitation: guestInvitation });
|
|
120
122
|
}
|
|
121
|
-
guestComplete.wake({ invitation: guestInvitation });
|
|
122
123
|
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
case Invitation.State.CONNECTED: {
|
|
136
|
-
hooks?.host?.onConnected?.(hostObservable);
|
|
137
|
-
break;
|
|
138
|
-
}
|
|
124
|
+
},
|
|
125
|
+
(error: Error) => {
|
|
126
|
+
if (hooks?.guest?.onError?.(guestObservable)) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
guestComplete.wake({ error });
|
|
130
|
+
},
|
|
131
|
+
);
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
139
134
|
|
|
140
|
-
|
|
141
|
-
|
|
135
|
+
case Invitation.State.CONNECTED: {
|
|
136
|
+
hooks?.host?.onConnected?.(hostObservable);
|
|
142
137
|
break;
|
|
143
138
|
}
|
|
144
|
-
|
|
145
|
-
|
|
139
|
+
|
|
140
|
+
case Invitation.State.READY_FOR_AUTHENTICATION: {
|
|
141
|
+
if (hooks?.host?.onReady?.(hostObservable)) {
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
if (hostInvitation.authCode) {
|
|
145
|
+
authCode.wake(hostInvitation.authCode);
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
146
148
|
}
|
|
147
|
-
break;
|
|
148
|
-
}
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
150
|
+
case Invitation.State.AUTHENTICATING: {
|
|
151
|
+
hooks?.host?.onAuthenticating?.(hostObservable);
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
154
|
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
case Invitation.State.SUCCESS: {
|
|
156
|
+
if (hooks?.host?.onSuccess?.(hostObservable)) {
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
hostComplete.wake({ invitation: hostInvitation });
|
|
157
160
|
break;
|
|
158
161
|
}
|
|
159
|
-
hostComplete.wake({ invitation: hostInvitation });
|
|
160
|
-
break;
|
|
161
|
-
}
|
|
162
162
|
|
|
163
|
-
|
|
164
|
-
|
|
163
|
+
case Invitation.State.CANCELLED: {
|
|
164
|
+
if (hooks?.host?.onCancelled?.(hostObservable)) {
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
hostComplete.wake({ invitation: hostInvitation });
|
|
165
168
|
break;
|
|
166
169
|
}
|
|
167
|
-
hostComplete.wake({ invitation: hostInvitation });
|
|
168
|
-
break;
|
|
169
|
-
}
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
case Invitation.State.TIMEOUT: {
|
|
172
|
+
if (hooks?.host?.onTimeout?.(hostObservable)) {
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
hostComplete.wake({ invitation: hostInvitation });
|
|
173
176
|
break;
|
|
174
177
|
}
|
|
175
|
-
hostComplete.wake({ invitation: hostInvitation });
|
|
176
|
-
break;
|
|
177
178
|
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
);
|
|
179
|
+
},
|
|
180
|
+
(error: Error) => {
|
|
181
|
+
if (hooks?.host?.onError?.(hostObservable)) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
hostComplete.wake({ error });
|
|
185
|
+
},
|
|
186
|
+
);
|
|
187
|
+
});
|
|
187
188
|
|
|
188
189
|
return [hostComplete.wait(), guestComplete.wait()];
|
|
189
190
|
};
|
|
190
191
|
|
|
191
|
-
const createInvitation = (
|
|
192
|
+
const createInvitation = async (
|
|
192
193
|
host: ServiceContext | InvitationHost,
|
|
193
194
|
options?: Partial<Invitation>,
|
|
194
|
-
): CancellableInvitation => {
|
|
195
|
+
): Promise<CancellableInvitation> => {
|
|
195
196
|
options ??= {
|
|
196
197
|
authMethod: Invitation.AuthMethod.NONE,
|
|
197
198
|
...(options ?? {}),
|
|
198
199
|
};
|
|
199
200
|
|
|
200
201
|
if (host instanceof ServiceContext) {
|
|
201
|
-
|
|
202
|
-
|
|
202
|
+
return host.invitationsManager.createInvitation({
|
|
203
|
+
kind: Invitation.Kind.SPACE,
|
|
204
|
+
...options,
|
|
205
|
+
});
|
|
203
206
|
}
|
|
204
207
|
|
|
205
208
|
return host.share(options);
|
|
@@ -6,15 +6,24 @@ import { type Config } from '@dxos/config';
|
|
|
6
6
|
import { Context } from '@dxos/context';
|
|
7
7
|
import { createCredentialSignerWithChain, CredentialGenerator } from '@dxos/credentials';
|
|
8
8
|
import { failUndefined } from '@dxos/debug';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
AutomergeHost,
|
|
11
|
+
MetadataStore,
|
|
12
|
+
type LevelDB,
|
|
13
|
+
SnapshotStore,
|
|
14
|
+
SpaceManager,
|
|
15
|
+
valueEncoding,
|
|
16
|
+
} from '@dxos/echo-pipeline';
|
|
17
|
+
import { createTestLevel } from '@dxos/echo-pipeline/testing';
|
|
10
18
|
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
11
|
-
import { createTestLevel } from '@dxos/indexing/testing';
|
|
12
19
|
import { Keyring } from '@dxos/keyring';
|
|
13
20
|
import { MemorySignalManager, MemorySignalManagerContext } from '@dxos/messaging';
|
|
14
21
|
import { MemoryTransportFactory, NetworkManager } from '@dxos/network-manager';
|
|
22
|
+
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
15
23
|
import { createStorage, StorageType, type Storage } from '@dxos/random-access-storage';
|
|
16
24
|
import { BlobStore } from '@dxos/teleport-extension-object-sync';
|
|
17
25
|
|
|
26
|
+
import { InvitationsHandler, InvitationsManager, SpaceInvitationProtocol } from '../invitations';
|
|
18
27
|
import { ClientServicesHost, ServiceContext } from '../services';
|
|
19
28
|
import { DataSpaceManager, type SigningContext } from '../spaces';
|
|
20
29
|
|
|
@@ -42,7 +51,8 @@ export const createServiceContext = async ({
|
|
|
42
51
|
signalManager,
|
|
43
52
|
transportFactory: MemoryTransportFactory,
|
|
44
53
|
});
|
|
45
|
-
const level =
|
|
54
|
+
const level = createTestLevel();
|
|
55
|
+
await level.open();
|
|
46
56
|
|
|
47
57
|
return new ServiceContext(storage, level, networkManager, signalManager);
|
|
48
58
|
};
|
|
@@ -85,6 +95,7 @@ export type TestPeerOpts = {
|
|
|
85
95
|
|
|
86
96
|
export type TestPeerProps = {
|
|
87
97
|
storage?: Storage;
|
|
98
|
+
level?: LevelDB;
|
|
88
99
|
feedStore?: FeedStore<any>;
|
|
89
100
|
metadataStore?: MetadataStore;
|
|
90
101
|
keyring?: Keyring;
|
|
@@ -95,6 +106,7 @@ export type TestPeerProps = {
|
|
|
95
106
|
signingContext?: SigningContext;
|
|
96
107
|
blobStore?: BlobStore;
|
|
97
108
|
automergeHost?: AutomergeHost;
|
|
109
|
+
invitationsManager?: InvitationsManager;
|
|
98
110
|
};
|
|
99
111
|
|
|
100
112
|
export class TestPeer {
|
|
@@ -117,6 +129,10 @@ export class TestPeer {
|
|
|
117
129
|
return (this._props.keyring ??= new Keyring(this.storage.createDirectory('keyring')));
|
|
118
130
|
}
|
|
119
131
|
|
|
132
|
+
get level() {
|
|
133
|
+
return (this._props.level ??= createTestLevel());
|
|
134
|
+
}
|
|
135
|
+
|
|
120
136
|
get feedStore() {
|
|
121
137
|
return (this._props.feedStore ??= new FeedStore({
|
|
122
138
|
factory: new FeedFactory({
|
|
@@ -163,10 +179,12 @@ export class TestPeer {
|
|
|
163
179
|
}
|
|
164
180
|
|
|
165
181
|
get automergeHost() {
|
|
166
|
-
return (this._props.automergeHost ??= new AutomergeHost({
|
|
182
|
+
return (this._props.automergeHost ??= new AutomergeHost({
|
|
183
|
+
db: this.level.sublevel('automerge'),
|
|
184
|
+
}));
|
|
167
185
|
}
|
|
168
186
|
|
|
169
|
-
get dataSpaceManager() {
|
|
187
|
+
get dataSpaceManager(): DataSpaceManager {
|
|
170
188
|
return (this._props.dataSpaceManager ??= new DataSpaceManager(
|
|
171
189
|
this.spaceManager,
|
|
172
190
|
this.metadataStore,
|
|
@@ -174,6 +192,21 @@ export class TestPeer {
|
|
|
174
192
|
this.identity,
|
|
175
193
|
this.feedStore,
|
|
176
194
|
this.automergeHost,
|
|
195
|
+
this.invitationsManager,
|
|
196
|
+
));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
get invitationsManager() {
|
|
200
|
+
return (this._props.invitationsManager ??= new InvitationsManager(
|
|
201
|
+
new InvitationsHandler(this.networkManager),
|
|
202
|
+
(invitation) => {
|
|
203
|
+
if (invitation.kind === Invitation.Kind.SPACE) {
|
|
204
|
+
return new SpaceInvitationProtocol(this.dataSpaceManager, this.identity!, this.keyring, invitation.spaceKey!);
|
|
205
|
+
} else {
|
|
206
|
+
throw new Error('not implemented');
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
this.metadataStore,
|
|
177
210
|
));
|
|
178
211
|
}
|
|
179
212
|
|
|
@@ -182,6 +215,7 @@ export class TestPeer {
|
|
|
182
215
|
}
|
|
183
216
|
|
|
184
217
|
async destroy() {
|
|
218
|
+
await this.level.close();
|
|
185
219
|
await this.storage.reset();
|
|
186
220
|
}
|
|
187
221
|
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const DXOS_VERSION = "0.4.10-main.
|
|
1
|
+
export const DXOS_VERSION = "0.4.10-main.fd8ea31";
|