hypercore 10.0.0-alpha.11 → 10.0.0-alpha.15

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.
@@ -1,19 +0,0 @@
1
- const Hypercore = require('../')
2
- const Hyperswarm = require('hyperswarm')
3
-
4
- const core = new Hypercore('./source')
5
-
6
- start()
7
-
8
- async function start () {
9
- await core.ready()
10
- while (core.length < 1000) {
11
- await core.append('block #' + core.length)
12
- }
13
-
14
- const swarm = new Hyperswarm()
15
- swarm.on('connection', socket => core.replicate(socket))
16
- swarm.join(core.discoveryKey, { server: true, client: false })
17
-
18
- console.log('Core:', core.key.toString('hex'))
19
- }
package/examples/basic.js DELETED
@@ -1,10 +0,0 @@
1
- const Hypercore = require('../')
2
-
3
- start()
4
-
5
- async function start () {
6
- const core = new Hypercore('/tmp/basic')
7
- await core.append(['Hello', 'World'])
8
- console.log(core)
9
- await core.close()
10
- }
package/examples/http.js DELETED
@@ -1,123 +0,0 @@
1
- const Hypercore = require('../')
2
- const streamx = require('streamx')
3
- const replicator = require('@hyperswarm/replicator')
4
-
5
- const core = new Hypercore('/tmp/movie')
6
-
7
- if (process.argv[2] === 'bench') bench()
8
- else if (process.argv[2]) importData()
9
- else start()
10
-
11
- class ByteStream extends streamx.Readable {
12
- constructor (core, byteOffset, byteLength) {
13
- super()
14
-
15
- this.core = core
16
- this.byteOffset = byteOffset
17
- this.byteLength = byteLength
18
- this.index = 0
19
- this.range = null
20
- }
21
-
22
- async _read (cb) {
23
- let data = null
24
-
25
- if (!this.byteLength) {
26
- this.push(null)
27
- return cb(null)
28
- }
29
-
30
- if (this.byteOffset > 0) {
31
- const [block, byteOffset] = await core.seek(this.byteOffset)
32
- this.byteOffset = 0
33
- this.index = block + 1
34
- this._select(this.index)
35
- data = (await core.get(block)).slice(byteOffset)
36
- } else {
37
- this._select(this.index + 1)
38
- data = await core.get(this.index++)
39
- }
40
-
41
- if (data.length >= this.byteLength) {
42
- data = data.slice(0, this.byteLength)
43
- this.push(data)
44
- this.push(null)
45
- } else {
46
- this.push(data)
47
- }
48
-
49
- this.byteLength -= data.length
50
-
51
- cb(null)
52
- }
53
-
54
- _select (index) {
55
- if (this.range !== null) this.range.destroy(null)
56
- this.range = this.core.download({ start: index, end: index + 32, linear: true })
57
- }
58
-
59
- _destroy (cb) {
60
- if (this.range) this.range.destroy(null)
61
- cb(null)
62
- }
63
- }
64
-
65
- async function bench () {
66
- await core.ready()
67
-
68
- console.time()
69
- for (let i = 0; i < core.length; i++) {
70
- await core.get(i)
71
- }
72
- console.timeEnd()
73
- }
74
-
75
- async function start () {
76
- const http = require('http')
77
- const parse = require('range-parser')
78
-
79
- await core.ready()
80
-
81
- core.on('download', (index) => console.log('Downloaded block #' + index))
82
- core.download({ start: 0, end: 1 })
83
-
84
- // hack until we update the replicator
85
- core.ready = (cb) => cb(null)
86
-
87
- replicator(core, {
88
- discoveryKey: require('crypto').createHash('sha256').update('http').digest(),
89
- announce: true,
90
- lookup: true
91
- })
92
-
93
- http.createServer(function (req, res) {
94
- res.setHeader('Content-Type', 'video/x-matroska')
95
- res.setHeader('Accept-Ranges', 'bytes')
96
-
97
- let s
98
-
99
- if (req.headers.range) {
100
- const range = parse(core.byteLength, req.headers.range)[0]
101
- const byteLength = range.end - range.start + 1
102
- res.statusCode = 206
103
- res.setHeader('Content-Range', 'bytes ' + range.start + '-' + range.end + '/' + core.byteLength)
104
- s = new ByteStream(core, range.start, byteLength)
105
- } else {
106
- s = new ByteStream(core, 0, core.byteLength)
107
- }
108
-
109
- res.setHeader('Content-Length', s.byteLength)
110
- s.pipe(res, () => {})
111
- }).listen(10101)
112
- }
113
-
114
- async function importData () {
115
- const fs = require('fs')
116
- const rs = fs.createReadStream(process.argv[2])
117
-
118
- for await (const data of rs) {
119
- await core.append(data)
120
- }
121
-
122
- console.log('done!', core)
123
- }
@@ -1,20 +0,0 @@
1
- const Hypercore = require('../')
2
- const Hyperswarm = require('hyperswarm')
3
-
4
- const core = new Hypercore('./clone', process.argv[2])
5
-
6
- start()
7
-
8
- async function start () {
9
- await core.ready()
10
-
11
- const swarm = new Hyperswarm()
12
- swarm.on('connection', socket => core.replicate(socket))
13
- swarm.join(core.discoveryKey, { server: false, client: true })
14
-
15
- console.log((await core.get(42)).toString())
16
- console.log((await core.get(142)).toString())
17
- console.log((await core.get(511)).toString())
18
- console.log((await core.get(512)).toString())
19
- console.log((await core.get(513)).toString())
20
- }
package/test/basic.js DELETED
@@ -1,90 +0,0 @@
1
- const test = require('brittle')
2
- const ram = require('random-access-memory')
3
-
4
- const Hypercore = require('../')
5
- const { create } = require('./helpers')
6
-
7
- test('basic', async function (t) {
8
- const core = await create()
9
- let appends = 0
10
-
11
- t.is(core.length, 0)
12
- t.is(core.byteLength, 0)
13
- t.is(core.writable, true)
14
- t.is(core.readable, true)
15
-
16
- core.on('append', function () {
17
- appends++
18
- })
19
-
20
- await core.append('hello')
21
- await core.append('world')
22
-
23
- t.is(core.length, 2)
24
- t.is(core.byteLength, 10)
25
- t.is(appends, 2)
26
-
27
- t.end()
28
- })
29
-
30
- test('session', async function (t) {
31
- const core = await create()
32
-
33
- const session = core.session()
34
-
35
- await session.append('test')
36
- t.alike(await core.get(0), Buffer.from('test'))
37
- t.alike(await session.get(0), Buffer.from('test'))
38
- t.end()
39
- })
40
-
41
- test('close', async function (t) {
42
- const core = await create()
43
- await core.append('hello world')
44
-
45
- await core.close()
46
-
47
- try {
48
- await core.get(0)
49
- t.fail('core should be closed')
50
- } catch {
51
- t.pass('get threw correctly when core was closed')
52
- }
53
- })
54
-
55
- test('close multiple', async function (t) {
56
- const core = await create()
57
- await core.append('hello world')
58
-
59
- const ev = t.test('events')
60
-
61
- ev.plan(4)
62
-
63
- let i = 0
64
-
65
- core.on('close', () => ev.is(i++, 0, 'on close'))
66
- core.close().then(() => ev.is(i++, 1, 'first close'))
67
- core.close().then(() => ev.is(i++, 2, 'second close'))
68
- core.close().then(() => ev.is(i++, 3, 'third close'))
69
-
70
- await ev
71
- })
72
-
73
- test('storage options', async function (t) {
74
- const core = new Hypercore({ storage: ram })
75
- await core.append('hello')
76
- t.alike(await core.get(0), Buffer.from('hello'))
77
- t.end()
78
- })
79
-
80
- test(
81
- 'allow publicKeys with different byteLength that 32, if opts.crypto were passed',
82
- function (t) {
83
- const key = Buffer.alloc(33).fill('a')
84
-
85
- const core = new Hypercore(ram, key, { crypto: {} })
86
-
87
- t.is(core.key, key)
88
- t.pass('creating a core with more than 32 byteLength key did not throw')
89
- }
90
- )
package/test/bitfield.js DELETED
@@ -1,71 +0,0 @@
1
- const test = require('brittle')
2
- const ram = require('random-access-memory')
3
- const Bitfield = require('../lib/bitfield')
4
-
5
- test('bitfield - set and get', async function (t) {
6
- const b = await Bitfield.open(ram())
7
-
8
- t.absent(b.get(42))
9
- b.set(42, true)
10
- t.ok(b.get(42))
11
-
12
- // bigger offsets
13
- t.absent(b.get(42000000))
14
- b.set(42000000, true)
15
- t.ok(b.get(42000000))
16
-
17
- b.set(42000000, false)
18
- t.absent(b.get(42000000))
19
-
20
- await b.flush()
21
- })
22
-
23
- test('bitfield - random set and gets', async function (t) {
24
- const b = await Bitfield.open(ram())
25
- const set = new Set()
26
-
27
- for (let i = 0; i < 200; i++) {
28
- const idx = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)
29
- b.set(idx, true)
30
- set.add(idx)
31
- }
32
-
33
- for (let i = 0; i < 500; i++) {
34
- const idx = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)
35
- const expected = set.has(idx)
36
- const val = b.get(idx)
37
- if (val !== expected) {
38
- t.fail('expected ' + expected + ' but got ' + val + ' at ' + idx)
39
- return
40
- }
41
- }
42
-
43
- for (const idx of set) {
44
- const val = b.get(idx)
45
- if (val !== true) {
46
- t.fail('expected true but got ' + val + ' at ' + idx)
47
- return
48
- }
49
- }
50
-
51
- t.pass('all random set and gets pass')
52
- })
53
-
54
- test('bitfield - reload', async function (t) {
55
- const s = ram()
56
-
57
- {
58
- const b = await Bitfield.open(s)
59
- b.set(142, true)
60
- b.set(40000, true)
61
- b.set(1424242424, true)
62
- await b.flush()
63
- }
64
-
65
- {
66
- const b = await Bitfield.open(s)
67
- t.ok(b.get(142))
68
- t.ok(b.get(40000))
69
- t.ok(b.get(1424242424))
70
- }
71
- })
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
- })