1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
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)
}
|