Skip to content

Adding docs to hypercore-streams #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# hypercore-streams

External implementation of a WriteStream and ReadStream for Hypercore
Implementation of WriteStream and ReadStream for [hypercore](https://github.com/hypercore-protocol/hypercore).

```
npm install hypercore-streams
Expand All @@ -11,12 +11,31 @@ npm install hypercore-streams
``` js
const { WriteStream, ReadStream } = require('hypercore-streams')

const ws = new WriteStream(feed)
const rs = new ReadStream(feed, {
start: 0,
live: true,
valueEncoding: 'json'
})
const ws = new WriteStream(feed, [options])
const rs = new ReadStream(feed, [options])
```

Options for `WriteStream`:

```js
{
maxBlockSize: Infinity // set this to auto chunk individual blocks if they are larger than this number
}
```

Options for `ReadStream`:

```js
{
start: 0, // read from this index
end: feed.length, // read until this index
snapshot: true, // if set to false it will update `end` to `feed.length` on every read
tail: false, // sets `start` to `feed.length`
live: false, // set to true to keep reading forever
timeout: 0, // timeout for each data event (0 means no timeout)
wait: true, // wait for data to be downloaded
batch: 1 // amount of messages to read in batch, increasing it (e.g. 100) can improve the performance reading
}
```

## License
Expand Down
16 changes: 16 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class ReadStream extends Readable {
this.tail = !!opts.tail
this.index = this.start
this.options = { wait: opts.wait !== false, ifAvailable: !!opts.ifAvailable, valueEncoding: opts.valueEncoding }
this.batch = opts.batch || 1
}

_open (cb) {
Expand All @@ -63,6 +64,21 @@ class ReadStream extends Readable {
this.push(null)
return cb(null)
}
if (this.batch > 1) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs to check if feed.getBatch exists also (remotehypercore does not have this atm)

Copy link
Contributor Author

@martinheidegger martinheidegger Nov 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be good to test the streams against remotehypercore as well? Or in other words: Is it desirable to consider remotehypercore as valid full implementation of the "hypercore-interface"?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already test it in hyperspace. This should only test against the "source of truth" which is hypercore :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about a PR to remote-hypercore that adds getBatch?

const batchStart = this.index
const batchEnd = Math.min(batchStart + this.batch, this.end, this.feed.length)
if (batchStart < batchEnd) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think this would ever trigger an else? ie, can we drop the if

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There could be an "undownload" operation or something alike happening inbetween. But testing for that is surely tricky.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how that would trigger it still

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I looked into it a bit more. I am not sure I am able to phrase this correctly, but you can replicate my findings by throwing an error statement in a else block: } else { throw new Error('foo') } and then run the tests (this case is actually already covered by the tests case.

My understanding, formatted in a way that I could add it as comment to the code :)

// A batched live stream may start with an empty stream, resulting in both
// `batchEnd` and `batchStart` to be `0`. In this case a download needs to take place and
// we fall back to `get()` operation as it will trigger a download of the blocks linearly.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this feels like it should be encapsulated with a IsBatchFinished or something that returns a bool, which you can call inside of if logic. Thank you for your contribution.

this.index = batchEnd
this.feed.getBatch(batchStart, batchEnd, this.options, (err, blocks) => {
if (err) return cb(err)
for (const block of blocks) {
this.push(block)
}
cb(null)
})
return
}
}
this.feed.get(this.index++, this.options, (err, block) => {
if (err) return cb(err)
this.push(block)
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,20 @@
"hypercore": "^9.2.1",
"random-access-memory": "^3.1.1",
"standard": "^14.3.4",
"stream-collector": "^1.0.1",
"tape": "^5.0.1"
},
"scripts": {
"test": "standard && tape test.js"
"test": "standard && tape test/index.js"
},
"repository": {
"type": "git",
"url": "https://github.com/mafintosh/hypercore-streams.git"
"url": "https://github.com/hypercore-protocol/hypercore-streams.git"
},
"author": "Mathias Buus (@mafintosh)",
"license": "MIT",
"bugs": {
"url": "https://github.com/mafintosh/hypercore-streams/issues"
"url": "https://github.com/hypercore-protocol/hypercore-streams/issues"
},
"homepage": "https://github.com/mafintosh/hypercore-streams"
"homepage": "https://github.com/hypercore-protocol/hypercore-streams"
}
109 changes: 0 additions & 109 deletions test.js

This file was deleted.

27 changes: 27 additions & 0 deletions test/helpers/create-tracking-ram.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const ram = require('random-access-memory')

module.exports = function () {
const logByFilename = {}
const factory = function (filename) {
const memory = ram()
const log = []
logByFilename[filename] = log
return {
read: logAndForward('read'),
write: logAndForward('write'),
del: logAndForward('del')
}

function logAndForward (op) {
return function () {
var statement = {}
statement[op] = [].slice.apply(arguments)
statement[op].pop()
log.push(statement)
return memory[op].apply(memory, arguments)
}
}
}
factory.log = logByFilename
return factory
}
Loading