@dxos/client-services 0.1.30-next.7c60cd3 → 0.1.30

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.
Files changed (161) hide show
  1. package/dist/lib/browser/{chunk-JLLUQQXD.mjs → chunk-DFO3FW2W.mjs} +949 -1150
  2. package/dist/lib/browser/chunk-DFO3FW2W.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +5 -41
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/packlets/testing/index.mjs +221 -50
  6. package/dist/lib/browser/packlets/testing/index.mjs.map +4 -4
  7. package/dist/lib/node/index.cjs +837 -1062
  8. package/dist/lib/node/index.cjs.map +4 -4
  9. package/dist/lib/node/meta.json +1 -1
  10. package/dist/lib/node/packlets/testing/index.cjs +2937 -2719
  11. package/dist/lib/node/packlets/testing/index.cjs.map +4 -4
  12. package/dist/types/src/packlets/invitations/device-invitations-handler.d.ts +1 -2
  13. package/dist/types/src/packlets/invitations/device-invitations-handler.d.ts.map +1 -1
  14. package/dist/types/src/packlets/invitations/device-invitations-service.d.ts +1 -1
  15. package/dist/types/src/packlets/invitations/device-invitations-service.d.ts.map +1 -1
  16. package/dist/types/src/packlets/invitations/index.d.ts +0 -6
  17. package/dist/types/src/packlets/invitations/index.d.ts.map +1 -1
  18. package/dist/types/src/packlets/invitations/invitations-service.d.ts +2 -3
  19. package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
  20. package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts +2 -4
  21. package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts.map +1 -1
  22. package/dist/types/src/packlets/invitations/space-invitations-service.d.ts +2 -3
  23. package/dist/types/src/packlets/invitations/space-invitations-service.d.ts.map +1 -1
  24. package/dist/types/src/packlets/services/client-rpc-server.d.ts +22 -0
  25. package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -0
  26. package/dist/types/src/packlets/services/index.d.ts +2 -3
  27. package/dist/types/src/packlets/services/index.d.ts.map +1 -1
  28. package/dist/types/src/packlets/services/local-client-services.d.ts +3 -2
  29. package/dist/types/src/packlets/services/local-client-services.d.ts.map +1 -1
  30. package/dist/types/src/packlets/services/service-context.d.ts +1 -1
  31. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  32. package/dist/types/src/packlets/services/service-host.d.ts +22 -8
  33. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  34. package/dist/types/src/packlets/services/service-registry.d.ts +3 -1
  35. package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
  36. package/dist/types/src/packlets/services/utils.d.ts +7 -0
  37. package/dist/types/src/packlets/services/utils.d.ts.map +1 -0
  38. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  39. package/dist/types/src/packlets/spaces/data-space.d.ts +8 -1
  40. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  41. package/dist/types/src/packlets/spaces/index.d.ts +2 -0
  42. package/dist/types/src/packlets/spaces/index.d.ts.map +1 -1
  43. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  44. package/dist/types/src/packlets/spaces/spaces-service.d.ts +4 -1
  45. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  46. package/dist/types/src/packlets/system/system-service.d.ts +2 -2
  47. package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
  48. package/dist/types/src/packlets/testing/host-test-builder.d.ts +43 -0
  49. package/dist/types/src/packlets/testing/host-test-builder.d.ts.map +1 -0
  50. package/dist/types/src/packlets/testing/index.d.ts +1 -0
  51. package/dist/types/src/packlets/testing/index.d.ts.map +1 -1
  52. package/dist/types/src/packlets/testing/invitation-utils.d.ts +1 -1
  53. package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
  54. package/dist/types/src/packlets/testing/test-builder.d.ts +32 -34
  55. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  56. package/dist/types/src/packlets/tests/client-services.test.d.ts +2 -0
  57. package/dist/types/src/packlets/tests/client-services.test.d.ts.map +1 -0
  58. package/dist/types/src/packlets/tests/client.test.d.ts +2 -0
  59. package/dist/types/src/packlets/tests/client.test.d.ts.map +1 -0
  60. package/dist/types/src/packlets/tests/halo-credentials.test.d.ts +2 -0
  61. package/dist/types/src/packlets/tests/halo-credentials.test.d.ts.map +1 -0
  62. package/dist/types/src/packlets/tests/halo-persistent.test.d.ts +2 -0
  63. package/dist/types/src/packlets/tests/halo-persistent.test.d.ts.map +1 -0
  64. package/dist/types/src/packlets/tests/halo-profile.test.d.ts +2 -0
  65. package/dist/types/src/packlets/tests/halo-profile.test.d.ts.map +1 -0
  66. package/dist/types/src/packlets/tests/shared-worker.test.d.ts +2 -0
  67. package/dist/types/src/packlets/tests/shared-worker.test.d.ts.map +1 -0
  68. package/dist/types/src/packlets/tests/spaces-invitations.test.d.ts +2 -0
  69. package/dist/types/src/packlets/tests/spaces-invitations.test.d.ts.map +1 -0
  70. package/dist/types/src/packlets/tests/spaces.test.d.ts +2 -0
  71. package/dist/types/src/packlets/tests/spaces.test.d.ts.map +1 -0
  72. package/dist/types/src/packlets/tests/text.test.d.ts +2 -0
  73. package/dist/types/src/packlets/tests/text.test.d.ts.map +1 -0
  74. package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts +0 -1
  75. package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts.map +1 -1
  76. package/dist/types/src/packlets/vault/iframe-proxy-runtime.d.ts.map +1 -1
  77. package/dist/types/src/packlets/vault/index.d.ts +0 -2
  78. package/dist/types/src/packlets/vault/index.d.ts.map +1 -1
  79. package/dist/types/src/packlets/vault/shell-runtime.d.ts.map +1 -1
  80. package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
  81. package/dist/types/src/packlets/vault/worker-session.d.ts +4 -4
  82. package/dist/types/src/packlets/vault/worker-session.d.ts.map +1 -1
  83. package/package.json +31 -30
  84. package/src/packlets/invitations/device-invitations-handler.ts +10 -9
  85. package/src/packlets/invitations/device-invitations-service.test.ts +1 -1
  86. package/src/packlets/invitations/device-invitations-service.ts +1 -1
  87. package/src/packlets/invitations/index.ts +0 -6
  88. package/src/packlets/invitations/invitations-service.ts +7 -2
  89. package/src/packlets/invitations/space-invitations-handler.test.ts +3 -3
  90. package/src/packlets/invitations/space-invitations-handler.ts +11 -11
  91. package/src/packlets/invitations/space-invitations-service.test.ts +1 -1
  92. package/src/packlets/invitations/space-invitations-service.ts +2 -3
  93. package/src/packlets/services/client-rpc-server.ts +91 -0
  94. package/src/packlets/services/index.ts +2 -3
  95. package/src/packlets/services/local-client-services.ts +5 -1
  96. package/src/packlets/services/service-context.test.ts +4 -4
  97. package/src/packlets/services/service-context.ts +1 -1
  98. package/src/packlets/services/service-host.ts +52 -19
  99. package/src/packlets/services/service-registry.test.ts +2 -2
  100. package/src/packlets/services/service-registry.ts +9 -1
  101. package/src/packlets/services/utils.ts +53 -0
  102. package/src/packlets/spaces/data-space-manager.test.ts +64 -4
  103. package/src/packlets/spaces/data-space-manager.ts +11 -7
  104. package/src/packlets/spaces/data-space.ts +13 -1
  105. package/src/packlets/spaces/index.ts +2 -0
  106. package/src/packlets/spaces/notarization-plugin.ts +9 -2
  107. package/src/packlets/spaces/spaces-service.ts +25 -0
  108. package/src/packlets/system/system-service.ts +3 -3
  109. package/src/packlets/testing/host-test-builder.ts +163 -0
  110. package/src/packlets/testing/index.ts +1 -0
  111. package/src/packlets/testing/invitation-utils.ts +1 -2
  112. package/src/packlets/testing/test-builder.ts +156 -138
  113. package/src/packlets/tests/client-services.test.ts +252 -0
  114. package/src/packlets/tests/client.test.ts +143 -0
  115. package/src/packlets/tests/halo-credentials.test.ts +94 -0
  116. package/src/packlets/tests/halo-persistent.test.ts +53 -0
  117. package/src/packlets/tests/halo-profile.test.ts +74 -0
  118. package/src/packlets/tests/shared-worker.test.ts +93 -0
  119. package/src/packlets/tests/spaces-invitations.test.ts +64 -0
  120. package/src/packlets/tests/spaces.test.ts +136 -0
  121. package/src/packlets/tests/text.test.ts +206 -0
  122. package/src/packlets/vault/iframe-host-runtime.ts +26 -34
  123. package/src/packlets/vault/iframe-proxy-runtime.ts +1 -1
  124. package/src/packlets/vault/index.ts +0 -2
  125. package/src/packlets/vault/shell-runtime.ts +1 -2
  126. package/src/packlets/vault/worker-runtime.ts +5 -15
  127. package/src/packlets/vault/worker-session.ts +39 -23
  128. package/dist/lib/browser/chunk-JLLUQQXD.mjs.map +0 -7
  129. package/dist/types/src/packlets/invitations/device-invitations-proxy.d.ts +0 -8
  130. package/dist/types/src/packlets/invitations/device-invitations-proxy.d.ts.map +0 -1
  131. package/dist/types/src/packlets/invitations/encoder.d.ts +0 -9
  132. package/dist/types/src/packlets/invitations/encoder.d.ts.map +0 -1
  133. package/dist/types/src/packlets/invitations/encoder.test.d.ts +0 -2
  134. package/dist/types/src/packlets/invitations/encoder.test.d.ts.map +0 -1
  135. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +0 -56
  136. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +0 -1
  137. package/dist/types/src/packlets/invitations/invitations-proxy.d.ts +0 -18
  138. package/dist/types/src/packlets/invitations/invitations-proxy.d.ts.map +0 -1
  139. package/dist/types/src/packlets/invitations/invitations.d.ts +0 -55
  140. package/dist/types/src/packlets/invitations/invitations.d.ts.map +0 -1
  141. package/dist/types/src/packlets/invitations/space-invitations-proxy.d.ts +0 -11
  142. package/dist/types/src/packlets/invitations/space-invitations-proxy.d.ts.map +0 -1
  143. package/dist/types/src/packlets/services/service-definitions.d.ts +0 -30
  144. package/dist/types/src/packlets/services/service-definitions.d.ts.map +0 -1
  145. package/dist/types/src/packlets/services/service-proxy.d.ts +0 -17
  146. package/dist/types/src/packlets/services/service-proxy.d.ts.map +0 -1
  147. package/dist/types/src/packlets/vault/services.d.ts +0 -21
  148. package/dist/types/src/packlets/vault/services.d.ts.map +0 -1
  149. package/dist/types/src/packlets/vault/shell-controller.d.ts +0 -18
  150. package/dist/types/src/packlets/vault/shell-controller.d.ts.map +0 -1
  151. package/src/packlets/invitations/device-invitations-proxy.ts +0 -14
  152. package/src/packlets/invitations/encoder.test.ts +0 -23
  153. package/src/packlets/invitations/encoder.ts +0 -26
  154. package/src/packlets/invitations/invitations-handler.ts +0 -68
  155. package/src/packlets/invitations/invitations-proxy.ts +0 -159
  156. package/src/packlets/invitations/invitations.ts +0 -113
  157. package/src/packlets/invitations/space-invitations-proxy.ts +0 -16
  158. package/src/packlets/services/service-definitions.ts +0 -68
  159. package/src/packlets/services/service-proxy.ts +0 -54
  160. package/src/packlets/vault/services.ts +0 -42
  161. package/src/packlets/vault/shell-controller.ts +0 -56
