@dxos/client-services 0.1.41 → 0.1.45-next.45667d4
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-T73F4MV4.mjs → chunk-IHSMRQ3L.mjs} +985 -867
- package/dist/lib/browser/chunk-IHSMRQ3L.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +7 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/testing/index.mjs +121 -297
- package/dist/lib/browser/packlets/testing/index.mjs.map +4 -4
- package/dist/lib/node/index.cjs +589 -469
- 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 +688 -740
- package/dist/lib/node/packlets/testing/index.cjs.map +4 -4
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/packlets/devices/devices-service.d.ts +1 -1
- package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/devtools.d.ts +4 -2
- package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/network.d.ts +5 -4
- package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/authenticator.d.ts +1 -1
- package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-manager.d.ts +2 -4
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-extension.d.ts +2 -3
- package/dist/types/src/packlets/invitations/invitation-extension.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +1 -3
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +1 -2
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/network/network-service.d.ts +6 -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 +2 -2
- package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
- package/dist/types/src/packlets/services/index.d.ts +0 -1
- package/dist/types/src/packlets/services/index.d.ts.map +1 -1
- package/dist/types/src/packlets/services/local-client-services.d.ts +1 -1
- package/dist/types/src/packlets/services/local-client-services.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +4 -2
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +16 -9
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +12 -7
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +15 -10
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/genesis.d.ts +5 -0
- package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -0
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +4 -4
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts +2 -1
- package/dist/types/src/packlets/spaces/spaces-service.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 +1 -1
- package/dist/types/src/packlets/testing/index.d.ts +0 -1
- package/dist/types/src/packlets/testing/index.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts +13 -7
- package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts +35 -32
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts +1 -1
- package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/iframe-proxy-runtime.d.ts +5 -2
- package/dist/types/src/packlets/vault/iframe-proxy-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/vault-resource-lock.d.ts +1 -1
- package/dist/types/src/packlets/vault/vault-resource-lock.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/worker-runtime.d.ts +1 -1
- package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/worker-session.d.ts +4 -7
- package/dist/types/src/packlets/vault/worker-session.d.ts.map +1 -1
- package/package.json +30 -31
- package/src/index.ts +1 -0
- package/src/packlets/devices/devices-service.ts +5 -5
- package/src/packlets/devtools/devtools.ts +25 -4
- package/src/packlets/devtools/feeds.ts +10 -10
- package/src/packlets/devtools/keys.ts +6 -6
- package/src/packlets/devtools/network.ts +14 -13
- package/src/packlets/devtools/spaces.ts +4 -4
- package/src/packlets/identity/authenticator.test.ts +1 -1
- package/src/packlets/identity/authenticator.ts +2 -2
- package/src/packlets/identity/identity-manager.test.ts +17 -13
- package/src/packlets/identity/identity-manager.ts +21 -22
- package/src/packlets/identity/identity-service.ts +3 -3
- package/src/packlets/identity/identity.test.ts +65 -36
- package/src/packlets/identity/identity.ts +17 -17
- package/src/packlets/invitations/device-invitation-protocol.test.ts +1 -1
- package/src/packlets/invitations/device-invitation-protocol.ts +7 -7
- package/src/packlets/invitations/invitation-extension.ts +16 -27
- package/src/packlets/invitations/invitations-handler.ts +17 -25
- package/src/packlets/invitations/invitations-service.ts +11 -11
- package/src/packlets/invitations/space-invitation-protocol.test.ts +9 -9
- package/src/packlets/invitations/space-invitation-protocol.ts +11 -12
- package/src/packlets/logging/logging-service.ts +8 -3
- package/src/packlets/network/network-service.test.ts +8 -8
- package/src/packlets/network/network-service.ts +20 -8
- package/src/packlets/services/client-rpc-server.ts +5 -5
- package/src/packlets/services/index.ts +0 -1
- package/src/packlets/services/local-client-services.ts +1 -1
- package/src/packlets/services/service-context.test.ts +3 -3
- package/src/packlets/services/service-context.ts +26 -24
- package/src/packlets/services/service-host.test.ts +6 -6
- package/src/packlets/services/service-host.ts +57 -31
- package/src/packlets/services/service-registry.test.ts +20 -38
- package/src/packlets/spaces/data-space-manager.test.ts +17 -29
- package/src/packlets/spaces/data-space-manager.ts +29 -35
- package/src/packlets/spaces/data-space.ts +73 -47
- package/src/packlets/spaces/genesis.ts +81 -0
- package/src/packlets/spaces/notarization-plugin.test.ts +2 -2
- package/src/packlets/spaces/notarization-plugin.ts +12 -12
- package/src/packlets/spaces/spaces-service.test.ts +2 -2
- package/src/packlets/spaces/spaces-service.ts +21 -10
- package/src/packlets/storage/storage.ts +3 -3
- package/src/packlets/system/system-service.test.ts +1 -1
- package/src/packlets/system/system-service.ts +1 -1
- package/src/packlets/testing/credential-utils.ts +4 -4
- package/src/packlets/testing/index.ts +0 -1
- package/src/packlets/testing/invitation-utils.ts +28 -33
- package/src/packlets/testing/test-builder.ts +132 -168
- package/src/packlets/vault/iframe-host-runtime.ts +8 -11
- package/src/packlets/vault/iframe-proxy-runtime.ts +25 -9
- package/src/packlets/vault/shell-runtime.ts +4 -4
- package/src/packlets/vault/vault-resource-lock.ts +2 -2
- package/src/packlets/vault/worker-runtime.ts +7 -9
- package/src/packlets/vault/worker-session.ts +24 -45
- package/dist/lib/browser/chunk-T73F4MV4.mjs.map +0 -7
- package/dist/types/src/packlets/services/utils.d.ts +0 -7
- package/dist/types/src/packlets/services/utils.d.ts.map +0 -1
- package/dist/types/src/packlets/testing/host-test-builder.d.ts +0 -43
- package/dist/types/src/packlets/testing/host-test-builder.d.ts.map +0 -1
- package/dist/types/src/packlets/tests/client-services.test.d.ts +0 -2
- package/dist/types/src/packlets/tests/client-services.test.d.ts.map +0 -1
- package/dist/types/src/packlets/tests/client.test.d.ts +0 -2
- package/dist/types/src/packlets/tests/client.test.d.ts.map +0 -1
- package/dist/types/src/packlets/tests/halo-credentials.test.d.ts +0 -2
- package/dist/types/src/packlets/tests/halo-credentials.test.d.ts.map +0 -1
- package/dist/types/src/packlets/tests/halo-persistent.test.d.ts +0 -2
- package/dist/types/src/packlets/tests/halo-persistent.test.d.ts.map +0 -1
- package/dist/types/src/packlets/tests/halo-profile.test.d.ts +0 -2
- package/dist/types/src/packlets/tests/halo-profile.test.d.ts.map +0 -1
- package/dist/types/src/packlets/tests/invitations.test.d.ts +0 -2
- package/dist/types/src/packlets/tests/invitations.test.d.ts.map +0 -1
- package/dist/types/src/packlets/tests/shared-worker.test.d.ts +0 -2
- package/dist/types/src/packlets/tests/shared-worker.test.d.ts.map +0 -1
- package/dist/types/src/packlets/tests/spaces-invitations.test.d.ts +0 -2
- package/dist/types/src/packlets/tests/spaces-invitations.test.d.ts.map +0 -1
- package/dist/types/src/packlets/tests/spaces.test.d.ts +0 -2
- package/dist/types/src/packlets/tests/spaces.test.d.ts.map +0 -1
- package/dist/types/src/packlets/tests/text.test.d.ts +0 -2
- package/dist/types/src/packlets/tests/text.test.d.ts.map +0 -1
- package/src/packlets/services/utils.ts +0 -53
- package/src/packlets/testing/host-test-builder.ts +0 -163
- package/src/packlets/tests/client-services.test.ts +0 -222
- package/src/packlets/tests/client.test.ts +0 -140
- package/src/packlets/tests/halo-credentials.test.ts +0 -94
- package/src/packlets/tests/halo-persistent.test.ts +0 -53
- package/src/packlets/tests/halo-profile.test.ts +0 -48
- package/src/packlets/tests/invitations.test.ts +0 -389
- package/src/packlets/tests/shared-worker.test.ts +0 -92
- package/src/packlets/tests/spaces-invitations.test.ts +0 -46
- package/src/packlets/tests/spaces.test.ts +0 -147
- package/src/packlets/tests/text.test.ts +0 -206
|
@@ -5,15 +5,7 @@
|
|
|
5
5
|
import assert from 'node:assert';
|
|
6
6
|
|
|
7
7
|
import { Trigger } from '@dxos/async';
|
|
8
|
-
import {
|
|
9
|
-
AuthenticatingInvitationObservable,
|
|
10
|
-
CancellableInvitationObservable,
|
|
11
|
-
Client,
|
|
12
|
-
EchoProxy,
|
|
13
|
-
HaloProxy,
|
|
14
|
-
InvitationsProxy,
|
|
15
|
-
SpaceProxy
|
|
16
|
-
} from '@dxos/client';
|
|
8
|
+
import { AuthenticatingInvitationObservable, CancellableInvitationObservable } from '@dxos/client-protocol';
|
|
17
9
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
18
10
|
|
|
19
11
|
import { ServiceContext } from '../services';
|
|
@@ -29,10 +21,18 @@ export const sanitizeInvitation = (invitation: Invitation): Invitation => {
|
|
|
29
21
|
authMethod: invitation.authMethod,
|
|
30
22
|
swarmKey: invitation.swarmKey,
|
|
31
23
|
state: invitation.state,
|
|
32
|
-
timeout: invitation.timeout
|
|
24
|
+
timeout: invitation.timeout,
|
|
33
25
|
};
|
|
34
26
|
};
|
|
35
27
|
|
|
28
|
+
export type InvitationHost = {
|
|
29
|
+
createInvitation(options?: Partial<Invitation>): CancellableInvitationObservable;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type InvitationGuest = {
|
|
33
|
+
acceptInvitation(invitation: Invitation): AuthenticatingInvitationObservable;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
36
|
export type PerformInvitationCallbacks<T> = {
|
|
37
37
|
onConnecting?: (value: T) => boolean | void;
|
|
38
38
|
onConnected?: (value: T) => boolean | void;
|
|
@@ -45,8 +45,8 @@ export type PerformInvitationCallbacks<T> = {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
export type PerformInvitationParams = {
|
|
48
|
-
host: ServiceContext |
|
|
49
|
-
guest: ServiceContext |
|
|
48
|
+
host: ServiceContext | InvitationHost;
|
|
49
|
+
guest: ServiceContext | InvitationGuest;
|
|
50
50
|
options?: Partial<Invitation>;
|
|
51
51
|
hooks?: {
|
|
52
52
|
host?: PerformInvitationCallbacks<CancellableInvitationObservable>;
|
|
@@ -60,7 +60,7 @@ export const performInvitation = ({
|
|
|
60
60
|
host,
|
|
61
61
|
guest,
|
|
62
62
|
options,
|
|
63
|
-
hooks
|
|
63
|
+
hooks,
|
|
64
64
|
}: PerformInvitationParams): [Promise<Result>, Promise<Result>] => {
|
|
65
65
|
const hostComplete = new Trigger<Result>();
|
|
66
66
|
const guestComplete = new Trigger<Result>();
|
|
@@ -133,7 +133,7 @@ export const performInvitation = ({
|
|
|
133
133
|
return;
|
|
134
134
|
}
|
|
135
135
|
guestComplete.wake({ error });
|
|
136
|
-
}
|
|
136
|
+
},
|
|
137
137
|
);
|
|
138
138
|
break;
|
|
139
139
|
}
|
|
@@ -188,44 +188,39 @@ export const performInvitation = ({
|
|
|
188
188
|
return;
|
|
189
189
|
}
|
|
190
190
|
hostComplete.wake({ error });
|
|
191
|
-
}
|
|
191
|
+
},
|
|
192
192
|
);
|
|
193
193
|
|
|
194
194
|
return [hostComplete.wait(), guestComplete.wait()];
|
|
195
195
|
};
|
|
196
196
|
|
|
197
197
|
const createInvitation = (
|
|
198
|
-
host: ServiceContext |
|
|
199
|
-
options?: Partial<Invitation
|
|
198
|
+
host: ServiceContext | InvitationHost,
|
|
199
|
+
options?: Partial<Invitation>,
|
|
200
200
|
): CancellableInvitationObservable => {
|
|
201
201
|
options ??= {
|
|
202
202
|
authMethod: Invitation.AuthMethod.NONE,
|
|
203
|
-
...(options ?? {})
|
|
203
|
+
...(options ?? {}),
|
|
204
204
|
};
|
|
205
205
|
|
|
206
|
-
if (host instanceof
|
|
207
|
-
|
|
206
|
+
if (host instanceof ServiceContext) {
|
|
207
|
+
const hostHandler = host.getInvitationHandler({ kind: Invitation.Kind.SPACE, ...options });
|
|
208
|
+
return host.invitations.createInvitation(hostHandler, options);
|
|
208
209
|
}
|
|
209
210
|
|
|
210
|
-
|
|
211
|
-
return host.invitations.createInvitation(hostHandler, options);
|
|
211
|
+
return host.createInvitation(options);
|
|
212
212
|
};
|
|
213
213
|
|
|
214
214
|
const acceptInvitation = (
|
|
215
|
-
guest: ServiceContext |
|
|
216
|
-
invitation: Invitation
|
|
215
|
+
guest: ServiceContext | InvitationGuest,
|
|
216
|
+
invitation: Invitation,
|
|
217
217
|
): AuthenticatingInvitationObservable => {
|
|
218
218
|
invitation = sanitizeInvitation(invitation);
|
|
219
219
|
|
|
220
|
-
if (
|
|
221
|
-
guest
|
|
222
|
-
guest
|
|
223
|
-
guest instanceof EchoProxy ||
|
|
224
|
-
guest instanceof Client
|
|
225
|
-
) {
|
|
226
|
-
return guest.acceptInvitation(invitation);
|
|
220
|
+
if (guest instanceof ServiceContext) {
|
|
221
|
+
const guestHandler = guest.getInvitationHandler({ kind: invitation.kind });
|
|
222
|
+
return guest.invitations.acceptInvitation(guestHandler, invitation);
|
|
227
223
|
}
|
|
228
224
|
|
|
229
|
-
|
|
230
|
-
return guest.invitations.acceptInvitation(guestHandler, invitation);
|
|
225
|
+
return guest.acceptInvitation(invitation);
|
|
231
226
|
};
|
|
@@ -1,193 +1,157 @@
|
|
|
1
1
|
//
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
import { asyncTimeout, Trigger } from '@dxos/async';
|
|
8
|
-
import { Client, ClientServices, ClientServicesProxy, createDefaultModelFactory, Invitation } from '@dxos/client';
|
|
5
|
+
import { createDefaultModelFactory } from '@dxos/client-protocol';
|
|
9
6
|
import { Config } from '@dxos/config';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import { MemorySignalManager, MemorySignalManagerContext
|
|
16
|
-
import {
|
|
17
|
-
import { Storage } from '@dxos/random-access-storage';
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
export const testConfigWithLocalSignal = new Config({
|
|
23
|
-
version: 1,
|
|
24
|
-
runtime: {
|
|
25
|
-
services: {
|
|
26
|
-
signaling: [
|
|
27
|
-
{
|
|
28
|
-
// TODO(burdon): Port numbers and global consts?
|
|
29
|
-
server: 'ws://localhost:4000/.well-known/dx/signal'
|
|
30
|
-
}
|
|
31
|
-
]
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
});
|
|
7
|
+
import { createCredentialSignerWithChain, CredentialGenerator } from '@dxos/credentials';
|
|
8
|
+
import { SnapshotStore, DataPipeline, MetadataStore, SpaceManager, valueEncoding } from '@dxos/echo-pipeline';
|
|
9
|
+
import { testLocalDatabase } from '@dxos/echo-pipeline/testing';
|
|
10
|
+
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
11
|
+
import { Keyring } from '@dxos/keyring';
|
|
12
|
+
import { MemorySignalManager, MemorySignalManagerContext } from '@dxos/messaging';
|
|
13
|
+
import { MemoryTransportFactory, NetworkManager } from '@dxos/network-manager';
|
|
14
|
+
import { createStorage, Storage, StorageType } from '@dxos/random-access-storage';
|
|
15
|
+
|
|
16
|
+
import { ClientServicesHost, ServiceContext } from '../services';
|
|
17
|
+
import { SigningContext } from '../spaces';
|
|
35
18
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
export class TestBuilder {
|
|
40
|
-
private readonly _config: Config;
|
|
19
|
+
//
|
|
20
|
+
// TODO(burdon): Replace with test builder.
|
|
21
|
+
//
|
|
41
22
|
|
|
42
|
-
|
|
23
|
+
export const createServiceHost = (config: Config, signalManagerContext: MemorySignalManagerContext) => {
|
|
24
|
+
return new ClientServicesHost({
|
|
25
|
+
config,
|
|
26
|
+
signalManager: new MemorySignalManager(signalManagerContext),
|
|
27
|
+
transportFactory: MemoryTransportFactory,
|
|
28
|
+
});
|
|
29
|
+
};
|
|
43
30
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
31
|
+
export const createServiceContext = ({
|
|
32
|
+
signalContext = new MemorySignalManagerContext(),
|
|
33
|
+
storage = createStorage({ type: StorageType.RAM }),
|
|
34
|
+
}: {
|
|
35
|
+
signalContext?: MemorySignalManagerContext;
|
|
36
|
+
storage?: Storage;
|
|
37
|
+
} = {}) => {
|
|
38
|
+
const signalManager = new MemorySignalManager(signalContext);
|
|
39
|
+
const networkManager = new NetworkManager({
|
|
40
|
+
signalManager,
|
|
41
|
+
transportFactory: MemoryTransportFactory,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const modelFactory = createDefaultModelFactory();
|
|
45
|
+
return new ServiceContext(storage, networkManager, signalManager, modelFactory);
|
|
46
|
+
};
|
|
52
47
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
48
|
+
export const createPeers = async (numPeers: number) => {
|
|
49
|
+
const signalContext = new MemorySignalManagerContext();
|
|
56
50
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
signalManager: new WebsocketSignalManager(signals),
|
|
66
|
-
transportFactory: createWebRTCTransportFactory({
|
|
67
|
-
iceServers: this._config.get('runtime.services.ice')
|
|
68
|
-
})
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Memory transport with shared context.
|
|
73
|
-
return new NetworkManager({
|
|
74
|
-
log: true,
|
|
75
|
-
signalManager: new MemorySignalManager(this._signalManagerContext),
|
|
76
|
-
transportFactory: MemoryTransportFactory
|
|
77
|
-
});
|
|
78
|
-
}
|
|
51
|
+
return await Promise.all(
|
|
52
|
+
Array.from(Array(numPeers)).map(async () => {
|
|
53
|
+
const peer = createServiceContext({ signalContext });
|
|
54
|
+
await peer.open();
|
|
55
|
+
return peer;
|
|
56
|
+
}),
|
|
57
|
+
);
|
|
58
|
+
};
|
|
79
59
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return new ClientServicesHost({
|
|
85
|
-
config: this._config,
|
|
86
|
-
modelFactory: this._modelFactory,
|
|
87
|
-
networkManager: this.networkManager,
|
|
88
|
-
storage: this.storage
|
|
89
|
-
});
|
|
90
|
-
}
|
|
60
|
+
export const createIdentity = async (peer: ServiceContext) => {
|
|
61
|
+
await peer.createIdentity();
|
|
62
|
+
return peer;
|
|
63
|
+
};
|
|
91
64
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
modelFactory: this._modelFactory,
|
|
99
|
-
networkManager: this.networkManager,
|
|
100
|
-
storage: this.storage
|
|
101
|
-
});
|
|
102
|
-
}
|
|
65
|
+
// TODO(burdon): Remove @dxos/client-testing.
|
|
66
|
+
// TODO(burdon): Create builder and make configurable.
|
|
67
|
+
export const syncItemsLocal = async (db1: DataPipeline, db2: DataPipeline) => {
|
|
68
|
+
await testLocalDatabase(db1, db2);
|
|
69
|
+
await testLocalDatabase(db2, db1);
|
|
70
|
+
};
|
|
103
71
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const server = createProtoRpcPeer({
|
|
110
|
-
exposed: host.descriptors,
|
|
111
|
-
handlers: host.services as ClientServices,
|
|
112
|
-
port: hostPort
|
|
113
|
-
});
|
|
114
|
-
// TODO(dmaretskyi): Refactor.
|
|
115
|
-
|
|
116
|
-
const client = new Client({ services: new ClientServicesProxy(proxyPort) });
|
|
117
|
-
return [client, server];
|
|
72
|
+
export class TestBuilder {
|
|
73
|
+
public readonly signalContext = new MemorySignalManagerContext();
|
|
74
|
+
|
|
75
|
+
createPeer(): TestPeer {
|
|
76
|
+
return new TestPeer(this.signalContext);
|
|
118
77
|
}
|
|
119
78
|
}
|
|
120
79
|
|
|
121
|
-
export
|
|
122
|
-
|
|
80
|
+
export type TestPeerProps = {
|
|
81
|
+
storage?: Storage;
|
|
82
|
+
feedStore?: FeedStore<any>;
|
|
83
|
+
metadataStore?: MetadataStore;
|
|
84
|
+
keyring?: Keyring;
|
|
85
|
+
networkManager?: NetworkManager;
|
|
86
|
+
spaceManager?: SpaceManager;
|
|
87
|
+
snapshotStore?: SnapshotStore;
|
|
88
|
+
};
|
|
123
89
|
|
|
124
|
-
|
|
90
|
+
export class TestPeer {
|
|
91
|
+
private _props: TestPeerProps = {};
|
|
125
92
|
|
|
126
|
-
|
|
127
|
-
// TODO(dmaretskiy): await result.waitToBeProcessed()
|
|
128
|
-
assert(create._itemManager.entities.has(result.objectsUpdated[0].id));
|
|
93
|
+
constructor(private readonly signalContext: MemorySignalManagerContext) {}
|
|
129
94
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
);
|
|
95
|
+
get storage() {
|
|
96
|
+
return (this._props.storage ??= createStorage({ type: StorageType.RAM }));
|
|
97
|
+
}
|
|
134
98
|
|
|
135
|
-
|
|
136
|
-
|
|
99
|
+
get keyring() {
|
|
100
|
+
return (this._props.keyring ??= new Keyring(this.storage.createDirectory('keyring')));
|
|
101
|
+
}
|
|
137
102
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
103
|
+
get feedStore() {
|
|
104
|
+
return (this._props.feedStore ??= new FeedStore({
|
|
105
|
+
factory: new FeedFactory({
|
|
106
|
+
root: this.storage.createDirectory('feeds'),
|
|
107
|
+
signer: this.keyring,
|
|
108
|
+
hypercore: {
|
|
109
|
+
valueEncoding,
|
|
110
|
+
},
|
|
111
|
+
}),
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
141
114
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
115
|
+
get metadataStore() {
|
|
116
|
+
return (this._props.metadataStore ??= new MetadataStore(this.storage.createDirectory('metadata')));
|
|
117
|
+
}
|
|
145
118
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
await Promise.all(
|
|
151
|
-
peers.map(async (peer) => {
|
|
152
|
-
const hostDone = new Trigger<Invitation>();
|
|
153
|
-
const guestDone = new Trigger<Invitation>();
|
|
154
|
-
|
|
155
|
-
const hostObservable = rootSpace.createInvitation({ authMethod: Invitation.AuthMethod.NONE });
|
|
156
|
-
log('invitation created');
|
|
157
|
-
hostObservable.subscribe(
|
|
158
|
-
(hostInvitation) => {
|
|
159
|
-
switch (hostInvitation.state) {
|
|
160
|
-
case Invitation.State.CONNECTING: {
|
|
161
|
-
const guestObservable = peer.acceptInvitation(hostInvitation);
|
|
162
|
-
log('invitation accepted');
|
|
163
|
-
|
|
164
|
-
guestObservable.subscribe(
|
|
165
|
-
(guestInvitation) => {
|
|
166
|
-
switch (guestInvitation.state) {
|
|
167
|
-
case Invitation.State.SUCCESS: {
|
|
168
|
-
guestDone.wake(guestInvitation);
|
|
169
|
-
log('invitation guestDone');
|
|
170
|
-
break;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
},
|
|
174
|
-
(err) => raise(err)
|
|
175
|
-
);
|
|
176
|
-
break;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
case Invitation.State.SUCCESS: {
|
|
180
|
-
hostDone.wake(hostInvitation);
|
|
181
|
-
log('invitation hostDone');
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
},
|
|
185
|
-
(err) => raise(err)
|
|
186
|
-
);
|
|
119
|
+
get snapshotStore() {
|
|
120
|
+
return (this._props.snapshotStore ??= new SnapshotStore(this.storage.createDirectory('snapshots')));
|
|
121
|
+
}
|
|
187
122
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
123
|
+
get networkManager() {
|
|
124
|
+
return (this._props.networkManager ??= new NetworkManager({
|
|
125
|
+
signalManager: new MemorySignalManager(this.signalContext),
|
|
126
|
+
transportFactory: MemoryTransportFactory,
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
get spaceManager() {
|
|
131
|
+
return (this._props.spaceManager ??= new SpaceManager({
|
|
132
|
+
feedStore: this.feedStore,
|
|
133
|
+
networkManager: this.networkManager,
|
|
134
|
+
metadataStore: this.metadataStore,
|
|
135
|
+
modelFactory: createDefaultModelFactory(),
|
|
136
|
+
snapshotStore: this.snapshotStore,
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
191
140
|
|
|
192
|
-
|
|
141
|
+
export const createSigningContext = async (keyring: Keyring): Promise<SigningContext> => {
|
|
142
|
+
const identityKey = await keyring.createKey();
|
|
143
|
+
const deviceKey = await keyring.createKey();
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
identityKey,
|
|
147
|
+
deviceKey,
|
|
148
|
+
credentialSigner: createCredentialSignerWithChain(
|
|
149
|
+
keyring,
|
|
150
|
+
{
|
|
151
|
+
credential: await new CredentialGenerator(keyring, identityKey, deviceKey).createDeviceAuthorization(deviceKey),
|
|
152
|
+
},
|
|
153
|
+
deviceKey,
|
|
154
|
+
),
|
|
155
|
+
recordCredential: async () => {}, // No-op.
|
|
156
|
+
};
|
|
193
157
|
};
|
|
@@ -6,7 +6,7 @@ import { Trigger } from '@dxos/async';
|
|
|
6
6
|
import { Config } from '@dxos/config';
|
|
7
7
|
import { log, logInfo } from '@dxos/log';
|
|
8
8
|
import { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';
|
|
9
|
-
import { createWebRTCTransportFactory,
|
|
9
|
+
import { createWebRTCTransportFactory, TransportFactory } from '@dxos/network-manager';
|
|
10
10
|
import { RpcPort } from '@dxos/rpc';
|
|
11
11
|
import { getAsyncValue, MaybePromise, Provider } from '@dxos/util';
|
|
12
12
|
|
|
@@ -70,19 +70,16 @@ export class IFrameHostRuntime {
|
|
|
70
70
|
try {
|
|
71
71
|
this._config = await getAsyncValue(this._configProvider);
|
|
72
72
|
this._transportFactory = createWebRTCTransportFactory({
|
|
73
|
-
iceServers: this._config.get('runtime.services.ice')
|
|
73
|
+
iceServers: this._config.get('runtime.services.ice'),
|
|
74
74
|
});
|
|
75
75
|
const signals = this._config.get('runtime.services.signaling');
|
|
76
76
|
this._clientServices = new LocalClientServices({
|
|
77
77
|
lockKey: LOCK_KEY,
|
|
78
78
|
config: this._config,
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
: new MemorySignalManager(new MemorySignalManagerContext()), // TODO(dmaretskyi): Inject this context.
|
|
84
|
-
transportFactory: this._transportFactory
|
|
85
|
-
})
|
|
79
|
+
signalManager: signals
|
|
80
|
+
? new WebsocketSignalManager(signals)
|
|
81
|
+
: new MemorySignalManager(new MemorySignalManagerContext()), // TODO(dmaretskyi): Inject this context.
|
|
82
|
+
transportFactory: this._transportFactory,
|
|
86
83
|
});
|
|
87
84
|
|
|
88
85
|
const middleware: Pick<ClientRpcServerParams, 'handleCall' | 'handleStream'> = {
|
|
@@ -101,13 +98,13 @@ export class IFrameHostRuntime {
|
|
|
101
98
|
}
|
|
102
99
|
|
|
103
100
|
return handler(method, params);
|
|
104
|
-
}
|
|
101
|
+
},
|
|
105
102
|
};
|
|
106
103
|
|
|
107
104
|
this._clientRpc = new ClientRpcServer({
|
|
108
105
|
serviceRegistry: this._clientServices.host.serviceRegistry,
|
|
109
106
|
port: this._appPort,
|
|
110
|
-
...middleware
|
|
107
|
+
...middleware,
|
|
111
108
|
});
|
|
112
109
|
|
|
113
110
|
await Promise.all([this._clientServices.open(), this._clientRpc.open(), this._shellRuntime?.open()]);
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Trigger } from '@dxos/async';
|
|
6
|
+
import { iframeServiceBundle, workerServiceBundle, WorkerServiceBundle } from '@dxos/client-protocol';
|
|
7
|
+
import { Config } from '@dxos/config';
|
|
6
8
|
import { RemoteServiceConnectionError } from '@dxos/errors';
|
|
7
9
|
import { log } from '@dxos/log';
|
|
8
10
|
import { WebRTCTransportService } from '@dxos/network-manager';
|
|
@@ -23,9 +25,11 @@ export type IFrameProxyRuntimeParams = {
|
|
|
23
25
|
* Manages the client connection to the shared worker.
|
|
24
26
|
*/
|
|
25
27
|
export class IFrameProxyRuntime {
|
|
28
|
+
private readonly _id = String(Math.floor(Math.random() * 1000000));
|
|
26
29
|
private readonly _configProvider: IFrameProxyRuntimeParams['config'];
|
|
27
30
|
private readonly _systemPort: RpcPort;
|
|
28
31
|
private readonly _shellPort?: RpcPort;
|
|
32
|
+
private _release = new Trigger();
|
|
29
33
|
private _config!: Config;
|
|
30
34
|
private _transportService!: BridgeService;
|
|
31
35
|
private _systemRpc!: ProtoRpcPeer<WorkerServiceBundle>;
|
|
@@ -49,7 +53,7 @@ export class IFrameProxyRuntime {
|
|
|
49
53
|
this._config = await getAsyncValue(this._configProvider);
|
|
50
54
|
|
|
51
55
|
this._transportService = new WebRTCTransportService({
|
|
52
|
-
iceServers: this._config.get('runtime.services.ice')
|
|
56
|
+
iceServers: this._config.get('runtime.services.ice'),
|
|
53
57
|
});
|
|
54
58
|
|
|
55
59
|
this._systemRpc = createProtoRpcPeer({
|
|
@@ -57,19 +61,26 @@ export class IFrameProxyRuntime {
|
|
|
57
61
|
exposed: iframeServiceBundle,
|
|
58
62
|
handlers: {
|
|
59
63
|
BridgeService: this._transportService,
|
|
60
|
-
IframeService: {
|
|
61
|
-
async heartbeat() {
|
|
62
|
-
// Ok.
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
64
|
},
|
|
66
65
|
port: this._systemPort,
|
|
67
|
-
timeout: 200
|
|
66
|
+
timeout: 200,
|
|
68
67
|
});
|
|
69
68
|
|
|
69
|
+
let lockKey: string | undefined;
|
|
70
|
+
if (typeof navigator !== 'undefined') {
|
|
71
|
+
lockKey = this._lockKey(origin);
|
|
72
|
+
this._release = new Trigger();
|
|
73
|
+
const ready = new Trigger();
|
|
74
|
+
void navigator.locks.request(lockKey, async () => {
|
|
75
|
+
ready.wake();
|
|
76
|
+
await this._release.wait();
|
|
77
|
+
});
|
|
78
|
+
await ready.wait();
|
|
79
|
+
}
|
|
80
|
+
|
|
70
81
|
try {
|
|
71
82
|
await this._systemRpc.open();
|
|
72
|
-
await this._systemRpc.rpc.WorkerService.start({ origin });
|
|
83
|
+
await this._systemRpc.rpc.WorkerService.start({ origin, lockKey });
|
|
73
84
|
} catch (err) {
|
|
74
85
|
log.catch(err);
|
|
75
86
|
throw new RemoteServiceConnectionError('Failed to connect to worker');
|
|
@@ -78,8 +89,13 @@ export class IFrameProxyRuntime {
|
|
|
78
89
|
}
|
|
79
90
|
|
|
80
91
|
async close() {
|
|
92
|
+
this._release.wake();
|
|
81
93
|
await this._shellRuntime?.close();
|
|
82
94
|
await this._systemRpc.rpc.WorkerService.stop();
|
|
83
95
|
await this._systemRpc.close();
|
|
84
96
|
}
|
|
97
|
+
|
|
98
|
+
private _lockKey(origin: string) {
|
|
99
|
+
return `${origin}-${this._id}`;
|
|
100
|
+
}
|
|
85
101
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import assert from 'node:assert';
|
|
6
6
|
|
|
7
7
|
import { Event } from '@dxos/async';
|
|
8
|
-
import { appServiceBundle, AppServiceBundle, shellServiceBundle } from '@dxos/client';
|
|
8
|
+
import { appServiceBundle, AppServiceBundle, shellServiceBundle } from '@dxos/client-protocol';
|
|
9
9
|
import { PublicKey } from '@dxos/keys';
|
|
10
10
|
import { AppContextRequest, LayoutRequest, ShellLayout } from '@dxos/protocols/proto/dxos/iframe';
|
|
11
11
|
import { createProtoRpcPeer, ProtoRpcPeer, RpcPort } from '@dxos/rpc';
|
|
@@ -67,10 +67,10 @@ export class ShellRuntimeImpl implements ShellRuntime {
|
|
|
67
67
|
this._invitationCode = request.invitationCode;
|
|
68
68
|
this._spaceKey = request.spaceKey;
|
|
69
69
|
this.layoutUpdate.emit(request);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
72
|
},
|
|
73
|
-
port: this._port
|
|
73
|
+
port: this._port,
|
|
74
74
|
});
|
|
75
75
|
|
|
76
76
|
await this._appRpc.open();
|
|
@@ -7,7 +7,7 @@ import { log, logInfo } from '@dxos/log';
|
|
|
7
7
|
import { MaybePromise } from '@dxos/util';
|
|
8
8
|
|
|
9
9
|
enum Message {
|
|
10
|
-
ACQUIRING = 'acquiring'
|
|
10
|
+
ACQUIRING = 'acquiring',
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export type VaultResourceLockOptions = {
|
|
@@ -37,7 +37,7 @@ export class VaultResourceLock {
|
|
|
37
37
|
|
|
38
38
|
async acquire() {
|
|
39
39
|
this._broadcastChannel.postMessage({
|
|
40
|
-
message: Message.ACQUIRING
|
|
40
|
+
message: Message.ACQUIRING,
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
try {
|
|
@@ -6,7 +6,7 @@ import { Trigger } from '@dxos/async';
|
|
|
6
6
|
import { Config } from '@dxos/config';
|
|
7
7
|
import { log } from '@dxos/log';
|
|
8
8
|
import { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';
|
|
9
|
-
import {
|
|
9
|
+
import { WebRTCTransportProxyFactory } from '@dxos/network-manager';
|
|
10
10
|
import { RpcPort } from '@dxos/rpc';
|
|
11
11
|
import { MaybePromise } from '@dxos/util';
|
|
12
12
|
|
|
@@ -51,13 +51,10 @@ export class WorkerRuntime {
|
|
|
51
51
|
const signals = this._config.get('runtime.services.signaling');
|
|
52
52
|
this._clientServices.initialize({
|
|
53
53
|
config: this._config,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
: new MemorySignalManager(new MemorySignalManagerContext()), // TODO(dmaretskyi): Inject this context.
|
|
59
|
-
transportFactory: this._transportFactory
|
|
60
|
-
})
|
|
54
|
+
signalManager: signals
|
|
55
|
+
? new WebsocketSignalManager(signals)
|
|
56
|
+
: new MemorySignalManager(new MemorySignalManagerContext()), // TODO(dmaretskyi): Inject this context.
|
|
57
|
+
transportFactory: this._transportFactory,
|
|
61
58
|
});
|
|
62
59
|
|
|
63
60
|
await this._clientServices.open();
|
|
@@ -83,7 +80,7 @@ export class WorkerRuntime {
|
|
|
83
80
|
appPort,
|
|
84
81
|
systemPort,
|
|
85
82
|
shellPort,
|
|
86
|
-
readySignal: this._ready
|
|
83
|
+
readySignal: this._ready,
|
|
87
84
|
});
|
|
88
85
|
|
|
89
86
|
// When tab is closed.
|
|
@@ -102,6 +99,7 @@ export class WorkerRuntime {
|
|
|
102
99
|
* Selects one of the existing session fro WebRTC networking.
|
|
103
100
|
*/
|
|
104
101
|
private _reconnectWebrtc() {
|
|
102
|
+
log('reconnecting webrtc...');
|
|
105
103
|
// Check if current session is already closed.
|
|
106
104
|
if (this._sessionForNetworking) {
|
|
107
105
|
if (!this.sessions.has(this._sessionForNetworking)) {
|