hippodrome 0.0.10 → 0.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +13 -0
- data/app/assets/javascripts/hippodrome.js +245 -0
- data/lib/hippodrome/version.rb +3 -1
- metadata +3 -22
- data/app/assets/javascripts/action.js.coffee +0 -22
- data/app/assets/javascripts/assert.js.coffee +0 -12
- data/app/assets/javascripts/dispatcher.js.coffee +0 -83
- data/app/assets/javascripts/hippodrome.js.coffee +0 -5
- data/app/assets/javascripts/side_effect.js.coffee +0 -19
- data/app/assets/javascripts/store.js.coffee +0 -52
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2cade2f33b8f261faf01d57453b3776b6603c2e4
|
4
|
+
data.tar.gz: ace2d0166e2fa55b203d098c472a4bbfd91c385f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49a39346480f430a5ca599a90a2febb65a46ebc7aaac0b4930afdcc4e001b397a088f839a7634d22bd3cd956cdf6fabb304ae4c7d7372d221debf0ebc15379d1
|
7
|
+
data.tar.gz: 6903cf94ec164280f96eef6e47e9db56c4d9c3a73c320fab61da1c7ad777e8e563da442e74378c8a74354a563a62a4be7101ad692cf2025bf77cc3a0fc7bd74e
|
data/README.md
CHANGED
@@ -20,6 +20,8 @@ response.
|
|
20
20
|
|
21
21
|
## Installation
|
22
22
|
|
23
|
+
### Rails
|
24
|
+
|
23
25
|
Add this line to your application's Gemfile:
|
24
26
|
|
25
27
|
gem 'hippodrome'
|
@@ -32,12 +34,23 @@ Or install it yourself as:
|
|
32
34
|
|
33
35
|
$ gem install hippodrome
|
34
36
|
|
37
|
+
### Node
|
38
|
+
|
39
|
+
npm install --save hippodrome
|
40
|
+
|
35
41
|
## Usage
|
36
42
|
|
43
|
+
### Rails
|
44
|
+
|
37
45
|
In your javascript manifest file:
|
38
46
|
|
39
47
|
//= require hippodrome
|
40
48
|
|
49
|
+
### Node
|
50
|
+
|
51
|
+
Hippodrome = require('hippodrome')
|
52
|
+
|
53
|
+
|
41
54
|
TODO: Explain how all the bits work.
|
42
55
|
|
43
56
|
## Contributing
|
@@ -0,0 +1,245 @@
|
|
1
|
+
//= require lodash
|
2
|
+
|
3
|
+
(function() {
|
4
|
+
var Action, Dispatcher, Hippodrome, SideEffect, Store, assert, bindToContextIfFunction, isNode, lastId, nextId, prefix, _,
|
5
|
+
__slice = [].slice;
|
6
|
+
|
7
|
+
isNode = typeof window === 'undefined';
|
8
|
+
|
9
|
+
if (isNode) {
|
10
|
+
_ = require('lodash');
|
11
|
+
} else {
|
12
|
+
_ = this._;
|
13
|
+
}
|
14
|
+
|
15
|
+
Hippodrome = {};
|
16
|
+
|
17
|
+
assert = function() {
|
18
|
+
var argIndex, args, condition, error, message;
|
19
|
+
condition = arguments[0], message = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
|
20
|
+
if (!condition) {
|
21
|
+
argIndex = 0;
|
22
|
+
error = new Error('Assertion Failed: ' + message.replace(/%s/g, function() {
|
23
|
+
return args[argIndex++];
|
24
|
+
}));
|
25
|
+
error.framesToPop = 1;
|
26
|
+
throw error;
|
27
|
+
}
|
28
|
+
return condition;
|
29
|
+
};
|
30
|
+
|
31
|
+
Action = function(name, ctor) {
|
32
|
+
var actionFn, buildPayload, send;
|
33
|
+
buildPayload = function() {
|
34
|
+
var payload;
|
35
|
+
payload = ctor.apply(null, arguments);
|
36
|
+
payload.action = name;
|
37
|
+
return payload;
|
38
|
+
};
|
39
|
+
send = function(payload) {
|
40
|
+
return Hippodrome.Dispatcher.dispatch(payload);
|
41
|
+
};
|
42
|
+
actionFn = function() {
|
43
|
+
var payload;
|
44
|
+
payload = buildPayload.apply(null, arguments);
|
45
|
+
return send(payload);
|
46
|
+
};
|
47
|
+
actionFn.buildPayload = buildPayload;
|
48
|
+
actionFn.send = send;
|
49
|
+
actionFn.hippoName = name;
|
50
|
+
actionFn.toString = function() {
|
51
|
+
return name;
|
52
|
+
};
|
53
|
+
return actionFn;
|
54
|
+
};
|
55
|
+
|
56
|
+
Hippodrome.Action = Action;
|
57
|
+
|
58
|
+
Dispatcher = function() {
|
59
|
+
this.callbacksByAction = {};
|
60
|
+
this.isStarted = {};
|
61
|
+
this.isFinished = {};
|
62
|
+
this.isDispatching = false;
|
63
|
+
return this.payload = null;
|
64
|
+
};
|
65
|
+
|
66
|
+
prefix = 'Dispatcher_ID_';
|
67
|
+
|
68
|
+
lastId = 1;
|
69
|
+
|
70
|
+
nextId = function() {
|
71
|
+
return prefix + lastId++;
|
72
|
+
};
|
73
|
+
|
74
|
+
Dispatcher.prototype.register = function() {
|
75
|
+
var action, args, callback, id, prereqStores, store, _base;
|
76
|
+
args = _.compact(arguments);
|
77
|
+
if (args.length === 3) {
|
78
|
+
return this.register(args[0], args[1], [], args[2]);
|
79
|
+
} else {
|
80
|
+
store = args[0], action = args[1], prereqStores = args[2], callback = args[3];
|
81
|
+
if ((_base = this.callbacksByAction)[action] == null) {
|
82
|
+
_base[action] = {};
|
83
|
+
}
|
84
|
+
id = nextId();
|
85
|
+
this.callbacksByAction[action][id] = {
|
86
|
+
callback: callback,
|
87
|
+
prerequisites: _.map(prereqStores, function(ps) {
|
88
|
+
return ps.dispatcherIdsByAction[action];
|
89
|
+
})
|
90
|
+
};
|
91
|
+
return id;
|
92
|
+
}
|
93
|
+
};
|
94
|
+
|
95
|
+
Dispatcher.prototype.unregister = function(action, id) {
|
96
|
+
assert(this.callbacksByAction[action][id], 'Dispatcher.unregister(%s, %s) does not map to a registered callback.', action, id);
|
97
|
+
return this.callbacks[action][id] = null;
|
98
|
+
};
|
99
|
+
|
100
|
+
Dispatcher.prototype.waitFor = function(action, ids) {
|
101
|
+
assert(this.isDispatching, 'Dispatcher.waitFor must be invoked while dispatching.');
|
102
|
+
return _.forEach(ids, (function(_this) {
|
103
|
+
return function(id) {
|
104
|
+
if (_this.isStarted[id]) {
|
105
|
+
assert(_this.isFinished[id], 'Dispatcher.waitFor encountered circular dependency while ' + 'waiting for `%s` during %s.', id, action);
|
106
|
+
return;
|
107
|
+
}
|
108
|
+
assert(_this.callbacksByAction[action][id], 'Dispatcher.waitFor `%s` is not a registered callback for %s.', id, action);
|
109
|
+
return _this.invokeCallback(action, id);
|
110
|
+
};
|
111
|
+
})(this));
|
112
|
+
};
|
113
|
+
|
114
|
+
Dispatcher.prototype.dispatch = function(payload) {
|
115
|
+
var action;
|
116
|
+
assert(!this.isDispatching, 'Dispatch.dispatch cannot be called during dispatch.');
|
117
|
+
this.startDispatching(payload);
|
118
|
+
try {
|
119
|
+
action = payload.action;
|
120
|
+
return _.forEach(this.callbacksByAction[action], (function(_this) {
|
121
|
+
return function(callback, id) {
|
122
|
+
if (_this.isStarted[id]) {
|
123
|
+
return;
|
124
|
+
}
|
125
|
+
return _this.invokeCallback(action, id);
|
126
|
+
};
|
127
|
+
})(this));
|
128
|
+
} finally {
|
129
|
+
this.stopDispatching();
|
130
|
+
}
|
131
|
+
};
|
132
|
+
|
133
|
+
Dispatcher.prototype.invokeCallback = function(action, id) {
|
134
|
+
var callback, prerequisites, _ref;
|
135
|
+
this.isStarted[id] = true;
|
136
|
+
_ref = this.callbacksByAction[action][id], callback = _ref.callback, prerequisites = _ref.prerequisites;
|
137
|
+
this.waitFor(action, prerequisites);
|
138
|
+
callback(this.payload);
|
139
|
+
return this.isFinished[id] = true;
|
140
|
+
};
|
141
|
+
|
142
|
+
Dispatcher.prototype.startDispatching = function(payload) {
|
143
|
+
this.isStarted = {};
|
144
|
+
this.isFinished = {};
|
145
|
+
this.payload = payload;
|
146
|
+
return this.isDispatching = true;
|
147
|
+
};
|
148
|
+
|
149
|
+
Dispatcher.prototype.stopDispatching = function() {
|
150
|
+
this.payload = null;
|
151
|
+
return this.isDispatching = false;
|
152
|
+
};
|
153
|
+
|
154
|
+
Hippodrome.Dispatcher = new Dispatcher();
|
155
|
+
|
156
|
+
SideEffect = function(options) {
|
157
|
+
var action, effect, id;
|
158
|
+
assert(options.action, 'SideEffect must register for exactly one action.');
|
159
|
+
assert(options.effect, 'SideEffect must supply exactly one effect to run');
|
160
|
+
action = options.action, effect = options.effect;
|
161
|
+
if (typeof effect === 'string') {
|
162
|
+
effect = this[effect];
|
163
|
+
}
|
164
|
+
effect = _.defer.bind(this, effect);
|
165
|
+
id = Hippodrome.Dispatcher.register(this, action.hippoName, [], effect);
|
166
|
+
this.dispatcherIdsByAction = {};
|
167
|
+
this.dispatcherIdsByAction[action.hippoName] = id;
|
168
|
+
return this;
|
169
|
+
};
|
170
|
+
|
171
|
+
Hippodrome.SideEffect = SideEffect;
|
172
|
+
|
173
|
+
bindToContextIfFunction = function(context) {
|
174
|
+
return function(objValue, srcValue) {
|
175
|
+
if (srcValue instanceof Function) {
|
176
|
+
return srcValue.bind(context);
|
177
|
+
} else {
|
178
|
+
return srcValue;
|
179
|
+
}
|
180
|
+
};
|
181
|
+
};
|
182
|
+
|
183
|
+
Store = function(options) {
|
184
|
+
this.dispatcherIdsByAction = {};
|
185
|
+
this.callbacks = [];
|
186
|
+
_.assign(this, _.omit(options, 'initialize', 'dispatches'), bindToContextIfFunction(this));
|
187
|
+
if (options.initialize) {
|
188
|
+
options.initialize.call(this);
|
189
|
+
}
|
190
|
+
if (options.dispatches) {
|
191
|
+
_.forEach(options.dispatches, (function(_this) {
|
192
|
+
return function(callbackDescription) {
|
193
|
+
var action, after, callback, id;
|
194
|
+
action = callbackDescription.action, after = callbackDescription.after, callback = callbackDescription.callback;
|
195
|
+
assert(!_this.dispatcherIdsByAction[action.hippoName], 'Each store can only register one callback for each action.');
|
196
|
+
if (typeof callback === 'string') {
|
197
|
+
callback = _this[callback];
|
198
|
+
}
|
199
|
+
callback = callback.bind(_this);
|
200
|
+
id = Hippodrome.Dispatcher.register(_this, action.hippoName, after, callback);
|
201
|
+
return _this.dispatcherIdsByAction[action.hippoName] = id;
|
202
|
+
};
|
203
|
+
})(this));
|
204
|
+
}
|
205
|
+
return this;
|
206
|
+
};
|
207
|
+
|
208
|
+
Store.prototype.register = function(callback) {
|
209
|
+
return this.callbacks.push(callback);
|
210
|
+
};
|
211
|
+
|
212
|
+
Store.prototype.unregister = function(callback) {
|
213
|
+
return this.callbacks = _.reject(this.callbacks, function(cb) {
|
214
|
+
return cb === callback;
|
215
|
+
});
|
216
|
+
};
|
217
|
+
|
218
|
+
Store.prototype.listen = function(callbackName) {
|
219
|
+
var store;
|
220
|
+
store = this;
|
221
|
+
return {
|
222
|
+
componentDidMount: function() {
|
223
|
+
return store.register(this[callbackName]);
|
224
|
+
},
|
225
|
+
componentWillUnmount: function() {
|
226
|
+
return store.unregister(this[callbackName]);
|
227
|
+
}
|
228
|
+
};
|
229
|
+
};
|
230
|
+
|
231
|
+
Store.prototype.trigger = function() {
|
232
|
+
return _.forEach(this.callbacks, function(callback) {
|
233
|
+
return callback();
|
234
|
+
});
|
235
|
+
};
|
236
|
+
|
237
|
+
Hippodrome.Store = Store;
|
238
|
+
|
239
|
+
if (isNode) {
|
240
|
+
module.exports = Hippodrome;
|
241
|
+
} else {
|
242
|
+
this.Hippodrome = Hippodrome;
|
243
|
+
}
|
244
|
+
|
245
|
+
}).call(this);
|
data/lib/hippodrome/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hippodrome
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Kermes
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-10-
|
12
|
+
date: 2014-10-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -53,20 +53,6 @@ dependencies:
|
|
53
53
|
- - ~>
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '4.0'
|
56
|
-
- !ruby/object:Gem::Dependency
|
57
|
-
name: coffee-rails
|
58
|
-
requirement: !ruby/object:Gem::Requirement
|
59
|
-
requirements:
|
60
|
-
- - ~>
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: 4.0.1
|
63
|
-
type: :runtime
|
64
|
-
prerelease: false
|
65
|
-
version_requirements: !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - ~>
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: 4.0.1
|
70
56
|
- !ruby/object:Gem::Dependency
|
71
57
|
name: lodash-rails
|
72
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,12 +80,7 @@ extra_rdoc_files: []
|
|
94
80
|
files:
|
95
81
|
- LICENSE.txt
|
96
82
|
- README.md
|
97
|
-
- app/assets/javascripts/
|
98
|
-
- app/assets/javascripts/assert.js.coffee
|
99
|
-
- app/assets/javascripts/dispatcher.js.coffee
|
100
|
-
- app/assets/javascripts/hippodrome.js.coffee
|
101
|
-
- app/assets/javascripts/side_effect.js.coffee
|
102
|
-
- app/assets/javascripts/store.js.coffee
|
83
|
+
- app/assets/javascripts/hippodrome.js
|
103
84
|
- lib/hippodrome.rb
|
104
85
|
- lib/hippodrome/version.rb
|
105
86
|
homepage: https://github.com/Structural/hippodrome
|
@@ -1,22 +0,0 @@
|
|
1
|
-
Action = (name, ctor) ->
|
2
|
-
buildPayload = ->
|
3
|
-
payload = ctor.apply(null, arguments)
|
4
|
-
payload.action = name
|
5
|
-
payload
|
6
|
-
|
7
|
-
send = (payload) ->
|
8
|
-
Hippodrome.Dispatcher.dispatch(payload)
|
9
|
-
|
10
|
-
actionFn = ->
|
11
|
-
payload = buildPayload.apply(null, arguments)
|
12
|
-
send(payload)
|
13
|
-
|
14
|
-
actionFn.buildPayload = buildPayload
|
15
|
-
actionFn.send = send
|
16
|
-
|
17
|
-
actionFn.hippoName = name
|
18
|
-
actionFn.toString = -> name
|
19
|
-
|
20
|
-
actionFn
|
21
|
-
|
22
|
-
Hippodrome.Action = Action
|
@@ -1,12 +0,0 @@
|
|
1
|
-
Hippodrome.assert = (condition, message, args...) ->
|
2
|
-
if not condition
|
3
|
-
# TODO: Don't report in non-dev mode
|
4
|
-
argIndex = 0;
|
5
|
-
error = new Error('Assertion Failed: ' +
|
6
|
-
message.replace(/%s/g, -> args[argIndex++]))
|
7
|
-
|
8
|
-
# Ignore assert's frame
|
9
|
-
error.framesToPop = 1
|
10
|
-
throw error
|
11
|
-
|
12
|
-
condition
|
@@ -1,83 +0,0 @@
|
|
1
|
-
Dispatcher = ->
|
2
|
-
@callbacksByAction = {}
|
3
|
-
@isStarted = {}
|
4
|
-
@isFinished = {}
|
5
|
-
@isDispatching = false
|
6
|
-
@payload = null
|
7
|
-
|
8
|
-
prefix = 'Dispatcher_ID_'
|
9
|
-
lastId = 1
|
10
|
-
nextId = -> prefix + lastId++
|
11
|
-
|
12
|
-
Dispatcher.prototype.register = ->
|
13
|
-
args = _.compact(arguments)
|
14
|
-
|
15
|
-
if args.length == 3
|
16
|
-
@register(args[0], args[1], [], args[2])
|
17
|
-
else
|
18
|
-
[store, action, prereqStores, callback] = args
|
19
|
-
@callbacksByAction[action] ?= {}
|
20
|
-
|
21
|
-
id = nextId()
|
22
|
-
@callbacksByAction[action][id] = {
|
23
|
-
callback: callback,
|
24
|
-
prerequisites: _.map(prereqStores,
|
25
|
-
(ps) -> ps.dispatcherIdsByAction[action])
|
26
|
-
}
|
27
|
-
id
|
28
|
-
|
29
|
-
Dispatcher.prototype.unregister = (action, id) ->
|
30
|
-
Hippodrome.assert(@callbacksByAction[action][id],
|
31
|
-
'Dispatcher.unregister(%s, %s) does not map to a registered callback.',
|
32
|
-
action, id)
|
33
|
-
@callbacks[action][id] = null
|
34
|
-
|
35
|
-
Dispatcher.prototype.waitFor = (action, ids) ->
|
36
|
-
Hippodrome.assert(@isDispatching,
|
37
|
-
'Dispatcher.waitFor must be invoked while dispatching.')
|
38
|
-
_.forEach(ids, (id) =>
|
39
|
-
if @isStarted[id]
|
40
|
-
Hippodrome.assert(@isFinished[id],
|
41
|
-
'Dispatcher.waitFor encountered circular dependency while ' +
|
42
|
-
'waiting for `%s` during %s.', id, action)
|
43
|
-
return
|
44
|
-
|
45
|
-
Hippodrome.assert(@callbacksByAction[action][id],
|
46
|
-
'Dispatcher.waitFor `%s` is not a registered callback for %s.',
|
47
|
-
id, action)
|
48
|
-
@invokeCallback(action, id)
|
49
|
-
)
|
50
|
-
|
51
|
-
Dispatcher.prototype.dispatch = (payload) ->
|
52
|
-
Hippodrome.assert(not @isDispatching,
|
53
|
-
'Dispatch.dispatch cannot be called during dispatch.')
|
54
|
-
@startDispatching(payload)
|
55
|
-
try
|
56
|
-
action = payload.action
|
57
|
-
_.forEach(@callbacksByAction[action], (callback, id) =>
|
58
|
-
if @isStarted[id]
|
59
|
-
return
|
60
|
-
|
61
|
-
@invokeCallback(action, id)
|
62
|
-
)
|
63
|
-
finally
|
64
|
-
@stopDispatching()
|
65
|
-
|
66
|
-
Dispatcher.prototype.invokeCallback = (action, id) ->
|
67
|
-
@isStarted[id] = true
|
68
|
-
{callback, prerequisites} = @callbacksByAction[action][id]
|
69
|
-
@waitFor(action, prerequisites)
|
70
|
-
callback(@payload)
|
71
|
-
@isFinished[id] = true
|
72
|
-
|
73
|
-
Dispatcher.prototype.startDispatching = (payload) ->
|
74
|
-
@isStarted = {}
|
75
|
-
@isFinished = {}
|
76
|
-
@payload = payload
|
77
|
-
@isDispatching = true
|
78
|
-
|
79
|
-
Dispatcher.prototype.stopDispatching = ->
|
80
|
-
@payload = null
|
81
|
-
@isDispatching = false
|
82
|
-
|
83
|
-
Hippodrome.Dispatcher = new Dispatcher()
|
@@ -1,19 +0,0 @@
|
|
1
|
-
SideEffect = (options) ->
|
2
|
-
Hippodrome.assert(options.action,
|
3
|
-
'SideEffect must register for exactly one action.')
|
4
|
-
Hippodrome.assert(options.effect,
|
5
|
-
'SideEffect must supply exactly one effect to run')
|
6
|
-
|
7
|
-
{action, effect} = options
|
8
|
-
|
9
|
-
if typeof effect == 'string'
|
10
|
-
effect = this[effect]
|
11
|
-
effect = _.defer.bind(this, effect)
|
12
|
-
|
13
|
-
id = Hippodrome.Dispatcher.register(this, action.hippoName, [], effect)
|
14
|
-
@dispatcherIdsByAction = {}
|
15
|
-
@dispatcherIdsByAction[action.hippoName] = id
|
16
|
-
|
17
|
-
this
|
18
|
-
|
19
|
-
Hippodrome.SideEffect = SideEffect
|
@@ -1,52 +0,0 @@
|
|
1
|
-
bindToContextIfFunction = (context) ->
|
2
|
-
(objValue, srcValue) ->
|
3
|
-
if srcValue instanceof Function
|
4
|
-
srcValue.bind(context)
|
5
|
-
else
|
6
|
-
srcValue
|
7
|
-
|
8
|
-
Store = (options) ->
|
9
|
-
@dispatcherIdsByAction = {}
|
10
|
-
@callbacks = []
|
11
|
-
_.assign(this, _.omit(options, 'initialize', 'dispatches'), bindToContextIfFunction(this))
|
12
|
-
|
13
|
-
if options.initialize
|
14
|
-
options.initialize.call(@)
|
15
|
-
|
16
|
-
if options.dispatches
|
17
|
-
_.forEach(options.dispatches, (callbackDescription) =>
|
18
|
-
{action, after, callback} = callbackDescription
|
19
|
-
|
20
|
-
Hippodrome.assert(not @dispatcherIdsByAction[action.hippoName]
|
21
|
-
'Each store can only register one callback for each action.')
|
22
|
-
|
23
|
-
if typeof callback == 'string'
|
24
|
-
callback = @[callback]
|
25
|
-
callback = callback.bind(@)
|
26
|
-
|
27
|
-
id = Hippodrome.Dispatcher.register(this, action.hippoName, after, callback)
|
28
|
-
@dispatcherIdsByAction[action.hippoName] = id
|
29
|
-
)
|
30
|
-
|
31
|
-
this
|
32
|
-
|
33
|
-
Store.prototype.register = (callback) ->
|
34
|
-
@callbacks.push(callback)
|
35
|
-
|
36
|
-
Store.prototype.unregister = (callback) ->
|
37
|
-
@callbacks = _.reject(@callbacks, (cb) -> cb == callback)
|
38
|
-
|
39
|
-
# register/unregister are completely general, this is tailored for React mixins.
|
40
|
-
Store.prototype.listen = (callbackName) ->
|
41
|
-
store = this
|
42
|
-
return {
|
43
|
-
componentDidMount: ->
|
44
|
-
store.register(this[callbackName])
|
45
|
-
componentWillUnmount: ->
|
46
|
-
store.unregister(this[callbackName])
|
47
|
-
}
|
48
|
-
|
49
|
-
Store.prototype.trigger = ->
|
50
|
-
_.forEach(@callbacks, (callback) -> callback())
|
51
|
-
|
52
|
-
Hippodrome.Store = Store
|