@@ -0,0 +1,163 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import { createDefaultModelFactory } from '@dxos/client';
6
+ import { Config } from '@dxos/config';
7
+ import { createCredentialSignerWithChain, CredentialGenerator } from '@dxos/credentials';
8
+ import {
9
+ SnapshotStore,
10
+ DataPipelineControllerImpl,
11
+ MetadataStore,
12
+ SigningContext,
13
+ SpaceManager,
14
+ valueEncoding
15
+ } from '@dxos/echo-pipeline';
16
+ import { testLocalDatabase } from '@dxos/echo-pipeline/testing';
17
+ import { FeedFactory, FeedStore } from '@dxos/feed-store';
18
+ import { Keyring } from '@dxos/keyring';
19
+ import { MemorySignalManager, MemorySignalManagerContext } from '@dxos/messaging';
20
+ import { MemoryTransportFactory, NetworkManager } from '@dxos/network-manager';
21
+ import { createStorage, Storage, StorageType } from '@dxos/random-access-storage';
22
+
23
+ import { ClientServicesHost, ServiceContext } from '../services';
24
+
25
+ //
26
+ // TODO(burdon): Replace with test builder.
27
+ //
28
+
29
+ export const createServiceHost = (config: Config, signalManagerContext: MemorySignalManagerContext) => {
30
+ const networkManager = new NetworkManager({
31
+ signalManager: new MemorySignalManager(signalManagerContext),
32
+ transportFactory: MemoryTransportFactory
33
+ });
34
+
35
+ return new ClientServicesHost({
36
+ config,
37
+ networkManager
38
+ });
39
+ };
40
+
41
+ export const createServiceContext = ({
42
+ signalContext = new MemorySignalManagerContext(),
43
+ storage = createStorage({ type: StorageType.RAM })
44
+ }: {
45
+ signalContext?: MemorySignalManagerContext;
46
+ storage?: Storage;
47
+ } = {}) => {
48
+ const networkManager = new NetworkManager({
49
+ signalManager: new MemorySignalManager(signalContext),
50
+ transportFactory: MemoryTransportFactory
51
+ });
52
+
53
+ const modelFactory = createDefaultModelFactory();
54
+ return new ServiceContext(storage, networkManager, modelFactory);
55
+ };
56
+
57
+ export const createPeers = async (numPeers: number) => {
58
+ const signalContext = new MemorySignalManagerContext();
59
+
60
+ return await Promise.all(
61
+ Array.from(Array(numPeers)).map(async () => {
62
+ const peer = createServiceContext({ signalContext });
63
+ await peer.open();
64
+ return peer;
65
+ })
66
+ );
67
+ };
68
+
69
+ export const createIdentity = async (peer: ServiceContext) => {
70
+ await peer.createIdentity();
71
+ return peer;
72
+ };
73
+
74
+ // TODO(burdon): Remove @dxos/client-testing.
75
+ // TODO(burdon): Create builder and make configurable.
76
+ export const syncItemsLocal = async (db1: DataPipelineControllerImpl, db2: DataPipelineControllerImpl) => {
77
+ await testLocalDatabase(db1, db2);
78
+ await testLocalDatabase(db2, db1);
79
+ };
80
+
81
+ export class HostTestBuilder {
82
+ public readonly signalContext = new MemorySignalManagerContext();
83
+
84
+ createPeer(): TestPeer {
85
+ return new TestPeer(this.signalContext);
86
+ }
87
+ }
88
+
89
+ export type TestPeerProps = {
90
+ storage?: Storage;
91
+ feedStore?: FeedStore<any>;
92
+ metadataStore?: MetadataStore;
93
+ keyring?: Keyring;
94
+ networkManager?: NetworkManager;
95
+ spaceManager?: SpaceManager;
96
+ snapshotStore?: SnapshotStore;
97
+ };
98
+
99
+ export class TestPeer {
100
+ private _props: TestPeerProps = {};
101
+
102
+ constructor(private readonly signalContext: MemorySignalManagerContext) {}
103
+
104
+ get storage() {
105
+ return (this._props.storage ??= createStorage({ type: StorageType.RAM }));
106
+ }
107
+
108
+ get keyring() {
109
+ return (this._props.keyring ??= new Keyring(this.storage.createDirectory('keyring')));
110
+ }
111
+
112
+ get feedStore() {
113
+ return (this._props.feedStore ??= new FeedStore({
114
+ factory: new FeedFactory({
115
+ root: this.storage.createDirectory('feeds'),
116
+ signer: this.keyring,
117
+ hypercore: {
118
+ valueEncoding
119
+ }
120
+ })
121
+ }));
122
+ }
123
+
124
+ get metadataStore() {
125
+ return (this._props.metadataStore ??= new MetadataStore(this.storage.createDirectory('metadata')));
126
+ }
127
+
128
+ get snapshotStore() {
129
+ return (this._props.snapshotStore ??= new SnapshotStore(this.storage.createDirectory('snapshots')));
130
+ }
131
+
132
+ get networkManager() {
133
+ return (this._props.networkManager ??= new NetworkManager({
134
+ signalManager: new MemorySignalManager(this.signalContext),
135
+ transportFactory: MemoryTransportFactory
136
+ }));
137
+ }
138
+
139
+ get spaceManager() {
140
+ return (this._props.spaceManager ??= new SpaceManager({
141
+ feedStore: this.feedStore,
142
+ networkManager: this.networkManager
143
+ }));
144
+ }
145
+ }
146
+
147
+ export const createSigningContext = async (keyring: Keyring): Promise<SigningContext> => {
148
+ const identityKey = await keyring.createKey();
149
+ const deviceKey = await keyring.createKey();
150
+
151
+ return {
152
+ identityKey,
153
+ deviceKey,
154
+ credentialSigner: createCredentialSignerWithChain(
155
+ keyring,
156
+ {
157
+ credential: await new CredentialGenerator(keyring, identityKey, deviceKey).createDeviceAuthorization(deviceKey)
158
+ },
159
+ deviceKey
160
+ ),
161
+ recordCredential: async () => {} // No-op.
162
+ };
163
+ };
@@ -3,5 +3,6 @@
3
3
  //
