hippodrome 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dc3cea9a26a649e2e04b3c21554ba063aca8bdd3
4
+ data.tar.gz: 7767ff96fcc07330ba8da26c4c5b4c347248e1f7
5
+ SHA512:
6
+ metadata.gz: be5730f42f7060510ed95b7db3065776fc2407fabf8df85801ff602ad677d755aa17b8004f8a94260139fe7015115351e3c4202eb5e9297a36672168bedd2e73
7
+ data.tar.gz: 4e76f557732c663a619ad9b51404d9cfc46fbf604cf145b94343e4690cfe891def01be959d3efada45eb894621c3d838f2782048b1b86596162c9a46f2e9608c
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Sean Kermes
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # Hippodrome
2
+
3
+ > At last the herald with loud blare of trumpet calls forth the impatient teams
4
+ > and launches the fleet chariots into the field. The swoop of forked lightning,
5
+ > the arrow sped by Scythian string, the trail of the swiftly-falling star, the
6
+ > leaden hurricane of bullets whirled from Balearic slings has never so rapidly
7
+ > split the airy paths of the sky.… Thus they go once round, then a
8
+ > second time; thus goes the third lap, thus the fourth…
9
+ >
10
+ > — [Sidonius](http://skookumpete.com/chariots.htm)
11
+
12
+ Hippodrome is an implementation of Facebook's
13
+ [Flux](http://facebook.github.io/flux/docs/overview.html)
14
+ architecture. It adds some more structure (especially to Stores) to the ideas
15
+ beyond what [Facebook's Flux](https://github.com/facebook/flux) has and
16
+ includes Side Effects, objects that can respond to Actions (like Stores) but
17
+ instead of exposing data to views, do additional asynchronous work like
18
+ making a network request and possibly dispatching more actions based on the
19
+ response.
20
+
21
+ ## Installation
22
+
23
+ Add this line to your application's Gemfile:
24
+
25
+ gem 'hippodrome'
26
+
27
+ And then execute:
28
+
29
+ $ bundle
30
+
31
+ Or install it yourself as:
32
+
33
+ $ gem install hippodrome
34
+
35
+ ## Usage
36
+
37
+ In your javascript manifest file:
38
+
39
+ //= require hippodrome
40
+
41
+ TODO: Explain how all the bits work.
42
+
43
+ ## Contributing
44
+
45
+ 1. Fork it ( http://github.com/structural/hippodrome/fork )
46
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
47
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
48
+ 4. Push to the branch (`git push origin my-new-feature`)
49
+ 5. Create new Pull Request
@@ -0,0 +1,22 @@
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
@@ -0,0 +1,12 @@
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
@@ -0,0 +1,83 @@
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()
@@ -0,0 +1,5 @@
1
+ #= require lodash
2
+ #= require_self
3
+ #= require_tree .
4
+
5
+ window.Hippodrome = {}
@@ -0,0 +1,19 @@
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
@@ -0,0 +1,52 @@
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
@@ -0,0 +1,3 @@
1
+ module Hippodrome
2
+ VERSION = "0.0.8"
3
+ end
data/lib/hippodrome.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'lodash-rails'
2
+
3
+ require "hippodrome/version"
4
+
5
+ module Hippodrome
6
+ class Engine < ::Rails::Engine
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hippodrome
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.8
5
+ platform: ruby
6
+ authors:
7
+ - Sean Kermes
8
+ - William Lubelksi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-10-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '1.5'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: '1.5'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: railties
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: '4.0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
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
+ - !ruby/object:Gem::Dependency
71
+ name: lodash-rails
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 2.4.1
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ~>
82
+ - !ruby/object:Gem::Version
83
+ version: 2.4.1
84
+ description: Longer descripttion to make rake happy.
85
+ email:
86
+ - skermes@gmail.com
87
+ - will.lubelski@gmail.com
88
+ executables: []
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - LICENSE.txt
93
+ - README.md
94
+ - app/assets/javascripts/action.js.coffee
95
+ - app/assets/javascripts/assert.js.coffee
96
+ - app/assets/javascripts/dispatcher.js.coffee
97
+ - app/assets/javascripts/hippodrome.js.coffee
98
+ - app/assets/javascripts/side_effect.js.coffee
99
+ - app/assets/javascripts/store.js.coffee
100
+ - lib/hippodrome.rb
101
+ - lib/hippodrome/version.rb
102
+ homepage: ''
103
+ licenses:
104
+ - MIT
105
+ metadata: {}
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 2.2.1
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: Your data, like your chariots, go around and around in one direction in this,
126
+ a Flux implementation that only Ben Hur could love.
127
+ test_files: []
128
+ has_rdoc: