aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts/lib/remote-store.js
blob: c81d5151cfb1e06b0b1809711f0ee43f788195ad (plain) (blame)
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)
}