const Dnode = require('dnode') const inherits = require('util').inherits module.exports = { HostStore: HostStore, RemoteStore: RemoteStore, } function BaseStore(initState){ this._state = initState || {} this._subs = [] } BaseStore.prototype.set = function(key, value){ throw Error('Not implemented.') } BaseStore.prototype.get = function(key){ return this._state[key] } BaseStore.prototype.subscribe = function(fn){ this._subs.push(fn) var unsubscribe = this.unsubscribe.bind(this, fn) return unsubscribe } BaseStore.prototype.unsubscribe = function(fn){ var index = this._subs.indexOf(fn) if (index !== -1) this._subs.splice(index, 1) } BaseStore.prototype._emitUpdates = function(state){ this._subs.forEach(function(handler){ handler(state) }) } // // host // inherits(HostStore, BaseStore) function HostStore(initState, opts){ BaseStore.call(this, initState) } HostStore.prototype.set = function(key, value){ this._state[key] = value process.nextTick(this._emitUpdates.bind(this, this._state)) } HostStore.prototype.createStream = function(){ var dnode = Dnode({ // update: this._didUpdate.bind(this), }) dnode.on('remote', this._didConnect.bind(this)) return dnode } HostStore.prototype._didConnect = function(remote){ this.subscribe(function(state){ remote.update(state) }) remote.update(this._state) } // // remote // inherits(RemoteStore, BaseStore) function RemoteStore(initState, opts){ BaseStore.call(this, initState) this._remote = null } RemoteStore.prototype.set = function(key, value){ this._remote.set(key, value) } RemoteStore.prototype.createStream = function(){ var dnode = Dnode({ update: this._didUpdate.bind(this), }) dnode.once('remote', this._didConnect.bind(this)) return dnode } RemoteStore.prototype._didConnect = function(remote){ this._remote = remote } RemoteStore.prototype._didUpdate = function(state){ this._state = state this._emitUpdates(state) }