@dxos/client-services 0.6.12-main.ed7cda7 → 0.6.12-staging.0b4bb48
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-VENIOUQ4.mjs → chunk-YCJNCCXZ.mjs} +5115 -5208
- package/dist/lib/browser/chunk-YCJNCCXZ.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +3 -3
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +5 -4
- package/dist/lib/browser/testing/index.mjs.map +2 -2
- package/dist/lib/node/{chunk-US3NPCS5.cjs → chunk-Z2ZTFILR.cjs} +4897 -4990
- package/dist/lib/node/chunk-Z2ZTFILR.cjs.map +7 -0
- package/dist/lib/node/index.cjs +46 -46
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +12 -11
- package/dist/lib/node/testing/index.cjs.map +2 -2
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/authenticator.test.d.ts +2 -0
- package/dist/types/src/packlets/identity/authenticator.test.d.ts.map +1 -0
- package/dist/types/src/packlets/identity/identity-manager.d.ts +7 -19
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +1 -7
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
- package/dist/types/src/packlets/services/automerge-host.test.d.ts +2 -0
- package/dist/types/src/packlets/services/automerge-host.test.d.ts.map +1 -0
- package/dist/types/src/packlets/services/service-context.d.ts +4 -3
- 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 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +2 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +0 -1
- 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/storage/storage.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/packlets/worker/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 +39 -43
- package/src/packlets/devices/devices-service.test.ts +5 -4
- package/src/packlets/diagnostics/diagnostics-broadcast.ts +0 -1
- package/src/packlets/identity/{authenticator.node.test.ts → authenticator.test.ts} +3 -2
- package/src/packlets/identity/identity-manager.test.ts +6 -5
- package/src/packlets/identity/identity-manager.ts +19 -35
- package/src/packlets/identity/identity-service.test.ts +8 -4
- package/src/packlets/identity/identity.test.ts +239 -128
- package/src/packlets/identity/identity.ts +8 -38
- package/src/packlets/invitations/device-invitation-protocol.test.ts +4 -7
- package/src/packlets/invitations/invitation-host-extension.ts +3 -0
- package/src/packlets/invitations/invitations-handler.test.ts +7 -14
- package/src/packlets/invitations/invitations-handler.ts +1 -1
- package/src/packlets/invitations/space-invitation-protocol.test.ts +3 -4
- package/src/packlets/logging/logging.test.ts +2 -1
- package/src/packlets/network/network-service.test.ts +3 -2
- package/src/packlets/services/automerge-host.test.ts +60 -0
- package/src/packlets/services/service-context.test.ts +1 -3
- package/src/packlets/services/service-context.ts +12 -24
- package/src/packlets/services/service-host.test.ts +12 -8
- package/src/packlets/services/service-host.ts +2 -2
- package/src/packlets/services/service-registry.test.ts +2 -1
- package/src/packlets/spaces/data-space-manager.test.ts +2 -2
- package/src/packlets/spaces/data-space-manager.ts +1 -4
- package/src/packlets/spaces/data-space.ts +2 -7
- package/src/packlets/spaces/edge-feed-replicator.ts +21 -59
- package/src/packlets/spaces/epoch-migrations.ts +2 -2
- package/src/packlets/spaces/notarization-plugin.test.ts +3 -2
- package/src/packlets/spaces/spaces-service.test.ts +9 -5
- package/src/packlets/storage/storage.ts +1 -0
- package/src/packlets/system/system-service.test.ts +2 -1
- package/src/packlets/testing/test-builder.ts +2 -1
- package/src/packlets/worker/worker-runtime.ts +2 -2
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-VENIOUQ4.mjs.map +0 -7
- package/dist/lib/node/chunk-US3NPCS5.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-LV7T6HCX.mjs +0 -7809
- package/dist/lib/node-esm/chunk-LV7T6HCX.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -416
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/testing/index.mjs +0 -418
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
- package/dist/types/src/packlets/identity/authenticator.node.test.d.ts +0 -2
- package/dist/types/src/packlets/identity/authenticator.node.test.d.ts.map +0 -1
- package/dist/types/src/packlets/spaces/edge-feed-replicator.test.d.ts +0 -2
- package/dist/types/src/packlets/spaces/edge-feed-replicator.test.d.ts.map +0 -1
- package/dist/types/src/testing/setup.d.ts +0 -3
- package/dist/types/src/testing/setup.d.ts.map +0 -1
- package/src/packlets/spaces/edge-feed-replicator.test.ts +0 -244
- package/src/testing/setup.ts +0 -11
|
@@ -2,21 +2,20 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { expect } from 'chai';
|
|
6
6
|
|
|
7
7
|
import { asyncChain, Trigger } from '@dxos/async';
|
|
8
8
|
import { raise } from '@dxos/debug';
|
|
9
9
|
import { AlreadyJoinedError } from '@dxos/protocols';
|
|
10
10
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
11
|
+
import { afterTest, describe, test } from '@dxos/test';
|
|
11
12
|
|
|
12
13
|
import { type ServiceContext } from '../services';
|
|
13
14
|
import { createIdentity, createPeers } from '../testing';
|
|
14
15
|
import { acceptInvitation, createInvitation, performInvitation } from '../testing/invitation-utils';
|
|
15
16
|
|
|
16
17
|
const closeAfterTest = async (peer: ServiceContext) => {
|
|
17
|
-
|
|
18
|
-
await peer.close();
|
|
19
|
-
});
|
|
18
|
+
afterTest(() => peer.close());
|
|
20
19
|
return peer;
|
|
21
20
|
};
|
|
22
21
|
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { expect } from 'chai';
|
|
6
6
|
|
|
7
7
|
import { Trigger } from '@dxos/async';
|
|
8
8
|
import { log, LogLevel } from '@dxos/log';
|
|
9
9
|
import { type LogEntry } from '@dxos/protocols/proto/dxos/client/services';
|
|
10
|
+
import { beforeEach, describe, test } from '@dxos/test';
|
|
10
11
|
|
|
11
12
|
import { LoggingServiceImpl } from './logging-service';
|
|
12
13
|
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { expect } from 'chai';
|
|
6
6
|
|
|
7
7
|
import { Trigger } from '@dxos/async';
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
9
|
import { type NetworkService, ConnectionState } from '@dxos/protocols/proto/dxos/client/services';
|
|
10
|
+
import { afterEach, afterTest, beforeEach, describe, test } from '@dxos/test';
|
|
10
11
|
|
|
11
12
|
import { NetworkServiceImpl } from './network-service';
|
|
12
13
|
import { type ServiceContext } from '../services';
|
|
@@ -40,7 +41,7 @@ describe('NetworkService', () => {
|
|
|
40
41
|
query.subscribe(({ swarm }) => {
|
|
41
42
|
result.wake(swarm);
|
|
42
43
|
});
|
|
43
|
-
|
|
44
|
+
afterTest(() => query.close());
|
|
44
45
|
expect(await result.wait()).to.equal(ConnectionState.ONLINE);
|
|
45
46
|
|
|
46
47
|
result = new Trigger<ConnectionState | undefined>();
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { expect } from 'chai';
|
|
6
|
+
|
|
7
|
+
import { asyncTimeout } from '@dxos/async';
|
|
8
|
+
import { AutomergeContext } from '@dxos/echo-db';
|
|
9
|
+
import { AutomergeHost, DataServiceImpl } from '@dxos/echo-pipeline';
|
|
10
|
+
import { IndexMetadataStore } from '@dxos/indexing';
|
|
11
|
+
import { createTestLevel } from '@dxos/kv-store/testing';
|
|
12
|
+
import { afterTest, describe, openAndClose, test } from '@dxos/test';
|
|
13
|
+
|
|
14
|
+
describe('AutomergeHost', () => {
|
|
15
|
+
test('automerge context is being synced with host', async () => {
|
|
16
|
+
//
|
|
17
|
+
// Setup:
|
|
18
|
+
// client-services | <-------------> | client
|
|
19
|
+
// AutomergeHost | DataServiceImpl | AutomergeContext
|
|
20
|
+
// creates repo and document | replicates repo | finds document in repo
|
|
21
|
+
//
|
|
22
|
+
|
|
23
|
+
const level = createTestLevel();
|
|
24
|
+
await level.open();
|
|
25
|
+
afterTest(() => level.close());
|
|
26
|
+
|
|
27
|
+
const host = new AutomergeHost({
|
|
28
|
+
db: level,
|
|
29
|
+
indexMetadataStore: new IndexMetadataStore({ db: level.sublevel('index-metadata') }),
|
|
30
|
+
});
|
|
31
|
+
await host.open();
|
|
32
|
+
afterTest(() => host.close());
|
|
33
|
+
|
|
34
|
+
const dataService = new DataServiceImpl({ automergeHost: host, updateIndexes: async () => {} });
|
|
35
|
+
const client = new AutomergeContext(dataService);
|
|
36
|
+
await openAndClose(client);
|
|
37
|
+
|
|
38
|
+
// Create document in repo.
|
|
39
|
+
const handle = host.repo.create();
|
|
40
|
+
const text = 'Hello World!';
|
|
41
|
+
handle.change((doc: any) => {
|
|
42
|
+
doc.text = text;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Find document in repo.
|
|
46
|
+
const doc = client.repo.find<{ text: string }>(handle.url);
|
|
47
|
+
await asyncTimeout(doc.whenReady(), 1_000);
|
|
48
|
+
expect(doc.docSync().text).to.equal(text);
|
|
49
|
+
|
|
50
|
+
// Changes from client are replicated to host.
|
|
51
|
+
const newText = 'Goodbye World!!!';
|
|
52
|
+
doc.change((doc: any) => {
|
|
53
|
+
doc.text = newText;
|
|
54
|
+
});
|
|
55
|
+
await client.flush({ documentIds: [doc.documentId] });
|
|
56
|
+
|
|
57
|
+
await asyncTimeout(handle.whenReady(), 1_000);
|
|
58
|
+
expect(handle.docSync().text).to.equal(newText);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { describe, test } from 'vitest';
|
|
6
|
-
|
|
7
5
|
import { MemorySignalManagerContext, MemorySignalManager } from '@dxos/messaging';
|
|
8
6
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
9
|
-
import { openAndClose } from '@dxos/test
|
|
7
|
+
import { describe, openAndClose, test } from '@dxos/test';
|
|
10
8
|
|
|
11
9
|
import { createServiceContext, performInvitation } from '../testing';
|
|
12
10
|
|
|
@@ -6,14 +6,8 @@ import { Trigger } from '@dxos/async';
|
|
|
6
6
|
import { Context, Resource } from '@dxos/context';
|
|
7
7
|
import { getCredentialAssertion, type CredentialProcessor } from '@dxos/credentials';
|
|
8
8
|
import { failUndefined } from '@dxos/debug';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
EchoHost,
|
|
12
|
-
MeshEchoReplicator,
|
|
13
|
-
MetadataStore,
|
|
14
|
-
SpaceManager,
|
|
15
|
-
valueEncoding,
|
|
16
|
-
} from '@dxos/echo-pipeline';
|
|
9
|
+
import { EchoEdgeReplicator, EchoHost } from '@dxos/echo-db';
|
|
10
|
+
import { MeshEchoReplicator, MetadataStore, SpaceManager, valueEncoding } from '@dxos/echo-pipeline';
|
|
17
11
|
import type { EdgeConnection } from '@dxos/edge-client';
|
|
18
12
|
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
19
13
|
import { invariant } from '@dxos/invariant';
|
|
@@ -37,8 +31,8 @@ import { safeInstanceof } from '@dxos/util';
|
|
|
37
31
|
import {
|
|
38
32
|
IdentityManager,
|
|
39
33
|
type CreateIdentityOptions,
|
|
34
|
+
type IdentityManagerRuntimeParams,
|
|
40
35
|
type JoinIdentityParams,
|
|
41
|
-
type IdentityManagerParams,
|
|
42
36
|
} from '../identity';
|
|
43
37
|
import {
|
|
44
38
|
DeviceInvitationProtocol,
|
|
@@ -49,10 +43,7 @@ import {
|
|
|
49
43
|
} from '../invitations';
|
|
50
44
|
import { DataSpaceManager, type DataSpaceManagerRuntimeParams, type SigningContext } from '../spaces';
|
|
51
45
|
|
|
52
|
-
export type ServiceContextRuntimeParams =
|
|
53
|
-
IdentityManagerParams,
|
|
54
|
-
'devicePresenceOfflineTimeout' | 'devicePresenceAnnounceInterval'
|
|
55
|
-
> &
|
|
46
|
+
export type ServiceContextRuntimeParams = IdentityManagerRuntimeParams &
|
|
56
47
|
DataSpaceManagerRuntimeParams & {
|
|
57
48
|
invitationConnectionDefaultParams?: Partial<TeleportParams>;
|
|
58
49
|
disableP2pReplication?: boolean;
|
|
@@ -125,16 +116,13 @@ export class ServiceContext extends Resource {
|
|
|
125
116
|
disableP2pReplication: this._runtimeParams?.disableP2pReplication,
|
|
126
117
|
});
|
|
127
118
|
|
|
128
|
-
this.identityManager = new IdentityManager(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
edgeConnection: this._edgeConnection,
|
|
136
|
-
edgeFeatures: this._edgeFeatures,
|
|
137
|
-
callbacks: {
|
|
119
|
+
this.identityManager = new IdentityManager(
|
|
120
|
+
this.metadataStore,
|
|
121
|
+
this.keyring,
|
|
122
|
+
this.feedStore,
|
|
123
|
+
this.spaceManager,
|
|
124
|
+
this._runtimeParams as IdentityManagerRuntimeParams,
|
|
125
|
+
{
|
|
138
126
|
onIdentityConstruction: (identity) => {
|
|
139
127
|
if (this._edgeConnection) {
|
|
140
128
|
log.info('Setting identity on edge connection', {
|
|
@@ -153,7 +141,7 @@ export class ServiceContext extends Resource {
|
|
|
153
141
|
}
|
|
154
142
|
},
|
|
155
143
|
},
|
|
156
|
-
|
|
144
|
+
);
|
|
157
145
|
|
|
158
146
|
this.echoHost = new EchoHost({ kv: this.level });
|
|
159
147
|
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import chai, { expect } from 'chai';
|
|
6
|
+
import chaiAsPromised from 'chai-as-promised';
|
|
5
7
|
import { rmSync } from 'node:fs';
|
|
6
|
-
import { afterEach, onTestFinished, describe, expect, test } from 'vitest';
|
|
7
8
|
|
|
8
9
|
import { asyncTimeout, latch, Trigger } from '@dxos/async';
|
|
9
10
|
import { Config } from '@dxos/config';
|
|
@@ -13,10 +14,13 @@ import { type PublicKey } from '@dxos/keys';
|
|
|
13
14
|
import { MemorySignalManagerContext } from '@dxos/messaging';
|
|
14
15
|
import { type Identity } from '@dxos/protocols/proto/dxos/client/services';
|
|
15
16
|
import { type Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
17
|
+
import { afterTest, describe, test } from '@dxos/test';
|
|
16
18
|
import { isNode } from '@dxos/util';
|
|
17
19
|
|
|
18
20
|
import { createMockCredential, createServiceHost } from '../testing';
|
|
19
21
|
|
|
22
|
+
chai.use(chaiAsPromised);
|
|
23
|
+
|
|
20
24
|
describe('ClientServicesHost', () => {
|
|
21
25
|
const dataRoot = '/tmp/dxos/client-services/service-host/storage';
|
|
22
26
|
|
|
@@ -34,7 +38,7 @@ describe('ClientServicesHost', () => {
|
|
|
34
38
|
test('queryCredentials', async () => {
|
|
35
39
|
const host = createServiceHost(new Config(), new MemorySignalManagerContext());
|
|
36
40
|
await host.open(new Context());
|
|
37
|
-
|
|
41
|
+
afterTest(() => host.close());
|
|
38
42
|
|
|
39
43
|
await host.services.IdentityService!.createIdentity({});
|
|
40
44
|
const { spaceKey } = await host.services.SpacesService!.createSpace();
|
|
@@ -45,7 +49,7 @@ describe('ClientServicesHost', () => {
|
|
|
45
49
|
tick();
|
|
46
50
|
// console.log(credential);
|
|
47
51
|
});
|
|
48
|
-
|
|
52
|
+
afterTest(() => stream.close());
|
|
49
53
|
|
|
50
54
|
await done();
|
|
51
55
|
});
|
|
@@ -53,7 +57,7 @@ describe('ClientServicesHost', () => {
|
|
|
53
57
|
test('write and query credentials', async () => {
|
|
54
58
|
const host = createServiceHost(new Config(), new MemorySignalManagerContext());
|
|
55
59
|
await host.open(new Context());
|
|
56
|
-
|
|
60
|
+
afterTest(() => host.close());
|
|
57
61
|
|
|
58
62
|
await host.services.IdentityService!.createIdentity({});
|
|
59
63
|
|
|
@@ -82,7 +86,7 @@ describe('ClientServicesHost', () => {
|
|
|
82
86
|
queriedCredential.wake(credential);
|
|
83
87
|
}
|
|
84
88
|
});
|
|
85
|
-
|
|
89
|
+
afterTest(() => credentials.close());
|
|
86
90
|
|
|
87
91
|
await queriedCredential.wait();
|
|
88
92
|
});
|
|
@@ -90,7 +94,7 @@ describe('ClientServicesHost', () => {
|
|
|
90
94
|
test('sign presentation', async () => {
|
|
91
95
|
const host = createServiceHost(new Config(), new MemorySignalManagerContext());
|
|
92
96
|
await host.open(new Context());
|
|
93
|
-
|
|
97
|
+
afterTest(() => host.close());
|
|
94
98
|
|
|
95
99
|
await host.services.IdentityService!.createIdentity({});
|
|
96
100
|
|
|
@@ -143,9 +147,9 @@ describe('ClientServicesHost', () => {
|
|
|
143
147
|
trigger.wake(identity.identity);
|
|
144
148
|
}
|
|
145
149
|
});
|
|
146
|
-
await expect(asyncTimeout(trigger.wait(), 200)).
|
|
150
|
+
await expect(asyncTimeout(trigger.wait(), 200)).to.be.rejectedWith();
|
|
147
151
|
await stream?.close();
|
|
148
152
|
await host.close();
|
|
149
153
|
}
|
|
150
|
-
});
|
|
154
|
+
}).onlyEnvironments('nodejs', 'chromium', 'firefox');
|
|
151
155
|
});
|
|
@@ -15,8 +15,8 @@ import { EdgeSignalManager, WebsocketSignalManager, type SignalManager } from '@
|
|
|
15
15
|
import {
|
|
16
16
|
SwarmNetworkManager,
|
|
17
17
|
createIceProvider,
|
|
18
|
+
createSimplePeerTransportFactory,
|
|
18
19
|
type TransportFactory,
|
|
19
|
-
createRtcTransportFactory,
|
|
20
20
|
} from '@dxos/network-manager';
|
|
21
21
|
import { trace } from '@dxos/protocols';
|
|
22
22
|
import { SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
|
|
@@ -218,7 +218,7 @@ export class ClientServicesHost {
|
|
|
218
218
|
|
|
219
219
|
const {
|
|
220
220
|
connectionLog = true,
|
|
221
|
-
transportFactory =
|
|
221
|
+
transportFactory = createSimplePeerTransportFactory(
|
|
222
222
|
{ iceServers: this._config?.get('runtime.services.ice') },
|
|
223
223
|
this._config?.get('runtime.services.iceProviders') &&
|
|
224
224
|
createIceProvider(this._config!.get('runtime.services.iceProviders')!),
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { expect } from 'chai';
|
|
6
6
|
|
|
7
7
|
import { Event } from '@dxos/async';
|
|
8
8
|
import { type ClientServices } from '@dxos/client-protocol';
|
|
@@ -12,6 +12,7 @@ import { log } from '@dxos/log';
|
|
|
12
12
|
import { schema } from '@dxos/protocols/proto';
|
|
13
13
|
import { type SystemService, SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
|
|
14
14
|
import { createLinkedPorts, createProtoRpcPeer, createServiceBundle } from '@dxos/rpc';
|
|
15
|
+
import { describe, test } from '@dxos/test';
|
|
15
16
|
|
|
16
17
|
import { ServiceRegistry } from './service-registry';
|
|
17
18
|
import { SystemServiceImpl } from '../system';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { expect } from 'chai';
|
|
6
6
|
|
|
7
7
|
import { asyncTimeout, latch } from '@dxos/async';
|
|
8
8
|
import { createAdmissionCredentials } from '@dxos/credentials';
|
|
@@ -10,7 +10,7 @@ import { AuthStatus } from '@dxos/echo-pipeline';
|
|
|
10
10
|
import { writeMessages } from '@dxos/feed-store';
|
|
11
11
|
import { log } from '@dxos/log';
|
|
12
12
|
import { SpaceState } from '@dxos/protocols/proto/dxos/client/services';
|
|
13
|
-
import { openAndClose } from '@dxos/test
|
|
13
|
+
import { describe, openAndClose, test } from '@dxos/test';
|
|
14
14
|
|
|
15
15
|
import { TestBuilder, type TestPeer } from '../testing';
|
|
16
16
|
|
|
@@ -14,11 +14,8 @@ import {
|
|
|
14
14
|
type DelegateInvitationCredential,
|
|
15
15
|
type MemberInfo,
|
|
16
16
|
} from '@dxos/credentials';
|
|
17
|
+
import { convertLegacyReferences, findInlineObjectOfType, type EchoEdgeReplicator, type EchoHost } from '@dxos/echo-db';
|
|
17
18
|
import {
|
|
18
|
-
convertLegacyReferences,
|
|
19
|
-
findInlineObjectOfType,
|
|
20
|
-
type EchoEdgeReplicator,
|
|
21
|
-
type EchoHost,
|
|
22
19
|
AuthStatus,
|
|
23
20
|
CredentialServerExtension,
|
|
24
21
|
type MeshEchoReplicator,
|
|
@@ -7,13 +7,8 @@ import { AUTH_TIMEOUT } from '@dxos/client-protocol';
|
|
|
7
7
|
import { Context, ContextDisposedError, cancelWithContext } from '@dxos/context';
|
|
8
8
|
import type { SpecificCredential } from '@dxos/credentials';
|
|
9
9
|
import { timed, warnAfterTimeout } from '@dxos/debug';
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
type DatabaseRoot,
|
|
13
|
-
createMappedFeedWriter,
|
|
14
|
-
type MetadataStore,
|
|
15
|
-
type Space,
|
|
16
|
-
} from '@dxos/echo-pipeline';
|
|
10
|
+
import { type EchoHost, type DatabaseRoot } from '@dxos/echo-db';
|
|
11
|
+
import { createMappedFeedWriter, type MetadataStore, type Space } from '@dxos/echo-pipeline';
|
|
17
12
|
import { SpaceDocVersion } from '@dxos/echo-protocol';
|
|
18
13
|
import type { EdgeConnection } from '@dxos/edge-client';
|
|
19
14
|
import { type FeedStore, type FeedWrapper } from '@dxos/feed-store';
|
|
@@ -5,19 +5,15 @@
|
|
|
5
5
|
import { decode as decodeCbor, encode as encodeCbor } from 'cbor-x';
|
|
6
6
|
|
|
7
7
|
import { Event, Mutex, scheduleMicroTask } from '@dxos/async';
|
|
8
|
-
import {
|
|
8
|
+
import { Resource, type Context } from '@dxos/context';
|
|
9
9
|
import { type EdgeConnection } from '@dxos/edge-client';
|
|
10
|
-
import { EdgeConnectionClosedError, EdgeIdentityChangedError } from '@dxos/edge-client';
|
|
11
10
|
import { type FeedWrapper } from '@dxos/feed-store';
|
|
12
11
|
import { invariant } from '@dxos/invariant';
|
|
13
12
|
import { PublicKey, type SpaceId } from '@dxos/keys';
|
|
14
13
|
import { log } from '@dxos/log';
|
|
15
14
|
import { EdgeService } from '@dxos/protocols';
|
|
16
15
|
import { buf } from '@dxos/protocols/buf';
|
|
17
|
-
import {
|
|
18
|
-
MessageSchema as RouterMessageSchema,
|
|
19
|
-
type Message as RouterMessage,
|
|
20
|
-
} from '@dxos/protocols/buf/dxos/edge/messenger_pb';
|
|
16
|
+
import { MessageSchema as RouterMessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';
|
|
21
17
|
import type { FeedBlock, ProtocolMessage } from '@dxos/protocols/feed-replication';
|
|
22
18
|
import { ComplexMap, arrayToBuffer, bufferToArray, defaultMap, rangeFromTo } from '@dxos/util';
|
|
23
19
|
|
|
@@ -52,7 +48,7 @@ export class EdgeFeedReplicator extends Resource {
|
|
|
52
48
|
protected override async _open(): Promise<void> {
|
|
53
49
|
// TODO: handle reconnects
|
|
54
50
|
this._ctx.onDispose(
|
|
55
|
-
this._messenger.addListener((message
|
|
51
|
+
this._messenger.addListener(async (message) => {
|
|
56
52
|
if (!message.serviceId) {
|
|
57
53
|
return;
|
|
58
54
|
}
|
|
@@ -68,43 +64,21 @@ export class EdgeFeedReplicator extends Resource {
|
|
|
68
64
|
}
|
|
69
65
|
|
|
70
66
|
const payload = decodeCbor(message.payload!.value) as ProtocolMessage;
|
|
71
|
-
log.info('
|
|
67
|
+
log.info('recv', { from: message.source, payload });
|
|
72
68
|
this._onMessage(payload);
|
|
73
69
|
}),
|
|
74
70
|
);
|
|
75
71
|
|
|
76
|
-
this.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
this.
|
|
80
|
-
|
|
81
|
-
onError: async (err: any) => {
|
|
82
|
-
if (connectionCtx !== this._connectionCtx) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
if (err instanceof EdgeIdentityChangedError || err instanceof EdgeConnectionClosedError) {
|
|
86
|
-
log('resetting on reconnect');
|
|
87
|
-
await this._resetConnection();
|
|
88
|
-
} else {
|
|
89
|
-
this._ctx.raise(err);
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
this._connectionCtx = connectionCtx;
|
|
94
|
-
log('connection context created');
|
|
95
|
-
scheduleMicroTask(connectionCtx, async () => {
|
|
96
|
-
for (const feed of this._feeds.values()) {
|
|
97
|
-
await this._replicateFeed(connectionCtx, feed);
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
});
|
|
72
|
+
this._connected = true;
|
|
73
|
+
this._connectionCtx = this._ctx.derive();
|
|
74
|
+
for (const feed of this._feeds.values()) {
|
|
75
|
+
await this._replicateFeed(feed);
|
|
76
|
+
}
|
|
101
77
|
}
|
|
102
78
|
|
|
103
79
|
protected override async _close(): Promise<void> {
|
|
104
|
-
|
|
105
|
-
}
|
|
80
|
+
this._connected = false;
|
|
106
81
|
|
|
107
|
-
private async _resetConnection() {
|
|
108
82
|
this._connected = false;
|
|
109
83
|
await this._connectionCtx?.dispose();
|
|
110
84
|
this._connectionCtx = undefined;
|
|
@@ -115,8 +89,8 @@ export class EdgeFeedReplicator extends Resource {
|
|
|
115
89
|
log.info('addFeed', { key: feed.key });
|
|
116
90
|
this._feeds.set(feed.key, feed);
|
|
117
91
|
|
|
118
|
-
if (this._connected
|
|
119
|
-
await this._replicateFeed(
|
|
92
|
+
if (this._connected) {
|
|
93
|
+
await this._replicateFeed(feed);
|
|
120
94
|
}
|
|
121
95
|
}
|
|
122
96
|
|
|
@@ -124,26 +98,21 @@ export class EdgeFeedReplicator extends Resource {
|
|
|
124
98
|
return defaultMap(this._pushMutex, key, () => new Mutex());
|
|
125
99
|
}
|
|
126
100
|
|
|
127
|
-
private async _replicateFeed(
|
|
101
|
+
private async _replicateFeed(feed: FeedWrapper<any>) {
|
|
102
|
+
invariant(this._connectionCtx);
|
|
103
|
+
|
|
128
104
|
await this._sendMessage({
|
|
129
105
|
type: 'get-metadata',
|
|
130
106
|
feedKey: feed.key.toHex(),
|
|
131
107
|
});
|
|
132
108
|
|
|
133
|
-
Event.wrap(feed.core as any, 'append').on(
|
|
109
|
+
Event.wrap(feed.core as any, 'append').on(this._connectionCtx, async () => {
|
|
134
110
|
await this._pushBlocksIfNeeded(feed);
|
|
135
111
|
});
|
|
136
112
|
}
|
|
137
113
|
|
|
138
114
|
private async _sendMessage(message: ProtocolMessage) {
|
|
139
|
-
|
|
140
|
-
log.info('message dropped because connection was disposed');
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const logPayload =
|
|
145
|
-
message.type === 'data' ? { feedKey: message.feedKey, blocks: message.blocks.map((b) => b.index) } : { message };
|
|
146
|
-
log.info('sending message', logPayload);
|
|
115
|
+
log.info('sending message', { message });
|
|
147
116
|
|
|
148
117
|
invariant(message.feedKey);
|
|
149
118
|
const payloadValue = bufferToArray(encodeCbor(message));
|
|
@@ -161,15 +130,11 @@ export class EdgeFeedReplicator extends Resource {
|
|
|
161
130
|
}
|
|
162
131
|
|
|
163
132
|
private _onMessage(message: ProtocolMessage) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
scheduleMicroTask(this._connectionCtx, async () => {
|
|
133
|
+
log.info('received message', { message });
|
|
134
|
+
|
|
135
|
+
scheduleMicroTask(this._ctx, async () => {
|
|
169
136
|
switch (message.type) {
|
|
170
137
|
case 'metadata': {
|
|
171
|
-
log.info('received metadata', { message });
|
|
172
|
-
|
|
173
138
|
const feedKey = PublicKey.fromHex(message.feedKey);
|
|
174
139
|
const feed = this._feeds.get(feedKey);
|
|
175
140
|
if (!feed) {
|
|
@@ -195,8 +160,6 @@ export class EdgeFeedReplicator extends Resource {
|
|
|
195
160
|
}
|
|
196
161
|
|
|
197
162
|
case 'data': {
|
|
198
|
-
log.info('received data', { feed: message.feedKey, blocks: message.blocks.map((b) => b.index) });
|
|
199
|
-
|
|
200
163
|
const feedKey = PublicKey.fromHex(message.feedKey);
|
|
201
164
|
const feed = this._feeds.get(feedKey);
|
|
202
165
|
if (!feed) {
|
|
@@ -260,10 +223,9 @@ export class EdgeFeedReplicator extends Resource {
|
|
|
260
223
|
}
|
|
261
224
|
|
|
262
225
|
private async _pushBlocksIfNeeded(feed: FeedWrapper<any>) {
|
|
263
|
-
using
|
|
226
|
+
using _guard = await this._getPushMutex(feed.key).acquire();
|
|
264
227
|
|
|
265
228
|
if (!this._remoteLength.has(feed.key)) {
|
|
266
|
-
log('blocks not pushed because remote length is unknown');
|
|
267
229
|
return;
|
|
268
230
|
}
|
|
269
231
|
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
import type { AutomergeUrl } from '@dxos/automerge/automerge-repo';
|
|
6
6
|
import { type Context } from '@dxos/context';
|
|
7
|
-
import { migrateDocument } from '@dxos/echo-db';
|
|
8
7
|
import {
|
|
9
8
|
convertLegacyReferences,
|
|
10
9
|
convertLegacySpaceRootDoc,
|
|
11
10
|
findInlineObjectOfType,
|
|
11
|
+
migrateDocument,
|
|
12
12
|
type EchoHost,
|
|
13
|
-
} from '@dxos/echo-
|
|
13
|
+
} from '@dxos/echo-db';
|
|
14
14
|
import { SpaceDocVersion, type SpaceDoc } from '@dxos/echo-protocol';
|
|
15
15
|
import { TYPE_PROPERTIES } from '@dxos/echo-schema';
|
|
16
16
|
import { invariant } from '@dxos/invariant';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { expect } from 'chai';
|
|
6
6
|
|
|
7
7
|
import { Context } from '@dxos/context';
|
|
8
8
|
import { CredentialGenerator } from '@dxos/credentials';
|
|
@@ -11,6 +11,7 @@ import { Keyring } from '@dxos/keyring';
|
|
|
11
11
|
import { log } from '@dxos/log';
|
|
12
12
|
import { AdmittedFeed, type Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
13
13
|
import { TestBuilder, type TestConnection, TestPeer } from '@dxos/teleport/testing';
|
|
14
|
+
import { afterTest, describe, test } from '@dxos/test';
|
|
14
15
|
|
|
15
16
|
import { NotarizationPlugin } from './notarization-plugin';
|
|
16
17
|
|
|
@@ -48,7 +49,7 @@ class TestAgent extends TestPeer {
|
|
|
48
49
|
describe('NotarizationPlugin', () => {
|
|
49
50
|
test('notarize single credential', async () => {
|
|
50
51
|
const testBuilder = new TestBuilder();
|
|
51
|
-
|
|
52
|
+
afterTest(() => testBuilder.destroy());
|
|
52
53
|
|
|
53
54
|
// peer0 is there to test retries.
|
|
54
55
|
const [_peer0, peer1, peer2] = await testBuilder.createPeers({ factory: () => new TestAgent() });
|
|
@@ -2,17 +2,21 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import chai, { expect } from 'chai';
|
|
6
|
+
import chaiAsPromised from 'chai-as-promised';
|
|
6
7
|
|
|
7
8
|
import { Trigger } from '@dxos/async';
|
|
8
9
|
import { Context } from '@dxos/context';
|
|
9
10
|
import { PublicKey } from '@dxos/keys';
|
|
10
11
|
import { type Space, type SpacesService } from '@dxos/protocols/proto/dxos/client/services';
|
|
12
|
+
import { afterEach, afterTest, beforeEach, describe, test } from '@dxos/test';
|
|
11
13
|
|
|
12
14
|
import { SpacesServiceImpl } from './spaces-service';
|
|
13
15
|
import { type ServiceContext } from '../services';
|
|
14
16
|
import { createServiceContext } from '../testing';
|
|
15
17
|
|
|
18
|
+
chai.use(chaiAsPromised);
|
|
19
|
+
|
|
16
20
|
describe('SpacesService', () => {
|
|
17
21
|
let serviceContext: ServiceContext;
|
|
18
22
|
let spacesService: SpacesService;
|
|
@@ -32,7 +36,7 @@ describe('SpacesService', () => {
|
|
|
32
36
|
|
|
33
37
|
describe('createSpace', () => {
|
|
34
38
|
test('fails if no identity is available', async () => {
|
|
35
|
-
await expect(spacesService.createSpace()).
|
|
39
|
+
await expect(spacesService.createSpace()).to.be.rejectedWith();
|
|
36
40
|
});
|
|
37
41
|
|
|
38
42
|
test('creates a new space', async () => {
|
|
@@ -52,7 +56,7 @@ describe('SpacesService', () => {
|
|
|
52
56
|
query.subscribe(({ spaces }) => {
|
|
53
57
|
result.wake(spaces);
|
|
54
58
|
});
|
|
55
|
-
|
|
59
|
+
afterTest(() => query.close());
|
|
56
60
|
expect(await result.wait()).to.be.length(0);
|
|
57
61
|
});
|
|
58
62
|
|
|
@@ -69,7 +73,7 @@ describe('SpacesService', () => {
|
|
|
69
73
|
query.subscribe(({ spaces }) => {
|
|
70
74
|
result.wake(spaces);
|
|
71
75
|
});
|
|
72
|
-
|
|
76
|
+
afterTest(() => query.close());
|
|
73
77
|
|
|
74
78
|
const spaces = await result.wait();
|
|
75
79
|
expect(spaces).to.be.length(3);
|
|
@@ -83,7 +87,7 @@ describe('SpacesService', () => {
|
|
|
83
87
|
query.subscribe(({ spaces }) => {
|
|
84
88
|
result.wake(spaces);
|
|
85
89
|
});
|
|
86
|
-
|
|
90
|
+
afterTest(() => query.close());
|
|
87
91
|
expect(await result.wait()).to.be.length(0);
|
|
88
92
|
|
|
89
93
|
result.reset();
|
|
@@ -14,6 +14,7 @@ import { getRootPath } from './util';
|
|
|
14
14
|
// TODO(burdon): Factor out.
|
|
15
15
|
export const createStorageObjects = (config: Runtime.Client.Storage) => {
|
|
16
16
|
const { persistent = false, keyStore, dataStore } = config ?? {};
|
|
17
|
+
|
|
17
18
|
if (persistent && dataStore === StorageDriver.RAM) {
|
|
18
19
|
throw new InvalidConfigError('RAM storage cannot be used in persistent mode.');
|
|
19
20
|
}
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { expect } from 'chai';
|
|
6
6
|
|
|
7
7
|
import { Event, Trigger } from '@dxos/async';
|
|
8
8
|
import { Config } from '@dxos/config';
|
|
9
9
|
import { type SystemService, SystemStatus, type QueryStatusResponse } from '@dxos/protocols/proto/dxos/client/services';
|
|
10
|
+
import { beforeEach, describe, test } from '@dxos/test';
|
|
10
11
|
|
|
11
12
|
import { SystemServiceImpl } from './system-service';
|
|
12
13
|
|