@dxos/client-services 0.5.1-main.ef0d69d → 0.5.1-main.f81ddc4
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-KGHYHY4Q.mjs → chunk-OE6XNPWD.mjs} +1296 -940
- package/dist/lib/browser/chunk-OE6XNPWD.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/testing/index.mjs +29 -9
- package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-4WE4TH57.cjs → chunk-PQ6V45LX.cjs} +1459 -1111
- package/dist/lib/node/chunk-PQ6V45LX.cjs.map +7 -0
- package/dist/lib/node/index.cjs +43 -43
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/packlets/testing/index.cjs +35 -15
- package/dist/lib/node/packlets/testing/index.cjs.map +3 -3
- 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 +8 -5
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.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 +2 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/package.json +36 -35
- 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 +42 -3
- package/src/packlets/invitations/space-invitation-protocol.ts +19 -1
- package/src/packlets/invitations/utils.ts +27 -0
- package/src/packlets/services/automerge-host.test.ts +3 -1
- package/src/packlets/services/service-context.ts +7 -6
- package/src/packlets/services/service-host.ts +3 -4
- package/src/packlets/spaces/data-space.ts +2 -1
- package/src/packlets/storage/level.ts +2 -2
- package/src/packlets/testing/invitation-utils.ts +23 -3
- package/src/packlets/testing/test-builder.ts +6 -3
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-KGHYHY4Q.mjs.map +0 -7
- package/dist/lib/node/chunk-4WE4TH57.cjs.map +0 -7
- package/dist/types/src/packlets/invitations/invitation-extension.d.ts.map +0 -1
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
createAdmissionCredentials,
|
|
7
|
+
createCancelDelegatedSpaceInvitationCredential,
|
|
7
8
|
createDelegatedSpaceInvitationCredential,
|
|
8
9
|
getCredentialAssertion,
|
|
9
10
|
} from '@dxos/credentials';
|
|
@@ -87,7 +88,7 @@ export class SpaceInvitationProtocol implements InvitationProtocol {
|
|
|
87
88
|
|
|
88
89
|
async delegate(invitation: Invitation): Promise<PublicKey> {
|
|
89
90
|
invariant(this._spaceKey);
|
|
90
|
-
const space =
|
|
91
|
+
const space = this._spaceManager.spaces.get(this._spaceKey);
|
|
91
92
|
invariant(space);
|
|
92
93
|
if (invitation.authMethod === Invitation.AuthMethod.KNOWN_PUBLIC_KEY) {
|
|
93
94
|
invariant(invitation.guestKeypair?.publicKey);
|
|
@@ -118,6 +119,23 @@ export class SpaceInvitationProtocol implements InvitationProtocol {
|
|
|
118
119
|
return credential.credential.credential.id!;
|
|
119
120
|
}
|
|
120
121
|
|
|
122
|
+
async cancelDelegation(invitation: Invitation): Promise<void> {
|
|
123
|
+
invariant(this._spaceKey);
|
|
124
|
+
invariant(invitation.type === Invitation.Type.DELEGATED && invitation.delegationCredentialId);
|
|
125
|
+
const space = this._spaceManager.spaces.get(this._spaceKey);
|
|
126
|
+
invariant(space);
|
|
127
|
+
|
|
128
|
+
log('cancelling delegated space invitation', { host: this._signingContext.deviceKey, id: invitation.invitationId });
|
|
129
|
+
const credential = await createCancelDelegatedSpaceInvitationCredential(
|
|
130
|
+
this._signingContext.credentialSigner,
|
|
131
|
+
space.key,
|
|
132
|
+
invitation.delegationCredentialId,
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
invariant(credential.credential);
|
|
136
|
+
await writeMessages(space.inner.controlPipeline.writer, [credential]);
|
|
137
|
+
}
|
|
138
|
+
|
|
121
139
|
checkInvitation(invitation: Partial<Invitation>) {
|
|
122
140
|
if (invitation.spaceKey && this._spaceManager.spaces.has(invitation.spaceKey)) {
|
|
123
141
|
return new AlreadyJoinedError('Already joined space.');
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Mutex, type MutexGuard } from '@dxos/async';
|
|
6
|
+
import { cancelWithContext, type Context, ContextDisposedError } from '@dxos/context';
|
|
7
|
+
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
8
|
+
|
|
9
|
+
export const stateToString = (state: Invitation.State): string => {
|
|
10
|
+
return Object.entries(Invitation.State).find(([key, val]) => val === state)?.[0] ?? 'unknown';
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const tryAcquireBeforeContextDisposed = async (ctx: Context, mutex: Mutex): Promise<MutexGuard> => {
|
|
14
|
+
let guard: MutexGuard | undefined;
|
|
15
|
+
return cancelWithContext(
|
|
16
|
+
ctx,
|
|
17
|
+
(async () => {
|
|
18
|
+
guard = await mutex.acquire();
|
|
19
|
+
if (ctx.disposed) {
|
|
20
|
+
guard.release();
|
|
21
|
+
guard = undefined;
|
|
22
|
+
throw new ContextDisposedError();
|
|
23
|
+
}
|
|
24
|
+
return guard;
|
|
25
|
+
})(),
|
|
26
|
+
);
|
|
27
|
+
};
|
|
@@ -8,7 +8,8 @@ import { asyncTimeout } from '@dxos/async';
|
|
|
8
8
|
import { getHeads } from '@dxos/automerge/automerge';
|
|
9
9
|
import { AutomergeContext } from '@dxos/echo-db';
|
|
10
10
|
import { AutomergeHost, DataServiceImpl } from '@dxos/echo-pipeline';
|
|
11
|
-
import {
|
|
11
|
+
import { IndexMetadataStore } from '@dxos/indexing';
|
|
12
|
+
import { createTestLevel } from '@dxos/kv-store/testing';
|
|
12
13
|
import { afterTest, describe, test } from '@dxos/test';
|
|
13
14
|
|
|
14
15
|
describe('AutomergeHost', () => {
|
|
@@ -26,6 +27,7 @@ describe('AutomergeHost', () => {
|
|
|
26
27
|
|
|
27
28
|
const host = new AutomergeHost({
|
|
28
29
|
db: level.sublevel('automerge'),
|
|
30
|
+
indexMetadataStore: new IndexMetadataStore({ db: level.sublevel('index-metadata') }),
|
|
29
31
|
});
|
|
30
32
|
await host.open();
|
|
31
33
|
afterTest(() => host.close());
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type Level } from 'level';
|
|
6
|
-
|
|
7
5
|
import { Trigger } from '@dxos/async';
|
|
8
6
|
import { Context, Resource } from '@dxos/context';
|
|
9
7
|
import { getCredentialAssertion, type CredentialProcessor } from '@dxos/credentials';
|
|
@@ -14,6 +12,7 @@ import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
|
14
12
|
import { invariant } from '@dxos/invariant';
|
|
15
13
|
import { Keyring } from '@dxos/keyring';
|
|
16
14
|
import { PublicKey } from '@dxos/keys';
|
|
15
|
+
import { type LevelDB } from '@dxos/kv-store';
|
|
17
16
|
import { log } from '@dxos/log';
|
|
18
17
|
import { type SignalManager } from '@dxos/messaging';
|
|
19
18
|
import { type NetworkManager } from '@dxos/network-manager';
|
|
@@ -22,6 +21,7 @@ import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
|
22
21
|
import type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
23
22
|
import { type Credential, type ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
24
23
|
import { type Storage } from '@dxos/random-access-storage';
|
|
24
|
+
import type { TeleportParams } from '@dxos/teleport';
|
|
25
25
|
import { BlobStore } from '@dxos/teleport-extension-object-sync';
|
|
26
26
|
import { trace as Trace } from '@dxos/tracing';
|
|
27
27
|
import { safeInstanceof } from '@dxos/util';
|
|
@@ -41,7 +41,8 @@ import {
|
|
|
41
41
|
import { InvitationsManager } from '../invitations/invitations-manager';
|
|
42
42
|
import { DataSpaceManager, type DataSpaceManagerRuntimeParams, type SigningContext } from '../spaces';
|
|
43
43
|
|
|
44
|
-
export type ServiceContextRuntimeParams = IdentityManagerRuntimeParams &
|
|
44
|
+
export type ServiceContextRuntimeParams = IdentityManagerRuntimeParams &
|
|
45
|
+
DataSpaceManagerRuntimeParams & { invitationConnectionDefaultParams?: Partial<TeleportParams> };
|
|
45
46
|
/**
|
|
46
47
|
* Shared backend for all client services.
|
|
47
48
|
*/
|
|
@@ -79,10 +80,10 @@ export class ServiceContext extends Resource {
|
|
|
79
80
|
|
|
80
81
|
constructor(
|
|
81
82
|
public readonly storage: Storage,
|
|
82
|
-
public readonly level:
|
|
83
|
+
public readonly level: LevelDB,
|
|
83
84
|
public readonly networkManager: NetworkManager,
|
|
84
85
|
public readonly signalManager: SignalManager,
|
|
85
|
-
public readonly _runtimeParams?:
|
|
86
|
+
public readonly _runtimeParams?: ServiceContextRuntimeParams,
|
|
86
87
|
) {
|
|
87
88
|
super();
|
|
88
89
|
|
|
@@ -124,7 +125,7 @@ export class ServiceContext extends Resource {
|
|
|
124
125
|
storage: this.storage,
|
|
125
126
|
});
|
|
126
127
|
|
|
127
|
-
this.invitations = new InvitationsHandler(this.networkManager);
|
|
128
|
+
this.invitations = new InvitationsHandler(this.networkManager, _runtimeParams?.invitationConnectionDefaultParams);
|
|
128
129
|
this.invitationsManager = new InvitationsManager(
|
|
129
130
|
this.invitations,
|
|
130
131
|
(invitation) => this.getInvitationHandler(invitation),
|
|
@@ -2,16 +2,15 @@
|
|
|
2
2
|
// Copyright 2021 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type Level } from 'level';
|
|
6
|
-
|
|
7
5
|
import { Event, synchronized } from '@dxos/async';
|
|
8
6
|
import { clientServiceBundle, defaultKey, type ClientServices, Properties } from '@dxos/client-protocol';
|
|
9
7
|
import { type Config } from '@dxos/config';
|
|
10
8
|
import { Context } from '@dxos/context';
|
|
11
|
-
import { type ObjectStructure, encodeReference, type SpaceDoc
|
|
9
|
+
import { type ObjectStructure, encodeReference, type SpaceDoc } from '@dxos/echo-protocol';
|
|
12
10
|
import { getTypeReference } from '@dxos/echo-schema';
|
|
13
11
|
import { invariant } from '@dxos/invariant';
|
|
14
12
|
import { PublicKey } from '@dxos/keys';
|
|
13
|
+
import { type LevelDB } from '@dxos/kv-store';
|
|
15
14
|
import { log } from '@dxos/log';
|
|
16
15
|
import { WebsocketSignalManager, type SignalManager } from '@dxos/messaging';
|
|
17
16
|
import { NetworkManager, createSimplePeerTransportFactory, type TransportFactory } from '@dxos/network-manager';
|
|
@@ -82,7 +81,7 @@ export class ClientServicesHost {
|
|
|
82
81
|
private _signalManager?: SignalManager;
|
|
83
82
|
private _networkManager?: NetworkManager;
|
|
84
83
|
private _storage?: Storage;
|
|
85
|
-
private _level?:
|
|
84
|
+
private _level?: LevelDB;
|
|
86
85
|
private _callbacks?: ClientServicesHostCallbacks;
|
|
87
86
|
private _devtoolsProxy?: WebsocketRpcClient<{}, ClientServices>;
|
|
88
87
|
|
|
@@ -7,8 +7,9 @@ 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
9
|
import { type EchoHost } from '@dxos/echo-db';
|
|
10
|
-
import { type MetadataStore, type Space, createMappedFeedWriter
|
|
10
|
+
import { type MetadataStore, type Space, createMappedFeedWriter } from '@dxos/echo-pipeline';
|
|
11
11
|
import { AutomergeDocumentLoaderImpl } from '@dxos/echo-pipeline';
|
|
12
|
+
import { type SpaceDoc } from '@dxos/echo-protocol';
|
|
12
13
|
import { TYPE_PROPERTIES } from '@dxos/echo-schema';
|
|
13
14
|
import { type FeedStore } from '@dxos/feed-store';
|
|
14
15
|
import { failedInvariant, invariant } from '@dxos/invariant';
|
|
@@ -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,7 @@ 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
17
|
// TODO(dmaretskyi): This function shouldn't call open - .
|
|
18
18
|
await level.open();
|
|
19
19
|
return level;
|
|
@@ -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);
|
|
@@ -7,10 +7,11 @@ import { Context } from '@dxos/context';
|
|
|
7
7
|
import { createCredentialSignerWithChain, CredentialGenerator } from '@dxos/credentials';
|
|
8
8
|
import { failUndefined } from '@dxos/debug';
|
|
9
9
|
import { EchoHost } from '@dxos/echo-db';
|
|
10
|
-
import { MetadataStore,
|
|
11
|
-
import { createTestLevel } from '@dxos/echo-pipeline/testing';
|
|
10
|
+
import { MetadataStore, SnapshotStore, SpaceManager, valueEncoding } from '@dxos/echo-pipeline';
|
|
12
11
|
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
13
12
|
import { Keyring } from '@dxos/keyring';
|
|
13
|
+
import { type LevelDB } from '@dxos/kv-store';
|
|
14
|
+
import { createTestLevel } from '@dxos/kv-store/testing';
|
|
14
15
|
import { MemorySignalManager, MemorySignalManagerContext } from '@dxos/messaging';
|
|
15
16
|
import { MemoryTransportFactory, NetworkManager } from '@dxos/network-manager';
|
|
16
17
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
@@ -48,7 +49,9 @@ export const createServiceContext = async ({
|
|
|
48
49
|
const level = createTestLevel();
|
|
49
50
|
await level.open();
|
|
50
51
|
|
|
51
|
-
return new ServiceContext(storage, level, networkManager, signalManager
|
|
52
|
+
return new ServiceContext(storage, level, networkManager, signalManager, {
|
|
53
|
+
invitationConnectionDefaultParams: { controlHeartbeatInterval: 200 },
|
|
54
|
+
});
|
|
52
55
|
};
|
|
53
56
|
|
|
54
57
|
export const createPeers = async (numPeers: number) => {
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const DXOS_VERSION = "0.5.1-main.
|
|
1
|
+
export const DXOS_VERSION = "0.5.1-main.f81ddc4";
|