@dxos/client-services 0.1.35 → 0.1.36
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-H5IXSSI7.mjs → chunk-2AYYVPWN.mjs} +835 -950
- package/dist/lib/browser/chunk-2AYYVPWN.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +9 -11
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/testing/index.mjs +212 -74
- package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
- package/dist/lib/node/index.cjs +942 -1058
- 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 +1089 -1067
- package/dist/lib/node/packlets/testing/index.cjs.map +4 -4
- package/dist/types/src/packlets/identity/identity-manager.d.ts +1 -0
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +3 -3
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +18 -0
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/device-invitation-protocol.test.d.ts +2 -0
- package/dist/types/src/packlets/invitations/device-invitation-protocol.test.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/index.d.ts +4 -4
- package/dist/types/src/packlets/invitations/index.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +12 -0
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +38 -0
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/invitations-service.d.ts +13 -15
- package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +22 -0
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/space-invitation-protocol.test.d.ts +2 -0
- package/dist/types/src/packlets/invitations/space-invitation-protocol.test.d.ts.map +1 -0
- package/dist/types/src/packlets/services/service-context.d.ts +6 -4
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +2 -0
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts +31 -2
- package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts +3 -3
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/tests/invitations.test.d.ts +2 -0
- package/dist/types/src/packlets/tests/invitations.test.d.ts.map +1 -0
- package/dist/types/src/packlets/vault/worker-runtime.d.ts +2 -0
- package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
- package/package.json +30 -30
- package/src/packlets/identity/identity-manager.ts +2 -1
- package/src/packlets/identity/identity.ts +3 -3
- package/src/packlets/invitations/{device-invitations-handler.test.ts → device-invitation-protocol.test.ts} +3 -3
- package/src/packlets/invitations/device-invitation-protocol.ts +83 -0
- package/src/packlets/invitations/index.ts +4 -4
- package/src/packlets/invitations/invitation-protocol.ts +21 -0
- package/src/packlets/invitations/invitations-handler.ts +462 -0
- package/src/packlets/invitations/invitations-service.ts +127 -104
- package/src/packlets/invitations/space-invitation-protocol.test.ts +221 -0
- package/src/packlets/invitations/space-invitation-protocol.ts +117 -0
- package/src/packlets/services/service-context.test.ts +11 -4
- package/src/packlets/services/service-context.ts +40 -19
- package/src/packlets/services/service-host.ts +4 -12
- package/src/packlets/services/service-registry.test.ts +23 -25
- package/src/packlets/spaces/data-space-manager.ts +5 -0
- package/src/packlets/spaces/spaces-service.ts +7 -2
- package/src/packlets/storage/storage.ts +2 -0
- package/src/packlets/testing/invitation-utils.ts +219 -31
- package/src/packlets/testing/test-builder.ts +33 -22
- package/src/packlets/tests/client-services.test.ts +33 -76
- package/src/packlets/tests/halo-profile.test.ts +2 -28
- package/src/packlets/tests/invitations.test.ts +389 -0
- package/src/packlets/tests/spaces-invitations.test.ts +12 -30
- package/src/packlets/tests/spaces.test.ts +30 -28
- package/src/packlets/vault/worker-runtime.ts +4 -0
- package/dist/lib/browser/chunk-H5IXSSI7.mjs.map +0 -7
- package/dist/types/src/packlets/invitations/device-invitations-handler.d.ts +0 -30
- package/dist/types/src/packlets/invitations/device-invitations-handler.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/device-invitations-handler.test.d.ts +0 -2
- package/dist/types/src/packlets/invitations/device-invitations-handler.test.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/device-invitations-service.d.ts +0 -13
- package/dist/types/src/packlets/invitations/device-invitations-service.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/device-invitations-service.test.d.ts +0 -2
- package/dist/types/src/packlets/invitations/device-invitations-service.test.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts +0 -26
- package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/space-invitations-handler.test.d.ts +0 -2
- package/dist/types/src/packlets/invitations/space-invitations-handler.test.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/space-invitations-service.d.ts +0 -16
- package/dist/types/src/packlets/invitations/space-invitations-service.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/space-invitations-service.test.d.ts +0 -2
- package/dist/types/src/packlets/invitations/space-invitations-service.test.d.ts.map +0 -1
- package/src/packlets/invitations/device-invitations-handler.ts +0 -370
- package/src/packlets/invitations/device-invitations-service.test.ts +0 -96
- package/src/packlets/invitations/device-invitations-service.ts +0 -24
- package/src/packlets/invitations/space-invitations-handler.test.ts +0 -246
- package/src/packlets/invitations/space-invitations-handler.ts +0 -463
- package/src/packlets/invitations/space-invitations-service.test.ts +0 -129
- package/src/packlets/invitations/space-invitations-service.ts +0 -35
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2022 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { expect } from 'chai';
|
|
6
|
-
import assert from 'node:assert';
|
|
7
|
-
|
|
8
|
-
import { asyncChain, latch, Trigger } from '@dxos/async';
|
|
9
|
-
import { raise } from '@dxos/debug';
|
|
10
|
-
import { testLocalDatabase } from '@dxos/echo-pipeline/testing';
|
|
11
|
-
import { PublicKey } from '@dxos/keys';
|
|
12
|
-
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
13
|
-
import { afterTest, describe, test } from '@dxos/test';
|
|
14
|
-
import { range } from '@dxos/util';
|
|
15
|
-
|
|
16
|
-
import { ServiceContext } from '../services';
|
|
17
|
-
import { createIdentity, createPeers, syncItemsLocal } from '../testing';
|
|
18
|
-
import { performInvitation } from '../testing/invitation-utils';
|
|
19
|
-
|
|
20
|
-
const closeAfterTest = async (peer: ServiceContext) => {
|
|
21
|
-
afterTest(() => peer.close());
|
|
22
|
-
return peer;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
describe('services/space-invitations-handler', () => {
|
|
26
|
-
test('genesis', async () => {
|
|
27
|
-
const [peer] = await asyncChain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(1));
|
|
28
|
-
|
|
29
|
-
const space = await peer.dataSpaceManager!.createSpace();
|
|
30
|
-
expect(peer.dataSpaceManager!.spaces.has(space.key)).to.be.true;
|
|
31
|
-
|
|
32
|
-
await space.close();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test('genesis & ready', async () => {
|
|
36
|
-
const [peer] = await asyncChain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(1));
|
|
37
|
-
|
|
38
|
-
const space = await peer.dataSpaceManager!.createSpace();
|
|
39
|
-
expect(peer.dataSpaceManager!.spaces.has(space.key)).to.be.true;
|
|
40
|
-
|
|
41
|
-
await peer.dataSpaceManager?.waitUntilSpaceReady(space.key);
|
|
42
|
-
await space.close();
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
test('genesis with database mutations', async () => {
|
|
46
|
-
const [peer] = await asyncChain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(1));
|
|
47
|
-
const space = await peer.dataSpaceManager!.createSpace();
|
|
48
|
-
afterTest(() => space.close());
|
|
49
|
-
|
|
50
|
-
await testLocalDatabase(space.dataPipeline);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
test('invitation with no auth', async () => {
|
|
54
|
-
const [host, guest] = await asyncChain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(2));
|
|
55
|
-
|
|
56
|
-
const space1 = await host.dataSpaceManager!.createSpace();
|
|
57
|
-
const spaceKey = space1.key;
|
|
58
|
-
|
|
59
|
-
await performInvitation(host.spaceInvitations!, guest.spaceInvitations!, space1);
|
|
60
|
-
|
|
61
|
-
{
|
|
62
|
-
const space1 = host.dataSpaceManager!.spaces.get(spaceKey)!;
|
|
63
|
-
const space2 = guest.dataSpaceManager!.spaces.get(spaceKey)!;
|
|
64
|
-
expect(space1).not.to.be.undefined;
|
|
65
|
-
expect(space2).not.to.be.undefined;
|
|
66
|
-
|
|
67
|
-
await host.dataSpaceManager?.waitUntilSpaceReady(space1.key);
|
|
68
|
-
await guest.dataSpaceManager?.waitUntilSpaceReady(space2.key);
|
|
69
|
-
|
|
70
|
-
await syncItemsLocal(space1.dataPipeline, space2.dataPipeline);
|
|
71
|
-
|
|
72
|
-
await space1.close();
|
|
73
|
-
await space2.close();
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
test('creates and accepts invitation with retry', async () => {
|
|
78
|
-
const [host, guest] = await asyncChain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(2));
|
|
79
|
-
|
|
80
|
-
const complete1 = new Trigger<PublicKey>();
|
|
81
|
-
const complete2 = new Trigger<PublicKey>();
|
|
82
|
-
|
|
83
|
-
let attempt = 0;
|
|
84
|
-
const authenticationCode = new Trigger<string>();
|
|
85
|
-
|
|
86
|
-
const space1 = await host.dataSpaceManager!.createSpace();
|
|
87
|
-
const observable1 = host.spaceInvitations!.createInvitation(space1);
|
|
88
|
-
observable1.subscribe({
|
|
89
|
-
onConnecting: async (invitation1: Invitation) => {
|
|
90
|
-
const observable2 = guest.spaceInvitations!.acceptInvitation(invitation1);
|
|
91
|
-
observable2.subscribe({
|
|
92
|
-
onConnecting: async () => {},
|
|
93
|
-
onConnected: async (invitation2: Invitation) => {
|
|
94
|
-
expect(invitation1.swarmKey).to.eq(invitation2.swarmKey);
|
|
95
|
-
},
|
|
96
|
-
onAuthenticating: async () => {
|
|
97
|
-
if (attempt++ === 0) {
|
|
98
|
-
// Force retry.
|
|
99
|
-
await observable2.authenticate('000000');
|
|
100
|
-
} else {
|
|
101
|
-
await observable2.authenticate(await authenticationCode.wait());
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
|
-
onSuccess: (invitation: Invitation) => {
|
|
105
|
-
complete2.wake(invitation.spaceKey!);
|
|
106
|
-
},
|
|
107
|
-
onCancelled: () => raise(new Error()),
|
|
108
|
-
onTimeout: (err: Error) => raise(err),
|
|
109
|
-
onError: (err: Error) => raise(err)
|
|
110
|
-
});
|
|
111
|
-
},
|
|
112
|
-
onConnected: (invitation: Invitation) => {
|
|
113
|
-
assert(invitation.authenticationCode);
|
|
114
|
-
authenticationCode.wake(invitation.authenticationCode);
|
|
115
|
-
},
|
|
116
|
-
onSuccess: (invitation: Invitation) => {
|
|
117
|
-
complete1.wake(invitation.spaceKey!);
|
|
118
|
-
},
|
|
119
|
-
onCancelled: () => raise(new Error()),
|
|
120
|
-
onTimeout: (err: Error) => raise(err),
|
|
121
|
-
onError: (err: Error) => raise(err)
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
const [spaceKey1, spaceKey2] = await Promise.all([complete1.wait(), complete2.wait()]);
|
|
125
|
-
expect(spaceKey1).to.deep.eq(spaceKey2);
|
|
126
|
-
|
|
127
|
-
{
|
|
128
|
-
const space1 = host.dataSpaceManager!.spaces.get(spaceKey1)!;
|
|
129
|
-
const space2 = guest.dataSpaceManager!.spaces.get(spaceKey2)!;
|
|
130
|
-
expect(space1).not.to.be.undefined;
|
|
131
|
-
expect(space2).not.to.be.undefined;
|
|
132
|
-
|
|
133
|
-
await host.dataSpaceManager?.waitUntilSpaceReady(space1.key);
|
|
134
|
-
await guest.dataSpaceManager?.waitUntilSpaceReady(space2.key);
|
|
135
|
-
|
|
136
|
-
await syncItemsLocal(space1.dataPipeline, space2.dataPipeline);
|
|
137
|
-
|
|
138
|
-
await space1.close();
|
|
139
|
-
await space2.close();
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
expect(
|
|
143
|
-
guest.identityManager.identity?.space.spaceState.getCredentialsOfType('dxos.halo.credentials.SpaceMember').length
|
|
144
|
-
).to.equal(2); // own halo + newly joined space.
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
test('cancels invitation', async () => {
|
|
148
|
-
const [host, guest] = await asyncChain<ServiceContext>([createIdentity, closeAfterTest])(createPeers(2));
|
|
149
|
-
|
|
150
|
-
const cancelled = new Trigger();
|
|
151
|
-
const connecting1 = new Trigger<Invitation>(); // peer 1 connected.
|
|
152
|
-
const connecting2 = new Trigger<Invitation>(); // peer 2 connected.
|
|
153
|
-
|
|
154
|
-
const space1 = await host.dataSpaceManager!.createSpace();
|
|
155
|
-
const observable1 = await host.spaceInvitations!.createInvitation(space1);
|
|
156
|
-
observable1.subscribe({
|
|
157
|
-
onConnecting: async (invitation1: Invitation) => {
|
|
158
|
-
connecting1.wake(invitation1);
|
|
159
|
-
|
|
160
|
-
const observable2 = await guest.spaceInvitations!.acceptInvitation(invitation1);
|
|
161
|
-
observable2.subscribe({
|
|
162
|
-
onConnecting: async (invitation2: Invitation) => {
|
|
163
|
-
expect(invitation1.swarmKey).to.eq(invitation2.swarmKey);
|
|
164
|
-
connecting2.wake(invitation2);
|
|
165
|
-
},
|
|
166
|
-
onConnected: async (invitation2: Invitation) => {},
|
|
167
|
-
onSuccess: () => {},
|
|
168
|
-
onCancelled: () => raise(new Error()),
|
|
169
|
-
onTimeout: (err: Error) => raise(err),
|
|
170
|
-
onError: (err: Error) => raise(err)
|
|
171
|
-
});
|
|
172
|
-
},
|
|
173
|
-
onConnected: async (invitation1: Invitation) => {},
|
|
174
|
-
onCancelled: () => {
|
|
175
|
-
cancelled.wake();
|
|
176
|
-
},
|
|
177
|
-
onSuccess: () => raise(new Error()),
|
|
178
|
-
onTimeout: (err: Error) => raise(err),
|
|
179
|
-
onError: (err: Error) => raise(err)
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
const invitation1 = await connecting1.wait();
|
|
183
|
-
const invitation2 = await connecting2.wait();
|
|
184
|
-
expect(invitation1.swarmKey).to.eq(invitation2.swarmKey); // TODO(burdon): Normalize to use to.deep.eq.
|
|
185
|
-
|
|
186
|
-
// TODO(burdon): Simulate network latency.
|
|
187
|
-
setTimeout(async () => {
|
|
188
|
-
await observable1.cancel();
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
await cancelled.wait();
|
|
192
|
-
await space1.close();
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
// TODO(burdon): Flaky.
|
|
196
|
-
test.skip('test multi-use invitation', async () => {
|
|
197
|
-
const GUEST_COUNT = 3;
|
|
198
|
-
const [host, ...guests] = await asyncChain<ServiceContext>([createIdentity, closeAfterTest])(
|
|
199
|
-
createPeers(GUEST_COUNT + 1)
|
|
200
|
-
);
|
|
201
|
-
|
|
202
|
-
const hostSpace = await host.dataSpaceManager!.createSpace();
|
|
203
|
-
const swarmKey = PublicKey.random();
|
|
204
|
-
const hostObservable = await host.spaceInvitations!.createInvitation(hostSpace, {
|
|
205
|
-
swarmKey,
|
|
206
|
-
type: Invitation.Type.MULTIUSE_TESTING
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
const [done, count] = latch({ count: GUEST_COUNT });
|
|
210
|
-
hostObservable.subscribe({
|
|
211
|
-
onConnecting: async (invitation2: Invitation) => {},
|
|
212
|
-
onConnected: async (invitation2: Invitation) => {},
|
|
213
|
-
onSuccess: () => {
|
|
214
|
-
count();
|
|
215
|
-
},
|
|
216
|
-
onCancelled: () => {},
|
|
217
|
-
onTimeout: (err: Error) => raise(err),
|
|
218
|
-
onError: (err: Error) => raise(err)
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
await Promise.all(
|
|
222
|
-
range(GUEST_COUNT).map(async (idx) => {
|
|
223
|
-
const observable = await guests[idx].spaceInvitations!.acceptInvitation({
|
|
224
|
-
swarmKey,
|
|
225
|
-
type: Invitation.Type.MULTIUSE_TESTING
|
|
226
|
-
});
|
|
227
|
-
const success = new Trigger();
|
|
228
|
-
observable.subscribe({
|
|
229
|
-
onConnecting: async (invitation2: Invitation) => {},
|
|
230
|
-
onConnected: async (invitation2: Invitation) => {},
|
|
231
|
-
onSuccess: () => {
|
|
232
|
-
success.wake();
|
|
233
|
-
},
|
|
234
|
-
onCancelled: () => raise(new Error()),
|
|
235
|
-
onTimeout: (err: Error) => raise(err),
|
|
236
|
-
onError: (err: Error) => raise(err)
|
|
237
|
-
});
|
|
238
|
-
await success.wait({ timeout: 300 });
|
|
239
|
-
})
|
|
240
|
-
);
|
|
241
|
-
await done();
|
|
242
|
-
|
|
243
|
-
await hostObservable.cancel();
|
|
244
|
-
await hostSpace.close();
|
|
245
|
-
});
|
|
246
|
-
});
|