4
4
 
5
5
  export * from './credential-utils';
6
+ export * from './host-test-builder';
6
7
  export * from './invitation-utils';
7
8
  export * from './test-builder';
@@ -5,11 +5,10 @@
5
5
  import assert from 'node:assert';
6
6
 
7
7
  import { Trigger } from '@dxos/async';
8
+ import { InvitationsHandler } from '@dxos/client';
8
9
  import { raise } from '@dxos/debug';
9
10
  import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
10
11
 
11
- import { InvitationsHandler } from '../invitations';
12
-
13
12
  export const performInvitation = async <T>(host: InvitationsHandler<T>, guest: InvitationsHandler<T>, context: T) => {
14
13
  const done1 = new Trigger<Invitation>(); // peer 1 connected.
15
14
  const done2 = new Trigger<Invitation>(); // peer 2 connected.
@@ -1,162 +1,180 @@
1
1
  //
2
- // Copyright 2022 DXOS.org
2
+ // Copyright 2020 DXOS.org
3
3
  //
4
4
 
5
- import { Config } from '@dxos/config';
6
- import { createCredentialSignerWithChain, CredentialGenerator } from '@dxos/credentials';
7
- import {
8
- SnapshotStore,
9
- DataPipelineControllerImpl,
10
- MetadataStore,
11
- SigningContext,
12
- SpaceManager,
13
- valueEncoding
14
- } from '@dxos/echo-pipeline';
15
- import { testLocalDatabase } from '@dxos/echo-pipeline/testing';
16
- import { FeedFactory, FeedStore } from '@dxos/feed-store';
17
- import { Keyring } from '@dxos/keyring';
18
- import { MemorySignalManager, MemorySignalManagerContext } from '@dxos/messaging';
19
- import { MemoryTransportFactory, NetworkManager } from '@dxos/network-manager';
20
- import { createStorage, Storage, StorageType } from '@dxos/random-access-storage';
21
-
22
- import { createDefaultModelFactory, ClientServicesHost, ServiceContext } from '../services';
5
+ import assert from 'node:assert';
23
6
 
24
- //
25
- // TODO(burdon): Replace with test builder.
26
- //
27
-
28
- export const createServiceHost = (config: Config, signalManagerContext: MemorySignalManagerContext) => {
29
- const networkManager = new NetworkManager({
30
- signalManager: new MemorySignalManager(signalManagerContext),
31
- transportFactory: MemoryTransportFactory
32
- });
7
+ import { asyncTimeout, Trigger } from '@dxos/async';
8
+ import { Client, ClientServices, ClientServicesProxy, createDefaultModelFactory, Invitation } from '@dxos/client';
9
+ import { Config } from '@dxos/config';
10
+ import { raise } from '@dxos/debug';
11
+ import { DocumentModel } from '@dxos/document-model';
12
+ import { DatabaseBackendProxy, genesisMutation } from '@dxos/echo-db';
13
+ import { PublicKey } from '@dxos/keys';
14
+ import { log } from '@dxos/log';
15
+ import { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';
16
+ import { createWebRTCTransportFactory, MemoryTransportFactory, NetworkManager } from '@dxos/network-manager';
17
+ import { Storage } from '@dxos/random-access-storage';
18
+ import { createLinkedPorts, createProtoRpcPeer, ProtoRpcPeer } from '@dxos/rpc';
19
+
20
+ import { ClientServicesHost, LocalClientServices } from '../services';
21
+
22
+ export const testConfigWithLocalSignal = new Config({
23
+ version: 1,
24
+ runtime: {
25
+ services: {
26
+ signal: {
27
+ // TODO(burdon): Port numbers and global consts?
28
+ server: 'ws://localhost:4000/.well-known/dx/signal'
29
+ }
30
+ }
31
+ }
32
+ });
33
33
 
34
- return new ClientServicesHost({
35
- config,
36
- networkManager
37
- });
38
- };
34
+ /**
35
+ * Client builder supports different configurations, incl. signaling, transports, storage.
36
+ */
37
+ export class TestBuilder {
38
+ private readonly _config: Config;
39
39
 
40
- export const createServiceContext = ({
41
- signalContext = new MemorySignalManagerContext(),
42
- storage = createStorage({ type: StorageType.RAM })
43
- }: {
44
- signalContext?: MemorySignalManagerContext;
45
- storage?: Storage;
46
- } = {}) => {
47
- const networkManager = new NetworkManager({
48
- signalManager: new MemorySignalManager(signalContext),
49
- transportFactory: MemoryTransportFactory
50
- });
51
-
52
- const modelFactory = createDefaultModelFactory();
53
- return new ServiceContext(storage, networkManager, modelFactory);
54
- };
40
+ public storage?: Storage;
55
41
 
56
- export const createPeers = async (numPeers: number) => {
57
- const signalContext = new MemorySignalManagerContext();
42
+ // prettier-ignore
43
+ constructor (
44
+ config?: Config,
45
+ private readonly _modelFactory = createDefaultModelFactory(),
46
+ private readonly _signalManagerContext = new MemorySignalManagerContext()
47
+ ) {
48
+ this._config = config ?? new Config();
49
+ }
58
50
 
59
- return await Promise.all(
60
- Array.from(Array(numPeers)).map(async () => {
61
- const peer = createServiceContext({ signalContext });
62
- await peer.open();
63
- return peer;
64
- })
65
- );
66
- };
51
+ get config(): Config {
52
+ return this._config;
53
+ }
67
54
 
68
- export const createIdentity = async (peer: ServiceContext) => {
69
- await peer.createIdentity();
70
- return peer;
71
- };
55
+ /**
56
+ * Get network manager using local shared memory or remote signal manager.
57
+ */
58
+ get networkManager() {
59
+ const signalServer = this._config.get('runtime.services.signal.server');
60
+ if (signalServer) {
61
+ return new NetworkManager({
62
+ log: true,
63
+ signalManager: new WebsocketSignalManager([signalServer]),
64
+ transportFactory: createWebRTCTransportFactory({
65
+ iceServers: this._config.get('runtime.services.ice')
66
+ })
67
+ });
68
+ }
69
+
70
+ // Memory transport with shared context.
71
+ return new NetworkManager({
72
+ log: true,
73
+ signalManager: new MemorySignalManager(this._signalManagerContext),
74
+ transportFactory: MemoryTransportFactory
75
+ });
76
+ }
72
77
 
73
- // TODO(burdon): Remove @dxos/client-testing.
74
- // TODO(burdon): Create builder and make configurable.
75
- export const syncItems = async (db1: DataPipelineControllerImpl, db2: DataPipelineControllerImpl) => {
76
- await testLocalDatabase(db1, db2);
77
- await testLocalDatabase(db2, db1);
78
- };
78
+ /**
79
+ * Create backend service handlers.
80
+ */
81
+ createClientServicesHost() {
82
+ return new ClientServicesHost({
83
+ config: this._config,
84
+ modelFactory: this._modelFactory,
85
+ networkManager: this.networkManager,
86
+ storage: this.storage
87
+ });
88
+ }
79
89
 
80
- export class TestBuilder {
81
- public readonly signalContext = new MemorySignalManagerContext();
90
+ /**
91
+ * Create local services host.
92
+ */
93
+ createLocal() {
94
+ return new LocalClientServices({
95
+ config: this._config,
96
+ modelFactory: this._modelFactory,
97
+ networkManager: this.networkManager,
98
+ storage: this.storage
99
+ });
100
+ }
82
101
 
83
- createPeer(): TestPeer {
84
- return new TestPeer(this.signalContext);
102
+ /**
103
+ * Create client/server.
104
+ */
105
+ createClientServer(host: ClientServicesHost = this.createClientServicesHost()): [Client, ProtoRpcPeer<{}>] {
106
+ const [proxyPort, hostPort] = createLinkedPorts();
107
+ const server = createProtoRpcPeer({
108
+ exposed: host.descriptors,
109
+ handlers: host.services as ClientServices,
110
+ port: hostPort
111
+ });
112
+ // TODO(dmaretskyi): Refactor.
113
+
114
+ const client = new Client({ services: new ClientServicesProxy(proxyPort) });
115
+ return [client, server];
85
116
  }
86
117
  }
87
118
 
88
- export type TestPeerProps = {
89
- storage?: Storage;
90
- feedStore?: FeedStore<any>;
91
- metadataStore?: MetadataStore;
92
- keyring?: Keyring;
93
- networkManager?: NetworkManager;
94
- spaceManager?: SpaceManager;
95
- snapshotStore?: SnapshotStore;
96
- };
97
-
98
- export class TestPeer {
99
- private _props: TestPeerProps = {};
100
-
101
- constructor(private readonly signalContext: MemorySignalManagerContext) {}
119
+ export const testSpace = async (create: DatabaseBackendProxy, check: DatabaseBackendProxy = create) => {
120
+ const objectId = PublicKey.random().toHex();
102
121
 
103
- get storage() {
104
- return (this._props.storage ??= createStorage({ type: StorageType.RAM }));
105
- }
122
+ const result = create.mutate(genesisMutation(objectId, DocumentModel.meta.type));
106
123
 
107
- get keyring() {
108
- return (this._props.keyring ??= new Keyring(this.storage.createDirectory('keyring')));
109
- }
124
+ await result.batch.getReceipt();
125
+ // TODO(dmaretskiy): await result.waitToBeProcessed()
126
+ assert(create._itemManager.entities.has(result.objectsUpdated[0].id));
110
127
 
111
- get feedStore() {
112
- return (this._props.feedStore ??= new FeedStore({
113
- factory: new FeedFactory({
114
- root: this.storage.createDirectory('feeds'),
115
- signer: this.keyring,
116
- hypercore: {
117
- valueEncoding
118
- }
119
- })
120
- }));
121
- }
128
+ await asyncTimeout(
129
+ check.itemUpdate.waitForCondition(() => check._itemManager.entities.has(objectId)),
130
+ 1000
131
+ );
122
132
 
123
- get metadataStore() {
124
- return (this._props.metadataStore ??= new MetadataStore(this.storage.createDirectory('metadata')));
125
- }
133
+ return result;
134
+ };
126
135
 
127
- get snapshotStore() {
128
- return (this._props.snapshotStore ??= new SnapshotStore(this.storage.createDirectory('snapshots')));
129
- }
136
+ export const syncItems = async (db1: DatabaseBackendProxy, db2: DatabaseBackendProxy) => {
137
+ // Check item replicated from 1 => 2.
138
+ await testSpace(db1, db2);
130
139
 
131
- get networkManager() {
132
- return (this._props.networkManager ??= new NetworkManager({
133
- signalManager: new MemorySignalManager(this.signalContext),
134
- transportFactory: MemoryTransportFactory
135
- }));
136
- }
140
+ // Check item replicated from 2 => 1.
141
+ await testSpace(db2, db1);
142
+ };
137
143
 
138
- get spaceManager() {
139
- return (this._props.spaceManager ??= new SpaceManager({
140
- feedStore: this.feedStore,
141
- networkManager: this.networkManager
142
- }));
143
- }
144
- }
144
+ export const joinCommonSpace = async ([initialPeer, ...peers]: Client[], spaceKey?: PublicKey): Promise<PublicKey> => {
145
+ const rootSpace = spaceKey ? initialPeer.echo.getSpace(spaceKey) : await initialPeer.echo.createSpace();
146
+ assert(rootSpace, 'Space not found.');
147
+
148
+ await Promise.all(
149
+ peers.map(async (peer) => {
150
+ const hostDone = new Trigger<Invitation>();
151
+ const guestDone = new Trigger<Invitation>();
152
+
153
+ const hostObservabli = rootSpace.createInvitation({ type: Invitation.Type.INTERACTIVE_TESTING });
154
+ log('invitation created');
155
+ hostObservabli.subscribe({
156
+ onConnecting: (invitation) => {
157
+ const guestObservable = peer.echo.acceptInvitation(invitation);
158
+ log('invitation accepted');
159
+
160
+ guestObservable.subscribe({
161
+ onSuccess: (invitation: Invitation) => {
162
+ guestDone.wake(invitation);
163
+ log('invitation guestDone');
164
+ },
165
+ onError: (err: Error) => raise(err)
166
+ });
167
+ },
168
+ onSuccess: (invitation) => {
169
+ hostDone.wake(invitation);
170
+ log('invitation hostDone');
171
+ },
172
+ onError: (err) => raise(err)
173
+ });
174
+
175
+ await Promise.all([hostDone.wait(), guestDone.wait()]);
176
+ })
177
+ );
145
178
 
146
- export const createSigningContext = async (keyring: Keyring): Promise<SigningContext> => {
147
- const identityKey = await keyring.createKey();
148
- const deviceKey = await keyring.createKey();
149
-
150
- return {
151
- identityKey,
152
- deviceKey,
153
- credentialSigner: createCredentialSignerWithChain(
154
- keyring,
155
- {
156
- credential: await new CredentialGenerator(keyring, identityKey, deviceKey).createDeviceAuthorization(deviceKey)
157
- },
158
- deviceKey
159
- ),
160
- recordCredential: async () => {} // No-op.
161
- };
179
+ return rootSpace.key;
162
180
  };