@dxos/client-services 0.8.4-main.fffef41 → 0.8.4-staging.60fe92afc8
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/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/browser/{chunk-I2RGLVJF.mjs → chunk-HPR4MJ4W.mjs} +2870 -3767
- package/dist/lib/browser/chunk-HPR4MJ4W.mjs.map +7 -0
- package/dist/lib/browser/chunk-QCWEHHJW.mjs +24 -0
- package/dist/lib/browser/chunk-QCWEHHJW.mjs.map +7 -0
- package/dist/lib/browser/chunk-XJRPB3GA.mjs +22 -0
- package/dist/lib/browser/chunk-XJRPB3GA.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +576 -139
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +88 -0
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
- package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/browser/packlets/locks/browser.mjs +86 -0
- package/dist/lib/browser/packlets/locks/browser.mjs.map +7 -0
- package/dist/lib/browser/packlets/locks/node.mjs +48 -0
- package/dist/lib/browser/packlets/locks/node.mjs.map +7 -0
- package/dist/lib/browser/testing/index.mjs +58 -53
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/chunk-2DT3MZRL.mjs +22 -0
- package/dist/lib/node-esm/chunk-2DT3MZRL.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +24 -0
- package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-QTUURCR4.mjs → chunk-JW6QHPRJ.mjs} +2810 -3576
- package/dist/lib/node-esm/chunk-JW6QHPRJ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +576 -139
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +88 -0
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
- package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/node-esm/packlets/locks/browser.mjs +86 -0
- package/dist/lib/node-esm/packlets/locks/browser.mjs.map +7 -0
- package/dist/lib/node-esm/packlets/locks/node.mjs +48 -0
- package/dist/lib/node-esm/packlets/locks/node.mjs.map +7 -0
- package/dist/lib/node-esm/testing/index.mjs +58 -53
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +3 -2
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts +2 -1
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
- package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/devtools.d.ts +7 -3
- package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/feeds.d.ts +1 -1
- package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/keys.d.ts +2 -2
- package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/metadata.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +2 -3
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/index.d.ts +1 -1
- package/dist/types/src/packlets/diagnostics/index.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/authenticator.d.ts +3 -3
- package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
- package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-manager.d.ts +10 -10
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +14 -9
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-service.d.ts +7 -11
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +10 -13
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +7 -6
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +1 -1
- package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +7 -4
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-topology.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +4 -4
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts +5 -5
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-service.d.ts +3 -3
- package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +6 -5
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
- package/dist/types/src/packlets/locks/browser.d.ts.map +1 -1
- package/dist/types/src/packlets/locks/index.d.ts +1 -1
- package/dist/types/src/packlets/locks/index.d.ts.map +1 -1
- package/dist/types/src/packlets/locks/node.d.ts.map +1 -1
- package/dist/types/src/packlets/logging/logging-service.d.ts +4 -0
- package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
- package/dist/types/src/packlets/network/network-service.d.ts +5 -4
- package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
- package/dist/types/src/packlets/services/client-rpc-server.d.ts +5 -5
- package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
- package/dist/types/src/packlets/services/feed-syncer.d.ts +75 -0
- package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
- package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
- package/dist/types/src/packlets/services/feed-syncer.test.d.ts.map +1 -0
- package/dist/types/src/packlets/services/index.d.ts +1 -0
- package/dist/types/src/packlets/services/index.d.ts.map +1 -1
- package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +22 -19
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +20 -13
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
- package/dist/types/src/packlets/services/sqlite-storage.d.ts +27 -0
- package/dist/types/src/packlets/services/sqlite-storage.d.ts.map +1 -0
- package/dist/types/src/packlets/services/util.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/archive-format.d.ts +9 -0
- package/dist/types/src/packlets/space-export/archive-format.d.ts.map +1 -0
- package/dist/types/src/packlets/space-export/index.d.ts +4 -1
- package/dist/types/src/packlets/space-export/index.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts +23 -0
- package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts.map +1 -0
- package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts +36 -0
- package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts.map +1 -0
- package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +9 -1
- package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +7 -1
- package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/space-archive.test.d.ts +2 -0
- package/dist/types/src/packlets/space-export/space-archive.test.d.ts.map +1 -0
- package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +49 -22
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +38 -13
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +2 -2
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/epoch-migrations.d.ts +1 -1
- package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/genesis.d.ts +4 -3
- package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -9
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts +10 -7
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/index.d.ts +1 -0
- package/dist/types/src/packlets/storage/index.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/profile-archive-sqlite.d.ts +24 -0
- package/dist/types/src/packlets/storage/profile-archive-sqlite.d.ts.map +1 -0
- package/dist/types/src/packlets/storage/profile-archive-sqlite.test.d.ts +2 -0
- package/dist/types/src/packlets/storage/profile-archive-sqlite.test.d.ts.map +1 -0
- package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/util.d.ts.map +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts +6 -3
- package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts +20 -22
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-runtime.d.ts +41 -4
- package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-session.d.ts +2 -4
- package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
- package/dist/types/src/testing/setup.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/dist/types/src/version.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +71 -57
- package/src/index.ts +1 -0
- package/src/packlets/agents/edge-agent-manager.ts +8 -5
- package/src/packlets/agents/edge-agent-service.ts +4 -2
- package/src/packlets/devices/devices-service.test.ts +0 -1
- package/src/packlets/devtools/devtools.ts +28 -7
- package/src/packlets/devtools/feeds.ts +1 -1
- package/src/packlets/devtools/keys.ts +2 -2
- package/src/packlets/devtools/spaces.ts +1 -1
- package/src/packlets/diagnostics/diagnostics.ts +1 -2
- package/src/packlets/diagnostics/index.ts +1 -1
- package/src/packlets/identity/authenticator.ts +3 -3
- package/src/packlets/identity/contacts-service.ts +1 -2
- package/src/packlets/identity/identity-manager.test.ts +6 -6
- package/src/packlets/identity/identity-manager.ts +29 -28
- package/src/packlets/identity/identity-recovery-manager.ts +31 -22
- package/src/packlets/identity/identity-service.test.ts +6 -27
- package/src/packlets/identity/identity-service.ts +17 -83
- package/src/packlets/identity/identity.test.ts +3 -3
- package/src/packlets/identity/identity.ts +12 -35
- package/src/packlets/invitations/device-invitation-protocol.ts +10 -9
- package/src/packlets/invitations/edge-invitation-handler.ts +9 -5
- package/src/packlets/invitations/invitation-guest-extenstion.ts +6 -4
- package/src/packlets/invitations/invitation-host-extension.ts +13 -14
- package/src/packlets/invitations/invitation-protocol.ts +7 -4
- package/src/packlets/invitations/invitation-state.ts +1 -15
- package/src/packlets/invitations/invitations-handler.test.ts +4 -5
- package/src/packlets/invitations/invitations-handler.ts +74 -22
- package/src/packlets/invitations/invitations-manager.ts +42 -17
- package/src/packlets/invitations/invitations-service.ts +9 -9
- package/src/packlets/invitations/space-invitation-protocol.test.ts +17 -16
- package/src/packlets/invitations/space-invitation-protocol.ts +13 -18
- package/src/packlets/locks/index.ts +1 -1
- package/src/packlets/logging/logging-service.ts +19 -15
- package/src/packlets/network/network-service.test.ts +0 -1
- package/src/packlets/network/network-service.ts +10 -8
- package/src/packlets/services/client-rpc-server.ts +19 -16
- package/src/packlets/services/feed-syncer.test.ts +376 -0
- package/src/packlets/services/feed-syncer.ts +536 -0
- package/src/packlets/services/index.ts +1 -0
- package/src/packlets/services/platform.ts +7 -1
- package/src/packlets/services/service-context.test.ts +3 -2
- package/src/packlets/services/service-context.ts +215 -78
- package/src/packlets/services/service-host.test.ts +8 -10
- package/src/packlets/services/service-host.ts +102 -70
- package/src/packlets/services/service-registry.test.ts +0 -1
- package/src/packlets/services/sqlite-storage.ts +390 -0
- package/src/packlets/space-export/archive-format.ts +42 -0
- package/src/packlets/space-export/index.ts +4 -1
- package/src/packlets/space-export/serialized-space-reader.ts +129 -0
- package/src/packlets/space-export/serialized-space-writer.ts +260 -0
- package/src/packlets/space-export/space-archive-reader.ts +64 -3
- package/src/packlets/space-export/space-archive-writer.ts +41 -4
- package/src/packlets/space-export/space-archive.test.ts +482 -0
- package/src/packlets/spaces/data-space-manager.test.ts +169 -14
- package/src/packlets/spaces/data-space-manager.ts +192 -127
- package/src/packlets/spaces/data-space.ts +89 -43
- package/src/packlets/spaces/edge-feed-replicator.test.ts +2 -2
- package/src/packlets/spaces/edge-feed-replicator.ts +11 -9
- package/src/packlets/spaces/epoch-migrations.ts +7 -6
- package/src/packlets/spaces/genesis.ts +9 -4
- package/src/packlets/spaces/notarization-plugin.test.ts +2 -2
- package/src/packlets/spaces/notarization-plugin.ts +10 -9
- package/src/packlets/spaces/spaces-service.test.ts +18 -11
- package/src/packlets/spaces/spaces-service.ts +130 -24
- package/src/packlets/storage/index.ts +1 -0
- package/src/packlets/storage/profile-archive-sqlite.test.ts +79 -0
- package/src/packlets/storage/profile-archive-sqlite.ts +100 -0
- package/src/packlets/storage/profile-archive.ts +3 -0
- package/src/packlets/storage/storage.ts +4 -4
- package/src/packlets/testing/invitation-utils.ts +10 -6
- package/src/packlets/testing/test-builder.ts +59 -40
- package/src/packlets/worker/worker-runtime.ts +173 -17
- package/src/packlets/worker/worker-session.ts +12 -18
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-I2RGLVJF.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-QTUURCR4.mjs.map +0 -7
- package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +0 -19
- package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +0 -1
- package/src/packlets/identity/default-space-state-machine.ts +0 -44
|
@@ -6,14 +6,13 @@ import platform from 'platform';
|
|
|
6
6
|
import { Event } from '@dxos/async';
|
|
7
7
|
import { Context } from '@dxos/context';
|
|
8
8
|
import { CredentialGenerator, createCredentialSignerWithKey, createDidFromIdentityKey } from '@dxos/credentials';
|
|
9
|
-
import { type
|
|
9
|
+
import { type IMetadataStore, type SpaceManager, type SwarmIdentity } from '@dxos/echo-host';
|
|
10
10
|
import { type EdgeConnection } from '@dxos/edge-client';
|
|
11
11
|
import { type FeedStore } from '@dxos/feed-store';
|
|
12
12
|
import { invariant } from '@dxos/invariant';
|
|
13
|
-
import { type
|
|
13
|
+
import { type KeyringApi } from '@dxos/keyring';
|
|
14
14
|
import { PublicKey } from '@dxos/keys';
|
|
15
15
|
import { log } from '@dxos/log';
|
|
16
|
-
import { trace } from '@dxos/protocols';
|
|
17
16
|
import { Device, DeviceKind } from '@dxos/protocols/proto/dxos/client/services';
|
|
18
17
|
import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
19
18
|
import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
@@ -28,7 +27,7 @@ import {
|
|
|
28
27
|
import { Gossip, Presence } from '@dxos/teleport-extension-gossip';
|
|
29
28
|
import { Timeframe } from '@dxos/timeframe';
|
|
30
29
|
import { trace as Trace } from '@dxos/tracing';
|
|
31
|
-
import { deferFunction, isNode } from '@dxos/util';
|
|
30
|
+
import { deferFunction, isNode, isTauri } from '@dxos/util';
|
|
32
31
|
|
|
33
32
|
import { createAuthProvider } from './authenticator';
|
|
34
33
|
import { Identity } from './identity';
|
|
@@ -36,14 +35,14 @@ import { Identity } from './identity';
|
|
|
36
35
|
const DEVICE_PRESENCE_ANNOUNCE_INTERVAL = 10_000;
|
|
37
36
|
const DEVICE_PRESENCE_OFFLINE_TIMEOUT = 20_000;
|
|
38
37
|
|
|
39
|
-
interface
|
|
38
|
+
interface ConstructSpaceProps {
|
|
40
39
|
spaceRecord: SpaceMetadata;
|
|
41
40
|
swarmIdentity: SwarmIdentity;
|
|
42
41
|
identityKey: PublicKey;
|
|
43
42
|
gossip: Gossip;
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
export type
|
|
45
|
+
export type JoinIdentityProps = {
|
|
47
46
|
identityKey: PublicKey;
|
|
48
47
|
deviceKey: PublicKey;
|
|
49
48
|
haloSpaceKey: PublicKey;
|
|
@@ -67,9 +66,9 @@ export type CreateIdentityOptions = {
|
|
|
67
66
|
deviceProfile?: DeviceProfileDocument;
|
|
68
67
|
};
|
|
69
68
|
|
|
70
|
-
export type
|
|
71
|
-
metadataStore:
|
|
72
|
-
keyring:
|
|
69
|
+
export type IdentityManagerProps = {
|
|
70
|
+
metadataStore: IMetadataStore;
|
|
71
|
+
keyring: KeyringApi;
|
|
73
72
|
feedStore: FeedStore<FeedMessage>;
|
|
74
73
|
spaceManager: SpaceManager;
|
|
75
74
|
edgeConnection?: EdgeConnection;
|
|
@@ -83,8 +82,8 @@ export type IdentityManagerParams = {
|
|
|
83
82
|
export class IdentityManager {
|
|
84
83
|
readonly stateUpdate = new Event();
|
|
85
84
|
|
|
86
|
-
private readonly _metadataStore:
|
|
87
|
-
private readonly _keyring:
|
|
85
|
+
private readonly _metadataStore: IMetadataStore;
|
|
86
|
+
private readonly _keyring: KeyringApi;
|
|
88
87
|
private readonly _feedStore: FeedStore<FeedMessage>;
|
|
89
88
|
private readonly _spaceManager: SpaceManager;
|
|
90
89
|
private readonly _devicePresenceAnnounceInterval: number;
|
|
@@ -95,7 +94,7 @@ export class IdentityManager {
|
|
|
95
94
|
private _identity?: Identity;
|
|
96
95
|
|
|
97
96
|
// TODO(dmaretskyi): Perhaps this should take/generate the peerKey outside of an initialized identity.
|
|
98
|
-
constructor(params:
|
|
97
|
+
constructor(params: IdentityManagerProps) {
|
|
99
98
|
this._metadataStore = params.metadataStore;
|
|
100
99
|
this._keyring = params.keyring;
|
|
101
100
|
this._feedStore = params.feedStore;
|
|
@@ -112,8 +111,7 @@ export class IdentityManager {
|
|
|
112
111
|
|
|
113
112
|
@Trace.span({ showInBrowserTimeline: true })
|
|
114
113
|
async open(ctx: Context): Promise<void> {
|
|
115
|
-
|
|
116
|
-
log.trace('dxos.halo.identity-manager.open', trace.begin({ id: traceId }));
|
|
114
|
+
log('opening identity manager');
|
|
117
115
|
|
|
118
116
|
const identityRecord = this._metadataStore.getIdentityRecord();
|
|
119
117
|
log('identity record', { identityRecord });
|
|
@@ -128,15 +126,14 @@ export class IdentityManager {
|
|
|
128
126
|
|
|
129
127
|
this.stateUpdate.emit();
|
|
130
128
|
}
|
|
131
|
-
log
|
|
129
|
+
log('opened identity manager');
|
|
132
130
|
}
|
|
133
131
|
|
|
134
|
-
async close(): Promise<void> {
|
|
135
|
-
await this._identity?.close(
|
|
132
|
+
async close(ctx: Context): Promise<void> {
|
|
133
|
+
await this._identity?.close(ctx);
|
|
136
134
|
}
|
|
137
135
|
|
|
138
|
-
async createIdentity({ profile, deviceProfile }: CreateIdentityOptions = {}): Promise<Identity> {
|
|
139
|
-
// TODO(nf): populate using context from ServiceContext?
|
|
136
|
+
async createIdentity({ profile, deviceProfile }: CreateIdentityOptions = {}, ctx?: Context): Promise<Identity> {
|
|
140
137
|
invariant(!this._identity, 'Identity already exists.');
|
|
141
138
|
log('creating identity...');
|
|
142
139
|
|
|
@@ -153,7 +150,7 @@ export class IdentityManager {
|
|
|
153
150
|
};
|
|
154
151
|
|
|
155
152
|
const identity = await this._constructIdentity(identityRecord);
|
|
156
|
-
await identity.open(
|
|
153
|
+
await identity.open(ctx ?? Context.default());
|
|
157
154
|
|
|
158
155
|
{
|
|
159
156
|
const generator = new CredentialGenerator(this._keyring, identityRecord.identityKey, identityRecord.deviceKey);
|
|
@@ -211,28 +208,32 @@ export class IdentityManager {
|
|
|
211
208
|
return identity;
|
|
212
209
|
}
|
|
213
210
|
|
|
214
|
-
// TODO(nf): receive platform info rather than generating it here.
|
|
215
211
|
createDefaultDeviceProfile(): DeviceProfileDocument {
|
|
212
|
+
// See TODOs in credentials.proto.
|
|
216
213
|
let type: DeviceType;
|
|
217
|
-
// TODO(nf): call Platform service instead?
|
|
218
214
|
if (isNode()) {
|
|
219
215
|
type = DeviceType.AGENT;
|
|
220
216
|
} else {
|
|
221
217
|
if (platform.name?.startsWith('iOS') || platform.name?.startsWith('Android')) {
|
|
222
218
|
type = DeviceType.MOBILE;
|
|
223
|
-
} else if ((
|
|
219
|
+
} else if (isTauri() || !platform.name) {
|
|
220
|
+
// Tauri's __TAURI__ global isn't available in web workers. Fallback: WKWebView
|
|
221
|
+
// (Tauri on macOS) reports null for platform.name; all standard browsers don't.
|
|
224
222
|
type = DeviceType.NATIVE;
|
|
225
223
|
} else {
|
|
226
224
|
type = DeviceType.BROWSER;
|
|
227
225
|
}
|
|
228
226
|
}
|
|
229
227
|
|
|
228
|
+
const os = platform.os?.family === 'OS X' ? 'macOS' : platform.os?.family;
|
|
229
|
+
const name = type === DeviceType.NATIVE || type === DeviceType.MOBILE ? 'App' : platform.name;
|
|
230
|
+
|
|
230
231
|
return {
|
|
231
232
|
type,
|
|
232
|
-
platform:
|
|
233
|
+
platform: name,
|
|
233
234
|
platformVersion: platform.version,
|
|
234
235
|
architecture: typeof platform.os?.architecture === 'number' ? String(platform.os.architecture) : undefined,
|
|
235
|
-
os
|
|
236
|
+
os,
|
|
236
237
|
osVersion: platform.os?.version,
|
|
237
238
|
};
|
|
238
239
|
}
|
|
@@ -240,7 +241,7 @@ export class IdentityManager {
|
|
|
240
241
|
/**
|
|
241
242
|
* Prepare an identity object as the first step of acceptIdentity flow.
|
|
242
243
|
*/
|
|
243
|
-
async prepareIdentity(params:
|
|
244
|
+
async prepareIdentity(params: JoinIdentityProps, ctx?: Context) {
|
|
244
245
|
log('accepting identity', { params });
|
|
245
246
|
invariant(!this._identity, 'Identity already exists.');
|
|
246
247
|
|
|
@@ -256,7 +257,7 @@ export class IdentityManager {
|
|
|
256
257
|
},
|
|
257
258
|
};
|
|
258
259
|
const identity = await this._constructIdentity(identityRecord);
|
|
259
|
-
await identity.open(
|
|
260
|
+
await identity.open(ctx ?? Context.default());
|
|
260
261
|
return { identity, identityRecord };
|
|
261
262
|
}
|
|
262
263
|
|
|
@@ -395,7 +396,7 @@ export class IdentityManager {
|
|
|
395
396
|
return identity;
|
|
396
397
|
}
|
|
397
398
|
|
|
398
|
-
private async _constructSpace({ spaceRecord, swarmIdentity, identityKey, gossip }:
|
|
399
|
+
private async _constructSpace({ spaceRecord, swarmIdentity, identityKey, gossip }: ConstructSpaceProps) {
|
|
399
400
|
return this._spaceManager.constructSpace({
|
|
400
401
|
metadata: {
|
|
401
402
|
key: spaceRecord.key,
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { type Context } from '@dxos/context';
|
|
5
6
|
import { generateSeedPhrase, keyPairFromSeedPhrase } from '@dxos/credentials';
|
|
6
7
|
import { sign } from '@dxos/crypto';
|
|
7
8
|
import { type EdgeHttpClient } from '@dxos/edge-client';
|
|
8
9
|
import { invariant } from '@dxos/invariant';
|
|
9
|
-
import { type
|
|
10
|
+
import { type KeyringApi } from '@dxos/keyring';
|
|
10
11
|
import { PublicKey } from '@dxos/keys';
|
|
11
12
|
import { log } from '@dxos/log';
|
|
12
13
|
import {
|
|
@@ -22,14 +23,14 @@ import {
|
|
|
22
23
|
import { Timeframe } from '@dxos/timeframe';
|
|
23
24
|
|
|
24
25
|
import { type Identity } from './identity';
|
|
25
|
-
import { type
|
|
26
|
+
import { type JoinIdentityProps } from './identity-manager';
|
|
26
27
|
|
|
27
28
|
export class EdgeIdentityRecoveryManager {
|
|
28
29
|
constructor(
|
|
29
|
-
private readonly _keyring:
|
|
30
|
+
private readonly _keyring: KeyringApi,
|
|
30
31
|
private readonly _edgeClient: EdgeHttpClient | undefined,
|
|
31
32
|
private readonly _identityProvider: () => Identity | undefined,
|
|
32
|
-
private readonly _acceptRecoveredIdentity: (params:
|
|
33
|
+
private readonly _acceptRecoveredIdentity: (params: JoinIdentityProps) => Promise<Identity>,
|
|
33
34
|
) {}
|
|
34
35
|
|
|
35
36
|
public async createRecoveryCredential({
|
|
@@ -72,7 +73,7 @@ export class EdgeIdentityRecoveryManager {
|
|
|
72
73
|
return { recoveryCode };
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
public async requestRecoveryChallenge() {
|
|
76
|
+
public async requestRecoveryChallenge(ctx: Context) {
|
|
76
77
|
invariant(this._edgeClient, 'Not connected to EDGE.');
|
|
77
78
|
|
|
78
79
|
const deviceKey = await this._keyring.createKey();
|
|
@@ -83,7 +84,7 @@ export class EdgeIdentityRecoveryManager {
|
|
|
83
84
|
};
|
|
84
85
|
|
|
85
86
|
try {
|
|
86
|
-
await this._edgeClient.recoverIdentity(request);
|
|
87
|
+
await this._edgeClient.recoverIdentity(ctx, request);
|
|
87
88
|
throw new Error('No challenge received.');
|
|
88
89
|
} catch (error: any) {
|
|
89
90
|
if (!(error instanceof EdgeAuthChallengeError)) {
|
|
@@ -97,14 +98,17 @@ export class EdgeIdentityRecoveryManager {
|
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
public async recoverIdentityWithExternalSignature(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
101
|
+
public async recoverIdentityWithExternalSignature(
|
|
102
|
+
ctx: Context,
|
|
103
|
+
{
|
|
104
|
+
lookupKey,
|
|
105
|
+
deviceKey,
|
|
106
|
+
controlFeedKey,
|
|
107
|
+
signature,
|
|
108
|
+
clientDataJson,
|
|
109
|
+
authenticatorData,
|
|
110
|
+
}: RecoverIdentityRequest.ExternalSignature,
|
|
111
|
+
): Promise<void> {
|
|
108
112
|
invariant(this._edgeClient, 'Not connected to EDGE.');
|
|
109
113
|
|
|
110
114
|
const request: EdgeRecoverIdentityRequest = {
|
|
@@ -121,7 +125,7 @@ export class EdgeIdentityRecoveryManager {
|
|
|
121
125
|
: Buffer.from(signature).toString('base64'),
|
|
122
126
|
};
|
|
123
127
|
|
|
124
|
-
const response = await this._edgeClient.recoverIdentity(request);
|
|
128
|
+
const response = await this._edgeClient.recoverIdentity(ctx, request);
|
|
125
129
|
|
|
126
130
|
await this._acceptRecoveredIdentity({
|
|
127
131
|
authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),
|
|
@@ -135,9 +139,14 @@ export class EdgeIdentityRecoveryManager {
|
|
|
135
139
|
}
|
|
136
140
|
|
|
137
141
|
/**
|
|
138
|
-
*
|
|
142
|
+
* Recover an identity using an opaque one-time token. Accepts either an email magic-link
|
|
143
|
+
* `token` (validated by hub-service) or an OAuth `recoveryProof` (redeemed by kms-service).
|
|
144
|
+
* The two fields are routed to different backends by db-service and must not be conflated.
|
|
139
145
|
*/
|
|
140
|
-
public async recoverIdentityWithToken(
|
|
146
|
+
public async recoverIdentityWithToken(
|
|
147
|
+
ctx: Context,
|
|
148
|
+
fields: { token: string } | { recoveryProof: string },
|
|
149
|
+
): Promise<void> {
|
|
141
150
|
invariant(this._edgeClient, 'Not connected to EDGE.');
|
|
142
151
|
|
|
143
152
|
const deviceKey = await this._keyring.createKey();
|
|
@@ -145,10 +154,10 @@ export class EdgeIdentityRecoveryManager {
|
|
|
145
154
|
const request: EdgeRecoverIdentityRequest = {
|
|
146
155
|
deviceKey: deviceKey.toHex(),
|
|
147
156
|
controlFeedKey: controlFeedKey.toHex(),
|
|
148
|
-
|
|
157
|
+
...fields,
|
|
149
158
|
};
|
|
150
159
|
|
|
151
|
-
const response = await this._edgeClient.recoverIdentity(request);
|
|
160
|
+
const response = await this._edgeClient.recoverIdentity(ctx, request);
|
|
152
161
|
|
|
153
162
|
await this._acceptRecoveredIdentity({
|
|
154
163
|
authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),
|
|
@@ -161,7 +170,7 @@ export class EdgeIdentityRecoveryManager {
|
|
|
161
170
|
});
|
|
162
171
|
}
|
|
163
172
|
|
|
164
|
-
public async recoverIdentity({ recoveryCode }: { recoveryCode: string }): Promise<void> {
|
|
173
|
+
public async recoverIdentity(ctx: Context, { recoveryCode }: { recoveryCode: string }): Promise<void> {
|
|
165
174
|
invariant(this._edgeClient, 'Not connected to EDGE.');
|
|
166
175
|
|
|
167
176
|
const recoveryKeypair = keyPairFromSeedPhrase(recoveryCode);
|
|
@@ -176,13 +185,13 @@ export class EdgeIdentityRecoveryManager {
|
|
|
176
185
|
|
|
177
186
|
let response: RecoverIdentityResponseBody;
|
|
178
187
|
try {
|
|
179
|
-
response = await this._edgeClient.recoverIdentity(request);
|
|
188
|
+
response = await this._edgeClient.recoverIdentity(ctx, request);
|
|
180
189
|
} catch (error: any) {
|
|
181
190
|
if (!(error instanceof EdgeAuthChallengeError)) {
|
|
182
191
|
throw error;
|
|
183
192
|
}
|
|
184
193
|
const signature = sign(Buffer.from(error.challenge, 'base64'), recoveryKeypair.secretKey);
|
|
185
|
-
response = await this._edgeClient.recoverIdentity({
|
|
194
|
+
response = await this._edgeClient.recoverIdentity(ctx, {
|
|
186
195
|
...request,
|
|
187
196
|
signature: Buffer.from(signature).toString('base64'),
|
|
188
197
|
});
|
|
@@ -11,7 +11,6 @@ import { type Identity, type IdentityService } from '@dxos/protocols/proto/dxos/
|
|
|
11
11
|
|
|
12
12
|
import { type ServiceContext } from '../services';
|
|
13
13
|
import { createServiceContext } from '../testing';
|
|
14
|
-
|
|
15
14
|
import { IdentityServiceImpl } from './identity-service';
|
|
16
15
|
|
|
17
16
|
describe('IdentityService', () => {
|
|
@@ -48,6 +47,12 @@ describe('IdentityService', () => {
|
|
|
48
47
|
await identityService.createIdentity({});
|
|
49
48
|
await expect(identityService.createIdentity({})).rejects.toThrowError('Identity already exists');
|
|
50
49
|
});
|
|
50
|
+
|
|
51
|
+
test('creates identity with no spaces', async () => {
|
|
52
|
+
await identityService.createIdentity({});
|
|
53
|
+
const dataSpaces = [...(serviceContext.dataSpaceManager?.spaces?.values() ?? [])];
|
|
54
|
+
expect(dataSpaces.length).to.eq(0);
|
|
55
|
+
});
|
|
51
56
|
});
|
|
52
57
|
|
|
53
58
|
describe.skip('recoverIdentity', () => {});
|
|
@@ -89,37 +94,11 @@ describe('IdentityService', () => {
|
|
|
89
94
|
});
|
|
90
95
|
});
|
|
91
96
|
|
|
92
|
-
describe('open', () => {
|
|
93
|
-
test('identity without default space fixed', async () => {
|
|
94
|
-
const serviceContext = await createServiceContext();
|
|
95
|
-
await serviceContext.open(new Context());
|
|
96
|
-
const identity = await serviceContext.createIdentity();
|
|
97
|
-
const identityService = createIdentityService(serviceContext);
|
|
98
|
-
const getDataSpaces = () => [...(serviceContext.dataSpaceManager?.spaces?.values() ?? [])];
|
|
99
|
-
expect(getDataSpaces().length).to.eq(0);
|
|
100
|
-
expect(identity.defaultSpaceId).to.be.undefined;
|
|
101
|
-
await identityService.open();
|
|
102
|
-
expect(getDataSpaces()[0].id === identity.defaultSpaceId).to.be.true;
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
test('identity without default space credential fixed', async () => {
|
|
106
|
-
const serviceContext = await createServiceContext();
|
|
107
|
-
await serviceContext.open(new Context());
|
|
108
|
-
const identity = await serviceContext.createIdentity();
|
|
109
|
-
const space = await serviceContext.dataSpaceManager!.createDefaultSpace();
|
|
110
|
-
const identityService = createIdentityService(serviceContext);
|
|
111
|
-
expect(identity.defaultSpaceId).to.be.undefined;
|
|
112
|
-
await identityService.open();
|
|
113
|
-
expect(identity.defaultSpaceId === space.id).to.be.true;
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
|
|
117
97
|
const createIdentityService = (serviceContext: ServiceContext) => {
|
|
118
98
|
return new IdentityServiceImpl(
|
|
119
99
|
serviceContext.identityManager,
|
|
120
100
|
serviceContext.recoveryManager,
|
|
121
101
|
serviceContext.keyring,
|
|
122
|
-
() => serviceContext.dataSpaceManager!,
|
|
123
102
|
(options) => serviceContext.createIdentity(options),
|
|
124
103
|
);
|
|
125
104
|
};
|
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { type RequestOptions } from '@dxos/codec-protobuf';
|
|
6
6
|
import { Stream } from '@dxos/codec-protobuf/stream';
|
|
7
|
-
import { Resource } from '@dxos/context';
|
|
7
|
+
import { Context, Resource } from '@dxos/context';
|
|
8
8
|
import { createCredential, signPresentation } from '@dxos/credentials';
|
|
9
9
|
import { invariant } from '@dxos/invariant';
|
|
10
|
-
import { type
|
|
11
|
-
import { log } from '@dxos/log';
|
|
10
|
+
import { type KeyringApi } from '@dxos/keyring';
|
|
12
11
|
import {
|
|
13
12
|
type CreateIdentityRequest,
|
|
14
13
|
type CreateRecoveryCredentialRequest,
|
|
@@ -17,52 +16,30 @@ import {
|
|
|
17
16
|
type QueryIdentityResponse,
|
|
18
17
|
type RecoverIdentityRequest,
|
|
19
18
|
type SignPresentationRequest,
|
|
20
|
-
SpaceState,
|
|
21
19
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
22
20
|
import { type Presentation, type ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
23
|
-
import { safeAwaitAll } from '@dxos/util';
|
|
24
|
-
|
|
25
|
-
import { type DataSpaceManager } from '../spaces';
|
|
26
21
|
|
|
27
22
|
import { type Identity } from './identity';
|
|
28
23
|
import { type CreateIdentityOptions, type IdentityManager } from './identity-manager';
|
|
29
24
|
import { type EdgeIdentityRecoveryManager } from './identity-recovery-manager';
|
|
30
25
|
|
|
31
|
-
const DEFAULT_SPACE_SEARCH_TIMEOUT = 10_000;
|
|
32
|
-
|
|
33
26
|
export class IdentityServiceImpl extends Resource implements IdentityService {
|
|
34
27
|
constructor(
|
|
35
28
|
private readonly _identityManager: IdentityManager,
|
|
36
29
|
private readonly _recoveryManager: EdgeIdentityRecoveryManager,
|
|
37
|
-
private readonly _keyring:
|
|
38
|
-
private readonly
|
|
39
|
-
private readonly _createIdentity: (params: CreateIdentityOptions) => Promise<Identity>,
|
|
30
|
+
private readonly _keyring: KeyringApi,
|
|
31
|
+
private readonly _createIdentity: (params: CreateIdentityOptions, ctx?: Context) => Promise<Identity>,
|
|
40
32
|
private readonly _onProfileUpdate?: (profile: ProfileDocument | undefined) => Promise<void>,
|
|
41
33
|
) {
|
|
42
34
|
super();
|
|
43
35
|
}
|
|
44
36
|
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
await this._fixIdentityWithoutDefaultSpace(identity);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async createIdentity(request: CreateIdentityRequest): Promise<IdentityProto> {
|
|
53
|
-
await this._createIdentity({ profile: request.profile, deviceProfile: request.deviceProfile });
|
|
54
|
-
const dataSpaceManager = this._dataSpaceManagerProvider();
|
|
55
|
-
await this._createDefaultSpace(dataSpaceManager);
|
|
37
|
+
async createIdentity(request: CreateIdentityRequest, options?: RequestOptions): Promise<IdentityProto> {
|
|
38
|
+
const ctx = options?.ctx ?? Context.default();
|
|
39
|
+
await this._createIdentity({ profile: request.profile, deviceProfile: request.deviceProfile }, ctx);
|
|
56
40
|
return this._getIdentity()!;
|
|
57
41
|
}
|
|
58
42
|
|
|
59
|
-
private async _createDefaultSpace(dataSpaceManager: DataSpaceManager): Promise<void> {
|
|
60
|
-
const space = await dataSpaceManager!.createDefaultSpace();
|
|
61
|
-
const identity = this._identityManager.identity;
|
|
62
|
-
invariant(identity);
|
|
63
|
-
await identity.updateDefaultSpace(space.id);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
43
|
queryIdentity(): Stream<QueryIdentityResponse> {
|
|
67
44
|
return new Stream(({ next }) => {
|
|
68
45
|
const emitNext = () => next({ identity: this._getIdentity() });
|
|
@@ -96,17 +73,20 @@ export class IdentityServiceImpl extends Resource implements IdentityService {
|
|
|
96
73
|
return this._recoveryManager.createRecoveryCredential(request);
|
|
97
74
|
}
|
|
98
75
|
|
|
99
|
-
async requestRecoveryChallenge() {
|
|
100
|
-
return this._recoveryManager.requestRecoveryChallenge();
|
|
76
|
+
async requestRecoveryChallenge(_request: void, options?: RequestOptions) {
|
|
77
|
+
return this._recoveryManager.requestRecoveryChallenge(options?.ctx ?? Context.default());
|
|
101
78
|
}
|
|
102
79
|
|
|
103
|
-
async recoverIdentity(request: RecoverIdentityRequest): Promise<IdentityProto> {
|
|
80
|
+
async recoverIdentity(request: RecoverIdentityRequest, options?: RequestOptions): Promise<IdentityProto> {
|
|
81
|
+
const ctx = options?.ctx ?? Context.default();
|
|
104
82
|
if (request.recoveryCode) {
|
|
105
|
-
await this._recoveryManager.recoverIdentity({ recoveryCode: request.recoveryCode });
|
|
83
|
+
await this._recoveryManager.recoverIdentity(ctx, { recoveryCode: request.recoveryCode });
|
|
106
84
|
} else if (request.external) {
|
|
107
|
-
await this._recoveryManager.recoverIdentityWithExternalSignature(request.external);
|
|
85
|
+
await this._recoveryManager.recoverIdentityWithExternalSignature(ctx, request.external);
|
|
108
86
|
} else if (request.token) {
|
|
109
|
-
await this._recoveryManager.recoverIdentityWithToken({ token: request.token });
|
|
87
|
+
await this._recoveryManager.recoverIdentityWithToken(ctx, { token: request.token });
|
|
88
|
+
} else if (request.recoveryProof) {
|
|
89
|
+
await this._recoveryManager.recoverIdentityWithToken(ctx, { recoveryProof: request.recoveryProof });
|
|
110
90
|
} else {
|
|
111
91
|
throw new Error('Invalid request.');
|
|
112
92
|
}
|
|
@@ -141,50 +121,4 @@ export class IdentityServiceImpl extends Resource implements IdentityService {
|
|
|
141
121
|
signer: this._keyring,
|
|
142
122
|
});
|
|
143
123
|
}
|
|
144
|
-
|
|
145
|
-
private async _fixIdentityWithoutDefaultSpace(identity: Identity): Promise<void> {
|
|
146
|
-
let recodedDefaultSpace = false;
|
|
147
|
-
let foundDefaultSpace = false;
|
|
148
|
-
const dataSpaceManager = this._dataSpaceManagerProvider();
|
|
149
|
-
|
|
150
|
-
const recordedDefaultSpaceTrigger = new Trigger();
|
|
151
|
-
|
|
152
|
-
const allProcessed = safeAwaitAll(
|
|
153
|
-
dataSpaceManager.spaces.values(),
|
|
154
|
-
async (space) => {
|
|
155
|
-
if (space.state === SpaceState.SPACE_CLOSED) {
|
|
156
|
-
await space.open();
|
|
157
|
-
|
|
158
|
-
// Wait until the space is either READY or REQUIRES_MIGRATION.
|
|
159
|
-
// NOTE: Space could potentially never initialize if the space data is corrupted.
|
|
160
|
-
const requiresMigration = space.stateUpdate.waitForCondition(
|
|
161
|
-
() => space.state === SpaceState.SPACE_REQUIRES_MIGRATION,
|
|
162
|
-
);
|
|
163
|
-
await Promise.race([space.initializeDataPipeline(), requiresMigration]);
|
|
164
|
-
}
|
|
165
|
-
if (await dataSpaceManager.isDefaultSpace(space)) {
|
|
166
|
-
if (foundDefaultSpace) {
|
|
167
|
-
log.warn('Multiple default spaces found. Using the first one.', { duplicate: space.id });
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
foundDefaultSpace = true;
|
|
172
|
-
await identity.updateDefaultSpace(space.id);
|
|
173
|
-
recodedDefaultSpace = true;
|
|
174
|
-
recordedDefaultSpaceTrigger.wake();
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
|
-
(err) => {
|
|
178
|
-
log.catch(err);
|
|
179
|
-
},
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
// Wait for all spaces to be processed or until the default space is recorded.
|
|
183
|
-
// If the timeout is reached, create a new default space.
|
|
184
|
-
await Promise.race([allProcessed, recordedDefaultSpaceTrigger.wait(), sleep(DEFAULT_SPACE_SEARCH_TIMEOUT)]);
|
|
185
|
-
|
|
186
|
-
if (!recodedDefaultSpace) {
|
|
187
|
-
await this._createDefaultSpace(dataSpaceManager);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
124
|
}
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
SpaceProtocol,
|
|
16
16
|
createIdFromSpaceKey,
|
|
17
17
|
valueEncoding,
|
|
18
|
-
} from '@dxos/echo-
|
|
18
|
+
} from '@dxos/echo-host';
|
|
19
19
|
import { type EdgeConnection, type MessageListener } from '@dxos/edge-client';
|
|
20
20
|
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
21
21
|
import { type FeedWrapper } from '@dxos/feed-store';
|
|
@@ -130,7 +130,7 @@ describe('identity/identity', () => {
|
|
|
130
130
|
onMessage: (_: MessageListener): (() => void) => {
|
|
131
131
|
return () => {};
|
|
132
132
|
},
|
|
133
|
-
send: async (_) => {
|
|
133
|
+
send: async (..._) => {
|
|
134
134
|
replicationStarted = true;
|
|
135
135
|
},
|
|
136
136
|
} as EdgeConnection,
|
|
@@ -218,7 +218,7 @@ describe('identity/identity', () => {
|
|
|
218
218
|
});
|
|
219
219
|
|
|
220
220
|
await identity.open(new Context());
|
|
221
|
-
await identity.joinNetwork();
|
|
221
|
+
await identity.joinNetwork(Context.default());
|
|
222
222
|
onTestFinished(() => identity.close(new Context()));
|
|
223
223
|
return { identity, identityKey, keyring, deviceKey, controlFeed, spaceKey, dataFeed };
|
|
224
224
|
};
|