hypercore 10.0.0-alpha.8 → 10.1.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/lib/streams.js ADDED
@@ -0,0 +1,56 @@
1
+ const { Writable, Readable } = require('streamx')
2
+
3
+ class ReadStream extends Readable {
4
+ constructor (core, opts = {}) {
5
+ super()
6
+
7
+ this.core = core
8
+ this.start = opts.start || 0
9
+ this.end = typeof opts.end === 'number' ? opts.end : -1
10
+ this.snapshot = !opts.live && opts.snapshot !== false
11
+ this.live = !!opts.live
12
+ }
13
+
14
+ _open (cb) {
15
+ this._openP().then(cb, cb)
16
+ }
17
+
18
+ _read (cb) {
19
+ this._readP().then(cb, cb)
20
+ }
21
+
22
+ async _openP () {
23
+ if (this.end === -1) await this.core.update()
24
+ else await this.core.ready()
25
+ if (this.snapshot && this.end === -1) this.end = this.core.length
26
+ }
27
+
28
+ async _readP () {
29
+ const end = this.live ? -1 : (this.end === -1 ? this.core.length : this.end)
30
+ if (end >= 0 && this.start >= end) {
31
+ this.push(null)
32
+ return
33
+ }
34
+
35
+ this.push(await this.core.get(this.start++))
36
+ }
37
+ }
38
+
39
+ exports.ReadStream = ReadStream
40
+
41
+ class WriteStream extends Writable {
42
+ constructor (core) {
43
+ super()
44
+ this.core = core
45
+ }
46
+
47
+ _writev (batch, cb) {
48
+ this._writevP(batch).then(cb, cb)
49
+ }
50
+
51
+ async _writevP (batch) {
52
+ await this.core.append(batch)
53
+ }
54
+ }
55
+
56
+ exports.WriteStream = WriteStream
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "hypercore",
3
- "version": "10.0.0-alpha.8",
4
- "description": "Hypercore 10",
3
+ "version": "10.1.0",
4
+ "description": "Hypercore is a secure, distributed append-only log",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
- "test": "standard && brittle test/*.js"
7
+ "test": "standard && node test/all.js",
8
+ "test:generate": "brittle -r test/all.js test/*.js"
8
9
  },
9
10
  "repository": {
10
11
  "type": "git",
@@ -27,30 +28,35 @@
27
28
  "url": "https://github.com/hypercore-protocol/hypercore/issues"
28
29
  },
29
30
  "homepage": "https://github.com/hypercore-protocol/hypercore#readme",
31
+ "files": [
32
+ "index.js",
33
+ "lib/**.js"
34
+ ],
30
35
  "dependencies": {
31
- "@hyperswarm/secret-stream": "^5.0.0",
36
+ "@hyperswarm/secret-stream": "^6.0.0",
37
+ "b4a": "^1.1.0",
32
38
  "big-sparse-array": "^1.0.2",
33
- "codecs": "^2.2.0",
34
- "compact-encoding": "^2.5.0",
39
+ "bits-to-bytes": "^1.3.0",
40
+ "compact-encoding": "^2.11.0",
35
41
  "crc32-universal": "^1.0.1",
42
+ "events": "^3.3.0",
36
43
  "flat-tree": "^1.9.0",
37
- "hypercore-crypto": "^2.1.1",
44
+ "hypercore-crypto": "^3.2.1",
38
45
  "is-options": "^1.0.1",
39
- "random-access-file": "^2.1.4",
46
+ "protomux": "^3.2.0",
47
+ "random-access-file": "^3.2.2",
40
48
  "random-array-iterator": "^1.0.0",
41
49
  "safety-catch": "^1.0.1",
42
50
  "sodium-universal": "^3.0.4",
43
- "uint64le": "^1.0.0",
44
- "xache": "^1.0.0"
51
+ "streamx": "^2.12.4",
52
+ "xache": "^1.1.0"
45
53
  },
46
54
  "devDependencies": {
47
- "brittle": "^1.4.1",
48
- "hyperswarm": "next",
49
- "random-access-memory": "^3.1.2",
55
+ "brittle": "^3.0.0",
56
+ "hyperswarm": "^4.1.1",
57
+ "random-access-memory": "^5.0.1",
58
+ "random-access-memory-overlay": "^2.0.0",
50
59
  "standard": "^16.0.3",
51
60
  "tmp-promise": "^3.0.2"
52
- },
53
- "optionalDependencies": {
54
- "fsctl": "^1.0.0"
55
61
  }
56
62
  }
