@dxos/client-services 0.5.0 → 0.5.1-main.0ec204c
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-ESEYLOPB.mjs → chunk-5I77NB7R.mjs} +1437 -1119
- package/dist/lib/browser/chunk-5I77NB7R.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +36 -5
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/testing/index.mjs +36 -14
- package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-GA7JFIXK.cjs → chunk-W24O4MIS.cjs} +1552 -1238
- package/dist/lib/node/chunk-W24O4MIS.cjs.map +7 -0
- package/dist/lib/node/index.cjs +78 -47
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/packlets/testing/index.cjs +40 -18
- package/dist/lib/node/packlets/testing/index.cjs.map +3 -3
- package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +2 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts +39 -0
- package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/{invitation-extension.d.ts → invitation-host-extension.d.ts} +17 -31
- package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +6 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-topology.d.ts +37 -0
- package/dist/types/src/packlets/invitations/invitation-topology.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +19 -10
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.test.d.ts +2 -0
- package/dist/types/src/packlets/invitations/invitations-handler.test.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts +2 -1
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +1 -0
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/utils.d.ts +6 -0
- package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -0
- package/dist/types/src/packlets/services/service-context.d.ts +12 -11
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +1 -2
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +4 -3
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +4 -3
- package/dist/types/src/packlets/spaces/data-space.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/storage/level.d.ts +1 -2
- package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts +2 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts +5 -3
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/shell-runtime.d.ts +10 -2
- package/dist/types/src/packlets/vault/shell-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/worker-runtime.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/package.json +36 -35
- package/src/packlets/diagnostics/diagnostics-collector.ts +14 -9
- package/src/packlets/diagnostics/diagnostics.ts +78 -68
- package/src/packlets/invitations/device-invitation-protocol.ts +5 -1
- package/src/packlets/invitations/invitation-guest-extenstion.ts +126 -0
- package/src/packlets/invitations/{invitation-extension.ts → invitation-host-extension.ts} +99 -105
- package/src/packlets/invitations/invitation-protocol.ts +7 -1
- package/src/packlets/invitations/invitation-topology.ts +87 -0
- package/src/packlets/invitations/invitations-handler.test.ts +361 -0
- package/src/packlets/invitations/invitations-handler.ts +246 -149
- package/src/packlets/invitations/invitations-manager.ts +45 -3
- package/src/packlets/invitations/space-invitation-protocol.ts +23 -3
- package/src/packlets/invitations/utils.ts +27 -0
- package/src/packlets/services/automerge-host.test.ts +6 -4
- package/src/packlets/services/service-context.test.ts +3 -3
- package/src/packlets/services/service-context.ts +18 -31
- package/src/packlets/services/service-host.test.ts +6 -0
- package/src/packlets/services/service-host.ts +11 -28
- package/src/packlets/spaces/data-space-manager.test.ts +4 -4
- package/src/packlets/spaces/data-space-manager.ts +8 -11
- package/src/packlets/spaces/data-space.ts +16 -19
- package/src/packlets/spaces/genesis.ts +1 -1
- package/src/packlets/spaces/spaces-service.ts +12 -6
- package/src/packlets/storage/level.ts +3 -2
- package/src/packlets/testing/invitation-utils.ts +23 -3
- package/src/packlets/testing/test-builder.ts +13 -15
- package/src/packlets/vault/shell-runtime.ts +40 -2
- package/src/packlets/vault/worker-runtime.ts +3 -1
- package/src/version.ts +1 -5
- package/dist/lib/browser/chunk-ESEYLOPB.mjs.map +0 -7
- package/dist/lib/node/chunk-GA7JFIXK.cjs.map +0 -7
- package/dist/types/src/packlets/indexing/index.d.ts +0 -2
- package/dist/types/src/packlets/indexing/index.d.ts.map +0 -1
- package/dist/types/src/packlets/indexing/util.d.ts +0 -11
- package/dist/types/src/packlets/indexing/util.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/invitation-extension.d.ts.map +0 -1
- package/src/packlets/indexing/index.ts +0 -5
- package/src/packlets/indexing/util.ts +0 -32
|
@@ -6,14 +6,10 @@ import { Event, asyncTimeout, scheduleTask, sleep, synchronized, trackLeaks } fr
|
|
|
6
6
|
import { AUTH_TIMEOUT } from '@dxos/client-protocol';
|
|
7
7
|
import { cancelWithContext, Context, ContextDisposedError } from '@dxos/context';
|
|
8
8
|
import { timed, warnAfterTimeout } from '@dxos/debug';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
type Space,
|
|
12
|
-
createMappedFeedWriter,
|
|
13
|
-
type AutomergeHost,
|
|
14
|
-
type SpaceDoc,
|
|
15
|
-
} from '@dxos/echo-pipeline';
|
|
9
|
+
import { type EchoHost } from '@dxos/echo-db';
|
|
10
|
+
import { type MetadataStore, type Space, createMappedFeedWriter } from '@dxos/echo-pipeline';
|
|
16
11
|
import { AutomergeDocumentLoaderImpl } from '@dxos/echo-pipeline';
|
|
12
|
+
import { type SpaceDoc } from '@dxos/echo-protocol';
|
|
17
13
|
import { TYPE_PROPERTIES } from '@dxos/echo-schema';
|
|
18
14
|
import { type FeedStore } from '@dxos/feed-store';
|
|
19
15
|
import { failedInvariant, invariant } from '@dxos/invariant';
|
|
@@ -24,6 +20,7 @@ import { CancelledError, SystemError } from '@dxos/protocols';
|
|
|
24
20
|
import { SpaceState, type Space as SpaceProto, CreateEpochRequest } from '@dxos/protocols/proto/dxos/client/services';
|
|
25
21
|
import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
26
22
|
import { type SpaceCache } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
23
|
+
import { SpaceMember } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
27
24
|
import {
|
|
28
25
|
AdmittedFeed,
|
|
29
26
|
type ProfileDocument,
|
|
@@ -66,10 +63,10 @@ export type DataSpaceParams = {
|
|
|
66
63
|
presence: Presence;
|
|
67
64
|
keyring: Keyring;
|
|
68
65
|
feedStore: FeedStore<FeedMessage>;
|
|
66
|
+
echoHost: EchoHost;
|
|
69
67
|
signingContext: SigningContext;
|
|
70
68
|
callbacks?: DataSpaceCallbacks;
|
|
71
69
|
cache?: SpaceCache;
|
|
72
|
-
automergeHost: AutomergeHost;
|
|
73
70
|
};
|
|
74
71
|
|
|
75
72
|
export type CreateEpochOptions = {
|
|
@@ -92,7 +89,7 @@ export class DataSpace {
|
|
|
92
89
|
private readonly _notarizationPlugin = new NotarizationPlugin();
|
|
93
90
|
private readonly _callbacks: DataSpaceCallbacks;
|
|
94
91
|
private readonly _cache?: SpaceCache = undefined;
|
|
95
|
-
private readonly
|
|
92
|
+
private readonly _echoHost: EchoHost;
|
|
96
93
|
|
|
97
94
|
// TODO(dmaretskyi): Move into Space?
|
|
98
95
|
private readonly _automergeSpaceState = new AutomergeSpaceState((rootUrl) => this._onNewAutomergeRoot(rootUrl));
|
|
@@ -120,14 +117,14 @@ export class DataSpace {
|
|
|
120
117
|
this._metadataStore = params.metadataStore;
|
|
121
118
|
this._signingContext = params.signingContext;
|
|
122
119
|
this._callbacks = params.callbacks ?? {};
|
|
123
|
-
this.
|
|
120
|
+
this._echoHost = params.echoHost;
|
|
124
121
|
|
|
125
122
|
this.authVerifier = new TrustedKeySetAuthVerifier({
|
|
126
123
|
trustedKeysProvider: () =>
|
|
127
124
|
new ComplexSet(
|
|
128
125
|
PublicKey.hash,
|
|
129
126
|
Array.from(this._inner.spaceState.members.values())
|
|
130
|
-
.filter((member) =>
|
|
127
|
+
.filter((member) => member.role !== SpaceMember.Role.REMOVED)
|
|
131
128
|
.map((member) => member.key),
|
|
132
129
|
),
|
|
133
130
|
update: this._inner.stateUpdate,
|
|
@@ -363,8 +360,8 @@ export class DataSpace {
|
|
|
363
360
|
|
|
364
361
|
private _onNewAutomergeRoot(rootUrl: string) {
|
|
365
362
|
log('loading automerge root doc for space', { space: this.key, rootUrl });
|
|
366
|
-
this.
|
|
367
|
-
const handle = this.
|
|
363
|
+
this._echoHost.replicateDocument(rootUrl);
|
|
364
|
+
const handle = this._echoHost.automergeRepo.find(rootUrl as any);
|
|
368
365
|
|
|
369
366
|
queueMicrotask(async () => {
|
|
370
367
|
try {
|
|
@@ -419,7 +416,7 @@ export class DataSpace {
|
|
|
419
416
|
break;
|
|
420
417
|
case CreateEpochRequest.Migration.INIT_AUTOMERGE:
|
|
421
418
|
{
|
|
422
|
-
const document = this.
|
|
419
|
+
const document = this._echoHost.automergeRepo.create();
|
|
423
420
|
// TODO(dmaretskyi): Unify epoch construction.
|
|
424
421
|
epoch = {
|
|
425
422
|
previousId: this._automergeSpaceState.lastEpoch?.id,
|
|
@@ -432,9 +429,9 @@ export class DataSpace {
|
|
|
432
429
|
case CreateEpochRequest.Migration.PRUNE_AUTOMERGE_ROOT_HISTORY:
|
|
433
430
|
{
|
|
434
431
|
const currentRootUrl = this._automergeSpaceState.rootUrl;
|
|
435
|
-
const rootHandle = this.
|
|
432
|
+
const rootHandle = this._echoHost.automergeRepo.find(currentRootUrl as any);
|
|
436
433
|
await cancelWithContext(this._ctx, asyncTimeout(rootHandle.whenReady(), 10_000));
|
|
437
|
-
const newRoot = this.
|
|
434
|
+
const newRoot = this._echoHost.automergeRepo.create(rootHandle.docSync());
|
|
438
435
|
invariant(typeof newRoot.url === 'string' && newRoot.url.length > 0);
|
|
439
436
|
// TODO(dmaretskyi): Unify epoch construction.
|
|
440
437
|
epoch = {
|
|
@@ -450,7 +447,7 @@ export class DataSpace {
|
|
|
450
447
|
log.info('Fragmenting');
|
|
451
448
|
|
|
452
449
|
const currentRootUrl = this._automergeSpaceState.rootUrl;
|
|
453
|
-
const rootHandle = this.
|
|
450
|
+
const rootHandle = this._echoHost.automergeRepo.find<SpaceDoc>(currentRootUrl as any);
|
|
454
451
|
await cancelWithContext(this._ctx, asyncTimeout(rootHandle.whenReady(), 10_000));
|
|
455
452
|
|
|
456
453
|
// Find properties object.
|
|
@@ -461,11 +458,11 @@ export class DataSpace {
|
|
|
461
458
|
|
|
462
459
|
// Create a new space doc with the properties object.
|
|
463
460
|
const newSpaceDoc: SpaceDoc = { ...rootHandle.docSync(), objects: Object.fromEntries([properties]) };
|
|
464
|
-
const newRoot = this.
|
|
461
|
+
const newRoot = this._echoHost.automergeRepo.create(newSpaceDoc);
|
|
465
462
|
invariant(typeof newRoot.url === 'string' && newRoot.url.length > 0);
|
|
466
463
|
|
|
467
464
|
// Create new automerge documents for all objects.
|
|
468
|
-
const docLoader = new AutomergeDocumentLoaderImpl(this.key, this.
|
|
465
|
+
const docLoader = new AutomergeDocumentLoaderImpl(this.key, this._echoHost.automergeRepo);
|
|
469
466
|
await docLoader.loadSpaceRootDocHandle(this._ctx, { rootUrl: newRoot.url });
|
|
470
467
|
|
|
471
468
|
otherObjects.forEach(([key, value]) => {
|
|
@@ -36,7 +36,7 @@ export const spaceGenesis = async (
|
|
|
36
36
|
assertion: {
|
|
37
37
|
'@type': 'dxos.halo.credentials.SpaceMember',
|
|
38
38
|
spaceKey: space.key,
|
|
39
|
-
role: SpaceMember.Role.
|
|
39
|
+
role: SpaceMember.Role.OWNER,
|
|
40
40
|
profile: signingContext.getProfile(),
|
|
41
41
|
genesisFeedKey: space.controlFeedKey ?? failUndefined(),
|
|
42
42
|
},
|
|
@@ -22,8 +22,9 @@ import {
|
|
|
22
22
|
type SubscribeMessagesRequest,
|
|
23
23
|
type UpdateSpaceRequest,
|
|
24
24
|
type WriteCredentialsRequest,
|
|
25
|
+
type UpdateMemberRoleRequest,
|
|
25
26
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
26
|
-
import { type Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
27
|
+
import { type Credential, SpaceMember as HaloSpaceMember } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
27
28
|
import { type GossipMessage } from '@dxos/protocols/proto/dxos/mesh/teleport/gossip';
|
|
28
29
|
import { type Provider } from '@dxos/util';
|
|
29
30
|
|
|
@@ -67,6 +68,10 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
async updateMemberRole(_: UpdateMemberRoleRequest): Promise<void> {
|
|
72
|
+
throw new Error('not implemented');
|
|
73
|
+
}
|
|
74
|
+
|
|
70
75
|
querySpaces(): Stream<QuerySpacesResponse> {
|
|
71
76
|
return new Stream<QuerySpacesResponse>(({ next, ctx }) => {
|
|
72
77
|
const scheduler = new UpdateScheduler(
|
|
@@ -213,11 +218,12 @@ export class SpacesServiceImpl implements SpacesService {
|
|
|
213
218
|
identityKey: member.key,
|
|
214
219
|
profile: member.profile ?? {},
|
|
215
220
|
},
|
|
216
|
-
presence:
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
+
presence:
|
|
222
|
+
member.role === HaloSpaceMember.Role.REMOVED
|
|
223
|
+
? SpaceMember.PresenceState.REMOVED
|
|
224
|
+
: isMe || peers.length > 0
|
|
225
|
+
? SpaceMember.PresenceState.ONLINE
|
|
226
|
+
: SpaceMember.PresenceState.OFFLINE,
|
|
221
227
|
peerStates: peers,
|
|
222
228
|
};
|
|
223
229
|
}),
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Level } from 'level';
|
|
6
5
|
import path from 'node:path';
|
|
7
6
|
|
|
8
7
|
import { PublicKey } from '@dxos/keys';
|
|
8
|
+
import { createLevel as createKV } from '@dxos/kv-store';
|
|
9
9
|
import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
10
10
|
|
|
11
11
|
import { getRootPath, isPersistent } from './util';
|
|
@@ -13,7 +13,8 @@ import { getRootPath, isPersistent } from './util';
|
|
|
13
13
|
export const createLevel = async (config: Runtime.Client.Storage) => {
|
|
14
14
|
const persistent = isPersistent(config);
|
|
15
15
|
const storagePath = persistent ? path.join(getRootPath(config), 'level') : `/tmp/dxos-${PublicKey.random().toHex()}`;
|
|
16
|
-
const level =
|
|
16
|
+
const level = createKV(storagePath);
|
|
17
|
+
// TODO(dmaretskyi): This function shouldn't call open - .
|
|
17
18
|
await level.open();
|
|
18
19
|
return level;
|
|
19
20
|
};
|
|
@@ -45,6 +45,7 @@ export type PerformInvitationParams = {
|
|
|
45
45
|
guest?: PerformInvitationCallbacks<AuthenticatingInvitation>;
|
|
46
46
|
};
|
|
47
47
|
guestDeviceProfile?: DeviceProfileDocument;
|
|
48
|
+
codeInputDelay?: number;
|
|
48
49
|
};
|
|
49
50
|
|
|
50
51
|
export type Result = { invitation?: Invitation; error?: Error };
|
|
@@ -55,7 +56,10 @@ export const performInvitation = ({
|
|
|
55
56
|
options,
|
|
56
57
|
hooks,
|
|
57
58
|
guestDeviceProfile,
|
|
59
|
+
codeInputDelay,
|
|
58
60
|
}: PerformInvitationParams): [Promise<Result>, Promise<Result>] => {
|
|
61
|
+
let guestError = false;
|
|
62
|
+
let guestConnected = false;
|
|
59
63
|
const hostComplete = new Trigger<Result>();
|
|
60
64
|
const guestComplete = new Trigger<Result>();
|
|
61
65
|
const authCode = new Trigger<string>();
|
|
@@ -65,6 +69,10 @@ export const performInvitation = ({
|
|
|
65
69
|
async (hostInvitation: Invitation) => {
|
|
66
70
|
switch (hostInvitation.state) {
|
|
67
71
|
case Invitation.State.CONNECTING: {
|
|
72
|
+
if (guestConnected) {
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
guestConnected = true;
|
|
68
76
|
if (hooks?.host?.onConnecting?.(hostObservable)) {
|
|
69
77
|
break;
|
|
70
78
|
}
|
|
@@ -89,7 +97,16 @@ export const performInvitation = ({
|
|
|
89
97
|
if (hooks?.guest?.onReady?.(guestObservable)) {
|
|
90
98
|
break;
|
|
91
99
|
}
|
|
92
|
-
|
|
100
|
+
const code = await authCode.wait();
|
|
101
|
+
if (codeInputDelay == null) {
|
|
102
|
+
await guestObservable.authenticate(code);
|
|
103
|
+
} else {
|
|
104
|
+
setTimeout(async () => {
|
|
105
|
+
if (!guestError) {
|
|
106
|
+
await guestObservable.authenticate(code);
|
|
107
|
+
}
|
|
108
|
+
}, codeInputDelay);
|
|
109
|
+
}
|
|
93
110
|
break;
|
|
94
111
|
}
|
|
95
112
|
|
|
@@ -123,6 +140,7 @@ export const performInvitation = ({
|
|
|
123
140
|
}
|
|
124
141
|
},
|
|
125
142
|
(error: Error) => {
|
|
143
|
+
guestError = true;
|
|
126
144
|
if (hooks?.guest?.onError?.(guestObservable)) {
|
|
127
145
|
return;
|
|
128
146
|
}
|
|
@@ -216,8 +234,10 @@ const acceptInvitation = (
|
|
|
216
234
|
invitation = sanitizeInvitation(invitation);
|
|
217
235
|
|
|
218
236
|
if (guest instanceof ServiceContext) {
|
|
219
|
-
|
|
220
|
-
|
|
237
|
+
return guest.invitationsManager.acceptInvitation({
|
|
238
|
+
invitation,
|
|
239
|
+
deviceProfile: guestDeviceProfile,
|
|
240
|
+
});
|
|
221
241
|
}
|
|
222
242
|
|
|
223
243
|
return guest.join(invitation, guestDeviceProfile);
|
|
@@ -6,17 +6,12 @@ import { type Config } from '@dxos/config';
|
|
|
6
6
|
import { Context } from '@dxos/context';
|
|
7
7
|
import { createCredentialSignerWithChain, CredentialGenerator } from '@dxos/credentials';
|
|
8
8
|
import { failUndefined } from '@dxos/debug';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
MetadataStore,
|
|
12
|
-
type LevelDB,
|
|
13
|
-
SnapshotStore,
|
|
14
|
-
SpaceManager,
|
|
15
|
-
valueEncoding,
|
|
16
|
-
} from '@dxos/echo-pipeline';
|
|
17
|
-
import { createTestLevel } from '@dxos/echo-pipeline/testing';
|
|
9
|
+
import { EchoHost } from '@dxos/echo-db';
|
|
10
|
+
import { MetadataStore, SnapshotStore, SpaceManager, valueEncoding } from '@dxos/echo-pipeline';
|
|
18
11
|
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
19
12
|
import { Keyring } from '@dxos/keyring';
|
|
13
|
+
import { type LevelDB } from '@dxos/kv-store';
|
|
14
|
+
import { createTestLevel } from '@dxos/kv-store/testing';
|
|
20
15
|
import { MemorySignalManager, MemorySignalManagerContext } from '@dxos/messaging';
|
|
21
16
|
import { MemoryTransportFactory, NetworkManager } from '@dxos/network-manager';
|
|
22
17
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
@@ -54,7 +49,9 @@ export const createServiceContext = async ({
|
|
|
54
49
|
const level = createTestLevel();
|
|
55
50
|
await level.open();
|
|
56
51
|
|
|
57
|
-
return new ServiceContext(storage, level, networkManager, signalManager
|
|
52
|
+
return new ServiceContext(storage, level, networkManager, signalManager, {
|
|
53
|
+
invitationConnectionDefaultParams: { controlHeartbeatInterval: 200 },
|
|
54
|
+
});
|
|
58
55
|
};
|
|
59
56
|
|
|
60
57
|
export const createPeers = async (numPeers: number) => {
|
|
@@ -105,7 +102,7 @@ export type TestPeerProps = {
|
|
|
105
102
|
snapshotStore?: SnapshotStore;
|
|
106
103
|
signingContext?: SigningContext;
|
|
107
104
|
blobStore?: BlobStore;
|
|
108
|
-
|
|
105
|
+
echoHost?: EchoHost;
|
|
109
106
|
invitationsManager?: InvitationsManager;
|
|
110
107
|
};
|
|
111
108
|
|
|
@@ -178,9 +175,10 @@ export class TestPeer {
|
|
|
178
175
|
return this._props.signingContext ?? failUndefined();
|
|
179
176
|
}
|
|
180
177
|
|
|
181
|
-
get
|
|
182
|
-
return (this._props.
|
|
183
|
-
|
|
178
|
+
get echoHost() {
|
|
179
|
+
return (this._props.echoHost ??= new EchoHost({
|
|
180
|
+
kv: this.level,
|
|
181
|
+
storage: this.storage,
|
|
184
182
|
}));
|
|
185
183
|
}
|
|
186
184
|
|
|
@@ -191,7 +189,7 @@ export class TestPeer {
|
|
|
191
189
|
this.keyring,
|
|
192
190
|
this.identity,
|
|
193
191
|
this.feedStore,
|
|
194
|
-
this.
|
|
192
|
+
this.echoHost,
|
|
195
193
|
this.invitationsManager,
|
|
196
194
|
));
|
|
197
195
|
}
|
|
@@ -6,7 +6,12 @@ import { Event } from '@dxos/async';
|
|
|
6
6
|
import { appServiceBundle, type AppServiceBundle, type ShellRuntime, shellServiceBundle } from '@dxos/client-protocol';
|
|
7
7
|
import { invariant } from '@dxos/invariant';
|
|
8
8
|
import { type PublicKey } from '@dxos/keys';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
type AppContextRequest,
|
|
11
|
+
type LayoutRequest,
|
|
12
|
+
ShellLayout,
|
|
13
|
+
type InvitationUrlRequest,
|
|
14
|
+
} from '@dxos/protocols/proto/dxos/iframe';
|
|
10
15
|
import { createProtoRpcPeer, type ProtoRpcPeer, type RpcPort } from '@dxos/rpc';
|
|
11
16
|
|
|
12
17
|
/**
|
|
@@ -14,11 +19,19 @@ import { createProtoRpcPeer, type ProtoRpcPeer, type RpcPort } from '@dxos/rpc';
|
|
|
14
19
|
*/
|
|
15
20
|
export class ShellRuntimeImpl implements ShellRuntime {
|
|
16
21
|
readonly layoutUpdate = new Event<LayoutRequest>();
|
|
22
|
+
readonly invitationUrlUpdate = new Event<InvitationUrlRequest>();
|
|
23
|
+
|
|
17
24
|
private _appRpc?: ProtoRpcPeer<AppServiceBundle>;
|
|
18
25
|
private _layout = ShellLayout.DEFAULT;
|
|
19
|
-
private _invitationCode?: string;
|
|
20
26
|
private _spaceKey?: PublicKey;
|
|
21
27
|
|
|
28
|
+
private _invitationCode?: string;
|
|
29
|
+
private _invitationUrl? = typeof window !== 'undefined' ? window.location.origin : undefined;
|
|
30
|
+
|
|
31
|
+
// TODO(burdon): Change to using underscores (coordinate with @dxos/web-auth).
|
|
32
|
+
private _deviceInvitationParam = 'deviceInvitationCode'; // TODO(burdon): device_invitation_code
|
|
33
|
+
private _spaceInvitationParam = 'spaceInvitationCode'; // TODO(burdon): space_invitation_code
|
|
34
|
+
|
|
22
35
|
constructor(private readonly _port: RpcPort) {}
|
|
23
36
|
|
|
24
37
|
get layout() {
|
|
@@ -33,6 +46,18 @@ export class ShellRuntimeImpl implements ShellRuntime {
|
|
|
33
46
|
return this._spaceKey;
|
|
34
47
|
}
|
|
35
48
|
|
|
49
|
+
get invitationUrl() {
|
|
50
|
+
return this._invitationUrl!;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
get deviceInvitationParam() {
|
|
54
|
+
return this._deviceInvitationParam;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get spaceInvitationParam() {
|
|
58
|
+
return this._spaceInvitationParam;
|
|
59
|
+
}
|
|
60
|
+
|
|
36
61
|
setLayout({ layout, invitationCode, spaceKey }: LayoutRequest) {
|
|
37
62
|
this._layout = layout;
|
|
38
63
|
this._invitationCode = invitationCode;
|
|
@@ -40,6 +65,13 @@ export class ShellRuntimeImpl implements ShellRuntime {
|
|
|
40
65
|
this.layoutUpdate.emit({ layout, invitationCode, spaceKey });
|
|
41
66
|
}
|
|
42
67
|
|
|
68
|
+
setInvitationUrl({ invitationUrl, deviceInvitationParam, spaceInvitationParam }: InvitationUrlRequest) {
|
|
69
|
+
this._invitationUrl = invitationUrl;
|
|
70
|
+
this._deviceInvitationParam = deviceInvitationParam;
|
|
71
|
+
this._spaceInvitationParam = spaceInvitationParam;
|
|
72
|
+
this.invitationUrlUpdate.emit({ invitationUrl, deviceInvitationParam, spaceInvitationParam });
|
|
73
|
+
}
|
|
74
|
+
|
|
43
75
|
async setAppContext(context: AppContextRequest) {
|
|
44
76
|
invariant(this._appRpc, 'runtime not open');
|
|
45
77
|
|
|
@@ -58,6 +90,12 @@ export class ShellRuntimeImpl implements ShellRuntime {
|
|
|
58
90
|
this._spaceKey = request.spaceKey;
|
|
59
91
|
this.layoutUpdate.emit(request);
|
|
60
92
|
},
|
|
93
|
+
setInvitationUrl: async (request) => {
|
|
94
|
+
this._invitationUrl = request.invitationUrl;
|
|
95
|
+
this._deviceInvitationParam = request.deviceInvitationParam;
|
|
96
|
+
this._spaceInvitationParam = request.spaceInvitationParam;
|
|
97
|
+
this.invitationUrlUpdate.emit(request);
|
|
98
|
+
},
|
|
61
99
|
},
|
|
62
100
|
},
|
|
63
101
|
port: this._port,
|
|
@@ -120,7 +120,9 @@ export class WorkerRuntime {
|
|
|
120
120
|
this._sessions.delete(session);
|
|
121
121
|
if (this._sessions.size === 0) {
|
|
122
122
|
// Terminate the worker when all sessions are closed.
|
|
123
|
-
self
|
|
123
|
+
if (globalThis.self) {
|
|
124
|
+
self.close();
|
|
125
|
+
}
|
|
124
126
|
} else {
|
|
125
127
|
this._reconnectWebrtc();
|
|
126
128
|
}
|
package/src/version.ts
CHANGED