@dxos/client-services 0.1.35 → 0.1.36-next.ef27157
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-H5IXSSI7.mjs → chunk-OINEQJWM.mjs} +783 -924
- package/dist/lib/browser/chunk-OINEQJWM.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +9 -11
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/testing/index.mjs +212 -74
- package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
- package/dist/lib/node/index.cjs +897 -1039
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/packlets/testing/index.cjs +1057 -1061
- package/dist/lib/node/packlets/testing/index.cjs.map +4 -4
- package/dist/types/src/packlets/identity/identity.d.ts +3 -3
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +18 -0
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/device-invitation-protocol.test.d.ts +2 -0
- package/dist/types/src/packlets/invitations/device-invitation-protocol.test.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/index.d.ts +4 -4
- package/dist/types/src/packlets/invitations/index.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +12 -0
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +38 -0
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/invitations-service.d.ts +13 -15
- package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +22 -0
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/space-invitation-protocol.test.d.ts +2 -0
- package/dist/types/src/packlets/invitations/space-invitation-protocol.test.d.ts.map +1 -0
- package/dist/types/src/packlets/services/service-context.d.ts +6 -4
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts +31 -2
- 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/tests/invitations.test.d.ts +2 -0
- package/dist/types/src/packlets/tests/invitations.test.d.ts.map +1 -0
- package/dist/types/src/packlets/vault/worker-runtime.d.ts +2 -0
- package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
- package/package.json +30 -30
- package/src/packlets/identity/identity.ts +3 -3
- package/src/packlets/invitations/{device-invitations-handler.test.ts → device-invitation-protocol.test.ts} +3 -3
- package/src/packlets/invitations/device-invitation-protocol.ts +83 -0
- package/src/packlets/invitations/index.ts +4 -4
- package/src/packlets/invitations/invitation-protocol.ts +21 -0
- package/src/packlets/invitations/invitations-handler.ts +462 -0
- package/src/packlets/invitations/invitations-service.ts +127 -104
- package/src/packlets/invitations/space-invitation-protocol.test.ts +221 -0
- package/src/packlets/invitations/space-invitation-protocol.ts +117 -0
- package/src/packlets/services/service-context.test.ts +11 -4
- package/src/packlets/services/service-context.ts +34 -17
- package/src/packlets/services/service-host.ts +4 -12
- package/src/packlets/services/service-registry.test.ts +23 -25
- package/src/packlets/spaces/spaces-service.ts +7 -2
- package/src/packlets/testing/invitation-utils.ts +219 -31
- package/src/packlets/testing/test-builder.ts +30 -19
- package/src/packlets/tests/client-services.test.ts +33 -76
- package/src/packlets/tests/halo-profile.test.ts +2 -28
- package/src/packlets/tests/invitations.test.ts +389 -0
- package/src/packlets/tests/spaces-invitations.test.ts +12 -30
- package/src/packlets/tests/spaces.test.ts +6 -28
- package/src/packlets/vault/worker-runtime.ts +4 -0
- package/dist/lib/browser/chunk-H5IXSSI7.mjs.map +0 -7
- package/dist/types/src/packlets/invitations/device-invitations-handler.d.ts +0 -30
- package/dist/types/src/packlets/invitations/device-invitations-handler.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/device-invitations-handler.test.d.ts +0 -2
- package/dist/types/src/packlets/invitations/device-invitations-handler.test.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/device-invitations-service.d.ts +0 -13
- package/dist/types/src/packlets/invitations/device-invitations-service.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/device-invitations-service.test.d.ts +0 -2
- package/dist/types/src/packlets/invitations/device-invitations-service.test.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts +0 -26
- package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/space-invitations-handler.test.d.ts +0 -2
- package/dist/types/src/packlets/invitations/space-invitations-handler.test.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/space-invitations-service.d.ts +0 -16
- package/dist/types/src/packlets/invitations/space-invitations-service.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/space-invitations-service.test.d.ts +0 -2
- package/dist/types/src/packlets/invitations/space-invitations-service.test.d.ts.map +0 -1
- package/src/packlets/invitations/device-invitations-handler.ts +0 -370
- package/src/packlets/invitations/device-invitations-service.test.ts +0 -96
- package/src/packlets/invitations/device-invitations-service.ts +0 -24
- package/src/packlets/invitations/space-invitations-handler.test.ts +0 -246
- package/src/packlets/invitations/space-invitations-handler.ts +0 -463
- package/src/packlets/invitations/space-invitations-service.test.ts +0 -129
- package/src/packlets/invitations/space-invitations-service.ts +0 -35
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import assert from 'node:assert';
|
|
6
|
+
|
|
5
7
|
import { Trigger } from '@dxos/async';
|
|
8
|
+
import { Invitation } from '@dxos/client';
|
|
6
9
|
import { CredentialConsumer, getCredentialAssertion } from '@dxos/credentials';
|
|
7
10
|
import { failUndefined } from '@dxos/debug';
|
|
8
11
|
import {
|
|
@@ -25,7 +28,12 @@ import { Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
|
25
28
|
import { Storage } from '@dxos/random-access-storage';
|
|
26
29
|
|
|
27
30
|
import { CreateIdentityOptions, IdentityManager, JoinIdentityParams } from '../identity';
|
|
28
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
DeviceInvitationProtocol,
|
|
33
|
+
InvitationsHandler,
|
|
34
|
+
InvitationProtocol,
|
|
35
|
+
SpaceInvitationProtocol
|
|
36
|
+
} from '../invitations';
|
|
29
37
|
import { DataSpaceManager } from '../spaces';
|
|
30
38
|
|
|
31
39
|
/**
|
|
@@ -41,13 +49,17 @@ export class ServiceContext {
|
|
|
41
49
|
public readonly keyring: Keyring;
|
|
42
50
|
public readonly spaceManager: SpaceManager;
|
|
43
51
|
public readonly identityManager: IdentityManager;
|
|
44
|
-
public readonly
|
|
45
|
-
|
|
46
|
-
private _deviceSpaceSync?: CredentialConsumer<any>;
|
|
52
|
+
public readonly invitations: InvitationsHandler;
|
|
47
53
|
|
|
48
54
|
// Initialized after identity is initialized.
|
|
49
55
|
public dataSpaceManager?: DataSpaceManager;
|
|
50
|
-
|
|
56
|
+
|
|
57
|
+
private readonly _handlerFactories = new Map<
|
|
58
|
+
Invitation.Kind,
|
|
59
|
+
(invitation: Partial<Invitation>) => InvitationProtocol
|
|
60
|
+
>();
|
|
61
|
+
|
|
62
|
+
private _deviceSpaceSync?: CredentialConsumer<any>;
|
|
51
63
|
|
|
52
64
|
private readonly _instanceId = PublicKey.random().toHex();
|
|
53
65
|
|
|
@@ -84,14 +96,15 @@ export class ServiceContext {
|
|
|
84
96
|
this.spaceManager
|
|
85
97
|
);
|
|
86
98
|
|
|
99
|
+
this.invitations = new InvitationsHandler(this.networkManager);
|
|
100
|
+
|
|
87
101
|
// TODO(burdon): _initialize called in multiple places.
|
|
88
102
|
// TODO(burdon): Call _initialize on success.
|
|
89
|
-
this.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
});
|
|
103
|
+
this._handlerFactories.set(Invitation.Kind.DEVICE, () => new DeviceInvitationProtocol(
|
|
104
|
+
this.keyring,
|
|
105
|
+
() => this.identityManager.identity ?? failUndefined(),
|
|
106
|
+
this._acceptIdentity.bind(this)
|
|
107
|
+
));
|
|
95
108
|
}
|
|
96
109
|
|
|
97
110
|
async open() {
|
|
@@ -135,6 +148,12 @@ export class ServiceContext {
|
|
|
135
148
|
return identity;
|
|
136
149
|
}
|
|
137
150
|
|
|
151
|
+
getInvitationHandler(invitation: Partial<Invitation> & Pick<Invitation, 'kind'>): InvitationProtocol {
|
|
152
|
+
const factory = this._handlerFactories.get(invitation.kind);
|
|
153
|
+
assert(factory, `Unknown invitation kind: ${invitation.kind}`);
|
|
154
|
+
return factory(invitation);
|
|
155
|
+
}
|
|
156
|
+
|
|
138
157
|
private async _acceptIdentity(params: JoinIdentityParams) {
|
|
139
158
|
const identity = await this.identityManager.acceptIdentity(params);
|
|
140
159
|
|
|
@@ -168,12 +187,10 @@ export class ServiceContext {
|
|
|
168
187
|
);
|
|
169
188
|
await this.dataSpaceManager.open();
|
|
170
189
|
|
|
171
|
-
this.
|
|
172
|
-
this.
|
|
173
|
-
this.dataSpaceManager,
|
|
174
|
-
|
|
175
|
-
this.keyring
|
|
176
|
-
);
|
|
190
|
+
this._handlerFactories.set(Invitation.Kind.SPACE, (invitation) => {
|
|
191
|
+
assert(this.dataSpaceManager, 'dataSpaceManager not initialized yet');
|
|
192
|
+
return new SpaceInvitationProtocol(this.dataSpaceManager, signingContext, this.keyring, invitation.spaceKey);
|
|
193
|
+
});
|
|
177
194
|
this.initialized.wake();
|
|
178
195
|
|
|
179
196
|
this._deviceSpaceSync = identity.space.spaceState.registerProcessor({
|
|
@@ -7,7 +7,6 @@ import assert from 'node:assert';
|
|
|
7
7
|
import { Event } from '@dxos/async';
|
|
8
8
|
import { clientServiceBundle, ClientServices, createDefaultModelFactory, PublicKey } from '@dxos/client';
|
|
9
9
|
import { Config } from '@dxos/config';
|
|
10
|
-
import { raise } from '@dxos/debug';
|
|
11
10
|
import { DataServiceImpl } from '@dxos/echo-pipeline';
|
|
12
11
|
import { log } from '@dxos/log';
|
|
13
12
|
import { ModelFactory } from '@dxos/model-factory';
|
|
@@ -20,7 +19,7 @@ import { TracingServiceImpl } from '../deprecated';
|
|
|
20
19
|
import { DevicesServiceImpl } from '../devices';
|
|
21
20
|
import { DevtoolsServiceImpl, DevtoolsHostEvents } from '../devtools';
|
|
22
21
|
import { IdentityServiceImpl } from '../identity';
|
|
23
|
-
import {
|
|
22
|
+
import { InvitationsServiceImpl } from '../invitations';
|
|
24
23
|
import { NetworkServiceImpl } from '../network';
|
|
25
24
|
import { SpacesServiceImpl } from '../spaces';
|
|
26
25
|
import { createStorageObjects } from '../storage';
|
|
@@ -185,18 +184,11 @@ export class ClientServicesHost {
|
|
|
185
184
|
|
|
186
185
|
IdentityService: new IdentityServiceImpl(this._serviceContext),
|
|
187
186
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
DeviceInvitationsService: new DeviceInvitationsServiceImpl(
|
|
191
|
-
this._serviceContext.identityManager,
|
|
192
|
-
this._serviceContext.deviceInvitations
|
|
187
|
+
InvitationsService: new InvitationsServiceImpl(this._serviceContext.invitations, (invitation) =>
|
|
188
|
+
this._serviceContext.getInvitationHandler(invitation)
|
|
193
189
|
),
|
|
194
190
|
|
|
195
|
-
|
|
196
|
-
this._serviceContext.identityManager,
|
|
197
|
-
() => this._serviceContext.spaceInvitations ?? raise(new Error('SpaceInvitations not initialized')),
|
|
198
|
-
() => this._serviceContext.dataSpaceManager ?? raise(new Error('SpaceManager not initialized'))
|
|
199
|
-
),
|
|
191
|
+
DevicesService: new DevicesServiceImpl(this._serviceContext.identityManager),
|
|
200
192
|
|
|
201
193
|
SpacesService: new SpacesServiceImpl(
|
|
202
194
|
this._serviceContext.identityManager,
|
|
@@ -5,25 +5,25 @@
|
|
|
5
5
|
import assert from 'node:assert';
|
|
6
6
|
|
|
7
7
|
import { Trigger } from '@dxos/async';
|
|
8
|
-
import { ClientServices,
|
|
8
|
+
import { ClientServices, InvitationsProxy } from '@dxos/client';
|
|
9
9
|
import { log } from '@dxos/log';
|
|
10
10
|
import { schema } from '@dxos/protocols';
|
|
11
|
-
import { Invitation,
|
|
11
|
+
import { Invitation, InvitationsService } from '@dxos/protocols/proto/dxos/client/services';
|
|
12
12
|
import { createLinkedPorts, createProtoRpcPeer, createServiceBundle } from '@dxos/rpc';
|
|
13
13
|
import { describe, test } from '@dxos/test';
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import { InvitationsServiceImpl } from '../invitations';
|
|
16
16
|
import { createServiceContext } from '../testing';
|
|
17
17
|
import { ServiceRegistry } from './service-registry';
|
|
18
18
|
|
|
19
19
|
// TODO(burdon): Create TestService (that doesn't require peers).
|
|
20
20
|
|
|
21
21
|
type TestServices = {
|
|
22
|
-
|
|
22
|
+
InvitationsService: InvitationsService;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
const serviceBundle = createServiceBundle<TestServices>({
|
|
26
|
-
|
|
26
|
+
InvitationsService: schema.getService('dxos.client.services.InvitationsService')
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
describe('service registry', () => {
|
|
@@ -33,14 +33,11 @@ describe('service registry', () => {
|
|
|
33
33
|
await serviceContext.createIdentity();
|
|
34
34
|
|
|
35
35
|
assert(serviceContext.dataSpaceManager);
|
|
36
|
-
assert(serviceContext.spaceInvitations);
|
|
37
36
|
const space = await serviceContext.dataSpaceManager.createSpace();
|
|
38
37
|
|
|
39
38
|
const serviceRegistry = new ServiceRegistry(serviceBundle, {
|
|
40
|
-
|
|
41
|
-
serviceContext.
|
|
42
|
-
() => serviceContext.spaceInvitations!,
|
|
43
|
-
() => serviceContext.dataSpaceManager!
|
|
39
|
+
InvitationsService: new InvitationsServiceImpl(serviceContext.invitations, (invitation) =>
|
|
40
|
+
serviceContext.getInvitationHandler(invitation)
|
|
44
41
|
)
|
|
45
42
|
});
|
|
46
43
|
|
|
@@ -66,21 +63,22 @@ describe('service registry', () => {
|
|
|
66
63
|
const done = new Trigger(); // createRpcServer
|
|
67
64
|
|
|
68
65
|
{
|
|
69
|
-
const spaceInvitationsProxy = new
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
66
|
+
const spaceInvitationsProxy = new InvitationsProxy(proxy.rpc.InvitationsService, () => ({
|
|
67
|
+
kind: Invitation.Kind.SPACE,
|
|
68
|
+
spaceKey: space.key
|
|
69
|
+
}));
|
|
70
|
+
const observer = spaceInvitationsProxy.createInvitation();
|
|
71
|
+
observer.subscribe((invitation: Invitation) => {
|
|
72
|
+
switch (invitation.state) {
|
|
73
|
+
case Invitation.State.CONNECTING: {
|
|
74
|
+
log('connecting', invitation);
|
|
75
|
+
void observer.cancel();
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
case Invitation.State.CANCELLED: {
|
|
80
|
+
done.wake();
|
|
81
|
+
}
|
|
84
82
|
}
|
|
85
83
|
});
|
|
86
84
|
}
|
|
@@ -149,10 +149,15 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
149
149
|
spaceKey: space.key,
|
|
150
150
|
state: space.state,
|
|
151
151
|
pipeline: {
|
|
152
|
-
|
|
152
|
+
controlFeeds: space.inner.controlPipeline.state.feeds.map((feed) => feed.key),
|
|
153
153
|
currentControlTimeframe: space.inner.controlPipeline.state.timeframe,
|
|
154
|
+
targetControlTimeframe: space.inner.controlPipeline.state.targetTimeframe,
|
|
155
|
+
totalControlTimeframe: space.inner.controlPipeline.state.endTimeframe,
|
|
156
|
+
|
|
157
|
+
dataFeeds: space.dataPipeline.pipelineState?.feeds.map((feed) => feed.key) ?? [],
|
|
154
158
|
currentDataTimeframe: space.dataPipeline.pipelineState?.timeframe,
|
|
155
|
-
targetDataTimeframe: space.dataPipeline.pipelineState?.targetTimeframe
|
|
159
|
+
targetDataTimeframe: space.dataPipeline.pipelineState?.targetTimeframe,
|
|
160
|
+
totalDataTimeframe: space.dataPipeline.pipelineState?.endTimeframe
|
|
156
161
|
},
|
|
157
162
|
members: Array.from(space.inner.spaceState.members.values()).map((member) => ({
|
|
158
163
|
identity: {
|
|
@@ -5,39 +5,227 @@
|
|
|
5
5
|
import assert from 'node:assert';
|
|
6
6
|
|
|
7
7
|
import { Trigger } from '@dxos/async';
|
|
8
|
-
import {
|
|
9
|
-
|
|
8
|
+
import {
|
|
9
|
+
AuthenticatingInvitationObservable,
|
|
10
|
+
CancellableInvitationObservable,
|
|
11
|
+
Client,
|
|
12
|
+
EchoProxy,
|
|
13
|
+
HaloProxy,
|
|
14
|
+
InvitationsProxy,
|
|
15
|
+
SpaceProxy
|
|
16
|
+
} from '@dxos/client';
|
|
10
17
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
11
18
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
19
|
+
import { ServiceContext } from '../services';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Strip secrets from invitation before giving it to the peer.
|
|
23
|
+
*/
|
|
24
|
+
export const sanitizeInvitation = (invitation: Invitation): Invitation => {
|
|
25
|
+
return {
|
|
26
|
+
invitationId: invitation.invitationId,
|
|
27
|
+
type: invitation.type,
|
|
28
|
+
kind: invitation.kind,
|
|
29
|
+
authMethod: invitation.authMethod,
|
|
30
|
+
swarmKey: invitation.swarmKey,
|
|
31
|
+
state: invitation.state,
|
|
32
|
+
timeout: invitation.timeout
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type PerformInvitationCallbacks<T> = {
|
|
37
|
+
onConnecting?: (value: T) => boolean | void;
|
|
38
|
+
onConnected?: (value: T) => boolean | void;
|
|
39
|
+
onReady?: (value: T) => boolean | void;
|
|
40
|
+
onAuthenticating?: (value: T) => boolean | void;
|
|
41
|
+
onSuccess?: (value: T) => boolean | void;
|
|
42
|
+
onCancelled?: (value: T) => boolean | void;
|
|
43
|
+
onTimeout?: (value: T) => boolean | void;
|
|
44
|
+
onError?: (value: T) => boolean | void;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type PerformInvitationParams = {
|
|
48
|
+
host: ServiceContext | InvitationsProxy | HaloProxy | SpaceProxy;
|
|
49
|
+
guest: ServiceContext | InvitationsProxy | HaloProxy | EchoProxy | Client;
|
|
50
|
+
options?: Partial<Invitation>;
|
|
51
|
+
hooks?: {
|
|
52
|
+
host?: PerformInvitationCallbacks<CancellableInvitationObservable>;
|
|
53
|
+
guest?: PerformInvitationCallbacks<AuthenticatingInvitationObservable>;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export type Result = { invitation?: Invitation; error?: Error };
|
|
58
|
+
|
|
59
|
+
export const performInvitation = ({
|
|
60
|
+
host,
|
|
61
|
+
guest,
|
|
62
|
+
options,
|
|
63
|
+
hooks
|
|
64
|
+
}: PerformInvitationParams): [Promise<Result>, Promise<Result>] => {
|
|
65
|
+
const hostComplete = new Trigger<Result>();
|
|
66
|
+
const guestComplete = new Trigger<Result>();
|
|
67
|
+
const authCode = new Trigger<string>();
|
|
68
|
+
|
|
69
|
+
const hostObservable = createInvitation(host, options);
|
|
70
|
+
hostObservable.subscribe(
|
|
71
|
+
async (hostInvitation: Invitation) => {
|
|
72
|
+
switch (hostInvitation.state) {
|
|
73
|
+
case Invitation.State.CONNECTING: {
|
|
74
|
+
if (hooks?.host?.onConnecting?.(hostObservable)) {
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
const guestObservable = acceptInvitation(guest, hostInvitation);
|
|
78
|
+
guestObservable.subscribe(
|
|
79
|
+
async (guestInvitation: Invitation) => {
|
|
80
|
+
switch (guestInvitation.state) {
|
|
81
|
+
case Invitation.State.CONNECTING: {
|
|
82
|
+
if (hooks?.guest?.onConnecting?.(guestObservable)) {
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
assert(hostInvitation.swarmKey!.equals(guestInvitation.swarmKey!));
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
case Invitation.State.CONNECTED: {
|
|
90
|
+
hooks?.guest?.onConnected?.(guestObservable);
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
case Invitation.State.READY_FOR_AUTHENTICATION: {
|
|
95
|
+
if (hooks?.guest?.onReady?.(guestObservable)) {
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
await guestObservable.authenticate(await authCode.wait());
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
case Invitation.State.AUTHENTICATING: {
|
|
103
|
+
hooks?.guest?.onAuthenticating?.(guestObservable);
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
case Invitation.State.SUCCESS: {
|
|
108
|
+
if (hooks?.guest?.onSuccess?.(guestObservable)) {
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
guestComplete.wake({ invitation: guestInvitation });
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
case Invitation.State.CANCELLED: {
|
|
116
|
+
if (hooks?.guest?.onCancelled?.(guestObservable)) {
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
guestComplete.wake({ invitation: guestInvitation });
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
case Invitation.State.TIMEOUT: {
|
|
124
|
+
if (hooks?.guest?.onTimeout?.(guestObservable)) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
guestComplete.wake({ invitation: guestInvitation });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
(error: Error) => {
|
|
132
|
+
if (hooks?.guest?.onError?.(guestObservable)) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
guestComplete.wake({ error });
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
case Invitation.State.CONNECTED: {
|
|
142
|
+
hooks?.host?.onConnected?.(hostObservable);
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
case Invitation.State.READY_FOR_AUTHENTICATION: {
|
|
147
|
+
if (hooks?.host?.onReady?.(hostObservable)) {
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
if (hostInvitation.authCode) {
|
|
151
|
+
authCode.wake(hostInvitation.authCode);
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
case Invitation.State.AUTHENTICATING: {
|
|
157
|
+
hooks?.host?.onAuthenticating?.(hostObservable);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
case Invitation.State.SUCCESS: {
|
|
162
|
+
if (hooks?.host?.onSuccess?.(hostObservable)) {
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
hostComplete.wake({ invitation: hostInvitation });
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
case Invitation.State.CANCELLED: {
|
|
170
|
+
if (hooks?.host?.onCancelled?.(hostObservable)) {
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
hostComplete.wake({ invitation: hostInvitation });
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
case Invitation.State.TIMEOUT: {
|
|
178
|
+
if (hooks?.host?.onTimeout?.(hostObservable)) {
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
hostComplete.wake({ invitation: hostInvitation });
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
36
185
|
},
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
186
|
+
(error: Error) => {
|
|
187
|
+
if (hooks?.host?.onError?.(hostObservable)) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
hostComplete.wake({ error });
|
|
191
|
+
}
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
return [hostComplete.wait(), guestComplete.wait()];
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const createInvitation = (
|
|
198
|
+
host: ServiceContext | InvitationsProxy | HaloProxy | SpaceProxy,
|
|
199
|
+
options?: Partial<Invitation>
|
|
200
|
+
): CancellableInvitationObservable => {
|
|
201
|
+
options ??= {
|
|
202
|
+
authMethod: Invitation.AuthMethod.NONE,
|
|
203
|
+
...(options ?? {})
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
if (host instanceof InvitationsProxy || host instanceof HaloProxy || host instanceof SpaceProxy) {
|
|
207
|
+
return host.createInvitation(options);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const hostHandler = host.getInvitationHandler({ kind: Invitation.Kind.SPACE, ...options });
|
|
211
|
+
return host.invitations.createInvitation(hostHandler, options);
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const acceptInvitation = (
|
|
215
|
+
guest: ServiceContext | InvitationsProxy | HaloProxy | EchoProxy | Client,
|
|
216
|
+
invitation: Invitation
|
|
217
|
+
): AuthenticatingInvitationObservable => {
|
|
218
|
+
invitation = sanitizeInvitation(invitation);
|
|
219
|
+
|
|
220
|
+
if (
|
|
221
|
+
guest instanceof InvitationsProxy ||
|
|
222
|
+
guest instanceof HaloProxy ||
|
|
223
|
+
guest instanceof EchoProxy ||
|
|
224
|
+
guest instanceof Client
|
|
225
|
+
) {
|
|
226
|
+
return guest.acceptInvitation(invitation);
|
|
227
|
+
}
|
|
40
228
|
|
|
41
|
-
|
|
42
|
-
|
|
229
|
+
const guestHandler = guest.getInvitationHandler({ kind: invitation.kind });
|
|
230
|
+
return guest.invitations.acceptInvitation(guestHandler, invitation);
|
|
43
231
|
};
|
|
@@ -150,27 +150,38 @@ export const joinCommonSpace = async ([initialPeer, ...peers]: Client[], spaceKe
|
|
|
150
150
|
const hostDone = new Trigger<Invitation>();
|
|
151
151
|
const guestDone = new Trigger<Invitation>();
|
|
152
152
|
|
|
153
|
-
const
|
|
153
|
+
const hostObservable = rootSpace.createInvitation({ authMethod: Invitation.AuthMethod.NONE });
|
|
154
154
|
log('invitation created');
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
155
|
+
hostObservable.subscribe(
|
|
156
|
+
(hostInvitation) => {
|
|
157
|
+
switch (hostInvitation.state) {
|
|
158
|
+
case Invitation.State.CONNECTING: {
|
|
159
|
+
const guestObservable = peer.acceptInvitation(hostInvitation);
|
|
160
|
+
log('invitation accepted');
|
|
161
|
+
|
|
162
|
+
guestObservable.subscribe(
|
|
163
|
+
(guestInvitation) => {
|
|
164
|
+
switch (guestInvitation.state) {
|
|
165
|
+
case Invitation.State.SUCCESS: {
|
|
166
|
+
guestDone.wake(guestInvitation);
|
|
167
|
+
log('invitation guestDone');
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
(err) => raise(err)
|
|
173
|
+
);
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
case Invitation.State.SUCCESS: {
|
|
178
|
+
hostDone.wake(hostInvitation);
|
|
179
|
+
log('invitation hostDone');
|
|
180
|
+
}
|
|
181
|
+
}
|
|
167
182
|
},
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
log('invitation hostDone');
|
|
171
|
-
},
|
|
172
|
-
onError: (err) => raise(err)
|
|
173
|
-
});
|
|
183
|
+
(err) => raise(err)
|
|
184
|
+
);
|
|
174
185
|
|
|
175
186
|
await Promise.all([hostDone.wait(), guestDone.wait()]);
|
|
176
187
|
})
|