├── .gitignore ├── LICENSE ├── README.md ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Mathias Buus 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hypercored 2 | 3 | A daemon that can download and share multiple hypercores and hyperdrives. Supports seeding them to the browser over WebSockets as well. 4 | Backed by [hypercore-archiver](https://github.com/mafintosh/hypercore-archiver) 5 | 6 | ``` 7 | npm install -g hypercored 8 | ``` 9 | 10 | ## Usage 11 | 12 | ``` js 13 | # will watch ./feeds and store data in ./archiver 14 | hypercored 15 | ``` 16 | 17 | For more info run 18 | 19 | ``` 20 | Usage: hypercored [key?] [options] 21 | 22 | --cwd [folder to run in] 23 | --websockets [share over websockets as well] 24 | --port [explicit websocket port] 25 | --no-swarm [disable swarming] 26 | ``` 27 | 28 | ## License 29 | 30 | MIT 31 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | process.title = 'hypercored' 4 | 5 | var datDns = require('dat-dns')() 6 | var wss = require('websocket-stream') 7 | var archiver = require('hypercore-archiver') 8 | var swarm = require('hypercore-archiver/swarm') 9 | var readFile = require('read-file-live') 10 | var minimist = require('minimist') 11 | var path = require('path') 12 | var pump = require('pump') 13 | var http = require('http') 14 | 15 | var argv = minimist(process.argv.slice(2)) 16 | var cwd = argv.cwd || process.cwd() 17 | var ar = archiver(path.join(cwd, 'archiver'), argv._[0]) 18 | var server = http.createServer() 19 | var port = argv.port || process.env.PORT || 0 20 | var unencryptedWebsockets = !!argv['unencrypted-websockets'] 21 | 22 | if (argv.help) { 23 | console.log( 24 | 'Usage: hypercored [key?] [options]\n\n' + 25 | ' --cwd [folder to run in]\n' + 26 | ' --websockets [share over websockets as well]\n' + 27 | ' --port [explicit websocket port]\n' + 28 | ' --no-swarm [disable swarming]\n' 29 | ) 30 | process.exit(0) 31 | } 32 | 33 | if (unencryptedWebsockets) { 34 | argv.websockets = true 35 | } 36 | 37 | ar.on('sync', function (feed) { 38 | console.log('Fully synced', feed.key.toString('hex')) 39 | }) 40 | 41 | ar.on('add', function (feed) { 42 | console.log('Adding', feed.key.toString('hex')) 43 | }) 44 | 45 | ar.on('remove', function (feed) { 46 | console.log('Removing', feed.key.toString('hex')) 47 | }) 48 | 49 | ar.on('changes', function (feed) { 50 | console.log('Archiver key is ' + feed.key.toString('hex')) 51 | }) 52 | 53 | console.log('Watching %s for a list of active feeds', path.join(cwd, 'feeds')) 54 | 55 | wss.createServer({server: server}, onwebsocket) 56 | server.on('request', function (req, res) { 57 | res.setHeader('Content-Type', 'application/json') 58 | res.end(JSON.stringify({ 59 | name: 'hypercored', 60 | version: require('./package').version 61 | })) 62 | }) 63 | 64 | if (argv.swarm !== false) { 65 | swarm(ar, {live: true}).on('listening', function () { 66 | console.log('Swarm listening on port %d', this.address().port) 67 | }) 68 | } 69 | 70 | if (argv.websockets === true) { 71 | server.listen(port, function () { 72 | console.log('WebSocket server listening on port %d', server.address().port) 73 | }) 74 | } 75 | 76 | function resolveAll (links, cb) { 77 | var keys = [] 78 | var missing = links.length 79 | 80 | if (!missing) return cb(null, []) 81 | 82 | for (var i = 0; i < links.length; i++) { 83 | datDns.resolveName(links[i], function (_, key) { 84 | keys.push(key) 85 | if (!--missing) cb(null, keys.filter(Boolean)) 86 | }) 87 | } 88 | } 89 | 90 | readFile(path.join(cwd, 'feeds'), function (file) { 91 | resolveAll(file.toString().trim().split('\n'), function (err, feeds) { 92 | if (err) return 93 | 94 | ar.list(function (err, keys) { 95 | if (err || !ar.changes.writable) return 96 | 97 | var i = 0 98 | 99 | for (i = 0; i < keys.length; i++) { 100 | if (feeds.indexOf(keys[i].toString('hex')) === -1) ar.remove(keys[i]) 101 | } 102 | for (i = 0; i < feeds.length; i++) { 103 | ar.add(feeds[i]) 104 | } 105 | }) 106 | }) 107 | }) 108 | 109 | function onwebsocket (stream) { 110 | pump(stream, ar.replicate({live: true, encrypt: !unencryptedWebsockets}), stream) 111 | } 112 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hypercored", 3 | "version": "1.4.1", 4 | "description": "A daemon that can download and share multiple hypercores and hyperdrives", 5 | "main": "index.js", 6 | "dependencies": { 7 | "dat-dns": "^1.3.2", 8 | "hypercore-archiver": "^4.1.0", 9 | "minimist": "^1.2.0", 10 | "pump": "^1.0.2", 11 | "read-file-live": "^1.0.1", 12 | "websocket-stream": "^5.0.0" 13 | }, 14 | "devDependencies": { 15 | "standard": "^10.0.2" 16 | }, 17 | "bin": { 18 | "hypercored": "./index.js" 19 | }, 20 | "scripts": { 21 | "test": "standard" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/mafintosh/hypercored.git" 26 | }, 27 | "author": "Mathias Buus (@mafintosh)", 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/mafintosh/hypercored/issues" 31 | }, 32 | "homepage": "https://github.com/mafintosh/hypercored" 33 | } 34 | --------------------------------------------------------------------------------