@automerge/automerge-repo 1.1.1 → 1.1.2
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/package.json +2 -2
- package/test/Repo.test.ts +90 -17
- package/test/helpers/DummyNetworkAdapter.ts +5 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automerge/automerge-repo",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "A repository object to manage a collection of automerge documents",
|
|
5
5
|
"repository": "https://github.com/automerge/automerge-repo/tree/master/packages/automerge-repo",
|
|
6
6
|
"author": "Peter van Hardenberg <pvh@pvh.ca>",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"publishConfig": {
|
|
56
56
|
"access": "public"
|
|
57
57
|
},
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "8bcba031ae952b1f3302cd41d1066cd2db5b677f"
|
|
59
59
|
}
|
package/test/Repo.test.ts
CHANGED
|
@@ -461,6 +461,80 @@ describe("Repo", () => {
|
|
|
461
461
|
})
|
|
462
462
|
|
|
463
463
|
describe("with peers (linear network)", async () => {
|
|
464
|
+
it("n-peers connected in a line", async () => {
|
|
465
|
+
const createNConnectedRepos = async (
|
|
466
|
+
numberOfPeers: number,
|
|
467
|
+
latency?: number
|
|
468
|
+
) => {
|
|
469
|
+
const networkAdapters: DummyNetworkAdapter[][] = []
|
|
470
|
+
const repos: Repo[] = []
|
|
471
|
+
const networkReady: Promise<void>[] = []
|
|
472
|
+
|
|
473
|
+
// Create n repos and connect them in a line.
|
|
474
|
+
for (let idx = 0; idx < numberOfPeers; idx++) {
|
|
475
|
+
const network = []
|
|
476
|
+
|
|
477
|
+
const pair = DummyNetworkAdapter.createConnectedPair({ latency })
|
|
478
|
+
networkAdapters.push(pair)
|
|
479
|
+
|
|
480
|
+
if (idx > 0) {
|
|
481
|
+
network.push(networkAdapters[idx - 1][1])
|
|
482
|
+
networkReady.push(
|
|
483
|
+
eventPromise(networkAdapters[idx - 1][1], "ready")
|
|
484
|
+
)
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (idx < numberOfPeers - 1) {
|
|
488
|
+
network.push(pair[0])
|
|
489
|
+
networkReady.push(eventPromise(pair[0], "ready"))
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
const repo = new Repo({
|
|
493
|
+
network,
|
|
494
|
+
storage: new DummyStorageAdapter(),
|
|
495
|
+
peerId: `peer-${idx}` as PeerId,
|
|
496
|
+
sharePolicy: async () => true,
|
|
497
|
+
})
|
|
498
|
+
repos.push(repo)
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
await Promise.all(networkReady)
|
|
502
|
+
|
|
503
|
+
const connectedPromise = Promise.all(
|
|
504
|
+
repos.map(repo => eventPromise(repo.networkSubsystem, "peer"))
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
// Initialize the network.
|
|
508
|
+
for (let idx = 0; idx < numberOfPeers; idx++) {
|
|
509
|
+
if (idx > 0) {
|
|
510
|
+
networkAdapters[idx - 1][1].peerCandidate(
|
|
511
|
+
`peer-${idx - 1}` as PeerId
|
|
512
|
+
)
|
|
513
|
+
}
|
|
514
|
+
if (idx < numberOfPeers - 1) {
|
|
515
|
+
networkAdapters[idx][0].peerCandidate(`peer-${idx + 1}` as PeerId)
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
await connectedPromise
|
|
520
|
+
|
|
521
|
+
return { repos }
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
const numberOfPeers = 10
|
|
525
|
+
const { repos } = await createNConnectedRepos(numberOfPeers, 10)
|
|
526
|
+
|
|
527
|
+
const handle0 = repos[0].create()
|
|
528
|
+
handle0.change((d: any) => {
|
|
529
|
+
d.foo = "bar"
|
|
530
|
+
})
|
|
531
|
+
|
|
532
|
+
const handleN = repos[numberOfPeers - 1].find<TestDoc>(handle0.url)
|
|
533
|
+
|
|
534
|
+
await handleN.whenReady()
|
|
535
|
+
assert.deepStrictEqual(handleN.docSync(), { foo: "bar" })
|
|
536
|
+
})
|
|
537
|
+
|
|
464
538
|
const setup = async ({
|
|
465
539
|
connectAlice = true,
|
|
466
540
|
isCharlieEphemeral = false,
|
|
@@ -1023,36 +1097,35 @@ describe("Repo", () => {
|
|
|
1023
1097
|
})
|
|
1024
1098
|
})
|
|
1025
1099
|
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
const
|
|
1029
|
-
const
|
|
1030
|
-
const [aliceAdapter, bobAdapter] = DummyNetworkAdapter.createConnectedPair();
|
|
1100
|
+
it("peer receives a document when connection is recovered", async () => {
|
|
1101
|
+
const alice = "alice" as PeerId
|
|
1102
|
+
const bob = "bob" as PeerId
|
|
1103
|
+
const [aliceAdapter, bobAdapter] = DummyNetworkAdapter.createConnectedPair()
|
|
1031
1104
|
const aliceRepo = new Repo({
|
|
1032
1105
|
network: [aliceAdapter],
|
|
1033
|
-
peerId: alice
|
|
1106
|
+
peerId: alice,
|
|
1034
1107
|
})
|
|
1035
1108
|
const bobRepo = new Repo({
|
|
1036
1109
|
network: [bobAdapter],
|
|
1037
|
-
peerId: bob
|
|
1110
|
+
peerId: bob,
|
|
1038
1111
|
})
|
|
1039
1112
|
|
|
1040
|
-
const aliceDoc = aliceRepo.create()
|
|
1041
|
-
aliceDoc.change((doc: any) => doc.text =
|
|
1113
|
+
const aliceDoc = aliceRepo.create()
|
|
1114
|
+
aliceDoc.change((doc: any) => (doc.text = "Hello world"))
|
|
1042
1115
|
|
|
1043
|
-
const bobDoc = bobRepo.find(aliceDoc.url)
|
|
1116
|
+
const bobDoc = bobRepo.find(aliceDoc.url)
|
|
1044
1117
|
bobDoc.unavailable()
|
|
1045
|
-
await bobDoc.whenReady([HandleState.UNAVAILABLE])
|
|
1118
|
+
await bobDoc.whenReady([HandleState.UNAVAILABLE])
|
|
1046
1119
|
|
|
1047
|
-
aliceAdapter.peerCandidate(bob)
|
|
1120
|
+
aliceAdapter.peerCandidate(bob)
|
|
1048
1121
|
// Bob isn't yet connected to Alice and can't respond to her sync message
|
|
1049
|
-
await pause(100)
|
|
1050
|
-
bobAdapter.peerCandidate(alice)
|
|
1122
|
+
await pause(100)
|
|
1123
|
+
bobAdapter.peerCandidate(alice)
|
|
1051
1124
|
|
|
1052
|
-
await bobDoc.whenReady([HandleState.READY])
|
|
1125
|
+
await bobDoc.whenReady([HandleState.READY])
|
|
1053
1126
|
|
|
1054
|
-
assert.equal(bobDoc.isReady(), true)
|
|
1055
|
-
})
|
|
1127
|
+
assert.equal(bobDoc.isReady(), true)
|
|
1128
|
+
})
|
|
1056
1129
|
|
|
1057
1130
|
describe("with peers (mesh network)", () => {
|
|
1058
1131
|
const setup = async () => {
|
|
@@ -11,7 +11,8 @@ export class DummyNetworkAdapter extends NetworkAdapter {
|
|
|
11
11
|
this.#sendMessage = opts.sendMessage;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
connect(
|
|
14
|
+
connect(peerId: PeerId) {
|
|
15
|
+
this.peerId = peerId;
|
|
15
16
|
if (this.#startReady) {
|
|
16
17
|
this.emit("ready", { network: this })
|
|
17
18
|
}
|
|
@@ -31,14 +32,14 @@ export class DummyNetworkAdapter extends NetworkAdapter {
|
|
|
31
32
|
this.emit('message', message);
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
static createConnectedPair() {
|
|
35
|
+
static createConnectedPair({ latency = 10 }: { latency?: number} = {}) {
|
|
35
36
|
const adapter1: DummyNetworkAdapter = new DummyNetworkAdapter({
|
|
36
37
|
startReady: true,
|
|
37
|
-
sendMessage: (message: Message) => pause(
|
|
38
|
+
sendMessage: (message: Message) => pause(latency).then(() => adapter2.receive(message)),
|
|
38
39
|
});
|
|
39
40
|
const adapter2: DummyNetworkAdapter = new DummyNetworkAdapter({
|
|
40
41
|
startReady: true,
|
|
41
|
-
sendMessage: (message: Message) => pause(
|
|
42
|
+
sendMessage: (message: Message) => pause(latency).then(() => adapter1.receive(message)),
|
|
42
43
|
});
|
|
43
44
|
|
|
44
45
|
return [adapter1, adapter2];
|