@dxos/echo-pipeline 0.6.12 → 0.6.13-main.548ca8d
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-PESZVYAN.mjs +2050 -0
- package/dist/lib/browser/chunk-PESZVYAN.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +3463 -17
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +3 -4
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-7HHYCGUR.cjs → chunk-6EZVIJNE.cjs} +89 -47
- package/dist/lib/node/chunk-6EZVIJNE.cjs.map +7 -0
- package/dist/lib/node/index.cjs +3440 -35
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +11 -12
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/lib/{browser/chunk-UKXIJW43.mjs → node-esm/chunk-4LW7MDPZ.mjs} +76 -36
- package/dist/lib/node-esm/chunk-4LW7MDPZ.mjs.map +7 -0
- package/dist/lib/{browser/chunk-MPWFDDQK.mjs → node-esm/index.mjs} +1702 -335
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/testing/index.mjs +551 -0
- package/dist/lib/node-esm/testing/index.mjs.map +7 -0
- package/dist/types/src/automerge/automerge-host.d.ts +24 -1
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/automerge/collection-synchronizer.d.ts +2 -0
- package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-replicator.d.ts +3 -3
- package/dist/types/src/automerge/echo-replicator.d.ts.map +1 -1
- package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts +3 -3
- package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts.map +1 -1
- package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +1 -1
- package/dist/types/src/automerge/space-collection.d.ts +3 -2
- package/dist/types/src/automerge/space-collection.d.ts.map +1 -1
- package/dist/types/src/db-host/automerge-metrics.d.ts +11 -0
- package/dist/types/src/db-host/automerge-metrics.d.ts.map +1 -0
- package/dist/types/src/db-host/data-service.d.ts +3 -2
- package/dist/types/src/db-host/data-service.d.ts.map +1 -1
- package/dist/types/src/db-host/database-root.d.ts +20 -0
- package/dist/types/src/db-host/database-root.d.ts.map +1 -0
- package/dist/types/src/db-host/documents-iterator.d.ts +7 -0
- package/dist/types/src/db-host/documents-iterator.d.ts.map +1 -0
- package/dist/types/src/db-host/echo-host.d.ts +73 -0
- package/dist/types/src/db-host/echo-host.d.ts.map +1 -0
- package/dist/types/src/db-host/index.d.ts +5 -0
- package/dist/types/src/db-host/index.d.ts.map +1 -1
- package/dist/types/src/db-host/migration.d.ts +8 -0
- package/dist/types/src/db-host/migration.d.ts.map +1 -0
- package/dist/types/src/db-host/query-service.d.ts +25 -0
- package/dist/types/src/db-host/query-service.d.ts.map +1 -0
- package/dist/types/src/db-host/query-state.d.ts +41 -0
- package/dist/types/src/db-host/query-state.d.ts.map +1 -0
- package/dist/types/src/db-host/space-state-manager.d.ts +23 -0
- package/dist/types/src/db-host/space-state-manager.d.ts.map +1 -0
- package/dist/types/src/edge/echo-edge-replicator.d.ts +23 -0
- package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -0
- package/dist/types/src/edge/echo-edge-replicator.test.d.ts +2 -0
- package/dist/types/src/edge/echo-edge-replicator.test.d.ts.map +1 -0
- package/dist/types/src/edge/index.d.ts +2 -0
- package/dist/types/src/edge/index.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/metadata/metadata-store.d.ts +4 -1
- package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
- package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
- package/dist/types/src/testing/test-replicator.d.ts +4 -4
- package/dist/types/src/testing/test-replicator.d.ts.map +1 -1
- package/package.json +40 -50
- package/src/automerge/automerge-host.test.ts +8 -9
- package/src/automerge/automerge-host.ts +46 -7
- package/src/automerge/automerge-repo.test.ts +18 -16
- package/src/automerge/collection-synchronizer.test.ts +10 -5
- package/src/automerge/collection-synchronizer.ts +17 -6
- package/src/automerge/echo-data-monitor.test.ts +1 -3
- package/src/automerge/echo-network-adapter.test.ts +4 -3
- package/src/automerge/echo-network-adapter.ts +5 -4
- package/src/automerge/echo-replicator.ts +3 -3
- package/src/automerge/mesh-echo-replicator-connection.ts +10 -9
- package/src/automerge/mesh-echo-replicator.ts +2 -1
- package/src/automerge/space-collection.ts +3 -2
- package/src/automerge/storage-adapter.test.ts +2 -3
- package/src/db-host/automerge-metrics.ts +38 -0
- package/src/db-host/data-service.ts +29 -14
- package/src/db-host/database-root.ts +86 -0
- package/src/db-host/documents-iterator.ts +73 -0
- package/src/db-host/documents-synchronizer.test.ts +2 -2
- package/src/db-host/echo-host.ts +257 -0
- package/src/db-host/index.ts +6 -1
- package/src/db-host/migration.ts +57 -0
- package/src/db-host/query-service.ts +208 -0
- package/src/db-host/query-state.ts +200 -0
- package/src/db-host/space-state-manager.ts +90 -0
- package/src/edge/echo-edge-replicator.test.ts +96 -0
- package/src/edge/echo-edge-replicator.ts +337 -0
- package/src/edge/index.ts +5 -0
- package/src/index.ts +1 -0
- package/src/metadata/metadata-store.ts +20 -0
- package/src/pipeline/pipeline-stress.test.ts +44 -47
- package/src/pipeline/pipeline.test.ts +3 -4
- package/src/space/control-pipeline.test.ts +2 -3
- package/src/space/control-pipeline.ts +10 -1
- package/src/space/replication.browser.test.ts +2 -8
- package/src/space/space-manager.browser.test.ts +6 -5
- package/src/space/space-protocol.browser.test.ts +29 -34
- package/src/space/space-protocol.test.ts +29 -27
- package/src/space/space.test.ts +28 -11
- package/src/testing/test-agent-builder.ts +2 -2
- package/src/testing/test-replicator.ts +3 -3
- package/dist/lib/browser/chunk-MPWFDDQK.mjs.map +0 -7
- package/dist/lib/browser/chunk-UKXIJW43.mjs.map +0 -7
- package/dist/lib/browser/chunk-XPCF2V5U.mjs +0 -31
- package/dist/lib/browser/chunk-XPCF2V5U.mjs.map +0 -7
- package/dist/lib/browser/light.mjs +0 -32
- package/dist/lib/browser/light.mjs.map +0 -7
- package/dist/lib/node/chunk-5DH4KR2S.cjs +0 -2148
- package/dist/lib/node/chunk-5DH4KR2S.cjs.map +0 -7
- package/dist/lib/node/chunk-7HHYCGUR.cjs.map +0 -7
- package/dist/lib/node/chunk-DZVH7HDD.cjs +0 -43
- package/dist/lib/node/chunk-DZVH7HDD.cjs.map +0 -7
- package/dist/lib/node/light.cjs +0 -52
- package/dist/lib/node/light.cjs.map +0 -7
- package/dist/types/src/light.d.ts +0 -4
- package/dist/types/src/light.d.ts.map +0 -1
- package/src/light.ts +0 -7
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
MOCK_AUTH_PROVIDER,
|
|
4
|
+
MOCK_AUTH_VERIFIER,
|
|
5
|
+
MetadataStore,
|
|
6
|
+
SpaceManager,
|
|
7
|
+
SpaceProtocol,
|
|
8
|
+
valueEncoding
|
|
9
|
+
} from "../chunk-4LW7MDPZ.mjs";
|
|
10
|
+
|
|
11
|
+
// packages/core/echo/echo-pipeline/src/testing/change-metadata.ts
|
|
12
|
+
import { log } from "@dxos/log";
|
|
13
|
+
import { schema } from "@dxos/protocols/proto";
|
|
14
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/testing/change-metadata.ts";
|
|
15
|
+
var EchoMetadata = schema.getCodecForType("dxos.echo.metadata.EchoMetadata");
|
|
16
|
+
var changeStorageVersionInMetadata = async (storage, version) => {
|
|
17
|
+
log.info("Changing storage version in metadata. USE ONLY FOR TESTING.", void 0, {
|
|
18
|
+
F: __dxlog_file,
|
|
19
|
+
L: 19,
|
|
20
|
+
S: void 0,
|
|
21
|
+
C: (f, a) => f(...a)
|
|
22
|
+
});
|
|
23
|
+
const metadata = new MetadataStore(storage.createDirectory("metadata"));
|
|
24
|
+
await metadata.load();
|
|
25
|
+
const echoMetadata = metadata.metadata;
|
|
26
|
+
echoMetadata.version = version;
|
|
27
|
+
const file = metadata._directory.getOrCreateFile("EchoMetadata");
|
|
28
|
+
await metadata._writeFile(file, EchoMetadata, echoMetadata);
|
|
29
|
+
await metadata._directory.flush();
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// packages/core/echo/echo-pipeline/src/testing/test-agent-builder.ts
|
|
33
|
+
import { Context } from "@dxos/context";
|
|
34
|
+
import { CredentialGenerator } from "@dxos/credentials";
|
|
35
|
+
import { PublicKey } from "@dxos/keys";
|
|
36
|
+
import { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from "@dxos/messaging";
|
|
37
|
+
import { MemoryTransportFactory, SwarmNetworkManager, createRtcTransportFactory } from "@dxos/network-manager";
|
|
38
|
+
import { AdmittedFeed } from "@dxos/protocols/proto/dxos/halo/credentials";
|
|
39
|
+
import { StorageType, createStorage } from "@dxos/random-access-storage";
|
|
40
|
+
import { Gossip, Presence } from "@dxos/teleport-extension-gossip";
|
|
41
|
+
import { BlobStore } from "@dxos/teleport-extension-object-sync";
|
|
42
|
+
import { ComplexMap } from "@dxos/util";
|
|
43
|
+
|
|
44
|
+
// packages/core/echo/echo-pipeline/src/testing/test-feed-builder.ts
|
|
45
|
+
import { TestBuilder } from "@dxos/feed-store/testing";
|
|
46
|
+
var TestFeedBuilder = class extends TestBuilder {
|
|
47
|
+
constructor() {
|
|
48
|
+
super({
|
|
49
|
+
valueEncoding
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// packages/core/echo/echo-pipeline/src/testing/test-agent-builder.ts
|
|
55
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/testing/test-agent-builder.ts";
|
|
56
|
+
var MemoryNetworkManagerProvider = (signalContext) => () => new SwarmNetworkManager({
|
|
57
|
+
signalManager: new MemorySignalManager(signalContext),
|
|
58
|
+
transportFactory: MemoryTransportFactory
|
|
59
|
+
});
|
|
60
|
+
var WebsocketNetworkManagerProvider = (signalUrl) => () => new SwarmNetworkManager({
|
|
61
|
+
signalManager: new WebsocketSignalManager([
|
|
62
|
+
{
|
|
63
|
+
server: signalUrl
|
|
64
|
+
}
|
|
65
|
+
]),
|
|
66
|
+
transportFactory: createRtcTransportFactory()
|
|
67
|
+
});
|
|
68
|
+
var TestAgentBuilder = class {
|
|
69
|
+
constructor({ storage, networkManagerProvider } = {}) {
|
|
70
|
+
this._agents = new ComplexMap(PublicKey.hash);
|
|
71
|
+
this._storage = storage ?? createStorage({
|
|
72
|
+
type: StorageType.RAM
|
|
73
|
+
});
|
|
74
|
+
this._networkManagerProvider = networkManagerProvider ?? MemoryNetworkManagerProvider(new MemorySignalManagerContext());
|
|
75
|
+
}
|
|
76
|
+
async close() {
|
|
77
|
+
return Promise.all(this.agents.map((agent) => agent.close()));
|
|
78
|
+
}
|
|
79
|
+
get agents() {
|
|
80
|
+
return Array.from(this._agents.values());
|
|
81
|
+
}
|
|
82
|
+
getAgent(deviceKey) {
|
|
83
|
+
return this._agents.get(deviceKey);
|
|
84
|
+
}
|
|
85
|
+
async createPeer() {
|
|
86
|
+
const feedBuilder = new TestFeedBuilder().setStorage(this._storage, `agent-${this._agents.size}`);
|
|
87
|
+
const identityKey = await feedBuilder.keyring.createKey();
|
|
88
|
+
const deviceKey = await feedBuilder.keyring.createKey();
|
|
89
|
+
const agent = new TestAgent(this._networkManagerProvider, feedBuilder, identityKey, deviceKey);
|
|
90
|
+
this._agents.set(deviceKey, agent);
|
|
91
|
+
return agent;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
var TestAgent = class {
|
|
95
|
+
get metadataStore() {
|
|
96
|
+
return this._metadataStore ??= new MetadataStore(this.storage.createDirectory("metadata"));
|
|
97
|
+
}
|
|
98
|
+
get blobStore() {
|
|
99
|
+
return this._blobStore ??= new BlobStore(this.storage.createDirectory("blobs"));
|
|
100
|
+
}
|
|
101
|
+
constructor(_networkManagerProvider, _feedBuilder, identityKey, deviceKey) {
|
|
102
|
+
this._networkManagerProvider = _networkManagerProvider;
|
|
103
|
+
this._feedBuilder = _feedBuilder;
|
|
104
|
+
this.identityKey = identityKey;
|
|
105
|
+
this.deviceKey = deviceKey;
|
|
106
|
+
this._spaces = new ComplexMap(PublicKey.hash);
|
|
107
|
+
this.storage = this._feedBuilder.storage;
|
|
108
|
+
this.keyring = this._feedBuilder.keyring;
|
|
109
|
+
this.feedStore = this._feedBuilder.createFeedStore();
|
|
110
|
+
}
|
|
111
|
+
async close() {
|
|
112
|
+
return Promise.all([
|
|
113
|
+
...this.spaces.map((space) => space.close())
|
|
114
|
+
]);
|
|
115
|
+
}
|
|
116
|
+
get spaces() {
|
|
117
|
+
return Array.from(this._spaces.values());
|
|
118
|
+
}
|
|
119
|
+
getSpace(spaceKey) {
|
|
120
|
+
return this._spaces.get(spaceKey);
|
|
121
|
+
}
|
|
122
|
+
get spaceManager() {
|
|
123
|
+
return this._spaceManager ??= new SpaceManager({
|
|
124
|
+
feedStore: this.feedStore,
|
|
125
|
+
networkManager: this._networkManagerProvider(),
|
|
126
|
+
metadataStore: this.metadataStore,
|
|
127
|
+
blobStore: this.blobStore
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
async createSpace(identityKey = this.identityKey, spaceKey, genesisKey, dataKey, saveMetadata = false) {
|
|
131
|
+
if (!spaceKey) {
|
|
132
|
+
saveMetadata = true;
|
|
133
|
+
spaceKey = await this.keyring.createKey();
|
|
134
|
+
}
|
|
135
|
+
if (!genesisKey) {
|
|
136
|
+
genesisKey = await this.keyring.createKey();
|
|
137
|
+
}
|
|
138
|
+
const controlFeed = await this.feedStore.openFeed(genesisKey, {
|
|
139
|
+
writable: true
|
|
140
|
+
});
|
|
141
|
+
const dataFeed = await this.feedStore.openFeed(dataKey ?? await this.keyring.createKey(), {
|
|
142
|
+
writable: true,
|
|
143
|
+
sparse: true
|
|
144
|
+
});
|
|
145
|
+
const metadata = {
|
|
146
|
+
key: spaceKey,
|
|
147
|
+
genesisFeedKey: genesisKey,
|
|
148
|
+
controlFeedKey: controlFeed.key,
|
|
149
|
+
dataFeedKey: dataFeed.key
|
|
150
|
+
};
|
|
151
|
+
if (saveMetadata) {
|
|
152
|
+
await this.metadataStore.addSpace(metadata);
|
|
153
|
+
}
|
|
154
|
+
await this.spaceManager.open();
|
|
155
|
+
const space = await this.spaceManager.constructSpace({
|
|
156
|
+
metadata,
|
|
157
|
+
swarmIdentity: {
|
|
158
|
+
identityKey: this.identityKey,
|
|
159
|
+
peerKey: this.deviceKey,
|
|
160
|
+
credentialProvider: MOCK_AUTH_PROVIDER,
|
|
161
|
+
credentialAuthenticator: MOCK_AUTH_VERIFIER
|
|
162
|
+
},
|
|
163
|
+
memberKey: identityKey,
|
|
164
|
+
onAuthorizedConnection: (session) => {
|
|
165
|
+
session.addExtension("dxos.mesh.teleport.gossip", this.createGossip().createExtension({
|
|
166
|
+
remotePeerId: session.remotePeerId
|
|
167
|
+
}));
|
|
168
|
+
},
|
|
169
|
+
onDelegatedInvitationStatusChange: async () => {
|
|
170
|
+
},
|
|
171
|
+
onMemberRolesChanged: async () => {
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
await space.setControlFeed(controlFeed);
|
|
175
|
+
await space.setDataFeed(dataFeed);
|
|
176
|
+
await space.open(new Context(void 0, {
|
|
177
|
+
F: __dxlog_file2,
|
|
178
|
+
L: 193
|
|
179
|
+
}));
|
|
180
|
+
this._spaces.set(spaceKey, space);
|
|
181
|
+
return space;
|
|
182
|
+
}
|
|
183
|
+
createSpaceProtocol(topic, gossip) {
|
|
184
|
+
return new SpaceProtocol({
|
|
185
|
+
topic,
|
|
186
|
+
swarmIdentity: {
|
|
187
|
+
identityKey: this.identityKey,
|
|
188
|
+
peerKey: this.deviceKey,
|
|
189
|
+
credentialProvider: MOCK_AUTH_PROVIDER,
|
|
190
|
+
credentialAuthenticator: MOCK_AUTH_VERIFIER
|
|
191
|
+
},
|
|
192
|
+
networkManager: this._networkManagerProvider(),
|
|
193
|
+
blobStore: this.blobStore,
|
|
194
|
+
onSessionAuth: (session) => {
|
|
195
|
+
session.addExtension("dxos.mesh.teleport.gossip", (gossip ?? this.createGossip()).createExtension({
|
|
196
|
+
remotePeerId: session.remotePeerId
|
|
197
|
+
}));
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
createGossip() {
|
|
202
|
+
return new Gossip({
|
|
203
|
+
localPeerId: this.deviceKey
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
createPresence(gossip) {
|
|
207
|
+
return new Presence({
|
|
208
|
+
announceInterval: 30,
|
|
209
|
+
offlineTimeout: 200,
|
|
210
|
+
identityKey: this.identityKey,
|
|
211
|
+
gossip: gossip ?? this.createGossip()
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
async spaceGenesis(space) {
|
|
215
|
+
const generator = new CredentialGenerator(this.keyring, this.identityKey, this.deviceKey);
|
|
216
|
+
const credentials = [
|
|
217
|
+
...await generator.createSpaceGenesis(space.key, space.controlFeedKey),
|
|
218
|
+
await generator.createFeedAdmission(space.key, space.dataFeedKey, AdmittedFeed.Designation.DATA),
|
|
219
|
+
await generator.createEpochCredential(space.key)
|
|
220
|
+
];
|
|
221
|
+
for (const credential of credentials) {
|
|
222
|
+
await space.controlPipeline.writer.write({
|
|
223
|
+
credential: {
|
|
224
|
+
credential
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// packages/core/echo/echo-pipeline/src/testing/test-network-adapter.ts
|
|
232
|
+
import { Trigger, sleep } from "@dxos/async";
|
|
233
|
+
import { NetworkAdapter } from "@dxos/automerge/automerge-repo";
|
|
234
|
+
import { invariant } from "@dxos/invariant";
|
|
235
|
+
import { log as log2 } from "@dxos/log";
|
|
236
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/testing/test-network-adapter.ts";
|
|
237
|
+
var TestAdapter = class _TestAdapter extends NetworkAdapter {
|
|
238
|
+
static createPair(connectionStateProvider = () => "on") {
|
|
239
|
+
const adapter1 = new _TestAdapter({
|
|
240
|
+
send: (message) => connectionStateProvider() === "on" && sleep(10).then(() => adapter2.receive(message))
|
|
241
|
+
});
|
|
242
|
+
const adapter2 = new _TestAdapter({
|
|
243
|
+
send: (message) => connectionStateProvider() === "on" && sleep(10).then(() => adapter1.receive(message))
|
|
244
|
+
});
|
|
245
|
+
return [
|
|
246
|
+
adapter1,
|
|
247
|
+
adapter2
|
|
248
|
+
];
|
|
249
|
+
}
|
|
250
|
+
constructor(_params) {
|
|
251
|
+
super();
|
|
252
|
+
this._params = _params;
|
|
253
|
+
this.onConnect = new Trigger();
|
|
254
|
+
}
|
|
255
|
+
// NOTE: Emitting `ready` event in NetworkAdapter`s constructor causes a race condition
|
|
256
|
+
// because `Repo` waits for `ready` event (which it never receives) before it starts using the adapter.
|
|
257
|
+
ready() {
|
|
258
|
+
this.emit("ready", {
|
|
259
|
+
network: this
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
connect(peerId) {
|
|
263
|
+
this.peerId = peerId;
|
|
264
|
+
this.onConnect.wake();
|
|
265
|
+
}
|
|
266
|
+
peerCandidate(peerId) {
|
|
267
|
+
invariant(peerId, "PeerId is required", {
|
|
268
|
+
F: __dxlog_file3,
|
|
269
|
+
L: 42,
|
|
270
|
+
S: this,
|
|
271
|
+
A: [
|
|
272
|
+
"peerId",
|
|
273
|
+
"'PeerId is required'"
|
|
274
|
+
]
|
|
275
|
+
});
|
|
276
|
+
this.emit("peer-candidate", {
|
|
277
|
+
peerId,
|
|
278
|
+
peerMetadata: {}
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
peerDisconnected(peerId) {
|
|
282
|
+
invariant(peerId, "PeerId is required", {
|
|
283
|
+
F: __dxlog_file3,
|
|
284
|
+
L: 47,
|
|
285
|
+
S: this,
|
|
286
|
+
A: [
|
|
287
|
+
"peerId",
|
|
288
|
+
"'PeerId is required'"
|
|
289
|
+
]
|
|
290
|
+
});
|
|
291
|
+
this.emit("peer-disconnected", {
|
|
292
|
+
peerId
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
send(message) {
|
|
296
|
+
log2("send", {
|
|
297
|
+
from: message.senderId,
|
|
298
|
+
to: message.targetId,
|
|
299
|
+
type: message.type
|
|
300
|
+
}, {
|
|
301
|
+
F: __dxlog_file3,
|
|
302
|
+
L: 52,
|
|
303
|
+
S: this,
|
|
304
|
+
C: (f, a) => f(...a)
|
|
305
|
+
});
|
|
306
|
+
this._params.send(message);
|
|
307
|
+
}
|
|
308
|
+
disconnect() {
|
|
309
|
+
this.peerId = void 0;
|
|
310
|
+
}
|
|
311
|
+
receive(message) {
|
|
312
|
+
invariant(this.peerId, "Peer id is not set", {
|
|
313
|
+
F: __dxlog_file3,
|
|
314
|
+
L: 61,
|
|
315
|
+
S: this,
|
|
316
|
+
A: [
|
|
317
|
+
"this.peerId",
|
|
318
|
+
"'Peer id is not set'"
|
|
319
|
+
]
|
|
320
|
+
});
|
|
321
|
+
this.emit("message", message);
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
// packages/core/echo/echo-pipeline/src/testing/test-replicator.ts
|
|
326
|
+
import { sleep as sleep2, synchronized } from "@dxos/async";
|
|
327
|
+
import { LifecycleState, Resource } from "@dxos/context";
|
|
328
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
329
|
+
import { log as log3 } from "@dxos/log";
|
|
330
|
+
import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
|
|
331
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
332
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
333
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
334
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
335
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
336
|
+
}
|
|
337
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/testing/test-replicator.ts";
|
|
338
|
+
var TestReplicationNetwork = class extends Resource {
|
|
339
|
+
constructor(options = {}) {
|
|
340
|
+
super();
|
|
341
|
+
this._replicators = /* @__PURE__ */ new Set();
|
|
342
|
+
this._latency = void 0;
|
|
343
|
+
this._latency = options.latency;
|
|
344
|
+
}
|
|
345
|
+
async _close(ctx) {
|
|
346
|
+
for (const replicator of this._replicators) {
|
|
347
|
+
for (const connection of replicator.connections) {
|
|
348
|
+
void connection.writable.abort();
|
|
349
|
+
void connection.readable.cancel();
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
async createReplicator() {
|
|
354
|
+
const replicator = new TestReplicator({
|
|
355
|
+
onConnect: async () => {
|
|
356
|
+
invariant2(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
357
|
+
F: __dxlog_file4,
|
|
358
|
+
L: 45,
|
|
359
|
+
S: this,
|
|
360
|
+
A: [
|
|
361
|
+
"this._lifecycleState === LifecycleState.OPEN",
|
|
362
|
+
""
|
|
363
|
+
]
|
|
364
|
+
});
|
|
365
|
+
await this._connectReplicator(replicator);
|
|
366
|
+
},
|
|
367
|
+
onDisconnect: async () => {
|
|
368
|
+
invariant2(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
369
|
+
F: __dxlog_file4,
|
|
370
|
+
L: 49,
|
|
371
|
+
S: this,
|
|
372
|
+
A: [
|
|
373
|
+
"this._lifecycleState === LifecycleState.OPEN",
|
|
374
|
+
""
|
|
375
|
+
]
|
|
376
|
+
});
|
|
377
|
+
await this._disconnectReplicator(replicator);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
this._replicators.add(replicator);
|
|
381
|
+
return replicator;
|
|
382
|
+
}
|
|
383
|
+
async _connectReplicator(replicator) {
|
|
384
|
+
for (const otherReplicator of this._replicators.values()) {
|
|
385
|
+
if (otherReplicator === replicator || !otherReplicator.connected) {
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
log3("create connection", {
|
|
389
|
+
from: replicator.context.peerId,
|
|
390
|
+
to: otherReplicator.context.peerId
|
|
391
|
+
}, {
|
|
392
|
+
F: __dxlog_file4,
|
|
393
|
+
L: 63,
|
|
394
|
+
S: this,
|
|
395
|
+
C: (f, a) => f(...a)
|
|
396
|
+
});
|
|
397
|
+
const [connection1, connection2] = this._createConnectionPair(replicator.context.peerId, otherReplicator.context.peerId);
|
|
398
|
+
await replicator.context.onConnectionOpen(connection1);
|
|
399
|
+
await otherReplicator.context.onConnectionOpen(connection2);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
async _disconnectReplicator(replicator) {
|
|
403
|
+
for (const connection of replicator.connections) {
|
|
404
|
+
await replicator.context.onConnectionClosed(connection);
|
|
405
|
+
await connection.otherSide.owningReplicator.removeConnection(connection.otherSide);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
_createConnectionPair(peer1, peer2) {
|
|
409
|
+
const LOG = false;
|
|
410
|
+
const forward = new TransformStream({
|
|
411
|
+
transform: async (message, controller) => {
|
|
412
|
+
if (LOG) {
|
|
413
|
+
log3.info("replicate", {
|
|
414
|
+
from: peer1,
|
|
415
|
+
to: peer2,
|
|
416
|
+
message
|
|
417
|
+
}, {
|
|
418
|
+
F: __dxlog_file4,
|
|
419
|
+
L: 86,
|
|
420
|
+
S: this,
|
|
421
|
+
C: (f, a) => f(...a)
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
if (this._latency !== void 0) {
|
|
425
|
+
await sleep2(this._latency);
|
|
426
|
+
}
|
|
427
|
+
controller.enqueue(message);
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
const backwards = new TransformStream({
|
|
431
|
+
transform: async (message, controller) => {
|
|
432
|
+
if (LOG) {
|
|
433
|
+
log3.info("replicate", {
|
|
434
|
+
from: peer2,
|
|
435
|
+
to: peer1,
|
|
436
|
+
message
|
|
437
|
+
}, {
|
|
438
|
+
F: __dxlog_file4,
|
|
439
|
+
L: 99,
|
|
440
|
+
S: this,
|
|
441
|
+
C: (f, a) => f(...a)
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
if (this._latency !== void 0) {
|
|
445
|
+
await sleep2(this._latency);
|
|
446
|
+
}
|
|
447
|
+
controller.enqueue(message);
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
const connection1 = new TestReplicatorConnection(peer2, backwards.readable, forward.writable);
|
|
451
|
+
const connection2 = new TestReplicatorConnection(peer1, forward.readable, backwards.writable);
|
|
452
|
+
connection1.otherSide = connection2;
|
|
453
|
+
connection2.otherSide = connection1;
|
|
454
|
+
return [
|
|
455
|
+
connection1,
|
|
456
|
+
connection2
|
|
457
|
+
];
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
_ts_decorate([
|
|
461
|
+
synchronized
|
|
462
|
+
], TestReplicationNetwork.prototype, "_connectReplicator", null);
|
|
463
|
+
var TestReplicator = class {
|
|
464
|
+
constructor(_params) {
|
|
465
|
+
this._params = _params;
|
|
466
|
+
this.connected = false;
|
|
467
|
+
this.context = void 0;
|
|
468
|
+
this.connections = /* @__PURE__ */ new Set();
|
|
469
|
+
}
|
|
470
|
+
async connect(context) {
|
|
471
|
+
log3("connect", {
|
|
472
|
+
peerId: context.peerId
|
|
473
|
+
}, {
|
|
474
|
+
F: __dxlog_file4,
|
|
475
|
+
L: 131,
|
|
476
|
+
S: this,
|
|
477
|
+
C: (f, a) => f(...a)
|
|
478
|
+
});
|
|
479
|
+
this.context = context;
|
|
480
|
+
this.connected = true;
|
|
481
|
+
await this._params.onConnect();
|
|
482
|
+
}
|
|
483
|
+
async disconnect() {
|
|
484
|
+
log3("disconnect", {
|
|
485
|
+
peerId: this.context.peerId
|
|
486
|
+
}, {
|
|
487
|
+
F: __dxlog_file4,
|
|
488
|
+
L: 138,
|
|
489
|
+
S: this,
|
|
490
|
+
C: (f, a) => f(...a)
|
|
491
|
+
});
|
|
492
|
+
this.connected = false;
|
|
493
|
+
await this._params.onDisconnect();
|
|
494
|
+
}
|
|
495
|
+
async addConnection(connection) {
|
|
496
|
+
connection.owningReplicator = this;
|
|
497
|
+
this.connections.add(connection);
|
|
498
|
+
this.context.onConnectionOpen(connection);
|
|
499
|
+
}
|
|
500
|
+
async removeConnection(connection) {
|
|
501
|
+
connection.owningReplicator = void 0;
|
|
502
|
+
this.context.onConnectionClosed(connection);
|
|
503
|
+
this.connections.delete(connection);
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
var TestReplicatorConnection = class {
|
|
507
|
+
constructor(peerId, readable, writable) {
|
|
508
|
+
this.peerId = peerId;
|
|
509
|
+
this.readable = readable;
|
|
510
|
+
this.writable = writable;
|
|
511
|
+
this.otherSide = void 0;
|
|
512
|
+
this.owningReplicator = void 0;
|
|
513
|
+
}
|
|
514
|
+
async shouldAdvertise(params) {
|
|
515
|
+
return true;
|
|
516
|
+
}
|
|
517
|
+
shouldSyncCollection(params) {
|
|
518
|
+
return true;
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
var testAutomergeReplicatorFactory = (params) => {
|
|
522
|
+
return new AutomergeReplicator({
|
|
523
|
+
...params[0],
|
|
524
|
+
sendSyncRetryPolicy: {
|
|
525
|
+
retryBackoff: 20,
|
|
526
|
+
retriesBeforeBackoff: 2,
|
|
527
|
+
maxRetries: 3
|
|
528
|
+
}
|
|
529
|
+
}, params[1]);
|
|
530
|
+
};
|
|
531
|
+
var brokenAutomergeReplicatorFactory = (params) => {
|
|
532
|
+
params[1].onSyncMessage = () => {
|
|
533
|
+
throw new Error();
|
|
534
|
+
};
|
|
535
|
+
return testAutomergeReplicatorFactory(params);
|
|
536
|
+
};
|
|
537
|
+
export {
|
|
538
|
+
MemoryNetworkManagerProvider,
|
|
539
|
+
TestAdapter,
|
|
540
|
+
TestAgent,
|
|
541
|
+
TestAgentBuilder,
|
|
542
|
+
TestFeedBuilder,
|
|
543
|
+
TestReplicationNetwork,
|
|
544
|
+
TestReplicator,
|
|
545
|
+
TestReplicatorConnection,
|
|
546
|
+
WebsocketNetworkManagerProvider,
|
|
547
|
+
brokenAutomergeReplicatorFactory,
|
|
548
|
+
changeStorageVersionInMetadata,
|
|
549
|
+
testAutomergeReplicatorFactory
|
|
550
|
+
};
|
|
551
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/testing/change-metadata.ts", "../../../../src/testing/test-agent-builder.ts", "../../../../src/testing/test-feed-builder.ts", "../../../../src/testing/test-network-adapter.ts", "../../../../src/testing/test-replicator.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols/proto';\nimport type { Storage } from '@dxos/random-access-storage';\n\nimport { MetadataStore } from '../metadata';\n\nconst EchoMetadata = schema.getCodecForType('dxos.echo.metadata.EchoMetadata');\n\n/**\n * This function will change the storage version in the metadata.\n * This will break your storage and make it unusable.\n * Use this only for testing purposes.\n */\nexport const changeStorageVersionInMetadata = async (storage: Storage, version: number) => {\n log.info('Changing storage version in metadata. USE ONLY FOR TESTING.');\n const metadata = new MetadataStore(storage.createDirectory('metadata'));\n await metadata.load();\n const echoMetadata = metadata.metadata;\n echoMetadata.version = version;\n const file = metadata._directory.getOrCreateFile('EchoMetadata');\n await metadata._writeFile(file, EchoMetadata, echoMetadata);\n await metadata._directory.flush();\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Context } from '@dxos/context';\nimport { CredentialGenerator } from '@dxos/credentials';\nimport { type FeedStore } from '@dxos/feed-store';\nimport { type Keyring } from '@dxos/keyring';\nimport { PublicKey } from '@dxos/keys';\nimport { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';\nimport { MemoryTransportFactory, SwarmNetworkManager, createRtcTransportFactory } from '@dxos/network-manager';\nimport type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';\nimport { type SpaceMetadata } from '@dxos/protocols/proto/dxos/echo/metadata';\nimport { AdmittedFeed } from '@dxos/protocols/proto/dxos/halo/credentials';\nimport { StorageType, createStorage, type Storage } from '@dxos/random-access-storage';\nimport { Gossip, Presence } from '@dxos/teleport-extension-gossip';\nimport { BlobStore } from '@dxos/teleport-extension-object-sync';\nimport { ComplexMap } from '@dxos/util';\n\nimport { TestFeedBuilder } from './test-feed-builder';\nimport { MetadataStore } from '../metadata';\nimport { MOCK_AUTH_PROVIDER, MOCK_AUTH_VERIFIER, SpaceManager, SpaceProtocol, type Space } from '../space';\n\nexport type NetworkManagerProvider = () => SwarmNetworkManager;\n\nexport const MemoryNetworkManagerProvider =\n (signalContext: MemorySignalManagerContext): NetworkManagerProvider =>\n () =>\n new SwarmNetworkManager({\n signalManager: new MemorySignalManager(signalContext),\n transportFactory: MemoryTransportFactory,\n });\n\nexport const WebsocketNetworkManagerProvider =\n (signalUrl: string): NetworkManagerProvider =>\n () =>\n new SwarmNetworkManager({\n signalManager: new WebsocketSignalManager([{ server: signalUrl }]),\n transportFactory: createRtcTransportFactory(),\n });\n\nexport type TestAgentBuilderOptions = {\n storage?: Storage;\n networkManagerProvider?: NetworkManagerProvider;\n};\n\n/**\n * Factory for test agents.\n */\nexport class TestAgentBuilder {\n private readonly _agents = new ComplexMap<PublicKey, TestAgent>(PublicKey.hash);\n private readonly _storage: Storage;\n private readonly _networkManagerProvider: NetworkManagerProvider;\n\n constructor({ storage, networkManagerProvider }: TestAgentBuilderOptions = {}) {\n this._storage = storage ?? createStorage({ type: StorageType.RAM });\n this._networkManagerProvider =\n networkManagerProvider ?? MemoryNetworkManagerProvider(new MemorySignalManagerContext());\n }\n\n async close() {\n return Promise.all(this.agents.map((agent) => agent.close()));\n }\n\n get agents() {\n return Array.from(this._agents.values());\n }\n\n getAgent(deviceKey: PublicKey) {\n return this._agents.get(deviceKey);\n }\n\n async createPeer(): Promise<TestAgent> {\n // prettier-ignore\n const feedBuilder = new TestFeedBuilder()\n .setStorage(this._storage, `agent-${this._agents.size}`);\n\n const identityKey = await feedBuilder.keyring.createKey();\n const deviceKey = await feedBuilder.keyring.createKey();\n\n const agent = new TestAgent(this._networkManagerProvider, feedBuilder, identityKey, deviceKey);\n this._agents.set(deviceKey, agent);\n return agent;\n }\n}\n\n/**\n * Test agent that enables the creation and replication of multiple spaces.\n */\nexport class TestAgent {\n private readonly _spaces = new ComplexMap<PublicKey, Space>(PublicKey.hash);\n\n public readonly storage: Storage;\n public readonly keyring: Keyring;\n public readonly feedStore: FeedStore<FeedMessage>;\n\n private _metadataStore?: MetadataStore;\n get metadataStore() {\n return (this._metadataStore ??= new MetadataStore(this.storage.createDirectory('metadata')));\n }\n\n private _blobStore?: BlobStore;\n get blobStore() {\n return (this._blobStore ??= new BlobStore(this.storage.createDirectory('blobs')));\n }\n\n constructor(\n private readonly _networkManagerProvider: NetworkManagerProvider,\n private readonly _feedBuilder: TestFeedBuilder,\n public readonly identityKey: PublicKey,\n public readonly deviceKey: PublicKey,\n ) {\n this.storage = this._feedBuilder.storage;\n this.keyring = this._feedBuilder.keyring;\n this.feedStore = this._feedBuilder.createFeedStore();\n }\n\n async close() {\n return Promise.all([...this.spaces.map((space) => space.close())]);\n }\n\n get spaces() {\n return Array.from(this._spaces.values());\n }\n\n getSpace(spaceKey: PublicKey) {\n return this._spaces.get(spaceKey);\n }\n\n private _spaceManager?: SpaceManager;\n get spaceManager() {\n return (this._spaceManager ??= new SpaceManager({\n feedStore: this.feedStore,\n networkManager: this._networkManagerProvider(),\n metadataStore: this.metadataStore,\n blobStore: this.blobStore,\n }));\n }\n\n async createSpace(\n identityKey: PublicKey = this.identityKey,\n spaceKey?: PublicKey,\n genesisKey?: PublicKey,\n dataKey?: PublicKey,\n saveMetadata = false,\n ): Promise<Space> {\n if (!spaceKey) {\n saveMetadata = true;\n spaceKey = await this.keyring.createKey();\n }\n if (!genesisKey) {\n genesisKey = await this.keyring.createKey();\n }\n\n const controlFeed = await this.feedStore.openFeed(genesisKey, { writable: true });\n const dataFeed = await this.feedStore.openFeed(dataKey ?? (await this.keyring.createKey()), {\n writable: true,\n sparse: true,\n });\n\n const metadata: SpaceMetadata = {\n key: spaceKey,\n genesisFeedKey: genesisKey,\n controlFeedKey: controlFeed.key,\n dataFeedKey: dataFeed.key,\n };\n if (saveMetadata) {\n await this.metadataStore.addSpace(metadata);\n }\n\n await this.spaceManager.open();\n const space = await this.spaceManager.constructSpace({\n metadata,\n swarmIdentity: {\n identityKey: this.identityKey,\n peerKey: this.deviceKey,\n credentialProvider: MOCK_AUTH_PROVIDER,\n credentialAuthenticator: MOCK_AUTH_VERIFIER,\n },\n memberKey: identityKey,\n onAuthorizedConnection: (session) => {\n session.addExtension(\n 'dxos.mesh.teleport.gossip',\n this.createGossip().createExtension({ remotePeerId: session.remotePeerId }),\n );\n },\n onDelegatedInvitationStatusChange: async () => {},\n onMemberRolesChanged: async () => {},\n });\n await space.setControlFeed(controlFeed);\n await space.setDataFeed(dataFeed);\n\n await space.open(new Context());\n\n this._spaces.set(spaceKey, space);\n return space;\n }\n\n createSpaceProtocol(topic: PublicKey, gossip?: Gossip) {\n return new SpaceProtocol({\n topic,\n swarmIdentity: {\n identityKey: this.identityKey,\n peerKey: this.deviceKey,\n credentialProvider: MOCK_AUTH_PROVIDER,\n credentialAuthenticator: MOCK_AUTH_VERIFIER,\n },\n networkManager: this._networkManagerProvider(),\n blobStore: this.blobStore,\n onSessionAuth: (session) => {\n session.addExtension(\n 'dxos.mesh.teleport.gossip',\n (gossip ?? this.createGossip()).createExtension({ remotePeerId: session.remotePeerId }),\n );\n },\n });\n }\n\n createGossip() {\n return new Gossip({\n localPeerId: this.deviceKey,\n });\n }\n\n createPresence(gossip?: Gossip) {\n return new Presence({\n announceInterval: 30,\n offlineTimeout: 200,\n identityKey: this.identityKey,\n gossip: gossip ?? this.createGossip(),\n });\n }\n\n async spaceGenesis(space: Space) {\n const generator = new CredentialGenerator(this.keyring, this.identityKey, this.deviceKey);\n const credentials = [\n ...(await generator.createSpaceGenesis(space.key, space.controlFeedKey!)),\n await generator.createFeedAdmission(space.key, space.dataFeedKey!, AdmittedFeed.Designation.DATA),\n await generator.createEpochCredential(space.key),\n ];\n\n for (const credential of credentials) {\n await space.controlPipeline.writer.write({\n credential: { credential },\n });\n }\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { TestBuilder } from '@dxos/feed-store/testing';\nimport type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';\n\nimport { valueEncoding } from '../common';\n\n/**\n * Builder with default encoder and generator.\n */\nexport class TestFeedBuilder extends TestBuilder<FeedMessage> {\n constructor() {\n super({\n valueEncoding,\n });\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Trigger, sleep } from '@dxos/async';\nimport { type Message, NetworkAdapter, type PeerId } from '@dxos/automerge/automerge-repo';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nexport type TestConnectionStateProvider = () => 'on' | 'off';\n\nexport class TestAdapter extends NetworkAdapter {\n static createPair(connectionStateProvider: TestConnectionStateProvider = () => 'on') {\n const adapter1: TestAdapter = new TestAdapter({\n send: (message: Message) => connectionStateProvider() === 'on' && sleep(10).then(() => adapter2.receive(message)),\n });\n const adapter2: TestAdapter = new TestAdapter({\n send: (message: Message) => connectionStateProvider() === 'on' && sleep(10).then(() => adapter1.receive(message)),\n });\n\n return [adapter1, adapter2];\n }\n\n public onConnect = new Trigger();\n\n constructor(private readonly _params: { send: (message: Message) => void }) {\n super();\n }\n\n // NOTE: Emitting `ready` event in NetworkAdapter`s constructor causes a race condition\n // because `Repo` waits for `ready` event (which it never receives) before it starts using the adapter.\n ready() {\n this.emit('ready', { network: this });\n }\n\n override connect(peerId: PeerId) {\n this.peerId = peerId;\n this.onConnect.wake();\n }\n\n peerCandidate(peerId: PeerId) {\n invariant(peerId, 'PeerId is required');\n this.emit('peer-candidate', { peerId, peerMetadata: {} });\n }\n\n peerDisconnected(peerId: PeerId) {\n invariant(peerId, 'PeerId is required');\n this.emit('peer-disconnected', { peerId });\n }\n\n override send(message: Message) {\n log('send', { from: message.senderId, to: message.targetId, type: message.type });\n this._params.send(message);\n }\n\n override disconnect() {\n this.peerId = undefined;\n }\n\n receive(message: Message) {\n invariant(this.peerId, 'Peer id is not set');\n this.emit('message', message);\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { sleep, synchronized } from '@dxos/async';\nimport { type Context, LifecycleState, Resource } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport type { AutomergeProtocolMessage } from '@dxos/protocols';\nimport { AutomergeReplicator, type AutomergeReplicatorFactory } from '@dxos/teleport-extension-automerge-replicator';\n\nimport type {\n EchoReplicator,\n EchoReplicatorContext,\n ReplicatorConnection,\n ShouldAdvertiseParams,\n ShouldSyncCollectionParams,\n} from '../automerge';\n\nexport type TestReplicatorNetworkOptions = {\n latency?: number;\n};\n\nexport class TestReplicationNetwork extends Resource {\n private readonly _replicators = new Set<TestReplicator>();\n private readonly _latency?: number = undefined;\n\n constructor(options: TestReplicatorNetworkOptions = {}) {\n super();\n this._latency = options.latency;\n }\n\n protected override async _close(ctx: Context): Promise<void> {\n for (const replicator of this._replicators) {\n for (const connection of replicator.connections) {\n void connection.writable.abort();\n void connection.readable.cancel();\n }\n }\n }\n\n async createReplicator(): Promise<TestReplicator> {\n const replicator = new TestReplicator({\n onConnect: async () => {\n invariant(this._lifecycleState === LifecycleState.OPEN);\n await this._connectReplicator(replicator);\n },\n onDisconnect: async () => {\n invariant(this._lifecycleState === LifecycleState.OPEN);\n await this._disconnectReplicator(replicator);\n },\n });\n this._replicators.add(replicator);\n return replicator;\n }\n\n @synchronized\n private async _connectReplicator(replicator: TestReplicator) {\n for (const otherReplicator of this._replicators.values()) {\n if (otherReplicator === replicator || !otherReplicator.connected) {\n continue;\n }\n log('create connection', { from: replicator.context!.peerId, to: otherReplicator.context!.peerId });\n const [connection1, connection2] = this._createConnectionPair(\n replicator.context!.peerId,\n otherReplicator.context!.peerId,\n );\n await replicator.context!.onConnectionOpen(connection1);\n await otherReplicator.context!.onConnectionOpen(connection2);\n }\n }\n\n private async _disconnectReplicator(replicator: TestReplicator) {\n for (const connection of replicator.connections) {\n await replicator.context!.onConnectionClosed(connection);\n await connection.otherSide!.owningReplicator!.removeConnection(connection.otherSide!);\n }\n }\n\n private _createConnectionPair(peer1: string, peer2: string): [TestReplicatorConnection, TestReplicatorConnection] {\n const LOG = false;\n\n const forward = new TransformStream({\n transform: async (message, controller) => {\n if (LOG) {\n log.info('replicate', { from: peer1, to: peer2, message });\n }\n\n if (this._latency !== undefined) {\n await sleep(this._latency);\n }\n\n controller.enqueue(message);\n },\n });\n const backwards = new TransformStream({\n transform: async (message, controller) => {\n if (LOG) {\n log.info('replicate', { from: peer2, to: peer1, message });\n }\n\n if (this._latency !== undefined) {\n await sleep(this._latency);\n }\n\n controller.enqueue(message);\n },\n });\n\n const connection1 = new TestReplicatorConnection(peer2, backwards.readable, forward.writable);\n const connection2 = new TestReplicatorConnection(peer1, forward.readable, backwards.writable);\n connection1.otherSide = connection2;\n connection2.otherSide = connection1;\n return [connection1, connection2];\n }\n}\n\ntype TestReplicatorParams = {\n onConnect: () => Promise<void>;\n onDisconnect: () => Promise<void>;\n};\n\nexport class TestReplicator implements EchoReplicator {\n constructor(private readonly _params: TestReplicatorParams) {}\n\n public connected = false;\n public context: EchoReplicatorContext | undefined = undefined;\n public connections = new Set<TestReplicatorConnection>();\n\n async connect(context: EchoReplicatorContext): Promise<void> {\n log('connect', { peerId: context.peerId });\n this.context = context;\n this.connected = true;\n await this._params.onConnect();\n }\n\n async disconnect(): Promise<void> {\n log('disconnect', { peerId: this.context!.peerId });\n this.connected = false;\n await this._params.onDisconnect();\n }\n\n async addConnection(connection: TestReplicatorConnection): Promise<void> {\n connection.owningReplicator = this;\n this.connections.add(connection);\n this.context!.onConnectionOpen(connection);\n }\n\n async removeConnection(connection: TestReplicatorConnection): Promise<void> {\n connection.owningReplicator = undefined;\n this.context!.onConnectionClosed(connection);\n this.connections.delete(connection);\n }\n}\n\nexport class TestReplicatorConnection implements ReplicatorConnection {\n public otherSide: TestReplicatorConnection | undefined = undefined;\n public owningReplicator: TestReplicator | undefined = undefined;\n\n constructor(\n public readonly peerId: string,\n public readonly readable: ReadableStream<AutomergeProtocolMessage>,\n public readonly writable: WritableStream<AutomergeProtocolMessage>,\n ) {}\n\n async shouldAdvertise(params: ShouldAdvertiseParams): Promise<boolean> {\n return true;\n }\n\n shouldSyncCollection(params: ShouldSyncCollectionParams): boolean {\n return true;\n }\n}\n\nexport const testAutomergeReplicatorFactory: AutomergeReplicatorFactory = (params) => {\n return new AutomergeReplicator(\n {\n ...params[0],\n sendSyncRetryPolicy: {\n retryBackoff: 20,\n retriesBeforeBackoff: 2,\n maxRetries: 3,\n },\n },\n params[1],\n );\n};\n\nexport const brokenAutomergeReplicatorFactory: AutomergeReplicatorFactory = (params) => {\n params[1]!.onSyncMessage = () => {\n throw new Error();\n };\n return testAutomergeReplicatorFactory(params);\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["log", "schema", "EchoMetadata", "schema", "getCodecForType", "changeStorageVersionInMetadata", "storage", "version", "log", "info", "metadata", "MetadataStore", "createDirectory", "load", "echoMetadata", "file", "_directory", "getOrCreateFile", "_writeFile", "flush", "Context", "CredentialGenerator", "PublicKey", "MemorySignalManager", "MemorySignalManagerContext", "WebsocketSignalManager", "MemoryTransportFactory", "SwarmNetworkManager", "createRtcTransportFactory", "AdmittedFeed", "StorageType", "createStorage", "Gossip", "Presence", "BlobStore", "ComplexMap", "TestBuilder", "TestFeedBuilder", "TestBuilder", "constructor", "valueEncoding", "MemoryNetworkManagerProvider", "signalContext", "SwarmNetworkManager", "signalManager", "MemorySignalManager", "transportFactory", "MemoryTransportFactory", "WebsocketNetworkManagerProvider", "signalUrl", "WebsocketSignalManager", "server", "createRtcTransportFactory", "TestAgentBuilder", "constructor", "storage", "networkManagerProvider", "_agents", "ComplexMap", "PublicKey", "hash", "_storage", "createStorage", "type", "StorageType", "RAM", "_networkManagerProvider", "MemorySignalManagerContext", "close", "Promise", "all", "agents", "map", "agent", "Array", "from", "values", "getAgent", "deviceKey", "get", "createPeer", "feedBuilder", "TestFeedBuilder", "setStorage", "size", "identityKey", "keyring", "createKey", "TestAgent", "set", "metadataStore", "_metadataStore", "MetadataStore", "createDirectory", "blobStore", "_blobStore", "BlobStore", "_feedBuilder", "_spaces", "feedStore", "createFeedStore", "spaces", "space", "getSpace", "spaceKey", "spaceManager", "_spaceManager", "SpaceManager", "networkManager", "createSpace", "genesisKey", "dataKey", "saveMetadata", "controlFeed", "openFeed", "writable", "dataFeed", "sparse", "metadata", "key", "genesisFeedKey", "controlFeedKey", "dataFeedKey", "addSpace", "open", "constructSpace", "swarmIdentity", "peerKey", "credentialProvider", "MOCK_AUTH_PROVIDER", "credentialAuthenticator", "MOCK_AUTH_VERIFIER", "memberKey", "onAuthorizedConnection", "session", "addExtension", "createGossip", "createExtension", "remotePeerId", "onDelegatedInvitationStatusChange", "onMemberRolesChanged", "setControlFeed", "setDataFeed", "Context", "createSpaceProtocol", "topic", "gossip", "SpaceProtocol", "onSessionAuth", "Gossip", "localPeerId", "createPresence", "Presence", "announceInterval", "offlineTimeout", "spaceGenesis", "generator", "CredentialGenerator", "credentials", "createSpaceGenesis", "createFeedAdmission", "AdmittedFeed", "Designation", "DATA", "createEpochCredential", "credential", "controlPipeline", "writer", "write", "Trigger", "sleep", "NetworkAdapter", "invariant", "log", "TestAdapter", "createPair", "connectionStateProvider", "adapter1", "send", "message", "then", "adapter2", "receive", "constructor", "_params", "onConnect", "ready", "emit", "network", "connect", "peerId", "wake", "peerCandidate", "peerMetadata", "peerDisconnected", "from", "senderId", "to", "targetId", "type", "disconnect", "undefined", "sleep", "synchronized", "LifecycleState", "Resource", "invariant", "log", "AutomergeReplicator", "TestReplicationNetwork", "constructor", "options", "_replicators", "Set", "_latency", "undefined", "latency", "_close", "ctx", "replicator", "connection", "connections", "writable", "abort", "readable", "cancel", "createReplicator", "TestReplicator", "onConnect", "_lifecycleState", "OPEN", "_connectReplicator", "onDisconnect", "_disconnectReplicator", "add", "otherReplicator", "values", "connected", "from", "context", "peerId", "to", "connection1", "connection2", "_createConnectionPair", "onConnectionOpen", "onConnectionClosed", "otherSide", "owningReplicator", "removeConnection", "peer1", "peer2", "LOG", "forward", "TransformStream", "transform", "message", "controller", "info", "enqueue", "backwards", "TestReplicatorConnection", "_params", "connect", "disconnect", "addConnection", "delete", "shouldAdvertise", "params", "shouldSyncCollection", "testAutomergeReplicatorFactory", "sendSyncRetryPolicy", "retryBackoff", "retriesBeforeBackoff", "maxRetries", "brokenAutomergeReplicatorFactory", "onSyncMessage", "Error"]
|
|
7
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { Event } from '@dxos/async';
|
|
1
2
|
import { type Doc, type Heads } from '@dxos/automerge/automerge';
|
|
2
3
|
import { Repo, type AnyDocumentId, type DocHandle, type DocumentId, type PeerId } from '@dxos/automerge/automerge-repo';
|
|
3
4
|
import { Context, Resource } from '@dxos/context';
|
|
4
|
-
import { type SpaceDoc } from '@dxos/echo-protocol';
|
|
5
|
+
import { type CollectionId, type SpaceDoc } from '@dxos/echo-protocol';
|
|
5
6
|
import { type IndexMetadataStore } from '@dxos/indexing';
|
|
6
7
|
import { type LevelDB } from '@dxos/kv-store';
|
|
7
8
|
import { type DocHeadsList, type FlushRequest } from '@dxos/protocols/proto/dxos/echo/service';
|
|
@@ -34,6 +35,9 @@ export declare class AutomergeHost extends Resource {
|
|
|
34
35
|
private _storage;
|
|
35
36
|
private readonly _headsStore;
|
|
36
37
|
private _peerId;
|
|
38
|
+
readonly collectionStateUpdated: Event<{
|
|
39
|
+
collectionId: CollectionId;
|
|
40
|
+
}>;
|
|
37
41
|
constructor({ db, indexMetadataStore, dataMonitor }: AutomergeHostParams);
|
|
38
42
|
protected _open(): Promise<void>;
|
|
39
43
|
protected _close(): Promise<void>;
|
|
@@ -93,6 +97,25 @@ export type CollectionSyncState = {
|
|
|
93
97
|
};
|
|
94
98
|
export type PeerSyncState = {
|
|
95
99
|
peerId: PeerId;
|
|
100
|
+
/**
|
|
101
|
+
* Documents that are present locally but not on the remote peer.
|
|
102
|
+
*/
|
|
103
|
+
missingOnRemote: number;
|
|
104
|
+
/**
|
|
105
|
+
* Documents that are present on the remote peer but not locally.
|
|
106
|
+
*/
|
|
107
|
+
missingOnLocal: number;
|
|
108
|
+
/**
|
|
109
|
+
* Documents that are present on both peers but have different heads.
|
|
110
|
+
*/
|
|
96
111
|
differentDocuments: number;
|
|
112
|
+
/**
|
|
113
|
+
* Total number of documents locally.
|
|
114
|
+
*/
|
|
115
|
+
localDocumentCount: number;
|
|
116
|
+
/**
|
|
117
|
+
* Total number of documents on the remote peer.
|
|
118
|
+
*/
|
|
119
|
+
remoteDocumentCount: number;
|
|
97
120
|
};
|
|
98
121
|
//# sourceMappingURL=automerge-host.d.ts.map
|