-
-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 47d307b
Showing
8 changed files
with
1,062 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
*.pid.lock | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# Bower dependency directory (https://bower.io/) | ||
bower_components | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (https://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules/ | ||
jspm_packages/ | ||
|
||
# TypeScript v1 declaration files | ||
typings/ | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional eslint cache | ||
.eslintcache | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Output of 'npm pack' | ||
*.tgz | ||
|
||
# Yarn Integrity file | ||
.yarn-integrity | ||
|
||
# dotenv environment variables file | ||
.env | ||
|
||
# next.js build output | ||
.next |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
language: node_js | ||
|
||
node_js: | ||
- '6' | ||
- '8' | ||
sudo: false | ||
|
||
script: | ||
- npm test |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# cabal-node | ||
|
||
Node.js library for p2p functions for chat. | ||
|
||
## Usage | ||
|
||
npm install cabal-node | ||
|
||
## API | ||
|
||
<!-- Generated by documentation.js. Update this documentation by updating the source code. --> | ||
|
||
#### Table of Contents | ||
|
||
- [Cabal](#cabal) | ||
- [onconnection](#onconnection) | ||
- [joinChannel](#joinchannel) | ||
- [leaveChannel](#leavechannel) | ||
- [createReadStream](#createreadstream) | ||
- [message](#message) | ||
- [replicate](#replicate) | ||
|
||
### Cabal | ||
|
||
Create a new Cabal. This is the object handling all | ||
local nickname -> cabal interactions for a single user. | ||
|
||
**Parameters** | ||
|
||
- `storage` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function))** A hyperdb compatible storage function, or a string representing the local data path. | ||
- `href` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The dat link | ||
- `opts` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Options include: username | ||
|
||
#### onconnection | ||
|
||
When a connection is made. Auto-authorizes new peers to | ||
write to the local database. Maintains the local view | ||
of visible users. | ||
|
||
**Parameters** | ||
|
||
- `peer` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The discovery-swarm peer emitted from the 'connection' or 'disconnection' event | ||
|
||
#### joinChannel | ||
|
||
Join a channel. | ||
|
||
**Parameters** | ||
|
||
- `channel` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The channel to join. | ||
|
||
#### leaveChannel | ||
|
||
Leave a channel. | ||
|
||
**Parameters** | ||
|
||
- `channel` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The channel to leave. | ||
|
||
#### createReadStream | ||
|
||
Create a readable stream for the cabal channel. | ||
|
||
**Parameters** | ||
|
||
- `channel` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The channel you want to read from. | ||
|
||
#### message | ||
|
||
Create a message. | ||
|
||
**Parameters** | ||
|
||
- `channel` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The channel to create the message. | ||
- `message` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The message to write. | ||
- `opts` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Options: date, username | ||
- `done` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** When message has been successfully added. | ||
|
||
#### replicate | ||
|
||
Replication stream for the cabal. Shares the username with the | ||
other peers it is connecting with. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
var hyperdb = require('hyperdb') | ||
var strftime = require('strftime') | ||
var events = require('events') | ||
var encoding = require('dat-encoding') | ||
var inherits = require('inherits') | ||
|
||
module.exports = Cabal | ||
|
||
/** | ||
* Create a new cabal. This is the object handling all | ||
* local nickname -> mesh interactions for a single user. | ||
* @constructor | ||
* @param {string|function} storage - A hyperdb compatible storage function, or a string representing the local data path. | ||
* @param {string} href - The dat link | ||
* @param {Object} opts - Options include: username | ||
*/ | ||
function Cabal (storage, href, opts) { | ||
if (!(this instanceof Cabal)) return new Cabal(storage, href, opts) | ||
if (!opts) opts = {} | ||
events.EventEmitter.call(this) | ||
var self = this | ||
|
||
var json = { | ||
encode: function (obj) { | ||
return Buffer.from(JSON.stringify(obj)) | ||
}, | ||
decode: function (buf) { | ||
var str = buf.toString('utf8') | ||
try { var obj = JSON.parse(str) } | ||
catch (err) { return {} } | ||
return obj | ||
} | ||
} | ||
|
||
self.username = opts.username || 'anonymous' | ||
|
||
try { | ||
var key = encoding.decode(href) | ||
self.addr = encoding.encode(key) | ||
} catch (e) { | ||
self.addr = null | ||
} | ||
self.db = self.addr | ||
? hyperdb(storage, self.addr, {valueEncoding: json}) | ||
: hyperdb(storage, {valueEncoding: json}) | ||
|
||
self.channels = {} | ||
self.users = {} | ||
self.users[opts.username] = new Date() | ||
} | ||
|
||
inherits(Cabal, events.EventEmitter) | ||
|
||
/** | ||
* When a connection is made. Auto-authorizes new peers to | ||
* write to the local database. Maintains the local view | ||
* of visible users. | ||
* @param {Object} peer - The discovery-swarm peer emitted from the 'connection' or 'disconnection' event | ||
*/ | ||
Cabal.prototype.onconnection = function (peer) { | ||
var self = this | ||
if (!peer.remoteUserData) return | ||
try { var data = JSON.parse(peer.remoteUserData) } | ||
catch (err) { return } | ||
var key = Buffer.from(data.key) | ||
var username = data.username | ||
|
||
self.db.authorized(key, function (err, auth) { | ||
if (err) return console.log(err) | ||
if (!auth) self.db.authorize(key, function (err) { | ||
if (err) return console.log(err) | ||
}) | ||
}) | ||
|
||
if (!self.users[username]) { | ||
self.users[username] = new Date() | ||
self.emit('join', username) | ||
peer.on('close', function () { | ||
if (!self.users[username]) return | ||
delete self.users[username] | ||
self.emit('leave', username) | ||
}) | ||
} | ||
} | ||
|
||
/** | ||
* Join a channel. | ||
* @param {String} channel - The channel to join. | ||
*/ | ||
Cabal.prototype.joinChannel = function (channel) { | ||
this.channels[channel] = true | ||
} | ||
|
||
/** | ||
* Leave a channel. | ||
* @param {String} channel - The channel to leave. | ||
*/ | ||
Cabal.prototype.leaveChannel = function (channel) { | ||
delete this.channels[channel] | ||
} | ||
|
||
/** | ||
* Create a readable stream for the mesh. | ||
* @param {String} channel - The channel you want to read from. | ||
*/ | ||
Cabal.prototype.createReadStream = function (channel, opts) { | ||
if (!opts) opts = {} | ||
return this.db.createReadStream(`${channel}/messages`, Object.assign({recursive: true}, opts)) | ||
} | ||
|
||
/** | ||
* Get the metadata of channel. | ||
* @param {String} channel Channel name | ||
* @param {Function} done Callback | ||
*/ | ||
Cabal.prototype.metadata = function (channel, done) { | ||
this.db.get(`${channel}/metadata`, function (err, data) { | ||
if (err) return done(err) | ||
var node = (data.length ? data[0].value : {latest: 0}) | ||
done(null, node) | ||
}) | ||
} | ||
|
||
/** | ||
* Create a message. | ||
* @param {String} channel - The channel to create the message. | ||
* @param {String} message - The message to write. | ||
* @param {Object} opts - Options: date, username | ||
* @param {function} done - When message has been successfully added. | ||
*/ | ||
Cabal.prototype.message = function (channel, message, opts, done) { | ||
if (typeof opts === 'function') return this.message(channel, message, null, opts) | ||
if (!opts) opts = {} | ||
var self = this | ||
if (!message) return done() | ||
var username = opts.username || self.username | ||
self.metadata(channel, function (err, metadata) { | ||
if (err) return done(err) | ||
var latest = parseInt(metadata.latest) | ||
var newLatest = latest + 1 | ||
var key = `${channel}/messages/${newLatest}` | ||
var d = opts.date || new Date() | ||
var date = new Date(d.valueOf() + d.getTimezoneOffset()*60*1000) | ||
self.db.put(key, {username, date, message}, function () { | ||
metadata.latest = newLatest | ||
self.db.put(`${channel}/metadata`, metadata, done) | ||
}) | ||
}) | ||
} | ||
|
||
/** | ||
* Replication stream for the mesh. Shares the username with the | ||
* other peers it is connecting with. | ||
*/ | ||
Cabal.prototype.replicate = function () { | ||
var self = this | ||
return this.db.replicate({ | ||
live: true, | ||
userData: JSON.stringify({ | ||
key: self.db.local.key, | ||
username: self.username | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{ | ||
"name": "cabal-node", | ||
"version": "1.0.0", | ||
"description": " p2p db functions for chat ", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "node test.js", | ||
"docs": "documentation readme index.js --section=API" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/cabal-club/cabal-node.git" | ||
}, | ||
"keywords": [ | ||
"cabal", | ||
"decentralized", | ||
"swarm", | ||
"chat", | ||
"p2p", | ||
"hyperdb" | ||
], | ||
"author": "Karissa McKelvey", | ||
"license": "AGPL-3.0", | ||
"bugs": { | ||
"url": "https://github.com/cabal-club/cabal-node/issues" | ||
}, | ||
"homepage": "https://github.com/cabal-club/cabal-node#readme", | ||
"dependencies": { | ||
"crypto": "^1.0.1", | ||
"dat-swarm-defaults": "^1.0.1", | ||
"discovery-swarm": "^5.1.1", | ||
"hyperdb": "^3.0.0-3", | ||
"strftime": "^0.10.0" | ||
}, | ||
"devDependencies": { | ||
"collect-stream": "^1.2.1", | ||
"documentation": "^6.3.2", | ||
"random-access-memory": "^3.0.0", | ||
"tape": "^4.9.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
var discovery = require('discovery-swarm') | ||
var swarmDefaults = require('dat-swarm-defaults') | ||
|
||
module.exports = function (cabal) { | ||
var swarm = discovery(swarmDefaults({ | ||
id: cabal.db.local.key, | ||
stream: function (peer) { | ||
return cabal.replicate() | ||
} | ||
})) | ||
var key = cabal.addr || cabal.db.key | ||
swarm.join(key.toString('hex')) | ||
swarm.on('connection', cabal.onconnection.bind(cabal)) | ||
return swarm | ||
} |
Oops, something went wrong.