hyper-operation 0.5.0
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 +7 -0
- data/.gitignore +49 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +324 -0
- data/LICENSE.txt +21 -0
- data/README.md +708 -0
- data/Rakefile +4 -0
- data/examples/chat-app/.gitignore +21 -0
- data/examples/chat-app/Gemfile +57 -0
- data/examples/chat-app/Gemfile.lock +282 -0
- data/examples/chat-app/README.md +3 -0
- data/examples/chat-app/Rakefile +6 -0
- data/examples/chat-app/app/assets/config/manifest.js +3 -0
- data/examples/chat-app/app/assets/images/.keep +0 -0
- data/examples/chat-app/app/assets/javascripts/application.js +3 -0
- data/examples/chat-app/app/assets/javascripts/cable.js +13 -0
- data/examples/chat-app/app/assets/javascripts/channels/.keep +0 -0
- data/examples/chat-app/app/assets/stylesheets/application.css +15 -0
- data/examples/chat-app/app/channels/application_cable/channel.rb +4 -0
- data/examples/chat-app/app/channels/application_cable/connection.rb +4 -0
- data/examples/chat-app/app/controllers/application_controller.rb +3 -0
- data/examples/chat-app/app/controllers/concerns/.keep +0 -0
- data/examples/chat-app/app/controllers/home_controller.rb +5 -0
- data/examples/chat-app/app/helpers/application_helper.rb +2 -0
- data/examples/chat-app/app/hyperloop/components/app.rb +11 -0
- data/examples/chat-app/app/hyperloop/components/formatted_div.rb +13 -0
- data/examples/chat-app/app/hyperloop/components/input_box.rb +29 -0
- data/examples/chat-app/app/hyperloop/components/message.rb +29 -0
- data/examples/chat-app/app/hyperloop/components/messages.rb +9 -0
- data/examples/chat-app/app/hyperloop/components/nav.rb +30 -0
- data/examples/chat-app/app/hyperloop/operations/operations.rb +56 -0
- data/examples/chat-app/app/hyperloop/stores/message_store.rb +23 -0
- data/examples/chat-app/app/models/application_record.rb +3 -0
- data/examples/chat-app/app/models/concerns/.keep +0 -0
- data/examples/chat-app/app/models/models.rb +2 -0
- data/examples/chat-app/app/models/public/.keep +0 -0
- data/examples/chat-app/app/models/public/announcement.rb +8 -0
- data/examples/chat-app/app/policies/application_policy.rb +5 -0
- data/examples/chat-app/app/views/layouts/application.html.erb +51 -0
- data/examples/chat-app/bin/bundle +3 -0
- data/examples/chat-app/bin/rails +9 -0
- data/examples/chat-app/bin/rake +9 -0
- data/examples/chat-app/bin/setup +34 -0
- data/examples/chat-app/bin/spring +17 -0
- data/examples/chat-app/bin/update +29 -0
- data/examples/chat-app/config.ru +5 -0
- data/examples/chat-app/config/application.rb +13 -0
- data/examples/chat-app/config/boot.rb +3 -0
- data/examples/chat-app/config/cable.yml +9 -0
- data/examples/chat-app/config/database.yml +25 -0
- data/examples/chat-app/config/environment.rb +5 -0
- data/examples/chat-app/config/environments/development.rb +56 -0
- data/examples/chat-app/config/environments/production.rb +86 -0
- data/examples/chat-app/config/environments/test.rb +42 -0
- data/examples/chat-app/config/initializers/application_controller_renderer.rb +6 -0
- data/examples/chat-app/config/initializers/assets.rb +11 -0
- data/examples/chat-app/config/initializers/backtrace_silencers.rb +7 -0
- data/examples/chat-app/config/initializers/cookies_serializer.rb +5 -0
- data/examples/chat-app/config/initializers/filter_parameter_logging.rb +4 -0
- data/examples/chat-app/config/initializers/hyperloop.rb +4 -0
- data/examples/chat-app/config/initializers/inflections.rb +16 -0
- data/examples/chat-app/config/initializers/mime_types.rb +4 -0
- data/examples/chat-app/config/initializers/new_framework_defaults.rb +24 -0
- data/examples/chat-app/config/initializers/session_store.rb +3 -0
- data/examples/chat-app/config/initializers/wrap_parameters.rb +14 -0
- data/examples/chat-app/config/locales/en.yml +23 -0
- data/examples/chat-app/config/puma.rb +47 -0
- data/examples/chat-app/config/routes.rb +5 -0
- data/examples/chat-app/config/secrets.yml +22 -0
- data/examples/chat-app/config/spring.rb +6 -0
- data/examples/chat-app/db/seeds.rb +7 -0
- data/examples/chat-app/lib/assets/.keep +0 -0
- data/examples/chat-app/lib/tasks/.keep +0 -0
- data/examples/chat-app/log/.keep +0 -0
- data/examples/chat-app/public/404.html +67 -0
- data/examples/chat-app/public/422.html +67 -0
- data/examples/chat-app/public/500.html +66 -0
- data/examples/chat-app/public/apple-touch-icon-precomposed.png +0 -0
- data/examples/chat-app/public/apple-touch-icon.png +0 -0
- data/examples/chat-app/public/favicon.ico +0 -0
- data/examples/chat-app/public/robots.txt +5 -0
- data/examples/chat-app/test/controllers/.keep +0 -0
- data/examples/chat-app/test/fixtures/.keep +0 -0
- data/examples/chat-app/test/fixtures/files/.keep +0 -0
- data/examples/chat-app/test/helpers/.keep +0 -0
- data/examples/chat-app/test/integration/.keep +0 -0
- data/examples/chat-app/test/mailers/.keep +0 -0
- data/examples/chat-app/test/models/.keep +0 -0
- data/examples/chat-app/test/test_helper.rb +10 -0
- data/examples/chat-app/tmp/.keep +0 -0
- data/examples/chat-app/vendor/assets/javascripts/.keep +0 -0
- data/examples/chat-app/vendor/assets/stylesheets/.keep +0 -0
- data/examples/five-letter-word-game/.gitignore +21 -0
- data/examples/five-letter-word-game/Gemfile +57 -0
- data/examples/five-letter-word-game/Gemfile.lock +282 -0
- data/examples/five-letter-word-game/README.md +24 -0
- data/examples/five-letter-word-game/Rakefile +6 -0
- data/examples/five-letter-word-game/app/assets/config/manifest.js +3 -0
- data/examples/five-letter-word-game/app/assets/images/.keep +0 -0
- data/examples/five-letter-word-game/app/assets/javascripts/application.js +3 -0
- data/examples/five-letter-word-game/app/assets/javascripts/cable.js +13 -0
- data/examples/five-letter-word-game/app/assets/javascripts/channels/.keep +0 -0
- data/examples/five-letter-word-game/app/assets/stylesheets/application.css +15 -0
- data/examples/five-letter-word-game/app/channels/application_cable/channel.rb +4 -0
- data/examples/five-letter-word-game/app/channels/application_cable/connection.rb +4 -0
- data/examples/five-letter-word-game/app/controllers/application_controller.rb +14 -0
- data/examples/five-letter-word-game/app/controllers/concerns/.keep +0 -0
- data/examples/five-letter-word-game/app/controllers/home_controller.rb +5 -0
- data/examples/five-letter-word-game/app/helpers/application_helper.rb +2 -0
- data/examples/five-letter-word-game/app/hyperloop/components/app.rb +65 -0
- data/examples/five-letter-word-game/app/hyperloop/components/guesses.rb +8 -0
- data/examples/five-letter-word-game/app/hyperloop/components/input_word.rb +13 -0
- data/examples/five-letter-word-game/app/hyperloop/models/user.rb +27 -0
- data/examples/five-letter-word-game/app/hyperloop/operations/ops.rb +115 -0
- data/examples/five-letter-word-game/app/hyperloop/stores/store.rb +120 -0
- data/examples/five-letter-word-game/app/jobs/application_job.rb +2 -0
- data/examples/five-letter-word-game/app/mailers/application_mailer.rb +4 -0
- data/examples/five-letter-word-game/app/models/application_record.rb +3 -0
- data/examples/five-letter-word-game/app/models/concerns/.keep +0 -0
- data/examples/five-letter-word-game/app/policies/user_policy.rb +4 -0
- data/examples/five-letter-word-game/app/views/layouts/application.html.erb +14 -0
- data/examples/five-letter-word-game/app/views/layouts/mailer.html.erb +13 -0
- data/examples/five-letter-word-game/app/views/layouts/mailer.text.erb +1 -0
- data/examples/five-letter-word-game/bin/bundle +3 -0
- data/examples/five-letter-word-game/bin/rails +9 -0
- data/examples/five-letter-word-game/bin/rake +9 -0
- data/examples/five-letter-word-game/bin/setup +34 -0
- data/examples/five-letter-word-game/bin/spring +17 -0
- data/examples/five-letter-word-game/bin/update +29 -0
- data/examples/five-letter-word-game/config.ru +5 -0
- data/examples/five-letter-word-game/config/application.rb +12 -0
- data/examples/five-letter-word-game/config/boot.rb +3 -0
- data/examples/five-letter-word-game/config/cable.yml +9 -0
- data/examples/five-letter-word-game/config/database.yml +25 -0
- data/examples/five-letter-word-game/config/environment.rb +5 -0
- data/examples/five-letter-word-game/config/environments/development.rb +56 -0
- data/examples/five-letter-word-game/config/environments/production.rb +86 -0
- data/examples/five-letter-word-game/config/environments/test.rb +42 -0
- data/examples/five-letter-word-game/config/initializers/application_controller_renderer.rb +6 -0
- data/examples/five-letter-word-game/config/initializers/assets.rb +11 -0
- data/examples/five-letter-word-game/config/initializers/backtrace_silencers.rb +7 -0
- data/examples/five-letter-word-game/config/initializers/cookies_serializer.rb +5 -0
- data/examples/five-letter-word-game/config/initializers/filter_parameter_logging.rb +4 -0
- data/examples/five-letter-word-game/config/initializers/hyperloop.rb +3 -0
- data/examples/five-letter-word-game/config/initializers/inflections.rb +16 -0
- data/examples/five-letter-word-game/config/initializers/mime_types.rb +4 -0
- data/examples/five-letter-word-game/config/initializers/new_framework_defaults.rb +24 -0
- data/examples/five-letter-word-game/config/initializers/session_store.rb +3 -0
- data/examples/five-letter-word-game/config/initializers/wrap_parameters.rb +14 -0
- data/examples/five-letter-word-game/config/locales/en.yml +23 -0
- data/examples/five-letter-word-game/config/puma.rb +47 -0
- data/examples/five-letter-word-game/config/routes.rb +5 -0
- data/examples/five-letter-word-game/config/secrets.yml +22 -0
- data/examples/five-letter-word-game/config/spring.rb +6 -0
- data/examples/five-letter-word-game/db/schema.rb +28 -0
- data/examples/five-letter-word-game/db/seeds.rb +7 -0
- data/examples/five-letter-word-game/lib/assets/.keep +0 -0
- data/examples/five-letter-word-game/lib/tasks/.keep +0 -0
- data/examples/five-letter-word-game/log/.keep +0 -0
- data/examples/five-letter-word-game/public/404.html +67 -0
- data/examples/five-letter-word-game/public/422.html +67 -0
- data/examples/five-letter-word-game/public/500.html +66 -0
- data/examples/five-letter-word-game/public/apple-touch-icon-precomposed.png +0 -0
- data/examples/five-letter-word-game/public/apple-touch-icon.png +0 -0
- data/examples/five-letter-word-game/public/favicon.ico +0 -0
- data/examples/five-letter-word-game/public/robots.txt +5 -0
- data/examples/five-letter-word-game/test/controllers/.keep +0 -0
- data/examples/five-letter-word-game/test/fixtures/.keep +0 -0
- data/examples/five-letter-word-game/test/fixtures/files/.keep +0 -0
- data/examples/five-letter-word-game/test/helpers/.keep +0 -0
- data/examples/five-letter-word-game/test/integration/.keep +0 -0
- data/examples/five-letter-word-game/test/mailers/.keep +0 -0
- data/examples/five-letter-word-game/test/models/.keep +0 -0
- data/examples/five-letter-word-game/test/test_helper.rb +10 -0
- data/examples/five-letter-word-game/tmp/.keep +0 -0
- data/examples/five-letter-word-game/vendor/assets/javascripts/.keep +0 -0
- data/examples/five-letter-word-game/vendor/assets/stylesheets/.keep +0 -0
- data/examples/smoke_test/.gitignore +21 -0
- data/examples/smoke_test/Gemfile +59 -0
- data/examples/smoke_test/Gemfile.lock +289 -0
- data/examples/smoke_test/README.md +24 -0
- data/examples/smoke_test/Rakefile +6 -0
- data/examples/smoke_test/app/assets/config/manifest.js +3 -0
- data/examples/smoke_test/app/assets/images/.keep +0 -0
- data/examples/smoke_test/app/assets/javascripts/application.js +15 -0
- data/examples/smoke_test/app/assets/javascripts/cable.js +13 -0
- data/examples/smoke_test/app/assets/javascripts/channels/.keep +0 -0
- data/examples/smoke_test/app/assets/stylesheets/application.css +15 -0
- data/examples/smoke_test/app/channels/application_cable/channel.rb +4 -0
- data/examples/smoke_test/app/channels/application_cable/connection.rb +4 -0
- data/examples/smoke_test/app/controllers/app_controller.rb +5 -0
- data/examples/smoke_test/app/controllers/application_controller.rb +3 -0
- data/examples/smoke_test/app/helpers/application_helper.rb +2 -0
- data/examples/smoke_test/app/hyperloop/components/hello.rb +25 -0
- data/examples/smoke_test/app/hyperloop/operations/operations/nested_send_to_all.rb +7 -0
- data/examples/smoke_test/app/hyperloop/operations/send_to_all.rb +6 -0
- data/examples/smoke_test/app/hyperloop/stores/messages.rb +4 -0
- data/examples/smoke_test/app/jobs/application_job.rb +2 -0
- data/examples/smoke_test/app/mailers/application_mailer.rb +4 -0
- data/examples/smoke_test/app/models/application_record.rb +3 -0
- data/examples/smoke_test/app/models/concerns/.keep +0 -0
- data/examples/smoke_test/app/policies/application_policy.rb +8 -0
- data/examples/smoke_test/app/views/layouts/application.html.erb +14 -0
- data/examples/smoke_test/app/views/layouts/mailer.html.erb +13 -0
- data/examples/smoke_test/app/views/layouts/mailer.text.erb +1 -0
- data/examples/smoke_test/bin/bundle +3 -0
- data/examples/smoke_test/bin/rails +9 -0
- data/examples/smoke_test/bin/rake +9 -0
- data/examples/smoke_test/bin/setup +34 -0
- data/examples/smoke_test/bin/spring +17 -0
- data/examples/smoke_test/bin/update +29 -0
- data/examples/smoke_test/config.ru +5 -0
- data/examples/smoke_test/config/application.rb +15 -0
- data/examples/smoke_test/config/boot.rb +3 -0
- data/examples/smoke_test/config/cable.yml +9 -0
- data/examples/smoke_test/config/database.yml +25 -0
- data/examples/smoke_test/config/environment.rb +5 -0
- data/examples/smoke_test/config/environments/development.rb +54 -0
- data/examples/smoke_test/config/environments/production.rb +86 -0
- data/examples/smoke_test/config/environments/test.rb +42 -0
- data/examples/smoke_test/config/initializers/application_controller_renderer.rb +6 -0
- data/examples/smoke_test/config/initializers/assets.rb +11 -0
- data/examples/smoke_test/config/initializers/backtrace_silencers.rb +7 -0
- data/examples/smoke_test/config/initializers/cookies_serializer.rb +5 -0
- data/examples/smoke_test/config/initializers/filter_parameter_logging.rb +4 -0
- data/examples/smoke_test/config/initializers/hyperloop.rb +32 -0
- data/examples/smoke_test/config/initializers/inflections.rb +16 -0
- data/examples/smoke_test/config/initializers/mime_types.rb +4 -0
- data/examples/smoke_test/config/initializers/new_framework_defaults.rb +24 -0
- data/examples/smoke_test/config/initializers/session_store.rb +3 -0
- data/examples/smoke_test/config/initializers/wrap_parameters.rb +14 -0
- data/examples/smoke_test/config/locales/en.yml +23 -0
- data/examples/smoke_test/config/puma.rb +47 -0
- data/examples/smoke_test/config/routes.rb +5 -0
- data/examples/smoke_test/config/secrets.yml +22 -0
- data/examples/smoke_test/config/spring.rb +6 -0
- data/examples/smoke_test/db/seeds.rb +7 -0
- data/examples/smoke_test/lib/assets/.keep +0 -0
- data/examples/smoke_test/lib/tasks/.keep +0 -0
- data/examples/smoke_test/log/.keep +0 -0
- data/examples/smoke_test/public/404.html +67 -0
- data/examples/smoke_test/public/422.html +67 -0
- data/examples/smoke_test/public/500.html +66 -0
- data/examples/smoke_test/public/apple-touch-icon-precomposed.png +0 -0
- data/examples/smoke_test/public/apple-touch-icon.png +0 -0
- data/examples/smoke_test/public/favicon.ico +0 -0
- data/examples/smoke_test/public/robots.txt +5 -0
- data/examples/smoke_test/test/controllers/.keep +0 -0
- data/examples/smoke_test/test/fixtures/.keep +0 -0
- data/examples/smoke_test/test/fixtures/files/.keep +0 -0
- data/examples/smoke_test/test/helpers/.keep +0 -0
- data/examples/smoke_test/test/integration/.keep +0 -0
- data/examples/smoke_test/test/mailers/.keep +0 -0
- data/examples/smoke_test/test/models/.keep +0 -0
- data/examples/smoke_test/test/test_helper.rb +10 -0
- data/examples/smoke_test/tmp/.keep +0 -0
- data/examples/smoke_test/vendor/assets/javascripts/.keep +0 -0
- data/examples/smoke_test/vendor/assets/stylesheets/.keep +0 -0
- data/hyper-operation.gemspec +44 -0
- data/lib/hyper-operation.rb +59 -0
- data/lib/hyper-operation/api.rb +154 -0
- data/lib/hyper-operation/boot.rb +24 -0
- data/lib/hyper-operation/call_by_class_name.rb +60 -0
- data/lib/hyper-operation/delay_and_interval.rb +9 -0
- data/lib/hyper-operation/engine.rb +11 -0
- data/lib/hyper-operation/exception.rb +13 -0
- data/lib/hyper-operation/filters/acting_user.rb +19 -0
- data/lib/hyper-operation/filters/outbound_filter.rb +9 -0
- data/lib/hyper-operation/filters/simple_hash.rb +22 -0
- data/lib/hyper-operation/opal_patches.rb +39 -0
- data/lib/hyper-operation/promise.rb +347 -0
- data/lib/hyper-operation/railway.rb +5 -0
- data/lib/hyper-operation/railway/dispatcher.rb +31 -0
- data/lib/hyper-operation/railway/operation_wrapper.rb +106 -0
- data/lib/hyper-operation/railway/params_wrapper.rb +124 -0
- data/lib/hyper-operation/railway/run.rb +140 -0
- data/lib/hyper-operation/railway/validations.rb +63 -0
- data/lib/hyper-operation/server_op.rb +98 -0
- data/lib/hyper-operation/transport/acting_user.rb +6 -0
- data/lib/hyper-operation/transport/action_cable.rb +39 -0
- data/lib/hyper-operation/transport/active_record.rb +15 -0
- data/lib/hyper-operation/transport/client_drivers.rb +210 -0
- data/lib/hyper-operation/transport/connection.rb +170 -0
- data/lib/hyper-operation/transport/hyperloop.rb +165 -0
- data/lib/hyper-operation/transport/hyperloop_controller.rb +184 -0
- data/lib/hyper-operation/transport/pluck.rb +6 -0
- data/lib/hyper-operation/transport/policy.rb +535 -0
- data/lib/hyper-operation/version.rb +5 -0
- data/lib/sources/hyperloop/pusher.js +98 -0
- metadata +628 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
module Hyperloop
|
2
|
+
# Tricky business here. Hyperloop::Store will define boot
|
3
|
+
# if it is not already defined. It creates a minimal compatible
|
4
|
+
# API that includes the run and on_dispatch methods. This way
|
5
|
+
# you can use the Boot interface without loading operations.
|
6
|
+
|
7
|
+
# Here we define Boot, but in case it has already been defined
|
8
|
+
# we make sure to run the inherited method, and define the
|
9
|
+
# on_dispatch and run methods. Finally we copy any receivers
|
10
|
+
# that may have been defined on the existing Boot to the new class.
|
11
|
+
class Application
|
12
|
+
Operation.inherited(Boot) if defined? Boot
|
13
|
+
class Boot < Operation
|
14
|
+
def self.on_dispatch(&block)
|
15
|
+
_Railway.add_receiver(&block)
|
16
|
+
end
|
17
|
+
def self.run(*args)
|
18
|
+
ClientDrivers.initialize_client_drivers_on_boot
|
19
|
+
_run(*args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
Boot.receivers.each { |r| Boot.on_dispatch &r } if Boot.respond_to? :receivers
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Hyperloop
|
2
|
+
class Operation
|
3
|
+
end
|
4
|
+
end
|
5
|
+
|
6
|
+
# patch so that we recognize Foo(...) as an operation inside a React Component
|
7
|
+
module React
|
8
|
+
module Component
|
9
|
+
module Tags
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# redefine find_component so if its a HyperOperation we return nil which will
|
14
|
+
# let Object.method_missing (see below) handle the method call to run.
|
15
|
+
def find_component(name)
|
16
|
+
component = lookup_const(name)
|
17
|
+
return nil if component && component < Hyperloop::Operation
|
18
|
+
if component && !component.method_defined?(:render)
|
19
|
+
raise "#{name} does not appear to be a react component."
|
20
|
+
end
|
21
|
+
component
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Object
|
28
|
+
class << self
|
29
|
+
alias _hyper_operation_original_method_missing method_missing
|
30
|
+
|
31
|
+
def method_missing(name, *args, &block)
|
32
|
+
if name =~ /^[A-Z]/
|
33
|
+
scopes = self.name.to_s.split('::').inject([Module]) do |nesting, next_const|
|
34
|
+
nesting + [nesting.last.const_get(next_const)]
|
35
|
+
end.reverse
|
36
|
+
#cant use const_defined? on server because it wont invoke rails auto loading
|
37
|
+
scope = scopes.detect { |s| s.const_get(name) rescue nil }
|
38
|
+
const = scope.const_get(name) if scope
|
39
|
+
end
|
40
|
+
_hyper_operation_original_method_missing(name, *args, &block) unless const.is_a?(Class) && const < Hyperloop::Operation
|
41
|
+
const.send(:run, *args)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
alias _hyper_operation_original_method_missing method_missing
|
46
|
+
|
47
|
+
def method_missing(name, *args, &block)
|
48
|
+
if name =~ /^[A-Z]/
|
49
|
+
first = self.is_a?(Module) || self.is_a?(Class) ? self.name : self.class.name
|
50
|
+
scopes = first.to_s.split('::').inject([Module]) do |nesting, next_const|
|
51
|
+
nesting + [nesting.last.const_get(next_const)]
|
52
|
+
end.reverse
|
53
|
+
#cant use const_defined? on server because it wont invoke rails auto loading
|
54
|
+
scope = scopes.detect { |s| s.const_get(name) rescue nil }
|
55
|
+
const = scope.const_get(name) if scope
|
56
|
+
end
|
57
|
+
_hyper_operation_original_method_missing(name, *args, &block) unless const.is_a?(Class) && const < Hyperloop::Operation
|
58
|
+
const.send(:run, *args)
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Hyperloop
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace Hyperloop
|
4
|
+
config.generators do |g|
|
5
|
+
g.test_framework :rspec, :fixture => false
|
6
|
+
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
|
7
|
+
g.assets false
|
8
|
+
g.helper false
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Hyperloop
|
2
|
+
class ActingUser
|
3
|
+
@default_options = {
|
4
|
+
:nils => false # true allows an explicit nil to be valid. Overrides any other options
|
5
|
+
}
|
6
|
+
|
7
|
+
def filter(data)
|
8
|
+
|
9
|
+
# Handle nil case
|
10
|
+
if data.nil?
|
11
|
+
return [nil, nil] if options[:nils]
|
12
|
+
return [nil, :nils]
|
13
|
+
end
|
14
|
+
|
15
|
+
# otherwise, we win.
|
16
|
+
return [data, nil]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Mutations
|
2
|
+
class SimpleHashFilter < AdditionalFilter
|
3
|
+
@default_options = {
|
4
|
+
:nils => false # true allows an explicit nil to be valid. Overrides any other options
|
5
|
+
}
|
6
|
+
|
7
|
+
def filter(data)
|
8
|
+
|
9
|
+
# Handle nil case
|
10
|
+
if data.nil?
|
11
|
+
return [nil, nil] if options[:nils]
|
12
|
+
return [nil, :nils]
|
13
|
+
end
|
14
|
+
|
15
|
+
# Now check if it's empty:
|
16
|
+
return [data, :empty] if data == {}
|
17
|
+
|
18
|
+
# If data is a hash, we win.
|
19
|
+
return [data, nil] if data.is_a? Hash
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Date
|
2
|
+
alias broken_equals ==
|
3
|
+
def ==(other)
|
4
|
+
return false unless other.is_a?(Date)
|
5
|
+
broken_equals(other)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Time
|
10
|
+
alias broken_equals ==
|
11
|
+
def ==(other)
|
12
|
+
return false unless other.is_a?(Time)
|
13
|
+
broken_equals(other)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
begin
|
18
|
+
JSON.parse("test")
|
19
|
+
rescue Exception => e
|
20
|
+
JSON.class_eval do
|
21
|
+
class << self
|
22
|
+
alias old_parse parse
|
23
|
+
end
|
24
|
+
def self.parse(*args, &block)
|
25
|
+
old_parse *args, &block
|
26
|
+
rescue Exception => e
|
27
|
+
raise StandardError.new e.message
|
28
|
+
end
|
29
|
+
end unless e.is_a? StandardError
|
30
|
+
end
|
31
|
+
|
32
|
+
class Set
|
33
|
+
def &(enum)
|
34
|
+
n = self.class.new
|
35
|
+
enum.each { |o| n.add(o) if include?(o) }
|
36
|
+
n
|
37
|
+
end
|
38
|
+
alias intersection &
|
39
|
+
end unless Set.method_defined? :intersection
|
@@ -0,0 +1,347 @@
|
|
1
|
+
class Promise
|
2
|
+
def self.value(value)
|
3
|
+
new.resolve(value)
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.error(value)
|
7
|
+
new.reject(value)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.when(*promises)
|
11
|
+
When.new(promises)
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :error, :prev, :next
|
15
|
+
|
16
|
+
def initialize(action = {})
|
17
|
+
@action = action
|
18
|
+
|
19
|
+
@realized = false
|
20
|
+
@exception = false
|
21
|
+
@value = nil
|
22
|
+
@error = nil
|
23
|
+
@delayed = false
|
24
|
+
|
25
|
+
@prev = nil
|
26
|
+
@next = []
|
27
|
+
end
|
28
|
+
|
29
|
+
def value
|
30
|
+
if Promise === @value
|
31
|
+
@value.value
|
32
|
+
else
|
33
|
+
@value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def act?
|
38
|
+
@action.has_key?(:success) || @action.has_key?(:always)
|
39
|
+
end
|
40
|
+
|
41
|
+
def action
|
42
|
+
@action.keys
|
43
|
+
end
|
44
|
+
|
45
|
+
def exception?
|
46
|
+
@exception
|
47
|
+
end
|
48
|
+
|
49
|
+
def realized?
|
50
|
+
!!@realized
|
51
|
+
end
|
52
|
+
|
53
|
+
def resolved?
|
54
|
+
@realized == :resolve
|
55
|
+
end
|
56
|
+
|
57
|
+
def rejected?
|
58
|
+
@realized == :reject
|
59
|
+
end
|
60
|
+
|
61
|
+
def pending?
|
62
|
+
!realized?
|
63
|
+
end
|
64
|
+
|
65
|
+
def ^(promise)
|
66
|
+
promise << self
|
67
|
+
self >> promise
|
68
|
+
|
69
|
+
promise
|
70
|
+
end
|
71
|
+
|
72
|
+
def <<(promise)
|
73
|
+
@prev = promise
|
74
|
+
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
def >>(promise)
|
79
|
+
@next << promise
|
80
|
+
|
81
|
+
if exception?
|
82
|
+
promise.reject(@delayed[0])
|
83
|
+
elsif resolved?
|
84
|
+
promise.resolve(@delayed ? @delayed[0] : value)
|
85
|
+
elsif rejected?
|
86
|
+
if !@action.has_key?(:failure) || Promise === (@delayed ? @delayed[0] : @error)
|
87
|
+
promise.reject(@delayed ? @delayed[0] : error)
|
88
|
+
elsif promise.action.include?(:always)
|
89
|
+
promise.reject(@delayed ? @delayed[0] : error)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
self
|
94
|
+
end
|
95
|
+
|
96
|
+
def resolve(value = nil)
|
97
|
+
if realized?
|
98
|
+
raise ArgumentError, 'the promise has already been realized'
|
99
|
+
end
|
100
|
+
|
101
|
+
if Promise === value
|
102
|
+
return (value << @prev) ^ self
|
103
|
+
end
|
104
|
+
|
105
|
+
begin
|
106
|
+
if block = @action[:success] || @action[:always]
|
107
|
+
value = block.call(value)
|
108
|
+
end
|
109
|
+
|
110
|
+
resolve!(value)
|
111
|
+
rescue Exception => e
|
112
|
+
exception!(e)
|
113
|
+
end
|
114
|
+
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
def resolve!(value)
|
119
|
+
@realized = :resolve
|
120
|
+
@value = value
|
121
|
+
|
122
|
+
if @next.any?
|
123
|
+
@next.each { |p| p.resolve(value) }
|
124
|
+
else
|
125
|
+
@delayed = [value]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def reject(value = nil)
|
130
|
+
if realized?
|
131
|
+
raise ArgumentError, 'the promise has already been realized'
|
132
|
+
end
|
133
|
+
|
134
|
+
if Promise === value
|
135
|
+
return (value << @prev) ^ self
|
136
|
+
end
|
137
|
+
|
138
|
+
begin
|
139
|
+
if block = @action[:failure] || @action[:always]
|
140
|
+
value = block.call(value)
|
141
|
+
end
|
142
|
+
|
143
|
+
if @action.has_key?(:always)
|
144
|
+
resolve!(value)
|
145
|
+
else
|
146
|
+
reject!(value)
|
147
|
+
end
|
148
|
+
rescue Exception => e
|
149
|
+
exception!(e)
|
150
|
+
end
|
151
|
+
|
152
|
+
self
|
153
|
+
end
|
154
|
+
|
155
|
+
def reject!(value)
|
156
|
+
@realized = :reject
|
157
|
+
@error = value
|
158
|
+
|
159
|
+
if @next.any?
|
160
|
+
@next.each { |p| p.reject(value) }
|
161
|
+
else
|
162
|
+
@delayed = [value]
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def exception!(error)
|
167
|
+
@exception = true
|
168
|
+
|
169
|
+
reject!(error)
|
170
|
+
end
|
171
|
+
|
172
|
+
def then(&block)
|
173
|
+
self ^ Promise.new(success: block)
|
174
|
+
end
|
175
|
+
|
176
|
+
def then!(&block)
|
177
|
+
there_can_be_only_one!
|
178
|
+
self.then(&block)
|
179
|
+
end
|
180
|
+
|
181
|
+
alias do then
|
182
|
+
alias do! then!
|
183
|
+
|
184
|
+
def fail(&block)
|
185
|
+
self ^ Promise.new(failure: block)
|
186
|
+
end
|
187
|
+
|
188
|
+
def fail!(&block)
|
189
|
+
there_can_be_only_one!
|
190
|
+
fail(&block)
|
191
|
+
end
|
192
|
+
|
193
|
+
alias rescue fail
|
194
|
+
alias catch fail
|
195
|
+
alias rescue! fail!
|
196
|
+
alias catch! fail!
|
197
|
+
|
198
|
+
def always(&block)
|
199
|
+
self ^ Promise.new(always: block)
|
200
|
+
end
|
201
|
+
|
202
|
+
def always!(&block)
|
203
|
+
there_can_be_only_one!
|
204
|
+
always(&block)
|
205
|
+
end
|
206
|
+
|
207
|
+
alias finally always
|
208
|
+
alias ensure always
|
209
|
+
alias finally! always!
|
210
|
+
alias ensure! always!
|
211
|
+
|
212
|
+
def trace(depth = nil, &block)
|
213
|
+
self ^ Trace.new(depth, block)
|
214
|
+
end
|
215
|
+
|
216
|
+
def trace!(*args, &block)
|
217
|
+
there_can_be_only_one!
|
218
|
+
trace(*args, &block)
|
219
|
+
end
|
220
|
+
|
221
|
+
def there_can_be_only_one!
|
222
|
+
if @next.any?
|
223
|
+
raise ArgumentError, 'a promise has already been chained'
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def inspect
|
228
|
+
result = "#<#{self.class}(#{object_id})"
|
229
|
+
|
230
|
+
if @next.any?
|
231
|
+
result += " >> #{@next.inspect}"
|
232
|
+
end
|
233
|
+
|
234
|
+
if realized?
|
235
|
+
result += ": #{(@value || @error).inspect}>"
|
236
|
+
else
|
237
|
+
result += ">"
|
238
|
+
end
|
239
|
+
|
240
|
+
result
|
241
|
+
end
|
242
|
+
|
243
|
+
class Trace < self
|
244
|
+
def self.it(promise)
|
245
|
+
current = []
|
246
|
+
|
247
|
+
if promise.act? || promise.prev.nil?
|
248
|
+
current.push(promise.value)
|
249
|
+
end
|
250
|
+
|
251
|
+
if prev = promise.prev
|
252
|
+
current.concat(it(prev))
|
253
|
+
else
|
254
|
+
current
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def initialize(depth, block)
|
259
|
+
@depth = depth
|
260
|
+
|
261
|
+
super success: proc {
|
262
|
+
trace = Trace.it(self).reverse
|
263
|
+
trace.pop
|
264
|
+
|
265
|
+
if depth && depth <= trace.length
|
266
|
+
trace.shift(trace.length - depth)
|
267
|
+
end
|
268
|
+
|
269
|
+
block.call(*trace)
|
270
|
+
}
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
class When < self
|
275
|
+
def initialize(promises = [])
|
276
|
+
super()
|
277
|
+
|
278
|
+
@wait = []
|
279
|
+
|
280
|
+
promises.each {|promise|
|
281
|
+
wait promise
|
282
|
+
}
|
283
|
+
end
|
284
|
+
|
285
|
+
def each(&block)
|
286
|
+
raise ArgumentError, 'no block given' unless block
|
287
|
+
|
288
|
+
self.then {|values|
|
289
|
+
values.each(&block)
|
290
|
+
}
|
291
|
+
end
|
292
|
+
|
293
|
+
def collect(&block)
|
294
|
+
raise ArgumentError, 'no block given' unless block
|
295
|
+
|
296
|
+
self.then {|values|
|
297
|
+
When.new(values.map(&block))
|
298
|
+
}
|
299
|
+
end
|
300
|
+
|
301
|
+
def inject(*args, &block)
|
302
|
+
self.then {|values|
|
303
|
+
values.reduce(*args, &block)
|
304
|
+
}
|
305
|
+
end
|
306
|
+
|
307
|
+
alias map collect
|
308
|
+
|
309
|
+
alias reduce inject
|
310
|
+
|
311
|
+
def wait(promise)
|
312
|
+
unless Promise === promise
|
313
|
+
promise = Promise.value(promise)
|
314
|
+
end
|
315
|
+
|
316
|
+
if promise.act?
|
317
|
+
promise = promise.then
|
318
|
+
end
|
319
|
+
|
320
|
+
@wait << promise
|
321
|
+
|
322
|
+
promise.always {
|
323
|
+
try if @next.any?
|
324
|
+
}
|
325
|
+
|
326
|
+
self
|
327
|
+
end
|
328
|
+
|
329
|
+
alias and wait
|
330
|
+
|
331
|
+
def >>(*)
|
332
|
+
super.tap {
|
333
|
+
try
|
334
|
+
}
|
335
|
+
end
|
336
|
+
|
337
|
+
def try
|
338
|
+
if @wait.all?(&:realized?)
|
339
|
+
if promise = @wait.find(&:rejected?)
|
340
|
+
reject(promise.error)
|
341
|
+
else
|
342
|
+
resolve(@wait.map(&:value))
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|