@@ -1,23 +0,0 @@
1
- name: Build Status
2
- on:
3
- push:
4
- branches:
5
- - master
6
- pull_request:
7
- branches:
8
- - master
9
- jobs:
10
- build:
11
- strategy:
12
- matrix:
13
- node-version: [lts/*]
14
- os: [ubuntu-latest, macos-latest, windows-latest]
15
- runs-on: ${{ matrix.os }}
16
- steps:
17
- - uses: actions/checkout@v2
18
- - name: Use Node.js ${{ matrix.node-version }}
19
- uses: actions/setup-node@v2
20
- with:
21
- node-version: ${{ matrix.node-version }}
22
- - run: npm install
23
- - run: npm test
package/CHANGELOG.md DELETED
@@ -1,37 +0,0 @@
1
- # CHANGELOG
2
-
3
- See [UPGRADE.md](UPGRADE.md) for notes on breaking changes for downstream developers.
4
-
5
- ## Current
6
-
7
- ## v9.5.0
8
-
9
- - Feed close makes the replication detach the channel used for this particular stream.
10
-
11
- ## v9.4.0
12
-
13
- - feed.get accepts onwait hook, that is called if get is waiting for a network peer.
14
-
15
- ## v9.3.0
16
-
17
- - feed.get returns an id, that can be used to cancel a pending get with feed.cancel(getId)
18
-
19
- ## v9.2.0
20
-
21
- - Add `maxBlockSize` on write streams to auto chunk big blocks being written.
22
-
23
- ## v9.1.0
24
-
25
- - Make peer.remoteOpened public ([#268](https://github.com/hypercore-protocol/hypercore/pull/268))
26
-
27
- ## v9.0.1
28
-
29
- - Upgraded standard to v14 with subsequent formatting tweaks
30
- - createReadStream is up to 8x faster now! ([#261](https://github.com/hypercore-protocol/hypercore/pull/261) by [@tinchoz49](https://github.com/tinchoz49))
31
- - Fixed benchmarks ([#266](https://github.com/hypercore-protocol/hypercore/pull/266) by [@fwip](https://github.com/fwip))
32
-
33
- ## v9.0.0
34
-
35
- - Ease of use update to signatures, https://github.com/mafintosh/hypercore/issues/260
36
- - Updates [noise-protocol](https://github.com/emilbayes/noise-protocol) to latest, which uses chacha instead of xchacha and moves avoid from the sodium kx api for better compatability with the rest of the Noise ecosystem.
37
- - Updates [sodium-native](https://github.com/sodium-friends/sodium-native) from 2 to 3 across the board. 3 uses n-api, so no more builds needed when Node is released.
package/UPGRADE.md DELETED
@@ -1,9 +0,0 @@
1
- # Upgrade Notes
2
-
3
- Notes for downstream developers who are upgrading their modules to new, breaking versions of hypercore.
4
-
5
- ## 9.0.0
6
-
7
- - The format of signatures [has been changed](https://github.com/mafintosh/hypercore/issues/260). This is backwards-compatible (v9 can read v8 signatures), but forward-incompatible (v8 cannot read v9 signatures). If a v8 peer replicates with a v9 peer, it will emit a "REMOTE SIGNTURE INVALID" error on the replication stream.
8
- - The encryption ([NOISE](https://github.com/emilbayes/noise-protocol)) handshake has been changed in an backwards- and forwards-incompatible way. v8 peers can not handshake with v9 peers, and vice-versa. A NOISE-related error is emitted on the replication stream.
9
- - There is no way (yet) to detect whether a peer is running an incompatible version of hypercore at the replication level. One workaround for downstream developers is to include their own application-level handshake before piping to the replication stream, to communicate a "app protocol version" (maybe "v8" and "v9") and abort the connection if the peer is running an incompatible version.
@@ -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/lib/extensions.js DELETED
@@ -1,76 +0,0 @@
1
- class Extension {
2
- constructor (extensions, name, handlers) {
3
- this.extensions = extensions
4
- this.name = name
5
- this.encoding = handlers.encoding
6
- this.destroyed = false
7
- // TODO: should avoid the bind here by calling directly on handlers instead?
8
- this.onmessage = (handlers.onmessage || noop).bind(handlers)
9
- this.onremotesupports = (handlers.onremotesupports || noop).bind(handlers)
10
- }
11
-
12
- send (message, peer) {
13
- if (this.destroyed) return
14
- const ext = peer.extensions.get(this.name)
15
- if (ext) ext.send(message)
16
- }
17
-
18
- broadcast (message) {
19
- if (this.extensions.replicator === null || this.destroyed) return
20
- for (const peer of this.extensions.replicator.peers) this.send(message, peer)
21
- }
22
-
23
- destroy () {
24
- if (this.destroyed) return
25
- this.destroyed = true
26
- this.extensions.all.delete(this.name)
27
- if (this.extensions.replicator === null) return
28
- for (const peer of this.extensions.replicator.peers) {
29
- const ext = peer.extensions.get(this.name)
30
- if (ext) ext.destroy()
31
- }
32
- }
33
- }
34
-
35
- module.exports = class Extensions {
36
- constructor () {
37
- this.replicator = null
38
- this.all = new Map()
39
- }
40
-
41
- [Symbol.iterator] () {
42
- return this.all[Symbol.iterator]()
43
- }
44
-
45
- attach (replicator) {
46
- if (replicator === this.replicator) return
47
- this.replicator = replicator
48
-
49
- for (const [name, ext] of this.all) {
50
- for (const peer of this.replicator.peers) {
51
- peer.registerExtension(name, ext)
52
- }
53
- }
54
- }
55
-
56
- register (name, handlers, ext = new Extension(this, name, handlers)) {
57
- if (this.all.has(name)) this.all.get(name).destroy()
58
- this.all.set(name, ext)
59
-
60
- if (this.replicator !== null) {
61
- for (const peer of this.replicator.peers) {
62
- peer.registerExtension(name, ext)
63
- }
64
- }
65
-
66
- return ext
67
- }
68
-
69
- update (peer) {
70
- for (const ext of this.all.values()) {
71
- peer.registerExtension(ext.name, ext)
72
- }
73
- }
74
- }
75
-
76
- function noop () {}