const Hypermerge = require('hypermerge')
const {EventEmitter} = require('events')
// It's normal for a chat channel with a lot of participants
// to have a lot of connections, so increase the limit to
// avoid warnings about emitter leaks
EventEmitter.prototype._maxListeners = 100
class Channel extends EventEmitter {
constructor ({channelKey, nick, path}) {
super()
this.channelKey = channelKey
this.nick = nick
this.hm = new Hypermerge({path: path})
this.hm.once('ready', this.setup.bind(this))
}
/**
* Either create a new channel or join an existing one
*/
setup (hm) {
hm.joinSwarm() // Fire up the network
if (!this.channelKey) {
// We're starting a new channel here, so first
// initialize the new channel document data structure.
hm.create()
hm.once('document:ready', (docId, doc) => {
this.channelKey = docId
this.doc = hm.change(doc, changeDoc => {
changeDoc.messages = {}
})
this.ready(this.doc)
})
} else {
console.log('Searching for chat channel on network...')
hm.open(this.channelKey)
hm.once('document:ready', (docId, doc) => { this.ready(doc) })
}
}
/**
* Everything is setup, send an event to signal the UI to
* start, and setup listeners to watch for remote document updates.
*/
ready (doc) {
console.log('ready call for', this.nick, doc);
this.doc = doc
this.joinChannel()
this.emit('ready', this)
// We merge any new documents that arrive due to events,
// but we don't update our hypercores
this.hm.on('document:updated', (docId, doc) => {
console.log('document updated', this.nick, docId);
this.doc = doc
this.emit('updated', this)
})
}
/**
* Post a chat message announcing someone has joined
*/
joinChannel () {
console.log('join this doc', this.doc);
this.doc = this.hm.change(this.doc, changeDoc => {
changeDoc.messages[Date.now()] = {
nick: this.nick,
joined: true
}
})
}
/**
* Called from the UI whenever somebody posts a message
*/
addMessageToDoc (line) {
const message = line.trim()
if (message.length === 0) return this.doc
this.doc = this.hm.change(this.doc, changeDoc => {
changeDoc.messages[Date.now()] = {
nick: this.nick,
message: line
}
})
return this.doc
}
/**
* Getter to return the number of connections for the UI
*/
getNumConnections () {
return this.hm.swarm.connections.length
}
}
//change this to channelKey after on second run
let KEY =null;
let chan1 = new Channel({nick: 'a1', path: 'a1/', channelKey: '2314d2c39da3cc8b46b159d001eafb32719ed0a280d43687bb6798d1776a9dc9'})
chan1.on('ready', () => {
console.log('key', chan1.channelKey);
console.log('doc in chan1', chan1.doc);
let chan2 = new Channel({nick: 'a2', channelKey: chan1.channelKey, path:'a2')})
chan2.on('ready', (chan3) => {
let docId = chan2.hm.getId(chan2.doc);
let newdoc = chan2.addMessageToDoc('hello world');
console.log('final', docId, newdoc);
})
})