@dxos/client-services 0.3.11-main.3f845e1 → 0.3.11-main.463e5cd
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-PYCJUZ6O.mjs → chunk-HQLYQQH7.mjs} +245 -117
- package/dist/lib/browser/chunk-HQLYQQH7.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +42 -33
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/testing/index.mjs +4 -11
- package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-KSD7OWNS.cjs → chunk-QJFUVEBN.cjs} +384 -256
- package/dist/lib/node/chunk-QJFUVEBN.cjs.map +7 -0
- package/dist/lib/node/index.cjs +77 -68
- 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 +11 -18
- package/dist/lib/node/packlets/testing/index.cjs.map +3 -3
- package/dist/types/src/packlets/identity/identity-service.d.ts +3 -3
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +2 -0
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +28 -3
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +2 -0
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
- package/dist/types/src/packlets/services/diagnostics.d.ts +32 -16
- package/dist/types/src/packlets/services/diagnostics.d.ts.map +1 -1
- package/dist/types/src/packlets/services/platform.d.ts +1 -14
- package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/automerge-space-state.d.ts +2 -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.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +2 -0
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts +3 -2
- 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/vault/iframe-host-runtime.d.ts +2 -0
- package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/index.d.ts +1 -1
- package/dist/types/src/packlets/vault/index.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/{iframe-proxy-runtime.d.ts → shared-worker-connection.d.ts} +12 -5
- package/dist/types/src/packlets/vault/shared-worker-connection.d.ts.map +1 -0
- package/dist/types/src/packlets/vault/worker-runtime.d.ts +10 -3
- package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/worker-session.d.ts +2 -2
- package/dist/types/src/packlets/vault/worker-session.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/package.json +35 -35
- package/src/packlets/identity/identity-manager.ts +1 -1
- package/src/packlets/identity/identity-service.test.ts +1 -1
- package/src/packlets/identity/identity-service.ts +6 -3
- package/src/packlets/invitations/device-invitation-protocol.test.ts +14 -0
- package/src/packlets/invitations/device-invitation-protocol.ts +14 -0
- package/src/packlets/invitations/invitation-protocol.ts +44 -6
- package/src/packlets/invitations/invitations-handler.ts +20 -18
- package/src/packlets/invitations/space-invitation-protocol.test.ts +28 -0
- package/src/packlets/invitations/space-invitation-protocol.ts +11 -0
- package/src/packlets/network/network-service.ts +5 -1
- package/src/packlets/services/diagnostics.ts +52 -16
- package/src/packlets/services/platform.ts +7 -19
- package/src/packlets/services/service-host.ts +27 -12
- package/src/packlets/spaces/automerge-space-state.ts +4 -0
- package/src/packlets/spaces/data-space-manager.ts +5 -1
- package/src/packlets/spaces/data-space.ts +37 -4
- package/src/packlets/spaces/spaces-service.ts +3 -3
- package/src/packlets/system/system-service.ts +7 -1
- package/src/packlets/testing/invitation-utils.ts +2 -10
- package/src/packlets/vault/iframe-host-runtime.ts +2 -0
- package/src/packlets/vault/index.ts +1 -1
- package/src/packlets/vault/{iframe-proxy-runtime.ts → shared-worker-connection.ts} +18 -6
- package/src/packlets/vault/worker-runtime.ts +27 -9
- package/src/packlets/vault/worker-session.ts +11 -8
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-PYCJUZ6O.mjs.map +0 -7
- package/dist/lib/node/chunk-KSD7OWNS.cjs.map +0 -7
- package/dist/types/src/packlets/vault/iframe-proxy-runtime.d.ts.map +0 -1
|
@@ -5,7 +5,12 @@ import { ClientServicesHost } from '../services';
|
|
|
5
5
|
export type CreateSessionParams = {
|
|
6
6
|
appPort: RpcPort;
|
|
7
7
|
systemPort: RpcPort;
|
|
8
|
-
shellPort
|
|
8
|
+
shellPort?: RpcPort;
|
|
9
|
+
};
|
|
10
|
+
export type WorkerRuntimeCallbacks = {
|
|
11
|
+
acquireLock: () => Promise<void>;
|
|
12
|
+
releaseLock: () => void;
|
|
13
|
+
onReset: () => Promise<void>;
|
|
9
14
|
};
|
|
10
15
|
/**
|
|
11
16
|
* Runtime for the shared worker.
|
|
@@ -14,13 +19,15 @@ export type CreateSessionParams = {
|
|
|
14
19
|
*/
|
|
15
20
|
export declare class WorkerRuntime {
|
|
16
21
|
private readonly _configProvider;
|
|
22
|
+
private readonly _acquireLock;
|
|
23
|
+
private readonly _releaseLock;
|
|
17
24
|
private readonly _transportFactory;
|
|
18
25
|
private readonly _ready;
|
|
19
26
|
private readonly _sessions;
|
|
20
27
|
private readonly _clientServices;
|
|
21
28
|
private _sessionForNetworking?;
|
|
22
29
|
private _config;
|
|
23
|
-
constructor(_configProvider: () => MaybePromise<Config
|
|
30
|
+
constructor(_configProvider: () => MaybePromise<Config>, { acquireLock, releaseLock, onReset }: WorkerRuntimeCallbacks);
|
|
24
31
|
get host(): ClientServicesHost;
|
|
25
32
|
start(): Promise<void>;
|
|
26
33
|
stop(): Promise<void>;
|
|
@@ -29,7 +36,7 @@ export declare class WorkerRuntime {
|
|
|
29
36
|
*/
|
|
30
37
|
createSession({ appPort, systemPort, shellPort }: CreateSessionParams): Promise<void>;
|
|
31
38
|
/**
|
|
32
|
-
* Selects one of the existing session
|
|
39
|
+
* Selects one of the existing session for WebRTC networking.
|
|
33
40
|
*/
|
|
34
41
|
private _reconnectWebrtc;
|
|
35
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-runtime.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/vault/worker-runtime.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAK3C,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGjD,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"worker-runtime.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/vault/worker-runtime.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAK3C,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGjD,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC;AAEF;;;;GAIG;AACH,qBAAa,aAAa;IAWtB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAVlC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAa;IAC1C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAyC;IAC3E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4B;IACtD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAsB;IACtD,OAAO,CAAC,qBAAqB,CAAC,CAAgB;IAC9C,OAAO,CAAC,OAAO,CAAU;gBAGN,eAAe,EAAE,MAAM,YAAY,CAAC,MAAM,CAAC,EAC5D,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,sBAAsB;IAW/D,IAAI,IAAI,uBAEP;IAEK,KAAK;IAuBL,IAAI;IAMV;;OAEG;IACG,aAAa,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,mBAAmB;IA0B3E;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAoBzB"}
|
|
@@ -7,7 +7,7 @@ export type WorkerSessionParams = {
|
|
|
7
7
|
serviceHost: ClientServicesHost;
|
|
8
8
|
systemPort: RpcPort;
|
|
9
9
|
appPort: RpcPort;
|
|
10
|
-
shellPort
|
|
10
|
+
shellPort?: RpcPort;
|
|
11
11
|
readySignal: Trigger<Error | undefined>;
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
@@ -15,7 +15,7 @@ export type WorkerSessionParams = {
|
|
|
15
15
|
*/
|
|
16
16
|
export declare class WorkerSession {
|
|
17
17
|
private readonly _clientRpc;
|
|
18
|
-
private readonly _shellClientRpc
|
|
18
|
+
private readonly _shellClientRpc?;
|
|
19
19
|
private readonly _iframeRpc;
|
|
20
20
|
private readonly _startTrigger;
|
|
21
21
|
private readonly _serviceHost;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-session.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/vault/worker-session.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgB,OAAO,EAAE,MAAM,aAAa,CAAC;AASpD,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAyC,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAqB,MAAM,YAAY,CAAC;AAEzD,OAAO,EAAE,KAAK,kBAAkB,EAA+C,MAAM,aAAa,CAAC;AAEnG,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"worker-session.d.ts","sourceRoot":"","sources":["../../../../../src/packlets/vault/worker-session.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgB,OAAO,EAAE,MAAM,aAAa,CAAC;AASpD,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAyC,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAqB,MAAM,YAAY,CAAC;AAEzD,OAAO,EAAE,KAAK,kBAAkB,EAA+C,MAAM,aAAa,CAAC;AAEnG,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IAEjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;CACzC,CAAC;AAEF;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoC;IAC/D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAElD,SAAgB,OAAO,iBAAsB,QAAQ,IAAI,CAAC,EAAI;IAGvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,aAAa,CAAC,EAAE,aAAa,CAAC;gBAEzB,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,mBAAmB;IAkEvF,IAAI;IAeJ,KAAK;YAYG,eAAe;IAQ7B,OAAO,CAAC,kBAAkB;CAO3B"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const DXOS_VERSION = "0.3.11-main.
|
|
1
|
+
export declare const DXOS_VERSION = "0.3.11-main.463e5cd";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/client-services",
|
|
3
|
-
"version": "0.3.11-main.
|
|
3
|
+
"version": "0.3.11-main.463e5cd",
|
|
4
4
|
"description": "DXOS client services implementation",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -22,44 +22,44 @@
|
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"platform": "^1.3.6",
|
|
25
|
-
"@dxos/async": "0.3.11-main.
|
|
26
|
-
"@dxos/client-protocol": "0.3.11-main.
|
|
27
|
-
"@dxos/
|
|
28
|
-
"@dxos/
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/
|
|
31
|
-
"@dxos/
|
|
32
|
-
"@dxos/
|
|
33
|
-
"@dxos/echo-db": "0.3.11-main.
|
|
34
|
-
"@dxos/
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/
|
|
37
|
-
"@dxos/
|
|
38
|
-
"@dxos/
|
|
39
|
-
"@dxos/
|
|
40
|
-
"@dxos/lock-file": "0.3.11-main.
|
|
41
|
-
"@dxos/keys": "0.3.11-main.
|
|
42
|
-
"@dxos/
|
|
43
|
-
"@dxos/
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@dxos/node-std": "0.3.11-main.
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/protocols": "0.3.11-main.
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/rpc": "0.3.11-main.
|
|
50
|
-
"@dxos/teleport
|
|
51
|
-
"@dxos/
|
|
52
|
-
"@dxos/teleport-extension-gossip": "0.3.11-main.
|
|
53
|
-
"@dxos/
|
|
54
|
-
"@dxos/timeframe": "0.3.11-main.
|
|
55
|
-
"@dxos/tracing": "0.3.11-main.
|
|
56
|
-
"@dxos/util": "0.3.11-main.
|
|
57
|
-
"@dxos/websocket-rpc": "0.3.11-main.
|
|
25
|
+
"@dxos/async": "0.3.11-main.463e5cd",
|
|
26
|
+
"@dxos/client-protocol": "0.3.11-main.463e5cd",
|
|
27
|
+
"@dxos/context": "0.3.11-main.463e5cd",
|
|
28
|
+
"@dxos/codec-protobuf": "0.3.11-main.463e5cd",
|
|
29
|
+
"@dxos/credentials": "0.3.11-main.463e5cd",
|
|
30
|
+
"@dxos/config": "0.3.11-main.463e5cd",
|
|
31
|
+
"@dxos/crypto": "0.3.11-main.463e5cd",
|
|
32
|
+
"@dxos/debug": "0.3.11-main.463e5cd",
|
|
33
|
+
"@dxos/echo-db": "0.3.11-main.463e5cd",
|
|
34
|
+
"@dxos/echo-pipeline": "0.3.11-main.463e5cd",
|
|
35
|
+
"@dxos/document-model": "0.3.11-main.463e5cd",
|
|
36
|
+
"@dxos/feed-store": "0.3.11-main.463e5cd",
|
|
37
|
+
"@dxos/echo-schema": "0.3.11-main.463e5cd",
|
|
38
|
+
"@dxos/invariant": "0.3.11-main.463e5cd",
|
|
39
|
+
"@dxos/keyring": "0.3.11-main.463e5cd",
|
|
40
|
+
"@dxos/lock-file": "0.3.11-main.463e5cd",
|
|
41
|
+
"@dxos/keys": "0.3.11-main.463e5cd",
|
|
42
|
+
"@dxos/messaging": "0.3.11-main.463e5cd",
|
|
43
|
+
"@dxos/log": "0.3.11-main.463e5cd",
|
|
44
|
+
"@dxos/model-factory": "0.3.11-main.463e5cd",
|
|
45
|
+
"@dxos/node-std": "0.3.11-main.463e5cd",
|
|
46
|
+
"@dxos/network-manager": "0.3.11-main.463e5cd",
|
|
47
|
+
"@dxos/protocols": "0.3.11-main.463e5cd",
|
|
48
|
+
"@dxos/random-access-storage": "0.3.11-main.463e5cd",
|
|
49
|
+
"@dxos/rpc": "0.3.11-main.463e5cd",
|
|
50
|
+
"@dxos/teleport": "0.3.11-main.463e5cd",
|
|
51
|
+
"@dxos/teleport-extension-object-sync": "0.3.11-main.463e5cd",
|
|
52
|
+
"@dxos/teleport-extension-gossip": "0.3.11-main.463e5cd",
|
|
53
|
+
"@dxos/text-model": "0.3.11-main.463e5cd",
|
|
54
|
+
"@dxos/timeframe": "0.3.11-main.463e5cd",
|
|
55
|
+
"@dxos/tracing": "0.3.11-main.463e5cd",
|
|
56
|
+
"@dxos/util": "0.3.11-main.463e5cd",
|
|
57
|
+
"@dxos/websocket-rpc": "0.3.11-main.463e5cd"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/platform": "^1.3.4",
|
|
61
61
|
"@types/readable-stream": "^2.3.9",
|
|
62
|
-
"@dxos/signal": "0.3.11-main.
|
|
62
|
+
"@dxos/signal": "0.3.11-main.463e5cd"
|
|
63
63
|
},
|
|
64
64
|
"publishConfig": {
|
|
65
65
|
"access": "public"
|
|
@@ -44,7 +44,7 @@ describe('IdentityService', () => {
|
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
test('creates a new identity with a display name', async () => {
|
|
47
|
-
const identity = await identityService.createIdentity({ displayName: 'Example' });
|
|
47
|
+
const identity = await identityService.createIdentity({ profile: { displayName: 'Example' } });
|
|
48
48
|
|
|
49
49
|
expect(identity.identityKey).to.be.instanceof(PublicKey);
|
|
50
50
|
expect(identity.spaceKey).to.be.instanceof(PublicKey);
|
|
@@ -8,6 +8,7 @@ import { todo } from '@dxos/debug';
|
|
|
8
8
|
import { invariant } from '@dxos/invariant';
|
|
9
9
|
import { type Keyring } from '@dxos/keyring';
|
|
10
10
|
import {
|
|
11
|
+
type CreateIdentityRequest,
|
|
11
12
|
type Identity,
|
|
12
13
|
type IdentityService,
|
|
13
14
|
type QueryIdentityResponse,
|
|
@@ -18,16 +19,18 @@ import { type Presentation, type ProfileDocument } from '@dxos/protocols/proto/d
|
|
|
18
19
|
|
|
19
20
|
import { type CreateIdentityOptions, type IdentityManager } from './identity-manager';
|
|
20
21
|
|
|
22
|
+
const CREATE_PROFILE_WITH_AUTOMERGE_DEFAULT = true;
|
|
23
|
+
|
|
21
24
|
export class IdentityServiceImpl implements IdentityService {
|
|
22
25
|
constructor(
|
|
23
|
-
private readonly _createIdentity: (params
|
|
26
|
+
private readonly _createIdentity: (params: CreateIdentityOptions, useAutomerge: boolean) => Promise<Identity>,
|
|
24
27
|
private readonly _identityManager: IdentityManager,
|
|
25
28
|
private readonly _keyring: Keyring,
|
|
26
29
|
private readonly _onProfileUpdate?: (profile: ProfileDocument | undefined) => Promise<void>,
|
|
27
30
|
) {}
|
|
28
31
|
|
|
29
|
-
async createIdentity(request:
|
|
30
|
-
await this._createIdentity(request);
|
|
32
|
+
async createIdentity(request: CreateIdentityRequest): Promise<Identity> {
|
|
33
|
+
await this._createIdentity(request.profile ?? {}, request.useAutomerge ?? CREATE_PROFILE_WITH_AUTOMERGE_DEFAULT);
|
|
31
34
|
return this._getIdentity()!;
|
|
32
35
|
}
|
|
33
36
|
|
|
@@ -6,6 +6,7 @@ import { expect } from 'chai';
|
|
|
6
6
|
|
|
7
7
|
import { asyncChain } from '@dxos/async';
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
|
+
import { AlreadyJoinedError } from '@dxos/protocols';
|
|
9
10
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
10
11
|
import { describe, test, afterTest } from '@dxos/test';
|
|
11
12
|
|
|
@@ -36,4 +37,17 @@ describe('services/device', () => {
|
|
|
36
37
|
await Promise.all(performInvitation({ host, guest, options: { kind: Invitation.Kind.DEVICE } }));
|
|
37
38
|
expect(guest.identityManager.identity?.identityKey).to.deep.eq(identity1.identityKey);
|
|
38
39
|
});
|
|
40
|
+
|
|
41
|
+
test('invitation when already joined', async () => {
|
|
42
|
+
const [host, guest] = await asyncChain<ServiceContext>([closeAfterTest])(createPeers(2));
|
|
43
|
+
|
|
44
|
+
const identity1 = await host.createIdentity();
|
|
45
|
+
expect(host.identityManager.identity).to.eq(identity1);
|
|
46
|
+
|
|
47
|
+
await Promise.all(performInvitation({ host, guest, options: { kind: Invitation.Kind.DEVICE } }));
|
|
48
|
+
expect(guest.identityManager.identity?.identityKey).to.deep.eq(identity1.identityKey);
|
|
49
|
+
|
|
50
|
+
const [_, result] = performInvitation({ host, guest, options: { kind: Invitation.Kind.DEVICE } });
|
|
51
|
+
expect((await result).error).to.be.instanceOf(AlreadyJoinedError);
|
|
52
|
+
});
|
|
39
53
|
});
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { invariant } from '@dxos/invariant';
|
|
6
6
|
import { type Keyring } from '@dxos/keyring';
|
|
7
|
+
import { AlreadyJoinedError } from '@dxos/protocols';
|
|
7
8
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
8
9
|
import {
|
|
9
10
|
type AdmissionRequest,
|
|
@@ -46,6 +47,17 @@ export class DeviceInvitationProtocol implements InvitationProtocol {
|
|
|
46
47
|
};
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
checkInvitation(invitation: Partial<Invitation>) {
|
|
51
|
+
try {
|
|
52
|
+
const identity = this._getIdentity();
|
|
53
|
+
if (identity) {
|
|
54
|
+
return new AlreadyJoinedError('Currently only one identity per client is supported.');
|
|
55
|
+
}
|
|
56
|
+
} catch {
|
|
57
|
+
// No identity.
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
49
61
|
createIntroduction(): IntroductionRequest {
|
|
50
62
|
return {};
|
|
51
63
|
}
|
|
@@ -71,6 +83,8 @@ export class DeviceInvitationProtocol implements InvitationProtocol {
|
|
|
71
83
|
invariant(request.device);
|
|
72
84
|
const { deviceKey, controlFeedKey, dataFeedKey } = request.device;
|
|
73
85
|
|
|
86
|
+
// TODO(wittjosiah): When multiple identities are supported, verify identity doesn't already exist before accepting.
|
|
87
|
+
|
|
74
88
|
await this._acceptIdentity({
|
|
75
89
|
identityKey,
|
|
76
90
|
deviceKey,
|
|
@@ -2,24 +2,62 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
import type { ApiError } from '@dxos/protocols';
|
|
6
|
+
import type { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
7
|
+
import type { ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
8
|
+
import type {
|
|
9
|
+
AdmissionRequest,
|
|
10
|
+
AdmissionResponse,
|
|
11
|
+
IntroductionRequest,
|
|
11
12
|
} from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
12
13
|
|
|
13
14
|
export interface InvitationProtocol {
|
|
15
|
+
//
|
|
14
16
|
// Debugging
|
|
17
|
+
//
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Protocol-specific debug info to include in logs.
|
|
21
|
+
*/
|
|
15
22
|
toJSON(): object;
|
|
16
23
|
|
|
24
|
+
//
|
|
17
25
|
// Host
|
|
26
|
+
//
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Protocol-specific information to include in the invitation.
|
|
30
|
+
*/
|
|
18
31
|
getInvitationContext(): Partial<Invitation> & Pick<Invitation, 'kind'>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Once authentication is successful, the host can admit the guest to the requested resource.
|
|
35
|
+
*/
|
|
19
36
|
admit(request: AdmissionRequest, guestProfile?: ProfileDocument): Promise<AdmissionResponse>;
|
|
20
37
|
|
|
38
|
+
//
|
|
21
39
|
// Guest
|
|
40
|
+
//
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Check if the invitation is valid.
|
|
44
|
+
*
|
|
45
|
+
* For example, the guest may already be a member of the space.
|
|
46
|
+
*/
|
|
47
|
+
checkInvitation(invitation: Partial<Invitation>): ApiError | undefined;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Get profile information to send to the host to identify the guest.
|
|
51
|
+
*/
|
|
22
52
|
createIntroduction(): IntroductionRequest;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Get key information to send to the host in order to create an admission credential for the guest.
|
|
56
|
+
*/
|
|
23
57
|
createAdmissionRequest(): Promise<AdmissionRequest>;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Redeem the admission credential.
|
|
61
|
+
*/
|
|
24
62
|
accept(response: AdmissionResponse, request: AdmissionRequest): Promise<Partial<Invitation>>;
|
|
25
63
|
}
|
|
@@ -303,9 +303,6 @@ export class InvitationsHandler {
|
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
305
|
}
|
|
306
|
-
} else {
|
|
307
|
-
// Notify that introduction is complete even if auth is not required.
|
|
308
|
-
setState({ state: Invitation.State.READY_FOR_AUTHENTICATION });
|
|
309
306
|
}
|
|
310
307
|
|
|
311
308
|
// 3. Send admission credentials to host (with local space keys).
|
|
@@ -321,7 +318,7 @@ export class InvitationsHandler {
|
|
|
321
318
|
|
|
322
319
|
// 5. Success.
|
|
323
320
|
log('admitted by host', { ...protocol.toJSON() });
|
|
324
|
-
setState({ ...result, state: Invitation.State.SUCCESS });
|
|
321
|
+
setState({ ...result, target: invitation.target, state: Invitation.State.SUCCESS });
|
|
325
322
|
log.trace('dxos.sdk.invitations-handler.guest.onOpen', trace.end({ id: traceId }));
|
|
326
323
|
} catch (err: any) {
|
|
327
324
|
if (err instanceof TimeoutError) {
|
|
@@ -355,20 +352,25 @@ export class InvitationsHandler {
|
|
|
355
352
|
};
|
|
356
353
|
|
|
357
354
|
scheduleTask(ctx, async () => {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
355
|
+
const error = protocol.checkInvitation(invitation);
|
|
356
|
+
if (error) {
|
|
357
|
+
stream.error(error);
|
|
358
|
+
} else {
|
|
359
|
+
invariant(invitation.swarmKey);
|
|
360
|
+
const topic = invitation.swarmKey;
|
|
361
|
+
const swarmConnection = await this._networkManager.joinSwarm({
|
|
362
|
+
topic,
|
|
363
|
+
peerId: PublicKey.random(),
|
|
364
|
+
protocolProvider: createTeleportProtocolFactory(async (teleport) => {
|
|
365
|
+
teleport.addExtension('dxos.halo.invitations', createExtension());
|
|
366
|
+
}),
|
|
367
|
+
topology: new StarTopology(topic),
|
|
368
|
+
label: 'invitation guest',
|
|
369
|
+
});
|
|
370
|
+
ctx.onDispose(() => swarmConnection.close());
|
|
371
|
+
|
|
372
|
+
setState({ state: Invitation.State.CONNECTING });
|
|
373
|
+
}
|
|
372
374
|
});
|
|
373
375
|
|
|
374
376
|
const observable = new AuthenticatingInvitation({
|
|
@@ -7,6 +7,7 @@ import { expect } from 'chai';
|
|
|
7
7
|
import { asyncChain, Trigger } from '@dxos/async';
|
|
8
8
|
import { raise } from '@dxos/debug';
|
|
9
9
|
import { testLocalDatabase } from '@dxos/echo-pipeline/testing';
|
|
10
|
+
import { AlreadyJoinedError } from '@dxos/protocols';
|
|
10
11
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
11
12
|
import { afterTest, describe, test } from '@dxos/test';
|
|
12
13
|
|
|
@@ -71,6 +72,33 @@ describe('services/space-invitations-protocol', () => {
|
|
|
71
72
|
}
|
|
72
73
|
});
|
|
73
74
|
|
|
75
|
+
test('invitation when already joined', async () => {
|
|
76
|
+
const [host, guest] = await asyncChain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(2));
|
|
77
|
+
|
|
78
|
+
const space1 = await host.dataSpaceManager!.createSpace();
|
|
79
|
+
const spaceKey = space1.key;
|
|
80
|
+
|
|
81
|
+
await Promise.all(performInvitation({ host, guest, options: { kind: Invitation.Kind.SPACE, spaceKey } }));
|
|
82
|
+
|
|
83
|
+
{
|
|
84
|
+
const space1 = host.dataSpaceManager!.spaces.get(spaceKey)!;
|
|
85
|
+
const space2 = guest.dataSpaceManager!.spaces.get(spaceKey)!;
|
|
86
|
+
expect(space1).not.to.be.undefined;
|
|
87
|
+
expect(space2).not.to.be.undefined;
|
|
88
|
+
|
|
89
|
+
await host.dataSpaceManager?.waitUntilSpaceReady(space1.key);
|
|
90
|
+
await guest.dataSpaceManager?.waitUntilSpaceReady(space2.key);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const [_, guestResult] = performInvitation({
|
|
94
|
+
host,
|
|
95
|
+
guest,
|
|
96
|
+
options: { kind: Invitation.Kind.SPACE, spaceKey },
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
expect((await guestResult).error).to.be.instanceOf(AlreadyJoinedError);
|
|
100
|
+
});
|
|
101
|
+
|
|
74
102
|
test('creates and accepts invitation with retry', async () => {
|
|
75
103
|
const [host, guest] = await asyncChain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(2));
|
|
76
104
|
|
|
@@ -8,6 +8,7 @@ import { invariant } from '@dxos/invariant';
|
|
|
8
8
|
import { type Keyring } from '@dxos/keyring';
|
|
9
9
|
import { type PublicKey } from '@dxos/keys';
|
|
10
10
|
import { log } from '@dxos/log';
|
|
11
|
+
import { AlreadyJoinedError } from '@dxos/protocols';
|
|
11
12
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
12
13
|
import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
13
14
|
import { type ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
@@ -76,6 +77,12 @@ export class SpaceInvitationProtocol implements InvitationProtocol {
|
|
|
76
77
|
};
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
checkInvitation(invitation: Partial<Invitation>) {
|
|
81
|
+
if (invitation.spaceKey && this._spaceManager.spaces.has(invitation.spaceKey)) {
|
|
82
|
+
return new AlreadyJoinedError('Already joined space.');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
79
86
|
createIntroduction(): IntroductionRequest {
|
|
80
87
|
return {
|
|
81
88
|
profile: this._signingContext.getProfile(),
|
|
@@ -104,6 +111,10 @@ export class SpaceInvitationProtocol implements InvitationProtocol {
|
|
|
104
111
|
invariant(assertion['@type'] === 'dxos.halo.credentials.SpaceMember', 'Invalid credential');
|
|
105
112
|
invariant(credential.subject.id.equals(this._signingContext.identityKey));
|
|
106
113
|
|
|
114
|
+
if (this._spaceManager.spaces.has(assertion.spaceKey)) {
|
|
115
|
+
throw new AlreadyJoinedError('Already joined space.');
|
|
116
|
+
}
|
|
117
|
+
|
|
107
118
|
// Create local space.
|
|
108
119
|
await this._spaceManager.acceptSpace({
|
|
109
120
|
spaceKey: assertion.spaceKey,
|
|
@@ -12,13 +12,17 @@ import {
|
|
|
12
12
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
13
13
|
|
|
14
14
|
export class NetworkServiceImpl implements NetworkService {
|
|
15
|
-
constructor(
|
|
15
|
+
constructor(
|
|
16
|
+
private readonly networkManager: NetworkManager,
|
|
17
|
+
private readonly signalManager: SignalManager,
|
|
18
|
+
) {}
|
|
16
19
|
|
|
17
20
|
queryStatus() {
|
|
18
21
|
return new Stream<NetworkStatus>(({ next }) => {
|
|
19
22
|
const update = () => {
|
|
20
23
|
next({
|
|
21
24
|
swarm: this.networkManager.connectionState,
|
|
25
|
+
connectionInfo: this.networkManager.connectionLog?.swarms,
|
|
22
26
|
signaling: this.signalManager.getStatus().map(({ host, state }) => ({ server: host, state })),
|
|
23
27
|
});
|
|
24
28
|
};
|
|
@@ -18,13 +18,17 @@ import {
|
|
|
18
18
|
type Metrics,
|
|
19
19
|
type NetworkStatus,
|
|
20
20
|
type Space as SpaceProto,
|
|
21
|
+
type Platform,
|
|
21
22
|
SpaceMember,
|
|
23
|
+
type LogEntry,
|
|
22
24
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
23
25
|
import { type SubscribeToFeedsResponse } from '@dxos/protocols/proto/dxos/devtools/host';
|
|
24
26
|
import { type SwarmInfo } from '@dxos/protocols/proto/dxos/devtools/swarm';
|
|
25
27
|
import { type Epoch } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
28
|
+
import { type Resource, type Span } from '@dxos/protocols/proto/dxos/tracing';
|
|
29
|
+
import { TRACE_PROCESSOR } from '@dxos/tracing';
|
|
26
30
|
|
|
27
|
-
import { getPlatform
|
|
31
|
+
import { getPlatform } from './platform';
|
|
28
32
|
import { type ServiceContext } from './service-context';
|
|
29
33
|
import { DXOS_VERSION } from '../../version';
|
|
30
34
|
import { type DataSpace } from '../spaces';
|
|
@@ -32,22 +36,36 @@ import { type DataSpace } from '../spaces';
|
|
|
32
36
|
const DEFAULT_TIMEOUT = 1_000;
|
|
33
37
|
|
|
34
38
|
export type Diagnostics = {
|
|
35
|
-
created: string;
|
|
36
|
-
platform: Platform;
|
|
37
|
-
config?: ConfigProto;
|
|
38
39
|
client: {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
config: ConfigProto;
|
|
41
|
+
trace: TraceDiagnostic;
|
|
42
|
+
};
|
|
43
|
+
services: {
|
|
44
|
+
trace: TraceDiagnostic;
|
|
45
|
+
created: string;
|
|
46
|
+
platform: Platform;
|
|
47
|
+
config?: ConfigProto;
|
|
48
|
+
client: {
|
|
49
|
+
version: string;
|
|
50
|
+
storage: {
|
|
51
|
+
version: number;
|
|
52
|
+
};
|
|
42
53
|
};
|
|
54
|
+
identity?: Identity;
|
|
55
|
+
devices?: Device[];
|
|
56
|
+
spaces?: SpaceStats[];
|
|
57
|
+
networkStatus?: NetworkStatus;
|
|
58
|
+
swarms?: SwarmInfo[];
|
|
59
|
+
feeds?: Partial<SubscribeToFeedsResponse.Feed>[];
|
|
60
|
+
metrics?: Metrics;
|
|
61
|
+
storage?: { file: string; count: number }[];
|
|
43
62
|
};
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
metrics?: Metrics;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export type TraceDiagnostic = {
|
|
66
|
+
resources: Record<string, Resource>;
|
|
67
|
+
spans: Span[];
|
|
68
|
+
logs: LogEntry[];
|
|
51
69
|
};
|
|
52
70
|
|
|
53
71
|
// TODO(burdon): Normalize for ECHO/HALO.
|
|
@@ -74,8 +92,8 @@ export const createDiagnostics = async (
|
|
|
74
92
|
clientServices: Partial<ClientServices>,
|
|
75
93
|
serviceContext: ServiceContext,
|
|
76
94
|
config: Config,
|
|
77
|
-
): Promise<Diagnostics> => {
|
|
78
|
-
const diagnostics: Diagnostics = {
|
|
95
|
+
): Promise<Diagnostics['services']> => {
|
|
96
|
+
const diagnostics: Diagnostics['services'] = {
|
|
79
97
|
created: new Date().toISOString(),
|
|
80
98
|
platform: getPlatform(),
|
|
81
99
|
client: {
|
|
@@ -84,6 +102,7 @@ export const createDiagnostics = async (
|
|
|
84
102
|
version: STORAGE_VERSION,
|
|
85
103
|
},
|
|
86
104
|
},
|
|
105
|
+
trace: TRACE_PROCESSOR.getDiagnostics(),
|
|
87
106
|
};
|
|
88
107
|
|
|
89
108
|
// Trace metrics.
|
|
@@ -95,6 +114,23 @@ export const createDiagnostics = async (
|
|
|
95
114
|
}).catch(() => undefined);
|
|
96
115
|
}
|
|
97
116
|
|
|
117
|
+
if (typeof navigator !== 'undefined' && navigator.storage) {
|
|
118
|
+
const map = new Map();
|
|
119
|
+
const dir = await navigator.storage.getDirectory();
|
|
120
|
+
for await (const filename of (dir as any)?.keys()) {
|
|
121
|
+
const idx = filename.indexOf('-', filename.indexOf('-') + 1);
|
|
122
|
+
if (idx === -1) {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
map.set(filename.slice(0, idx), (map.get(filename.slice(0, idx)) ?? 0) + 1);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
diagnostics.storage = Array.from(map.entries())
|
|
130
|
+
.sort((a, b) => b[1] - a[1])
|
|
131
|
+
.map(([file, count]) => ({ file, count }));
|
|
132
|
+
}
|
|
133
|
+
|
|
98
134
|
const identity = serviceContext.identityManager.identity;
|
|
99
135
|
if (identity) {
|
|
100
136
|
// Identity.
|