Class: TurboBoost::Commands::Runner
- Inherits:
-
Object
- Object
- TurboBoost::Commands::Runner
- Defined in:
- lib/turbo_boost/commands/runner.rb
Instance Attribute Summary collapse
-
#controller ⇒ Object
readonly
Returns the value of attribute controller.
-
#state_manager ⇒ Object
readonly
Returns the value of attribute state_manager.
Instance Method Summary collapse
- #command_aborted? ⇒ Boolean
- #command_class ⇒ Object
- #command_class_name ⇒ Object
- #command_errored? ⇒ Boolean
- #command_instance ⇒ Object
- #command_method_name ⇒ Object
- #command_name ⇒ Object
- #command_params ⇒ Object
- #command_performed? ⇒ Boolean
- #command_performing? ⇒ Boolean
- #command_requested? ⇒ Boolean
- #command_succeeded? ⇒ Boolean
- #command_valid? ⇒ Boolean
- #controller_action_prevented? ⇒ Boolean
-
#cookies ⇒ Object
Same implementation as ActionController::Base but with public visibility.
- #handle_command_event(event, error: nil) ⇒ Object
-
#initialize(controller, state_manager) ⇒ Runner
constructor
A new instance of Runner.
- #message_verifier ⇒ Object
- #meta_tag ⇒ Object
- #prevent_controller_action(error: nil) ⇒ Object
- #render_response(html: "", status: nil, headers: {TurboBoost: :Append}) ⇒ Object
- #run ⇒ Object
- #should_prevent_controller_action? ⇒ Boolean
- #turbo_stream ⇒ Object
- #update_response ⇒ Object
Constructor Details
#initialize(controller, state_manager) ⇒ Runner
Returns a new instance of Runner.
8 9 10 11 |
# File 'lib/turbo_boost/commands/runner.rb', line 8 def initialize(controller, state_manager) @controller = controller @state_manager = state_manager end |
Instance Attribute Details
#controller ⇒ Object (readonly)
Returns the value of attribute controller.
6 7 8 |
# File 'lib/turbo_boost/commands/runner.rb', line 6 def controller @controller end |
#state_manager ⇒ Object (readonly)
Returns the value of attribute state_manager.
6 7 8 |
# File 'lib/turbo_boost/commands/runner.rb', line 6 def state_manager @state_manager end |
Instance Method Details
#command_aborted? ⇒ Boolean
88 89 90 |
# File 'lib/turbo_boost/commands/runner.rb', line 88 def command_aborted? !!command_instance&.aborted? end |
#command_class ⇒ Object
78 79 80 |
# File 'lib/turbo_boost/commands/runner.rb', line 78 def command_class @command_class ||= command_class_name&.safe_constantize end |
#command_class_name ⇒ Object
65 66 67 68 69 70 |
# File 'lib/turbo_boost/commands/runner.rb', line 65 def command_class_name return nil unless command_requested? name = command_name.split("#").first name << "Command" unless name.end_with?("Command") name end |
#command_errored? ⇒ Boolean
92 93 94 |
# File 'lib/turbo_boost/commands/runner.rb', line 92 def command_errored? !!command_instance&.errored? end |
#command_instance ⇒ Object
82 83 84 85 86 |
# File 'lib/turbo_boost/commands/runner.rb', line 82 def command_instance @command_instance ||= command_class&.new(controller, state_manager, command_params).tap do |instance| instance&.add_observer self, :handle_command_event end end |
#command_method_name ⇒ Object
72 73 74 75 76 |
# File 'lib/turbo_boost/commands/runner.rb', line 72 def command_method_name return nil unless command_requested? return "perform" unless command_name.include?("#") command_name.split("#").last end |
#command_name ⇒ Object
60 61 62 63 |
# File 'lib/turbo_boost/commands/runner.rb', line 60 def command_name return nil unless command_requested? command_params[:name] end |
#command_params ⇒ Object
52 53 54 55 56 57 58 |
# File 'lib/turbo_boost/commands/runner.rb', line 52 def command_params return ActionController::Parameters.new if controller.params[:turbo_boost_command].nil? @command_params ||= begin payload = parsed_command_params.deep_transform_keys(&:underscore) ActionController::Parameters.new(payload).permit! end end |
#command_performed? ⇒ Boolean
100 101 102 |
# File 'lib/turbo_boost/commands/runner.rb', line 100 def command_performed? !!command_instance&.performed? end |
#command_performing? ⇒ Boolean
96 97 98 |
# File 'lib/turbo_boost/commands/runner.rb', line 96 def command_performing? !!command_instance&.performing? end |
#command_requested? ⇒ Boolean
24 25 26 |
# File 'lib/turbo_boost/commands/runner.rb', line 24 def command_requested? command_params.present? end |
#command_succeeded? ⇒ Boolean
104 105 106 |
# File 'lib/turbo_boost/commands/runner.rb', line 104 def command_succeeded? !!command_instance&.succeeded? end |
#command_valid? ⇒ Boolean
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/turbo_boost/commands/runner.rb', line 28 def command_valid? return false unless command_requested? # validate class unless command_instance.is_a?(TurboBoost::Commands::Command) raise TurboBoost::Commands::InvalidClassError, "`#{command_class_name}` is not a subclass of `TurboBoost::Commands::Command`!" end # validate method unless command_instance.respond_to?(command_method_name) raise TurboBoost::Commands::InvalidMethodError, "`#{command_class_name}` does not define the public method `#{command_method_name}`!" end # validate csrf token unless valid_client_token? raise TurboBoost::InvalidTokenError, "CSRF token mismatch! The request header `TurboBoost-Token: #{client_token}` does not match the expected value of `#{server_token}`." end true end |
#controller_action_prevented? ⇒ Boolean
108 109 110 |
# File 'lib/turbo_boost/commands/runner.rb', line 108 def controller_action_prevented? !!@controller_action_prevented end |
#cookies ⇒ Object
Same implementation as ActionController::Base but with public visibility
170 171 172 |
# File 'lib/turbo_boost/commands/runner.rb', line 170 def controller.request. end |
#handle_command_event(event, error: nil) ⇒ Object
174 175 176 177 178 179 180 181 182 |
# File 'lib/turbo_boost/commands/runner.rb', line 174 def handle_command_event(event, error: nil) case event when :aborted prevent_controller_action error: error append_streams_to_response_body when :errored then prevent_controller_action(error: error) when :performed then prevent_controller_action if should_prevent_controller_action? end end |
#message_verifier ⇒ Object
165 166 167 |
# File 'lib/turbo_boost/commands/runner.rb', line 165 def ActiveSupport::MessageVerifier.new Rails.application.secret_key_base, digest: "SHA256" end |
#meta_tag ⇒ Object
13 14 15 16 17 18 19 20 21 22 |
# File 'lib/turbo_boost/commands/runner.rb', line 13 def masked_token = .generate(new_token) = { id: "turbo-boost", name: "turbo-boost", content: masked_token, data: {busy: false, state: state_manager.payload} } controller.view_context.tag("meta", ).html_safe end |
#prevent_controller_action(error: nil) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/turbo_boost/commands/runner.rb', line 128 def prevent_controller_action(error: nil) return if controller_action_prevented? @controller_action_prevented = true if error render_response status: :internal_server_error append_error_to_response error else render_response append_success_to_response end # called before `write_cookie` so all state is emitted to the DOM state_manager. # truncates state to stay within cookie size limits (4k) end |
#render_response(html: "", status: nil, headers: {TurboBoost: :Append}) ⇒ Object
156 157 158 159 |
# File 'lib/turbo_boost/commands/runner.rb', line 156 def render_response(html: "", status: nil, headers: {TurboBoost: :Append}) headers.each { |key, value| controller.response.set_header key.to_s, value.to_s } controller.render html: html, layout: false, status: status || response_status end |
#run ⇒ Object
117 118 119 120 121 122 123 124 125 126 |
# File 'lib/turbo_boost/commands/runner.rb', line 117 def run return unless command_valid? return if command_aborted? return if command_errored? return if command_performing? return if command_performed? command_instance.perform_with_callbacks command_method_name rescue => error prevent_controller_action error: error end |
#should_prevent_controller_action? ⇒ Boolean
112 113 114 115 |
# File 'lib/turbo_boost/commands/runner.rb', line 112 def should_prevent_controller_action? return false unless command_performed? command_instance.should_prevent_controller_action? command_method_name end |
#turbo_stream ⇒ Object
161 162 163 |
# File 'lib/turbo_boost/commands/runner.rb', line 161 def turbo_stream @turbo_stream ||= Turbo::Streams::TagBuilder.new(controller.view_context) end |
#update_response ⇒ Object
144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/turbo_boost/commands/runner.rb', line 144 def update_response return if controller_action_prevented? return if @update_response_performed @update_response_performed = true # called before `write_cookie` so all state is emitted to the DOM state_manager. # truncates state to stay within cookie size limits (4k) append_success_to_response if command_succeeded? rescue => error Rails.logger.error "TurboBoost::Commands::Runner failed to update the response! #{error.}" end |