hypercore 10.0.0-alpha.7 → 10.0.0
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/README.md +83 -22
- package/index.js +587 -217
- package/lib/bitfield.js +109 -41
- package/lib/block-encryption.js +3 -2
- package/lib/block-store.js +6 -4
- package/lib/caps.js +32 -0
- package/lib/core.js +166 -35
- package/lib/errors.js +50 -0
- package/lib/info.js +23 -0
- package/lib/merkle-tree.js +181 -105
- package/lib/messages.js +249 -168
- package/lib/oplog.js +4 -3
- package/lib/remote-bitfield.js +28 -7
- package/lib/replicator.js +1415 -624
- package/lib/streams.js +56 -0
- package/package.json +20 -15
- package/.github/workflows/test-node.yml +0 -23
- package/CHANGELOG.md +0 -37
- package/UPGRADE.md +0 -9
- package/examples/announce.js +0 -19
- package/examples/basic.js +0 -10
- package/examples/http.js +0 -123
- package/examples/lookup.js +0 -20
- package/lib/extensions.js +0 -76
- package/lib/protocol.js +0 -524
- package/lib/random-iterator.js +0 -46
- package/test/basic.js +0 -90
- package/test/bitfield.js +0 -71
- package/test/core.js +0 -290
- package/test/encodings.js +0 -18
- package/test/encryption.js +0 -85
- package/test/extension.js +0 -71
- package/test/helpers/index.js +0 -23
- package/test/merkle-tree.js +0 -518
- package/test/mutex.js +0 -137
- package/test/oplog.js +0 -399
- package/test/preload.js +0 -72
- package/test/replicate.js +0 -372
- package/test/sessions.js +0 -173
- package/test/user-data.js +0 -47
package/test/core.js
DELETED
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
const test = require('brittle')
|
|
2
|
-
const RAM = require('random-access-memory')
|
|
3
|
-
const Core = require('../lib/core')
|
|
4
|
-
|
|
5
|
-
test('core - append', async function (t) {
|
|
6
|
-
const { core } = await create()
|
|
7
|
-
|
|
8
|
-
{
|
|
9
|
-
const seq = await core.append([
|
|
10
|
-
Buffer.from('hello'),
|
|
11
|
-
Buffer.from('world')
|
|
12
|
-
])
|
|
13
|
-
|
|
14
|
-
t.is(seq, 0)
|
|
15
|
-
t.is(core.tree.length, 2)
|
|
16
|
-
t.is(core.tree.byteLength, 10)
|
|
17
|
-
t.alike([
|
|
18
|
-
await core.blocks.get(0),
|
|
19
|
-
await core.blocks.get(1)
|
|
20
|
-
], [
|
|
21
|
-
Buffer.from('hello'),
|
|
22
|
-
Buffer.from('world')
|
|
23
|
-
])
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
{
|
|
27
|
-
const seq = await core.append([
|
|
28
|
-
Buffer.from('hej')
|
|
29
|
-
])
|
|
30
|
-
|
|
31
|
-
t.is(seq, 2)
|
|
32
|
-
t.is(core.tree.length, 3)
|
|
33
|
-
t.is(core.tree.byteLength, 13)
|
|
34
|
-
t.alike([
|
|
35
|
-
await core.blocks.get(0),
|
|
36
|
-
await core.blocks.get(1),
|
|
37
|
-
await core.blocks.get(2)
|
|
38
|
-
], [
|
|
39
|
-
Buffer.from('hello'),
|
|
40
|
-
Buffer.from('world'),
|
|
41
|
-
Buffer.from('hej')
|
|
42
|
-
])
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
test('core - append and truncate', async function (t) {
|
|
47
|
-
const { core, reopen } = await create()
|
|
48
|
-
|
|
49
|
-
await core.append([
|
|
50
|
-
Buffer.from('hello'),
|
|
51
|
-
Buffer.from('world'),
|
|
52
|
-
Buffer.from('fo'),
|
|
53
|
-
Buffer.from('ooo')
|
|
54
|
-
])
|
|
55
|
-
|
|
56
|
-
await core.truncate(3, 1)
|
|
57
|
-
|
|
58
|
-
t.is(core.tree.length, 3)
|
|
59
|
-
t.is(core.tree.byteLength, 12)
|
|
60
|
-
t.is(core.tree.fork, 1)
|
|
61
|
-
t.alike(core.header.hints.reorgs, [{ from: 0, to: 1, ancestors: 3 }])
|
|
62
|
-
|
|
63
|
-
await core.append([
|
|
64
|
-
Buffer.from('a'),
|
|
65
|
-
Buffer.from('b'),
|
|
66
|
-
Buffer.from('c'),
|
|
67
|
-
Buffer.from('d')
|
|
68
|
-
])
|
|
69
|
-
|
|
70
|
-
await core.truncate(3, 2)
|
|
71
|
-
|
|
72
|
-
t.is(core.tree.length, 3)
|
|
73
|
-
t.is(core.tree.byteLength, 12)
|
|
74
|
-
t.is(core.tree.fork, 2)
|
|
75
|
-
t.alike(core.header.hints.reorgs, [{ from: 0, to: 1, ancestors: 3 }, { from: 1, to: 2, ancestors: 3 }])
|
|
76
|
-
|
|
77
|
-
await core.truncate(2, 3)
|
|
78
|
-
|
|
79
|
-
t.alike(core.header.hints.reorgs, [{ from: 2, to: 3, ancestors: 2 }])
|
|
80
|
-
|
|
81
|
-
await core.append([Buffer.from('a')])
|
|
82
|
-
await core.truncate(2, 4)
|
|
83
|
-
|
|
84
|
-
await core.append([Buffer.from('a')])
|
|
85
|
-
await core.truncate(2, 5)
|
|
86
|
-
|
|
87
|
-
await core.append([Buffer.from('a')])
|
|
88
|
-
await core.truncate(2, 6)
|
|
89
|
-
|
|
90
|
-
await core.append([Buffer.from('a')])
|
|
91
|
-
await core.truncate(2, 7)
|
|
92
|
-
|
|
93
|
-
t.is(core.header.hints.reorgs.length, 4)
|
|
94
|
-
|
|
95
|
-
// check that it was persisted
|
|
96
|
-
const coreReopen = await reopen()
|
|
97
|
-
|
|
98
|
-
t.is(coreReopen.tree.length, 2)
|
|
99
|
-
t.is(coreReopen.tree.byteLength, 10)
|
|
100
|
-
t.is(coreReopen.tree.fork, 7)
|
|
101
|
-
t.is(coreReopen.header.hints.reorgs.length, 4)
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
test('core - user data', async function (t) {
|
|
105
|
-
const { core, reopen } = await create()
|
|
106
|
-
|
|
107
|
-
await core.userData('hello', Buffer.from('world'))
|
|
108
|
-
t.alike(core.header.userData, [{ key: 'hello', value: Buffer.from('world') }])
|
|
109
|
-
|
|
110
|
-
await core.userData('hej', Buffer.from('verden'))
|
|
111
|
-
t.alike(core.header.userData, [
|
|
112
|
-
{ key: 'hello', value: Buffer.from('world') },
|
|
113
|
-
{ key: 'hej', value: Buffer.from('verden') }
|
|
114
|
-
])
|
|
115
|
-
|
|
116
|
-
await core.userData('hello', null)
|
|
117
|
-
t.alike(core.header.userData, [{ key: 'hej', value: Buffer.from('verden') }])
|
|
118
|
-
|
|
119
|
-
await core.userData('hej', Buffer.from('world'))
|
|
120
|
-
t.alike(core.header.userData, [{ key: 'hej', value: Buffer.from('world') }])
|
|
121
|
-
|
|
122
|
-
// check that it was persisted
|
|
123
|
-
const coreReopen = await reopen()
|
|
124
|
-
|
|
125
|
-
t.alike(coreReopen.header.userData, [{ key: 'hej', value: Buffer.from('world') }])
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
test('core - verify', async function (t) {
|
|
129
|
-
const { core } = await create()
|
|
130
|
-
const { core: clone } = await create({ keyPair: { publicKey: core.header.signer.publicKey } })
|
|
131
|
-
|
|
132
|
-
t.is(clone.header.signer.publicKey, core.header.signer.publicKey)
|
|
133
|
-
|
|
134
|
-
await core.append([Buffer.from('a'), Buffer.from('b')])
|
|
135
|
-
|
|
136
|
-
{
|
|
137
|
-
const p = await core.tree.proof({ upgrade: { start: 0, length: 2 } })
|
|
138
|
-
await clone.verify(p)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
t.is(clone.header.tree.length, 2)
|
|
142
|
-
t.is(clone.header.tree.signature, core.header.tree.signature)
|
|
143
|
-
|
|
144
|
-
{
|
|
145
|
-
const p = await core.tree.proof({ block: { index: 1, nodes: await clone.tree.nodes(2), value: true } })
|
|
146
|
-
p.block.value = await core.blocks.get(1)
|
|
147
|
-
await clone.verify(p)
|
|
148
|
-
}
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
test('core - verify parallel upgrades', async function (t) {
|
|
152
|
-
const { core } = await create()
|
|
153
|
-
const { core: clone } = await create({ keyPair: { publicKey: core.header.signer.publicKey } })
|
|
154
|
-
|
|
155
|
-
t.is(clone.header.signer.publicKey, core.header.signer.publicKey)
|
|
156
|
-
|
|
157
|
-
await core.append([Buffer.from('a'), Buffer.from('b'), Buffer.from('c'), Buffer.from('d')])
|
|
158
|
-
|
|
159
|
-
{
|
|
160
|
-
const p1 = await core.tree.proof({ upgrade: { start: 0, length: 2 } })
|
|
161
|
-
const p2 = await core.tree.proof({ upgrade: { start: 0, length: 3 } })
|
|
162
|
-
|
|
163
|
-
const v1 = clone.verify(p1)
|
|
164
|
-
const v2 = clone.verify(p2)
|
|
165
|
-
|
|
166
|
-
await v1
|
|
167
|
-
await v2
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
t.is(clone.header.tree.length, core.header.tree.length)
|
|
171
|
-
t.is(clone.header.tree.signature, core.header.tree.signature)
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
test('core - update hook is triggered', async function (t) {
|
|
175
|
-
const { core } = await create()
|
|
176
|
-
const { core: clone } = await create({ keyPair: { publicKey: core.header.signer.publicKey } })
|
|
177
|
-
|
|
178
|
-
let ran = 0
|
|
179
|
-
|
|
180
|
-
core.onupdate = (status, bitfield, value, from) => {
|
|
181
|
-
t.is(status, 0b01, 'was appended')
|
|
182
|
-
t.is(from, null, 'was local')
|
|
183
|
-
t.alike(bitfield, { drop: false, start: 0, length: 4 })
|
|
184
|
-
ran |= 1
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
await core.append([Buffer.from('a'), Buffer.from('b'), Buffer.from('c'), Buffer.from('d')])
|
|
188
|
-
|
|
189
|
-
const peer = {}
|
|
190
|
-
|
|
191
|
-
clone.onupdate = (status, bitfield, value, from) => {
|
|
192
|
-
t.is(status, 0b01, 'was appended')
|
|
193
|
-
t.is(from, peer, 'was remote')
|
|
194
|
-
t.alike(bitfield, { drop: false, start: 1, length: 1 })
|
|
195
|
-
t.alike(value, Buffer.from('b'))
|
|
196
|
-
ran |= 2
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
{
|
|
200
|
-
const p = await core.tree.proof({ block: { index: 1, nodes: 0, value: true }, upgrade: { start: 0, length: 2 } })
|
|
201
|
-
p.block.value = await core.blocks.get(1)
|
|
202
|
-
await clone.verify(p, peer)
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
clone.onupdate = (status, bitfield, value, from) => {
|
|
206
|
-
t.is(status, 0b00, 'no append or truncate')
|
|
207
|
-
t.is(from, peer, 'was remote')
|
|
208
|
-
t.alike(bitfield, { drop: false, start: 3, length: 1 })
|
|
209
|
-
t.alike(value, Buffer.from('d'))
|
|
210
|
-
ran |= 4
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
{
|
|
214
|
-
const p = await core.tree.proof({ block: { index: 3, nodes: await clone.tree.nodes(6), value: true } })
|
|
215
|
-
p.block.value = await core.blocks.get(3)
|
|
216
|
-
await clone.verify(p, peer)
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
core.onupdate = (status, bitfield, value, from) => {
|
|
220
|
-
t.is(status, 0b10, 'was truncated')
|
|
221
|
-
t.is(from, null, 'was local')
|
|
222
|
-
t.alike(bitfield, { drop: true, start: 1, length: 3 })
|
|
223
|
-
ran |= 8
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
await core.truncate(1, 1)
|
|
227
|
-
|
|
228
|
-
core.onupdate = (status, bitfield, value, from) => {
|
|
229
|
-
t.is(status, 0b01, 'was appended')
|
|
230
|
-
t.is(from, null, 'was local')
|
|
231
|
-
t.alike(bitfield, { drop: false, start: 1, length: 1 })
|
|
232
|
-
ran |= 16
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
await core.append([Buffer.from('e')])
|
|
236
|
-
|
|
237
|
-
clone.onupdate = (status, bitfield, value, from) => {
|
|
238
|
-
t.is(status, 0b11, 'was appended and truncated')
|
|
239
|
-
t.is(from, peer, 'was remote')
|
|
240
|
-
t.alike(bitfield, { drop: true, start: 1, length: 3 })
|
|
241
|
-
ran |= 32
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
{
|
|
245
|
-
const p = await core.tree.proof({ block: { index: 0, nodes: 0, value: false }, upgrade: { start: 0, length: 2 } })
|
|
246
|
-
const r = await clone.tree.reorg(p)
|
|
247
|
-
|
|
248
|
-
await clone.reorg(r, peer)
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
core.onupdate = (status, bitfield, value, from) => {
|
|
252
|
-
t.is(status, 0b10, 'was truncated')
|
|
253
|
-
t.is(from, null, 'was local')
|
|
254
|
-
t.alike(bitfield, { drop: true, start: 1, length: 1 })
|
|
255
|
-
ran |= 64
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
await core.truncate(1, 2)
|
|
259
|
-
|
|
260
|
-
clone.onupdate = (status, bitfield, value, from) => {
|
|
261
|
-
t.is(status, 0b10, 'was truncated')
|
|
262
|
-
t.is(from, peer, 'was remote')
|
|
263
|
-
t.alike(bitfield, { drop: true, start: 1, length: 1 })
|
|
264
|
-
ran |= 128
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
{
|
|
268
|
-
const p = await core.tree.proof({ block: { index: 0, nodes: 0, value: false }, upgrade: { start: 0, length: 1 } })
|
|
269
|
-
const r = await clone.tree.reorg(p)
|
|
270
|
-
|
|
271
|
-
await clone.reorg(r, peer)
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
t.is(ran, 255, 'ran all')
|
|
275
|
-
})
|
|
276
|
-
|
|
277
|
-
async function create (opts) {
|
|
278
|
-
const storage = new Map()
|
|
279
|
-
|
|
280
|
-
const createFile = (name) => {
|
|
281
|
-
if (storage.has(name)) return storage.get(name)
|
|
282
|
-
const s = new RAM()
|
|
283
|
-
storage.set(name, s)
|
|
284
|
-
return s
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const reopen = () => Core.open(createFile, opts)
|
|
288
|
-
const core = await reopen()
|
|
289
|
-
return { core, reopen }
|
|
290
|
-
}
|
package/test/encodings.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
const test = require('brittle')
|
|
2
|
-
const { create } = require('./helpers')
|
|
3
|
-
|
|
4
|
-
test('encodings - supports built ins', async function (t) {
|
|
5
|
-
const a = await create(null, { valueEncoding: 'json' })
|
|
6
|
-
|
|
7
|
-
await a.append({ hello: 'world' })
|
|
8
|
-
t.alike(await a.get(0), { hello: 'world' })
|
|
9
|
-
t.alike(await a.get(0, { valueEncoding: 'utf-8' }), '{"hello":"world"}')
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
test('encodings - supports custom encoding', async function (t) {
|
|
13
|
-
const a = await create(null, { valueEncoding: { encode () { return Buffer.from('foo') }, decode () { return 'bar' } } })
|
|
14
|
-
|
|
15
|
-
await a.append({ hello: 'world' })
|
|
16
|
-
t.is(await a.get(0), 'bar')
|
|
17
|
-
t.alike(await a.get(0, { valueEncoding: 'utf-8' }), 'foo')
|
|
18
|
-
})
|
package/test/encryption.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
const test = require('brittle')
|
|
2
|
-
const { create, replicate } = require('./helpers')
|
|
3
|
-
|
|
4
|
-
const encryptionKey = Buffer.alloc(32, 'hello world')
|
|
5
|
-
|
|
6
|
-
test('encrypted append and get', async function (t) {
|
|
7
|
-
const a = await create({ encryptionKey })
|
|
8
|
-
|
|
9
|
-
t.alike(a.encryptionKey, encryptionKey)
|
|
10
|
-
|
|
11
|
-
await a.append(['hello'])
|
|
12
|
-
|
|
13
|
-
t.is(a.byteLength, 5)
|
|
14
|
-
t.is(a.core.tree.byteLength, 5 + a.padding)
|
|
15
|
-
|
|
16
|
-
const unencrypted = await a.get(0)
|
|
17
|
-
const encrypted = await a.core.blocks.get(0)
|
|
18
|
-
|
|
19
|
-
t.alike(unencrypted, Buffer.from('hello'))
|
|
20
|
-
t.unlike(unencrypted, encrypted)
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
test('encrypted seek', async function (t) {
|
|
24
|
-
const a = await create({ encryptionKey })
|
|
25
|
-
|
|
26
|
-
await a.append(['hello', 'world', '!'])
|
|
27
|
-
|
|
28
|
-
t.alike(await a.seek(0), [0, 0])
|
|
29
|
-
t.alike(await a.seek(4), [0, 4])
|
|
30
|
-
t.alike(await a.seek(5), [1, 0])
|
|
31
|
-
t.alike(await a.seek(6), [1, 1])
|
|
32
|
-
t.alike(await a.seek(6), [1, 1])
|
|
33
|
-
t.alike(await a.seek(9), [1, 4])
|
|
34
|
-
t.alike(await a.seek(10), [2, 0])
|
|
35
|
-
t.alike(await a.seek(11), [3, 0])
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
test('encrypted replication', async function (t) {
|
|
39
|
-
const a = await create({ encryptionKey })
|
|
40
|
-
|
|
41
|
-
await a.append(['a', 'b', 'c', 'd', 'e'])
|
|
42
|
-
|
|
43
|
-
t.test('with encryption key', async function (t) {
|
|
44
|
-
t.plan(10)
|
|
45
|
-
|
|
46
|
-
const b = await create(a.key, { encryptionKey })
|
|
47
|
-
|
|
48
|
-
b.on('download', (i, block) => {
|
|
49
|
-
t.alike(block, Buffer.from([i + /* a */ 0x61]))
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
replicate(a, b, t)
|
|
53
|
-
|
|
54
|
-
const r = b.download({ start: 0, end: a.length })
|
|
55
|
-
await r.downloaded()
|
|
56
|
-
|
|
57
|
-
for (let i = 0; i < 5; i++) {
|
|
58
|
-
t.alike(await b.get(i), await a.get(i))
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
t.test('without encryption key', async function (t) {
|
|
63
|
-
const b = await create(a.key)
|
|
64
|
-
|
|
65
|
-
replicate(a, b, t)
|
|
66
|
-
|
|
67
|
-
const r = b.download({ start: 0, end: a.length })
|
|
68
|
-
await r.downloaded()
|
|
69
|
-
|
|
70
|
-
for (let i = 0; i < 5; i++) {
|
|
71
|
-
t.unlike(await b.get(i), await a.get(i))
|
|
72
|
-
t.alike(await b.get(i), await a.core.blocks.get(i))
|
|
73
|
-
}
|
|
74
|
-
})
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
test('encrypted sessions', async function (t) {
|
|
78
|
-
const a = await create({ encryptionKey })
|
|
79
|
-
|
|
80
|
-
await a.append(['hello'])
|
|
81
|
-
|
|
82
|
-
const session = a.session()
|
|
83
|
-
|
|
84
|
-
t.alike(await session.get(0), Buffer.from('hello'))
|
|
85
|
-
})
|
package/test/extension.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
const test = require('brittle')
|
|
2
|
-
const { create, replicate, eventFlush } = require('./helpers')
|
|
3
|
-
|
|
4
|
-
test('basic extension', async function (t) {
|
|
5
|
-
const messages = ['world', 'hello']
|
|
6
|
-
|
|
7
|
-
const a = await create()
|
|
8
|
-
a.registerExtension('test-extension', {
|
|
9
|
-
encoding: 'utf-8',
|
|
10
|
-
onmessage: (message, peer) => {
|
|
11
|
-
t.ok(peer === a.peers[0])
|
|
12
|
-
t.is(message, messages.pop())
|
|
13
|
-
}
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
const b = await create(a.key)
|
|
17
|
-
const bExt = b.registerExtension('test-extension', {
|
|
18
|
-
encoding: 'utf-8'
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
replicate(a, b, t)
|
|
22
|
-
|
|
23
|
-
await eventFlush()
|
|
24
|
-
t.is(b.peers.length, 1)
|
|
25
|
-
|
|
26
|
-
bExt.send('hello', b.peers[0])
|
|
27
|
-
bExt.send('world', b.peers[0])
|
|
28
|
-
|
|
29
|
-
await eventFlush()
|
|
30
|
-
t.absent(messages.length)
|
|
31
|
-
|
|
32
|
-
t.end()
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
test('two extensions', async function (t) {
|
|
36
|
-
const messages = ['world', 'hello']
|
|
37
|
-
|
|
38
|
-
const a = await create()
|
|
39
|
-
const b = await create(a.key)
|
|
40
|
-
|
|
41
|
-
replicate(a, b, t)
|
|
42
|
-
|
|
43
|
-
b.registerExtension('test-extension-1', {
|
|
44
|
-
encoding: 'utf-8'
|
|
45
|
-
})
|
|
46
|
-
const bExt2 = b.registerExtension('test-extension-2', {
|
|
47
|
-
encoding: 'utf-8'
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
await eventFlush()
|
|
51
|
-
t.is(b.peers.length, 1)
|
|
52
|
-
|
|
53
|
-
bExt2.send('world', b.peers[0])
|
|
54
|
-
|
|
55
|
-
await eventFlush()
|
|
56
|
-
|
|
57
|
-
a.registerExtension('test-extension-2', {
|
|
58
|
-
encoding: 'utf-8',
|
|
59
|
-
onmessage: (message, peer) => {
|
|
60
|
-
t.ok(peer === a.peers[0])
|
|
61
|
-
t.is(message, messages.pop())
|
|
62
|
-
}
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
bExt2.send('hello', b.peers[0])
|
|
66
|
-
|
|
67
|
-
await eventFlush()
|
|
68
|
-
t.is(messages.length, 1) // First message gets ignored
|
|
69
|
-
|
|
70
|
-
t.end()
|
|
71
|
-
})
|
package/test/helpers/index.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
const Hypercore = require('../../')
|
|
2
|
-
const ram = require('random-access-memory')
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
async create (...args) {
|
|
6
|
-
const core = new Hypercore(ram, ...args)
|
|
7
|
-
await core.ready()
|
|
8
|
-
return core
|
|
9
|
-
},
|
|
10
|
-
|
|
11
|
-
replicate (a, b, t) {
|
|
12
|
-
const s1 = a.replicate(true)
|
|
13
|
-
const s2 = b.replicate(false)
|
|
14
|
-
s1.on('error', err => t.comment(`STREAM ERROR: ${err}`))
|
|
15
|
-
s2.on('error', err => t.comment(`STREAM ERROR: ${err}`))
|
|
16
|
-
s1.pipe(s2).pipe(s1)
|
|
17
|
-
return [s1, s2]
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
async eventFlush () {
|
|
21
|
-
await new Promise(resolve => setImmediate(resolve))
|
|
22
|
-
}
|
|
23
|
-
}
|